* merged with tip (040f180a056b)
authorRobert Schuster <robertschuster@fsfe.org>
Mon, 11 Aug 2008 10:48:32 +0000 (12:48 +0200)
committerRobert Schuster <robertschuster@fsfe.org>
Mon, 11 Aug 2008 10:48:32 +0000 (12:48 +0200)
--HG--
branch : jitcache-arm-x86
rename : src/vmcore/class.c => src/vm/class.c
rename : src/vmcore/class.h => src/vm/class.h
rename : src/vmcore/system.h => src/vm/os.hpp
rename : src/vmcore/references.h => src/vm/references.h
rename : src/vmcore/statistics.c => src/vm/statistics.c
rename : src/vmcore/statistics.h => src/vm/statistics.h

502 files changed:
configure.ac
contrib/mapfile-vers-product
doc/doxygen/Makefile.am
m4/cacaoh.m4 [deleted file]
m4/java-runtime-library.m4
m4/opagent.m4 [new file with mode: 0644]
src/Makefile.am
src/cacao/Makefile.am
src/cacao/cacao.c [deleted file]
src/cacao/cacao.cpp [new file with mode: 0644]
src/cacaoh/Makefile.am [deleted file]
src/cacaoh/cacaoh.c [deleted file]
src/cacaoh/dummy.c [deleted file]
src/cacaoh/headers.c [deleted file]
src/cacaoh/headers.h [deleted file]
src/classes/gnuclasspath/java/lang/VMThread.java
src/classes/gnuclasspath/sun/reflect/annotation/AnnotationParser.java
src/classes/gnuclasspath/sun/reflect/annotation/AnnotationType.java
src/mm/Makefile.am
src/mm/boehm-gc/Makefile.am
src/mm/boehm-gc/include/gc.h
src/mm/boehm-gc/include/private/gcconfig.h
src/mm/boehm-gc/m4/dummy [new file with mode: 0644]
src/mm/boehm-gc/pthread_stop_world.c
src/mm/boehm.c [deleted file]
src/mm/cacao-gc/final.c
src/mm/cacao-gc/final.h
src/mm/cacao-gc/gc.c
src/mm/cacao-gc/gc.h
src/mm/cacao-gc/heap.c
src/mm/cacao-gc/mark.c
src/mm/cacao-gc/rootset.c
src/mm/cacao-gc/rootset.h
src/mm/codememory.c
src/mm/codememory.h
src/mm/dumpmemory.c
src/mm/dumpmemory.h
src/mm/gc-boehm.cpp [new file with mode: 0644]
src/mm/gc-common.h [deleted file]
src/mm/gc-none.cpp [new file with mode: 0644]
src/mm/gc.hpp [new file with mode: 0644]
src/mm/memory.c
src/mm/memory.h
src/mm/nogc.c [deleted file]
src/mm/tlh.c [new file with mode: 0644]
src/mm/tlh.h [new file with mode: 0644]
src/native/Makefile.am
src/native/include/Makefile.am
src/native/jni.c [deleted file]
src/native/jni.cpp [new file with mode: 0644]
src/native/jni.h
src/native/jvmti/cacaodbg.c
src/native/jvmti/cacaodbg.h
src/native/jvmti/jvmti.c
src/native/llni.c
src/native/llni.h
src/native/localref.c
src/native/localref.h
src/native/native.c
src/native/native.h
src/native/vm/Makefile.am
src/native/vm/cldc1.1/Makefile.am
src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.c [deleted file]
src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.c [deleted file]
src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/com_sun_cldchi_io_ConsoleOutputStream.c [deleted file]
src/native/vm/cldc1.1/com_sun_cldchi_io_ConsoleOutputStream.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.c [deleted file]
src/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_Class.c [deleted file]
src/native/vm/cldc1.1/java_lang_Class.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_Double.c [deleted file]
src/native/vm/cldc1.1/java_lang_Double.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_Float.c [deleted file]
src/native/vm/cldc1.1/java_lang_Float.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_Math.c [deleted file]
src/native/vm/cldc1.1/java_lang_Math.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_Object.c [deleted file]
src/native/vm/cldc1.1/java_lang_Object.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_Runtime.c [deleted file]
src/native/vm/cldc1.1/java_lang_Runtime.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_String.c [deleted file]
src/native/vm/cldc1.1/java_lang_String.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_System.c [deleted file]
src/native/vm/cldc1.1/java_lang_System.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_Thread.c [deleted file]
src/native/vm/cldc1.1/java_lang_Thread.cpp [new file with mode: 0644]
src/native/vm/cldc1.1/java_lang_Throwable.c [deleted file]
src/native/vm/cldc1.1/java_lang_Throwable.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/Makefile.am
src/native/vm/gnuclasspath/gnu_classpath_VMStackWalker.c [deleted file]
src/native/vm/gnuclasspath/gnu_classpath_VMStackWalker.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/gnu_classpath_VMSystemProperties.c [deleted file]
src/native/vm/gnuclasspath/gnu_classpath_VMSystemProperties.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/gnu_java_lang_VMCPStringBuilder.c [deleted file]
src/native/vm/gnuclasspath/gnu_java_lang_VMCPStringBuilder.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/gnu_java_lang_management_VMClassLoadingMXBeanImpl.c [deleted file]
src/native/vm/gnuclasspath/gnu_java_lang_management_VMClassLoadingMXBeanImpl.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/gnu_java_lang_management_VMMemoryMXBeanImpl.c [deleted file]
src/native/vm/gnuclasspath/gnu_java_lang_management_VMMemoryMXBeanImpl.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/gnu_java_lang_management_VMRuntimeMXBeanImpl.c [deleted file]
src/native/vm/gnuclasspath/gnu_java_lang_management_VMRuntimeMXBeanImpl.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.c [deleted file]
src/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_VMClass.c [deleted file]
src/native/vm/gnuclasspath/java_lang_VMClass.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_VMClassLoader.c [deleted file]
src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_VMObject.c [deleted file]
src/native/vm/gnuclasspath/java_lang_VMObject.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_VMRuntime.c [deleted file]
src/native/vm/gnuclasspath/java_lang_VMRuntime.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_VMString.c [deleted file]
src/native/vm/gnuclasspath/java_lang_VMString.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_VMSystem.c [deleted file]
src/native/vm/gnuclasspath/java_lang_VMSystem.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_VMThread.c [deleted file]
src/native/vm/gnuclasspath/java_lang_VMThread.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_VMThrowable.c [deleted file]
src/native/vm/gnuclasspath/java_lang_VMThrowable.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_management_VMManagementFactory.c
src/native/vm/gnuclasspath/java_lang_reflect_VMConstructor.c [deleted file]
src/native/vm/gnuclasspath/java_lang_reflect_VMConstructor.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_reflect_VMField.c [deleted file]
src/native/vm/gnuclasspath/java_lang_reflect_VMField.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.c [deleted file]
src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_lang_reflect_VMProxy.c
src/native/vm/gnuclasspath/java_security_VMAccessController.c [deleted file]
src/native/vm/gnuclasspath/java_security_VMAccessController.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/java_util_concurrent_atomic_AtomicLong.c [deleted file]
src/native/vm/gnuclasspath/java_util_concurrent_atomic_AtomicLong.cpp [new file with mode: 0644]
src/native/vm/gnuclasspath/sun_reflect_ConstantPool.c [deleted file]
src/native/vm/gnuclasspath/sun_reflect_ConstantPool.cpp [new file with mode: 0644]
src/native/vm/nativevm.c
src/native/vm/nativevm.h
src/native/vm/openjdk/Makefile.am
src/native/vm/openjdk/hpi.c
src/native/vm/openjdk/hpi.h
src/native/vm/openjdk/jvm.c [deleted file]
src/native/vm/openjdk/jvm.cpp [new file with mode: 0644]
src/native/vm/reflect.c [deleted file]
src/native/vm/reflect.h [deleted file]
src/native/vm/reflection.cpp [new file with mode: 0644]
src/native/vm/reflection.hpp [new file with mode: 0644]
src/native/vm/sun_misc_Unsafe.c [deleted file]
src/native/vm/sun_misc_Unsafe.cpp [new file with mode: 0644]
src/threads/Makefile.am
src/threads/atomic.cpp [new file with mode: 0644]
src/threads/atomic.hpp [new file with mode: 0644]
src/threads/condition.hpp [new file with mode: 0644]
src/threads/critical.c [deleted file]
src/threads/critical.h [deleted file]
src/threads/lock-common.h
src/threads/mutex.h [deleted file]
src/threads/mutex.hpp [new file with mode: 0644]
src/threads/none/thread-none.c
src/threads/none/thread-none.h
src/threads/posix/Makefile.am
src/threads/posix/condition-posix.hpp [new file with mode: 0644]
src/threads/posix/generic-primitives.h [deleted file]
src/threads/posix/lock.c
src/threads/posix/lock.h
src/threads/posix/mutex-posix.h [deleted file]
src/threads/posix/mutex-posix.hpp [new file with mode: 0644]
src/threads/posix/thread-posix.c [deleted file]
src/threads/posix/thread-posix.cpp [new file with mode: 0644]
src/threads/posix/thread-posix.h [deleted file]
src/threads/posix/thread-posix.hpp [new file with mode: 0644]
src/threads/removeme.cpp [new file with mode: 0644]
src/threads/thread.c [deleted file]
src/threads/thread.cpp [new file with mode: 0644]
src/threads/thread.h [deleted file]
src/threads/thread.hpp [new file with mode: 0644]
src/threads/threadlist.c
src/threads/threadlist.h
src/toolbox/avl.c
src/toolbox/avl.h
src/toolbox/hashtable.h
src/toolbox/logging.c
src/toolbox/logging.h
src/toolbox/util.c
src/toolbox/util.h
src/vm/Makefile.am
src/vm/access.c
src/vm/access.h
src/vm/annotation.c [new file with mode: 0644]
src/vm/annotation.h [new file with mode: 0644]
src/vm/array.c
src/vm/array.h
src/vm/assertion.c
src/vm/assertion.h
src/vm/builtin.c
src/vm/builtin.h
src/vm/builtintable.inc
src/vm/class.c [new file with mode: 0644]
src/vm/class.h [new file with mode: 0644]
src/vm/classcache.c [new file with mode: 0644]
src/vm/classcache.h [new file with mode: 0644]
src/vm/descriptor.c [new file with mode: 0644]
src/vm/descriptor.h [new file with mode: 0644]
src/vm/exceptions.c [deleted file]
src/vm/exceptions.cpp [new file with mode: 0644]
src/vm/exceptions.h [deleted file]
src/vm/exceptions.hpp [new file with mode: 0644]
src/vm/field.c [new file with mode: 0644]
src/vm/field.h [new file with mode: 0644]
src/vm/finalizer.c
src/vm/finalizer.h
src/vm/global.h
src/vm/globals.cpp [new file with mode: 0644]
src/vm/globals.hpp [new file with mode: 0644]
src/vm/initialize.c
src/vm/initialize.h
src/vm/javaobjects.cpp [new file with mode: 0644]
src/vm/javaobjects.hpp [new file with mode: 0644]
src/vm/jit/Makefile.am
src/vm/jit/allocator/liveness.c
src/vm/jit/allocator/lsra.c
src/vm/jit/allocator/simplereg.c
src/vm/jit/alpha/Makefile.am
src/vm/jit/alpha/asmpart.S
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/machine-instr.h [deleted file]
src/vm/jit/alpha/md-abi.c
src/vm/jit/alpha/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/alpha/md-trap.h
src/vm/jit/alpha/md.h
src/vm/jit/alpha/patcher.c
src/vm/jit/argument.c
src/vm/jit/argument.h
src/vm/jit/arm/Makefile.am
src/vm/jit/arm/asmpart.S
src/vm/jit/arm/codegen.c
src/vm/jit/arm/emit.c
src/vm/jit/arm/linux/md-os.c
src/vm/jit/arm/machine-instr.h [deleted file]
src/vm/jit/arm/md-abi.c
src/vm/jit/arm/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/arm/md-trap.h
src/vm/jit/arm/md.c
src/vm/jit/arm/md.h
src/vm/jit/arm/patcher.c
src/vm/jit/asmpart.h
src/vm/jit/cfg.c
src/vm/jit/code.c
src/vm/jit/code.h
src/vm/jit/codegen-common.c
src/vm/jit/codegen-common.h
src/vm/jit/disass.h
src/vm/jit/dseg.c
src/vm/jit/dseg.h
src/vm/jit/emit-common.c
src/vm/jit/emit-common.h
src/vm/jit/executionstate.c
src/vm/jit/i386/Makefile.am
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/machine-instr.h [deleted file]
src/vm/jit/i386/md-abi.c
src/vm/jit/i386/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/i386/md-trap.h
src/vm/jit/i386/md.c
src/vm/jit/i386/patcher.c
src/vm/jit/i386/solaris/Makefile.am [new file with mode: 0644]
src/vm/jit/i386/solaris/md-asm.h [new file with mode: 0644]
src/vm/jit/i386/solaris/md-os.c [new file with mode: 0644]
src/vm/jit/inline/inline.c
src/vm/jit/intrp/asmpart.c
src/vm/jit/intrp/codegen.c
src/vm/jit/intrp/dynamic-super.c
src/vm/jit/intrp/engine.c
src/vm/jit/intrp/intrp.h
src/vm/jit/intrp/patcher.c
src/vm/jit/intrp/peephole.c
src/vm/jit/jit.c
src/vm/jit/jit.h
src/vm/jit/linenumbertable.c
src/vm/jit/linenumbertable.h
src/vm/jit/loop/graph.h
src/vm/jit/loop/loop.h
src/vm/jit/m68k/Makefile.am
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/machine-instr.h [deleted file]
src/vm/jit/m68k/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/m68k/md-trap.h
src/vm/jit/m68k/md.c
src/vm/jit/m68k/patcher.c
src/vm/jit/methodtree.c
src/vm/jit/methodtree.h
src/vm/jit/mips/Makefile.am
src/vm/jit/mips/asmpart.S
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/machine-instr.h [deleted file]
src/vm/jit/mips/md-abi.c
src/vm/jit/mips/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/mips/md-trap.h
src/vm/jit/mips/md.c
src/vm/jit/mips/md.h
src/vm/jit/mips/patcher.c
src/vm/jit/mips/uclinux/md-os.c
src/vm/jit/oprofile-agent.cpp [new file with mode: 0644]
src/vm/jit/oprofile-agent.hpp [new file with mode: 0644]
src/vm/jit/optimizing/bytecode_escape.c
src/vm/jit/optimizing/escape.c
src/vm/jit/optimizing/escape.h
src/vm/jit/optimizing/graph.c
src/vm/jit/optimizing/ifconv.c
src/vm/jit/optimizing/ifconv.h
src/vm/jit/optimizing/lifetimes.c
src/vm/jit/optimizing/lsra.c
src/vm/jit/optimizing/profile.c
src/vm/jit/optimizing/profile.h
src/vm/jit/optimizing/recompile.c
src/vm/jit/optimizing/recompile.h
src/vm/jit/optimizing/ssa.c
src/vm/jit/optimizing/ssa3.c
src/vm/jit/optimizing/ssa_phi.c
src/vm/jit/optimizing/ssa_rename.c
src/vm/jit/parisc/arch.h
src/vm/jit/parse.c
src/vm/jit/patcher-common.c
src/vm/jit/patcher-common.h
src/vm/jit/powerpc/Makefile.am
src/vm/jit/powerpc/asmpart.S
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/machine-instr.h [deleted file]
src/vm/jit/powerpc/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/powerpc/md-trap.h
src/vm/jit/powerpc/md.c
src/vm/jit/powerpc/md.h
src/vm/jit/powerpc/netbsd/md-os.c
src/vm/jit/powerpc/patcher.c
src/vm/jit/powerpc64/Makefile.am
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/machine-instr.h [deleted file]
src/vm/jit/powerpc64/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/powerpc64/md-trap.h
src/vm/jit/powerpc64/md.c
src/vm/jit/powerpc64/md.h
src/vm/jit/powerpc64/patcher.c
src/vm/jit/reg.h
src/vm/jit/replace.c
src/vm/jit/replace.h
src/vm/jit/s390/Makefile.am
src/vm/jit/s390/codegen.c
src/vm/jit/s390/emit.c
src/vm/jit/s390/machine-instr.h [deleted file]
src/vm/jit/s390/md-abi.c
src/vm/jit/s390/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/s390/md-trap.h
src/vm/jit/s390/md.c
src/vm/jit/s390/patcher.c
src/vm/jit/show.c
src/vm/jit/show.h
src/vm/jit/sparc64/Makefile.am
src/vm/jit/sparc64/codegen.c
src/vm/jit/sparc64/emit.c
src/vm/jit/sparc64/linux/md-os.c
src/vm/jit/sparc64/machine-instr.h [deleted file]
src/vm/jit/sparc64/md-abi.c
src/vm/jit/sparc64/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/sparc64/md-trap.h
src/vm/jit/sparc64/md.c
src/vm/jit/sparc64/patcher.c
src/vm/jit/sparc64/solaris/md-os.c
src/vm/jit/stack.c
src/vm/jit/stack.h
src/vm/jit/stacktrace.c [deleted file]
src/vm/jit/stacktrace.cpp [new file with mode: 0644]
src/vm/jit/stacktrace.h [deleted file]
src/vm/jit/stacktrace.hpp [new file with mode: 0644]
src/vm/jit/trace.c [deleted file]
src/vm/jit/trace.cpp [new file with mode: 0644]
src/vm/jit/trace.h [deleted file]
src/vm/jit/trace.hpp [new file with mode: 0644]
src/vm/jit/trap.c
src/vm/jit/trap.h
src/vm/jit/verify/icmds.c
src/vm/jit/verify/typecheck-common.c
src/vm/jit/verify/typecheck-stackbased.c
src/vm/jit/verify/typecheck-typeinferer.c
src/vm/jit/verify/typecheck.c
src/vm/jit/verify/typeinfo.c
src/vm/jit/verify/typeinfo.h
src/vm/jit/x86_64/Makefile.am
src/vm/jit/x86_64/asmpart.S
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/machine-instr.h [deleted file]
src/vm/jit/x86_64/md-abi.c
src/vm/jit/x86_64/md-atomic.hpp [new file with mode: 0644]
src/vm/jit/x86_64/md-trap.h
src/vm/jit/x86_64/md.c
src/vm/jit/x86_64/patcher.c
src/vm/jit/x86_64/solaris/Makefile.am [new file with mode: 0644]
src/vm/jit/x86_64/solaris/md-os.c [new file with mode: 0644]
src/vm/jit_interface.h [deleted file]
src/vm/linker.c [new file with mode: 0644]
src/vm/linker.h [new file with mode: 0644]
src/vm/loader.c [new file with mode: 0644]
src/vm/loader.h [new file with mode: 0644]
src/vm/method.c [new file with mode: 0644]
src/vm/method.h [new file with mode: 0644]
src/vm/options.c [new file with mode: 0644]
src/vm/options.h [new file with mode: 0644]
src/vm/os.cpp [new file with mode: 0644]
src/vm/os.hpp [new file with mode: 0644]
src/vm/package.cpp
src/vm/primitive.c [deleted file]
src/vm/primitive.cpp [new file with mode: 0644]
src/vm/primitive.h [deleted file]
src/vm/primitive.hpp [new file with mode: 0644]
src/vm/primitivecore.c [new file with mode: 0644]
src/vm/properties.c
src/vm/properties.h
src/vm/references.h [new file with mode: 0644]
src/vm/resolve.c
src/vm/resolve.h
src/vm/rt-timing.c [new file with mode: 0644]
src/vm/rt-timing.h [new file with mode: 0644]
src/vm/signal.c
src/vm/signallocal.h
src/vm/stackmap.c [new file with mode: 0644]
src/vm/stackmap.h [new file with mode: 0644]
src/vm/statistics.c [new file with mode: 0644]
src/vm/statistics.h [new file with mode: 0644]
src/vm/string.c [deleted file]
src/vm/string.cpp [new file with mode: 0644]
src/vm/string.hpp [new file with mode: 0644]
src/vm/stringlocal.h [deleted file]
src/vm/suck.c [new file with mode: 0644]
src/vm/suck.h [new file with mode: 0644]
src/vm/utf8.c [new file with mode: 0644]
src/vm/utf8.h [new file with mode: 0644]
src/vm/vm.c [deleted file]
src/vm/vm.cpp [new file with mode: 0644]
src/vm/vm.h [deleted file]
src/vm/vm.hpp [new file with mode: 0644]
src/vm/zip.c [new file with mode: 0644]
src/vm/zip.h [new file with mode: 0644]
src/vmcore/Makefile.am [deleted file]
src/vmcore/annotation.c [deleted file]
src/vmcore/annotation.h [deleted file]
src/vmcore/class.c [deleted file]
src/vmcore/class.h [deleted file]
src/vmcore/classcache.c [deleted file]
src/vmcore/classcache.h [deleted file]
src/vmcore/descriptor.c [deleted file]
src/vmcore/descriptor.h [deleted file]
src/vmcore/field.c [deleted file]
src/vmcore/field.h [deleted file]
src/vmcore/linker.c [deleted file]
src/vmcore/linker.h [deleted file]
src/vmcore/loader.c [deleted file]
src/vmcore/loader.h [deleted file]
src/vmcore/method.c [deleted file]
src/vmcore/method.h [deleted file]
src/vmcore/options.c [deleted file]
src/vmcore/options.h [deleted file]
src/vmcore/primitivecore.c [deleted file]
src/vmcore/references.h [deleted file]
src/vmcore/rt-timing.c [deleted file]
src/vmcore/rt-timing.h [deleted file]
src/vmcore/stackmap.c [deleted file]
src/vmcore/stackmap.h [deleted file]
src/vmcore/statistics.c [deleted file]
src/vmcore/statistics.h [deleted file]
src/vmcore/suck.c [deleted file]
src/vmcore/suck.h [deleted file]
src/vmcore/system.c [deleted file]
src/vmcore/system.h [deleted file]
src/vmcore/utf8.c [deleted file]
src/vmcore/utf8.h [deleted file]
src/vmcore/zip.c [deleted file]
src/vmcore/zip.h [deleted file]
tests/regression/bugzilla/All.java
tests/regression/bugzilla/PR89.java [new file with mode: 0644]

index 61b3bffe77268cc9d8d442d5ea83c56b1464ba33..1d19445a06b62f610f5b024841b47a121b88542a 100644 (file)
@@ -24,7 +24,7 @@ dnl Process this file with autoconf to produce a configure script.
 
 
 AC_INIT(cacao, 1.1.0pre, cacao@cacaojvm.org)
-AC_CONFIG_SRCDIR(src/cacao/cacao.c)
+AC_CONFIG_SRCDIR(src/cacao/cacao.cpp)
 AC_CANONICAL_HOST
 AC_PREREQ(2.59)
 AM_INIT_AUTOMAKE([1.9.0 dist-bzip2 tar-ustar])
@@ -37,13 +37,13 @@ AC_PREFIX_DEFAULT(/usr/local/cacao)
 
 dnl Set optimization and debugging for all architectures and systems.
 if test x"$CFLAGS" = "x"; then
-    OPT_CFLAGS="-O0 -g"
+    OPT_CFLAGS="-g -O0"
 else
     OPT_CFLAGS=$CFLAGS
 fi
 
 if test x"$CXXFLAGS" = "x"; then
-    OPT_CXXFLAGS="-O0 -g"
+    OPT_CXXFLAGS="-g -O0"
 else
     OPT_CXXFLAGS=$CXXFLAGS
 fi
@@ -56,7 +56,7 @@ alpha | alphaev56 | alphapca56 )
     JAVA_ARCH="alpha"
     ;;
 
-arm | armv4 | armv4tl | armv5b | armv5l )
+arm | armv4 | armv4tl | armv5b | armv5l | armv5tel | armv5tejl )
     ARCH_DIR="arm"
     ARCH_FLAGS="-D__ARM__"
     JAVA_ARCH="arm"
@@ -70,7 +70,7 @@ hppa2.0 )
 
 i386 | i486 | i586 | i686 )
     ARCH_DIR="i386"
-    ARCH_FLAGS="-D__I386__"
+    ARCH_FLAGS="-m32 -D__I386__"
     JAVA_ARCH="i386"
     ;;
 
@@ -89,13 +89,13 @@ mips | mipsel )
 
 powerpc )
     ARCH_DIR="powerpc"
-    ARCH_FLAGS="-D__POWERPC__"
+    ARCH_FLAGS="-m32 -D__POWERPC__"
     JAVA_ARCH="ppc"
     ;;
 
 powerpc64 )
     ARCH_DIR="powerpc64"
-    ARCH_FLAGS="-D__POWERPC64__"
+    ARCH_FLAGS="-m64 -D__POWERPC64__"
     JAVA_ARCH="ppc64"
     ;;
 
@@ -241,6 +241,8 @@ AC_PROG_LN_S
 AC_PROG_MAKE_SET
 AM_PROG_MKDIR_P
 
+AM_CONDITIONAL([WITH_GNU_LD], [test x"$with_gnu_ld" = "xyes"])
+
 dnl Checks for header files.
 AC_HEADER_DIRENT
 AC_HEADER_STDC
@@ -255,6 +257,7 @@ AC_CHECK_HEADERS([errno.h])
 AC_CHECK_HEADERS([fcntl.h])
 AC_CHECK_HEADERS([libgen.h])
 AC_CHECK_HEADERS([netdb.h])
+AC_CHECK_HEADERS([signal.h])
 AC_CHECK_HEADERS([stdint.h])
 AC_CHECK_HEADERS([stdio.h])
 AC_CHECK_HEADERS([stdlib.h])
@@ -283,6 +286,12 @@ AC_STRUCT_TM
 dnl Checks for libraries (NOTE: Should be done before function checks,
 dnl as some functions may be in libraries we check for).
 
+case "${OS_DIR}" in
+    solaris )
+         AC_CHECK_LIB([socket], [gethostname],, [AC_MSG_ERROR(cannot find libsocket)])
+         ;;
+esac
+
 dnl Checks for library functions.
 AC_PROG_GCC_TRADITIONAL
 AC_TYPE_SIGNAL
@@ -342,6 +351,7 @@ AC_CHECK_FUNCS([setsockopt])
 AC_CHECK_FUNCS([shutdown])
 AC_CHECK_FUNCS([socket])
 AC_CHECK_FUNCS([stat])
+AC_CHECK_FUNCS([str2sig])
 AC_CHECK_FUNCS([strcat])
 AC_CHECK_FUNCS([strchr])
 AC_CHECK_FUNCS([strcpy])
@@ -445,11 +455,13 @@ AC_MSG_RESULT(${ENABLE_SSA})
 AM_CONDITIONAL([ENABLE_SSA], test x"${ENABLE_SSA}" = "xyes")
 AM_CONDITIONAL([ENABLE_ESCAPE], test x"${ENABLE_SSA}" = "xyes")
 AM_CONDITIONAL([ENABLE_ESCAPE_CHECK], test x"${ENABLE_SSA}" = "xyes")
+AM_CONDITIONAL([ENABLE_TLH], test x"${ENABLE_SSA}" = "xyes")
 
 if test x"${ENABLE_SSA}" = "xyes"; then
     AC_DEFINE([ENABLE_SSA], 1, [enable lsra with ssa])
     AC_DEFINE([ENABLE_ESCAPE], 1, [enable escape analysis with ssa])
     AC_DEFINE([ENABLE_ESCAPE_CHECK], 1, [enable generating code to validate escape analysis results])
+    AC_DEFINE([ENABLE_TLH], 1, [enable thread local heap])
     ENABLE_LSRA="no"
 fi
 
@@ -514,6 +526,7 @@ else
        AM_CONDITIONAL([USE_SCHEDULER], [false])
 fi
 
+AC_CHECK_ENABLE_OPAGENT
 
 AC_CHECK_ENABLE_ZLIB
 
@@ -543,7 +556,6 @@ AC_DEFINE_UNQUOTED([CACAO_VM_ZIP], "${CACAO_VM_ZIP}", [CACAO's vm.zip])
 AC_SUBST(CACAO_VM_ZIP)
 
 
-AC_CHECK_WITH_CACAOH
 AC_CHECK_WITH_JAVA_RUNTIME_LIBRARY
 
 dnl Now we check for jre-layout so we can skip some checks that are
@@ -552,6 +564,7 @@ AC_CHECK_ENABLE_JRE_LAYOUT
 
 AC_CHECK_WITH_JAVA_RUNTIME_LIBRARY_PREFIX
 AC_CHECK_WITH_JAVA_RUNTIME_LIBRARY_CLASSES
+AC_CHECK_WITH_BUILD_JAVA_RUNTIME_LIBRARY_CLASSES
 
 if test x"${ENABLE_JRE_LAYOUT}" = "xno"; then
    AC_CHECK_WITH_JAVA_RUNTIME_LIBRARY_LIBDIR
@@ -646,7 +659,6 @@ AC_CONFIG_FILES([Makefile]
                [man/Makefile]
                [src/Makefile]
                [src/cacao/Makefile]
-               [src/cacaoh/Makefile]
                [src/classes/Makefile]
                [src/fdlibm/Makefile]
                [src/mm/Makefile]
@@ -677,6 +689,7 @@ AC_CONFIG_FILES([Makefile]
                [src/vm/jit/i386/darwin/Makefile]
                [src/vm/jit/i386/freebsd/Makefile]
                [src/vm/jit/i386/linux/Makefile]
+               [src/vm/jit/i386/solaris/Makefile]
                [src/vm/jit/intrp/Makefile]
                [src/vm/jit/inline/Makefile]
                [src/vm/jit/ir/Makefile]
@@ -705,7 +718,7 @@ AC_CONFIG_FILES([Makefile]
                [src/vm/jit/x86_64/Makefile]
                [src/vm/jit/x86_64/freebsd/Makefile]
                [src/vm/jit/x86_64/linux/Makefile]
-               [src/vmcore/Makefile]
+               [src/vm/jit/x86_64/solaris/Makefile]
                [tests/Makefile]
                [tests/regression/Makefile]
                [tests/regression/assertion/Makefile]
index 5d23dfa6a39cba8819fd75f90dd348ccdc155aa0..d414e6358b2b86d451b08c7ba0f85215136f7dda 100644 (file)
@@ -31,7 +31,7 @@
 SUNWprivate_1.1 {
         global:
                 # CACAO
-                vm_createjvm;
+                VM_create;
                 vm_run;
 
                 # JNI
index c75bf12b80ac0e9c4d49358b8311bdc21b5abb74..2ea19e9a5b7e36ae405a0d07be49a56cceec9b5b 100644 (file)
@@ -25,7 +25,7 @@ dist_noinst_DATA = \
        Doxyfile
 
 doxygen:
-       doxygen
+       doxygen $(srcdir)/Doxyfile
 
 clean-local:
        -rm -rf html latex
diff --git a/m4/cacaoh.m4 b/m4/cacaoh.m4
deleted file mode 100644 (file)
index 1c19667..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-dnl m4/cacaoh.m4
-dnl
-dnl Copyright (C) 2007, 2008
-dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-dnl 
-dnl This file is part of CACAO.
-dnl 
-dnl This program is free software; you can redistribute it and/or
-dnl modify it under the terms of the GNU General Public License as
-dnl published by the Free Software Foundation; either version 2, or (at
-dnl your option) any later version.
-dnl 
-dnl This program is distributed in the hope that it will be useful, but
-dnl WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-dnl General Public License for more details.
-dnl 
-dnl You should have received a copy of the GNU General Public License
-dnl along with this program; if not, write to the Free Software
-dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-dnl 02110-1301, USA.
-
-
-dnl check which cacaoh to use
-
-AC_DEFUN([AC_CHECK_WITH_CACAOH],[
-AC_MSG_CHECKING(which cacaoh to use (for crosscompilation))
-AC_ARG_WITH([cacaoh],
-            [AS_HELP_STRING(--with-cacaoh,which cacaoh to use [[default=$(top_builddir)/src/cacaoh/cacaoh]])],
-            [CACAOH="${withval}"],
-            [CACAOH=["\$(top_builddir)/src/cacaoh/cacaoh"]])
-AC_MSG_RESULT(${CACAOH})
-AC_SUBST(CACAOH)
-])
index d69cf7e07e3a5343a13994089da20bec65b341fa..587ddfaf954d4e804ce4514d7182ee5b2a6adb3a 100644 (file)
@@ -92,14 +92,28 @@ AC_ARG_WITH([java-runtime-library-classes],
 AC_MSG_RESULT(${JAVA_RUNTIME_LIBRARY_CLASSES})
 AC_DEFINE_UNQUOTED([JAVA_RUNTIME_LIBRARY_CLASSES], "${JAVA_RUNTIME_LIBRARY_CLASSES}", [Java runtime library classes])
 AC_SUBST(JAVA_RUNTIME_LIBRARY_CLASSES)
+])
+
+
+dnl where are Java core library classes located at compilation time
+
+AC_DEFUN([AC_CHECK_WITH_BUILD_JAVA_RUNTIME_LIBRARY_CLASSES],[
+AC_MSG_CHECKING(where Java core library classes are located at compile time)
+AC_ARG_WITH([build-java-runtime-library-classes],
+            [AS_HELP_STRING(--with-build-java-runtime-library-classes=<path>,path to Java core library classes (includes the name of the file and may be flat) [[default=${JAVA_RUNTIME_LIBRARY_CLASSES}]])],
+            [BUILD_JAVA_RUNTIME_LIBRARY_CLASSES=${withval}],
+            [BUILD_JAVA_RUNTIME_LIBRARY_CLASSES=${JAVA_RUNTIME_LIBRARY_CLASSES}])
+AC_MSG_RESULT(${BUILD_JAVA_RUNTIME_LIBRARY_CLASSES})
+AC_DEFINE_UNQUOTED([BUILD_JAVA_RUNTIME_LIBRARY_CLASSES], "${BUILD_JAVA_RUNTIME_LIBRARY_CLASSES}", [Java core library classes at compile time])
+AC_SUBST(BUILD_JAVA_RUNTIME_LIBRARY_CLASSES)
 
 dnl define BOOTCLASSPATH for Makefiles
 case "${WITH_JAVA_RUNTIME_LIBRARY}" in
     cldc1.1 | gnuclasspath)
-        BOOTCLASSPATH="\$(top_builddir)/src/classes/classes:\$(JAVA_RUNTIME_LIBRARY_CLASSES)"
+        BOOTCLASSPATH="\$(top_builddir)/src/classes/classes:${BUILD_JAVA_RUNTIME_LIBRARY_CLASSES}"
         ;;
     *)
-        BOOTCLASSPATH="\$(JAVA_RUNTIME_LIBRARY_CLASSES)"
+        BOOTCLASSPATH="${BUILD_JAVA_RUNTIME_LIBRARY_CLASSES}"
         ;;
 esac
 AC_SUBST(BOOTCLASSPATH)
diff --git a/m4/opagent.m4 b/m4/opagent.m4
new file mode 100644 (file)
index 0000000..5b55961
--- /dev/null
@@ -0,0 +1,58 @@
+dnl m4/opagent.m4
+dnl
+dnl Copyright (C) 2008
+dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+dnl 
+dnl This file is part of CACAO.
+dnl 
+dnl This program is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU General Public License as
+dnl published by the Free Software Foundation; either version 2, or (at
+dnl your option) any later version.
+dnl 
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+dnl 02110-1301, USA.
+
+dnl check if opagent library should be used
+
+AC_DEFUN([AC_CHECK_ENABLE_OPAGENT],[
+AC_ARG_WITH([opagent-includedir],
+            [AS_HELP_STRING(--with-opagent-includedir=<path>,location of opagent header files [[default=/usr/include]])],
+            [OPAGENT_CFLAGS=-I"${withval}"],
+            [])
+AC_SUBST(OPAGENT_CFLAGS)
+
+AC_ARG_WITH([opagent-libdir],
+            [AS_HELP_STRING(--with-opagent-libdir=<path>,location of opagent library [[default=/usr/lib/oprofile]])],
+            [OPAGENT_LDFLAGS=-L"${withval}"],
+            [OPAGENT_LDFLAGS=-L/usr/lib/oprofile])
+AC_SUBST(OPAGENT_LDFLAGS)
+
+AC_MSG_CHECKING(whether Oprofile opagent support code should be compiled)
+AC_ARG_ENABLE([opagent],
+              [AS_HELP_STRING(--enable-opagent,enable opagent library support [[default=disabled]])],
+              [case "${enableval}" in
+                  yes) ENABLE_OPAGENT=yes;;
+                  *) ENABLE_OPAGENT=no;;
+               esac],
+              [ENABLE_OPAGENT=no])
+AC_MSG_RESULT(${ENABLE_OPAGENT})
+
+if test x"${ENABLE_OPAGENT}" = "xyes"; then
+    CFLAGS="$CFLAGS $OPAGENT_CFLAGS"
+    CPPFLAGS="$CPPFLAGS $OPAGENT_CFLAGS"
+    LDFLAGS="$LDFLAGS $OPAGENT_LDFLAGS"
+    AC_CHECK_HEADERS([opagent.h],, [AC_MSG_ERROR(cannot find opagent.h)])
+    AC_CHECK_LIB(opagent, op_open_agent,, [AC_MSG_ERROR(cannot find libopagent)])
+    AC_DEFINE([ENABLE_OPAGENT], 1, [use opagent])
+fi
+AM_CONDITIONAL([ENABLE_OPAGENT], [test x"${ENABLE_OPAGENT}" = "xyes"])
+])
+
index b2cb8bf2aec61d7f8be3544a1bc6438da5a63e88..b1bf2b10609d14a455453926493e4c9dd795cd6b 100644 (file)
@@ -23,7 +23,6 @@
 
 DIST_SUBDIRS = \
        cacao \
-       cacaoh \
        classes \
        fdlibm \
        mm \
@@ -31,21 +30,18 @@ DIST_SUBDIRS = \
        scripts \
        threads \
        toolbox \
-       vm \
-       vmcore
+       vm
 
 # DON'T CHANGE THIS ORDER!!!
 
 SUBDIRS = \
-       toolbox \
-       vmcore \
-       cacaoh \
        classes \
-       native \
        fdlibm \
+       toolbox \
        mm \
-       threads \
        vm \
+       threads \
+       native \
        cacao \
        scripts
 
index d804c994f6a93acd64b53968518b2b316bb892ca..0f59f3228b95e4d90472c359f992b8cae152cd2a 100644 (file)
@@ -35,11 +35,17 @@ lib_LTLIBRARIES = \
        libjvm.la
 
 libjvm_la_LDFLAGS = \
-       -version-info 1:0:0
+       -avoid-version
 
 if WITH_JAVA_RUNTIME_LIBRARY_OPENJDK
+if WITH_GNU_LD
 libjvm_la_LDFLAGS += \
        -Xlinker --version-script=$(top_srcdir)/contrib/mapfile-vers-product
+else
+# This is for the Solaris LD.
+libjvm_la_LDFLAGS += \
+       -Xlinker -M$(top_srcdir)/contrib/mapfile-vers-product
+endif
 endif
 
 cacao_LDFLAGS += \
@@ -80,14 +86,13 @@ libjvm_la_LIBADD = \
        $(top_builddir)/src/threads/libthreads.la \
        $(top_builddir)/src/toolbox/libtoolbox.la \
        $(top_builddir)/src/vm/libvm.la \
-       $(top_builddir)/src/vmcore/libvmcore.la \
        $(GC_LIB)
 
 bin_PROGRAMS = \
        cacao
 
 cacao_SOURCES = \
-       cacao.c
+       cacao.cpp
 
 cacao_LDADD = \
        $(CACAO_LIBS)
diff --git a/src/cacao/cacao.c b/src/cacao/cacao.c
deleted file mode 100644 (file)
index c65a890..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/* src/cacao/cacao.c - contains main() of cacao
-
-   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>
-
-#if defined(ENABLE_JRE_LAYOUT)
-# include <errno.h>
-# include <libgen.h>
-# include <unistd.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#if defined(ENABLE_JVMTI)
-# include "native/jvmti/jvmti.h"
-# include "native/jvmti/cacaodbg.h"
-# include "threads/mutex.h"
-#endif
-
-#include "vmcore/system.h"
-
-#include "vm/vm.h"
-
-
-/* Defines. *******************************************************************/
-
-#define LIBJVM_NAME    NATIVE_LIBRARY_PREFIX"jvm"NATIVE_LIBRARY_SUFFIX
-
-
-/* forward declarations *******************************************************/
-
-static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv);
-
-
-/* main ************************************************************************
-
-   The main program.
-   
-*******************************************************************************/
-
-int main(int argc, char **argv)
-{
-#if defined(ENABLE_LIBJVM)
-       char*       path;
-
-# if defined(ENABLE_JRE_LAYOUT)
-       int         len;
-# endif
-#endif
-
-#if defined(ENABLE_LIBJVM)     
-       /* Variables for JNI_CreateJavaVM dlopen call. */
-       void*       libjvm_handle;
-       void*       libjvm_vm_createjvm;
-       void*       libjvm_vm_run;
-       const char* lterror;
-
-       bool (*vm_createjvm)(JavaVM **, void **, void *);
-       void (*vm_run)(JavaVM *, JavaVMInitArgs *);
-#endif
-
-       JavaVM         *vm;                 /* denotes a Java VM                  */
-       JNIEnv         *env;
-       JavaVMInitArgs *vm_args;
-
-       /* prepare the options */
-
-       vm_args = cacao_options_prepare(argc, argv);
-       
-       /* load and initialize a Java VM, return a JNI interface pointer in env */
-
-#if defined(ENABLE_LIBJVM)
-# if defined(ENABLE_JRE_LAYOUT)
-       /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
-
-       path = malloc(sizeof(char) * 4096);
-
-       if (readlink("/proc/self/exe", path, 4095) == -1) {
-               fprintf(stderr, "main: readlink failed: %s\n", strerror(errno));
-               abort();
-       }
-
-       /* get the path of the current executable */
-
-       path = dirname(path);
-       len  = strlen(path) + strlen("/../lib/"LIBJVM_NAME) + strlen("0");
-
-       if (len > 4096) {
-               fprintf(stderr, "main: libjvm name to long for buffer\n");
-               abort();
-       }
-
-       /* concatinate the library name */
-
-       strcat(path, "/../lib/"LIBJVM_NAME);
-# else
-       path = CACAO_LIBDIR"/"LIBJVM_NAME;
-# endif
-
-       /* First try to open where dlopen searches, e.g. LD_LIBRARY_PATH.
-          If not found, try the absolute path. */
-
-       libjvm_handle = system_dlopen(LIBJVM_NAME, RTLD_LAZY);
-
-       if (libjvm_handle == NULL) {
-               /* save the error message */
-
-               lterror = strdup(system_dlerror());
-
-               libjvm_handle = system_dlopen(path, RTLD_LAZY);
-
-               if (libjvm_handle == NULL) {
-                       /* print the first error message too */
-
-                       fprintf(stderr, "main: system_dlopen failed: %s\n", lterror);
-
-                       /* and now the current one */
-
-                       fprintf(stderr, "main: system_dlopen failed: %s\n",
-                                       system_dlerror());
-                       abort();
-               }
-
-               /* free the error string */
-
-               free((void *) lterror);
-       }
-
-       libjvm_vm_createjvm = system_dlsym(libjvm_handle, "vm_createjvm");
-
-       if (libjvm_vm_createjvm == NULL) {
-               fprintf(stderr, "main: lt_dlsym failed: %s\n", system_dlerror());
-               abort();
-       }
-
-       vm_createjvm =
-               (bool (*)(JavaVM **, void **, void *)) (ptrint) libjvm_vm_createjvm;
-#endif
-
-       /* create the Java VM */
-
-       (void) vm_createjvm(&vm, (void *) &env, vm_args);
-
-#if defined(ENABLE_JVMTI)
-       mutex_init(&dbgcomlock);
-       if (jvmti) jvmti_set_phase(JVMTI_PHASE_START);
-#endif
-
-#if defined(ENABLE_LIBJVM)
-       libjvm_vm_run = system_dlsym(libjvm_handle, "vm_run");
-
-       if (libjvm_vm_run == NULL) {
-               fprintf(stderr, "main: system_dlsym failed: %s\n", system_dlerror());
-               abort();
-       }
-
-       vm_run = (void (*)(JavaVM *, JavaVMInitArgs *)) (ptrint) libjvm_vm_run;
-#endif
-
-       /* run the VM */
-
-       vm_run(vm, vm_args);
-
-       /* keep compiler happy */
-
-       return 0;
-}
-
-
-/* cacao_options_prepare *******************************************************
-
-   Prepare the JavaVMInitArgs.
-
-*******************************************************************************/
-
-static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv)
-{
-       JavaVMInitArgs *vm_args;
-       s4              i;
-
-       vm_args = malloc(sizeof(JavaVMInitArgs));
-
-       vm_args->version            = JNI_VERSION_1_2;
-       vm_args->nOptions           = argc - 1;
-       vm_args->options            = malloc(sizeof(JavaVMOption) * argc);
-       vm_args->ignoreUnrecognized = JNI_FALSE;
-
-       for (i = 1; i < argc; i++)
-               vm_args->options[i - 1].optionString = argv[i];
-
-       return vm_args;
-}
-
-
-/*
- * 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/cacao/cacao.cpp b/src/cacao/cacao.cpp
new file mode 100644 (file)
index 0000000..e1ad416
--- /dev/null
@@ -0,0 +1,230 @@
+/* src/cacao/cacao.cpp - contains main() of cacao
+
+   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>
+
+#if defined(ENABLE_JRE_LAYOUT)
+# include <errno.h>
+# include <libgen.h>
+# include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JVMTI)
+# include "native/jvmti/jvmti.h"
+# include "native/jvmti/cacaodbg.h"
+#endif
+
+#include "vm/os.hpp"
+#include "vm/vm.hpp"
+
+
+/* Defines. *******************************************************************/
+
+#define LIBJVM_NAME    NATIVE_LIBRARY_PREFIX"jvm"NATIVE_LIBRARY_SUFFIX
+
+
+/* forward declarations *******************************************************/
+
+static JavaVMInitArgs* prepare_options(int argc, char** argv);
+
+
+/* main ************************************************************************
+
+   The main program.
+   
+*******************************************************************************/
+
+int main(int argc, char **argv)
+{
+#if defined(ENABLE_LIBJVM)
+       char* path;
+
+# if defined(ENABLE_JRE_LAYOUT)
+       int         len;
+# endif
+#endif
+
+#if defined(ENABLE_LIBJVM)     
+       /* Variables for JNI_CreateJavaVM dlopen call. */
+       void*       libjvm_handle;
+       void*       libjvm_VM_create;
+       void*       libjvm_vm_run;
+       const char* lterror;
+
+       bool (*VM_create)(JavaVM **, void **, void *);
+       void (*vm_run)(JavaVM *, JavaVMInitArgs *);
+#endif
+
+       JavaVM         *vm;                 /* denotes a Java VM                  */
+       JNIEnv         *env;
+       JavaVMInitArgs *vm_args;
+
+       /* prepare the options */
+
+       vm_args = prepare_options(argc, argv);
+       
+       /* load and initialize a Java VM, return a JNI interface pointer in env */
+
+#if defined(ENABLE_LIBJVM)
+# if defined(ENABLE_JRE_LAYOUT)
+       /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
+
+       path = (char*) os::malloc(sizeof(char) * 4096);
+
+       if (readlink("/proc/self/exe", path, 4095) == -1) {
+               fprintf(stderr, "main: readlink failed: %s\n", strerror(errno));
+               os::abort();
+       }
+
+       /* get the path of the current executable */
+
+       path = os::dirname(path);
+       len  = os::strlen(path) + os::strlen("/../lib/"LIBJVM_NAME) + os::strlen("0");
+
+       if (len > 4096) {
+               fprintf(stderr, "main: libjvm name to long for buffer\n");
+               os::abort();
+       }
+
+       /* concatinate the library name */
+
+       strcat(path, "/../lib/"LIBJVM_NAME);
+# else
+       path = (char*) CACAO_LIBDIR"/"LIBJVM_NAME;
+# endif
+
+       /* First try to open where dlopen searches, e.g. LD_LIBRARY_PATH.
+          If not found, try the absolute path. */
+
+       libjvm_handle = os::dlopen(LIBJVM_NAME, RTLD_NOW);
+
+       if (libjvm_handle == NULL) {
+               /* save the error message */
+
+               lterror = strdup(os::dlerror());
+
+               libjvm_handle = os::dlopen(path, RTLD_NOW);
+
+               if (libjvm_handle == NULL) {
+                       /* print the first error message too */
+
+                       fprintf(stderr, "main: os::dlopen failed: %s\n", lterror);
+
+                       /* and now the current one */
+
+                       fprintf(stderr, "main: os::dlopen failed: %s\n", os::dlerror());
+                       os::abort();
+               }
+
+               /* free the error string */
+
+               free((void *) lterror);
+       }
+
+       libjvm_VM_create = os::dlsym(libjvm_handle, "VM_create");
+
+       if (libjvm_VM_create == NULL) {
+               fprintf(stderr, "main: lt_dlsym failed: %s\n", os::dlerror());
+               os::abort();
+       }
+
+       VM_create =
+               (bool (*)(JavaVM **, void **, void *)) (ptrint) libjvm_VM_create;
+#endif
+
+       /* create the Java VM */
+
+       (void) VM_create(&vm, (void**) &env, vm_args);
+
+#if defined(ENABLE_JVMTI)
+# error This should be a JVMTI function.
+       Mutex_init(&dbgcomlock);
+       if (jvmti) jvmti_set_phase(JVMTI_PHASE_START);
+#endif
+
+#if defined(ENABLE_LIBJVM)
+       libjvm_vm_run = os::dlsym(libjvm_handle, "vm_run");
+
+       if (libjvm_vm_run == NULL) {
+               fprintf(stderr, "main: os::dlsym failed: %s\n", os::dlerror());
+               os::abort();
+       }
+
+       vm_run = (void (*)(JavaVM *, JavaVMInitArgs *)) (ptrint) libjvm_vm_run;
+#endif
+
+       /* run the VM */
+
+       vm_run(vm, vm_args);
+
+       /* keep compiler happy */
+
+       return 0;
+}
+
+
+/**
+ * Prepare the JavaVMInitArgs structure.
+ */
+static JavaVMInitArgs* prepare_options(int argc, char** argv)
+{
+       JavaVMInitArgs* vm_args;
+
+       vm_args = (JavaVMInitArgs*) malloc(sizeof(JavaVMInitArgs));
+
+       vm_args->version            = JNI_VERSION_1_2;
+       vm_args->nOptions           = argc - 1;
+       vm_args->options            = (JavaVMOption*) malloc(sizeof(JavaVMOption) * argc);
+       vm_args->ignoreUnrecognized = JNI_FALSE;
+
+       for (int i = 1; i < argc; i++)
+               vm_args->options[i - 1].optionString = argv[i];
+
+       return vm_args;
+}
+
+
+/*
+ * 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/cacaoh/Makefile.am b/src/cacaoh/Makefile.am
deleted file mode 100644 (file)
index 7ab1d64..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-## src/cacaoh/Makefile.am
-##
-## 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.
-
-
-AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR)
-
-if ENABLE_RT_TIMING
-cacaoh_LDFLAGS = -lrt
-endif
-
-noinst_LTLIBRARIES = \
-       libcacaoh.la
-
-libcacaoh_la_SOURCES = \
-       dummy.c \
-       headers.c \
-       headers.h
-
-libcacaoh_la_LIBADD = \
-       $(top_builddir)/src/toolbox/libtoolbox.la \
-       $(top_builddir)/src/vmcore/libvmcore.la
-
-noinst_PROGRAMS = \
-       cacaoh
-
-cacaoh_SOURCES = \
-       cacaoh.c
-
-cacaoh_LDADD = \
-       libcacaoh.la
-
-cacaoh_DEPENDENCIES = \
-       $(cacaoh_LDADD)
-
-
-## Local variables:
-## mode: Makefile
-## indent-tabs-mode: t
-## c-basic-offset: 4
-## tab-width: 8
-## compile-command: "automake --add-missing"
-## End:
diff --git a/src/cacaoh/cacaoh.c b/src/cacaoh/cacaoh.c
deleted file mode 100644 (file)
index 0f1e8ed..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-/* src/cacaoh/cacaoh.c - main for header generation (cacaoh)
-
-   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 "cacaoh/headers.h"
-
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#include "toolbox/hashtable.h"
-#include "toolbox/logging.h"
-
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/classcache.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-#include "vmcore/suck.h"
-
-
-/* define cacaoh options ******************************************************/
-
-enum {
-       OPT_HELP,
-       OPT_VERSION,
-       OPT_VERBOSE,
-       OPT_DIRECTORY,
-       OPT_CLASSPATH,
-       OPT_BOOTCLASSPATH,
-
-       DUMMY
-};
-
-
-opt_struct opts[] = {
-       { "help",             false, OPT_HELP          },
-       { "version",          false, OPT_VERSION       },
-       { "verbose",          false, OPT_VERBOSE       },
-       { "d",                true,  OPT_DIRECTORY     },
-       { "classpath",        true,  OPT_CLASSPATH     },
-       { "bootclasspath",    true,  OPT_BOOTCLASSPATH },
-       { NULL,               false, 0                 }
-};
-
-
-/* usage ***********************************************************************
-
-   Obviously prints usage information of cacaoh.
-
-*******************************************************************************/
-
-void usage(void)
-{
-       printf("Usage: cacaoh [options] <classes>\n"
-                  "\n"
-                  "Options:\n"
-                  "    -help                 Print this message\n"
-                  "    -classpath <path>     \n"
-                  "    -bootclasspath <path> \n"
-                  "    -d <dir>              Output directory\n"
-                  "    -version              Print version information\n"
-                  "    -verbose              Enable verbose output\n");
-
-       /* exit with error code */
-
-       exit(1);
-}
-
-
-/* version *********************************************************************
-
-   Prints cacaoh version information.
-
-*******************************************************************************/
-
-static void version(void)
-{
-       printf("cacaoh version "VERSION"\n");
-       printf("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,\n");
-       printf("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,\n");
-       printf("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,\n");
-       printf("J. Wenninger, Institut f. Computersprachen - TU Wien\n\n");
-
-       printf("This program is free software; you can redistribute it and/or\n");
-       printf("modify it under the terms of the GNU General Public License as\n");
-       printf("published by the Free Software Foundation; either version 2, or (at\n");
-       printf("your option) any later version.\n\n");
-
-       printf("This program is distributed in the hope that it will be useful, but\n");
-       printf("WITHOUT ANY WARRANTY; without even the implied warranty of\n");
-       printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n");
-       printf("General Public License for more details.\n");
-
-       exit(0);
-}
-
-
-/* forward declarations *******************************************************/
-
-static JavaVMInitArgs *cacaoh_options_prepare(int argc, char **argv);
-
-
-/* main ************************************************************************
-
-   Main program.
-   
-*******************************************************************************/
-
-int main(int argc, char **argv)
-{
-       JavaVMInitArgs *vm_args;
-       s4 i, j;
-       s4 opt;
-       classinfo *c;
-       char *opt_directory;
-
-       /********** internal (only used by main) *****************************/
-   
-       char *bootclasspath;
-       char *classpath;
-       char *cp;
-       s4    cplen;
-
-       if (argc < 2)
-               usage();
-
-       /* set the bootclasspath */
-
-       cp = getenv("BOOTCLASSPATH");
-
-       if (cp) {
-               bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
-               strcpy(bootclasspath, cp);
-       }
-       else {
-               cplen =
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-                       strlen(CACAO_VM_ZIP) +
-                       strlen(":") +
-#endif
-                       strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
-                       strlen("0");
-
-               bootclasspath = MNEW(char, cplen);
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-               strcat(bootclasspath, CACAO_VM_ZIP);
-               strcat(bootclasspath, ":");
-#endif
-               strcat(bootclasspath, JAVA_RUNTIME_LIBRARY_CLASSES);
-       }
-
-
-       /* set the classpath */
-
-       cp = getenv("CLASSPATH");
-
-       if (cp != NULL) {
-               classpath = MNEW(char, strlen(cp) + strlen("0"));
-               strcat(classpath, cp);
-       }
-       else {
-               classpath = MNEW(char, strlen(".") + strlen("0"));
-               strcpy(classpath, ".");
-       }
-
-
-       /* initialize options with default values */
-
-       opt_verbose = false;
-       opt_directory = NULL;
-
-
-       /* parse the options ******************************************************/
-
-       vm_args = cacaoh_options_prepare(argc, argv);
-
-       while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
-               switch (opt) {
-               case OPT_IGNORE:
-                       break;
-
-               case OPT_HELP:
-                       usage();
-                       break;
-
-               case OPT_CLASSPATH:
-                       /* forget old classpath and set the argument as new classpath */
-                       MFREE(classpath, char, strlen(classpath));
-
-                       classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
-                       strcpy(classpath, opt_arg);
-                       break;
-
-               case OPT_BOOTCLASSPATH:
-                       /* Forget default bootclasspath and set the argument as
-                          new boot classpath. */
-                       MFREE(bootclasspath, char, strlen(bootclasspath));
-
-                       bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
-                       strcpy(bootclasspath, opt_arg);
-                       break;
-
-               case OPT_DIRECTORY:
-                       opt_directory = MNEW(char, strlen(opt_arg) + strlen("0"));
-                       strcpy(opt_directory, opt_arg);
-                       break;
-
-               case OPT_VERSION:
-                       version();
-                       break;
-
-               case OPT_VERBOSE:
-                       opt_verbose = true;
-                       loadverbose = true;
-                       break;
-
-               default:
-                       usage();
-               }
-       }
-                       
-       /**************************** Program start **************************/
-
-       if (opt_verbose) {
-               log_init(NULL);
-               log_println("Java - header-generator started"); 
-       }
-
-       utf8_init();
-
-       /* initialize the classcache hashtable stuff: lock, hashtable
-          (must be done _after_ threads_preinit) */
-
-       if (!classcache_init())
-               vm_abort("classcache_init failed\n");
-
-       /* initialize the loader with bootclasspath (must be done _after_
-          thread_preinit) */
-
-       if (!suck_init())
-               vm_abort("suck_init failed\n");
-
-       suck_add(bootclasspath);
-
-       /* Also add the normal classpath, so the bootstrap class loader
-          can find the files. */
-
-       suck_add(classpath);
-
-       /* AFTER: classcache_init */
-
-       loader_preinit();
-       loader_init();
-
-
-       /* load Java classes ******************************************************/
-       
-       for (i = opt_index; i < vm_args->nOptions; i++) {
-               cp = vm_args->options[i].optionString;
-
-               /* convert classname */
-
-               for (j = strlen(cp) - 1; j >= 0; j--) {
-                       switch (cp[j]) {
-                       case '.':
-                               cp[j] = '/';
-                               break;
-                       case '_':
-                               cp[j] = '$';
-                               break;
-                       }
-               }
-       
-               /* exceptions are catched with new_exception call */
-
-               if (!(c = load_class_bootstrap(utf_new_char(cp))))
-                       vm_abort("java.lang.NoClassDefFoundError: %s\n", cp);
-
-               if (!link_class(c))
-                       vm_abort("java.lang.LinkageError: %s\n", cp);
-
-               headerfile_generate(c, opt_directory);
-       }
-
-       /************************ Release all resources **********************/
-
-       loader_close();
-
-       if (opt_verbose) {
-               log_println("Java - header-generator stopped");
-#if defined(ENABLE_STATISTICS)
-               statistics_print_memory_usage();
-#endif
-       }
-       
-       return 0;
-}
-
-
-/* cacaoh_options_prepare ******************************************************
-
-   Prepare the JavaVMInitArgs.
-
-*******************************************************************************/
-
-static JavaVMInitArgs *cacaoh_options_prepare(int argc, char **argv)
-{
-       JavaVMInitArgs *vm_args;
-       s4              i;
-
-       vm_args = NEW(JavaVMInitArgs);
-
-       vm_args->nOptions = argc - 1;
-       vm_args->options  = MNEW(JavaVMOption, argc);
-
-       for (i = 1; i < argc; i++)
-               vm_args->options[i - 1].optionString = argv[i];
-
-       return vm_args;
-}
-
-
-/*
- * 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/cacaoh/dummy.c b/src/cacaoh/dummy.c
deleted file mode 100644 (file)
index 90168f7..0000000
+++ /dev/null
@@ -1,865 +0,0 @@
-/* src/cacaoh/dummy.c - dummy functions for cacaoh
-
-   Copyright (C) 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 <errno.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/primitive.h"
-#include "vm/vm.h"
-
-#include "vm/jit/code.h"
-
-#include "vmcore/class.h"
-#include "vmcore/classcache.h"
-#include "vmcore/field.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-#include "vmcore/utf8.h"
-#include "vmcore/system.h"
-
-
-/* global variables ***********************************************************/
-
-bool  vm_initializing = true;
-char *_Jv_bootclasspath;
-
-
-java_handle_t *javastring_new_slash_to_dot(utf *u)
-{
-       vm_abort("javastring_new_slash_to_dot");
-
-       return NULL;
-}
-
-
-/* access *********************************************************************/
-
-bool access_is_accessible_class(classinfo *referer, classinfo *cls)
-{
-       return true;
-}
-
-bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
-                                                                int32_t memberflags)
-{
-       vm_abort("access_is_accessible_member");
-
-       return true;
-}
-
-
-/* array **********************************************************************/
-
-java_handle_t *array_objectarray_element_get(java_handle_objectarray_t *a, int32_t index)
-{
-       java_handle_t *value;
-       int32_t        size;
-
-       if (a == NULL) {
-               log_println("array_objectarray_element_get(a=%p, index=%d): NullPointerException", a, index);
-               return NULL;
-       }
-
-       size = LLNI_array_size(a);
-
-       if ((index < 0) || (index > size)) {
-               log_println("array_objectarray_element_get(a=%p, index=%d): ArrayIndexOutOfBoundsException", a, index);
-               return NULL;
-       }
-
-       value = LLNI_WRAP(LLNI_array_direct(a, index));
-
-       return value;
-}
-
-void array_objectarray_element_set(java_handle_objectarray_t *a, int32_t index, java_handle_t *value)
-{
-       int32_t size;
-
-       if (a == NULL) {
-               log_println("array_objectarray_element_set(a=%p, index=%d): NullPointerException", a, index);
-               return;
-       }
-
-       size = LLNI_array_size(a);
-
-       if ((index < 0) || (index > size)) {
-               log_println("array_objectarray_element_set(a=%p, index=%d): ArrayIndexOutOfBoundsException", a, index);
-               return;
-       }
-
-       LLNI_array_direct(a, index) = LLNI_UNWRAP(value);
-}
-
-int32_t array_length_get(java_handle_t *a)
-{
-       if (a == NULL) {
-               log_println("array_length_get(a=%p): NullPointerException", a);
-               return 0;
-       }
-
-       return LLNI_array_size(a);
-}
-
-
-/* asm ************************************************************************/
-
-void asm_abstractmethoderror(void)
-{
-       abort();
-}
-
-void intrp_asm_abstractmethoderror(void)
-{
-       abort();
-}
-
-
-/* builtin ********************************************************************/
-
-java_handle_t *builtin_clone(void *env, java_handle_t *o)
-{
-       vm_abort("builtin_clone: Not implemented.");
-       return NULL;
-}
-
-bool builtin_isanysubclass(classinfo *sub, classinfo *super)
-{
-       vm_abort("builtin_isanysubclass: Not implemented.");
-       return 0;
-}
-
-bool builtin_instanceof(java_handle_t *o, classinfo *class)
-{
-       vm_abort("builtin_instanceof: Not implemented.");
-       return 0;
-}
-
-java_handle_t *builtin_new(classinfo *c)
-{
-       vm_abort("builtin_new: Not implemented.");
-       return NULL;
-}
-
-java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
-{
-       java_objectarray_t *oa = (java_objectarray_t*) mem_alloc(
-               sizeof(java_array_t) + size * sizeof(java_object_t*));
-       java_handle_objectarray_t *h = (java_handle_objectarray_t*) LLNI_WRAP(
-               (java_object_t*) oa);
-
-       if (h != NULL) {
-               LLNI_array_size(h) = size;
-       }
-
-       return h;
-}
-
-java_handle_bytearray_t *builtin_newarray_byte(int32_t size)
-{
-       java_bytearray_t *ba = (java_bytearray_t*) mem_alloc(
-               sizeof(java_array_t) + size * sizeof(int8_t));
-       java_handle_bytearray_t *h = (java_handle_bytearray_t*) LLNI_WRAP(
-               (java_object_t*) ba);
-
-       if (h != NULL) {
-               LLNI_array_size(h) = size;
-       }
-       
-       return h;
-}
-
-
-/* code ***********************************************************************/
-
-void code_free_code_of_method(methodinfo *m)
-{
-}
-
-
-methodinfo *code_get_methodinfo_for_pv(void *pv)
-{
-       return NULL;
-}
-
-
-/* codegen ********************************************************************/
-
-u1 *codegen_generate_stub_compiler(methodinfo *m)
-{
-       return NULL;
-}
-
-codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
-{
-       return NULL;
-}
-
-#if defined(ENABLE_INTRP)
-u1 *intrp_createcompilerstub(methodinfo *m)
-{
-       return NULL;
-}
-#endif
-
-void removecompilerstub(u1 *stub)
-{
-}
-
-void removenativestub(u1 *stub)
-{
-}
-
-
-/* exceptions *****************************************************************/
-
-void exceptions_clear_exception(void)
-{
-}
-
-void exceptions_print_current_exception(void)
-{
-       abort();
-}
-
-void exceptions_throw_abstractmethoderror(void)
-{
-       fprintf(stderr, "java.lang.AbstractMethodError\n");
-
-       abort();
-}
-
-void exceptions_throw_classcircularityerror(classinfo *c)
-{
-       fprintf(stderr, "java.lang.ClassCircularityError: ");
-
-       utf_display_printable_ascii(c->name);
-       fputc('\n', stderr);
-
-       abort();
-}
-
-void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
-{
-       va_list ap;
-
-       fprintf(stderr, "java.lang.ClassFormatError: ");
-
-       utf_display_printable_ascii(c->name);
-       fprintf(stderr, ": ");
-
-       va_start(ap, message);
-       vfprintf(stderr, message, ap);
-       va_end(ap);
-
-       fputc('\n', stderr);
-
-       abort();
-}
-
-void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
-{
-       fprintf(stderr, "java.lang.IncompatibleClassChangeError: ");
-
-       if (c != NULL)
-               utf_fprint_printable_ascii_classname(stderr, c->name);
-
-       fputc('\n', stderr);
-
-       abort();
-}
-
-void exceptions_throw_internalerror(const char *message, ...)
-{
-       va_list ap;
-
-       fprintf(stderr, "java.lang.InternalError: ");
-
-       va_start(ap, message);
-       vfprintf(stderr, message, ap);
-       va_end(ap);
-
-       abort();
-}
-
-void exceptions_throw_linkageerror(const char *message, classinfo *c)
-{
-       fprintf(stderr, "java.lang.LinkageError: %s", message);
-
-       if (c != NULL)
-               utf_fprint_printable_ascii_classname(stderr, c->name);
-
-       fputc('\n', stderr);
-
-       abort();
-}
-
-void exceptions_throw_noclassdeffounderror(utf *name)
-{
-       fprintf(stderr, "java.lang.NoClassDefFoundError: ");
-       utf_fprint_printable_ascii(stderr, name);
-       fputc('\n', stderr);
-
-       abort();
-}
-
-void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
-{
-       fprintf(stderr, "java.lang.NoClassDefFoundError: ");
-       utf_fprint_printable_ascii(stderr, c->name);
-       fprintf(stderr, " (wrong name: ");
-       utf_fprint_printable_ascii(stderr, name);
-       fprintf(stderr, ")\n");
-
-       abort();
-}
-
-void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
-{
-       fprintf(stderr, "java.lang.VerifyError: ");
-       utf_fprint_printable_ascii(stderr, m->name);
-       fprintf(stderr, ": %s", message);
-
-       abort();
-}
-
-void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
-{
-       fprintf(stderr, "java.lang.NoSuchFieldError: ");
-       utf_fprint_printable_ascii(stderr, c->name);
-       fprintf(stderr, ".");
-       utf_fprint_printable_ascii(stderr, name);
-       fputc('\n', stderr);
-
-       abort();
-}
-
-void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
-{
-       fprintf(stderr, "java.lang.NoSuchMethodError: ");
-       utf_fprint_printable_ascii(stderr, c->name);
-       fprintf(stderr, ".");
-       utf_fprint_printable_ascii(stderr, name);
-       utf_fprint_printable_ascii(stderr, desc);
-       fputc('\n', stderr);
-
-       abort();
-}
-
-void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
-{
-       fprintf(stderr, "java.lang.UnsupportedClassVersionError: " );
-       utf_display_printable_ascii(c->name);
-       fprintf(stderr, " (Unsupported major.minor version %d.%d)\n", ma, mi);
-
-       abort();
-}
-
-void exceptions_throw_classnotfoundexception(utf *name)
-{
-       fprintf(stderr, "java.lang.ClassNotFoundException: ");
-       utf_fprint_printable_ascii(stderr, name);
-       fputc('\n', stderr);
-
-       abort();
-}
-
-void exceptions_throw_nullpointerexception(void)
-{
-       fprintf(stderr, "java.lang.NullPointerException\n");
-
-       abort();
-}
-
-
-/* finalizer ******************************************************************/
-
-void finalizer_notify(void)
-{
-       vm_abort("finalizer_notify");
-}
-
-void finalizer_run(void *o, void *p)
-{
-       vm_abort("finalizer_run");
-}
-
-
-/* gc *************************************************************************/
-
-void gc_reference_register(java_object_t **ref, int32_t reftype)
-{
-       vm_abort("gc_reference_register");
-}
-
-int64_t gc_get_heap_size(void)
-{
-       return 0;
-}
-
-int64_t gc_get_free_bytes(void)
-{
-       return 0;
-}
-
-int64_t gc_get_total_bytes(void)
-{
-       return 0;
-}
-
-int64_t gc_get_max_heap_size(void)
-{
-       return 0;
-}
-
-
-/* heap ***********************************************************************/
-
-void *heap_alloc_uncollectable(size_t bytelength)
-{
-       return calloc(bytelength, 1);
-}
-
-s4 heap_get_hashcode(java_object_t *o)
-{
-       return 0;
-}
-
-
-/* instruction ****************************************************************/
-
-methoddesc *instruction_call_site(const instruction *iptr)
-{
-       return NULL;
-}
-
-
-/* jit ************************************************************************/
-
-icmdtable_entry_t icmd_table[256] = {};
-
-void jit_invalidate_code(methodinfo *m)
-{
-       vm_abort("jit_invalidate_code");
-}
-
-
-/* llni ***********************************************************************/
-
-void llni_critical_start()
-{
-}
-
-void llni_critical_end()
-{
-}
-
-
-/* localref *******************************************************************/
-
-java_handle_t *localref_add(java_object_t *o)
-{
-#if defined(ENABLE_HANDLES)
-       java_handle_t *h = (java_handle_t*) mem_alloc(sizeof(java_handle_t));
-
-       h->heap_object = o;
-
-       return h;
-#else
-       return (java_handle_t*) o;
-#endif
-}
-
-
-/* lock ***********************************************************************/
-
-void lock_init_object_lock(java_object_t *o)
-{
-}
-
-bool lock_monitor_enter(java_handle_t *o)
-{
-       return true;
-}
-
-bool lock_monitor_exit(java_handle_t *o)
-{
-       return true;
-}
-
-
-/* md *************************************************************************/
-
-void md_param_alloc(methoddesc *md)
-{
-}
-
-void md_param_alloc_native(methoddesc *md)
-{
-}
-
-
-/* memory *********************************************************************/
-
-void *mem_alloc(int32_t size)
-{
-       /* real implementation in src/mm/memory.c clears memory */
-
-       return calloc(size, 1);
-}
-
-void *mem_realloc(void *src, int32_t len1, int32_t len2)
-{
-       return realloc(src, len2);
-}
-
-void mem_free(void *m, int32_t size)
-{
-       free(m);
-}
-
-void *dumpmemory_get(size_t size)
-{
-       return malloc(size);
-}
-
-int32_t dumpmemory_marker(void)
-{
-       return 0;
-}
-
-void dumpmemory_release(int32_t size)
-{
-}
-
-
-/* package ********************************************************************/
-
-/* void Package_add(java_handle_t *packagename) */
-void Package_add(utf *packagename)
-{
-       /* Do nothing. */
-}
-
-
-/* primitive ******************************************************************/
-
-classinfo *primitive_arrayclass_get_by_type(int type)
-{
-       return NULL;
-}
-
-classinfo *primitive_class_get_by_type(int type)
-{
-       abort();
-       return NULL;
-}
-
-classinfo *primitive_class_get_by_char(char ch)
-{
-       abort();
-       return NULL;
-}
-
-
-/* properties *****************************************************************/
-
-void properties_add(char *key, char *value)
-{
-}
-
-char *properties_get(char *key)
-{
-       return NULL;
-}
-
-
-/* reflect ********************************************************************/
-
-java_handle_t *reflect_constructor_new(fieldinfo *f)
-{
-       vm_abort("reflect_constructor_new: Not implemented.");
-       return NULL;
-}
-
-java_handle_t *reflect_field_new(fieldinfo *f)
-{
-       vm_abort("reflect_field_new: Not implemented.");
-       return NULL;
-}
-
-java_handle_t *reflect_method_new(methodinfo *m)
-{
-       vm_abort("reflect_method_new: Not implemented.");
-       return NULL;
-}
-
-
-/* resolve ********************************************************************/
-
-void resolve_handle_pending_exception(bool throwError)
-{
-       vm_abort("resolve_handle_pending_exception: Not implemented.");
-}
-
-bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
-{
-       abort();
-
-       return false;
-}
-
-/* stupid resolving implementation used by resolve_classref_or_classinfo_eager */
-/* This function does eager resolving without any access checks.               */
-
-static classinfo * dummy_resolve_class_from_name(classinfo *referer,
-                                                 utf *classname,
-                                                 bool checkaccess)
-{
-       classinfo *cls = NULL;
-       char *utf_ptr;
-       int len;
-       
-       assert(referer);
-       assert(classname);
-       
-       /* lookup if this class has already been loaded */
-
-       cls = classcache_lookup(referer->classloader, classname);
-
-       if (!cls) {
-               /* resolve array types */
-
-               if (classname->text[0] == '[') {
-                       utf_ptr = classname->text + 1;
-                       len = classname->blength - 1;
-
-                       /* classname is an array type name */
-
-                       switch (*utf_ptr) {
-                               case 'L':
-                                       utf_ptr++;
-                                       len -= 2;
-                                       /* FALLTHROUGH */
-                               case '[':
-                                       /* the component type is a reference type */
-                                       /* resolve the component type */
-                                       if ((cls = dummy_resolve_class_from_name(referer,
-                                                                          utf_new(utf_ptr,len),
-                                                                          checkaccess)) == NULL)
-                                               return NULL; /* exception */
-
-                                       /* create the array class */
-                                       cls = class_array_of(cls,false);
-                                       if (!cls)
-                                               return NULL; /* exception */
-                       }
-               }
-
-               /* load the class */
-               if (!cls) {
-                       if (!(cls = load_class_from_classloader(classname,
-                                                                                                       referer->classloader)))
-                               return false; /* exception */
-               }
-       }
-
-       /* the class is now loaded */
-       assert(cls);
-       assert(cls->state & CLASS_LOADED);
-
-       return cls;
-}
-
-
-classinfo * resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
-                                                                                               bool checkaccess)
-{
-       classinfo         *c;
-       
-       assert(cls.any);
-
-       if (IS_CLASSREF(cls)) {
-               /* we must resolve this reference */
-
-               if ((c = dummy_resolve_class_from_name(cls.ref->referer, cls.ref->name,
-                                                                                  checkaccess)) == NULL)
-                       return NULL;
-       }
-       else {
-               /* cls has already been resolved */
-               c = cls.cls;
-       }
-
-       assert(c);
-       assert(c->state & CLASS_LOADED);
-
-       /* succeeded */
-       return c;
-}
-
-
-/* stacktrace *****************************************************************/
-
-java_handle_objectarray_t *stacktrace_getClassContext()
-{
-       return NULL;
-}
-
-
-/* threads ********************************************************************/
-
-#if defined(HAVE___THREAD)
-__thread threadobject *thread_current;
-#else
-#include <pthread.h>
-pthread_key_t thread_current_key;
-#endif
-
-intptr_t threads_get_current_tid(void)
-{
-       return 0;
-}
-
-void threads_cast_stopworld(void)
-{
-}
-
-void threads_cast_startworld(void)
-{
-}
-
-
-/* vm *************************************************************************/
-
-void vm_printconfig(void)
-{
-}
-
-void vm_abort(const char *text, ...)
-{
-       va_list ap;
-
-       va_start(ap, text);
-       vfprintf(stderr, text, ap);
-       va_end(ap);
-
-       system_abort();
-}
-
-void vm_abort_errno(const char *text, ...)
-{
-       va_list ap;
-
-       va_start(ap, text);
-       vm_abort_errnum(errno, text, ap);
-       va_end(ap);
-}
-
-void vm_abort_errnum(int errnum, const char *text, ...)
-{
-       va_list ap;
-
-       log_start();
-
-       va_start(ap, text);
-       log_vprint(text, ap);
-       va_end(ap);
-
-       log_print(": %s", system_strerror(errnum));
-       log_finish();
-
-       system_abort();
-}
-
-java_handle_t *vm_call_method(methodinfo *m, java_handle_t *o, ...)
-{
-       return NULL;
-}
-
-
-/* XXX */
-
-void stringtable_update(void)
-{
-       log_println("stringtable_update: REMOVE ME!");
-}
-
-java_object_t *literalstring_new(utf *u)
-{
-       log_println("literalstring_new: REMOVE ME!");
-
-       return NULL;
-}
-
-
-void print_dynamic_super_statistics(void)
-{
-}
-
-
-#if defined(ENABLE_VMLOG)
-void vmlog_cacao_set_prefix(const char *arg)
-{
-}
-
-void vmlog_cacao_set_stringprefix(const char *arg)
-{
-}
-
-void vmlog_cacao_set_ignoreprefix(const char *arg)
-{
-}
-#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/cacaoh/headers.c b/src/cacaoh/headers.c
deleted file mode 100644 (file)
index e8a2951..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-/* src/cacaoh/headers.c - functions for header generation
-
-   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 <ctype.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(ENABLE_THREADS)
-# if defined(__DARWIN__)
-#  include <signal.h>
-# endif
-# include <ucontext.h>
-#endif
-
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#include "toolbox/chain.h"
-#include "toolbox/logging.h"
-
-#include "vm/builtin.h"
-#include "vm/global.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
-
-/************************ global variables **********************/
-
-#define ACC_NATIVELY_OVERLOADED    0x10000000
-
-#if defined(ENABLE_HANDLES)
-# define HEAP_PREFIX "heap_"
-#else
-# define HEAP_PREFIX ""
-#endif
-
-chain *ident_chain;     /* chain with method and field names in current class */
-FILE *file = NULL;
-static uint32_t outputsize;
-static bool dopadding;
-
-
-static void printIDpart(int c)
-{
-       if ((c >= 'a' && c <= 'z') ||
-               (c >= 'A' && c <= 'Z') ||
-               (c >= '0' && c <= '9') ||
-               (c == '_'))
-               putc(c, file);
-       else
-               putc('_', file);
-}
-
-
-void printID(utf *u)
-{
-       char *utf_ptr = u->text;
-       int i;
-
-       for (i = 0; i < utf_get_number_of_u2s(u); i++) 
-               printIDpart(utf_nextu2(&utf_ptr));
-}
-
-
-static void addoutputsize(int len)
-{
-       uint32_t newsize;
-       int32_t  i;
-
-       if (!dopadding)
-               return;
-
-       newsize = MEMORY_ALIGN(outputsize, len);
-       
-       for (i = outputsize; i < newsize; i++)
-               fprintf(file, "   uint8_t pad%d\n", (int) i);
-
-       outputsize = newsize;
-}
-
-
-void printOverloadPart(utf *desc)
-{
-       char *utf_ptr=desc->text;
-       uint16_t c;
-
-       fprintf(file, "__");
-
-       while ((c = utf_nextu2(&utf_ptr)) != ')') {
-               switch (c) {
-               case 'I':
-               case 'S':
-               case 'B':
-               case 'C':
-               case 'Z':
-               case 'J':
-               case 'F':
-               case 'D': 
-                       fprintf(file, "%c", (char) c);
-                       break;
-               case '[':
-                       fprintf(file, "_3");
-                       break;
-               case 'L':
-                       putc('L', file);
-                       while ((c = utf_nextu2(&utf_ptr)) != ';')
-                               printIDpart(c);
-                       fprintf(file, "_2");
-                       break;
-               case '(':
-                       break;
-               default: 
-                       log_text("invalid method descriptor");
-                       assert(0);
-               }
-       }
-}
-
-static char *printtype(char *utf_ptr, char *prefix, char *infix)
-{
-       uint16_t c;
-
-       switch (utf_nextu2(&utf_ptr)) {
-       case 'V':
-               fprintf(file, "void");
-               break;
-       case 'I':
-       case 'S':
-       case 'B':
-       case 'C':
-       case 'Z':
-               addoutputsize(4);
-               fprintf(file, "int32_t");
-               break;
-       case 'J':
-               addoutputsize(8);
-               fprintf(file, "int64_t");
-               break;
-       case 'F':
-               addoutputsize(4);
-               fprintf(file, "float");
-               break;
-       case 'D':
-               addoutputsize(8);
-               fprintf(file, "double");
-               break;
-       case '[':
-               addoutputsize ( sizeof(java_array_t*) ); 
-               switch (utf_nextu2(&utf_ptr)) {
-               case 'I':  fprintf (file, "java%s_intarray_t*", infix); break;
-               case 'J':  fprintf (file, "java%s_longarray_t*", infix); break;
-               case 'Z':  fprintf (file, "java%s_booleanarray_t*", infix); break;
-               case 'B':  fprintf (file, "java%s_bytearray_t*", infix); break;
-               case 'S':  fprintf (file, "java%s_shortarray_t*", infix); break;
-               case 'C':  fprintf (file, "java%s_chararray_t*", infix); break;
-               case 'F':  fprintf (file, "java%s_floatarray_t*", infix); break;
-               case 'D':  fprintf (file, "java%s_doublearray_t*", infix); break;
-                               
-               case '[': fprintf(file, "java%s_objectarray_t*", infix);
-                       while ((c = utf_nextu2(&utf_ptr)) == '[');
-                       if (c == 'L')
-                               while (utf_nextu2(&utf_ptr) != ';');
-                       break;
-                           
-               case 'L':  fprintf(file, "java%s_objectarray_t*", infix);
-                       while (utf_nextu2(&utf_ptr) != ';');
-                       break;
-               default:
-                       log_text("invalid type descriptor");
-                       assert(0);
-               }
-               break;
-               
-       case 'L': 
-               addoutputsize ( sizeof(java_object_t*));
-               fprintf (file, "struct %s", prefix);
-               while ( (c = utf_nextu2(&utf_ptr)) != ';' ) printIDpart (c);     
-               fprintf (file, "*");
-               break;
-                                       
-       default:
-               log_text("Unknown type in field descriptor");
-               assert(0);
-       }
-       
-       return utf_ptr;
-}
-
-
-/***** determine the number of entries of a utf string in the ident chain *****/
-
-static int searchidentchain_utf(utf *ident) 
-{
-       utf *u = chain_first(ident_chain);     /* first element of list */
-       int count = 0;
-
-       while (u) {
-               if (u==ident) count++;         /* string found */
-               u = chain_next(ident_chain);   /* next element in list */ 
-       }
-
-       return count;
-}
-
-
-/************** print structure for direct access to objects ******************/
-
-static void printfields(classinfo *c)
-{
-       int32_t i;
-       fieldinfo *f;
-       int ident_count;
-       
-       if (!c) {
-               addoutputsize(sizeof(java_object_t));
-               fprintf(file, "   java_object_t header;\n");
-               return;
-       }
-               
-       printfields(c->super);
-       
-       for (i = 0; i < c->fieldscount; i++) {
-               f = &(c->fields[i]);
-               
-               if (!(f->flags & ACC_STATIC)) {
-                       fprintf(file, "   ");
-                       printtype(f->descriptor->text, HEAP_PREFIX, "");
-                       fprintf(file, " ");
-                       utf_fprint_printable_ascii(file, f->name);
-
-                       /* rename multiple fieldnames */
-                       if ((ident_count = searchidentchain_utf(f->name)))
-                               fprintf(file, "%d", ident_count - 1);
-                       chain_addlast(ident_chain, f->name);    
-
-                       fprintf(file, ";\n");
-               }
-       }
-}
-
-
-/***************** store prototype for native method in file ******************/
-
-void printmethod(methodinfo *m)
-{
-       char *utf_ptr;
-       int32_t paramnum = 1;
-
-       /* search for return-type in descriptor */      
-       utf_ptr = m->descriptor->text;
-       while (utf_nextu2(&utf_ptr) != ')');
-
-       /* create remarks */
-       fprintf(file, "\n/*\n * Class:     ");
-       utf_fprint_printable_ascii(file, m->clazz->name);
-       fprintf(file, "\n * Method:    ");
-       utf_fprint_printable_ascii(file, m->name);
-       fprintf(file, "\n * Signature: ");
-       utf_fprint_printable_ascii(file, m->descriptor);
-       fprintf(file, "\n */\n");
-
-       /* create prototype */                  
-       fprintf(file, "JNIEXPORT ");
-       printtype(utf_ptr, "", "_handle");
-       fprintf(file, " JNICALL Java_");
-       printID(m->clazz->name);
-
-       chain_addlast(ident_chain, m->name);
-
-       fprintf(file, "_");
-       printID(m->name);
-
-       /* ATTENTION: We use a dummy flag here. */
-
-       if (m->flags & ACC_NATIVELY_OVERLOADED)
-               printOverloadPart(m->descriptor);
-
-       fprintf(file, "(JNIEnv *env");
-       
-       utf_ptr = m->descriptor->text + 1;
-                       
-       if (!(m->flags & ACC_STATIC)) {
-               fprintf(file, ", struct ");
-               printID(m->clazz->name);
-               fprintf(file, "* _this");
-
-       } else {
-               fprintf(file, ", jclass clazz");
-       }
-
-       if ((*utf_ptr) != ')') fprintf(file, ", ");
-                       
-       while ((*utf_ptr) != ')') {
-               utf_ptr = printtype(utf_ptr, "", "_handle");
-               fprintf(file, " par%d", paramnum++);
-               if ((*utf_ptr)!=')') fprintf(file, ", ");
-       }
-                       
-       fprintf(file, ");\n\n");
-}
-
-
-/******* remove package-name in fully-qualified classname *********************/
-
-void gen_header_filename(char *buffer, utf *u)
-{
-       int32_t i;
-  
-       for (i = 0; i < utf_get_number_of_u2s(u); i++) {
-               if ((u->text[i] == '/') || (u->text[i] == '$')) {
-                       buffer[i] = '_';  /* convert '$' and '/' to '_' */
-
-               } else {
-                       buffer[i] = u->text[i];
-               }
-       }
-       buffer[utf_get_number_of_u2s(u)] = '\0';
-}
-
-
-/* create headerfile for classes and store native methods in chain ************/
-
-void headerfile_generate(classinfo *c, char *opt_directory)
-{
-       char header_filename[1024] = "";
-       char classname[1024]; 
-       char uclassname[1024];
-       int32_t i;
-       methodinfo *m;                  
-       int32_t j;
-       methodinfo *m2;
-       bool nativelyoverloaded;
-
-       /* prevent compiler warnings */
-
-       nativelyoverloaded = false;
-
-       /* open headerfile for class */
-       gen_header_filename(classname, c->name);
-
-       /* create chain for renaming fields */
-       ident_chain = chain_new();
-       
-       if (opt_directory) {
-               sprintf(header_filename, "%s/%s.h", opt_directory, classname);
-
-       } else {
-               sprintf(header_filename, "%s.h", classname);
-       }
-
-       file = fopen(header_filename, "w");
-       if (!file) {
-               log_text("Can not open file to store header information");
-               assert(0);
-       }
-
-       fprintf(file, "/* This file is machine generated, don't edit it! */\n\n");
-
-       /* convert to uppercase */
-       for (i = 0; classname[i]; i++) {
-               uclassname[i] = toupper(classname[i]);
-       }
-       uclassname[i] = '\0';
-
-       fprintf(file, "#ifndef _%s_H\n#define _%s_H\n\n", uclassname, uclassname);
-
-       /* create structure for direct access to objects */     
-       fprintf(file, "/* Structure information for class: ");
-       utf_fprint_printable_ascii(file, c->name);
-       fprintf(file, " */\n\n");
-       fprintf(file, "typedef struct %s", HEAP_PREFIX);
-       printID(c->name);
-       fprintf(file, " {\n");
-       outputsize = 0;
-       dopadding = true;
-
-       printfields(c);
-
-       fprintf(file, "} %s", HEAP_PREFIX);
-       printID(c->name);
-       fprintf(file, ";\n\n");
-
-#if defined(ENABLE_HANDLES)
-       /* create structure for indirection cell */
-       fprintf(file, "typedef struct ");
-       printID(c->name);
-       fprintf(file, " {\n");
-       fprintf(file, "   %s", HEAP_PREFIX);
-       printID(c->name);
-       fprintf(file, " *heap_object;\n");
-       fprintf(file, "} ");
-       printID(c->name);
-       fprintf(file, ";\n\n");
-#endif
-
-       /* create chain for renaming overloaded methods */
-       chain_free(ident_chain);
-       ident_chain = chain_new();
-
-       /* create method-prototypes */
-                               
-       /* find overloaded methods */
-
-       for (i = 0; i < c->methodscount; i++) {
-               m = &(c->methods[i]);
-
-               if (!(m->flags & ACC_NATIVE))
-                       continue;
-
-               /* We use a dummy flag here. */
-
-               if (!(m->flags & ACC_NATIVELY_OVERLOADED)) {
-                       nativelyoverloaded = false;
-
-                       for (j = i + 1; j < c->methodscount; j++) {
-                               m2 = &(c->methods[j]);
-
-                               if (!(m2->flags & ACC_NATIVE))
-                                       continue;
-
-                               if (m->name == m2->name) {
-                                       m2->flags          |= ACC_NATIVELY_OVERLOADED;
-                                       nativelyoverloaded  = true;
-                               }
-                       }
-               }
-
-               if (nativelyoverloaded == true)
-                       m->flags |= ACC_NATIVELY_OVERLOADED;
-       }
-
-       for (i = 0; i < c->methodscount; i++) {
-               m = &(c->methods[i]);
-
-               if (m->flags & ACC_NATIVE)
-                       printmethod(m);
-       }
-
-       chain_free(ident_chain);
-
-       fprintf(file, "#endif\n\n");
-
-       fclose(file);
-}
-
-
-/******** print classname, '$' used to seperate inner-class name ***********/
-
-void print_classname(classinfo *clazz)
-{
-       utf *u = clazz->name;
-    char *endpos  = u->text + u->blength;
-    char *utf_ptr = u->text; 
-       uint16_t c;
-
-    while (utf_ptr < endpos) {
-               if ((c = utf_nextu2(&utf_ptr)) == '_')
-                       putc('$', file);
-               else
-                       putc(c, file);
-       }
-} 
-
-
-/*
- * 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/cacaoh/headers.h b/src/cacaoh/headers.h
deleted file mode 100644 (file)
index de8ed71..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* src/cacaoh/headers.h - export functions for header generation
-
-   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
-
-   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 _HEADERS_H
-#define _HEADERS_H
-
-#include "config.h"
-
-#include "toolbox/chain.h"
-
-#include "vm/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/utf8.h"
-
-
-/* export variables ***********************************************************/
-
-extern chain *nativemethod_chain;
-extern chain *nativeclass_chain;
-extern chain *ident_chain;
-extern FILE *file;
-
-
-/* function prototypes ********************************************************/
-
-void printID(utf *u);
-void printOverloadPart(utf *desc);
-void printmethod(methodinfo *m);
-void gen_header_filename(char *buffer, utf *u);
-void headerfile_generate(classinfo *c, char *opt_directory);
-void print_classname(classinfo *clazz);
-
-#endif /* _HEADERS_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 a511f3cf05691c657a5f6c92d620df11df3e3bae..e4f2595d323353b90ff6f0220b2f7fe50b896c18 100644 (file)
@@ -376,41 +376,42 @@ final class VMThread
      * @throws InterruptedException if the Thread is (or was) interrupted;
      *         it's <i>interrupted status</i> will be cleared
      */
-    static void sleep(long ms, int ns) throws InterruptedException
-    {
-      // Note: JDK treats a zero length sleep is like Thread.yield(),
-      // without checking the interrupted status of the thread.
-      // It's unclear if this is a bug in the implementation or the spec.
-      // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203
-      if (ms == 0 && ns == 0)
-       {
-         if (Thread.interrupted())
-           throw new InterruptedException();
-         return;
-       }
+//     static void sleep(long ms, int ns) throws InterruptedException
+//     {
+//       // Note: JDK treats a zero length sleep is like Thread.yield(),
+//       // without checking the interrupted status of the thread.
+//       // It's unclear if this is a bug in the implementation or the spec.
+//       // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203
+//       if (ms == 0 && ns == 0)
+//     {
+//       if (Thread.interrupted())
+//         throw new InterruptedException();
+//       return;
+//     }
 
-      // Compute end time, but don't overflow
-      long now = System.currentTimeMillis();
-      long end = now + ms;
-      if (end < now)
-         end = Long.MAX_VALUE;
+//       // Compute end time, but don't overflow
+//       long now = System.currentTimeMillis();
+//       long end = now + ms;
+//       if (end < now)
+//       end = Long.MAX_VALUE;
 
-      // A VM is allowed to return from wait() without notify() having been
-      // called, so we loop to handle possible spurious wakeups.
-      VMThread vt = Thread.currentThread().vmThread;
-      synchronized (vt)
-       {
-         while (true)
-           {
-             vt.wait(ms, ns);
-             now = System.currentTimeMillis();
-             if (now >= end)
-               break;
-             ms = end - now;
-             ns = 0;
-           }
-       }
-    }
+//       // A VM is allowed to return from wait() without notify() having been
+//       // called, so we loop to handle possible spurious wakeups.
+//       VMThread vt = Thread.currentThread().vmThread;
+//       synchronized (vt)
+//     {
+//       while (true)
+//         {
+//           vt.wait(ms, ns);
+//           now = System.currentTimeMillis();
+//           if (now >= end)
+//             break;
+//           ms = end - now;
+//           ns = 0;
+//         }
+//     }
+//     }
+    static native void sleep(long ms, int ns) throws InterruptedException;
 
     /**
      * Determine whether the current Thread has been interrupted, and clear
index 8c5aca3652bfe2ec6717691bd6b26720e4e0d764..51ce4729e9bb2ecf480f137568d5d342fc7f6625 100644 (file)
@@ -47,7 +47,7 @@ public class AnnotationParser {
      * Parses the annotations described by the passed byte array,
      * but returns Annotation[] so I don't have to do this in C.
      *
-     * @author Mathias Panzenböck
+     * @author Mathias Panzenboeck
      * 
      * @param rawAnnotations are the unparsed annotations
      * @param constPool is the constant pool of the declaring class
@@ -67,7 +67,7 @@ public class AnnotationParser {
     /**
      * Parses parameter annotations.
      * 
-     * @author Mathias Panzenböck
+     * @author Mathias Panzenboeck
      * 
      * @param parameterAnnotations are the unparsed parameter annotations
      * @param constPool is the constant pool of the declaring class
@@ -99,7 +99,7 @@ public class AnnotationParser {
      * This method is basically copied from OpenJDKs
      * java.lang.reflect.Method.getAnnotationDefault()
      * 
-     * @author Mathias Panzenböck
+     * @author Mathias Panzenboeck
      *
      * @param method represents the method for which the annotation default value has to be parsed
      * @param annotationDefault is the unparsed annotation default value
index ea559bbb99178b947377edabb31abc81bb1c6881..f80fe7f98d493c8447c8ae5d0fe9538fbb064fb3 100644 (file)
@@ -45,7 +45,7 @@ public class AnnotationType {
      * sun.misc.SharedSecrets.getJavaLangAccess().setAnnotationType() so
      * this class can be used with gnu classpath.
      *
-     * @author Mathias Panzenböck
+     * @author Mathias Panzenboeck
      */
     private static Map<Class, AnnotationType> annotationTypes =
         new HashMap<Class, AnnotationType>();
index 22c39cec2ed77c989a22004cbf4b07976c250b7f..203d919442b844119de43cc4ea731f9e745c9938 100644 (file)
@@ -31,7 +31,7 @@ DIST_SUBDIRS = \
 
 if DISABLE_GC
 GC_FILE = \
-       nogc.c
+       gc-none.cpp
 endif
 
 if ENABLE_GC_BOEHM
@@ -39,7 +39,7 @@ SUBDIRS = \
        boehm-gc
 
 GC_FILE = \
-       boehm.c
+       gc-boehm.cpp
 
 GC_LIB = \
        $(top_builddir)/src/mm/boehm-gc/libgc.la
@@ -62,13 +62,18 @@ libmm_la_SOURCES = \
        dumpmemory.c \
        dumpmemory.h \
        $(GC_FILE) \
-       gc-common.h \
+       gc.hpp \
        memory.c \
        memory.h
 
 libmm_la_LIBADD = \
        $(GC_LIB)
 
+if ENABLE_TLH
+libmm_la_SOURCES += \
+       tlh.h \
+       tlh.c
+endif
 
 ## Local variables:
 ## mode: Makefile
index 14091f125765507737082f8e14b75bcc148ab800..cf83b26147f3d9bd6d6adaefbd4f0098221b3566 100644 (file)
@@ -16,6 +16,8 @@
 
 ## Process this file with automake to produce Makefile.in.
 
+ACLOCAL_AMFLAGS = -I m4
+
 DISTCLEANFILES = \
        atomic_ops.c \
        atomic_ops_sysdeps.S \
index 1dab4c214cc789b75b4e80ade73ef2f56750f505..19a6571058bb76ca49207b366a4c324b2a3d4b9e 100644 (file)
@@ -242,11 +242,6 @@ GC_API unsigned long GC_time_limit;
  */
 GC_API void GC_init(void);
 
-/* Added for cacao */
-int GC_signum1();   
-int GC_signum2();   
-/* cacao END */
-
 /*
  * general purpose allocation routines, with roughly malloc calling conv.
  * The atomic versions promise that no relevant pointers are contained
index 8e77c48a860031ff15eb5433abaf04caa767e8e5..b828759d0cb5d6d204113ebe0ba82ca85dd023d6 100644 (file)
 #    define SEQUENT
 #    define mach_type_known
 # endif
-# if defined(sun) && (defined(i386) || defined(__i386__))
+# if (defined(sun) || defined(__sun)) && (defined(i386) || defined(__i386__))
 #    define I386
 #    define SOLARIS
 #    define mach_type_known
 # endif
-# if defined(sun) && defined(__amd64)
+# if (defined(sun) || defined(__sun)) && defined(__amd64)
 #    define X86_64
 #    define SOLARIS
 #    define mach_type_known
diff --git a/src/mm/boehm-gc/m4/dummy b/src/mm/boehm-gc/m4/dummy
new file mode 100644 (file)
index 0000000..e69de29
index 85fa531cb193f6b1f53d2bc0fa6a60792641d5d8..30ad9bef53ca8bad92d49fac06f3d7a965ef74aa 100644 (file)
@@ -372,9 +372,6 @@ int GC_suspend_all()
     return n_live_threads;
 }
 
-void lock_stopworld(int);
-void unlock_stopworld();
-
 void GC_stop_world()
 {
     int i;
@@ -561,16 +558,4 @@ void GC_stop_init() {
       }
 }
 
-/* Added for cacao */
-int GC_signum1()
-{
-    return SIG_SUSPEND;
-}
-
-int GC_signum2()
-{
-    return SIG_THR_RESTART;
-}
-/* cacao END */
-
 #endif
diff --git a/src/mm/boehm.c b/src/mm/boehm.c
deleted file mode 100644 (file)
index 411cb6c..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/* src/mm/boehm.c - interface for boehm gc
-
-   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 <stdint.h>
-
-#if defined(ENABLE_THREADS) && defined(__LINUX__)
-#define GC_LINUX_THREADS
-#endif
-#if defined(ENABLE_THREADS) && defined(__IRIX__)
-#define GC_IRIX_THREADS
-#endif
-#if defined(ENABLE_THREADS) && defined(__DARWIN__)
-#define GC_DARWIN_THREADS
-#endif
-
-#include "boehm-gc/include/gc.h"
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/finalizer.h"
-#include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/rt-timing.h"
-
-
-/* global variables ***********************************************************/
-
-static bool in_gc_out_of_memory = false;    /* is GC out of memory?           */
-
-
-/* prototype static functions *************************************************/
-
-static void gc_ignore_warnings(char *msg, GC_word arg);
-
-
-/* gc_init *********************************************************************
-
-   Initializes the boehm garbage collector.
-
-*******************************************************************************/
-
-void gc_init(size_t heapmaxsize, size_t heapstartsize)
-{
-       size_t heapcurrentsize;
-
-       TRACESUBSYSTEMINITIALIZATION("gc_init");
-
-       /* just to be sure (should be set to 1 by JAVA_FINALIZATION macro) */
-
-       GC_java_finalization = 1;
-
-       /* Ignore pointers that do not point to the start of an object. */
-
-       GC_all_interior_pointers = 0;
-
-       /* suppress warnings */
-
-       GC_set_warn_proc(gc_ignore_warnings);
-
-       /* install a GC notifier */
-
-       GC_finalize_on_demand = 1;
-       GC_finalizer_notifier = finalizer_notify;
-
-       /* define OOM function */
-
-       GC_oom_fn = gc_out_of_memory;
-
-       GC_INIT();
-
-       /* set the maximal heap size */
-
-       GC_set_max_heap_size(heapmaxsize);
-
-       /* set the initial heap size */
-
-       heapcurrentsize = GC_get_heap_size();
-
-       if (heapstartsize > heapcurrentsize)
-               GC_expand_hp(heapstartsize - heapcurrentsize);
-}
-
-
-static void gc_ignore_warnings(char *msg, GC_word arg)
-{
-}
-
-
-void *heap_alloc_uncollectable(size_t size)
-{
-       void *p;
-
-       p = GC_MALLOC_UNCOLLECTABLE(size);
-
-       /* clear allocated memory region */
-
-       MSET(p, 0, uint8_t, size);
-
-       return p;
-}
-
-
-/* heap_alloc ******************************************************************
-
-   Allocates memory on the Java heap.
-
-*******************************************************************************/
-
-void *heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect)
-{
-       void *p;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_end;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       /* We can't use a bool here for references, as it's passed as a
-          bitmask in builtin_new.  Thus we check for != 0. */
-
-       if (references != 0)
-               p = GC_MALLOC(size);
-       else
-               p = GC_MALLOC_ATOMIC(size);
-
-       if (p == NULL)
-               return NULL;
-
-       if (finalizer != NULL)
-               GC_REGISTER_FINALIZER_NO_ORDER(p, finalizer_run, 0, 0, 0);
-
-       /* clear allocated memory region */
-
-       MSET(p, 0, uint8_t, size);
-
-       RT_TIMING_GET_TIME(time_end);
-       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_GC_ALLOC);
-
-       return p;
-}
-
-
-void heap_free(void *p)
-{
-       GC_FREE(p);
-}
-
-void gc_call(void)
-{
-       if (opt_verbosegc)
-               dolog("Garbage Collection:  previous/now = %d / %d ",
-                         0, 0);
-
-       GC_gcollect();
-}
-
-
-int64_t gc_get_heap_size(void)
-{
-       return GC_get_heap_size();
-}
-
-
-int64_t gc_get_free_bytes(void)
-{
-       return GC_get_free_bytes();
-}
-
-
-/* gc_get_total_bytes **********************************************************
-
-   Returns the number of total bytes currently used on the Java heap.
-
-*******************************************************************************/
-
-int64_t gc_get_total_bytes(void)
-{
-       return GC_get_total_bytes();
-}
-
-
-int64_t gc_get_max_heap_size(void)
-{
-       return GC_get_max_heap_size();
-}
-
-
-void gc_invoke_finalizers(void)
-{
-       GC_invoke_finalizers();
-}
-
-
-void gc_finalize_all(void)
-{
-       GC_finalize_all();
-}
-
-
-/* gc_out_of_memory ************************************************************
-
-   This function is called when boehm detects that it is OOM.
-
-*******************************************************************************/
-
-void *gc_out_of_memory(size_t bytes_requested)
-{
-       /* if this happens, we are REALLY out of memory */
-
-       if (in_gc_out_of_memory) {
-               /* this is all we can do... */
-               vm_abort("gc_out_of_memory: out of memory");
-       }
-
-       in_gc_out_of_memory = true;
-
-       /* try to release some memory */
-
-       gc_call();
-
-       /* now instantiate the exception */
-
-       exceptions_throw_outofmemoryerror();
-
-       in_gc_out_of_memory = false;
-
-       return NULL;
-}
-
-
-/*
- * 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 fb0d77342dcf9334513c1a576d05cb53dbed4306..b895797e4305c9ac5a9b6b854ae9b19b26c086eb 100644 (file)
@@ -1,9 +1,7 @@
 /* mm/cacao-gc/final.c - GC module for finalization and weak references
 
-   Copyright (C) 2006 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) 2006, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
index 8987073fe1a31e8cdfdbc966f6ec45b6fd994885..e09309f843e9c55c877f71935e83ada3c7515165 100644 (file)
@@ -1,9 +1,7 @@
 /* mm/cacao-gc/final.h - GC header for finalization and weak references
 
-   Copyright (C) 2006 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) 2006, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 #ifndef _FINAL_H
 #define _FINAL_H
 
+#include "config.h"
 #include "vm/types.h"
 
 #include "toolbox/list.h"
-#include "vmcore/method.h"
+#include "vm/method.h"
 
 
 /* Global Variables ***********************************************************/
index 1f8f5db417ab966ca231be28a922a910a92e961e..4362d85f58e288919c750db9c80655cb5a254491 100644 (file)
@@ -31,7 +31,7 @@
 #include "vm/types.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "compact.h"
 #include "copy.h"
 #include "rootset.h"
 #include "mm/memory.h"
 #include "toolbox/logging.h"
+
 #include "vm/finalizer.h"
-#include "vm/vm.h"
-#include "vmcore/rt-timing.h"
+#include "vm/rt-timing.h"
+#include "vm/vm.hpp"
 
 
 /* Global Variables ***********************************************************/
index 31060381d73868057a9a8dcbfb33960a0ee6cf40..fd42e44a40f34d409f6d25ded778a32b217996fc 100644 (file)
@@ -35,7 +35,7 @@
 #include "config.h"
 #include "vm/types.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/list.h"
 #include "vm/jit/replace.h"
@@ -54,7 +54,7 @@
 
 #if !defined(NDEBUG) && defined(GC_DEBUGGING)
 # include <assert.h>
-# include "vmcore/options.h"
+# include "vm/options.h"
 # define GC_LOG(code) if (opt_verbosegc) { code; }
 # define GC_ASSERT(assertion) assert(assertion)
 #else
index 425b0dfc38286eb353155446e7d76fcdbde2be9d..f3630c7a3b1d8963db94b7703bcbe89700905fbc 100644 (file)
@@ -1,9 +1,7 @@
 /* mm/cacao-gc/heap.c - GC module for heap management
 
-   Copyright (C) 2006 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) 2006, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 #include "native/include/java_lang_String.h"
 #include "native/llni.h"
 #include "toolbox/logging.h"
+
 #include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-#include "vmcore/options.h"
-#include "vmcore/rt-timing.h"
+#include "vm/options.h"
+#include "vm/rt-timing.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
 
 
 /* Global Variables ***********************************************************/
index c2c8a5c9b71a4896bf5b2c9743b3c9b0e91830ae..1a64e8626f3433442a55641478c35c2e6828b3c3 100644 (file)
 #include "rootset.h"
 #include "mm/memory.h"
 #include "toolbox/logging.h"
+
 #include "vm/global.h"
-#include "vm/vm.h"
-#include "vmcore/linker.h"
+#include "vm/linker.h"
+#include "vm/vm.hpp"
 
 
 /* Helper Macros **************************************************************/
index 89ac2c2018b6df521a8f32f70583ca6bb55db34d..fe3253579640d3797d90d0761ed45946c3d9c869 100644 (file)
 #include "mm/memory.h"
 
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
 #include "vm/global.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 rootset_t *rootset_create(void)
index e61315f555a6fae6bdd8955515b270bcd31c65fa..5b0dc52b824d30ffbf50a8fa4d82096609a9040f 100644 (file)
@@ -31,10 +31,11 @@ typedef struct rootset_t rootset_t;
 #include "config.h"
 #include "vm/types.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
+
+#include "vm/method.h"
 
 #include "vm/jit/replace.h"
-#include "vmcore/method.h"
 
 
 /* Structures *****************************************************************/
index 7d2fd89c867dfbda7c993c547ed614af1043c8fa..1e0c095466a33789195590b8698a28d9ce4a8456 100644 (file)
 #include <sys/mman.h> /* REMOVEME */
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "mm/codememory.h"
 #include "mm/memory.h"
 
-#include "vmcore/options.h"
+#include "vm/global.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
 
 #if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
+# include "vm/statistics.h"
 #endif
 
-#include "vmcore/system.h"
-
-#include "vm/global.h"
-
 
 /* global code memory variables ***********************************************/
 
@@ -78,7 +76,7 @@ void codememory_init(void)
 
        /* Get the pagesize of this architecture. */
 
-       pagesize = system_getpagesize();
+       pagesize = os_getpagesize();
 }
 
 
@@ -124,9 +122,9 @@ void *codememory_get(size_t size)
 
                /* allocate the memory */
 
-               p = system_mmap_anonymous(NULL, code_memory_size,
-                                                                 PROT_READ | PROT_WRITE | PROT_EXEC,
-                                                                 MAP_PRIVATE);
+               p = os_mmap_anonymous(NULL, code_memory_size,
+                                                         PROT_READ | PROT_WRITE | PROT_EXEC,
+                                                         MAP_PRIVATE);
 
                /* set global code memory pointer */
 
index c9dd38393dacffdf559f92d63326236a2c814e0a..3fe3a18cb209929e3699a0f233fa572382232d1a 100644 (file)
 #include "config.h"
 
 #include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <sys/types.h>
 
 
@@ -45,6 +50,10 @@ void  codememory_init(void);
 void *codememory_get(size_t size);
 void  codememory_release(void *p, size_t size);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _CODEMEMORY_H */
 
 
index 0dc19151500dced52cc509cb8a16a3a51be2ef64..943a9c6062b5e199875a8451e5344ae4ea608b11 100644 (file)
 #include "mm/dumpmemory.h"
 #include "mm/memory.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
-#include "vmcore/options.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
 
 #if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
+# include "vm/statistics.h"
 #endif
 
-#include "vmcore/system.h"
-
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 
 /*******************************************************************************
@@ -297,7 +296,7 @@ void *dumpmemory_get(size_t size)
 
                /* clear the memory */
 
-               (void) system_memset(p, MEMORY_CLEAR_BYTE, da->size);
+               (void) os_memset(p, MEMORY_CLEAR_BYTE, da->size);
        }
 #endif /* defined(ENABLE_MEMCHECK) */
 
@@ -334,12 +333,12 @@ void *dumpmemory_realloc(void *src, s4 len1, s4 len2)
 
        dst = dumpmemory_get(len2);
 
-       (void) system_memcpy(dst, src, len1);
+       (void) os_memcpy(dst, src, len1);
 
 #if defined(ENABLE_MEMCHECK)
        /* destroy the source */
 
-       (void) system_memset(src, MEMORY_CLEAR_BYTE, len1);
+       (void) os_memset(src, MEMORY_CLEAR_BYTE, len1);
 #endif
 
        return dst;
@@ -398,7 +397,7 @@ void dumpmemory_release(s4 size)
 
                        /* invalidate the freed memory */
 
-                       (void) system_memset(da->mem, MEMORY_CLEAR_BYTE, da->size);
+                       (void) os_memset(da->mem, MEMORY_CLEAR_BYTE, da->size);
 
                        FREE(da, dump_allocation_t);
 
@@ -427,8 +426,8 @@ void dumpmemory_release(s4 size)
 
                /* Release the dump memory and the dumpinfo structure. */
 
-               system_free(tmp->dumpmem);
-               system_free(tmp);
+               os_free(tmp->dumpmem);
+               os_free(tmp);
        }
 
 #endif /* defined(DISABLE_DUMP) */
index f51977799533768759635be856b7c2a2657c6826..54fdb6a0aa29453d9f81341afaed0eba3947174e 100644 (file)
 #ifndef _DUMPMEMORY_H
 #define _DUMPMEMORY_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* forward typedefs ***********************************************************/
 
 typedef struct dumpblock_t dumpblock_t;
@@ -90,8 +94,8 @@ struct dumpinfo_t {
 
 #define DNEW(type)            ((type *) dumpmemory_get(sizeof(type)))
 #define DMNEW(type,num)       ((type *) dumpmemory_get(sizeof(type) * (num)))
-#define DMREALLOC(ptr,type,num1,num2) dumpmemory_realloc((ptr), sizeof(type) * (num1), \
-                                                          sizeof(type) * (num2))
+#define DMREALLOC(ptr,type,num1,num2) ((type*) dumpmemory_realloc((ptr), sizeof(type) * (num1), \
+                                                                                                                                 sizeof(type) * (num2)))
 
 /* function prototypes ********************************************************/
 
@@ -100,6 +104,10 @@ void    *dumpmemory_realloc(void *src, int32_t len1, int32_t len2);
 int32_t  dumpmemory_marker(void);
 void     dumpmemory_release(int32_t size);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _DUMPMEMORY_H */
 
 
diff --git a/src/mm/gc-boehm.cpp b/src/mm/gc-boehm.cpp
new file mode 100644 (file)
index 0000000..2b4f64a
--- /dev/null
@@ -0,0 +1,273 @@
+/* src/mm/gc-boehm.cpp - interface for boehm gc
+
+   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 <stdint.h>
+
+#if defined(ENABLE_THREADS) && defined(__LINUX__)
+#define GC_LINUX_THREADS
+#endif
+#if defined(ENABLE_THREADS) && defined(__IRIX__)
+#define GC_IRIX_THREADS
+#endif
+#if defined(ENABLE_THREADS) && defined(__DARWIN__)
+#define GC_DARWIN_THREADS
+#endif
+
+#include "boehm-gc/include/gc.h"
+#include "mm/gc.hpp"
+#include "mm/memory.h"
+
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/finalizer.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/rt-timing.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+
+/* global variables ***********************************************************/
+
+static bool in_gc_out_of_memory = false;    /* is GC out of memory?           */
+
+
+/* prototype static functions *************************************************/
+
+static void gc_ignore_warnings(char *msg, GC_word arg);
+
+
+/* gc_init *********************************************************************
+
+   Initializes the boehm garbage collector.
+
+*******************************************************************************/
+
+void gc_init(size_t heapmaxsize, size_t heapstartsize)
+{
+       size_t heapcurrentsize;
+
+       TRACESUBSYSTEMINITIALIZATION("gc_init");
+
+       /* just to be sure (should be set to 1 by JAVA_FINALIZATION macro) */
+
+       GC_java_finalization = 1;
+
+       /* Ignore pointers that do not point to the start of an object. */
+
+       GC_all_interior_pointers = 0;
+
+       /* suppress warnings */
+
+       GC_set_warn_proc(gc_ignore_warnings);
+
+       /* install a GC notifier */
+
+       GC_finalize_on_demand = 1;
+       GC_finalizer_notifier = finalizer_notify;
+
+       /* define OOM function */
+
+       GC_oom_fn = gc_out_of_memory;
+
+       GC_INIT();
+
+       /* set the maximal heap size */
+
+       GC_set_max_heap_size(heapmaxsize);
+
+       /* set the initial heap size */
+
+       heapcurrentsize = GC_get_heap_size();
+
+       if (heapstartsize > heapcurrentsize)
+               GC_expand_hp(heapstartsize - heapcurrentsize);
+}
+
+
+static void gc_ignore_warnings(char *msg, GC_word arg)
+{
+}
+
+
+void *heap_alloc_uncollectable(size_t size)
+{
+       void *p;
+
+       p = GC_MALLOC_UNCOLLECTABLE(size);
+
+       /* clear allocated memory region */
+
+       MSET(p, 0, uint8_t, size);
+
+       return p;
+}
+
+
+/* heap_alloc ******************************************************************
+
+   Allocates memory on the Java heap.
+
+*******************************************************************************/
+
+void *heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect)
+{
+       void *p;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       /* We can't use a bool here for references, as it's passed as a
+          bitmask in builtin_new.  Thus we check for != 0. */
+
+       if (references != 0)
+               p = GC_MALLOC(size);
+       else
+               p = GC_MALLOC_ATOMIC(size);
+
+       if (p == NULL)
+               return NULL;
+
+       if (finalizer != NULL)
+               GC_REGISTER_FINALIZER_NO_ORDER(p, finalizer_run, 0, 0, 0);
+
+       /* clear allocated memory region */
+
+       MSET(p, 0, uint8_t, size);
+
+       RT_TIMING_GET_TIME(time_end);
+       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_GC_ALLOC);
+
+       return p;
+}
+
+
+void heap_free(void *p)
+{
+       GC_FREE(p);
+}
+
+void gc_call(void)
+{
+       if (opt_verbosegc)
+               dolog("Garbage Collection:  previous/now = %d / %d ",
+                         0, 0);
+
+       GC_gcollect();
+}
+
+
+int64_t gc_get_heap_size(void)
+{
+       return GC_get_heap_size();
+}
+
+
+int64_t gc_get_free_bytes(void)
+{
+       return GC_get_free_bytes();
+}
+
+
+/* gc_get_total_bytes **********************************************************
+
+   Returns the number of total bytes currently used on the Java heap.
+
+*******************************************************************************/
+
+int64_t gc_get_total_bytes(void)
+{
+       return GC_get_total_bytes();
+}
+
+
+int64_t gc_get_max_heap_size(void)
+{
+       return GC_get_max_heap_size();
+}
+
+
+void gc_invoke_finalizers(void)
+{
+       GC_invoke_finalizers();
+}
+
+
+void gc_finalize_all(void)
+{
+       GC_finalize_all();
+}
+
+
+/* gc_out_of_memory ************************************************************
+
+   This function is called when boehm detects that it is OOM.
+
+*******************************************************************************/
+
+void *gc_out_of_memory(size_t bytes_requested)
+{
+       /* if this happens, we are REALLY out of memory */
+
+       if (in_gc_out_of_memory) {
+               /* this is all we can do... */
+               vm_abort("gc_out_of_memory: out of memory");
+       }
+
+       in_gc_out_of_memory = true;
+
+       /* try to release some memory */
+
+       gc_call();
+
+       /* now instantiate the exception */
+
+       exceptions_throw_outofmemoryerror();
+
+       in_gc_out_of_memory = false;
+
+       return NULL;
+}
+
+
+/*
+ * 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/mm/gc-common.h b/src/mm/gc-common.h
deleted file mode 100644 (file)
index 12454e8..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* src/mm/gc-common.h - gc independant interface for heap managment
-
-   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 _GC_COMMON_H
-#define _GC_COMMON_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/global.h"
-
-#include "vmcore/method.h"
-
-
-/* reference types ************************************************************/
-
-enum {
-       GC_REFTYPE_THREADOBJECT,
-       GC_REFTYPE_CLASSLOADER,
-       GC_REFTYPE_JNI_GLOBALREF,
-       GC_REFTYPE_FINALIZER,
-       GC_REFTYPE_LOCALREF,
-       GC_REFTYPE_STACK,
-       GC_REFTYPE_CLASSREF,
-       GC_REFTYPE_LOCKRECORD
-};
-
-
-/* function prototypes ********************************************************/
-
-void    gc_init(size_t heapmaxsize, size_t heapstartsize);
-
-void*   heap_alloc_uncollectable(size_t size);
-void*   heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect);
-void    heap_free(void *p);
-
-#if defined(ENABLE_GC_CACAO)
-void    heap_init_objectheader(java_object_t *o, uint32_t size);
-int32_t heap_get_hashcode(java_object_t *o);
-
-void    gc_reference_register(java_object_t **ref, int32_t reftype);
-void    gc_reference_unregister(java_object_t **ref);
-
-void    gc_weakreference_register(java_object_t **ref, int32_t reftype);
-void    gc_weakreference_unregister(java_object_t **ref);
-#endif
-
-void    gc_call(void);
-int64_t gc_get_heap_size(void);
-int64_t gc_get_free_bytes(void);
-int64_t gc_get_total_bytes(void);
-int64_t gc_get_max_heap_size(void);
-void    gc_invoke_finalizers(void);
-void    gc_finalize_all(void);
-void*   gc_out_of_memory(size_t bytes_requested);
-
-
-/* inlined functions **********************************************************/
-
-static inline int32_t heap_hashcode(java_object_t *obj)
-{
-#if defined(ENABLE_GC_CACAO)
-       return heap_get_hashcode(obj);
-#else
-       return (int32_t)(intptr_t) obj;
-#endif
-}
-
-#endif /* _GC_COMMON_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/mm/gc-none.cpp b/src/mm/gc-none.cpp
new file mode 100644 (file)
index 0000000..01209e0
--- /dev/null
@@ -0,0 +1,178 @@
+/* src/mm/gc-none.cpp - allocates memory through malloc (no GC)
+
+   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>
+
+#if defined(HAVE_SYS_MMAN_H)
+# include <sys/mman.h>
+#endif
+
+#include "vm/types.h"
+
+#include "boehm-gc/include/gc.h"
+
+#include "mm/gc.hpp"
+#include "mm/memory.h"
+
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
+
+
+/* global stuff ***************************************************************/
+
+#define MMAP_HEAPADDRESS    0x10000000  /* try to map the heap to this addr.  */
+#define ALIGNSIZE           8
+
+static void *mmapptr = NULL;
+static int mmapsize = 0;
+static void *mmaptop = NULL;
+
+
+void* heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect)
+{
+       void *m;
+
+       mmapptr = (void *) MEMORY_ALIGN((ptrint) mmapptr, ALIGNSIZE);
+       
+       m = mmapptr;
+       mmapptr = (void *) ((ptrint) mmapptr + size);
+
+       if (mmapptr > mmaptop)
+               vm_abort("heap_alloc: out of memory");
+
+       MSET(m, 0, u1, size);
+
+       return m;
+}
+
+
+void* heap_alloc_uncollectable(size_t size)
+{
+       return heap_alloc(size, false, NULL, false);
+}
+
+
+void heap_free(void* p)
+{
+       /* nop */
+}
+
+
+
+void gc_init(size_t heapmaxsize, size_t heapstartsize)
+{
+       heapmaxsize = MEMORY_ALIGN(heapmaxsize, ALIGNSIZE);
+
+#if defined(HAVE_MMAP)
+       mmapptr = mmap((void *) MMAP_HEAPADDRESS,
+                                  (size_t) heapmaxsize,
+                                  PROT_READ | PROT_WRITE,
+                                  MAP_PRIVATE |
+# if defined(MAP_ANONYMOUS)
+                                  MAP_ANONYMOUS,
+# elif defined(MAP_ANON)
+                                  MAP_ANON,
+# else
+                                  0,
+# endif
+                                  -1,
+                                  (off_t) 0);
+
+       if (mmapptr == MAP_FAILED)
+               vm_abort("gc_init: out of memory");
+#else
+       mmapptr = malloc(heapmaxsize);
+
+       if (mmapptr == NULL)
+               vm_abort("gc_init: out of memory");
+#endif
+
+       mmapsize = heapmaxsize;
+       mmaptop = (void *) ((ptrint) mmapptr + mmapsize);
+}
+
+
+void gc_call(void)
+{
+       log_text("GC call: nothing done...");
+       /* nop */
+}
+
+
+s8 gc_get_heap_size(void)
+{
+       return 0;
+}
+
+
+s8 gc_get_free_bytes(void)
+{
+       return 0;
+}
+
+
+s8 gc_get_total_bytes(void)
+{
+       return 0;
+}
+
+
+s8 gc_get_max_heap_size(void)
+{
+       return 0;
+}
+
+
+void gc_invoke_finalizers(void)
+{
+       /* nop */
+}
+
+
+void gc_finalize_all(void)
+{
+       /* nop */
+}
+
+
+/*
+ * 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/mm/gc.hpp b/src/mm/gc.hpp
new file mode 100644 (file)
index 0000000..60d5c3a
--- /dev/null
@@ -0,0 +1,113 @@
+/* src/mm/gc.hpp - gc independant interface for heap managment
+
+   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 _GC_HPP
+#define _GC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vm/global.h"
+#include "vm/method.h"
+
+
+/* reference types ************************************************************/
+
+enum {
+       GC_REFTYPE_THREADOBJECT,
+       GC_REFTYPE_CLASSLOADER,
+       GC_REFTYPE_JNI_GLOBALREF,
+       GC_REFTYPE_FINALIZER,
+       GC_REFTYPE_LOCALREF,
+       GC_REFTYPE_STACK,
+       GC_REFTYPE_CLASSREF,
+       GC_REFTYPE_LOCKRECORD
+};
+
+
+/* function prototypes ********************************************************/
+
+void    gc_init(size_t heapmaxsize, size_t heapstartsize);
+
+void*   heap_alloc_uncollectable(size_t size);
+void*   heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect);
+void    heap_free(void *p);
+
+#if defined(ENABLE_GC_CACAO)
+void    heap_init_objectheader(java_object_t *o, uint32_t size);
+int32_t heap_get_hashcode(java_object_t *o);
+
+void    gc_reference_register(java_object_t **ref, int32_t reftype);
+void    gc_reference_unregister(java_object_t **ref);
+
+void    gc_weakreference_register(java_object_t **ref, int32_t reftype);
+void    gc_weakreference_unregister(java_object_t **ref);
+#endif
+
+void    gc_call(void);
+int64_t gc_get_heap_size(void);
+int64_t gc_get_free_bytes(void);
+int64_t gc_get_total_bytes(void);
+int64_t gc_get_max_heap_size(void);
+void    gc_invoke_finalizers(void);
+void    gc_finalize_all(void);
+void*   gc_out_of_memory(size_t bytes_requested);
+
+
+/* inlined functions **********************************************************/
+
+static inline int32_t heap_hashcode(java_object_t *obj)
+{
+#if defined(ENABLE_GC_CACAO)
+       return heap_get_hashcode(obj);
+#else
+       return (int32_t)(intptr_t) obj;
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GC_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:
+ */
index 0b74e53517e14d2a2fa788716ef834917addf308..ccaa8ec4d1b196c579f1c888b3a5893c52d2abae 100644 (file)
 #include "config.h"
 
 #include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
+#include <stdint.h>
 
 #if defined(__DARWIN__)
 /* If we compile with -ansi on darwin, <sys/types.h> is not
 #include "native/native.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
-#include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
 
-#include "vmcore/options.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
 
 #if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
+# include "vm/statistics.h"
 #endif
 
-#include "vmcore/system.h"
-
 
 /* memory_mprotect *************************************************************
 
@@ -74,9 +68,8 @@
 
 void memory_mprotect(void *addr, size_t len, int prot)
 {
-       if (system_mprotect(addr, len, prot) != 0)
-               vm_abort("memory_mprotect: system_mprotect failed: %s",
-                                strerror(errno));
+       if (os_mprotect(addr, len, prot) != 0)
+               vm_abort_errno("memory_mprotect: os_mprotect failed");
 }
 
 
@@ -93,7 +86,7 @@ void *memory_checked_alloc(size_t size)
 {
        /* always allocate memory zeroed out */
 
-       void *p = calloc(size, 1);
+       void *p = os_calloc(size, 1);
 
        if (p == NULL)
                vm_abort("memory_checked_alloc: calloc failed: out of memory");
@@ -149,7 +142,7 @@ void *mem_realloc(void *src, int32_t len1, int32_t len2)
 
 #if defined(ENABLE_MEMCHECK)
        if (len2 < len1)
-               memset((u1*)dst + len2, MEMORY_CLEAR_BYTE, len1 - len2);
+               os_memset((u1*)dst + len2, MEMORY_CLEAR_BYTE, len1 - len2);
 #endif
 
        dst = realloc(src, len2);
@@ -159,7 +152,7 @@ void *mem_realloc(void *src, int32_t len1, int32_t len2)
 
 #if defined(ENABLE_MEMCHECK)
        if (len2 > len1)
-               memset((u1*)dst + len1, MEMORY_CLEAR_BYTE, len2 - len1);
+               os_memset((u1*)dst + len1, MEMORY_CLEAR_BYTE, len2 - len1);
 #endif
 
        return dst;
@@ -183,10 +176,10 @@ void mem_free(void *m, int32_t size)
 
 #if defined(ENABLE_MEMCHECK)
        /* destroy the contents */
-       memset(m, MEMORY_CLEAR_BYTE, size);
+       os_memset(m, MEMORY_CLEAR_BYTE, size);
 #endif
 
-       free(m);
+       os_free(m);
 }
 
 
index 8a88321d38480fceaa3ebb1d34759a2b84952dd9..12ca651c2eecd3f1b4ac872fab8ae2b73cc09d4c 100644 (file)
@@ -51,7 +51,7 @@ extern "C" {
 
 /* internal includes **********************************************************/
 
-#include "mm/gc-common.h"
+#include "mm/gc.hpp"
 
 
 /* 
diff --git a/src/mm/nogc.c b/src/mm/nogc.c
deleted file mode 100644 (file)
index c84deb4..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* src/mm/nogc.c - allocates memory through malloc (no GC)
-
-   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
-
-   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>
-
-#if defined(HAVE_SYS_MMAN_H)
-# include <sys/mman.h>
-#endif
-
-#include "vm/types.h"
-
-#include "boehm-gc/include/gc.h"
-
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
-
-/* global stuff ***************************************************************/
-
-#define MMAP_HEAPADDRESS    0x10000000  /* try to map the heap to this addr.  */
-#define ALIGNSIZE           8
-
-static void *mmapptr = NULL;
-static int mmapsize = 0;
-static void *mmaptop = NULL;
-
-
-void *heap_alloc(u4 size, u4 references, methodinfo *finalizer, bool collect)
-{
-       void *m;
-
-       mmapptr = (void *) MEMORY_ALIGN((ptrint) mmapptr, ALIGNSIZE);
-       
-       m = mmapptr;
-       mmapptr = (void *) ((ptrint) mmapptr + size);
-
-       if (mmapptr > mmaptop)
-               vm_abort("heap_alloc: out of memory");
-
-       MSET(m, 0, u1, size);
-
-       return m;
-}
-
-
-void *heap_alloc_uncollectable(u4 size)
-{
-       return heap_alloc(size, false, NULL, false);
-}
-
-
-void heap_free(void *p)
-{
-       /* nop */
-}
-
-
-
-void gc_init(u4 heapmaxsize, u4 heapstartsize)
-{
-       heapmaxsize = MEMORY_ALIGN(heapmaxsize, ALIGNSIZE);
-
-#if defined(HAVE_MMAP)
-       mmapptr = mmap((void *) MMAP_HEAPADDRESS,
-                                  (size_t) heapmaxsize,
-                                  PROT_READ | PROT_WRITE,
-                                  MAP_PRIVATE |
-# if defined(MAP_ANONYMOUS)
-                                  MAP_ANONYMOUS,
-# elif defined(MAP_ANON)
-                                  MAP_ANON,
-# else
-                                  0,
-# endif
-                                  -1,
-                                  (off_t) 0);
-
-       if (mmapptr == MAP_FAILED)
-               vm_abort("gc_init: out of memory");
-#else
-       mmapptr = malloc(heapmaxsize);
-
-       if (mmapptr == NULL)
-               vm_abort("gc_init: out of memory");
-#endif
-
-       mmapsize = heapmaxsize;
-       mmaptop = (void *) ((ptrint) mmapptr + mmapsize);
-}
-
-
-void gc_call(void)
-{
-       log_text("GC call: nothing done...");
-       /* nop */
-}
-
-
-s8 gc_get_heap_size(void)
-{
-       return 0;
-}
-
-
-s8 gc_get_free_bytes(void)
-{
-       return 0;
-}
-
-
-s8 gc_get_total_bytes(void)
-{
-       return 0;
-}
-
-
-s8 gc_get_max_heap_size(void)
-{
-       return 0;
-}
-
-
-void gc_invoke_finalizers(void)
-{
-       /* nop */
-}
-
-
-void gc_finalize_all(void)
-{
-       /* nop */
-}
-
-
-/*
- * 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/mm/tlh.c b/src/mm/tlh.c
new file mode 100644 (file)
index 0000000..e46cf87
--- /dev/null
@@ -0,0 +1,128 @@
+/* src/mm/tlh.c
+
+   Copyright (C) 2008
+   CACAOVM - Verein zu Foerderung der freien virtuellen Machine 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 "mm/memory.h"
+#include "mm/tlh.h"
+
+#include "vm/global.h"
+
+#include <assert.h>
+#include <sys/mman.h>
+
+static const int TLH_MAX_SIZE = (20 * 1024 * 1024);
+
+static inline bool tlh_avail(tlh_t *tlh, unsigned n) {
+       /*
+    ---  --- --- ---
+                    ^ end
+            ^ top
+                    ^ top + 2
+       */
+       return (tlh->top + n) <= tlh->end;
+}
+
+void tlh_init(tlh_t *tlh) {
+
+       void *heap = mmap(
+               NULL, 
+               TLH_MAX_SIZE, 
+               PROT_READ|PROT_WRITE, 
+               MAP_ANONYMOUS|MAP_PRIVATE, 
+               -1, 
+               0
+       );
+       
+       if (heap == MAP_FAILED) {
+               /* The top pointer points to end, so all allocations will fail. */
+               tlh->start = NULL;
+               tlh->end = NULL;
+               tlh->top = NULL;
+               tlh->base = NULL;
+       } else {
+               tlh->start = (uint8_t *)heap;
+               tlh->top = tlh->start;
+               tlh->base = tlh->start;
+               tlh->end = tlh->start + TLH_MAX_SIZE;
+       }
+
+       tlh->overflows = 0;
+}
+
+void tlh_destroy(tlh_t *tlh) {
+       int res = munmap(tlh->start, TLH_MAX_SIZE);
+       if (res == -1) {
+               /* TODO */
+               assert(0);
+       }
+       tlh->start = NULL;
+       tlh->end = NULL;
+       tlh->top = NULL;
+       tlh->base = NULL;
+}
+
+void tlh_add_frame(tlh_t *tlh) {
+       if (tlh_avail(tlh, SIZEOF_VOID_P)) {
+               *(uint8_t **)tlh->top = tlh->base;
+               tlh->base = tlh->top;
+               tlh->top += SIZEOF_VOID_P;
+       } else {
+               tlh->overflows += 1;
+       }
+}
+
+void tlh_remove_frame(tlh_t *tlh) {
+       if (tlh->overflows > 0) {
+               tlh->overflows -= 1;
+       } else {
+               tlh->top = tlh->base;
+               tlh->base = *(uint8_t **)tlh->top;
+       }
+}
+
+void *tlh_alloc(tlh_t *tlh, size_t size) {
+       void *ret;
+       if (tlh_avail(tlh, size)) {
+               ret = tlh->top;
+               tlh->top += size;
+               MZERO(ret, char, size);
+       } else {
+               ret = NULL;
+       }
+       return ret;
+}
+
+/*
+ * 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/tlh.h b/src/mm/tlh.h
new file mode 100644 (file)
index 0000000..48b40e3
--- /dev/null
@@ -0,0 +1,62 @@
+/* src/mm/tlh.h
+
+   Copyright (C) 2008
+   CACAOVM - Verein zu Foerderung der freien virtuellen Machine 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 _MM_TLH_H
+#define _MM_TLH_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef struct {
+       uint8_t *start;
+       uint8_t *end;
+       uint8_t *top;
+       uint8_t *base;
+       unsigned overflows;
+} tlh_t;
+
+void tlh_init(tlh_t *tlh);
+
+void tlh_destroy(tlh_t *tlh);
+
+void tlh_add_frame(tlh_t *tlh);
+
+void tlh_remove_frame(tlh_t *tlh);
+
+void *tlh_alloc(tlh_t *tlh, size_t size);
+
+#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:
+ */
index 8cb17b562df183739d54a40fd245c2e5e35fdb52..facd048b9b37b4dcc6fc18a5fb690a929b8b8b59 100644 (file)
@@ -1,9 +1,7 @@
 ## src/native/Makefile.am
 ##
-## 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.
 ##
@@ -28,7 +26,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top
 LIBS =
 
 SUBDIRS = \
-       include \
        vm
 
 if ENABLE_JVMTI
@@ -40,7 +37,7 @@ noinst_LTLIBRARIES = libnative.la
 
 if ENABLE_JNI
 JNI_SOURCES = \
-       jni.c \
+       jni.cpp \
        jni.h \
        localref.c \
        localref.h
index 90a57a8b0e2e2236199f8ed800445979264b1747..28a29873cc7737d4326ee4b8c1c505112d882db6 100644 (file)
 ## 02110-1301, USA.
 
 
-JAVAH    = $(CACAOH)
-JAVAHCMD = $(JAVAH) -bootclasspath $(BOOTCLASSPATH)
+JAVAH    = javah
+JAVAHCMD = $(JAVAH) -jni -bootclasspath $(BOOTCLASSPATH)
 
-COMMON_HEADER_FILES = \
-       java_lang_Class.h \
-       java_lang_Object.h \
-       java_lang_String.h \
-       java_lang_Thread.h \
-       java_lang_Throwable.h \
-       \
-       java_io_InputStream.h \
-       java_io_PrintStream.h \
-       \
-       java_lang_Boolean.h \
-       java_lang_Byte.h \
-       java_lang_Character.h \
-       java_lang_Double.h \
-       java_lang_Float.h \
-       java_lang_Integer.h \
-       java_lang_Long.h \
-       java_lang_Short.h \
-       java_util_Vector.h
-
-JAVASE_HEADER_FILES = \
-       java_lang_ClassLoader.h \
-       java_lang_Cloneable.h \
-       java_lang_ThreadGroup.h \
-       java_util_Properties.h \
-       \
-       java_io_File.h \
-       java_lang_Process.h \
-       java_lang_StackTraceElement.h \
-       java_lang_reflect_Constructor.h \
-       java_lang_reflect_Field.h \
-       java_lang_reflect_Method.h \
-       java_nio_Buffer.h \
-       java_security_ProtectionDomain.h \
-       java_util_HashMap.h \
-       java_util_Map.h \
-       java_util_concurrent_atomic_AtomicLong.h \
-       sun_misc_Unsafe.h
-
-if WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH
-JAVASE_HEADER_FILES += \
-       java_lang_VMThread.h \
-       java_lang_VMThrowable.h \
-       \
-       gnu_classpath_Pointer.h \
-       gnu_classpath_Pointer32.h \
-       gnu_classpath_Pointer64.h \
-       gnu_java_lang_VMCPStringBuilder.h \
-       java_lang_VMObject.h \
-       java_lang_reflect_VMConstructor.h \
-       java_lang_reflect_VMField.h \
-       java_lang_reflect_VMMethod.h \
-       java_nio_DirectByteBufferImpl.h
-
-if ENABLE_ANNOTATIONS
-JAVASE_HEADER_FILES += \
-       sun_reflect_ConstantPool.h
-endif
-endif
-
-if WITH_JAVA_RUNTIME_LIBRARY_OPENJDK
-JAVASE_HEADER_FILES += \
-       java_lang_AssertionStatusDirectives.h \
-       java_nio_ByteBuffer.h \
-       sun_reflect_ConstantPool.h
-endif
-
-JAVAME_CLDC1_1_HEADER_FILES = \
+if WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1
+IMPLEMENTED_VM_CLASSES_HEADER_FILES = \
        com_sun_cldc_io_ResourceInputStream.h \
        com_sun_cldc_io_j2me_socket_Protocol.h \
        com_sun_cldchi_io_ConsoleOutputStream.h \
        com_sun_cldchi_jvm_FileDescriptor.h \
        com_sun_cldchi_jvm_JVM.h \
+       java_lang_Class.h \
        java_lang_Math.h \
        java_lang_Runtime.h \
        java_lang_System.h
-
-JVMTI_HEADER_FILES = \
-       gnu_classpath_jdwp_VMFrame.h \
-       gnu_classpath_jdwp_VMMethod.h \
-       gnu_classpath_jdwp_VMVirtualMachine.h \
-       gnu_classpath_jdwp_event_EventRequest.h \
-       gnu_classpath_jdwp_util_VariableTable.h
+endif
 
 if WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH
-ADDITIONAL_IMPLEMENTED_VM_CLASSES_HEADER_FILES = \
+IMPLEMENTED_VM_CLASSES_HEADER_FILES = \
        gnu_classpath_VMStackWalker.h \
        gnu_classpath_VMSystemProperties.h \
+       gnu_java_lang_VMCPStringBuilder.h \
        gnu_java_lang_management_VMClassLoadingMXBeanImpl.h \
        gnu_java_lang_management_VMMemoryMXBeanImpl.h \
        gnu_java_lang_management_VMRuntimeMXBeanImpl.h \
        gnu_java_lang_management_VMThreadMXBeanImpl.h \
        java_lang_VMClass.h \
        java_lang_VMClassLoader.h \
+       java_lang_VMObject.h \
        java_lang_VMRuntime.h \
        java_lang_VMString.h \
        java_lang_VMSystem.h \
-       java_lang_management_MemoryUsage.h \
-       java_lang_management_ThreadInfo.h \
+       java_lang_VMThread.h \
+       java_lang_VMThrowable.h \
        java_lang_management_VMManagementFactory.h \
+       java_lang_reflect_VMConstructor.h \
+       java_lang_reflect_VMField.h \
+       java_lang_reflect_VMMethod.h \
        java_lang_reflect_VMProxy.h \
-       java_security_VMAccessController.h
-endif
-
-CLEANFILES = \
-       *.h
-
-DO_HEADER_FILES = \
-       $(COMMON_HEADER_FILES)
+       java_security_VMAccessController.h \
+       java_util_concurrent_atomic_AtomicLong.h \
+       sun_misc_Unsafe.h
 
-if ENABLE_JAVASE
-DO_HEADER_FILES += \
-       $(JAVASE_HEADER_FILES) \
-       $(ADDITIONAL_IMPLEMENTED_VM_CLASSES_HEADER_FILES)
+if ENABLE_ANNOTATIONS
+IMPLEMENTED_VM_CLASSES_HEADER_FILES += \
+       sun_reflect_ConstantPool.h
+endif
 endif
 
-if ENABLE_JAVAME_CLDC1_1
-DO_HEADER_FILES += \
-       $(JAVAME_CLDC1_1_HEADER_FILES)
+if WITH_JAVA_RUNTIME_LIBRARY_OPENJDK
+IMPLEMENTED_VM_CLASSES_HEADER_FILES = \
+       sun_misc_Unsafe.h
 endif
 
 if ENABLE_JVMTI
-DO_HEADER_FILES += \
-       $(GEN_JVMTI_HEADER_FILES)
+JVMTI_HEADER_FILES = \
+       gnu_classpath_jdwp_VMFrame.h \
+       gnu_classpath_jdwp_VMMethod.h \
+       gnu_classpath_jdwp_VMVirtualMachine.h \
+       gnu_classpath_jdwp_event_EventRequest.h \
+       gnu_classpath_jdwp_util_VariableTable.h
 endif
 
+CLEANFILES = \
+       *.h
+
+DO_HEADER_FILES = \
+       $(IMPLEMENTED_VM_CLASSES_HEADER_FILES)
+
 if WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH
 if ENABLE_ZLIB
 VM_ZIP = $(top_builddir)/src/classes/vm.zip
diff --git a/src/native/jni.c b/src/native/jni.c
deleted file mode 100644 (file)
index c2cf660..0000000
+++ /dev/null
@@ -1,4411 +0,0 @@
-/* src/native/jni.c - implementation of the Java Native Interface functions
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/localref.h"
-#include "native/native.h"
-
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-#  include "native/include/gnu_classpath_Pointer.h"
-
-#  if SIZEOF_VOID_P == 8
-#   include "native/include/gnu_classpath_Pointer64.h"
-#  else
-#   include "native/include/gnu_classpath_Pointer32.h"
-#  endif
-# endif
-#endif
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
-
-#if defined(ENABLE_JAVASE)
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-#  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
-# endif
-
-/* java_lang_ClassLoader is used in java_lang_Class and vice versa, so
-   we pre-define it here to prevent a compiler warning for Sun
-   configurations. */
-
-struct java_lang_ClassLoader;
-
-# include "native/include/java_lang_Class.h"
-# include "native/include/java_lang_ClassLoader.h"
-
-# include "native/include/java_lang_reflect_Constructor.h"
-# include "native/include/java_lang_reflect_Field.h"
-# include "native/include/java_lang_reflect_Method.h"
-
-# include "native/include/java_nio_Buffer.h"
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-#  include "native/include/java_lang_reflect_VMConstructor.h"
-#  include "native/include/java_lang_reflect_VMField.h"
-#  include "native/include/java_lang_reflect_VMMethod.h"
-
-#  include "native/include/java_nio_DirectByteBufferImpl.h"
-# endif
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-# include "native/include/java_lang_Class.h"
-#endif
-
-#if defined(ENABLE_JVMTI)
-# include "native/jvmti/cacaodbg.h"
-#endif
-
-#if defined(ENABLE_JAVASE)
-# include "native/vm/reflect.h"
-#endif
-
-#include "threads/lock-common.h"
-#include "threads/thread.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/array.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/initialize.h"
-#include "vm/primitive.h"
-#include "vm/resolve.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/argument.h"
-#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
-
-/* debug **********************************************************************/
-
-#if !defined(NDEBUG)
-
-# define TRACEJNICALLS(x)                                              \
-    do {                                                                               \
-        if (opt_TraceJNICalls) {                               \
-            log_println x;                                             \
-        }                                                                              \
-    } while (0)
-
-# define TRACEJNICALLSENTER(x)                                                                 \
-    do {                                                                                                               \
-        if (opt_TraceJNICalls) {                                                               \
-                       log_start();                                                                            \
-            log_print x;                                                                               \
-        }                                                                                                              \
-    } while (0)
-
-# define TRACEJNICALLSEXIT(x)                                                                  \
-    do {                                                                                                               \
-        if (opt_TraceJNICalls) {                                                               \
-                       log_print x;                                                                            \
-                       log_finish();                                                                           \
-        }                                                                                                              \
-    } while (0)
-
-#else
-
-# define TRACEJNICALLS(x)
-# define TRACEJNICALLSENTER(x)
-# define TRACEJNICALLSEXIT(x)
-
-#endif
-
-
-/* global variables ***********************************************************/
-
-/* global reference table *****************************************************/
-
-/* hashsize must be power of 2 */
-
-#define HASHTABLE_GLOBAL_REF_SIZE    64 /* initial size of globalref-hash     */
-
-static hashtable *hashtable_global_ref; /* hashtable for globalrefs           */
-
-
-/* direct buffer stuff ********************************************************/
-
-#if defined(ENABLE_JAVASE)
-static classinfo *class_java_nio_Buffer;
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-static classinfo *class_java_nio_DirectByteBufferImpl;
-static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
-
-#  if SIZEOF_VOID_P == 8
-static classinfo *class_gnu_classpath_Pointer64;
-#  else
-static classinfo *class_gnu_classpath_Pointer32;
-#  endif
-
-static methodinfo *dbbirw_init;
-
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-static classinfo *class_sun_nio_ch_DirectBuffer;
-static classinfo *class_java_nio_DirectByteBuffer;
-
-static methodinfo *dbb_init;
-
-# endif
-#endif
-
-
-/* some forward declarations **************************************************/
-
-jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
-
-
-/* jni_init ********************************************************************
-
-   Initialize the JNI subsystem.
-
-*******************************************************************************/
-
-bool jni_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("jni_init");
-
-       /* create global ref hashtable */
-
-       hashtable_global_ref = NEW(hashtable);
-
-       hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
-
-
-#if defined(ENABLE_JAVASE)
-       /* Direct buffer stuff. */
-
-       if (!(class_java_nio_Buffer =
-                 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
-               !link_class(class_java_nio_Buffer))
-               return false;
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       if (!(class_java_nio_DirectByteBufferImpl =
-                 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
-               !link_class(class_java_nio_DirectByteBufferImpl))
-               return false;
-
-       if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
-                 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
-               !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
-               return false;
-
-       if (!(dbbirw_init =
-               class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
-                                                       utf_init,
-                                                       utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
-               return false;
-
-#  if SIZEOF_VOID_P == 8
-       if (!(class_gnu_classpath_Pointer64 =
-                 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
-               !link_class(class_gnu_classpath_Pointer64))
-               return false;
-#  else
-       if (!(class_gnu_classpath_Pointer32 =
-                 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
-               !link_class(class_gnu_classpath_Pointer32))
-               return false;
-#  endif
-
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       if (!(class_sun_nio_ch_DirectBuffer =
-                 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
-               vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
-
-       if (!link_class(class_sun_nio_ch_DirectBuffer))
-               vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
-
-       if (!(class_java_nio_DirectByteBuffer =
-                 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
-               vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
-
-       if (!link_class(class_java_nio_DirectByteBuffer))
-               vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
-
-       if (!(dbb_init =
-                 class_resolvemethod(class_java_nio_DirectByteBuffer,
-                                                         utf_init,
-                                                         utf_new_char("(JI)V"))))
-               vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
-
-# endif
-
-#endif /* defined(ENABLE_JAVASE) */
-
-       return true;
-}
-
-
-/* jni_version_check ***********************************************************
-
-   Check if the given JNI version is supported.
-
-   IN:
-       version....JNI version to check
-
-   RETURN VALUE:
-       true.......supported
-       false......not supported
-
-*******************************************************************************/
-
-bool jni_version_check(int version)
-{
-       switch (version) {
-       case JNI_VERSION_1_1:
-       case JNI_VERSION_1_2:
-       case JNI_VERSION_1_4:
-       case JNI_VERSION_1_6:
-               return true;
-       default:
-               return false;
-       }
-}
-
-
-/* _Jv_jni_CallObjectMethod ****************************************************
-
-   Internal function to call Java Object methods.
-
-*******************************************************************************/
-
-static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
-                                                                                          vftbl_t *vftbl,
-                                                                                          methodinfo *m, va_list ap)
-{
-       methodinfo    *resm;
-       java_handle_t *ro;
-
-       STATISTICS(jniinvokation());
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       ro = vm_call_method_valist(resm, o, ap);
-
-       return ro;
-}
-
-
-/* _Jv_jni_CallObjectMethodA ***************************************************
-
-   Internal function to call Java Object methods.
-
-*******************************************************************************/
-
-static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
-                                                                                               vftbl_t *vftbl,
-                                                                                               methodinfo *m,
-                                                                                               const jvalue *args)
-{
-       methodinfo    *resm;
-       java_handle_t *ro;
-
-       STATISTICS(jniinvokation());
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       ro = vm_call_method_jvalue(resm, o, args);
-
-       return ro;
-}
-
-
-/* _Jv_jni_CallIntMethod *******************************************************
-
-   Internal function to call Java integer class methods (boolean,
-   byte, char, short, int).
-
-*******************************************************************************/
-
-static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
-                                                                 methodinfo *m, va_list ap)
-{
-       methodinfo *resm;
-       jint        i;
-
-       STATISTICS(jniinvokation());
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-        
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       i = vm_call_method_int_valist(resm, o, ap);
-
-       return i;
-}
-
-
-/* _Jv_jni_CallIntMethodA ******************************************************
-
-   Internal function to call Java integer class methods (boolean,
-   byte, char, short, int).
-
-*******************************************************************************/
-
-static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
-                                                                  methodinfo *m, const jvalue *args)
-{
-       methodinfo *resm;
-       jint        i;
-
-       STATISTICS(jniinvokation());
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-        
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       i = vm_call_method_int_jvalue(resm, o, args);
-
-       return i;
-}
-
-
-/* _Jv_jni_CallLongMethod ******************************************************
-
-   Internal function to call Java long methods.
-
-*******************************************************************************/
-
-static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
-                                                                       methodinfo *m, va_list ap)
-{
-       methodinfo *resm;
-       jlong       l;
-
-       STATISTICS(jniinvokation());
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       l = vm_call_method_long_valist(resm, o, ap);
-
-       return l;
-}
-
-
-/* _Jv_jni_CallLongMethodA *****************************************************
-
-   Internal function to call Java long methods.
-
-*******************************************************************************/
-
-static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
-                                                                        methodinfo *m, const jvalue *args)
-{
-       methodinfo *resm;
-       jlong       l;
-
-       STATISTICS(jniinvokation());
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-       }
-       else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       l = vm_call_method_long_jvalue(resm, o, args);
-
-       return l;
-}
-
-
-/* _Jv_jni_CallFloatMethod *****************************************************
-
-   Internal function to call Java float methods.
-
-*******************************************************************************/
-
-static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
-                                                                         methodinfo *m, va_list ap)
-{
-       methodinfo *resm;
-       jfloat      f;
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       f = vm_call_method_float_valist(resm, o, ap);
-
-       return f;
-}
-
-
-/* _Jv_jni_CallFloatMethodA ****************************************************
-
-   Internal function to call Java float methods.
-
-*******************************************************************************/
-
-static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
-                                                                          methodinfo *m, const jvalue *args)
-{
-       methodinfo *resm;
-       jfloat      f;
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-       }
-       else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       f = vm_call_method_float_jvalue(resm, o, args);
-
-       return f;
-}
-
-
-/* _Jv_jni_CallDoubleMethod ****************************************************
-
-   Internal function to call Java double methods.
-
-*******************************************************************************/
-
-static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
-                                                                               methodinfo *m, va_list ap)
-{
-       methodinfo *resm;
-       jdouble     d;
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       d = vm_call_method_double_valist(resm, o, ap);
-
-       return d;
-}
-
-
-/* _Jv_jni_CallDoubleMethodA ***************************************************
-
-   Internal function to call Java double methods.
-
-*******************************************************************************/
-
-static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
-                                                                                methodinfo *m, const jvalue *args)
-{
-       methodinfo *resm;
-       jdouble     d;
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-       }
-       else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       d = vm_call_method_double_jvalue(resm, o, args);
-
-       return d;
-}
-
-
-/* _Jv_jni_CallVoidMethod ******************************************************
-
-   Internal function to call Java void methods.
-
-*******************************************************************************/
-
-static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
-                                                                  methodinfo *m, va_list ap)
-{      
-       methodinfo *resm;
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return;
-       }
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       (void) vm_call_method_valist(resm, o, ap);
-}
-
-
-/* _Jv_jni_CallVoidMethodA *****************************************************
-
-   Internal function to call Java void methods.
-
-*******************************************************************************/
-
-static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
-                                                                       methodinfo *m, const jvalue *args)
-{      
-       methodinfo *resm;
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return;
-       }
-
-       /* Class initialization is done by the JIT compiler.  This is ok
-          since a static method always belongs to the declaring class. */
-
-       if (m->flags & ACC_STATIC) {
-               /* For static methods we reset the object. */
-
-               if (o != NULL)
-                       o = NULL;
-
-               /* for convenience */
-
-               resm = m;
-
-       } else {
-               /* For instance methods we make a virtual function table lookup. */
-
-               resm = method_vftbl_lookup(vftbl, m);
-       }
-
-       STATISTICS(jnicallXmethodnvokation());
-
-       (void) vm_call_method_jvalue(resm, o, args);
-}
-
-
-/* GetVersion ******************************************************************
-
-   Returns the major version number in the higher 16 bits and the
-   minor version number in the lower 16 bits.
-
-*******************************************************************************/
-
-jint _Jv_JNI_GetVersion(JNIEnv *env)
-{
-       TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
-
-       /* We support JNI 1.6. */
-
-       return JNI_VERSION_1_6;
-}
-
-
-/* Class Operations ***********************************************************/
-
-/* DefineClass *****************************************************************
-
-   Loads a class from a buffer of raw class data. The buffer
-   containing the raw class data is not referenced by the VM after the
-   DefineClass call returns, and it may be discarded if desired.
-
-*******************************************************************************/
-
-jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
-                                                  const jbyte *buf, jsize bufLen)
-{
-#if defined(ENABLE_JAVASE)
-       utf             *u;
-       classloader_t   *cl;
-       classinfo       *c;
-       java_lang_Class *co;
-
-       TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
-
-       u  = utf_new_char(name);
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-
-       c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
-
-       co = LLNI_classinfo_wrap(c);
-
-       return (jclass) jni_NewLocalRef(env, (jobject) co);
-#else
-       vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
-
-       /* keep compiler happy */
-
-       return 0;
-#endif
-}
-
-
-/* FindClass *******************************************************************
-
-   This function loads a locally-defined class. It searches the
-   directories and zip files specified by the CLASSPATH environment
-   variable for the class with the specified name.
-
-*******************************************************************************/
-
-jclass jni_FindClass(JNIEnv *env, const char *name)
-{
-#if defined(ENABLE_JAVASE)
-
-       utf             *u;
-       classinfo       *cc;
-       classinfo       *c;
-       java_lang_Class *co;
-
-       TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
-
-       /* FIXME If name is NULL we have a problem here. */
-
-       u = utf_new_char_classname((char *) name);
-
-       if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
-               exceptions_throw_noclassdeffounderror(u);
-               return NULL;
-       }
-
-       /* Check stacktrace for classloader, if one found use it,
-          otherwise use the system classloader. */
-
-       /* Quote from the JNI documentation:
-        
-          In the Java 2 Platform, FindClass locates the class loader
-          associated with the current native method.  If the native code
-          belongs to a system class, no class loader will be
-          involved. Otherwise, the proper class loader will be invoked to
-          load and link the named class. When FindClass is called through
-          the Invocation Interface, there is no current native method or
-          its associated class loader. In that case, the result of
-          ClassLoader.getBaseClassLoader is used." */
-
-       cc = stacktrace_get_current_class();
-
-       if (cc == NULL)
-               c = load_class_from_sysloader(u);
-       else
-               c = load_class_from_classloader(u, cc->classloader);
-
-       if (c == NULL) {
-               resolve_handle_pending_exception(true);
-               return NULL;
-       }
-
-       if (!link_class(c))
-               return NULL;
-
-       co = LLNI_classinfo_wrap(c);
-
-       return (jclass) jni_NewLocalRef(env, (jobject) co);
-
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-
-       utf       *u;
-       classinfo *c;
-
-       TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
-
-       u = utf_new_char_classname((char *) name);
-       c = load_class_bootstrap(u);
-
-       if (c == NULL) {
-               resolve_handle_pending_exception(true);
-               return NULL;
-       }
-
-       if (!link_class(c))
-               return NULL;
-
-       return (jclass) jni_NewLocalRef(env, (jobject) c);
-       
-#else
-       vm_abort("jni_FindClass: not implemented in this configuration");
-
-       /* keep compiler happy */
-
-       return NULL;
-#endif
-}
-  
-
-/* GetSuperclass ***************************************************************
-
-   If clazz represents any class other than the class Object, then
-   this function returns the object that represents the superclass of
-   the class specified by clazz.
-
-*******************************************************************************/
-jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
-{
-       classinfo       *c;
-       classinfo       *super;
-       java_lang_Class *co;
-
-       TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
-
-       c = LLNI_classinfo_unwrap(sub);
-
-       if (c == NULL)
-               return NULL;
-
-       super = class_get_superclass(c);
-
-       co = LLNI_classinfo_wrap(super);
-
-       return (jclass) jni_NewLocalRef(env, (jobject) co);
-}
-  
-/* IsAssignableFrom ************************************************************
-
-   Determines whether an object of sub can be safely cast to sup.
-
-*******************************************************************************/
-
-jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
-{
-       classinfo *to;
-       classinfo *from;
-
-       TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
-
-       to   = (classinfo *) sup;
-       from = (classinfo *) sub;
-
-       return class_is_assignable_from(to, from);
-}
-
-
-/* Throw ***********************************************************************
-
-   Causes a java.lang.Throwable object to be thrown.
-
-*******************************************************************************/
-
-jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
-{
-       java_handle_t *o;
-
-       STATISTICS(jniinvokation());
-
-       o = (java_handle_t *) obj;
-
-       exceptions_set_exception(o);
-
-       return JNI_OK;
-}
-
-
-/* ThrowNew ********************************************************************
-
-   Constructs an exception object from the specified class with the
-   message specified by message and causes that exception to be
-   thrown.
-
-*******************************************************************************/
-
-jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
-{
-       classinfo     *c;
-       java_handle_t *o;
-       java_handle_t *s;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-       if (msg == NULL)
-               msg = "";
-       s = javastring_new_from_utf_string(msg);
-
-       /* instantiate exception object */
-
-       o = native_new_and_init_string(c, s);
-
-       if (o == NULL)
-               return -1;
-
-       exceptions_set_exception(o);
-
-       return 0;
-}
-
-
-/* ExceptionOccurred ***********************************************************
-
-   Determines if an exception is being thrown. The exception stays
-   being thrown until either the native code calls ExceptionClear(),
-   or the Java code handles the exception.
-
-*******************************************************************************/
-
-jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
-{
-       java_handle_t *o;
-
-       TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
-
-       o = exceptions_get_exception();
-
-       return jni_NewLocalRef(env, (jthrowable) o);
-}
-
-
-/* ExceptionDescribe ***********************************************************
-
-   Prints an exception and a backtrace of the stack to a system
-   error-reporting channel, such as stderr. This is a convenience
-   routine provided for debugging.
-
-*******************************************************************************/
-
-void jni_ExceptionDescribe(JNIEnv *env)
-{
-       TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
-
-       exceptions_print_stacktrace();
-}
-
-
-/* ExceptionClear **************************************************************
-
-   Clears any exception that is currently being thrown. If no
-   exception is currently being thrown, this routine has no effect.
-
-*******************************************************************************/
-
-void jni_ExceptionClear(JNIEnv *env)
-{
-       TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
-
-       exceptions_clear_exception();
-}
-
-
-/* FatalError ******************************************************************
-
-   Raises a fatal error and does not expect the VM to recover. This
-   function does not return.
-
-*******************************************************************************/
-
-void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
-{
-       STATISTICS(jniinvokation());
-
-       /* this seems to be the best way */
-
-       vm_abort("JNI Fatal error: %s", msg);
-}
-
-
-/* PushLocalFrame **************************************************************
-
-   Creates a new local reference frame, in which at least a given
-   number of local references can be created.
-
-*******************************************************************************/
-
-jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
-{
-       TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
-
-       if (capacity <= 0)
-               return -1;
-
-       /* add new local reference frame to current table */
-
-       if (!localref_frame_push(capacity))
-               return -1;
-
-       return 0;
-}
-
-
-/* PopLocalFrame ***************************************************************
-
-   Pops off the current local reference frame, frees all the local
-   references, and returns a local reference in the previous local
-   reference frame for the given result object.
-
-*******************************************************************************/
-
-jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
-{
-       TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
-
-       /* release all current local frames */
-
-       localref_frame_pop_all();
-
-       /* add local reference and return the value */
-
-       return jni_NewLocalRef(env, result);
-}
-
-
-/* DeleteLocalRef **************************************************************
-
-   Deletes the local reference pointed to by localRef.
-
-*******************************************************************************/
-
-void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
-{
-       java_handle_t *o;
-
-       TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
-
-       o = (java_handle_t *) localRef;
-
-       if (o == NULL)
-               return;
-
-       /* delete the reference */
-
-       localref_del(o);
-}
-
-
-/* IsSameObject ****************************************************************
-
-   Tests whether two references refer to the same Java object.
-
-*******************************************************************************/
-
-jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
-{
-       java_handle_t *o1;
-       java_handle_t *o2;
-       jboolean       result;
-
-       STATISTICS(jniinvokation());
-
-       o1 = (java_handle_t *) ref1;
-       o2 = (java_handle_t *) ref2;
-
-       LLNI_CRITICAL_START;
-
-       if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
-               result = JNI_TRUE;
-       else
-               result = JNI_FALSE;
-
-       LLNI_CRITICAL_END;
-
-       return result;
-}
-
-
-/* NewLocalRef *****************************************************************
-
-   Creates a new local reference that refers to the same object as ref.
-
-*******************************************************************************/
-
-jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
-{
-       java_handle_t *o;
-       java_handle_t *localref;
-
-       TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
-
-       o = (java_handle_t *) ref;
-
-       if (o == NULL)
-               return NULL;
-
-       /* insert the reference */
-
-       localref = localref_add(LLNI_DIRECT(o));
-
-       return (jobject) localref;
-}
-
-
-/* EnsureLocalCapacity *********************************************************
-
-   Ensures that at least a given number of local references can be
-   created in the current thread
-
-*******************************************************************************/
-
-jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
-{
-       localref_table *lrt;
-
-       TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
-
-       /* get local reference table (thread specific) */
-
-       lrt = LOCALREFTABLE;
-
-       /* check if capacity elements are available in the local references table */
-
-       if ((lrt->used + capacity) > lrt->capacity)
-               return jni_PushLocalFrame(env, capacity);
-
-       return 0;
-}
-
-
-/* AllocObject *****************************************************************
-
-   Allocates a new Java object without invoking any of the
-   constructors for the object. Returns a reference to the object.
-
-*******************************************************************************/
-
-jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
-{
-       classinfo     *c;
-       java_handle_t *o;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-
-       if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
-               exceptions_throw_instantiationexception(c);
-               return NULL;
-       }
-               
-       o = builtin_new(c);
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-/* NewObject *******************************************************************
-
-   Programmers place all arguments that are to be passed to the
-   constructor immediately following the methodID
-   argument. NewObject() accepts these arguments and passes them to
-   the Java method that the programmer wishes to invoke.
-
-*******************************************************************************/
-
-jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-       va_list        ap;
-
-       TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
-
-       c = LLNI_classinfo_unwrap(clazz);
-       m = (methodinfo *) methodID;
-
-       /* create object */
-
-       o = builtin_new(c);
-       
-       if (o == NULL)
-               return NULL;
-
-       /* call constructor */
-
-       va_start(ap, methodID);
-       _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
-       va_end(ap);
-
-       TRACEJNICALLSEXIT(("->%p", o));
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-/* NewObjectV ******************************************************************
-
-   Programmers place all arguments that are to be passed to the
-   constructor in an args argument of type va_list that immediately
-   follows the methodID argument. NewObjectV() accepts these
-   arguments, and, in turn, passes them to the Java method that the
-   programmer wishes to invoke.
-
-*******************************************************************************/
-
-jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
-                                                  va_list args)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-       m = (methodinfo *) methodID;
-
-       /* create object */
-
-       o = builtin_new(c);
-       
-       if (o == NULL)
-               return NULL;
-
-       /* call constructor */
-
-       _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-/* NewObjectA ***************************************************************** 
-
-   Programmers place all arguments that are to be passed to the
-   constructor in an args array of jvalues that immediately follows
-   the methodID argument. NewObjectA() accepts the arguments in this
-   array, and, in turn, passes them to the Java method that the
-   programmer wishes to invoke.
-
-*******************************************************************************/
-
-jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
-                                                  const jvalue *args)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-       m = (methodinfo *) methodID;
-
-       /* create object */
-
-       o = builtin_new(c);
-       
-       if (o == NULL)
-               return NULL;
-
-       /* call constructor */
-
-       _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-/* GetObjectClass **************************************************************
-
- Returns the class of an object.
-
-*******************************************************************************/
-
-jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
-{
-       java_handle_t   *o;
-       classinfo       *c;
-       java_lang_Class *co;
-
-       STATISTICS(jniinvokation());
-
-       o = (java_handle_t *) obj;
-
-       if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
-               return NULL;
-
-       LLNI_class_get(o, c);
-
-       co = LLNI_classinfo_wrap(c);
-
-       return (jclass) jni_NewLocalRef(env, (jobject) co);
-}
-
-
-/* IsInstanceOf ****************************************************************
-
-   Tests whether an object is an instance of a class.
-
-*******************************************************************************/
-
-jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
-{
-       classinfo     *c;
-       java_handle_t *h;
-
-       TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
-
-       /* XXX Is this correct? */
-       c = LLNI_classinfo_unwrap(clazz);
-       h = (java_handle_t *) obj;
-
-       return class_is_instance(c, h);
-}
-
-
-/* Reflection Support *********************************************************/
-
-/* FromReflectedMethod *********************************************************
-
-   Converts java.lang.reflect.Method or java.lang.reflect.Constructor
-   object to a method ID.
-  
-*******************************************************************************/
-  
-jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
-{
-#if defined(ENABLE_JAVASE)
-       java_handle_t                   *o;
-       java_lang_reflect_Method        *rm;
-       java_lang_reflect_Constructor   *rc;
-       classinfo                       *c;
-       methodinfo                      *m;
-       int32_t                          slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_reflect_VMMethod      *rvmm;
-       java_lang_reflect_VMConstructor *rvmc;
-#endif
-
-       TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
-
-       o = (java_handle_t *) method;
-
-       if (o == NULL)
-               return NULL;
-
-       if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
-               rc = (java_lang_reflect_Constructor *) method;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-               LLNI_field_get_ref(rc,   cons , rvmc);
-               LLNI_field_get_cls(rvmc, clazz, c);
-               LLNI_field_get_val(rvmc, slot , slot);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-               LLNI_field_get_cls(rc, clazz, c);
-               LLNI_field_get_val(rc, slot , slot);
-
-#else
-# error unknown configuration
-#endif
-       }
-       else {
-               assert(o->vftbl->clazz == class_java_lang_reflect_Method);
-
-               rm = (java_lang_reflect_Method *) method;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-               LLNI_field_get_ref(rm,   m ,    rvmm);
-               LLNI_field_get_cls(rvmm, clazz, c);
-               LLNI_field_get_val(rvmm, slot , slot);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-               LLNI_field_get_cls(rm, clazz, c);
-               LLNI_field_get_val(rm, slot , slot);
-
-#else
-# error unknown configuration
-#endif
-       }
-
-       m = &(c->methods[slot]);
-
-       return (jmethodID) m;
-#else
-       vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
-
-       /* Keep compiler happy. */
-
-       return NULL;
-#endif
-}
-
-
-/* FromReflectedField **********************************************************
-
-   Converts a java.lang.reflect.Field to a field ID.
-
-*******************************************************************************/
-jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
-{
-#if defined(ENABLE_JAVASE)
-       java_lang_reflect_Field   *rf;
-       classinfo                 *c;
-       fieldinfo                 *f;
-       int32_t                    slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_reflect_VMField *rvmf;
-#endif
-
-       TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
-
-       rf = (java_lang_reflect_Field *) field;
-
-       if (rf == NULL)
-               return NULL;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       LLNI_field_get_ref(rf,   f,     rvmf);
-       LLNI_field_get_cls(rvmf, clazz, c);
-       LLNI_field_get_val(rvmf, slot , slot);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       LLNI_field_get_cls(rf, clazz, c);
-       LLNI_field_get_val(rf, slot , slot);
-
-#else
-# error unknown configuration
-#endif
-
-       f = &(c->fields[slot]);
-
-       return (jfieldID) f;
-#else
-       vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
-
-       /* Keep compiler happy. */
-
-       return NULL;
-#endif
-}
-
-
-/* ToReflectedMethod ***********************************************************
-
-   Converts a method ID derived from cls to an instance of the
-   java.lang.reflect.Method class or to an instance of the
-   java.lang.reflect.Constructor class.
-
-*******************************************************************************/
-
-jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
-                                                                 jboolean isStatic)
-{
-#if defined(ENABLE_JAVASE)
-       methodinfo                    *m;
-       java_lang_reflect_Constructor *rc;
-       java_lang_reflect_Method      *rm;
-
-       TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
-
-       m = (methodinfo *) methodID;
-
-       /* HotSpot does the same assert. */
-
-       assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
-
-       if (m->name == utf_init) {
-               rc = reflect_constructor_new(m);
-
-               return (jobject) rc;
-       }
-       else {
-               rm = reflect_method_new(m);
-
-               return (jobject) rm;
-       }
-#else
-       vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
-
-       /* keep compiler happy */
-
-       return NULL;
-#endif
-}
-
-
-/* ToReflectedField ************************************************************
-
-   Converts a field ID derived from cls to an instance of the
-   java.lang.reflect.Field class.
-
-*******************************************************************************/
-
-jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
-                                                                jboolean isStatic)
-{
-       STATISTICS(jniinvokation());
-
-       log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* Calling Instance Methods ***************************************************/
-
-/* GetMethodID *****************************************************************
-
-   Returns the method ID for an instance (nonstatic) method of a class
-   or interface. The method may be defined in one of the clazz's
-   superclasses and inherited by clazz. The method is determined by
-   its name and signature.
-
-   GetMethodID() causes an uninitialized class to be initialized.
-
-*******************************************************************************/
-
-jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
-                                                         const char *sig)
-{
-       classinfo  *c;
-       utf        *uname;
-       utf        *udesc;
-       methodinfo *m;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-
-       if (c == NULL)
-               return NULL;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return NULL;
-
-       /* try to get the method of the class or one of it's superclasses */
-
-       uname = utf_new_char((char *) name);
-       udesc = utf_new_char((char *) sig);
-
-       m = class_resolvemethod(c, uname, udesc);
-
-       if ((m == NULL) || (m->flags & ACC_STATIC)) {
-               exceptions_throw_nosuchmethoderror(c, uname, udesc);
-
-               return NULL;
-       }
-
-       return (jmethodID) m;
-}
-
-
-/* JNI-functions for calling instance methods *********************************/
-
-#define JNI_CALL_VIRTUAL_METHOD(name, type, intern)         \
-type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj,   \
-                                                               jmethodID methodID, ...)    \
-{                                                           \
-       java_handle_t *o;                                       \
-       methodinfo    *m;                                       \
-       va_list        ap;                                      \
-       type           ret;                                     \
-                                                            \
-       o = (java_handle_t *) obj;                              \
-       m = (methodinfo *) methodID;                            \
-                                                            \
-       va_start(ap, methodID);                                 \
-       ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
-       va_end(ap);                                             \
-                                                            \
-       return ret;                                             \
-}
-
-JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
-JNI_CALL_VIRTUAL_METHOD(Byte,    jbyte,    Int)
-JNI_CALL_VIRTUAL_METHOD(Char,    jchar,    Int)
-JNI_CALL_VIRTUAL_METHOD(Short,   jshort,   Int)
-JNI_CALL_VIRTUAL_METHOD(Int,     jint,     Int)
-JNI_CALL_VIRTUAL_METHOD(Long,    jlong,    Long)
-JNI_CALL_VIRTUAL_METHOD(Float,   jfloat,   Float)
-JNI_CALL_VIRTUAL_METHOD(Double,  jdouble,  Double)
-
-
-#define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern)              \
-type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj,         \
-                                                                jmethodID methodID, va_list args) \
-{                                                                  \
-       java_handle_t *o;                                              \
-       methodinfo    *m;                                              \
-       type           ret;                                            \
-                                                                   \
-       o = (java_handle_t *) obj;                                     \
-       m = (methodinfo *) methodID;                                   \
-                                                                   \
-       ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args);      \
-                                                                   \
-       return ret;                                                    \
-}
-
-JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
-JNI_CALL_VIRTUAL_METHOD_V(Byte,    jbyte,    Int)
-JNI_CALL_VIRTUAL_METHOD_V(Char,    jchar,    Int)
-JNI_CALL_VIRTUAL_METHOD_V(Short,   jshort,   Int)
-JNI_CALL_VIRTUAL_METHOD_V(Int,     jint,     Int)
-JNI_CALL_VIRTUAL_METHOD_V(Long,    jlong,    Long)
-JNI_CALL_VIRTUAL_METHOD_V(Float,   jfloat,   Float)
-JNI_CALL_VIRTUAL_METHOD_V(Double,  jdouble,  Double)
-
-
-#define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern)          \
-type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj,     \
-                                                                jmethodID methodID,           \
-                                                                const jvalue *args)           \
-{                                                              \
-       java_handle_t *o;                                          \
-       methodinfo    *m;                                          \
-       type           ret;                                        \
-                                                               \
-       o = (java_handle_t *) obj;                                 \
-       m = (methodinfo *) methodID;                               \
-                                                               \
-       ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
-                                                               \
-       return ret;                                                \
-}
-
-JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
-JNI_CALL_VIRTUAL_METHOD_A(Byte,    jbyte,    Int)
-JNI_CALL_VIRTUAL_METHOD_A(Char,    jchar,    Int)
-JNI_CALL_VIRTUAL_METHOD_A(Short,   jshort,   Int)
-JNI_CALL_VIRTUAL_METHOD_A(Int,     jint,     Int)
-JNI_CALL_VIRTUAL_METHOD_A(Long,    jlong,    Long)
-JNI_CALL_VIRTUAL_METHOD_A(Float,   jfloat,   Float)
-JNI_CALL_VIRTUAL_METHOD_A(Double,  jdouble,  Double)
-
-
-jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                                ...)
-{
-       java_handle_t *o;
-       methodinfo    *m;
-       java_handle_t *ret;
-       va_list        ap;
-
-       o = (java_handle_t *) obj;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
-       va_end(ap);
-
-       return jni_NewLocalRef(env, (jobject) ret);
-}
-
-
-jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                                 va_list args)
-{
-       java_handle_t *o;
-       methodinfo    *m;
-       java_handle_t *ret;
-
-       o = (java_handle_t *) obj;
-       m = (methodinfo *) methodID;
-
-       ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
-
-       return jni_NewLocalRef(env, (jobject) ret);
-}
-
-
-jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                                 const jvalue *args)
-{
-       java_handle_t *o;
-       methodinfo    *m;
-       java_handle_t *ret;
-
-       o = (java_handle_t *) obj;
-       m = (methodinfo *) methodID;
-
-       ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
-
-       return jni_NewLocalRef(env, (jobject) ret);
-}
-
-
-
-void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_handle_t *o;
-       methodinfo    *m;
-       va_list        ap;
-
-       o = (java_handle_t *) obj;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
-       va_end(ap);
-}
-
-
-void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                        va_list args)
-{
-       java_handle_t *o;
-       methodinfo    *m;
-
-       o = (java_handle_t *) obj;
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
-}
-
-
-void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                        const jvalue *args)
-{
-       java_handle_t *o;
-       methodinfo    *m;
-
-       o = (java_handle_t *) obj;
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
-}
-
-
-
-#define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern)                      \
-type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj,         \
-                                                                                 jclass clazz, jmethodID methodID, \
-                                                                                 ...)                              \
-{                                                                           \
-       java_handle_t *o;                                                       \
-       classinfo     *c;                                                       \
-       methodinfo    *m;                                                       \
-       va_list        ap;                                                      \
-       type           ret;                                                     \
-                                                                            \
-       o = (java_handle_t *) obj;                                              \
-       c = LLNI_classinfo_unwrap(clazz);                                       \
-       m = (methodinfo *) methodID;                                            \
-                                                                            \
-       va_start(ap, methodID);                                                 \
-       ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap);                 \
-       va_end(ap);                                                             \
-                                                                            \
-       return ret;                                                             \
-}
-
-JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
-JNI_CALL_NONVIRTUAL_METHOD(Byte,    jbyte,    Int)
-JNI_CALL_NONVIRTUAL_METHOD(Char,    jchar,    Int)
-JNI_CALL_NONVIRTUAL_METHOD(Short,   jshort,   Int)
-JNI_CALL_NONVIRTUAL_METHOD(Int,     jint,     Int)
-JNI_CALL_NONVIRTUAL_METHOD(Long,    jlong,    Long)
-JNI_CALL_NONVIRTUAL_METHOD(Float,   jfloat,   Float)
-JNI_CALL_NONVIRTUAL_METHOD(Double,  jdouble,  Double)
-
-
-#define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern)                     \
-type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj,         \
-                                                                                  jclass clazz, jmethodID methodID, \
-                                                                                  va_list args)                     \
-{                                                                            \
-       java_handle_t *o;                                                        \
-       classinfo     *c;                                                        \
-       methodinfo    *m;                                                        \
-       type           ret;                                                      \
-                                                                             \
-       o = (java_handle_t *) obj;                                               \
-       c = LLNI_classinfo_unwrap(clazz);                                        \
-       m = (methodinfo *) methodID;                                             \
-                                                                             \
-       ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);                       \
-                                                                             \
-       return ret;                                                              \
-}
-
-JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
-JNI_CALL_NONVIRTUAL_METHOD_V(Byte,    jbyte,    Int)
-JNI_CALL_NONVIRTUAL_METHOD_V(Char,    jchar,    Int)
-JNI_CALL_NONVIRTUAL_METHOD_V(Short,   jshort,   Int)
-JNI_CALL_NONVIRTUAL_METHOD_V(Int,     jint,     Int)
-JNI_CALL_NONVIRTUAL_METHOD_V(Long,    jlong,    Long)
-JNI_CALL_NONVIRTUAL_METHOD_V(Float,   jfloat,   Float)
-JNI_CALL_NONVIRTUAL_METHOD_V(Double,  jdouble,  Double)
-
-
-#define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern)                     \
-type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj,         \
-                                                                                  jclass clazz, jmethodID methodID, \
-                                                                                  const jvalue *args)               \
-{                                                                            \
-       log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!");      \
-                                                                             \
-       return 0;                                                                \
-}
-
-JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
-JNI_CALL_NONVIRTUAL_METHOD_A(Byte,    jbyte,    Int)
-JNI_CALL_NONVIRTUAL_METHOD_A(Char,    jchar,    Int)
-JNI_CALL_NONVIRTUAL_METHOD_A(Short,   jshort,   Int)
-JNI_CALL_NONVIRTUAL_METHOD_A(Int,     jint,     Int)
-JNI_CALL_NONVIRTUAL_METHOD_A(Long,    jlong,    Long)
-JNI_CALL_NONVIRTUAL_METHOD_A(Float,   jfloat,   Float)
-JNI_CALL_NONVIRTUAL_METHOD_A(Double,  jdouble,  Double)
-
-jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
-                                                                                  jclass clazz, jmethodID methodID,
-                                                                                  ...)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-       java_handle_t *r;
-       va_list        ap;
-
-       o = (java_handle_t *) obj;
-       c = LLNI_classinfo_unwrap(clazz);
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
-       va_end(ap);
-
-       return jni_NewLocalRef(env, (jobject) r);
-}
-
-
-jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
-                                                                                       jclass clazz, jmethodID methodID,
-                                                                                       va_list args)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-       java_handle_t *r;
-
-       o = (java_handle_t *) obj;
-       c = LLNI_classinfo_unwrap(clazz);
-       m = (methodinfo *) methodID;
-
-       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
-
-       return jni_NewLocalRef(env, (jobject) r);
-}
-
-
-jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
-                                                                                       jclass clazz, jmethodID methodID,
-                                                                                       const jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
-
-       return jni_NewLocalRef(env, NULL);
-}
-
-
-void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
-                                                                         jmethodID methodID, ...)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-       va_list        ap;
-
-       o = (java_handle_t *) obj;
-       c = LLNI_classinfo_unwrap(clazz);
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
-       va_end(ap);
-}
-
-
-void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
-                                                                          jmethodID methodID, va_list args)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-
-       o = (java_handle_t *) obj;
-       c = LLNI_classinfo_unwrap(clazz);
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
-}
-
-
-void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
-                                                                          jmethodID methodID, const jvalue * args)
-{      
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-
-       o = (java_handle_t *) obj;
-       c = LLNI_classinfo_unwrap(clazz);
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
-}
-
-
-/* Accessing Fields of Objects ************************************************/
-
-/* GetFieldID ******************************************************************
-
-   Returns the field ID for an instance (nonstatic) field of a
-   class. The field is specified by its name and signature. The
-   Get<type>Field and Set<type>Field families of accessor functions
-   use field IDs to retrieve object fields.
-
-*******************************************************************************/
-
-jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
-                                                       const char *sig)
-{
-       classinfo *c;
-       fieldinfo *f;
-       utf       *uname;
-       utf       *udesc;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-
-       /* XXX NPE check? */
-
-       uname = utf_new_char((char *) name);
-       udesc = utf_new_char((char *) sig);
-
-       f = class_findfield(c, uname, udesc); 
-       
-       if (f == NULL)
-               exceptions_throw_nosuchfielderror(c, uname);  
-
-       return (jfieldID) f;
-}
-
-
-/* Get<type>Field Routines *****************************************************
-
-   This family of accessor routines returns the value of an instance
-   (nonstatic) field of an object. The field to access is specified by
-   a field ID obtained by calling GetFieldID().
-
-*******************************************************************************/
-
-#define GET_FIELD(o,type,f) \
-    *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
-
-#define JNI_GET_FIELD(name, type, intern)                                 \
-type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
-{                                                                         \
-       intern ret;                                                           \
-                                                                          \
-       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
-                                                                          \
-       LLNI_CRITICAL_START;                                                  \
-                                                                          \
-       ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
-                                                                          \
-       LLNI_CRITICAL_END;                                                    \
-                                                                          \
-       return (type) ret;                                                    \
-}
-
-JNI_GET_FIELD(Boolean, jboolean, s4)
-JNI_GET_FIELD(Byte,    jbyte,    s4)
-JNI_GET_FIELD(Char,    jchar,    s4)
-JNI_GET_FIELD(Short,   jshort,   s4)
-JNI_GET_FIELD(Int,     jint,     s4)
-JNI_GET_FIELD(Long,    jlong,    s8)
-JNI_GET_FIELD(Float,   jfloat,   float)
-JNI_GET_FIELD(Double,  jdouble,  double)
-
-
-jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       java_handle_t *o;
-
-       TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
-
-       LLNI_CRITICAL_START;
-
-       o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
-
-       LLNI_CRITICAL_END;
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-/* Set<type>Field Routines *****************************************************
-
-   This family of accessor routines sets the value of an instance
-   (nonstatic) field of an object. The field to access is specified by
-   a field ID obtained by calling GetFieldID().
-
-*******************************************************************************/
-
-#define SET_FIELD(o,type,f,value) \
-    *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
-
-#define JNI_SET_FIELD(name, type, intern)                                  \
-void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
-                                                         type value)                                  \
-{                                                                          \
-       TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
-                                                                           \
-       LLNI_CRITICAL_START;                                                   \
-                                                                           \
-       SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
-                                                                              \
-       LLNI_CRITICAL_START;                                                   \
-}
-
-JNI_SET_FIELD(Boolean, jboolean, s4)
-JNI_SET_FIELD(Byte,    jbyte,    s4)
-JNI_SET_FIELD(Char,    jchar,    s4)
-JNI_SET_FIELD(Short,   jshort,   s4)
-JNI_SET_FIELD(Int,     jint,     s4)
-JNI_SET_FIELD(Long,    jlong,    s8)
-JNI_SET_FIELD(Float,   jfloat,   float)
-JNI_SET_FIELD(Double,  jdouble,  double)
-
-
-void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
-                                                       jobject value)
-{
-       TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
-
-       LLNI_CRITICAL_START;
-
-       SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
-
-       LLNI_CRITICAL_END;
-}
-
-
-/* Calling Static Methods *****************************************************/
-
-/* GetStaticMethodID ***********************************************************
-
-   Returns the method ID for a static method of a class. The method is
-   specified by its name and signature.
-
-   GetStaticMethodID() causes an uninitialized class to be
-   initialized.
-
-*******************************************************************************/
-
-jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
-                                                                       const char *sig)
-{
-       classinfo  *c;
-       utf        *uname;
-       utf        *udesc;
-       methodinfo *m;
-
-       TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
-
-       c = LLNI_classinfo_unwrap(clazz);
-
-       if (c == NULL)
-               return NULL;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return NULL;
-
-       /* try to get the static method of the class */
-
-       uname = utf_new_char((char *) name);
-       udesc = utf_new_char((char *) sig);
-
-       m = class_resolvemethod(c, uname, udesc);
-
-       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
-               exceptions_throw_nosuchmethoderror(c, uname, udesc);
-
-               return NULL;
-       }
-
-       return (jmethodID) m;
-}
-
-
-#define JNI_CALL_STATIC_METHOD(name, type, intern)               \
-type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
-                                                                         jmethodID methodID, ...)   \
-{                                                                \
-       methodinfo *m;                                               \
-       va_list     ap;                                              \
-       type        res;                                             \
-                                                                 \
-       m = (methodinfo *) methodID;                                 \
-                                                                 \
-       va_start(ap, methodID);                                      \
-       res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap);       \
-       va_end(ap);                                                  \
-                                                                 \
-       return res;                                                  \
-}
-
-JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
-JNI_CALL_STATIC_METHOD(Byte,    jbyte,    Int)
-JNI_CALL_STATIC_METHOD(Char,    jchar,    Int)
-JNI_CALL_STATIC_METHOD(Short,   jshort,   Int)
-JNI_CALL_STATIC_METHOD(Int,     jint,     Int)
-JNI_CALL_STATIC_METHOD(Long,    jlong,    Long)
-JNI_CALL_STATIC_METHOD(Float,   jfloat,   Float)
-JNI_CALL_STATIC_METHOD(Double,  jdouble,  Double)
-
-
-#define JNI_CALL_STATIC_METHOD_V(name, type, intern)                     \
-type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz,        \
-                                                                          jmethodID methodID, va_list args) \
-{                                                                        \
-       methodinfo *m;                                                       \
-       type        res;                                                     \
-                                                                         \
-       m = (methodinfo *) methodID;                                         \
-                                                                         \
-       res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args);             \
-                                                                         \
-       return res;                                                          \
-}
-
-JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
-JNI_CALL_STATIC_METHOD_V(Byte,    jbyte,    Int)
-JNI_CALL_STATIC_METHOD_V(Char,    jchar,    Int)
-JNI_CALL_STATIC_METHOD_V(Short,   jshort,   Int)
-JNI_CALL_STATIC_METHOD_V(Int,     jint,     Int)
-JNI_CALL_STATIC_METHOD_V(Long,    jlong,    Long)
-JNI_CALL_STATIC_METHOD_V(Float,   jfloat,   Float)
-JNI_CALL_STATIC_METHOD_V(Double,  jdouble,  Double)
-
-
-#define JNI_CALL_STATIC_METHOD_A(name, type, intern)                           \
-type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz,              \
-                                                                          jmethodID methodID, const jvalue *args) \
-{                                                                              \
-       methodinfo *m;                                                             \
-       type        res;                                                           \
-                                                                               \
-       m = (methodinfo *) methodID;                                               \
-                                                                               \
-       res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args);                  \
-                                                                               \
-       return res;                                                                \
-}
-
-JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
-JNI_CALL_STATIC_METHOD_A(Byte,    jbyte,    Int)
-JNI_CALL_STATIC_METHOD_A(Char,    jchar,    Int)
-JNI_CALL_STATIC_METHOD_A(Short,   jshort,   Int)
-JNI_CALL_STATIC_METHOD_A(Int,     jint,     Int)
-JNI_CALL_STATIC_METHOD_A(Long,    jlong,    Long)
-JNI_CALL_STATIC_METHOD_A(Float,   jfloat,   Float)
-JNI_CALL_STATIC_METHOD_A(Double,  jdouble,  Double)
-
-
-jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
-                                                                          jmethodID methodID, ...)
-{
-       methodinfo    *m;
-       java_handle_t *o;
-       va_list        ap;
-
-       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
-       va_end(ap);
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
-                                                                               jmethodID methodID, va_list args)
-{
-       methodinfo    *m;
-       java_handle_t *o;
-
-       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
-
-       m = (methodinfo *) methodID;
-
-       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
-                                                                               jmethodID methodID, const jvalue *args)
-{
-       methodinfo    *m;
-       java_handle_t *o;
-
-       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
-
-       m = (methodinfo *) methodID;
-
-       o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
-                                                                 jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-
-       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
-       va_end(ap);
-}
-
-
-void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
-                                                                  jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-
-       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
-
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
-}
-
-
-void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
-                                                                  jmethodID methodID, const jvalue * args)
-{
-       methodinfo *m;
-
-       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
-
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
-}
-
-
-/* Accessing Static Fields ****************************************************/
-
-/* GetStaticFieldID ************************************************************
-
-   Returns the field ID for a static field of a class. The field is
-   specified by its name and signature. The GetStatic<type>Field and
-   SetStatic<type>Field families of accessor functions use field IDs
-   to retrieve static fields.
-
-*******************************************************************************/
-
-jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
-                                                                 const char *sig)
-{
-       classinfo *c;
-       fieldinfo *f;
-       utf       *uname;
-       utf       *usig;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-
-       uname = utf_new_char((char *) name);
-       usig  = utf_new_char((char *) sig);
-
-       f = class_findfield(c, uname, usig);
-       
-       if (f == NULL)
-               exceptions_throw_nosuchfielderror(c, uname);
-
-       return (jfieldID) f;
-}
-
-
-/* GetStatic<type>Field ********************************************************
-
-   This family of accessor routines returns the value of a static
-   field of an object.
-
-*******************************************************************************/
-
-#define JNI_GET_STATIC_FIELD(name, type, field)                \
-type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
-                                                                       jfieldID fieldID)          \
-{                                                              \
-       classinfo *c;                                              \
-       fieldinfo *f;                                              \
-                                                               \
-       STATISTICS(jniinvokation());                               \
-                                                               \
-       c = LLNI_classinfo_unwrap(clazz);                          \
-       f = (fieldinfo *) fieldID;                                 \
-                                                               \
-       if (!(c->state & CLASS_INITIALIZED))                       \
-               if (!initialize_class(c))                              \
-                       return 0;                                          \
-                                                               \
-       return f->value->field;                                    \
-}
-
-JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
-JNI_GET_STATIC_FIELD(Byte,    jbyte,    i)
-JNI_GET_STATIC_FIELD(Char,    jchar,    i)
-JNI_GET_STATIC_FIELD(Short,   jshort,   i)
-JNI_GET_STATIC_FIELD(Int,     jint,     i)
-JNI_GET_STATIC_FIELD(Long,    jlong,    l)
-JNI_GET_STATIC_FIELD(Float,   jfloat,   f)
-JNI_GET_STATIC_FIELD(Double,  jdouble,  d)
-
-
-jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
-                                                                        jfieldID fieldID)
-{
-       classinfo     *c;
-       fieldinfo     *f;
-       java_handle_t *h;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return NULL;
-
-       h = LLNI_WRAP(f->value->a);
-
-       return jni_NewLocalRef(env, (jobject) h);
-}
-
-
-/*  SetStatic<type>Field *******************************************************
-
-       This family of accessor routines sets the value of a static field
-       of an object.
-
-*******************************************************************************/
-
-#define JNI_SET_STATIC_FIELD(name, type, field)                \
-void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
-                                                                       jfieldID fieldID,          \
-                                                                       type value)                \
-{                                                              \
-       classinfo *c;                                              \
-       fieldinfo *f;                                              \
-                                                               \
-       STATISTICS(jniinvokation());                               \
-                                                               \
-       c = LLNI_classinfo_unwrap(clazz);                          \
-       f = (fieldinfo *) fieldID;                                 \
-                                                               \
-       if (!(c->state & CLASS_INITIALIZED))                       \
-               if (!initialize_class(c))                              \
-                       return;                                            \
-                                                               \
-       f->value->field = value;                                   \
-}
-
-JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
-JNI_SET_STATIC_FIELD(Byte,    jbyte,    i)
-JNI_SET_STATIC_FIELD(Char,    jchar,    i)
-JNI_SET_STATIC_FIELD(Short,   jshort,   i)
-JNI_SET_STATIC_FIELD(Int,     jint,     i)
-JNI_SET_STATIC_FIELD(Long,    jlong,    l)
-JNI_SET_STATIC_FIELD(Float,   jfloat,   f)
-JNI_SET_STATIC_FIELD(Double,  jdouble,  d)
-
-
-void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
-                                                                 jobject value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value->a = LLNI_UNWRAP((java_handle_t *) value);
-}
-
-
-/* String Operations **********************************************************/
-
-/* NewString *******************************************************************
-
-   Create new java.lang.String object from an array of Unicode
-   characters.
-
-*******************************************************************************/
-
-jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
-{
-       java_lang_String        *s;
-       java_handle_chararray_t *a;
-       u4                       i;
-
-       STATISTICS(jniinvokation());
-       
-       s = (java_lang_String *) builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(len);
-
-       /* javastring or characterarray could not be created */
-       if ((a == NULL) || (s == NULL))
-               return NULL;
-
-       /* copy text */
-       for (i = 0; i < len; i++)
-               LLNI_array_direct(a, i) = buf[i];
-
-       LLNI_field_set_ref(s, value , a);
-       LLNI_field_set_val(s, offset, 0);
-       LLNI_field_set_val(s, count , len);
-
-       return (jstring) jni_NewLocalRef(env, (jobject) s);
-}
-
-
-static jchar emptyStringJ[]={0,0};
-
-/* GetStringLength *************************************************************
-
-   Returns the length (the count of Unicode characters) of a Java
-   string.
-
-*******************************************************************************/
-
-jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
-{
-       java_lang_String *s;
-       jsize             len;
-
-       TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
-
-       s = (java_lang_String *) str;
-
-       LLNI_field_get_val(s, count, len);
-
-       return len;
-}
-
-
-/********************  convertes javastring to u2-array ****************************/
-       
-u2 *javastring_tou2(jstring so) 
-{
-       java_lang_String        *s;
-       java_handle_chararray_t *a;
-       u2                      *stringbuffer;
-       u4                       i;
-       int32_t                  count;
-       int32_t                  offset;
-
-       STATISTICS(jniinvokation());
-       
-       s = (java_lang_String *) so;
-
-       if (!s)
-               return NULL;
-
-       LLNI_field_get_ref(s, value, a);
-
-       if (!a)
-               return NULL;
-
-       LLNI_field_get_val(s, count, count);
-       LLNI_field_get_val(s, offset, offset);
-
-       /* allocate memory */
-
-       stringbuffer = MNEW(u2, count + 1);
-
-       /* copy text */
-
-       for (i = 0; i < count; i++)
-               stringbuffer[i] = LLNI_array_direct(a, offset + i);
-       
-       /* terminate string */
-
-       stringbuffer[i] = '\0';
-
-       return stringbuffer;
-}
-
-
-/* GetStringChars **************************************************************
-
-   Returns a pointer to the array of Unicode characters of the
-   string. This pointer is valid until ReleaseStringChars() is called.
-
-*******************************************************************************/
-
-const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
-{      
-       jchar *jc;
-
-       STATISTICS(jniinvokation());
-
-       jc = javastring_tou2(str);
-
-       if (jc) {
-               if (isCopy)
-                       *isCopy = JNI_TRUE;
-
-               return jc;
-       }
-
-       if (isCopy)
-               *isCopy = JNI_TRUE;
-
-       return emptyStringJ;
-}
-
-
-/* ReleaseStringChars **********************************************************
-
-   Informs the VM that the native code no longer needs access to
-   chars. The chars argument is a pointer obtained from string using
-   GetStringChars().
-
-*******************************************************************************/
-
-void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
-{
-       java_lang_String *s;
-
-       STATISTICS(jniinvokation());
-
-       if (chars == emptyStringJ)
-               return;
-
-       s = (java_lang_String *) str;
-
-       MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
-}
-
-
-/* NewStringUTF ****************************************************************
-
-   Constructs a new java.lang.String object from an array of UTF-8
-   characters.
-
-*******************************************************************************/
-
-jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
-{
-       java_lang_String *s;
-
-       TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
-
-       s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
-
-    return (jstring) jni_NewLocalRef(env, (jobject) s);
-}
-
-
-/****************** returns the utf8 length in bytes of a string *******************/
-
-jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
-{   
-       java_lang_String *s;
-       s4                length;
-
-       TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
-
-       s = (java_lang_String *) string;
-
-       length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
-
-       return length;
-}
-
-
-/* GetStringUTFChars ***********************************************************
-
-   Returns a pointer to an array of UTF-8 characters of the
-   string. This array is valid until it is released by
-   ReleaseStringUTFChars().
-
-*******************************************************************************/
-
-const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
-                                                                         jboolean *isCopy)
-{
-       utf *u;
-
-       STATISTICS(jniinvokation());
-
-       if (string == NULL)
-               return "";
-
-       if (isCopy)
-               *isCopy = JNI_TRUE;
-       
-       u = javastring_toutf((java_handle_t *) string, false);
-
-       if (u != NULL)
-               return u->text;
-
-       return "";
-}
-
-
-/* ReleaseStringUTFChars *******************************************************
-
-   Informs the VM that the native code no longer needs access to
-   utf. The utf argument is a pointer derived from string using
-   GetStringUTFChars().
-
-*******************************************************************************/
-
-void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
-{
-       STATISTICS(jniinvokation());
-
-    /* XXX we don't release utf chars right now, perhaps that should be done 
-          later. Since there is always one reference the garbage collector will
-          never get them */
-}
-
-
-/* Array Operations ***********************************************************/
-
-/* GetArrayLength **************************************************************
-
-   Returns the number of elements in the array.
-
-*******************************************************************************/
-
-jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
-{
-       java_handle_t *a;
-       jsize          size;
-
-       TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
-
-       a = (java_handle_t *) array;
-
-       size = LLNI_array_size(a);
-
-       return size;
-}
-
-
-/* NewObjectArray **************************************************************
-
-   Constructs a new array holding objects in class elementClass. All
-   elements are initially set to initialElement.
-
-*******************************************************************************/
-
-jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
-                                                                       jclass elementClass, jobject initialElement)
-{
-       classinfo                 *c;
-       java_handle_t             *o;
-       java_handle_objectarray_t *oa;
-       s4                         i;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(elementClass);
-       o = (java_handle_t *) initialElement;
-
-       if (length < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-    oa = builtin_anewarray(length, c);
-
-       if (oa == NULL)
-               return NULL;
-
-       /* set all elements to initialElement */
-
-       for (i = 0; i < length; i++)
-               array_objectarray_element_set(oa, i, o);
-
-       return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
-}
-
-
-jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
-                                                                         jsize index)
-{
-       java_handle_objectarray_t *oa;
-       java_handle_t             *o;
-
-       STATISTICS(jniinvokation());
-
-       oa = (java_handle_objectarray_t *) array;
-
-       if (index >= LLNI_array_size(oa)) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       o = array_objectarray_element_get(oa, index);
-
-       return jni_NewLocalRef(env, (jobject) o);
-}
-
-
-void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
-                                                                  jsize index, jobject val)
-{
-       java_handle_objectarray_t *oa;
-       java_handle_t             *o;
-
-       STATISTICS(jniinvokation());
-
-       oa = (java_handle_objectarray_t *) array;
-       o  = (java_handle_t *) val;
-
-       if (index >= LLNI_array_size(oa)) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return;
-       }
-
-       /* check if the class of value is a subclass of the element class
-          of the array */
-
-       if (!builtin_canstore(oa, o))
-               return;
-
-       array_objectarray_element_set(oa, index, o);
-}
-
-
-#define JNI_NEW_ARRAY(name, type, intern)                \
-type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
-{                                                        \
-       java_handle_##intern##array_t *a;                    \
-                                                         \
-       STATISTICS(jniinvokation());                         \
-                                                         \
-       if (len < 0) {                                       \
-               exceptions_throw_negativearraysizeexception();   \
-               return NULL;                                     \
-       }                                                    \
-                                                         \
-       a = builtin_newarray_##intern(len);                  \
-                                                         \
-       return (type) jni_NewLocalRef(env, (jobject) a); \
-}
-
-JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
-JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
-JNI_NEW_ARRAY(Char,    jcharArray,    char)
-JNI_NEW_ARRAY(Short,   jshortArray,   short)
-JNI_NEW_ARRAY(Int,     jintArray,     int)
-JNI_NEW_ARRAY(Long,    jlongArray,    long)
-JNI_NEW_ARRAY(Float,   jfloatArray,   float)
-JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
-
-
-/* Get<PrimitiveType>ArrayElements *********************************************
-
-   A family of functions that returns the body of the primitive array.
-
-*******************************************************************************/
-
-#define JNI_GET_ARRAY_ELEMENTS(name, type, intern)                     \
-type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
-                                                                                jboolean *isCopy)             \
-{                                                                      \
-       java_handle_##intern##array_t *a;                                  \
-                                                                       \
-       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
-                                                                       \
-       a = (java_handle_##intern##array_t *) array;                       \
-                                                                       \
-       if (isCopy)                                                        \
-               *isCopy = JNI_FALSE;                                           \
-                                                                       \
-       return (type *) LLNI_array_data(a);                                \
-}
-
-JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
-JNI_GET_ARRAY_ELEMENTS(Byte,    jbyte,    byte)
-JNI_GET_ARRAY_ELEMENTS(Char,    jchar,    char)
-JNI_GET_ARRAY_ELEMENTS(Short,   jshort,   short)
-JNI_GET_ARRAY_ELEMENTS(Int,     jint,     int)
-JNI_GET_ARRAY_ELEMENTS(Long,    jlong,    long)
-JNI_GET_ARRAY_ELEMENTS(Float,   jfloat,   float)
-JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
-
-
-/* Release<PrimitiveType>ArrayElements *****************************************
-
-   A family of functions that informs the VM that the native code no
-   longer needs access to elems. The elems argument is a pointer
-   derived from array using the corresponding
-   Get<PrimitiveType>ArrayElements() function. If necessary, this
-   function copies back all changes made to elems to the original
-   array.
-
-*******************************************************************************/
-
-#define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2)            \
-void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array,  \
-                                                                                 type *elems, jint mode)          \
-{                                                                          \
-       java_handle_##intern##array_t *a;                                      \
-                                                                           \
-       STATISTICS(jniinvokation());                                           \
-                                                                           \
-       a = (java_handle_##intern##array_t *) array;                           \
-                                                                           \
-       if (elems != (type *) LLNI_array_data(a)) {                            \
-               switch (mode) {                                                    \
-               case JNI_COMMIT:                                                   \
-                       MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
-                       break;                                                         \
-               case 0:                                                            \
-                       MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
-                       /* XXX TWISTI how should it be freed? */                       \
-                       break;                                                         \
-               case JNI_ABORT:                                                    \
-                       /* XXX TWISTI how should it be freed? */                       \
-                       break;                                                         \
-               }                                                                  \
-       }                                                                      \
-}
-
-JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
-JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    s1)
-JNI_RELEASE_ARRAY_ELEMENTS(Char,    jchar,    char,    u2)
-JNI_RELEASE_ARRAY_ELEMENTS(Short,   jshort,   short,   s2)
-JNI_RELEASE_ARRAY_ELEMENTS(Int,     jint,     int,     s4)
-JNI_RELEASE_ARRAY_ELEMENTS(Long,    jlong,    long,    s8)
-JNI_RELEASE_ARRAY_ELEMENTS(Float,   jfloat,   float,   float)
-JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
-
-
-/*  Get<PrimitiveType>ArrayRegion **********************************************
-
-       A family of functions that copies a region of a primitive array
-       into a buffer.
-
-*******************************************************************************/
-
-#define JNI_GET_ARRAY_REGION(name, type, intern, intern2)               \
-void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
-                                                                       jsize start, jsize len, type *buf)  \
-{                                                                       \
-       java_handle_##intern##array_t *a;                                   \
-                                                                        \
-       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
-                                                                        \
-       a = (java_handle_##intern##array_t *) array;                        \
-                                                                        \
-       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
-               exceptions_throw_arrayindexoutofboundsexception();              \
-       else                                                                \
-               MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
-}
-
-JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
-JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
-JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
-JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
-JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
-JNI_GET_ARRAY_REGION(Long,    jlong,    long,    s8)
-JNI_GET_ARRAY_REGION(Float,   jfloat,   float,   float)
-JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
-
-
-/*  Set<PrimitiveType>ArrayRegion **********************************************
-
-       A family of functions that copies back a region of a primitive
-       array from a buffer.
-
-*******************************************************************************/
-
-#define JNI_SET_ARRAY_REGION(name, type, intern, intern2)                    \
-void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
-                                                                       jsize start, jsize len, const type *buf) \
-{                                                                            \
-       java_handle_##intern##array_t *a;                                        \
-                                                                             \
-       STATISTICS(jniinvokation());                                             \
-                                                                             \
-       a = (java_handle_##intern##array_t *) array;                             \
-                                                                             \
-       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
-               exceptions_throw_arrayindexoutofboundsexception();                   \
-       else                                                                     \
-               MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
-}
-
-JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
-JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
-JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
-JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
-JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
-JNI_SET_ARRAY_REGION(Long,    jlong,    long,    s8)
-JNI_SET_ARRAY_REGION(Float,   jfloat,   float,   float)
-JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
-
-
-/* Registering Native Methods *************************************************/
-
-/* RegisterNatives *************************************************************
-
-   Registers native methods with the class specified by the clazz
-   argument. The methods parameter specifies an array of
-   JNINativeMethod structures that contain the names, signatures, and
-   function pointers of the native methods. The nMethods parameter
-   specifies the number of native methods in the array.
-
-*******************************************************************************/
-
-jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
-                                                        const JNINativeMethod *methods, jint nMethods)
-{
-       classinfo *c;
-
-       STATISTICS(jniinvokation());
-
-       c = LLNI_classinfo_unwrap(clazz);
-
-       /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
-       if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
-       */
-
-       native_method_register(c->name, methods, nMethods);
-
-    return 0;
-}
-
-
-/* UnregisterNatives ***********************************************************
-
-   Unregisters native methods of a class. The class goes back to the
-   state before it was linked or registered with its native method
-   functions.
-
-   This function should not be used in normal native code. Instead, it
-   provides special programs a way to reload and relink native
-   libraries.
-
-*******************************************************************************/
-
-jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
-{
-       STATISTICS(jniinvokation());
-
-       /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
-
-    log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
-
-    return 0;
-}
-
-
-/* Monitor Operations *********************************************************/
-
-/* MonitorEnter ****************************************************************
-
-   Enters the monitor associated with the underlying Java object
-   referred to by obj.
-
-*******************************************************************************/
-
-jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
-{
-       STATISTICS(jniinvokation());
-
-       if (obj == NULL) {
-               exceptions_throw_nullpointerexception();
-               return JNI_ERR;
-       }
-
-       LOCK_MONITOR_ENTER(obj);
-
-       return JNI_OK;
-}
-
-
-/* MonitorExit *****************************************************************
-
-   The current thread must be the owner of the monitor associated with
-   the underlying Java object referred to by obj. The thread
-   decrements the counter indicating the number of times it has
-   entered this monitor. If the value of the counter becomes zero, the
-   current thread releases the monitor.
-
-*******************************************************************************/
-
-jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
-{
-       STATISTICS(jniinvokation());
-
-       if (obj == NULL) {
-               exceptions_throw_nullpointerexception();
-               return JNI_ERR;
-       }
-
-       LOCK_MONITOR_EXIT(obj);
-
-       return JNI_OK;
-}
-
-
-/* JavaVM Interface ***********************************************************/
-
-/* GetJavaVM *******************************************************************
-
-   Returns the Java VM interface (used in the Invocation API)
-   associated with the current thread. The result is placed at the
-   location pointed to by the second argument, vm.
-
-*******************************************************************************/
-
-jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
-{
-       STATISTICS(jniinvokation());
-
-    *vm = (JavaVM *) _Jv_jvm;
-
-       return 0;
-}
-
-
-/* GetStringRegion *************************************************************
-
-   Copies len number of Unicode characters beginning at offset start
-   to the given buffer buf.
-
-   Throws StringIndexOutOfBoundsException on index overflow.
-
-*******************************************************************************/
-
-void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
-                                                        jchar *buf)
-{
-       java_lang_String        *s;
-       java_handle_chararray_t *ca;
-
-       STATISTICS(jniinvokation());
-
-       s  = (java_lang_String *) str;
-       LLNI_field_get_ref(s, value, ca);
-
-       if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
-               (start + len > LLNI_field_direct(s, count))) {
-               exceptions_throw_stringindexoutofboundsexception();
-               return;
-       }
-
-       MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
-}
-
-
-/* GetStringUTFRegion **********************************************************
-
-    Translates len number of Unicode characters beginning at offset
-    start into UTF-8 format and place the result in the given buffer
-    buf.
-
-    Throws StringIndexOutOfBoundsException on index overflow. 
-
-*******************************************************************************/
-
-void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
-                                                               jsize len, char *buf)
-{
-       java_lang_String        *s;
-       java_handle_chararray_t *ca;
-       s4                       i;
-       int32_t                  count;
-       int32_t                  offset;
-
-       TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
-
-       s  = (java_lang_String *) str;
-       LLNI_field_get_ref(s, value, ca);
-       LLNI_field_get_val(s, count, count);
-       LLNI_field_get_val(s, offset, offset);
-
-       if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
-               exceptions_throw_stringindexoutofboundsexception();
-               return;
-       }
-
-       for (i = 0; i < len; i++)
-               buf[i] = LLNI_array_direct(ca, offset + start + i);
-
-       buf[i] = '\0';
-}
-
-
-/* GetPrimitiveArrayCritical ***************************************************
-
-   Obtain a direct pointer to array elements.
-
-   ATTENTION: Critical section keeps open when this function returns!
-   See ReleasePrimitiveArrayCritical.
-
-*******************************************************************************/
-
-void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
-{
-       java_handle_t*   h;
-       java_array_t*    a;
-       arraydescriptor* ad;
-       void*            data;
-
-       TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
-
-       if (isCopy != NULL) {
-               *isCopy = JNI_FALSE;
-       }
-
-       LLNI_CRITICAL_START;
-
-       h  = (java_handle_t*) array;
-       a  = (java_array_t*) LLNI_UNWRAP(h);
-       ad = a->objheader.vftbl->arraydesc;
-
-       /* Sanity check. */
-
-       assert(ad != NULL);
-
-       data = (void*) (((intptr_t) a) + ad->dataoffset);
-
-       return data;
-}
-
-
-/* ReleasePrimitiveArrayCritical ***********************************************
-
-   No specific documentation.
-
-   ATTENTION: This function closes the critical section opened in
-   GetPrimitiveArrayCritical!
-
-*******************************************************************************/
-
-void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
-{
-       TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
-
-       LLNI_CRITICAL_END;
-}
-
-
-/* GetStringCritical ***********************************************************
-
-   The semantics of these two functions are similar to the existing
-   Get/ReleaseStringChars functions.
-
-*******************************************************************************/
-
-const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
-                                                                          jboolean *isCopy)
-{
-       STATISTICS(jniinvokation());
-
-       return _Jv_JNI_GetStringChars(env, string, isCopy);
-}
-
-
-void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
-                                                                  const jchar *cstring)
-{
-       STATISTICS(jniinvokation());
-
-       _Jv_JNI_ReleaseStringChars(env, string, cstring);
-}
-
-
-jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
-{
-       TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
-
-       return obj;
-}
-
-
-void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
-{
-       TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
-}
-
-
-/* NewGlobalRef ****************************************************************
-
-   Creates a new global reference to the object referred to by the obj
-   argument.
-
-*******************************************************************************/
-    
-jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
-{
-       hashtable_global_ref_entry *gre;
-       u4   key;                           /* hashkey                            */
-       u4   slot;                          /* slot in hashtable                  */
-       java_handle_t *o;
-
-       TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
-
-       o = (java_handle_t *) obj;
-
-       LOCK_MONITOR_ENTER(hashtable_global_ref->header);
-
-       LLNI_CRITICAL_START;
-
-       /* normally addresses are aligned to 4, 8 or 16 bytes */
-
-       key  = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
-       slot = key & (hashtable_global_ref->size - 1);
-       gre  = hashtable_global_ref->ptr[slot];
-       
-       /* search external hash chain for the entry */
-
-       while (gre) {
-               if (gre->o == LLNI_DIRECT(o)) {
-                       /* global object found, increment the reference */
-
-                       gre->refs++;
-
-                       break;
-               }
-
-               gre = gre->hashlink;                /* next element in external chain */
-       }
-
-       LLNI_CRITICAL_END;
-
-       /* global ref not found, create a new one */
-
-       if (gre == NULL) {
-               gre = GCNEW_UNCOLLECTABLE(hashtable_global_ref_entry, 1);
-
-#if defined(ENABLE_GC_CACAO)
-               /* register global ref with the GC */
-
-               gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
-#endif
-
-               LLNI_CRITICAL_START;
-
-               gre->o    = LLNI_DIRECT(o);
-               gre->refs = 1;
-
-               LLNI_CRITICAL_END;
-
-               /* insert entry into hashtable */
-
-               gre->hashlink = hashtable_global_ref->ptr[slot];
-
-               hashtable_global_ref->ptr[slot] = gre;
-
-               /* update number of hashtable-entries */
-
-               hashtable_global_ref->entries++;
-       }
-
-       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
-
-#if defined(ENABLE_HANDLES)
-       return gre;
-#else
-       return obj;
-#endif
-}
-
-
-/* DeleteGlobalRef *************************************************************
-
-   Deletes the global reference pointed to by globalRef.
-
-*******************************************************************************/
-
-void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
-{
-       hashtable_global_ref_entry *gre;
-       hashtable_global_ref_entry *prevgre;
-       u4   key;                           /* hashkey                            */
-       u4   slot;                          /* slot in hashtable                  */
-       java_handle_t              *o;
-
-       TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
-
-       o = (java_handle_t *) globalRef;
-
-       LOCK_MONITOR_ENTER(hashtable_global_ref->header);
-
-       LLNI_CRITICAL_START;
-
-       /* normally addresses are aligned to 4, 8 or 16 bytes */
-
-       key  = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
-       slot = key & (hashtable_global_ref->size - 1);
-       gre  = hashtable_global_ref->ptr[slot];
-
-       /* initialize prevgre */
-
-       prevgre = NULL;
-
-       /* search external hash chain for the entry */
-
-       while (gre) {
-               if (gre->o == LLNI_DIRECT(o)) {
-                       /* global object found, decrement the reference count */
-
-                       gre->refs--;
-
-                       /* if reference count is 0, remove the entry */
-
-                       if (gre->refs == 0) {
-                               /* special handling if it's the first in the chain */
-
-                               if (prevgre == NULL)
-                                       hashtable_global_ref->ptr[slot] = gre->hashlink;
-                               else
-                                       prevgre->hashlink = gre->hashlink;
-
-#if defined(ENABLE_GC_CACAO)
-                               /* unregister global ref with the GC */
-
-                               gc_reference_unregister(&(gre->o));
-#endif
-
-                               GCFREE(gre);
-                       }
-
-                       LLNI_CRITICAL_END;
-
-                       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
-
-                       return;
-               }
-
-               prevgre = gre;                    /* save current pointer for removal */
-               gre     = gre->hashlink;            /* next element in external chain */
-       }
-
-       log_println("jni_DeleteGlobalRef: Global reference not found.");
-
-       LLNI_CRITICAL_END;
-
-       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
-}
-
-
-/* ExceptionCheck **************************************************************
-
-   Returns JNI_TRUE when there is a pending exception; otherwise,
-   returns JNI_FALSE.
-
-*******************************************************************************/
-
-jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
-{
-       java_handle_t *o;
-
-       STATISTICS(jniinvokation());
-
-       o = exceptions_get_exception();
-
-       return (o != NULL) ? JNI_TRUE : JNI_FALSE;
-}
-
-
-/* New JNI 1.4 functions ******************************************************/
-
-/* NewDirectByteBuffer *********************************************************
-
-   Allocates and returns a direct java.nio.ByteBuffer referring to the
-   block of memory starting at the memory address address and
-   extending capacity bytes.
-
-*******************************************************************************/
-
-jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
-{
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_handle_t           *nbuf;
-
-# if SIZEOF_VOID_P == 8
-       gnu_classpath_Pointer64 *paddress;
-# else
-       gnu_classpath_Pointer32 *paddress;
-# endif
-
-       TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
-
-       /* alocate a gnu.classpath.Pointer{32,64} object */
-
-# if SIZEOF_VOID_P == 8
-       if (!(paddress = (gnu_classpath_Pointer64 *)
-                 builtin_new(class_gnu_classpath_Pointer64)))
-# else
-       if (!(paddress = (gnu_classpath_Pointer32 *)
-                 builtin_new(class_gnu_classpath_Pointer32)))
-# endif
-               return NULL;
-
-       /* fill gnu.classpath.Pointer{32,64} with address */
-
-       LLNI_field_set_val(paddress, data, (ptrint) address);
-
-       /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
-
-       nbuf = (*env)->NewObject(env, class_java_nio_DirectByteBufferImpl_ReadWrite,
-                                                        (jmethodID) dbbirw_init, NULL, paddress,
-                                                        (jint) capacity, (jint) capacity, (jint) 0);
-
-       /* add local reference and return the value */
-
-       TRACEJNICALLSEXIT(("->%p", nbuf));
-
-       return jni_NewLocalRef(env, nbuf);
-
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       jobject o;
-       int64_t addr;
-       int32_t cap;
-
-       TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
-
-       /* Be paranoid about address sign-extension. */
-
-       addr = (int64_t) ((uintptr_t) address);
-       cap  = (int32_t) capacity;
-
-       o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
-                                                 (jmethodID) dbb_init, addr, cap);
-
-       /* Add local reference and return the value. */
-
-       TRACEJNICALLSEXIT(("->%p", o));
-
-       return jni_NewLocalRef(env, o);
-
-# else
-#  error unknown classpath configuration
-# endif
-
-#else
-       vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
-
-       /* keep compiler happy */
-
-       return NULL;
-#endif
-}
-
-
-/* GetDirectBufferAddress ******************************************************
-
-   Fetches and returns the starting address of the memory region
-   referenced by the given direct java.nio.Buffer.
-
-*******************************************************************************/
-
-void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
-{
-#if defined(ENABLE_JAVASE)
-       java_handle_t                 *h;
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       java_nio_DirectByteBufferImpl *nbuf;
-       gnu_classpath_Pointer         *po;
-#  if SIZEOF_VOID_P == 8
-       gnu_classpath_Pointer64       *paddress;
-       int64_t                        address;
-#  else
-       gnu_classpath_Pointer32       *paddress;
-       int32_t                        address;
-#  endif
-       void                          *p;
-
-       TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
-
-       /* Prevent compiler warning. */
-
-       h = (java_handle_t *) buf;
-
-       if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
-               return NULL;
-
-       nbuf = (java_nio_DirectByteBufferImpl *) buf;
-
-       LLNI_field_get_ref(nbuf, address, po);
-
-#  if SIZEOF_VOID_P == 8
-       paddress = (gnu_classpath_Pointer64 *) po;
-#  else
-       paddress = (gnu_classpath_Pointer32 *) po;
-#  endif
-
-       if (paddress == NULL)
-               return NULL;
-
-       LLNI_field_get_val(paddress, data, address);
-
-       p = (void *) (intptr_t) address;
-
-       return p;
-
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       java_nio_Buffer *o;
-       int64_t          address;
-       void            *p;
-
-       TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
-
-       /* Prevent compiler warning. */
-
-       h = (java_handle_t *) buf;
-
-       if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
-               return NULL;
-
-       o = (java_nio_Buffer *) buf;
-
-       LLNI_field_get_val(o, address, address);
-
-       p = (void *) (intptr_t) address;
-
-       return p;
-
-# else
-#  error unknown classpath configuration
-# endif
-
-#else
-
-       vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
-
-       /* keep compiler happy */
-
-       return NULL;
-
-#endif
-}
-
-
-/* GetDirectBufferCapacity *****************************************************
-
-   Fetches and returns the capacity in bytes of the memory region
-   referenced by the given direct java.nio.Buffer.
-
-*******************************************************************************/
-
-jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
-{
-#if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_handle_t   *o;
-       java_nio_Buffer *nbuf;
-       jlong            capacity;
-
-       STATISTICS(jniinvokation());
-
-       o = (java_handle_t *) buf;
-
-       if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
-               return -1;
-
-       nbuf = (java_nio_Buffer *) o;
-
-       LLNI_field_get_val(nbuf, cap, capacity);
-
-       return capacity;
-#else
-       vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
-
-       /* keep compiler happy */
-
-       return 0;
-#endif
-}
-
-
-/* GetObjectRefType ************************************************************
-
-   Returns the type of the object referred to by the obj argument. The
-   argument obj can either be a local, global or weak global
-   reference.
-
-*******************************************************************************/
-
-jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
-{
-       log_println("jni_GetObjectRefType: IMPLEMENT ME!");
-
-       return -1;
-}
-
-
-/* DestroyJavaVM ***************************************************************
-
-   Unloads a Java VM and reclaims its resources. Only the main thread
-   can unload the VM. The system waits until the main thread is only
-   remaining user thread before it destroys the VM.
-
-*******************************************************************************/
-
-jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
-{
-       int status;
-
-       TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
-
-       if (vm_created == false)
-               return JNI_ERR;
-
-    status = vm_destroy(vm);
-
-       return status;
-}
-
-
-/* AttachCurrentThread *********************************************************
-
-   Attaches the current thread to a Java VM. Returns a JNI interface
-   pointer in the JNIEnv argument.
-
-   Trying to attach a thread that is already attached is a no-op.
-
-   A native thread cannot be attached simultaneously to two Java VMs.
-
-   When a thread is attached to the VM, the context class loader is
-   the bootstrap loader.
-
-*******************************************************************************/
-
-static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
-{
-#if defined(ENABLE_THREADS)
-       JavaVMAttachArgs *vm_aargs;
-       bool              result;
-
-    /* If the current thread has already been attached, this operation
-          is a no-op. */
-
-       result = thread_current_is_attached();
-
-       if (result == true) {
-               *p_env = _Jv_env;
-
-               return JNI_OK;
-       }
-
-       vm_aargs = (JavaVMAttachArgs *) thr_args;
-
-       if (vm_aargs != NULL) {
-               if ((vm_aargs->version != JNI_VERSION_1_2) &&
-                       (vm_aargs->version != JNI_VERSION_1_4))
-                       return JNI_EVERSION;
-       }
-
-       if (!thread_attach_current_external_thread(vm_aargs, false))
-               return JNI_ERR;
-
-       if (!localref_table_init())
-               return JNI_ERR;
-#endif
-
-       *p_env = _Jv_env;
-
-       return JNI_OK;
-}
-
-
-jint jni_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
-{
-       int result;
-
-       TRACEJNICALLS(("jni_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
-
-       if (vm_created == false)
-               return JNI_ERR;
-
-       result = jni_attach_current_thread(p_env, thr_args, false);
-
-       return result;
-}
-
-
-/* DetachCurrentThread *********************************************************
-
-   Detaches the current thread from a Java VM. All Java monitors held
-   by this thread are released. All Java threads waiting for this
-   thread to die are notified.
-
-   In JDK 1.1, the main thread cannot be detached from the VM. It must
-   call DestroyJavaVM to unload the entire VM.
-
-   In the JDK, the main thread can be detached from the VM.
-
-   The main thread, which is the thread that created the Java VM,
-   cannot be detached from the VM. Instead, the main thread must call
-   JNI_DestroyJavaVM() to unload the entire VM.
-
-*******************************************************************************/
-
-jint jni_DetachCurrentThread(JavaVM *vm)
-{
-#if defined(ENABLE_THREADS)
-       bool result;
-
-       TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
-
-    /* If the current thread has already been detached, this operation
-          is a no-op. */
-
-       result = thread_current_is_attached();
-
-       if (result == false)
-               return true;
-
-       /* We need to pop all frames before we can destroy the table. */
-
-       localref_frame_pop_all();
-
-       if (!localref_table_destroy())
-               return JNI_ERR;
-
-       if (!thread_detach_current_external_thread())
-               return JNI_ERR;
-#endif
-
-       return JNI_OK;
-}
-
-
-/* GetEnv **********************************************************************
-
-   If the current thread is not attached to the VM, sets *env to NULL,
-   and returns JNI_EDETACHED. If the specified version is not
-   supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
-   sets *env to the appropriate interface, and returns JNI_OK.
-
-*******************************************************************************/
-
-jint jni_GetEnv(JavaVM *vm, void **env, jint version)
-{
-       TRACEJNICALLS(("jni_GetEnv(vm=%p, env=%p, version=%d)", vm, env, version));
-
-       if (vm_created == false) {
-               *env = NULL;
-               return JNI_EDETACHED;
-       }
-
-#if defined(ENABLE_THREADS)
-       if (thread_get_current() == NULL) {
-               *env = NULL;
-
-               return JNI_EDETACHED;
-       }
-#endif
-
-       /* Check the JNI version. */
-
-       if (jni_version_check(version) == true) {
-               *env = _Jv_env;
-               return JNI_OK;
-       }
-
-#if defined(ENABLE_JVMTI)
-       if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
-               == JVMTI_VERSION_INTERFACE_JVMTI) {
-
-               *env = (void *) jvmti_new_environment();
-
-               if (env != NULL)
-                       return JNI_OK;
-       }
-#endif
-       
-       *env = NULL;
-
-       return JNI_EVERSION;
-}
-
-
-/* AttachCurrentThreadAsDaemon *************************************************
-
-   Same semantics as AttachCurrentThread, but the newly-created
-   java.lang.Thread instance is a daemon.
-
-   If the thread has already been attached via either
-   AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
-   simply sets the value pointed to by penv to the JNIEnv of the
-   current thread. In this case neither AttachCurrentThread nor this
-   routine have any effect on the daemon status of the thread.
-
-*******************************************************************************/
-
-jint jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
-{
-       int result;
-
-       TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
-
-       if (vm_created == false)
-               return JNI_ERR;
-
-       result = jni_attach_current_thread(penv, args, true);
-
-       return result;
-}
-
-
-/* JNI invocation table *******************************************************/
-
-const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
-       NULL,
-       NULL,
-       NULL,
-
-       _Jv_JNI_DestroyJavaVM,
-       jni_AttachCurrentThread,
-       jni_DetachCurrentThread,
-       jni_GetEnv,
-       jni_AttachCurrentThreadAsDaemon
-};
-
-
-/* JNI function table *********************************************************/
-
-struct JNINativeInterface_ _Jv_JNINativeInterface = {
-       NULL,
-       NULL,
-       NULL,
-       NULL,    
-       _Jv_JNI_GetVersion,
-
-       _Jv_JNI_DefineClass,
-       jni_FindClass,
-       jni_FromReflectedMethod,
-       jni_FromReflectedField,
-       _Jv_JNI_ToReflectedMethod,
-       _Jv_JNI_GetSuperclass,
-       _Jv_JNI_IsAssignableFrom,
-       _Jv_JNI_ToReflectedField,
-
-       _Jv_JNI_Throw,
-       _Jv_JNI_ThrowNew,
-       _Jv_JNI_ExceptionOccurred,
-       jni_ExceptionDescribe,
-       jni_ExceptionClear,
-       _Jv_JNI_FatalError,
-       jni_PushLocalFrame,
-       jni_PopLocalFrame,
-
-       jni_NewGlobalRef,
-       jni_DeleteGlobalRef,
-       jni_DeleteLocalRef,
-       _Jv_JNI_IsSameObject,
-       jni_NewLocalRef,
-       jni_EnsureLocalCapacity,
-
-       _Jv_JNI_AllocObject,
-       jni_NewObject,
-       _Jv_JNI_NewObjectV,
-       _Jv_JNI_NewObjectA,
-
-       _Jv_JNI_GetObjectClass,
-       _Jv_JNI_IsInstanceOf,
-
-       _Jv_JNI_GetMethodID,
-
-       _Jv_JNI_CallObjectMethod,
-       _Jv_JNI_CallObjectMethodV,
-       _Jv_JNI_CallObjectMethodA,
-       _Jv_JNI_CallBooleanMethod,
-       _Jv_JNI_CallBooleanMethodV,
-       _Jv_JNI_CallBooleanMethodA,
-       _Jv_JNI_CallByteMethod,
-       _Jv_JNI_CallByteMethodV,
-       _Jv_JNI_CallByteMethodA,
-       _Jv_JNI_CallCharMethod,
-       _Jv_JNI_CallCharMethodV,
-       _Jv_JNI_CallCharMethodA,
-       _Jv_JNI_CallShortMethod,
-       _Jv_JNI_CallShortMethodV,
-       _Jv_JNI_CallShortMethodA,
-       _Jv_JNI_CallIntMethod,
-       _Jv_JNI_CallIntMethodV,
-       _Jv_JNI_CallIntMethodA,
-       _Jv_JNI_CallLongMethod,
-       _Jv_JNI_CallLongMethodV,
-       _Jv_JNI_CallLongMethodA,
-       _Jv_JNI_CallFloatMethod,
-       _Jv_JNI_CallFloatMethodV,
-       _Jv_JNI_CallFloatMethodA,
-       _Jv_JNI_CallDoubleMethod,
-       _Jv_JNI_CallDoubleMethodV,
-       _Jv_JNI_CallDoubleMethodA,
-       _Jv_JNI_CallVoidMethod,
-       _Jv_JNI_CallVoidMethodV,
-       _Jv_JNI_CallVoidMethodA,
-
-       _Jv_JNI_CallNonvirtualObjectMethod,
-       _Jv_JNI_CallNonvirtualObjectMethodV,
-       _Jv_JNI_CallNonvirtualObjectMethodA,
-       _Jv_JNI_CallNonvirtualBooleanMethod,
-       _Jv_JNI_CallNonvirtualBooleanMethodV,
-       _Jv_JNI_CallNonvirtualBooleanMethodA,
-       _Jv_JNI_CallNonvirtualByteMethod,
-       _Jv_JNI_CallNonvirtualByteMethodV,
-       _Jv_JNI_CallNonvirtualByteMethodA,
-       _Jv_JNI_CallNonvirtualCharMethod,
-       _Jv_JNI_CallNonvirtualCharMethodV,
-       _Jv_JNI_CallNonvirtualCharMethodA,
-       _Jv_JNI_CallNonvirtualShortMethod,
-       _Jv_JNI_CallNonvirtualShortMethodV,
-       _Jv_JNI_CallNonvirtualShortMethodA,
-       _Jv_JNI_CallNonvirtualIntMethod,
-       _Jv_JNI_CallNonvirtualIntMethodV,
-       _Jv_JNI_CallNonvirtualIntMethodA,
-       _Jv_JNI_CallNonvirtualLongMethod,
-       _Jv_JNI_CallNonvirtualLongMethodV,
-       _Jv_JNI_CallNonvirtualLongMethodA,
-       _Jv_JNI_CallNonvirtualFloatMethod,
-       _Jv_JNI_CallNonvirtualFloatMethodV,
-       _Jv_JNI_CallNonvirtualFloatMethodA,
-       _Jv_JNI_CallNonvirtualDoubleMethod,
-       _Jv_JNI_CallNonvirtualDoubleMethodV,
-       _Jv_JNI_CallNonvirtualDoubleMethodA,
-       _Jv_JNI_CallNonvirtualVoidMethod,
-       _Jv_JNI_CallNonvirtualVoidMethodV,
-       _Jv_JNI_CallNonvirtualVoidMethodA,
-
-       _Jv_JNI_GetFieldID,
-
-       _Jv_JNI_GetObjectField,
-       _Jv_JNI_GetBooleanField,
-       _Jv_JNI_GetByteField,
-       _Jv_JNI_GetCharField,
-       _Jv_JNI_GetShortField,
-       _Jv_JNI_GetIntField,
-       _Jv_JNI_GetLongField,
-       _Jv_JNI_GetFloatField,
-       _Jv_JNI_GetDoubleField,
-       _Jv_JNI_SetObjectField,
-       _Jv_JNI_SetBooleanField,
-       _Jv_JNI_SetByteField,
-       _Jv_JNI_SetCharField,
-       _Jv_JNI_SetShortField,
-       _Jv_JNI_SetIntField,
-       _Jv_JNI_SetLongField,
-       _Jv_JNI_SetFloatField,
-       _Jv_JNI_SetDoubleField,
-
-       _Jv_JNI_GetStaticMethodID,
-
-       _Jv_JNI_CallStaticObjectMethod,
-       _Jv_JNI_CallStaticObjectMethodV,
-       _Jv_JNI_CallStaticObjectMethodA,
-       _Jv_JNI_CallStaticBooleanMethod,
-       _Jv_JNI_CallStaticBooleanMethodV,
-       _Jv_JNI_CallStaticBooleanMethodA,
-       _Jv_JNI_CallStaticByteMethod,
-       _Jv_JNI_CallStaticByteMethodV,
-       _Jv_JNI_CallStaticByteMethodA,
-       _Jv_JNI_CallStaticCharMethod,
-       _Jv_JNI_CallStaticCharMethodV,
-       _Jv_JNI_CallStaticCharMethodA,
-       _Jv_JNI_CallStaticShortMethod,
-       _Jv_JNI_CallStaticShortMethodV,
-       _Jv_JNI_CallStaticShortMethodA,
-       _Jv_JNI_CallStaticIntMethod,
-       _Jv_JNI_CallStaticIntMethodV,
-       _Jv_JNI_CallStaticIntMethodA,
-       _Jv_JNI_CallStaticLongMethod,
-       _Jv_JNI_CallStaticLongMethodV,
-       _Jv_JNI_CallStaticLongMethodA,
-       _Jv_JNI_CallStaticFloatMethod,
-       _Jv_JNI_CallStaticFloatMethodV,
-       _Jv_JNI_CallStaticFloatMethodA,
-       _Jv_JNI_CallStaticDoubleMethod,
-       _Jv_JNI_CallStaticDoubleMethodV,
-       _Jv_JNI_CallStaticDoubleMethodA,
-       _Jv_JNI_CallStaticVoidMethod,
-       _Jv_JNI_CallStaticVoidMethodV,
-       _Jv_JNI_CallStaticVoidMethodA,
-
-       _Jv_JNI_GetStaticFieldID,
-
-       _Jv_JNI_GetStaticObjectField,
-       _Jv_JNI_GetStaticBooleanField,
-       _Jv_JNI_GetStaticByteField,
-       _Jv_JNI_GetStaticCharField,
-       _Jv_JNI_GetStaticShortField,
-       _Jv_JNI_GetStaticIntField,
-       _Jv_JNI_GetStaticLongField,
-       _Jv_JNI_GetStaticFloatField,
-       _Jv_JNI_GetStaticDoubleField,
-       _Jv_JNI_SetStaticObjectField,
-       _Jv_JNI_SetStaticBooleanField,
-       _Jv_JNI_SetStaticByteField,
-       _Jv_JNI_SetStaticCharField,
-       _Jv_JNI_SetStaticShortField,
-       _Jv_JNI_SetStaticIntField,
-       _Jv_JNI_SetStaticLongField,
-       _Jv_JNI_SetStaticFloatField,
-       _Jv_JNI_SetStaticDoubleField,
-
-       _Jv_JNI_NewString,
-       _Jv_JNI_GetStringLength,
-       _Jv_JNI_GetStringChars,
-       _Jv_JNI_ReleaseStringChars,
-
-       _Jv_JNI_NewStringUTF,
-       _Jv_JNI_GetStringUTFLength,
-       _Jv_JNI_GetStringUTFChars,
-       _Jv_JNI_ReleaseStringUTFChars,
-
-       _Jv_JNI_GetArrayLength,
-
-       _Jv_JNI_NewObjectArray,
-       _Jv_JNI_GetObjectArrayElement,
-       _Jv_JNI_SetObjectArrayElement,
-
-       _Jv_JNI_NewBooleanArray,
-       _Jv_JNI_NewByteArray,
-       _Jv_JNI_NewCharArray,
-       _Jv_JNI_NewShortArray,
-       _Jv_JNI_NewIntArray,
-       _Jv_JNI_NewLongArray,
-       _Jv_JNI_NewFloatArray,
-       _Jv_JNI_NewDoubleArray,
-
-       _Jv_JNI_GetBooleanArrayElements,
-       _Jv_JNI_GetByteArrayElements,
-       _Jv_JNI_GetCharArrayElements,
-       _Jv_JNI_GetShortArrayElements,
-       _Jv_JNI_GetIntArrayElements,
-       _Jv_JNI_GetLongArrayElements,
-       _Jv_JNI_GetFloatArrayElements,
-       _Jv_JNI_GetDoubleArrayElements,
-
-       _Jv_JNI_ReleaseBooleanArrayElements,
-       _Jv_JNI_ReleaseByteArrayElements,
-       _Jv_JNI_ReleaseCharArrayElements,
-       _Jv_JNI_ReleaseShortArrayElements,
-       _Jv_JNI_ReleaseIntArrayElements,
-       _Jv_JNI_ReleaseLongArrayElements,
-       _Jv_JNI_ReleaseFloatArrayElements,
-       _Jv_JNI_ReleaseDoubleArrayElements,
-
-       _Jv_JNI_GetBooleanArrayRegion,
-       _Jv_JNI_GetByteArrayRegion,
-       _Jv_JNI_GetCharArrayRegion,
-       _Jv_JNI_GetShortArrayRegion,
-       _Jv_JNI_GetIntArrayRegion,
-       _Jv_JNI_GetLongArrayRegion,
-       _Jv_JNI_GetFloatArrayRegion,
-       _Jv_JNI_GetDoubleArrayRegion,
-       _Jv_JNI_SetBooleanArrayRegion,
-       _Jv_JNI_SetByteArrayRegion,
-       _Jv_JNI_SetCharArrayRegion,
-       _Jv_JNI_SetShortArrayRegion,
-       _Jv_JNI_SetIntArrayRegion,
-       _Jv_JNI_SetLongArrayRegion,
-       _Jv_JNI_SetFloatArrayRegion,
-       _Jv_JNI_SetDoubleArrayRegion,
-
-       _Jv_JNI_RegisterNatives,
-       _Jv_JNI_UnregisterNatives,
-
-       _Jv_JNI_MonitorEnter,
-       _Jv_JNI_MonitorExit,
-
-       _Jv_JNI_GetJavaVM,
-
-       /* New JNI 1.2 functions. */
-
-       _Jv_JNI_GetStringRegion,
-       _Jv_JNI_GetStringUTFRegion,
-
-       jni_GetPrimitiveArrayCritical,
-       jni_ReleasePrimitiveArrayCritical,
-
-       _Jv_JNI_GetStringCritical,
-       _Jv_JNI_ReleaseStringCritical,
-
-       _Jv_JNI_NewWeakGlobalRef,
-       _Jv_JNI_DeleteWeakGlobalRef,
-
-       _Jv_JNI_ExceptionCheck,
-
-       /* New JNI 1.4 functions. */
-
-       jni_NewDirectByteBuffer,
-       _Jv_JNI_GetDirectBufferAddress,
-       _Jv_JNI_GetDirectBufferCapacity,
-
-       /* New JNI 1.6 functions. */
-
-       jni_GetObjectRefType
-};
-
-
-/* Invocation API Functions ***************************************************/
-
-/* JNI_GetDefaultJavaVMInitArgs ************************************************
-
-   Returns a default configuration for the Java VM.
-
-*******************************************************************************/
-
-jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
-{
-       JavaVMInitArgs *_vm_args;
-
-       _vm_args = (JavaVMInitArgs *) vm_args;
-
-       /* GNU classpath currently supports JNI 1.2 */
-
-       switch (_vm_args->version) {
-    case JNI_VERSION_1_1:
-               _vm_args->version = JNI_VERSION_1_1;
-               break;
-
-    case JNI_VERSION_1_2:
-    case JNI_VERSION_1_4:
-               _vm_args->ignoreUnrecognized = JNI_FALSE;
-               _vm_args->options = NULL;
-               _vm_args->nOptions = 0;
-               break;
-
-    default:
-               return -1;
-       }
-  
-       return 0;
-}
-
-
-/* JNI_GetCreatedJavaVMs *******************************************************
-
-   Returns all Java VMs that have been created. Pointers to VMs are written in
-   the buffer vmBuf in the order they are created. At most bufLen number of
-   entries will be written. The total number of created VMs is returned in
-   *nVMs.
-
-*******************************************************************************/
-
-jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
-{
-       TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
-
-       if (bufLen <= 0)
-               return JNI_ERR;
-
-       /* We currently only support 1 VM running. */
-
-       vmBuf[0] = (JavaVM *) _Jv_jvm;
-       *nVMs    = 1;
-
-    return JNI_OK;
-}
-
-
-/* JNI_CreateJavaVM ************************************************************
-
-   Loads and initializes a Java VM. The current thread becomes the main thread.
-   Sets the env argument to the JNI interface pointer of the main thread.
-
-*******************************************************************************/
-
-jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
-{
-       TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
-
-       /* actually create the JVM */
-
-       if (!vm_createjvm(p_vm, p_env, vm_args))
-               return JNI_ERR;
-
-       return JNI_OK;
-}
-
-
-/*
- * 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/native/jni.cpp b/src/native/jni.cpp
new file mode 100644 (file)
index 0000000..842840b
--- /dev/null
@@ -0,0 +1,4211 @@
+/* src/native/jni.cpp - implementation of the Java Native Interface functions
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "mm/gc.hpp"
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/localref.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JVMTI)
+# include "native/jvmti/cacaodbg.h"
+#endif
+
+#include "threads/lock-common.h"
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/array.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/resolve.h"
+#include "vm/statistics.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+#include "vm/jit/argument.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/stacktrace.hpp"
+
+
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+
+# define TRACEJNICALLS(x)                                              \
+    do {                                                                               \
+        if (opt_TraceJNICalls) {                               \
+            log_println x;                                             \
+        }                                                                              \
+    } while (0)
+
+# define TRACEJNICALLSENTER(x)                                                                 \
+    do {                                                                                                               \
+        if (opt_TraceJNICalls) {                                                               \
+                       log_start();                                                                            \
+            log_print x;                                                                               \
+        }                                                                                                              \
+    } while (0)
+
+# define TRACEJNICALLSEXIT(x)                                                                  \
+    do {                                                                                                               \
+        if (opt_TraceJNICalls) {                                                               \
+                       log_print x;                                                                            \
+                       log_finish();                                                                           \
+        }                                                                                                              \
+    } while (0)
+
+#else
+
+# define TRACEJNICALLS(x)
+# define TRACEJNICALLSENTER(x)
+# define TRACEJNICALLSEXIT(x)
+
+#endif
+
+
+/* global variables ***********************************************************/
+
+/* global reference table *****************************************************/
+
+/* hashsize must be power of 2 */
+
+#define HASHTABLE_GLOBAL_REF_SIZE    64 /* initial size of globalref-hash     */
+
+static hashtable *hashtable_global_ref; /* hashtable for globalrefs           */
+
+
+/* direct buffer stuff ********************************************************/
+
+#if defined(ENABLE_JAVASE)
+static classinfo *class_java_nio_Buffer;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+static classinfo *class_java_nio_DirectByteBufferImpl;
+static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
+
+#  if SIZEOF_VOID_P == 8
+static classinfo *class_gnu_classpath_Pointer64;
+#  else
+static classinfo *class_gnu_classpath_Pointer32;
+#  endif
+
+static methodinfo *dbbirw_init;
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+static classinfo *class_sun_nio_ch_DirectBuffer;
+static classinfo *class_java_nio_DirectByteBuffer;
+
+static methodinfo *dbb_init;
+
+# endif
+#endif
+
+
+/* some forward declarations **************************************************/
+
+extern "C" {
+jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
+}
+
+
+/* jni_init ********************************************************************
+
+   Initialize the JNI subsystem.
+
+*******************************************************************************/
+
+bool jni_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("jni_init");
+
+       /* create global ref hashtable */
+
+       hashtable_global_ref = NEW(hashtable);
+
+       hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
+
+
+#if defined(ENABLE_JAVASE)
+       /* Direct buffer stuff. */
+
+       if (!(class_java_nio_Buffer =
+                 load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
+               !link_class(class_java_nio_Buffer))
+               return false;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       if (!(class_java_nio_DirectByteBufferImpl =
+                 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
+               !link_class(class_java_nio_DirectByteBufferImpl))
+               return false;
+
+       if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
+                 load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
+               !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
+               return false;
+
+       if (!(dbbirw_init =
+               class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
+                                                       utf_init,
+                                                       utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
+               return false;
+
+#  if SIZEOF_VOID_P == 8
+       if (!(class_gnu_classpath_Pointer64 =
+                 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
+               !link_class(class_gnu_classpath_Pointer64))
+               return false;
+#  else
+       if (!(class_gnu_classpath_Pointer32 =
+                 load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
+               !link_class(class_gnu_classpath_Pointer32))
+               return false;
+#  endif
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       if (!(class_sun_nio_ch_DirectBuffer =
+                 load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
+               vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
+
+       if (!link_class(class_sun_nio_ch_DirectBuffer))
+               vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
+
+       if (!(class_java_nio_DirectByteBuffer =
+                 load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
+               vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
+
+       if (!link_class(class_java_nio_DirectByteBuffer))
+               vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
+
+       if (!(dbb_init =
+                 class_resolvemethod(class_java_nio_DirectByteBuffer,
+                                                         utf_init,
+                                                         utf_new_char("(JI)V"))))
+               vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
+
+# endif
+
+#endif /* defined(ENABLE_JAVASE) */
+
+       return true;
+}
+
+
+/* jni_version_check ***********************************************************
+
+   Check if the given JNI version is supported.
+
+   IN:
+       version....JNI version to check
+
+   RETURN VALUE:
+       true.......supported
+       false......not supported
+
+*******************************************************************************/
+
+bool jni_version_check(int version)
+{
+       switch (version) {
+       case JNI_VERSION_1_1:
+       case JNI_VERSION_1_2:
+       case JNI_VERSION_1_4:
+       case JNI_VERSION_1_6:
+               return true;
+       default:
+               return false;
+       }
+}
+
+
+/* _Jv_jni_CallObjectMethod ****************************************************
+
+   Internal function to call Java Object methods.
+
+*******************************************************************************/
+
+static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
+                                                                                          vftbl_t *vftbl,
+                                                                                          methodinfo *m, va_list ap)
+{
+       methodinfo    *resm;
+       java_handle_t *ro;
+
+       STATISTICS(jniinvokation());
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       ro = vm_call_method_valist(resm, o, ap);
+
+       return ro;
+}
+
+
+/* _Jv_jni_CallObjectMethodA ***************************************************
+
+   Internal function to call Java Object methods.
+
+*******************************************************************************/
+
+static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
+                                                                                               vftbl_t *vftbl,
+                                                                                               methodinfo *m,
+                                                                                               const jvalue *args)
+{
+       methodinfo    *resm;
+       java_handle_t *ro;
+
+       STATISTICS(jniinvokation());
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       ro = vm_call_method_jvalue(resm, o, args);
+
+       return ro;
+}
+
+
+/* _Jv_jni_CallIntMethod *******************************************************
+
+   Internal function to call Java integer class methods (boolean,
+   byte, char, short, int).
+
+*******************************************************************************/
+
+static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
+                                                                 methodinfo *m, va_list ap)
+{
+       methodinfo *resm;
+       jint        i;
+
+       STATISTICS(jniinvokation());
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+        
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       i = vm_call_method_int_valist(resm, o, ap);
+
+       return i;
+}
+
+
+/* _Jv_jni_CallIntMethodA ******************************************************
+
+   Internal function to call Java integer class methods (boolean,
+   byte, char, short, int).
+
+*******************************************************************************/
+
+static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                  methodinfo *m, const jvalue *args)
+{
+       methodinfo *resm;
+       jint        i;
+
+       STATISTICS(jniinvokation());
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+        
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       i = vm_call_method_int_jvalue(resm, o, args);
+
+       return i;
+}
+
+
+/* _Jv_jni_CallLongMethod ******************************************************
+
+   Internal function to call Java long methods.
+
+*******************************************************************************/
+
+static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
+                                                                       methodinfo *m, va_list ap)
+{
+       methodinfo *resm;
+       jlong       l;
+
+       STATISTICS(jniinvokation());
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       l = vm_call_method_long_valist(resm, o, ap);
+
+       return l;
+}
+
+
+/* _Jv_jni_CallLongMethodA *****************************************************
+
+   Internal function to call Java long methods.
+
+*******************************************************************************/
+
+static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                        methodinfo *m, const jvalue *args)
+{
+       methodinfo *resm;
+       jlong       l;
+
+       STATISTICS(jniinvokation());
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+       }
+       else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       l = vm_call_method_long_jvalue(resm, o, args);
+
+       return l;
+}
+
+
+/* _Jv_jni_CallFloatMethod *****************************************************
+
+   Internal function to call Java float methods.
+
+*******************************************************************************/
+
+static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
+                                                                         methodinfo *m, va_list ap)
+{
+       methodinfo *resm;
+       jfloat      f;
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       f = vm_call_method_float_valist(resm, o, ap);
+
+       return f;
+}
+
+
+/* _Jv_jni_CallFloatMethodA ****************************************************
+
+   Internal function to call Java float methods.
+
+*******************************************************************************/
+
+static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                          methodinfo *m, const jvalue *args)
+{
+       methodinfo *resm;
+       jfloat      f;
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+       }
+       else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       f = vm_call_method_float_jvalue(resm, o, args);
+
+       return f;
+}
+
+
+/* _Jv_jni_CallDoubleMethod ****************************************************
+
+   Internal function to call Java double methods.
+
+*******************************************************************************/
+
+static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
+                                                                               methodinfo *m, va_list ap)
+{
+       methodinfo *resm;
+       jdouble     d;
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       d = vm_call_method_double_valist(resm, o, ap);
+
+       return d;
+}
+
+
+/* _Jv_jni_CallDoubleMethodA ***************************************************
+
+   Internal function to call Java double methods.
+
+*******************************************************************************/
+
+static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                                methodinfo *m, const jvalue *args)
+{
+       methodinfo *resm;
+       jdouble     d;
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+       }
+       else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       d = vm_call_method_double_jvalue(resm, o, args);
+
+       return d;
+}
+
+
+/* _Jv_jni_CallVoidMethod ******************************************************
+
+   Internal function to call Java void methods.
+
+*******************************************************************************/
+
+static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
+                                                                  methodinfo *m, va_list ap)
+{      
+       methodinfo *resm;
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       (void) vm_call_method_valist(resm, o, ap);
+}
+
+
+/* _Jv_jni_CallVoidMethodA *****************************************************
+
+   Internal function to call Java void methods.
+
+*******************************************************************************/
+
+static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                       methodinfo *m, const jvalue *args)
+{      
+       methodinfo *resm;
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       (void) vm_call_method_jvalue(resm, o, args);
+}
+
+
+// JNI functions are exported as C functions.
+extern "C" {
+
+/* GetVersion ******************************************************************
+
+   Returns the major version number in the higher 16 bits and the
+   minor version number in the lower 16 bits.
+
+*******************************************************************************/
+
+jint _Jv_JNI_GetVersion(JNIEnv *env)
+{
+       TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
+
+       /* We support JNI 1.6. */
+
+       return JNI_VERSION_1_6;
+}
+
+
+/* Class Operations ***********************************************************/
+
+/* DefineClass *****************************************************************
+
+   Loads a class from a buffer of raw class data. The buffer
+   containing the raw class data is not referenced by the VM after the
+   DefineClass call returns, and it may be discarded if desired.
+
+*******************************************************************************/
+
+jclass jni_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
+{
+#if defined(ENABLE_JAVASE)
+       utf           *u;
+       classloader_t *cl;
+       classinfo     *c;
+       java_handle_t* h;
+
+       TRACEJNICALLS(("jni_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
+
+       u  = utf_new_char(name);
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
+
+       c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
+
+       h = LLNI_classinfo_wrap(c);
+
+       return (jclass) jni_NewLocalRef(env, (jobject) h);
+#else
+       vm_abort("jni_DefineClass: Not implemented in this configuration");
+
+       // Keep compiler happy.
+
+       return 0;
+#endif
+}
+
+
+/* FindClass *******************************************************************
+
+   This function loads a locally-defined class. It searches the
+   directories and zip files specified by the CLASSPATH environment
+   variable for the class with the specified name.
+
+*******************************************************************************/
+
+jclass jni_FindClass(JNIEnv *env, const char *name)
+{
+#if defined(ENABLE_JAVASE)
+
+       utf*       u;    
+       classinfo* cc;
+       classinfo* c;
+       java_handle_t* h;
+
+       TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
+
+       /* FIXME If name is NULL we have a problem here. */
+
+       u = utf_new_char_classname((char *) name);
+
+       if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
+               exceptions_throw_noclassdeffounderror(u);
+               return NULL;
+       }
+
+       /* Check stacktrace for classloader, if one found use it,
+          otherwise use the system classloader. */
+
+       /* Quote from the JNI documentation:
+        
+          In the Java 2 Platform, FindClass locates the class loader
+          associated with the current native method.  If the native code
+          belongs to a system class, no class loader will be
+          involved. Otherwise, the proper class loader will be invoked to
+          load and link the named class. When FindClass is called through
+          the Invocation Interface, there is no current native method or
+          its associated class loader. In that case, the result of
+          ClassLoader.getBaseClassLoader is used." */
+
+       cc = stacktrace_get_current_class();
+
+       if (cc == NULL)
+               c = load_class_from_sysloader(u);
+       else
+               c = load_class_from_classloader(u, cc->classloader);
+
+       if (c == NULL) {
+               resolve_handle_pending_exception(true);
+               return NULL;
+       }
+
+       if (!link_class(c))
+               return NULL;
+
+       h = LLNI_classinfo_wrap(c);
+
+       return (jclass) jni_NewLocalRef(env, (jobject) h);
+
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+
+       utf       *u;
+       classinfo *c;
+
+       TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
+
+       u = utf_new_char_classname((char *) name);
+       c = load_class_bootstrap(u);
+
+       if (c == NULL) {
+               resolve_handle_pending_exception(true);
+               return NULL;
+       }
+
+       if (!link_class(c))
+               return NULL;
+
+       return (jclass) jni_NewLocalRef(env, (jobject) c);
+       
+#else
+       vm_abort("jni_FindClass: not implemented in this configuration");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
+}
+  
+
+/* GetSuperclass ***************************************************************
+
+   If clazz represents any class other than the class Object, then
+   this function returns the object that represents the superclass of
+   the class specified by clazz.
+
+*******************************************************************************/
+jclass jni_GetSuperclass(JNIEnv *env, jclass sub)
+{
+       classinfo* c;
+       classinfo* super;
+
+       TRACEJNICALLS(("jni_GetSuperclass(env=%p, sub=%p)", env, sub));
+
+       c = LLNI_classinfo_unwrap(sub);
+
+       if (c == NULL)
+               return NULL;
+
+       super = class_get_superclass(c);
+
+       java_handle_t* h = LLNI_classinfo_wrap(super);
+
+       return (jclass) jni_NewLocalRef(env, (jobject) h);
+}
+  
+/* IsAssignableFrom ************************************************************
+
+   Determines whether an object of sub can be safely cast to sup.
+
+*******************************************************************************/
+
+jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
+{
+       classinfo *to;
+       classinfo *from;
+
+       TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
+
+       to   = (classinfo *) sup;
+       from = (classinfo *) sub;
+
+       return class_is_assignable_from(to, from);
+}
+
+
+/* Throw ***********************************************************************
+
+   Causes a java.lang.Throwable object to be thrown.
+
+*******************************************************************************/
+
+jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
+{
+       java_handle_t *o;
+
+       STATISTICS(jniinvokation());
+
+       o = (java_handle_t *) obj;
+
+       exceptions_set_exception(o);
+
+       return JNI_OK;
+}
+
+
+/* ThrowNew ********************************************************************
+
+   Constructs an exception object from the specified class with the
+   message specified by message and causes that exception to be
+   thrown.
+
+*******************************************************************************/
+
+jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
+{
+       classinfo     *c;
+       java_handle_t *o;
+       java_handle_t *s;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+       if (msg == NULL)
+               msg = "";
+       s = javastring_new_from_utf_string(msg);
+
+       /* instantiate exception object */
+
+       o = native_new_and_init_string(c, s);
+
+       if (o == NULL)
+               return -1;
+
+       exceptions_set_exception(o);
+
+       return 0;
+}
+
+
+/* ExceptionOccurred ***********************************************************
+
+   Determines if an exception is being thrown. The exception stays
+   being thrown until either the native code calls ExceptionClear(),
+   or the Java code handles the exception.
+
+*******************************************************************************/
+
+jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
+{
+       java_handle_t *o;
+
+       TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
+
+       o = exceptions_get_exception();
+
+       return (jthrowable) jni_NewLocalRef(env, (jthrowable) o);
+}
+
+
+/* ExceptionDescribe ***********************************************************
+
+   Prints an exception and a backtrace of the stack to a system
+   error-reporting channel, such as stderr. This is a convenience
+   routine provided for debugging.
+
+*******************************************************************************/
+
+void jni_ExceptionDescribe(JNIEnv *env)
+{
+       TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
+
+       exceptions_print_stacktrace();
+}
+
+
+/* ExceptionClear **************************************************************
+
+   Clears any exception that is currently being thrown. If no
+   exception is currently being thrown, this routine has no effect.
+
+*******************************************************************************/
+
+void jni_ExceptionClear(JNIEnv *env)
+{
+       TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
+
+       exceptions_clear_exception();
+}
+
+
+/* FatalError ******************************************************************
+
+   Raises a fatal error and does not expect the VM to recover. This
+   function does not return.
+
+*******************************************************************************/
+
+void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
+{
+       STATISTICS(jniinvokation());
+
+       /* this seems to be the best way */
+
+       vm_abort("JNI Fatal error: %s", msg);
+}
+
+
+/* PushLocalFrame **************************************************************
+
+   Creates a new local reference frame, in which at least a given
+   number of local references can be created.
+
+*******************************************************************************/
+
+jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
+{
+       TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
+
+       if (capacity <= 0)
+               return -1;
+
+       /* add new local reference frame to current table */
+
+       if (!localref_frame_push(capacity))
+               return -1;
+
+       return 0;
+}
+
+
+/* PopLocalFrame ***************************************************************
+
+   Pops off the current local reference frame, frees all the local
+   references, and returns a local reference in the previous local
+   reference frame for the given result object.
+
+*******************************************************************************/
+
+jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
+{
+       TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
+
+       /* release all current local frames */
+
+       localref_frame_pop_all();
+
+       /* add local reference and return the value */
+
+       return jni_NewLocalRef(env, result);
+}
+
+
+/* DeleteLocalRef **************************************************************
+
+   Deletes the local reference pointed to by localRef.
+
+*******************************************************************************/
+
+void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
+{
+       java_handle_t *o;
+
+       TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
+
+       o = (java_handle_t *) localRef;
+
+       if (o == NULL)
+               return;
+
+       /* delete the reference */
+
+       localref_del(o);
+}
+
+
+/* IsSameObject ****************************************************************
+
+   Tests whether two references refer to the same Java object.
+
+*******************************************************************************/
+
+jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
+{
+       java_handle_t *o1;
+       java_handle_t *o2;
+       jboolean       result;
+
+       STATISTICS(jniinvokation());
+
+       o1 = (java_handle_t *) ref1;
+       o2 = (java_handle_t *) ref2;
+
+       LLNI_CRITICAL_START;
+
+       if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
+               result = JNI_TRUE;
+       else
+               result = JNI_FALSE;
+
+       LLNI_CRITICAL_END;
+
+       return result;
+}
+
+
+/* NewLocalRef *****************************************************************
+
+   Creates a new local reference that refers to the same object as ref.
+
+*******************************************************************************/
+
+jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
+{
+       java_handle_t *o;
+       java_handle_t *localref;
+
+       TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
+
+       o = (java_handle_t *) ref;
+
+       if (o == NULL)
+               return NULL;
+
+       /* insert the reference */
+
+       localref = localref_add(LLNI_DIRECT(o));
+
+       return (jobject) localref;
+}
+
+
+/* EnsureLocalCapacity *********************************************************
+
+   Ensures that at least a given number of local references can be
+   created in the current thread
+
+*******************************************************************************/
+
+jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
+{
+       localref_table *lrt;
+
+       TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
+
+       /* get local reference table (thread specific) */
+
+       lrt = LOCALREFTABLE;
+
+       /* check if capacity elements are available in the local references table */
+
+       if ((lrt->used + capacity) > lrt->capacity)
+               return jni_PushLocalFrame(env, capacity);
+
+       return 0;
+}
+
+
+/* AllocObject *****************************************************************
+
+   Allocates a new Java object without invoking any of the
+   constructors for the object. Returns a reference to the object.
+
+*******************************************************************************/
+
+jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
+{
+       classinfo     *c;
+       java_handle_t *o;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+
+       if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
+               exceptions_throw_instantiationexception(c);
+               return NULL;
+       }
+               
+       o = builtin_new(c);
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+/* NewObject *******************************************************************
+
+   Programmers place all arguments that are to be passed to the
+   constructor immediately following the methodID
+   argument. NewObject() accepts these arguments and passes them to
+   the Java method that the programmer wishes to invoke.
+
+*******************************************************************************/
+
+jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       va_list        ap;
+
+       TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
+
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       /* create object */
+
+       o = builtin_new(c);
+       
+       if (o == NULL)
+               return NULL;
+
+       /* call constructor */
+
+       va_start(ap, methodID);
+       _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
+       va_end(ap);
+
+       TRACEJNICALLSEXIT(("->%p", o));
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+/* NewObjectV ******************************************************************
+
+   Programmers place all arguments that are to be passed to the
+   constructor in an args argument of type va_list that immediately
+   follows the methodID argument. NewObjectV() accepts these
+   arguments, and, in turn, passes them to the Java method that the
+   programmer wishes to invoke.
+
+*******************************************************************************/
+
+jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
+                                                  va_list args)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       /* create object */
+
+       o = builtin_new(c);
+       
+       if (o == NULL)
+               return NULL;
+
+       /* call constructor */
+
+       _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+/* NewObjectA ***************************************************************** 
+
+   Programmers place all arguments that are to be passed to the
+   constructor in an args array of jvalues that immediately follows
+   the methodID argument. NewObjectA() accepts the arguments in this
+   array, and, in turn, passes them to the Java method that the
+   programmer wishes to invoke.
+
+*******************************************************************************/
+
+jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
+                                                  const jvalue *args)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       /* create object */
+
+       o = builtin_new(c);
+       
+       if (o == NULL)
+               return NULL;
+
+       /* call constructor */
+
+       _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+/* GetObjectClass **************************************************************
+
+ Returns the class of an object.
+
+*******************************************************************************/
+
+jclass jni_GetObjectClass(JNIEnv *env, jobject obj)
+{
+       java_handle_t* o;
+       classinfo*     c;
+
+       TRACEJNICALLS(("jni_GetObjectClass(env=%p, obj=%p)", env, obj));
+
+       o = (java_handle_t *) obj;
+
+       if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
+               return NULL;
+
+       LLNI_class_get(o, c);
+
+       java_handle_t* h = LLNI_classinfo_wrap(c);
+
+       return (jclass) jni_NewLocalRef(env, (jobject) h);
+}
+
+
+/* IsInstanceOf ****************************************************************
+
+   Tests whether an object is an instance of a class.
+
+*******************************************************************************/
+
+jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
+{
+       classinfo     *c;
+       java_handle_t *h;
+
+       TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
+
+       /* XXX Is this correct? */
+       c = LLNI_classinfo_unwrap(clazz);
+       h = (java_handle_t *) obj;
+
+       return class_is_instance(c, h);
+}
+
+
+/* Reflection Support *********************************************************/
+
+/* FromReflectedMethod *********************************************************
+
+   Converts java.lang.reflect.Method or java.lang.reflect.Constructor
+   object to a method ID.
+  
+*******************************************************************************/
+  
+jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
+{
+#if defined(ENABLE_JAVASE)
+       java_handle_t* o;
+       methodinfo*    m;
+
+       TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
+
+       o = (java_handle_t *) method;
+
+       if (o == NULL)
+               return NULL;
+
+       // FIXME We can't access the object here directly.
+       if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
+               java_lang_reflect_Constructor rc(method);
+               m = rc.get_method();
+       }
+       else {
+               // FIXME We can't access the object here directly.
+               assert(o->vftbl->clazz == class_java_lang_reflect_Method);
+
+               java_lang_reflect_Method rm(method);
+               m = rm.get_method();
+       }
+
+       return (jmethodID) m;
+#else
+       vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
+
+       // Keep compiler happy.
+       return NULL;
+#endif
+}
+
+
+/* FromReflectedField **********************************************************
+
+   Converts a java.lang.reflect.Field to a field ID.
+
+*******************************************************************************/
+jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
+{
+#if defined(ENABLE_JAVASE)
+
+       TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
+
+       java_lang_reflect_Field rf(field);
+
+       if (rf.is_null())
+               return NULL;
+
+       fieldinfo* f = rf.get_field();
+
+       return (jfieldID) f;
+#else
+       vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
+
+       // Keep compiler happy.
+       return NULL;
+#endif
+}
+
+
+/* ToReflectedMethod ***********************************************************
+
+   Converts a method ID derived from cls to an instance of the
+   java.lang.reflect.Method class or to an instance of the
+   java.lang.reflect.Constructor class.
+
+*******************************************************************************/
+
+jobject jni_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
+{
+#if defined(ENABLE_JAVASE)
+       TRACEJNICALLS(("jni_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
+
+       methodinfo* m = (methodinfo *) methodID;
+
+       /* HotSpot does the same assert. */
+
+       assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
+
+       java_handle_t* h;
+
+       if (m->name == utf_init) {
+               h = java_lang_reflect_Constructor(m).get_handle();
+       }
+       else {
+               h = java_lang_reflect_Method(m).get_handle();
+       }
+
+       return (jobject) h;
+#else
+       vm_abort("jni_ToReflectedMethod: Not implemented in this configuration.");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
+}
+
+
+/* ToReflectedField ************************************************************
+
+   Converts a field ID derived from cls to an instance of the
+   java.lang.reflect.Field class.
+
+*******************************************************************************/
+
+jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
+                                                                jboolean isStatic)
+{
+       STATISTICS(jniinvokation());
+
+       log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* Calling Instance Methods ***************************************************/
+
+/* GetMethodID *****************************************************************
+
+   Returns the method ID for an instance (nonstatic) method of a class
+   or interface. The method may be defined in one of the clazz's
+   superclasses and inherited by clazz. The method is determined by
+   its name and signature.
+
+   GetMethodID() causes an uninitialized class to be initialized.
+
+*******************************************************************************/
+
+jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
+                                                         const char *sig)
+{
+       classinfo  *c;
+       utf        *uname;
+       utf        *udesc;
+       methodinfo *m;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+
+       if (c == NULL)
+               return NULL;
+
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return NULL;
+
+       /* try to get the method of the class or one of it's superclasses */
+
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
+
+       m = class_resolvemethod(c, uname, udesc);
+
+       if ((m == NULL) || (m->flags & ACC_STATIC)) {
+               exceptions_throw_nosuchmethoderror(c, uname, udesc);
+
+               return NULL;
+       }
+
+       return (jmethodID) m;
+}
+
+
+/* JNI-functions for calling instance methods *********************************/
+
+#define JNI_CALL_VIRTUAL_METHOD(name, type, intern)         \
+type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj,   \
+                                                               jmethodID methodID, ...)    \
+{                                                           \
+       java_handle_t *o;                                       \
+       methodinfo    *m;                                       \
+       va_list        ap;                                      \
+       type           ret;                                     \
+                                                            \
+       o = (java_handle_t *) obj;                              \
+       m = (methodinfo *) methodID;                            \
+                                                            \
+       va_start(ap, methodID);                                 \
+       ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
+       va_end(ap);                                             \
+                                                            \
+       return ret;                                             \
+}
+
+JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD(Byte,    jbyte,    Int)
+JNI_CALL_VIRTUAL_METHOD(Char,    jchar,    Int)
+JNI_CALL_VIRTUAL_METHOD(Short,   jshort,   Int)
+JNI_CALL_VIRTUAL_METHOD(Int,     jint,     Int)
+JNI_CALL_VIRTUAL_METHOD(Long,    jlong,    Long)
+JNI_CALL_VIRTUAL_METHOD(Float,   jfloat,   Float)
+JNI_CALL_VIRTUAL_METHOD(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern)              \
+type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj,         \
+                                                                jmethodID methodID, va_list args) \
+{                                                                  \
+       java_handle_t *o;                                              \
+       methodinfo    *m;                                              \
+       type           ret;                                            \
+                                                                   \
+       o = (java_handle_t *) obj;                                     \
+       m = (methodinfo *) methodID;                                   \
+                                                                   \
+       ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args);      \
+                                                                   \
+       return ret;                                                    \
+}
+
+JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD_V(Byte,    jbyte,    Int)
+JNI_CALL_VIRTUAL_METHOD_V(Char,    jchar,    Int)
+JNI_CALL_VIRTUAL_METHOD_V(Short,   jshort,   Int)
+JNI_CALL_VIRTUAL_METHOD_V(Int,     jint,     Int)
+JNI_CALL_VIRTUAL_METHOD_V(Long,    jlong,    Long)
+JNI_CALL_VIRTUAL_METHOD_V(Float,   jfloat,   Float)
+JNI_CALL_VIRTUAL_METHOD_V(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern)          \
+type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj,     \
+                                                                jmethodID methodID,           \
+                                                                const jvalue *args)           \
+{                                                              \
+       java_handle_t *o;                                          \
+       methodinfo    *m;                                          \
+       type           ret;                                        \
+                                                               \
+       o = (java_handle_t *) obj;                                 \
+       m = (methodinfo *) methodID;                               \
+                                                               \
+       ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
+                                                               \
+       return ret;                                                \
+}
+
+JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD_A(Byte,    jbyte,    Int)
+JNI_CALL_VIRTUAL_METHOD_A(Char,    jchar,    Int)
+JNI_CALL_VIRTUAL_METHOD_A(Short,   jshort,   Int)
+JNI_CALL_VIRTUAL_METHOD_A(Int,     jint,     Int)
+JNI_CALL_VIRTUAL_METHOD_A(Long,    jlong,    Long)
+JNI_CALL_VIRTUAL_METHOD_A(Float,   jfloat,   Float)
+JNI_CALL_VIRTUAL_METHOD_A(Double,  jdouble,  Double)
+
+
+jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                                ...)
+{
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *ret;
+       va_list        ap;
+
+       o = (java_handle_t *) obj;
+       m = (methodinfo *) methodID;
+
+       va_start(ap, methodID);
+       ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
+       va_end(ap);
+
+       return jni_NewLocalRef(env, (jobject) ret);
+}
+
+
+jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                                 va_list args)
+{
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *ret;
+
+       o = (java_handle_t *) obj;
+       m = (methodinfo *) methodID;
+
+       ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
+
+       return jni_NewLocalRef(env, (jobject) ret);
+}
+
+
+jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                                 const jvalue *args)
+{
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *ret;
+
+       o = (java_handle_t *) obj;
+       m = (methodinfo *) methodID;
+
+       ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
+
+       return jni_NewLocalRef(env, (jobject) ret);
+}
+
+
+
+void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+{
+       java_handle_t *o;
+       methodinfo    *m;
+       va_list        ap;
+
+       o = (java_handle_t *) obj;
+       m = (methodinfo *) methodID;
+
+       va_start(ap, methodID);
+       _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
+       va_end(ap);
+}
+
+
+void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                        va_list args)
+{
+       java_handle_t *o;
+       methodinfo    *m;
+
+       o = (java_handle_t *) obj;
+       m = (methodinfo *) methodID;
+
+       _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
+}
+
+
+void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                        const jvalue *args)
+{
+       java_handle_t *o;
+       methodinfo    *m;
+
+       o = (java_handle_t *) obj;
+       m = (methodinfo *) methodID;
+
+       _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
+}
+
+
+
+#define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern)                      \
+type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj,         \
+                                                                                 jclass clazz, jmethodID methodID, \
+                                                                                 ...)                              \
+{                                                                           \
+       java_handle_t *o;                                                       \
+       classinfo     *c;                                                       \
+       methodinfo    *m;                                                       \
+       va_list        ap;                                                      \
+       type           ret;                                                     \
+                                                                            \
+       o = (java_handle_t *) obj;                                              \
+       c = LLNI_classinfo_unwrap(clazz);                                       \
+       m = (methodinfo *) methodID;                                            \
+                                                                            \
+       va_start(ap, methodID);                                                 \
+       ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap);                 \
+       va_end(ap);                                                             \
+                                                                            \
+       return ret;                                                             \
+}
+
+JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD(Byte,    jbyte,    Int)
+JNI_CALL_NONVIRTUAL_METHOD(Char,    jchar,    Int)
+JNI_CALL_NONVIRTUAL_METHOD(Short,   jshort,   Int)
+JNI_CALL_NONVIRTUAL_METHOD(Int,     jint,     Int)
+JNI_CALL_NONVIRTUAL_METHOD(Long,    jlong,    Long)
+JNI_CALL_NONVIRTUAL_METHOD(Float,   jfloat,   Float)
+JNI_CALL_NONVIRTUAL_METHOD(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern)                     \
+type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj,         \
+                                                                                  jclass clazz, jmethodID methodID, \
+                                                                                  va_list args)                     \
+{                                                                            \
+       java_handle_t *o;                                                        \
+       classinfo     *c;                                                        \
+       methodinfo    *m;                                                        \
+       type           ret;                                                      \
+                                                                             \
+       o = (java_handle_t *) obj;                                               \
+       c = LLNI_classinfo_unwrap(clazz);                                        \
+       m = (methodinfo *) methodID;                                             \
+                                                                             \
+       ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);                       \
+                                                                             \
+       return ret;                                                              \
+}
+
+JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Byte,    jbyte,    Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Char,    jchar,    Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Short,   jshort,   Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Int,     jint,     Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Long,    jlong,    Long)
+JNI_CALL_NONVIRTUAL_METHOD_V(Float,   jfloat,   Float)
+JNI_CALL_NONVIRTUAL_METHOD_V(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern)                     \
+type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj,         \
+                                                                                  jclass clazz, jmethodID methodID, \
+                                                                                  const jvalue *args)               \
+{                                                                            \
+       log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!");      \
+                                                                             \
+       return 0;                                                                \
+}
+
+JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Byte,    jbyte,    Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Char,    jchar,    Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Short,   jshort,   Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Int,     jint,     Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Long,    jlong,    Long)
+JNI_CALL_NONVIRTUAL_METHOD_A(Float,   jfloat,   Float)
+JNI_CALL_NONVIRTUAL_METHOD_A(Double,  jdouble,  Double)
+
+jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
+                                                                                  jclass clazz, jmethodID methodID,
+                                                                                  ...)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       java_handle_t *r;
+       va_list        ap;
+
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       va_start(ap, methodID);
+       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
+       va_end(ap);
+
+       return jni_NewLocalRef(env, (jobject) r);
+}
+
+
+jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
+                                                                                       jclass clazz, jmethodID methodID,
+                                                                                       va_list args)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       java_handle_t *r;
+
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
+
+       return jni_NewLocalRef(env, (jobject) r);
+}
+
+
+jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
+                                                                                       jclass clazz, jmethodID methodID,
+                                                                                       const jvalue *args)
+{
+       log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
+
+       return jni_NewLocalRef(env, NULL);
+}
+
+
+void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
+                                                                         jmethodID methodID, ...)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       va_list        ap;
+
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       va_start(ap, methodID);
+       _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
+       va_end(ap);
+}
+
+
+void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
+                                                                          jmethodID methodID, va_list args)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
+}
+
+
+void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
+                                                                          jmethodID methodID, const jvalue * args)
+{      
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
+}
+
+
+/* Accessing Fields of Objects ************************************************/
+
+/* GetFieldID ******************************************************************
+
+   Returns the field ID for an instance (nonstatic) field of a
+   class. The field is specified by its name and signature. The
+   Get<type>Field and Set<type>Field families of accessor functions
+   use field IDs to retrieve object fields.
+
+*******************************************************************************/
+
+jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
+                                                       const char *sig)
+{
+       classinfo *c;
+       fieldinfo *f;
+       utf       *uname;
+       utf       *udesc;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+
+       /* XXX NPE check? */
+
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
+
+       f = class_findfield(c, uname, udesc); 
+       
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);  
+
+       return (jfieldID) f;
+}
+
+
+/* Get<type>Field Routines *****************************************************
+
+   This family of accessor routines returns the value of an instance
+   (nonstatic) field of an object. The field to access is specified by
+   a field ID obtained by calling GetFieldID().
+
+*******************************************************************************/
+
+#define GET_FIELD(o,type,f) \
+    *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
+
+#define JNI_GET_FIELD(name, type, intern)                                 \
+type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
+{                                                                         \
+       intern ret;                                                           \
+                                                                          \
+       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
+                                                                          \
+       LLNI_CRITICAL_START;                                                  \
+                                                                          \
+       ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
+                                                                          \
+       LLNI_CRITICAL_END;                                                    \
+                                                                          \
+       return (type) ret;                                                    \
+}
+
+JNI_GET_FIELD(Boolean, jboolean, s4)
+JNI_GET_FIELD(Byte,    jbyte,    s4)
+JNI_GET_FIELD(Char,    jchar,    s4)
+JNI_GET_FIELD(Short,   jshort,   s4)
+JNI_GET_FIELD(Int,     jint,     s4)
+JNI_GET_FIELD(Long,    jlong,    s8)
+JNI_GET_FIELD(Float,   jfloat,   float)
+JNI_GET_FIELD(Double,  jdouble,  double)
+
+
+jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
+{
+       java_handle_t *o;
+
+       TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
+
+       LLNI_CRITICAL_START;
+
+       o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
+
+       LLNI_CRITICAL_END;
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+/* Set<type>Field Routines *****************************************************
+
+   This family of accessor routines sets the value of an instance
+   (nonstatic) field of an object. The field to access is specified by
+   a field ID obtained by calling GetFieldID().
+
+*******************************************************************************/
+
+#define SET_FIELD(o,type,f,value) \
+    *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
+
+#define JNI_SET_FIELD(name, type, intern)                                  \
+void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
+                                                         type value)                                  \
+{                                                                          \
+       TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
+                                                                           \
+       LLNI_CRITICAL_START;                                                   \
+                                                                           \
+       SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
+                                                                              \
+       LLNI_CRITICAL_START;                                                   \
+}
+
+JNI_SET_FIELD(Boolean, jboolean, s4)
+JNI_SET_FIELD(Byte,    jbyte,    s4)
+JNI_SET_FIELD(Char,    jchar,    s4)
+JNI_SET_FIELD(Short,   jshort,   s4)
+JNI_SET_FIELD(Int,     jint,     s4)
+JNI_SET_FIELD(Long,    jlong,    s8)
+JNI_SET_FIELD(Float,   jfloat,   float)
+JNI_SET_FIELD(Double,  jdouble,  double)
+
+
+void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
+                                                       jobject value)
+{
+       TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
+
+       LLNI_CRITICAL_START;
+
+       SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
+
+       LLNI_CRITICAL_END;
+}
+
+
+/* Calling Static Methods *****************************************************/
+
+/* GetStaticMethodID ***********************************************************
+
+   Returns the method ID for a static method of a class. The method is
+   specified by its name and signature.
+
+   GetStaticMethodID() causes an uninitialized class to be
+   initialized.
+
+*******************************************************************************/
+
+jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
+                                                                       const char *sig)
+{
+       classinfo  *c;
+       utf        *uname;
+       utf        *udesc;
+       methodinfo *m;
+
+       TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
+
+       c = LLNI_classinfo_unwrap(clazz);
+
+       if (c == NULL)
+               return NULL;
+
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return NULL;
+
+       /* try to get the static method of the class */
+
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
+
+       m = class_resolvemethod(c, uname, udesc);
+
+       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
+               exceptions_throw_nosuchmethoderror(c, uname, udesc);
+
+               return NULL;
+       }
+
+       return (jmethodID) m;
+}
+
+
+#define JNI_CALL_STATIC_METHOD(name, type, intern)               \
+type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
+                                                                         jmethodID methodID, ...)   \
+{                                                                \
+       methodinfo *m;                                               \
+       va_list     ap;                                              \
+       type        res;                                             \
+                                                                 \
+       m = (methodinfo *) methodID;                                 \
+                                                                 \
+       va_start(ap, methodID);                                      \
+       res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap);       \
+       va_end(ap);                                                  \
+                                                                 \
+       return res;                                                  \
+}
+
+JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD(Byte,    jbyte,    Int)
+JNI_CALL_STATIC_METHOD(Char,    jchar,    Int)
+JNI_CALL_STATIC_METHOD(Short,   jshort,   Int)
+JNI_CALL_STATIC_METHOD(Int,     jint,     Int)
+JNI_CALL_STATIC_METHOD(Long,    jlong,    Long)
+JNI_CALL_STATIC_METHOD(Float,   jfloat,   Float)
+JNI_CALL_STATIC_METHOD(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_STATIC_METHOD_V(name, type, intern)                     \
+type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz,        \
+                                                                          jmethodID methodID, va_list args) \
+{                                                                        \
+       methodinfo *m;                                                       \
+       type        res;                                                     \
+                                                                         \
+       m = (methodinfo *) methodID;                                         \
+                                                                         \
+       res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args);             \
+                                                                         \
+       return res;                                                          \
+}
+
+JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD_V(Byte,    jbyte,    Int)
+JNI_CALL_STATIC_METHOD_V(Char,    jchar,    Int)
+JNI_CALL_STATIC_METHOD_V(Short,   jshort,   Int)
+JNI_CALL_STATIC_METHOD_V(Int,     jint,     Int)
+JNI_CALL_STATIC_METHOD_V(Long,    jlong,    Long)
+JNI_CALL_STATIC_METHOD_V(Float,   jfloat,   Float)
+JNI_CALL_STATIC_METHOD_V(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_STATIC_METHOD_A(name, type, intern)                           \
+type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz,              \
+                                                                          jmethodID methodID, const jvalue *args) \
+{                                                                              \
+       methodinfo *m;                                                             \
+       type        res;                                                           \
+                                                                               \
+       m = (methodinfo *) methodID;                                               \
+                                                                               \
+       res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args);                  \
+                                                                               \
+       return res;                                                                \
+}
+
+JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD_A(Byte,    jbyte,    Int)
+JNI_CALL_STATIC_METHOD_A(Char,    jchar,    Int)
+JNI_CALL_STATIC_METHOD_A(Short,   jshort,   Int)
+JNI_CALL_STATIC_METHOD_A(Int,     jint,     Int)
+JNI_CALL_STATIC_METHOD_A(Long,    jlong,    Long)
+JNI_CALL_STATIC_METHOD_A(Float,   jfloat,   Float)
+JNI_CALL_STATIC_METHOD_A(Double,  jdouble,  Double)
+
+
+jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
+                                                                          jmethodID methodID, ...)
+{
+       methodinfo    *m;
+       java_handle_t *o;
+       va_list        ap;
+
+       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
+
+       m = (methodinfo *) methodID;
+
+       va_start(ap, methodID);
+       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
+       va_end(ap);
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
+                                                                               jmethodID methodID, va_list args)
+{
+       methodinfo    *m;
+       java_handle_t *o;
+
+       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
+       m = (methodinfo *) methodID;
+
+       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
+                                                                               jmethodID methodID, const jvalue *args)
+{
+       methodinfo    *m;
+       java_handle_t *o;
+
+       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
+       m = (methodinfo *) methodID;
+
+       o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
+                                                                 jmethodID methodID, ...)
+{
+       methodinfo *m;
+       va_list     ap;
+
+       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
+
+       m = (methodinfo *) methodID;
+
+       va_start(ap, methodID);
+       _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
+       va_end(ap);
+}
+
+
+void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
+                                                                  jmethodID methodID, va_list args)
+{
+       methodinfo *m;
+
+       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
+       m = (methodinfo *) methodID;
+
+       _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
+}
+
+
+void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
+                                                                  jmethodID methodID, const jvalue * args)
+{
+       methodinfo *m;
+
+       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
+       m = (methodinfo *) methodID;
+
+       _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
+}
+
+
+/* Accessing Static Fields ****************************************************/
+
+/* GetStaticFieldID ************************************************************
+
+   Returns the field ID for a static field of a class. The field is
+   specified by its name and signature. The GetStatic<type>Field and
+   SetStatic<type>Field families of accessor functions use field IDs
+   to retrieve static fields.
+
+*******************************************************************************/
+
+jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
+                                                                 const char *sig)
+{
+       classinfo *c;
+       fieldinfo *f;
+       utf       *uname;
+       utf       *usig;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+
+       uname = utf_new_char((char *) name);
+       usig  = utf_new_char((char *) sig);
+
+       f = class_findfield(c, uname, usig);
+       
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);
+
+       return (jfieldID) f;
+}
+
+
+/* GetStatic<type>Field ********************************************************
+
+   This family of accessor routines returns the value of a static
+   field of an object.
+
+*******************************************************************************/
+
+#define JNI_GET_STATIC_FIELD(name, type, field)                \
+type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
+                                                                       jfieldID fieldID)          \
+{                                                              \
+       classinfo *c;                                              \
+       fieldinfo *f;                                              \
+                                                               \
+       STATISTICS(jniinvokation());                               \
+                                                               \
+       c = LLNI_classinfo_unwrap(clazz);                          \
+       f = (fieldinfo *) fieldID;                                 \
+                                                               \
+       if (!(c->state & CLASS_INITIALIZED))                       \
+               if (!initialize_class(c))                              \
+                       return 0;                                          \
+                                                               \
+       return f->value->field;                                    \
+}
+
+JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
+JNI_GET_STATIC_FIELD(Byte,    jbyte,    i)
+JNI_GET_STATIC_FIELD(Char,    jchar,    i)
+JNI_GET_STATIC_FIELD(Short,   jshort,   i)
+JNI_GET_STATIC_FIELD(Int,     jint,     i)
+JNI_GET_STATIC_FIELD(Long,    jlong,    l)
+JNI_GET_STATIC_FIELD(Float,   jfloat,   f)
+JNI_GET_STATIC_FIELD(Double,  jdouble,  d)
+
+
+jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
+                                                                        jfieldID fieldID)
+{
+       classinfo     *c;
+       fieldinfo     *f;
+       java_handle_t *h;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+       f = (fieldinfo *) fieldID;
+
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return NULL;
+
+       h = (java_handle_t*) LLNI_WRAP(f->value->a);
+
+       return jni_NewLocalRef(env, (jobject) h);
+}
+
+
+/*  SetStatic<type>Field *******************************************************
+
+       This family of accessor routines sets the value of a static field
+       of an object.
+
+*******************************************************************************/
+
+#define JNI_SET_STATIC_FIELD(name, type, field)                \
+void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
+                                                                       jfieldID fieldID,          \
+                                                                       type value)                \
+{                                                              \
+       classinfo *c;                                              \
+       fieldinfo *f;                                              \
+                                                               \
+       STATISTICS(jniinvokation());                               \
+                                                               \
+       c = LLNI_classinfo_unwrap(clazz);                          \
+       f = (fieldinfo *) fieldID;                                 \
+                                                               \
+       if (!(c->state & CLASS_INITIALIZED))                       \
+               if (!initialize_class(c))                              \
+                       return;                                            \
+                                                               \
+       f->value->field = value;                                   \
+}
+
+JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
+JNI_SET_STATIC_FIELD(Byte,    jbyte,    i)
+JNI_SET_STATIC_FIELD(Char,    jchar,    i)
+JNI_SET_STATIC_FIELD(Short,   jshort,   i)
+JNI_SET_STATIC_FIELD(Int,     jint,     i)
+JNI_SET_STATIC_FIELD(Long,    jlong,    l)
+JNI_SET_STATIC_FIELD(Float,   jfloat,   f)
+JNI_SET_STATIC_FIELD(Double,  jdouble,  d)
+
+
+void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+                                                                 jobject value)
+{
+       classinfo *c;
+       fieldinfo *f;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+       f = (fieldinfo *) fieldID;
+
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return;
+
+       f->value->a = LLNI_UNWRAP((java_handle_t *) value);
+}
+
+
+/* String Operations **********************************************************/
+
+/* NewString *******************************************************************
+
+   Create new java.lang.String object from an array of Unicode
+   characters.
+
+*******************************************************************************/
+
+jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
+{
+       TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
+       
+       java_handle_chararray_t* a = builtin_newarray_char(len);
+
+       if (a == NULL)
+               return NULL;
+
+       /* copy text */
+       for (jsize i = 0; i < len; i++)
+               LLNI_array_direct(a, i) = buf[i];
+
+       java_handle_t* h = builtin_new(class_java_lang_String);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_String s(h, a, len, 0);
+
+       return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
+}
+
+
+static jchar emptyStringJ[]={0,0};
+
+/* GetStringLength *************************************************************
+
+   Returns the length (the count of Unicode characters) of a Java
+   string.
+
+*******************************************************************************/
+
+jsize jni_GetStringLength(JNIEnv *env, jstring str)
+{
+       TRACEJNICALLSENTER(("jni_GetStringLength(env=%p, str=%p)", env, str));
+
+       java_lang_String s(str);
+       jsize count = s.get_count();
+
+       TRACEJNICALLSEXIT(("->%d)", count));
+
+       return count;
+}
+
+
+/* GetStringChars **************************************************************
+
+   Returns a pointer to the array of Unicode characters of the
+   string. This pointer is valid until ReleaseStringChars() is called.
+
+*******************************************************************************/
+
+const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
+{      
+       u2      *stringbuffer;
+       int32_t  i;
+
+       TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
+
+       if (str == NULL)
+               // FIXME This is really ugly.
+               return emptyStringJ;
+
+       java_lang_String s(str);
+
+       java_handle_chararray_t* ca     = s.get_value();
+       int32_t                  count  = s.get_count();
+       int32_t                  offset = s.get_offset();
+       
+       if (ca == NULL)
+               return NULL;
+
+       /* allocate memory */
+
+       stringbuffer = MNEW(u2, count + 1);
+
+       /* copy text */
+
+       for (i = 0; i < count; i++)
+               stringbuffer[i] = LLNI_array_direct(ca, offset + i);
+       
+       /* terminate string */
+
+       stringbuffer[i] = '\0';
+
+       if (isCopy)
+               *isCopy = JNI_TRUE;
+
+       return (jchar*) stringbuffer;
+}
+
+
+/* ReleaseStringChars **********************************************************
+
+   Informs the VM that the native code no longer needs access to
+   chars. The chars argument is a pointer obtained from string using
+   GetStringChars().
+
+*******************************************************************************/
+
+void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
+{
+       TRACEJNICALLS(("jni_ReleaseStringChars(env=%p, str=%p, chars=%p)", env, str, chars));
+
+       // FIXME
+       if (chars == emptyStringJ)
+               return;
+
+       java_lang_String s(str);
+       int32_t count = s.get_count();
+
+       MFREE(((jchar*) chars), jchar, count + 1);
+}
+
+
+/* NewStringUTF ****************************************************************
+
+   Constructs a new java.lang.String object from an array of UTF-8
+   characters.
+
+*******************************************************************************/
+
+jstring jni_NewStringUTF(JNIEnv *env, const char *bytes)
+{
+       TRACEJNICALLS(("jni_NewStringUTF(env=%p, bytes=%s)", env, bytes));
+
+       java_handle_t *h = javastring_safe_new_from_utf8(bytes);
+
+    return (jstring) jni_NewLocalRef(env, (jobject) h);
+}
+
+
+/****************** returns the utf8 length in bytes of a string *******************/
+
+jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
+{   
+       TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
+
+       java_lang_String s(string);
+       java_handle_chararray_t* ca     = s.get_value();
+       int32_t                  count  = s.get_count();
+
+       // FIXME GC critical section!
+       int32_t length = u2_utflength(ca->data, count);
+
+       return length;
+}
+
+
+/* GetStringUTFChars ***********************************************************
+
+   Returns a pointer to an array of UTF-8 characters of the
+   string. This array is valid until it is released by
+   ReleaseStringUTFChars().
+
+*******************************************************************************/
+
+const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
+                                                                         jboolean *isCopy)
+{
+       utf *u;
+
+       STATISTICS(jniinvokation());
+
+       if (string == NULL)
+               return "";
+
+       if (isCopy)
+               *isCopy = JNI_TRUE;
+       
+       u = javastring_toutf((java_handle_t *) string, false);
+
+       if (u != NULL)
+               return u->text;
+
+       return "";
+}
+
+
+/* ReleaseStringUTFChars *******************************************************
+
+   Informs the VM that the native code no longer needs access to
+   utf. The utf argument is a pointer derived from string using
+   GetStringUTFChars().
+
+*******************************************************************************/
+
+void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
+{
+       STATISTICS(jniinvokation());
+
+    /* XXX we don't release utf chars right now, perhaps that should be done 
+          later. Since there is always one reference the garbage collector will
+          never get them */
+}
+
+
+/* Array Operations ***********************************************************/
+
+/* GetArrayLength **************************************************************
+
+   Returns the number of elements in the array.
+
+*******************************************************************************/
+
+jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
+{
+       java_handle_t *a;
+       jsize          size;
+
+       TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
+
+       a = (java_handle_t *) array;
+
+       size = LLNI_array_size(a);
+
+       return size;
+}
+
+
+/* NewObjectArray **************************************************************
+
+   Constructs a new array holding objects in class elementClass. All
+   elements are initially set to initialElement.
+
+*******************************************************************************/
+
+jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
+                                                                       jclass elementClass, jobject initialElement)
+{
+       classinfo                 *c;
+       java_handle_t             *o;
+       java_handle_objectarray_t *oa;
+       s4                         i;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(elementClass);
+       o = (java_handle_t *) initialElement;
+
+       if (length < 0) {
+               exceptions_throw_negativearraysizeexception();
+               return NULL;
+       }
+
+    oa = builtin_anewarray(length, c);
+
+       if (oa == NULL)
+               return NULL;
+
+       /* set all elements to initialElement */
+
+       for (i = 0; i < length; i++)
+               array_objectarray_element_set(oa, i, o);
+
+       return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
+}
+
+
+jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
+                                                                         jsize index)
+{
+       java_handle_objectarray_t *oa;
+       java_handle_t             *o;
+
+       STATISTICS(jniinvokation());
+
+       oa = (java_handle_objectarray_t *) array;
+
+       if (index >= LLNI_array_size(oa)) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return NULL;
+       }
+
+       o = array_objectarray_element_get(oa, index);
+
+       return jni_NewLocalRef(env, (jobject) o);
+}
+
+
+void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
+                                                                  jsize index, jobject val)
+{
+       java_handle_objectarray_t *oa;
+       java_handle_t             *o;
+
+       STATISTICS(jniinvokation());
+
+       oa = (java_handle_objectarray_t *) array;
+       o  = (java_handle_t *) val;
+
+       if (index >= LLNI_array_size(oa)) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return;
+       }
+
+       /* check if the class of value is a subclass of the element class
+          of the array */
+
+       if (!builtin_canstore(oa, o))
+               return;
+
+       array_objectarray_element_set(oa, index, o);
+}
+
+
+#define JNI_NEW_ARRAY(name, type, intern)                \
+type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
+{                                                        \
+       java_handle_##intern##array_t *a;                    \
+                                                         \
+       STATISTICS(jniinvokation());                         \
+                                                         \
+       if (len < 0) {                                       \
+               exceptions_throw_negativearraysizeexception();   \
+               return NULL;                                     \
+       }                                                    \
+                                                         \
+       a = builtin_newarray_##intern(len);                  \
+                                                         \
+       return (type) jni_NewLocalRef(env, (jobject) a); \
+}
+
+JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
+JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
+JNI_NEW_ARRAY(Char,    jcharArray,    char)
+JNI_NEW_ARRAY(Short,   jshortArray,   short)
+JNI_NEW_ARRAY(Int,     jintArray,     int)
+JNI_NEW_ARRAY(Long,    jlongArray,    long)
+JNI_NEW_ARRAY(Float,   jfloatArray,   float)
+JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
+
+
+/* Get<PrimitiveType>ArrayElements *********************************************
+
+   A family of functions that returns the body of the primitive array.
+
+*******************************************************************************/
+
+#define JNI_GET_ARRAY_ELEMENTS(name, type, intern)                     \
+type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
+                                                                                jboolean *isCopy)             \
+{                                                                      \
+       java_handle_##intern##array_t *a;                                  \
+                                                                       \
+       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
+                                                                       \
+       a = (java_handle_##intern##array_t *) array;                       \
+                                                                       \
+       if (isCopy)                                                        \
+               *isCopy = JNI_FALSE;                                           \
+                                                                       \
+       return (type *) LLNI_array_data(a);                                \
+}
+
+JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
+JNI_GET_ARRAY_ELEMENTS(Byte,    jbyte,    byte)
+JNI_GET_ARRAY_ELEMENTS(Char,    jchar,    char)
+JNI_GET_ARRAY_ELEMENTS(Short,   jshort,   short)
+JNI_GET_ARRAY_ELEMENTS(Int,     jint,     int)
+JNI_GET_ARRAY_ELEMENTS(Long,    jlong,    long)
+JNI_GET_ARRAY_ELEMENTS(Float,   jfloat,   float)
+JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
+
+
+/* Release<PrimitiveType>ArrayElements *****************************************
+
+   A family of functions that informs the VM that the native code no
+   longer needs access to elems. The elems argument is a pointer
+   derived from array using the corresponding
+   Get<PrimitiveType>ArrayElements() function. If necessary, this
+   function copies back all changes made to elems to the original
+   array.
+
+*******************************************************************************/
+
+#define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2)            \
+void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array,  \
+                                                                                 type *elems, jint mode)          \
+{                                                                          \
+       java_handle_##intern##array_t *a;                                      \
+                                                                           \
+       STATISTICS(jniinvokation());                                           \
+                                                                           \
+       a = (java_handle_##intern##array_t *) array;                           \
+                                                                           \
+       if (elems != (type *) LLNI_array_data(a)) {                            \
+               switch (mode) {                                                    \
+               case JNI_COMMIT:                                                   \
+                       MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+                       break;                                                         \
+               case 0:                                                            \
+                       MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+                       /* XXX TWISTI how should it be freed? */                       \
+                       break;                                                         \
+               case JNI_ABORT:                                                    \
+                       /* XXX TWISTI how should it be freed? */                       \
+                       break;                                                         \
+               }                                                                  \
+       }                                                                      \
+}
+
+JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
+JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    s1)
+JNI_RELEASE_ARRAY_ELEMENTS(Char,    jchar,    char,    u2)
+JNI_RELEASE_ARRAY_ELEMENTS(Short,   jshort,   short,   s2)
+JNI_RELEASE_ARRAY_ELEMENTS(Int,     jint,     int,     s4)
+JNI_RELEASE_ARRAY_ELEMENTS(Long,    jlong,    long,    s8)
+JNI_RELEASE_ARRAY_ELEMENTS(Float,   jfloat,   float,   float)
+JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
+
+
+/*  Get<PrimitiveType>ArrayRegion **********************************************
+
+       A family of functions that copies a region of a primitive array
+       into a buffer.
+
+*******************************************************************************/
+
+#define JNI_GET_ARRAY_REGION(name, type, intern, intern2)               \
+void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
+                                                                       jsize start, jsize len, type *buf)  \
+{                                                                       \
+       java_handle_##intern##array_t *a;                                   \
+                                                                        \
+       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
+                                                                        \
+       a = (java_handle_##intern##array_t *) array;                        \
+                                                                        \
+       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
+               exceptions_throw_arrayindexoutofboundsexception();              \
+       else                                                                \
+               MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
+}
+
+JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
+JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
+JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
+JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
+JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
+JNI_GET_ARRAY_REGION(Long,    jlong,    long,    s8)
+JNI_GET_ARRAY_REGION(Float,   jfloat,   float,   float)
+JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
+
+
+/*  Set<PrimitiveType>ArrayRegion **********************************************
+
+       A family of functions that copies back a region of a primitive
+       array from a buffer.
+
+*******************************************************************************/
+
+#define JNI_SET_ARRAY_REGION(name, type, intern, intern2)                    \
+void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
+                                                                       jsize start, jsize len, const type *buf) \
+{                                                                            \
+       java_handle_##intern##array_t *a;                                        \
+                                                                             \
+       STATISTICS(jniinvokation());                                             \
+                                                                             \
+       a = (java_handle_##intern##array_t *) array;                             \
+                                                                             \
+       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
+               exceptions_throw_arrayindexoutofboundsexception();                   \
+       else                                                                     \
+               MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
+}
+
+JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
+JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
+JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
+JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
+JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
+JNI_SET_ARRAY_REGION(Long,    jlong,    long,    s8)
+JNI_SET_ARRAY_REGION(Float,   jfloat,   float,   float)
+JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
+
+
+/* Registering Native Methods *************************************************/
+
+/* RegisterNatives *************************************************************
+
+   Registers native methods with the class specified by the clazz
+   argument. The methods parameter specifies an array of
+   JNINativeMethod structures that contain the names, signatures, and
+   function pointers of the native methods. The nMethods parameter
+   specifies the number of native methods in the array.
+
+*******************************************************************************/
+
+jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
+                                                        const JNINativeMethod *methods, jint nMethods)
+{
+       classinfo *c;
+
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+
+       /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
+       if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
+       */
+
+       native_method_register(c->name, methods, nMethods);
+
+    return 0;
+}
+
+
+/* UnregisterNatives ***********************************************************
+
+   Unregisters native methods of a class. The class goes back to the
+   state before it was linked or registered with its native method
+   functions.
+
+   This function should not be used in normal native code. Instead, it
+   provides special programs a way to reload and relink native
+   libraries.
+
+*******************************************************************************/
+
+jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
+{
+       STATISTICS(jniinvokation());
+
+       /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
+
+    log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
+
+    return 0;
+}
+
+
+/* Monitor Operations *********************************************************/
+
+/* MonitorEnter ****************************************************************
+
+   Enters the monitor associated with the underlying Java object
+   referred to by obj.
+
+*******************************************************************************/
+
+jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
+{
+       STATISTICS(jniinvokation());
+
+       if (obj == NULL) {
+               exceptions_throw_nullpointerexception();
+               return JNI_ERR;
+       }
+
+       LOCK_MONITOR_ENTER(obj);
+
+       return JNI_OK;
+}
+
+
+/* MonitorExit *****************************************************************
+
+   The current thread must be the owner of the monitor associated with
+   the underlying Java object referred to by obj. The thread
+   decrements the counter indicating the number of times it has
+   entered this monitor. If the value of the counter becomes zero, the
+   current thread releases the monitor.
+
+*******************************************************************************/
+
+jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
+{
+       STATISTICS(jniinvokation());
+
+       if (obj == NULL) {
+               exceptions_throw_nullpointerexception();
+               return JNI_ERR;
+       }
+
+       LOCK_MONITOR_EXIT(obj);
+
+       return JNI_OK;
+}
+
+
+/* JavaVM Interface ***********************************************************/
+
+/* GetJavaVM *******************************************************************
+
+   Returns the Java VM interface (used in the Invocation API)
+   associated with the current thread. The result is placed at the
+   location pointed to by the second argument, vm.
+
+*******************************************************************************/
+
+jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
+{
+       STATISTICS(jniinvokation());
+
+    *javavm = vm->get_javavm();
+
+       return 0;
+}
+
+
+/* GetStringRegion *************************************************************
+
+   Copies len number of Unicode characters beginning at offset start
+   to the given buffer buf.
+
+   Throws StringIndexOutOfBoundsException on index overflow.
+
+*******************************************************************************/
+
+void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
+{
+       java_lang_String s(str);
+       java_handle_chararray_t* ca    = s.get_value();
+       int32_t                  count = s.get_count();
+
+       if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
+               exceptions_throw_stringindexoutofboundsexception();
+               return;
+       }
+
+       MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
+}
+
+
+/* GetStringUTFRegion **********************************************************
+
+    Translates len number of Unicode characters beginning at offset
+    start into UTF-8 format and place the result in the given buffer
+    buf.
+
+    Throws StringIndexOutOfBoundsException on index overflow. 
+
+*******************************************************************************/
+
+void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
+{
+       TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
+
+       java_lang_String s(str);
+       java_handle_chararray_t* ca     = s.get_value();
+       int32_t                  count  = s.get_count();
+       int32_t                  offset = s.get_offset();
+
+       if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
+               exceptions_throw_stringindexoutofboundsexception();
+               return;
+       }
+
+       int32_t i;
+
+       for (i = 0; i < len; i++)
+               buf[i] = LLNI_array_direct(ca, offset + start + i);
+
+       buf[i] = '\0';
+}
+
+
+/* GetPrimitiveArrayCritical ***************************************************
+
+   Obtain a direct pointer to array elements.
+
+   ATTENTION: Critical section keeps open when this function returns!
+   See ReleasePrimitiveArrayCritical.
+
+*******************************************************************************/
+
+void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
+{
+       java_handle_t*   h;
+       java_array_t*    a;
+       arraydescriptor* ad;
+       void*            data;
+
+       TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
+
+       if (isCopy != NULL) {
+               *isCopy = JNI_FALSE;
+       }
+
+       LLNI_CRITICAL_START;
+
+       h  = (java_handle_t*) array;
+       a  = (java_array_t*) LLNI_UNWRAP(h);
+       ad = a->objheader.vftbl->arraydesc;
+
+       /* Sanity check. */
+
+       assert(ad != NULL);
+
+       data = (void*) (((intptr_t) a) + ad->dataoffset);
+
+       return data;
+}
+
+
+/* ReleasePrimitiveArrayCritical ***********************************************
+
+   No specific documentation.
+
+   ATTENTION: This function closes the critical section opened in
+   GetPrimitiveArrayCritical!
+
+*******************************************************************************/
+
+void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
+{
+       TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
+
+       LLNI_CRITICAL_END;
+}
+
+
+/* GetStringCritical ***********************************************************
+
+   The semantics of these two functions are similar to the existing
+   Get/ReleaseStringChars functions.
+
+*******************************************************************************/
+
+const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
+                                                                          jboolean *isCopy)
+{
+       STATISTICS(jniinvokation());
+
+       return jni_GetStringChars(env, string, isCopy);
+}
+
+
+void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
+                                                                  const jchar *cstring)
+{
+       STATISTICS(jniinvokation());
+
+       _Jv_JNI_ReleaseStringChars(env, string, cstring);
+}
+
+
+jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
+{
+       TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
+
+       return (jweak) obj;
+}
+
+
+void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
+{
+       TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
+}
+
+
+/* NewGlobalRef ****************************************************************
+
+   Creates a new global reference to the object referred to by the obj
+   argument.
+
+*******************************************************************************/
+    
+jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
+{
+       hashtable_global_ref_entry *gre;
+       u4   key;                           /* hashkey                            */
+       u4   slot;                          /* slot in hashtable                  */
+       java_handle_t *o;
+
+       TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
+
+       o = (java_handle_t *) obj;
+
+       LOCK_MONITOR_ENTER(hashtable_global_ref->header);
+
+       LLNI_CRITICAL_START;
+
+       /* normally addresses are aligned to 4, 8 or 16 bytes */
+
+       key  = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
+       slot = key & (hashtable_global_ref->size - 1);
+       gre  = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
+       
+       /* search external hash chain for the entry */
+
+       while (gre) {
+               if (gre->o == LLNI_DIRECT(o)) {
+                       /* global object found, increment the reference */
+
+                       gre->refs++;
+
+                       break;
+               }
+
+               gre = gre->hashlink;                /* next element in external chain */
+       }
+
+       LLNI_CRITICAL_END;
+
+       /* global ref not found, create a new one */
+
+       if (gre == NULL) {
+               gre = (hashtable_global_ref_entry*) heap_alloc_uncollectable(sizeof(hashtable_global_ref_entry));
+
+#if defined(ENABLE_GC_CACAO)
+               /* register global ref with the GC */
+
+               gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
+#endif
+
+               LLNI_CRITICAL_START;
+
+               gre->o    = LLNI_DIRECT(o);
+               gre->refs = 1;
+
+               LLNI_CRITICAL_END;
+
+               /* insert entry into hashtable */
+
+               gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
+
+               hashtable_global_ref->ptr[slot] = gre;
+
+               /* update number of hashtable-entries */
+
+               hashtable_global_ref->entries++;
+       }
+
+       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+
+#if defined(ENABLE_HANDLES)
+       return gre;
+#else
+       return obj;
+#endif
+}
+
+
+/* DeleteGlobalRef *************************************************************
+
+   Deletes the global reference pointed to by globalRef.
+
+*******************************************************************************/
+
+void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
+{
+       hashtable_global_ref_entry *gre;
+       hashtable_global_ref_entry *prevgre;
+       u4   key;                           /* hashkey                            */
+       u4   slot;                          /* slot in hashtable                  */
+       java_handle_t              *o;
+
+       TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
+
+       o = (java_handle_t *) globalRef;
+
+       LOCK_MONITOR_ENTER(hashtable_global_ref->header);
+
+       LLNI_CRITICAL_START;
+
+       /* normally addresses are aligned to 4, 8 or 16 bytes */
+
+       key  = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
+       slot = key & (hashtable_global_ref->size - 1);
+       gre  = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
+
+       /* initialize prevgre */
+
+       prevgre = NULL;
+
+       /* search external hash chain for the entry */
+
+       while (gre) {
+               if (gre->o == LLNI_DIRECT(o)) {
+                       /* global object found, decrement the reference count */
+
+                       gre->refs--;
+
+                       /* if reference count is 0, remove the entry */
+
+                       if (gre->refs == 0) {
+                               /* special handling if it's the first in the chain */
+
+                               if (prevgre == NULL)
+                                       hashtable_global_ref->ptr[slot] = gre->hashlink;
+                               else
+                                       prevgre->hashlink = gre->hashlink;
+
+#if defined(ENABLE_GC_CACAO)
+                               /* unregister global ref with the GC */
+
+                               gc_reference_unregister(&(gre->o));
+#endif
+
+                               heap_free(gre);
+                       }
+
+                       LLNI_CRITICAL_END;
+
+                       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+
+                       return;
+               }
+
+               prevgre = gre;                    /* save current pointer for removal */
+               gre     = gre->hashlink;            /* next element in external chain */
+       }
+
+       log_println("jni_DeleteGlobalRef: Global reference not found.");
+
+       LLNI_CRITICAL_END;
+
+       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+}
+
+
+/* ExceptionCheck **************************************************************
+
+   Returns JNI_TRUE when there is a pending exception; otherwise,
+   returns JNI_FALSE.
+
+*******************************************************************************/
+
+jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
+{
+       java_handle_t *o;
+
+       STATISTICS(jniinvokation());
+
+       o = exceptions_get_exception();
+
+       return (o != NULL) ? JNI_TRUE : JNI_FALSE;
+}
+
+
+/* New JNI 1.4 functions ******************************************************/
+
+/* NewDirectByteBuffer *********************************************************
+
+   Allocates and returns a direct java.nio.ByteBuffer referring to the
+   block of memory starting at the memory address address and
+   extending capacity bytes.
+
+*******************************************************************************/
+
+jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
+{
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
+
+       // Allocate a gnu.classpath.Pointer{32,64} object.
+
+# if SIZEOF_VOID_P == 8
+       java_handle_t* h = builtin_new(class_gnu_classpath_Pointer64);
+# else
+       java_handle_t* h = builtin_new(class_gnu_classpath_Pointer32);
+# endif
+
+       if (h == NULL)
+               return NULL;
+
+       gnu_classpath_Pointer p(h, address);
+
+       // Create a java.nio.DirectByteBufferImpl$ReadWrite object.
+
+       java_handle_t* nbuf =
+               (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
+                                                                          (jmethodID) dbbirw_init, NULL, p.get_handle(),
+                                                                          (jint) capacity, (jint) capacity, (jint) 0);
+
+       // Add a local reference and return the value.
+
+       TRACEJNICALLSEXIT(("->%p", nbuf));
+
+       return jni_NewLocalRef(env, (jobject) nbuf);
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       jobject o;
+       int64_t addr;
+       int32_t cap;
+
+       TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
+
+       /* Be paranoid about address sign-extension. */
+
+       addr = (int64_t) ((uintptr_t) address);
+       cap  = (int32_t) capacity;
+
+       o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
+                                         (jmethodID) dbb_init, addr, cap);
+
+       /* Add local reference and return the value. */
+
+       TRACEJNICALLSEXIT(("->%p", o));
+
+       return jni_NewLocalRef(env, o);
+
+# else
+#  error unknown classpath configuration
+# endif
+
+#else
+       vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
+}
+
+
+/* GetDirectBufferAddress ******************************************************
+
+   Fetches and returns the starting address of the memory region
+   referenced by the given direct java.nio.Buffer.
+
+*******************************************************************************/
+
+void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
+{
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       TRACEJNICALLSENTER(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
+
+       /* Prevent compiler warning. */
+
+       java_handle_t* h = (java_handle_t *) buf;
+
+       if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
+               return NULL;
+
+       java_nio_DirectByteBufferImpl dbb(buf);
+       java_handle_t* address = dbb.get_address();
+
+       if (address == NULL) {
+               TRACEJNICALLSEXIT(("->%p", NULL));
+               return NULL;
+       }
+
+       gnu_classpath_Pointer p(address);
+       void* data = p.get_data();
+
+       TRACEJNICALLSEXIT(("->%p", data));
+
+       return data;
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       TRACEJNICALLS(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
+
+       java_nio_Buffer jnb(buf);
+
+       if (jnb.is_non_null() && !builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
+               return NULL;
+
+       void* address = jnb.get_address();
+
+       return address;
+
+# else
+#  error unknown classpath configuration
+# endif
+
+#else
+
+       vm_abort("jni_GetDirectBufferAddress: Not implemented in this configuration.");
+
+       // Keep compiler happy.
+       return NULL;
+
+#endif
+}
+
+
+/* GetDirectBufferCapacity *****************************************************
+
+   Fetches and returns the capacity in bytes of the memory region
+   referenced by the given direct java.nio.Buffer.
+
+*******************************************************************************/
+
+jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
+{
+#if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
+
+       java_handle_t* h = (java_handle_t *) buf;
+
+       if (!builtin_instanceof(h, class_java_nio_DirectByteBufferImpl))
+               return -1;
+
+       java_nio_Buffer b(h);
+       jlong capacity = b.get_cap();
+
+       return capacity;
+#else
+       vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
+
+       // Keep compiler happy.
+
+       return 0;
+#endif
+}
+
+
+/* GetObjectRefType ************************************************************
+
+   Returns the type of the object referred to by the obj argument. The
+   argument obj can either be a local, global or weak global
+   reference.
+
+*******************************************************************************/
+
+jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
+{
+       log_println("jni_GetObjectRefType: IMPLEMENT ME!");
+
+       return (jobjectRefType) NULL;
+}
+
+
+/* DestroyJavaVM ***************************************************************
+
+   Unloads a Java VM and reclaims its resources. Only the main thread
+   can unload the VM. The system waits until the main thread is only
+   remaining user thread before it destroys the VM.
+
+*******************************************************************************/
+
+jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
+{
+       int status;
+
+       TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
+
+       if (vm->is_created() == false)
+               return JNI_ERR;
+
+    status = vm_destroy(javavm);
+
+       return status;
+}
+
+
+/* AttachCurrentThread *********************************************************
+
+   Attaches the current thread to a Java VM. Returns a JNI interface
+   pointer in the JNIEnv argument.
+
+   Trying to attach a thread that is already attached is a no-op.
+
+   A native thread cannot be attached simultaneously to two Java VMs.
+
+   When a thread is attached to the VM, the context class loader is
+   the bootstrap loader.
+
+*******************************************************************************/
+
+static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
+{
+#if defined(ENABLE_THREADS)
+       JavaVMAttachArgs *vm_aargs;
+       bool              result;
+
+    /* If the current thread has already been attached, this operation
+          is a no-op. */
+
+       result = thread_current_is_attached();
+
+       if (result == true) {
+               *p_env = vm->get_jnienv();
+               return JNI_OK;
+       }
+
+       vm_aargs = (JavaVMAttachArgs *) thr_args;
+
+       if (vm_aargs != NULL) {
+               if ((vm_aargs->version != JNI_VERSION_1_2) &&
+                       (vm_aargs->version != JNI_VERSION_1_4))
+                       return JNI_EVERSION;
+       }
+
+       if (!thread_attach_current_external_thread(vm_aargs, false))
+               return JNI_ERR;
+
+       if (!localref_table_init())
+               return JNI_ERR;
+#endif
+
+       *p_env = vm->get_jnienv();
+
+       return JNI_OK;
+}
+
+
+jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
+{
+       int result;
+
+       TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
+
+       if (vm->is_created() == false)
+               return JNI_ERR;
+
+       result = jni_attach_current_thread(p_env, thr_args, false);
+
+       return result;
+}
+
+
+/* DetachCurrentThread *********************************************************
+
+   Detaches the current thread from a Java VM. All Java monitors held
+   by this thread are released. All Java threads waiting for this
+   thread to die are notified.
+
+   In JDK 1.1, the main thread cannot be detached from the VM. It must
+   call DestroyJavaVM to unload the entire VM.
+
+   In the JDK, the main thread can be detached from the VM.
+
+   The main thread, which is the thread that created the Java VM,
+   cannot be detached from the VM. Instead, the main thread must call
+   JNI_DestroyJavaVM() to unload the entire VM.
+
+*******************************************************************************/
+
+jint jni_DetachCurrentThread(JavaVM *vm)
+{
+#if defined(ENABLE_THREADS)
+       bool result;
+
+       TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
+
+    /* If the current thread has already been detached, this operation
+          is a no-op. */
+
+       result = thread_current_is_attached();
+
+       if (result == false)
+               return true;
+
+       /* We need to pop all frames before we can destroy the table. */
+
+       localref_frame_pop_all();
+
+       if (!localref_table_destroy())
+               return JNI_ERR;
+
+       if (!thread_detach_current_external_thread())
+               return JNI_ERR;
+#endif
+
+       return JNI_OK;
+}
+
+
+/* GetEnv **********************************************************************
+
+   If the current thread is not attached to the VM, sets *env to NULL,
+   and returns JNI_EDETACHED. If the specified version is not
+   supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
+   sets *env to the appropriate interface, and returns JNI_OK.
+
+*******************************************************************************/
+
+jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
+{
+       TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
+
+       if (vm->is_created() == false) {
+               *env = NULL;
+               return JNI_EDETACHED;
+       }
+
+#if defined(ENABLE_THREADS)
+       if (thread_get_current() == NULL) {
+               *env = NULL;
+
+               return JNI_EDETACHED;
+       }
+#endif
+
+       /* Check the JNI version. */
+
+       if (jni_version_check(version) == true) {
+               *env = vm->get_jnienv();
+               return JNI_OK;
+       }
+
+#if defined(ENABLE_JVMTI)
+       if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
+               == JVMTI_VERSION_INTERFACE_JVMTI) {
+
+               *env = (void *) jvmti_new_environment();
+
+               if (env != NULL)
+                       return JNI_OK;
+       }
+#endif
+       
+       *env = NULL;
+
+       return JNI_EVERSION;
+}
+
+
+/* AttachCurrentThreadAsDaemon *************************************************
+
+   Same semantics as AttachCurrentThread, but the newly-created
+   java.lang.Thread instance is a daemon.
+
+   If the thread has already been attached via either
+   AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
+   simply sets the value pointed to by penv to the JNIEnv of the
+   current thread. In this case neither AttachCurrentThread nor this
+   routine have any effect on the daemon status of the thread.
+
+*******************************************************************************/
+
+jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
+{
+       int result;
+
+       TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
+
+       if (vm->is_created() == false)
+               return JNI_ERR;
+
+       result = jni_attach_current_thread(penv, args, true);
+
+       return result;
+}
+
+
+/* JNI invocation table *******************************************************/
+
+const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
+       NULL,
+       NULL,
+       NULL,
+
+       _Jv_JNI_DestroyJavaVM,
+       jni_AttachCurrentThread,
+       jni_DetachCurrentThread,
+       jni_GetEnv,
+       jni_AttachCurrentThreadAsDaemon
+};
+
+
+/* JNI function table *********************************************************/
+
+struct JNINativeInterface_ _Jv_JNINativeInterface = {
+       NULL,
+       NULL,
+       NULL,
+       NULL,    
+       _Jv_JNI_GetVersion,
+
+       jni_DefineClass,
+       jni_FindClass,
+       jni_FromReflectedMethod,
+       jni_FromReflectedField,
+       jni_ToReflectedMethod,
+       jni_GetSuperclass,
+       _Jv_JNI_IsAssignableFrom,
+       _Jv_JNI_ToReflectedField,
+
+       _Jv_JNI_Throw,
+       _Jv_JNI_ThrowNew,
+       _Jv_JNI_ExceptionOccurred,
+       jni_ExceptionDescribe,
+       jni_ExceptionClear,
+       _Jv_JNI_FatalError,
+       jni_PushLocalFrame,
+       jni_PopLocalFrame,
+
+       jni_NewGlobalRef,
+       jni_DeleteGlobalRef,
+       jni_DeleteLocalRef,
+       _Jv_JNI_IsSameObject,
+       jni_NewLocalRef,
+       jni_EnsureLocalCapacity,
+
+       _Jv_JNI_AllocObject,
+       jni_NewObject,
+       _Jv_JNI_NewObjectV,
+       _Jv_JNI_NewObjectA,
+
+       jni_GetObjectClass,
+       _Jv_JNI_IsInstanceOf,
+
+       _Jv_JNI_GetMethodID,
+
+       _Jv_JNI_CallObjectMethod,
+       _Jv_JNI_CallObjectMethodV,
+       _Jv_JNI_CallObjectMethodA,
+       _Jv_JNI_CallBooleanMethod,
+       _Jv_JNI_CallBooleanMethodV,
+       _Jv_JNI_CallBooleanMethodA,
+       _Jv_JNI_CallByteMethod,
+       _Jv_JNI_CallByteMethodV,
+       _Jv_JNI_CallByteMethodA,
+       _Jv_JNI_CallCharMethod,
+       _Jv_JNI_CallCharMethodV,
+       _Jv_JNI_CallCharMethodA,
+       _Jv_JNI_CallShortMethod,
+       _Jv_JNI_CallShortMethodV,
+       _Jv_JNI_CallShortMethodA,
+       _Jv_JNI_CallIntMethod,
+       _Jv_JNI_CallIntMethodV,
+       _Jv_JNI_CallIntMethodA,
+       _Jv_JNI_CallLongMethod,
+       _Jv_JNI_CallLongMethodV,
+       _Jv_JNI_CallLongMethodA,
+       _Jv_JNI_CallFloatMethod,
+       _Jv_JNI_CallFloatMethodV,
+       _Jv_JNI_CallFloatMethodA,
+       _Jv_JNI_CallDoubleMethod,
+       _Jv_JNI_CallDoubleMethodV,
+       _Jv_JNI_CallDoubleMethodA,
+       _Jv_JNI_CallVoidMethod,
+       _Jv_JNI_CallVoidMethodV,
+       _Jv_JNI_CallVoidMethodA,
+
+       _Jv_JNI_CallNonvirtualObjectMethod,
+       _Jv_JNI_CallNonvirtualObjectMethodV,
+       _Jv_JNI_CallNonvirtualObjectMethodA,
+       _Jv_JNI_CallNonvirtualBooleanMethod,
+       _Jv_JNI_CallNonvirtualBooleanMethodV,
+       _Jv_JNI_CallNonvirtualBooleanMethodA,
+       _Jv_JNI_CallNonvirtualByteMethod,
+       _Jv_JNI_CallNonvirtualByteMethodV,
+       _Jv_JNI_CallNonvirtualByteMethodA,
+       _Jv_JNI_CallNonvirtualCharMethod,
+       _Jv_JNI_CallNonvirtualCharMethodV,
+       _Jv_JNI_CallNonvirtualCharMethodA,
+       _Jv_JNI_CallNonvirtualShortMethod,
+       _Jv_JNI_CallNonvirtualShortMethodV,
+       _Jv_JNI_CallNonvirtualShortMethodA,
+       _Jv_JNI_CallNonvirtualIntMethod,
+       _Jv_JNI_CallNonvirtualIntMethodV,
+       _Jv_JNI_CallNonvirtualIntMethodA,
+       _Jv_JNI_CallNonvirtualLongMethod,
+       _Jv_JNI_CallNonvirtualLongMethodV,
+       _Jv_JNI_CallNonvirtualLongMethodA,
+       _Jv_JNI_CallNonvirtualFloatMethod,
+       _Jv_JNI_CallNonvirtualFloatMethodV,
+       _Jv_JNI_CallNonvirtualFloatMethodA,
+       _Jv_JNI_CallNonvirtualDoubleMethod,
+       _Jv_JNI_CallNonvirtualDoubleMethodV,
+       _Jv_JNI_CallNonvirtualDoubleMethodA,
+       _Jv_JNI_CallNonvirtualVoidMethod,
+       _Jv_JNI_CallNonvirtualVoidMethodV,
+       _Jv_JNI_CallNonvirtualVoidMethodA,
+
+       _Jv_JNI_GetFieldID,
+
+       _Jv_JNI_GetObjectField,
+       _Jv_JNI_GetBooleanField,
+       _Jv_JNI_GetByteField,
+       _Jv_JNI_GetCharField,
+       _Jv_JNI_GetShortField,
+       _Jv_JNI_GetIntField,
+       _Jv_JNI_GetLongField,
+       _Jv_JNI_GetFloatField,
+       _Jv_JNI_GetDoubleField,
+       _Jv_JNI_SetObjectField,
+       _Jv_JNI_SetBooleanField,
+       _Jv_JNI_SetByteField,
+       _Jv_JNI_SetCharField,
+       _Jv_JNI_SetShortField,
+       _Jv_JNI_SetIntField,
+       _Jv_JNI_SetLongField,
+       _Jv_JNI_SetFloatField,
+       _Jv_JNI_SetDoubleField,
+
+       _Jv_JNI_GetStaticMethodID,
+
+       _Jv_JNI_CallStaticObjectMethod,
+       _Jv_JNI_CallStaticObjectMethodV,
+       _Jv_JNI_CallStaticObjectMethodA,
+       _Jv_JNI_CallStaticBooleanMethod,
+       _Jv_JNI_CallStaticBooleanMethodV,
+       _Jv_JNI_CallStaticBooleanMethodA,
+       _Jv_JNI_CallStaticByteMethod,
+       _Jv_JNI_CallStaticByteMethodV,
+       _Jv_JNI_CallStaticByteMethodA,
+       _Jv_JNI_CallStaticCharMethod,
+       _Jv_JNI_CallStaticCharMethodV,
+       _Jv_JNI_CallStaticCharMethodA,
+       _Jv_JNI_CallStaticShortMethod,
+       _Jv_JNI_CallStaticShortMethodV,
+       _Jv_JNI_CallStaticShortMethodA,
+       _Jv_JNI_CallStaticIntMethod,
+       _Jv_JNI_CallStaticIntMethodV,
+       _Jv_JNI_CallStaticIntMethodA,
+       _Jv_JNI_CallStaticLongMethod,
+       _Jv_JNI_CallStaticLongMethodV,
+       _Jv_JNI_CallStaticLongMethodA,
+       _Jv_JNI_CallStaticFloatMethod,
+       _Jv_JNI_CallStaticFloatMethodV,
+       _Jv_JNI_CallStaticFloatMethodA,
+       _Jv_JNI_CallStaticDoubleMethod,
+       _Jv_JNI_CallStaticDoubleMethodV,
+       _Jv_JNI_CallStaticDoubleMethodA,
+       _Jv_JNI_CallStaticVoidMethod,
+       _Jv_JNI_CallStaticVoidMethodV,
+       _Jv_JNI_CallStaticVoidMethodA,
+
+       _Jv_JNI_GetStaticFieldID,
+
+       _Jv_JNI_GetStaticObjectField,
+       _Jv_JNI_GetStaticBooleanField,
+       _Jv_JNI_GetStaticByteField,
+       _Jv_JNI_GetStaticCharField,
+       _Jv_JNI_GetStaticShortField,
+       _Jv_JNI_GetStaticIntField,
+       _Jv_JNI_GetStaticLongField,
+       _Jv_JNI_GetStaticFloatField,
+       _Jv_JNI_GetStaticDoubleField,
+       _Jv_JNI_SetStaticObjectField,
+       _Jv_JNI_SetStaticBooleanField,
+       _Jv_JNI_SetStaticByteField,
+       _Jv_JNI_SetStaticCharField,
+       _Jv_JNI_SetStaticShortField,
+       _Jv_JNI_SetStaticIntField,
+       _Jv_JNI_SetStaticLongField,
+       _Jv_JNI_SetStaticFloatField,
+       _Jv_JNI_SetStaticDoubleField,
+
+       jni_NewString,
+       jni_GetStringLength,
+       jni_GetStringChars,
+       _Jv_JNI_ReleaseStringChars,
+
+       jni_NewStringUTF,
+       jni_GetStringUTFLength,
+       _Jv_JNI_GetStringUTFChars,
+       _Jv_JNI_ReleaseStringUTFChars,
+
+       _Jv_JNI_GetArrayLength,
+
+       _Jv_JNI_NewObjectArray,
+       _Jv_JNI_GetObjectArrayElement,
+       _Jv_JNI_SetObjectArrayElement,
+
+       _Jv_JNI_NewBooleanArray,
+       _Jv_JNI_NewByteArray,
+       _Jv_JNI_NewCharArray,
+       _Jv_JNI_NewShortArray,
+       _Jv_JNI_NewIntArray,
+       _Jv_JNI_NewLongArray,
+       _Jv_JNI_NewFloatArray,
+       _Jv_JNI_NewDoubleArray,
+
+       _Jv_JNI_GetBooleanArrayElements,
+       _Jv_JNI_GetByteArrayElements,
+       _Jv_JNI_GetCharArrayElements,
+       _Jv_JNI_GetShortArrayElements,
+       _Jv_JNI_GetIntArrayElements,
+       _Jv_JNI_GetLongArrayElements,
+       _Jv_JNI_GetFloatArrayElements,
+       _Jv_JNI_GetDoubleArrayElements,
+
+       _Jv_JNI_ReleaseBooleanArrayElements,
+       _Jv_JNI_ReleaseByteArrayElements,
+       _Jv_JNI_ReleaseCharArrayElements,
+       _Jv_JNI_ReleaseShortArrayElements,
+       _Jv_JNI_ReleaseIntArrayElements,
+       _Jv_JNI_ReleaseLongArrayElements,
+       _Jv_JNI_ReleaseFloatArrayElements,
+       _Jv_JNI_ReleaseDoubleArrayElements,
+
+       _Jv_JNI_GetBooleanArrayRegion,
+       _Jv_JNI_GetByteArrayRegion,
+       _Jv_JNI_GetCharArrayRegion,
+       _Jv_JNI_GetShortArrayRegion,
+       _Jv_JNI_GetIntArrayRegion,
+       _Jv_JNI_GetLongArrayRegion,
+       _Jv_JNI_GetFloatArrayRegion,
+       _Jv_JNI_GetDoubleArrayRegion,
+       _Jv_JNI_SetBooleanArrayRegion,
+       _Jv_JNI_SetByteArrayRegion,
+       _Jv_JNI_SetCharArrayRegion,
+       _Jv_JNI_SetShortArrayRegion,
+       _Jv_JNI_SetIntArrayRegion,
+       _Jv_JNI_SetLongArrayRegion,
+       _Jv_JNI_SetFloatArrayRegion,
+       _Jv_JNI_SetDoubleArrayRegion,
+
+       _Jv_JNI_RegisterNatives,
+       _Jv_JNI_UnregisterNatives,
+
+       _Jv_JNI_MonitorEnter,
+       _Jv_JNI_MonitorExit,
+
+       _Jv_JNI_GetJavaVM,
+
+       /* New JNI 1.2 functions. */
+
+       jni_GetStringRegion,
+       jni_GetStringUTFRegion,
+
+       jni_GetPrimitiveArrayCritical,
+       jni_ReleasePrimitiveArrayCritical,
+
+       _Jv_JNI_GetStringCritical,
+       _Jv_JNI_ReleaseStringCritical,
+
+       _Jv_JNI_NewWeakGlobalRef,
+       _Jv_JNI_DeleteWeakGlobalRef,
+
+       _Jv_JNI_ExceptionCheck,
+
+       /* New JNI 1.4 functions. */
+
+       jni_NewDirectByteBuffer,
+       jni_GetDirectBufferAddress,
+       jni_GetDirectBufferCapacity,
+
+       /* New JNI 1.6 functions. */
+
+       jni_GetObjectRefType
+};
+
+
+/* Invocation API Functions ***************************************************/
+
+/* JNI_GetDefaultJavaVMInitArgs ************************************************
+
+   Returns a default configuration for the Java VM.
+
+*******************************************************************************/
+
+jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
+{
+       JavaVMInitArgs *_vm_args;
+
+       _vm_args = (JavaVMInitArgs *) vm_args;
+
+       /* GNU classpath currently supports JNI 1.2 */
+
+       switch (_vm_args->version) {
+    case JNI_VERSION_1_1:
+               _vm_args->version = JNI_VERSION_1_1;
+               break;
+
+    case JNI_VERSION_1_2:
+    case JNI_VERSION_1_4:
+               _vm_args->ignoreUnrecognized = JNI_FALSE;
+               _vm_args->options = NULL;
+               _vm_args->nOptions = 0;
+               break;
+
+    default:
+               return -1;
+       }
+  
+       return 0;
+}
+
+
+/* JNI_GetCreatedJavaVMs *******************************************************
+
+   Returns all Java VMs that have been created. Pointers to VMs are written in
+   the buffer vmBuf in the order they are created. At most bufLen number of
+   entries will be written. The total number of created VMs is returned in
+   *nVMs.
+
+*******************************************************************************/
+
+jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
+{
+       TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
+
+       if (bufLen <= 0)
+               return JNI_ERR;
+
+       // We currently only support 1 VM running.
+
+       vmBuf[0] = vm->get_javavm();
+       *nVMs    = 1;
+
+    return JNI_OK;
+}
+
+
+/* JNI_CreateJavaVM ************************************************************
+
+   Loads and initializes a Java VM. The current thread becomes the main thread.
+   Sets the env argument to the JNI interface pointer of the main thread.
+
+*******************************************************************************/
+
+jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
+{
+       TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
+
+       /* actually create the JVM */
+
+       if (!VM_create(p_vm, p_env, vm_args))
+               return JNI_ERR;
+
+       return JNI_OK;
+}
+
+} // extern "C"
+
+
+/*
+ * 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 c930fab0b5ac02ce4e23c60effe6357961ad851a..aacd8504168294852b528cc8fa47fc9cfcfa01b6 100644 (file)
 #ifndef _JNI_H
 #define _JNI_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #include "vm/types.h"
 
 #include "vm/global.h"
-
-#include "vmcore/method.h"
+#include "vm/method.h"
 
 
+#if 0
 /* _Jv_JNIEnv *****************************************************************/
 
 #ifndef __cplusplus
@@ -103,6 +106,7 @@ struct _Jv_JavaVM {
 };
 
 #endif
+#endif
 
 
 /* CACAO related stuff ********************************************************/
@@ -127,6 +131,10 @@ struct hashtable_global_ref_entry {
 bool jni_init(void);
 bool jni_version_check(int version);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _JNI_H */
 
 
index 8db874a8fb8d8102250be0fe2d80aeb16f0ffbf1..ced10d58fa02060213e106d1e08615432943296e 100644 (file)
 #include "native/jvmti/jvmti.h"
 #include "native/jvmti/cacaodbg.h"
 #include "native/jvmti/dbg.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 #include "vm/loader.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/builtin.h"
 #include "vm/jit/asmpart.h"
-#include "vm/stringlocal.h"
+#include "vm/string.hpp"
 #include "toolbox/logging.h"
 #include "threads/mutex.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include <sys/types.h>
 #include <unistd.h>
index 4b4a219eb7025cd7e2b4dc57d8f111821369e188..04abbd85c2a04d45fef38bc426c7a8557e85d100 100644 (file)
@@ -26,7 +26,7 @@
 #define _CACAODBG_H
 
 #include "threads/mutex.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 #include "native/jvmti/jvmti.h"
 #include "native/include/java_lang_String.h"
 #include <ltdl.h>
index 55da5cb01cc0f92b2063f9bf15f60c60c08e7074..49e7f795c24be6a4e5819a26b70d4631fafeaa0a 100644 (file)
 #include "native/native.h"
 #include "native/jvmti/cacaodbg.h"
 #include "native/jvmti/jvmti.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/global.h"
 #include "vm/loader.h"
 #include "vm/builtin.h"
 #include "vm/jit/asmpart.h"
 #include "vm/class.h"
 #include "vm/classcache.h"
-#include "mm/gc-common.h"
+#include "mm/gc.hpp"
 #include "toolbox/logging.h"
 #include "vm/options.h"
-#include "vm/stringlocal.h"
+#include "vm/string.hpp"
 #include "mm/memory.h"
 #include "threads/mutex.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 #include "threads/lock-common.h"
-#include "vm/exceptions.h"
-#include "native/include/java_util_Vector.h"
+#include "vm/exceptions.hpp"
 #include "native/include/java_io_PrintStream.h"
 #include "native/include/java_io_InputStream.h"
 #include "native/include/java_lang_Cloneable.h"
index e9df0d64328252041395f42b32d6abbe3af08c55..02c171b7bc1ef05ac449846de7a967609a6502b4 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <assert.h>
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 
 /* LLNI critical sections ******************************************************
index 65e708685bd69a83c88cc14ccc77e757b50681a1..043d82964baa26a3bcd6e12dc88b8e9857ab4735 100644 (file)
 #ifndef _LLNI_H
 #define _LLNI_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "config.h"
 
 /* forward defines ************************************************************/
 
 #include "native/localref.h"
 
-#include "threads/thread.h"
-
-
-/* LLNI macros *****************************************************************
-
-   The following macros should be used whenever a Java Object is
-   accessed in native code without the use of an JNI function.
-
-   LLNI_field_set_val, LLNI_field_get_val:
-     Deal with primitive values like integer and float values. Do
-     not use these macros to access pointers or references!
-
-   LLNI_field_set_ref, LLNI_field_get_ref:
-     Deal with references to other objects.
-
-   LLNI_field_set_cls, LLNI_field_get_cls:
-     Deal with references to Java Classes which are internally
-     represented by classinfo or java_lang_Class.
+#include "threads/thread.hpp"
 
-*******************************************************************************/
-
-#define LLNI_field_set_val(obj, field, value) \
-       LLNI_field_direct(obj, field) = (value)
-
-#define LLNI_field_set_ref(obj, field, reference) \
-       LLNI_field_direct(obj, field) = LLNI_UNWRAP(reference)
-
-#define LLNI_field_set_cls(obj, field, value) \
-       LLNI_field_direct(obj, field) = (java_lang_Class *) (value)
-
-#define LLNI_field_get_val(obj, field, variable) \
-       (variable) = LLNI_field_direct(obj, field)
-
-#define LLNI_field_get_ref(obj, field, variable) \
-       (variable) = LLNI_WRAP(LLNI_field_direct(obj, field))
-
-#define LLNI_field_get_cls(obj, field, variable) \
-       (variable) = (classinfo *) LLNI_field_direct(obj, field)
 
 #define LLNI_class_get(obj, variable) \
        (variable) = LLNI_field_direct((java_handle_t *) obj, vftbl->clazz)
 *******************************************************************************/
 
 #define LLNI_classinfo_wrap(classinfo) \
-       ((java_lang_Class *) LLNI_WRAP(classinfo))
+       ((java_handle_t*) LLNI_WRAP(classinfo))
 
 #define LLNI_classinfo_unwrap(clazz) \
        ((classinfo *) LLNI_UNWRAP((java_handle_t *) (clazz)))
@@ -186,6 +154,9 @@ void llni_critical_end();
 void llni_critical_start_thread(threadobject *t);
 void llni_critical_end_thread(threadobject *t);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _LLNI_H */
 
index 8e364b515e79ead77c0183e6996efeac655bd32b..f686858c2e25f2964630a1ebbe0bc8f4cff318e3 100644 (file)
 
 #include "native/localref.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
-#include "vm/vm.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/argument.h"
 
-#include "vmcore/options.h"
-
 
 /* debug **********************************************************************/
 
index f99a56be5f50264c3d4a9db641379c42617f79b7..b1df773fde79c34795c1785889f3ade5a19afc51 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/localref.h - Management of local reference tables
 
-   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.
 
 typedef struct localref_table localref_table;
 
 #include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/types.h"
 
 #include "vm/global.h"
-
-#include "vmcore/method.h"
+#include "vm/method.h"
 
 
 /* localref_table **************************************************************
@@ -88,6 +90,9 @@ void localref_native_exit(methodinfo *m, uint64_t *return_regs);
 void localref_dump(void);
 #endif
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _LOCALREF_H */
 
index 72c90371a5f3d4d99c04bd82426a2441b96fc2c9..f1aca471296ac464d06e74cbc764d2de8311edac 100644 (file)
 #include "toolbox/logging.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
 #include "vm/resolve.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/system.h"
-
 #if defined(ENABLE_JVMTI)
 #include "native/jvmti/cacaodbg.h"
 #endif
@@ -553,10 +553,10 @@ functionptr native_method_resolve(methodinfo *m)
                ne = le->namelink;
                        
                while ((ne != NULL) && (f == NULL)) {
-                       f = (functionptr) (ptrint) system_dlsym(ne->handle, name->text);
+                       f = (functionptr) (ptrint) os_dlsym(ne->handle, name->text);
 
                        if (f == NULL)
-                               f = (functionptr) (ptrint) system_dlsym(ne->handle, newname->text);
+                               f = (functionptr) (ptrint) os_dlsym(ne->handle, newname->text);
 
                        ne = ne->hashlink;
                }
@@ -657,7 +657,7 @@ void* native_library_open(utf *filename)
 
        /* try to open the library */
 
-       handle = system_dlopen(filename->text, RTLD_LAZY);
+       handle = os_dlopen(filename->text, RTLD_LAZY);
 
        if (handle == NULL) {
                if (opt_verbosejni)
@@ -665,7 +665,7 @@ void* native_library_open(utf *filename)
 
                if (opt_verbose) {
                        log_start();
-                       log_print("native_library_open: system_dlopen failed: ");
+                       log_print("native_library_open: os_dlopen failed: ");
                        log_print(dlerror());
                        log_finish();
                }
@@ -703,12 +703,12 @@ void native_library_close(void* handle)
 
        /* Close the library. */
 
-       result = system_dlclose(handle);
+       result = os_dlclose(handle);
 
        if (result != 0) {
                if (opt_verbose) {
                        log_start();
-                       log_print("native_library_close: system_dlclose failed: ");
+                       log_print("native_library_close: os_dlclose failed: ");
                        log_print(dlerror());
                        log_finish();
                }
@@ -895,7 +895,7 @@ int native_library_load(JNIEnv *env, utf *name, classloader_t *cl)
 # if defined(ENABLE_JNI)
        /* Resolve JNI_OnLoad function. */
 
-       onload = system_dlsym(handle, "JNI_OnLoad");
+       onload = os_dlsym(handle, "JNI_OnLoad");
 
        if (onload != NULL) {
                JNIEXPORT int32_t (JNICALL *JNI_OnLoad) (JavaVM *, void *);
@@ -911,7 +911,7 @@ int native_library_load(JNIEnv *env, utf *name, classloader_t *cl)
                   loaded. */
 
                if ((version != JNI_VERSION_1_2) && (version != JNI_VERSION_1_4)) {
-                       system_dlclose(handle);
+                       os_dlclose(handle);
                        return 0;
                }
        }
index 89c8acb8c568d9599a48940df497cd5a02cd384e..a2d355691bd890552cba191cbd52c2756221be6f 100644 (file)
 
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "native/jni.h"
 
+#include "vm/class.h"
 #include "vm/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-#include "vmcore/system.h"
-#include "vmcore/utf8.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+#include "vm/os.hpp"
+#include "vm/utf8.h"
 
 
 /* defines ********************************************************************/
@@ -110,6 +113,10 @@ int         native_library_load(JNIEnv *env, utf *name, classloader_t *cl);
 java_handle_t *native_new_and_init(classinfo *c);
 java_handle_t *native_new_and_init_string(classinfo *c, java_handle_t *s);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _NATIVE_H */
 
 
index 70d401e344d2d2535952352380e3d77fbf0af077..f819ead808e5c7a9f5e773810846a6e11ba59614 100644 (file)
@@ -55,12 +55,12 @@ NATIVEVM_LIB = \
 endif
 
 if ENABLE_JAVASE
-REFLECT_SOURCES = \
-       reflect.c \
-       reflect.h
+REFLECTION_SOURCES = \
+       reflection.c \
+       reflection.h
 
 SUN_MISC_UNSAFE_SOURCES = \
-       sun_misc_Unsafe.c
+       sun_misc_Unsafe.cpp
 endif
 
 noinst_LTLIBRARIES = \
@@ -69,7 +69,7 @@ noinst_LTLIBRARIES = \
 libnativevm_la_SOURCES = \
        nativevm.c \
        nativevm.h \
-       $(REFLECT_SOURCES) \
+       $(REFLECTION_SOURCES) \
        $(SUN_MISC_UNSAFE_SOURCES)
 
 libnativevm_la_LIBADD = \
index 625d9acec0b804dd5b89bef2910eee810385bdcc..3cc9877172b4150e2d00f3079341279e9e6dc68a 100644 (file)
@@ -1,9 +1,7 @@
 ## src/native/vm/cldc1.1/Makefile.am
 ##
-## Copyright (C) 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) 2006, 2007, 2008
+## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 ##
 ## This file is part of CACAO.
 ##
@@ -31,20 +29,20 @@ noinst_LTLIBRARIES = \
        libnativevmcore.la
 
 libnativevmcore_la_SOURCES = \
-       com_sun_cldc_io_ResourceInputStream.c \
-       com_sun_cldc_io_j2me_socket_Protocol.c \
-       com_sun_cldchi_io_ConsoleOutputStream.c \
-       com_sun_cldchi_jvm_JVM.c \
-       java_lang_Class.c \
-       java_lang_Double.c \
-       java_lang_Float.c \
-       java_lang_Math.c \
-       java_lang_Object.c \
-       java_lang_Runtime.c \
-       java_lang_String.c \
-       java_lang_System.c \
-       java_lang_Thread.c \
-       java_lang_Throwable.c
+       com_sun_cldc_io_ResourceInputStream.cpp \
+       com_sun_cldc_io_j2me_socket_Protocol.cpp \
+       com_sun_cldchi_io_ConsoleOutputStream.cpp \
+       com_sun_cldchi_jvm_JVM.cpp \
+       java_lang_Class.cpp \
+       java_lang_Double.cpp \
+       java_lang_Float.cpp \
+       java_lang_Math.cpp \
+       java_lang_Object.cpp \
+       java_lang_Runtime.cpp \
+       java_lang_String.cpp \
+       java_lang_System.cpp \
+       java_lang_Thread.cpp \
+       java_lang_Throwable.cpp
 
 
 ## Local variables:
diff --git a/src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.c b/src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.c
deleted file mode 100644 (file)
index 8395ada..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/* src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.c
-
-   Copyright (C) 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
-
-   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 <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <zlib.h>
-
-#include "config.h"
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/com_sun_cldc_io_ResourceInputStream.h"
-#include "native/include/com_sun_cldchi_jvm_FileDescriptor.h"
-
-#include "vm/types.h"
-#include "vm/builtin.h"
-#include "vm/vm.h" /* REMOVE ME: temporarily */
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/zip.h"
-
-#include "threads/lock-common.h"
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "open", "(Ljava/lang/String;)Ljava/lang/Object;", (void *) (ptrint) &Java_com_sun_cldc_io_ResourceInputStream_open },
-       { "bytesRemain", "(Ljava/lang/Object;)I", (void *) (ptrint) &Java_com_sun_cldc_io_ResourceInputStream_bytesRemain },
-       { "readByte", "(Ljava/lang/Object;)I", (void *) (ptrint) &Java_com_sun_cldc_io_ResourceInputStream_readByte },
-       { "readBytes", "(Ljava/lang/Object;[BII)I", (void *) (ptrint) &Java_com_sun_cldc_io_ResourceInputStream_readBytes },
-       { "clone", "(Ljava/lang/Object;)Ljava/lang/Object;", (void *) (ptrint) &Java_com_sun_cldc_io_ResourceInputStream_clone },
-};
-/* _Jv_com_sun_cldc_io_ResourceInputStream_init ********************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_com_sun_cldc_io_ResourceInputStream_init(void)
-{
-       utf *u;
-       u = utf_new_char("com/sun/cldc/io/ResourceInputStream");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-static struct com_sun_cldchi_jvm_FileDescriptor* zip_read_resource(list_classpath_entry *lce, utf *name)
-{
-       hashtable_zipfile_entry *htzfe;
-       lfh                      lfh;
-       u1                      *indata;
-       u1                      *outdata;
-       z_stream                 zs;
-       int                      err;
-       
-       classinfo *ci;
-       com_sun_cldchi_jvm_FileDescriptor *fileDescriptor = NULL;
-
-       /* try to find the class in the current archive */
-
-       htzfe = zip_find(lce, name);
-
-       if (htzfe == NULL)
-               return NULL;
-
-       /* read stuff from local file header */
-
-       lfh.filenamelength   = SUCK_LE_U2(htzfe->data + LFH_FILE_NAME_LENGTH);
-       lfh.extrafieldlength = SUCK_LE_U2(htzfe->data + LFH_EXTRA_FIELD_LENGTH);
-
-       indata = htzfe->data +
-               LFH_HEADER_SIZE +
-               lfh.filenamelength +
-               lfh.extrafieldlength;
-
-       /* allocate buffer for uncompressed data */
-
-       outdata = MNEW(u1, htzfe->uncompressedsize);
-
-       /* how is the file stored? */
-
-       switch (htzfe->compressionmethod) {
-       case Z_DEFLATED:
-               /* fill z_stream structure */
-
-               zs.next_in   = indata;
-               zs.avail_in  = htzfe->compressedsize;
-               zs.next_out  = outdata;
-               zs.avail_out = htzfe->uncompressedsize;
-
-               zs.zalloc = Z_NULL;
-               zs.zfree  = Z_NULL;
-               zs.opaque = Z_NULL;
-
-               /* initialize this inflate run */
-
-               if (inflateInit2(&zs, -MAX_WBITS) != Z_OK)
-                       vm_abort("zip_get: inflateInit2 failed: %s", strerror(errno));
-
-               /* decompress the file into buffer */
-
-               err = inflate(&zs, Z_SYNC_FLUSH);
-
-               if ((err != Z_STREAM_END) && (err != Z_OK))
-                       vm_abort("zip_get: inflate failed: %s", strerror(errno));
-
-               /* finish this inflate run */
-
-               if (inflateEnd(&zs) != Z_OK)
-                       vm_abort("zip_get: inflateEnd failed: %s", strerror(errno));
-               break;
-
-       case 0:
-               /* uncompressed file, just copy the data */
-               MCOPY(outdata, indata, u1, htzfe->compressedsize);
-               break;
-
-       default:
-               vm_abort("zip_get: unknown compression method %d",
-                                htzfe->compressionmethod);
-       }
-               
-       /* Create a file descriptor object */
-       ci = load_class_bootstrap(utf_new_char("com/sun/cldchi/jvm/FileDescriptor"));
-       fileDescriptor = (com_sun_cldchi_jvm_FileDescriptor *) native_new_and_init(ci);
-       LLNI_field_set_val(fileDescriptor, pointer, (int)outdata);
-       LLNI_field_set_val(fileDescriptor, length, htzfe->uncompressedsize);
-       LLNI_field_set_val(fileDescriptor, position, 0);
-       return fileDescriptor;
-       
-}
-
-static struct com_sun_cldchi_jvm_FileDescriptor* file_read_resource(char *path) 
-{
-       int len;
-       struct stat statBuffer;
-       u1 *filep;
-       com_sun_cldchi_jvm_FileDescriptor *fileDescriptor = NULL; 
-       classinfo *ci;
-       int fd;
-       
-       fd = open(path, O_RDONLY);
-       
-       if (fd > 0) {
-               
-               if (fstat(fd, &statBuffer) != -1) {
-                       len = statBuffer.st_size;
-               } else {  
-                       return NULL;
-               }
-               
-               /* Map file into the memory */
-               filep = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
-               
-               /* Create a file descriptor object */
-               ci = load_class_bootstrap(utf_new_char("com/sun/cldchi/jvm/FileDescriptor"));
-               fileDescriptor = (com_sun_cldchi_jvm_FileDescriptor *) native_new_and_init(ci);
-               LLNI_field_set_val(fileDescriptor, pointer, (int)filep);
-               LLNI_field_set_val(fileDescriptor, length, len);
-               LLNI_field_set_val(fileDescriptor, position, 0);
-               
-               return fileDescriptor;  
-               
-       } else {
-               return NULL;
-       }
-       
-}
-
-
-/*
- * Class:     com/sun/cldc/io/ResourceInputStream
- * Method:    open
- * Signature: (Ljava/lang/String;)Ljava/lang/Object;
- */
-JNIEXPORT struct java_lang_Object* JNICALL Java_com_sun_cldc_io_ResourceInputStream_open(JNIEnv *env, jclass clazz, java_lang_String *name)
-{
-       
-       list_classpath_entry *lce;
-       char *filename;
-       s4 filenamelen;
-       char *path;
-       utf *uname;
-       com_sun_cldchi_jvm_FileDescriptor* descriptor;
-       
-       /* get the classname as char string (do it here for the warning at
-       the end of the function) */
-
-       uname = javastring_toutf((java_handle_t *)name, false);
-       filenamelen = utf_bytes(uname) + strlen("0");
-       filename = MNEW(char, filenamelen);
-       utf_copy(filename, uname);
-       
-       /* walk through all classpath entries */
-
-       for (lce = list_first(list_classpath_entries); lce != NULL;
-                lce = list_next(list_classpath_entries, lce)) {
-                       
-#if defined(ENABLE_ZLIB)
-               if (lce->type == CLASSPATH_ARCHIVE) {
-
-                       /* enter a monitor on zip/jar archives */
-                       LOCK_MONITOR_ENTER(lce);
-
-                       /* try to get the file in current archive */
-                       descriptor = zip_read_resource(lce, uname);
-
-                       /* leave the monitor */
-                       LOCK_MONITOR_EXIT(lce);
-                       
-                       if (descriptor != NULL) { /* file exists */
-                               break;
-                       }
-
-               } else {
-#endif
-                       
-                       path = MNEW(char, lce->pathlen + filenamelen);
-                       strcpy(path, lce->path);
-                       strcat(path, filename);
-
-                       descriptor = file_read_resource(path);
-                       
-                       MFREE(path, char, lce->pathlen + filenamelen);
-
-                       if (descriptor != NULL) { /* file exists */
-                               break;
-                       }
-                       
-#if defined(ENABLE_ZLIB)
-               }
-#endif 
-                       
-       }
-
-       MFREE(filename, char, filenamelen);
-
-       return (java_lang_Object*) descriptor;
-       
-}
-
-
-/*
- * Class:     com_sun_cldc_io_ResourceInputStream
- * Method:    bytesRemain
- * Signature: (Ljava/lang/Object;)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_ResourceInputStream_bytesRemain(JNIEnv *env, jclass clazz, struct java_lang_Object* jobj) {
-       
-       com_sun_cldchi_jvm_FileDescriptor *fileDescriptor;
-       int32_t length;
-       int32_t position;
-
-       fileDescriptor = (com_sun_cldchi_jvm_FileDescriptor *) jobj;
-       LLNI_field_get_val(fileDescriptor, position, position);
-       LLNI_field_get_val(fileDescriptor, length, length);
-       
-       return length - position;
-
-}
-
-/*
- * Class:     com_sun_cldc_io_ResourceInputStream
- * Method:    readByte
- * Signature: (Ljava/lang/Object;)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_ResourceInputStream_readByte(JNIEnv *env, jclass clazz, struct java_lang_Object* jobj) {
-       
-       com_sun_cldchi_jvm_FileDescriptor *fileDescriptor;
-       u1 byte;
-       int32_t length;
-       int32_t position;
-       int64_t filep;
-       
-       fileDescriptor = (com_sun_cldchi_jvm_FileDescriptor *) jobj;
-       LLNI_field_get_val(fileDescriptor, position, position);
-       LLNI_field_get_val(fileDescriptor, length, length);
-       LLNI_field_get_val(fileDescriptor, pointer, filep);
-       
-       if (position < length) {
-               byte = ((u1*)(int)filep)[position];
-               position++;
-       } else {
-               return -1; /* EOF */
-       }
-
-       /* Update access position */
-       LLNI_field_set_val(fileDescriptor, position, position);
-       
-       return (byte & 0xFF);
-
-}
-
-/*
- * Class:     com_sun_cldc_io_ResourceInputStream
- * Method:    readBytes
- * Signature: (Ljava/lang/Object;[BII)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_ResourceInputStream_readBytes(JNIEnv *env, jclass clazz, struct java_lang_Object* jobj, java_handle_bytearray_t* byteArray, s4 off, s4 len) {
-       
-       com_sun_cldchi_jvm_FileDescriptor *fileDescriptor;
-       s4 readBytes = -1;
-       int32_t fileLength;
-       int32_t position;
-       s4 available;
-       int64_t filep;
-       void *buf;
-
-       /* get pointer to the buffer */
-       buf = &(LLNI_array_direct(byteArray, off));
-       
-       fileDescriptor = (com_sun_cldchi_jvm_FileDescriptor *) jobj;
-       LLNI_field_get_val(fileDescriptor, position, position);
-       LLNI_field_get_val(fileDescriptor, length, fileLength);
-       LLNI_field_get_val(fileDescriptor, pointer, filep);
-       
-       if (position < fileLength) {
-               available = fileLength - position;
-               if (available < len) {
-                       readBytes = available;
-               } else {
-                       readBytes = len;
-               }
-               memcpy(buf, ((u1*)(int)filep) + position, readBytes * sizeof(u1));
-               position += readBytes;
-       } else {
-               return -1; /* EOF */
-       }
-
-       /* Update access position */
-       LLNI_field_set_val(fileDescriptor, position, position);
-       
-       return readBytes;
-}
-
-/*
- * Class:     com_sun_cldc_io_ResourceInputStream
- * Method:    clone
- * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
- */
-JNIEXPORT struct java_lang_Object* JNICALL Java_com_sun_cldc_io_ResourceInputStream_clone(JNIEnv *env, jclass clazz, struct java_lang_Object* jobj) {
-       
-       classinfo *ci;
-       com_sun_cldchi_jvm_FileDescriptor *srcFileDescriptor;
-       com_sun_cldchi_jvm_FileDescriptor *dstFileDescriptor;
-       int32_t srcLength;
-       int32_t srcPosition;
-       int64_t srcFilePointer;
-       
-       srcFileDescriptor = (com_sun_cldchi_jvm_FileDescriptor *) jobj;
-       LLNI_field_get_val(srcFileDescriptor, position, srcPosition);
-       LLNI_field_get_val(srcFileDescriptor, length, srcLength);
-       LLNI_field_get_val(srcFileDescriptor, pointer, srcFilePointer);
-       
-       ci = load_class_bootstrap(utf_new_char("com/sun/cldchi/jvm/FileDescriptor"));
-       dstFileDescriptor = (com_sun_cldchi_jvm_FileDescriptor *) native_new_and_init(ci);
-       LLNI_field_set_val(dstFileDescriptor, position, srcPosition);
-       LLNI_field_set_val(dstFileDescriptor, length, srcLength);
-       LLNI_field_set_val(dstFileDescriptor, pointer, srcFilePointer);
-       
-       return (java_lang_Object*) dstFileDescriptor;
-
-}
-
-
-/*
- * 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/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.cpp b/src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.cpp
new file mode 100644 (file)
index 0000000..a262ca4
--- /dev/null
@@ -0,0 +1,404 @@
+/* src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.cpp
+
+   Copyright (C) 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 <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <zlib.h>
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/com_sun_cldc_io_ResourceInputStream.h"
+#endif
+
+#include "threads/lock-common.h"
+
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/string.hpp"
+#include "vm/types.h"
+#include "vm/vm.hpp" /* REMOVE ME: temporarily */
+#include "vm/zip.h"
+
+
+static java_handle_t* zip_read_resource(list_classpath_entry *lce, utf *name)
+{
+       hashtable_zipfile_entry *htzfe;
+       lfh                      lfh;
+       u1                      *indata;
+       u1                      *outdata;
+       z_stream                 zs;
+       int                      err;
+       
+       classinfo *ci;
+
+       /* try to find the class in the current archive */
+
+       htzfe = zip_find(lce, name);
+
+       if (htzfe == NULL)
+               return NULL;
+
+       /* read stuff from local file header */
+
+       lfh.filenamelength   = SUCK_LE_U2(htzfe->data + LFH_FILE_NAME_LENGTH);
+       lfh.extrafieldlength = SUCK_LE_U2(htzfe->data + LFH_EXTRA_FIELD_LENGTH);
+
+       indata = htzfe->data +
+               LFH_HEADER_SIZE +
+               lfh.filenamelength +
+               lfh.extrafieldlength;
+
+       /* allocate buffer for uncompressed data */
+
+       outdata = MNEW(u1, htzfe->uncompressedsize);
+
+       /* how is the file stored? */
+
+       switch (htzfe->compressionmethod) {
+       case Z_DEFLATED:
+               /* fill z_stream structure */
+
+               zs.next_in   = indata;
+               zs.avail_in  = htzfe->compressedsize;
+               zs.next_out  = outdata;
+               zs.avail_out = htzfe->uncompressedsize;
+
+               zs.zalloc = Z_NULL;
+               zs.zfree  = Z_NULL;
+               zs.opaque = Z_NULL;
+
+               /* initialize this inflate run */
+
+               if (inflateInit2(&zs, -MAX_WBITS) != Z_OK)
+                       vm_abort("zip_get: inflateInit2 failed: %s", strerror(errno));
+
+               /* decompress the file into buffer */
+
+               err = inflate(&zs, Z_SYNC_FLUSH);
+
+               if ((err != Z_STREAM_END) && (err != Z_OK))
+                       vm_abort("zip_get: inflate failed: %s", strerror(errno));
+
+               /* finish this inflate run */
+
+               if (inflateEnd(&zs) != Z_OK)
+                       vm_abort("zip_get: inflateEnd failed: %s", strerror(errno));
+               break;
+
+       case 0:
+               /* uncompressed file, just copy the data */
+               MCOPY(outdata, indata, u1, htzfe->compressedsize);
+               break;
+
+       default:
+               vm_abort("zip_get: unknown compression method %d",
+                                htzfe->compressionmethod);
+       }
+               
+       // Create a file descriptor object.
+       ci = load_class_bootstrap(utf_new_char("com/sun/cldchi/jvm/FileDescriptor"));
+       java_handle_t* h = native_new_and_init(ci);
+
+       if (h == NULL)
+               return NULL;
+
+       com_sun_cldchi_jvm_FileDescriptor fd(h, (int64_t) outdata, 0, htzfe->uncompressedsize);
+
+       return fd.get_handle();
+}
+
+
+static java_handle_t* file_read_resource(char *path) 
+{
+       int len;
+       struct stat statBuffer;
+       u1 *filep;
+       classinfo *ci;
+       int fd;
+       
+       fd = open(path, O_RDONLY);
+       
+       if (fd > 0) {
+               
+               if (fstat(fd, &statBuffer) != -1) {
+                       len = statBuffer.st_size;
+               } else {  
+                       return NULL;
+               }
+               
+               /* Map file into the memory */
+               filep = (u1*) mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
+               
+               /* Create a file descriptor object */
+               ci = load_class_bootstrap(utf_new_char("com/sun/cldchi/jvm/FileDescriptor"));
+               java_handle_t* h = native_new_and_init(ci);
+
+               if (h == NULL)
+                       return NULL;
+
+               com_sun_cldchi_jvm_FileDescriptor fd(h, (int64_t) filep, 0, len); 
+
+               return fd.get_handle(); 
+       }
+       else {
+               return NULL;
+       }
+}
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     com/sun/cldc/io/ResourceInputStream
+ * Method:    open
+ * Signature: (Ljava/lang/String;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_com_sun_cldc_io_ResourceInputStream_open(JNIEnv *env, jclass clazz, jstring name)
+{
+       list_classpath_entry *lce;
+       char *filename;
+       s4 filenamelen;
+       char *path;
+       utf *uname;
+       java_handle_t* descriptor;
+       
+       /* get the classname as char string (do it here for the warning at
+       the end of the function) */
+
+       uname = javastring_toutf((java_handle_t *)name, false);
+       filenamelen = utf_bytes(uname) + strlen("0");
+       filename = MNEW(char, filenamelen);
+       utf_copy(filename, uname);
+       
+       /* walk through all classpath entries */
+
+       for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL;
+                lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
+                       
+#if defined(ENABLE_ZLIB)
+               if (lce->type == CLASSPATH_ARCHIVE) {
+
+                       /* enter a monitor on zip/jar archives */
+                       LOCK_MONITOR_ENTER(lce);
+
+                       /* try to get the file in current archive */
+                       descriptor = zip_read_resource(lce, uname);
+
+                       /* leave the monitor */
+                       LOCK_MONITOR_EXIT(lce);
+                       
+                       if (descriptor != NULL) { /* file exists */
+                               break;
+                       }
+
+               } else {
+#endif
+                       
+                       path = MNEW(char, lce->pathlen + filenamelen);
+                       strcpy(path, lce->path);
+                       strcat(path, filename);
+
+                       descriptor = file_read_resource(path);
+                       
+                       MFREE(path, char, lce->pathlen + filenamelen);
+
+                       if (descriptor != NULL) { /* file exists */
+                               break;
+                       }
+#if defined(ENABLE_ZLIB)
+               }
+#endif 
+       }
+
+       MFREE(filename, char, filenamelen);
+
+       return (jobject) descriptor;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/ResourceInputStream
+ * Method:    bytesRemain
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_ResourceInputStream_bytesRemain(JNIEnv *env, jclass clazz, jobject jobj)
+{
+       com_sun_cldchi_jvm_FileDescriptor fd(jobj);
+       int32_t length   = fd.get_position();
+       int32_t position = fd.get_length();
+
+       return length - position;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/ResourceInputStream
+ * Method:    readByte
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_ResourceInputStream_readByte(JNIEnv *env, jclass clazz, jobject jobj)
+{
+       com_sun_cldchi_jvm_FileDescriptor fd(jobj);
+
+       int64_t filep    = fd.get_pointer();
+       int32_t position = fd.get_position();
+       int32_t length   = fd.get_length();
+
+       uint8_t byte;
+
+       if (position < length) {
+               byte = ((uint8_t*) filep)[position];
+               position++;
+       }
+       else {
+               return -1; /* EOF */
+       }
+
+       // Update access position.
+       fd.set_position(position);
+       
+       return (byte & 0xFF);
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/ResourceInputStream
+ * Method:    readBytes
+ * Signature: (Ljava/lang/Object;[BII)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_ResourceInputStream_readBytes(JNIEnv *env, jclass clazz, jobject jobj, jbyteArray byteArray, jint off, jint len)
+{
+       /* get pointer to the buffer */
+       // XXX Not GC safe.
+       void* buf = &(LLNI_array_direct((java_handle_bytearray_t*) byteArray, off));
+       
+       com_sun_cldchi_jvm_FileDescriptor fd(jobj);
+
+       int64_t filep      = fd.get_pointer();
+       int32_t position   = fd.get_position();
+       int32_t fileLength = fd.get_length();
+
+       int32_t readBytes = -1;
+
+       if (position < fileLength) {
+               int32_t available = fileLength - position;
+
+               if (available < len) {
+                       readBytes = available;
+               } else {
+                       readBytes = len;
+               }
+
+               os::memcpy(buf, ((uint8_t*) filep) + position, readBytes * sizeof(uint8_t));
+               position += readBytes;
+       }
+       else {
+               return -1; /* EOF */
+       }
+
+       // Update access position.
+       fd.set_position(position);
+       
+       return readBytes;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/ResourceInputStream
+ * Method:    clone
+ * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_com_sun_cldc_io_ResourceInputStream_clone(JNIEnv *env, jclass clazz, jobject jobj)
+{
+       com_sun_cldchi_jvm_FileDescriptor fd(jobj);
+
+       classinfo* c = load_class_bootstrap(utf_new_char("com/sun/cldchi/jvm/FileDescriptor"));
+       java_handle_t* h = native_new_and_init(c);
+
+       if (h == NULL)
+               return NULL;
+
+       com_sun_cldchi_jvm_FileDescriptor clonefd(h, fd);
+       
+       return (jobject) clonefd.get_handle();
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "open",        (char*) "(Ljava/lang/String;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_open        },
+       { (char*) "bytesRemain", (char*) "(Ljava/lang/Object;)I",                  (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_bytesRemain },
+       { (char*) "readByte",    (char*) "(Ljava/lang/Object;)I",                  (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_readByte    },
+       { (char*) "readBytes",   (char*) "(Ljava/lang/Object;[BII)I",              (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_readBytes   },
+       { (char*) "clone",       (char*) "(Ljava/lang/Object;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_com_sun_cldc_io_ResourceInputStream_clone       },
+};
+
+/* _Jv_com_sun_cldc_io_ResourceInputStream_init ********************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" {
+void _Jv_com_sun_cldc_io_ResourceInputStream_init(void)
+{
+       utf *u;
+       u = utf_new_char("com/sun/cldc/io/ResourceInputStream");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.c b/src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.c
deleted file mode 100644 (file)
index ee32030..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-/* src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.c
-
-   Copyright (C) 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
-
-   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 <errno.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/com_sun_cldc_io_j2me_socket_Protocol.h"
-
-#include "vm/global.h"
-#include "vm/vm.h" /* REMOVE ME: temporarily */
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "open0",      "([BII)I",  (void *) (ptrint) &Java_com_sun_cldc_io_j2me_socket_Protocol_open0      },
-       { "readBuf",    "(I[BII)I", (void *) (ptrint) &Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf    },
-       { "readByte",   "(I)I",     (void *) (ptrint) &Java_com_sun_cldc_io_j2me_socket_Protocol_readByte   },
-       { "writeBuf",   "(I[BII)I", (void *) (ptrint) &Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf   },
-       { "writeByte",  "(II)I",    (void *) (ptrint) &Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte  },
-       { "available0", "(I)I",     (void *) (ptrint) &Java_com_sun_cldc_io_j2me_socket_Protocol_available0 },
-       { "close0",     "(I)V",     (void *) (ptrint) &Java_com_sun_cldc_io_j2me_socket_Protocol_close0     },
-};
-
-/* _Jv_com_sun_cldc_io_j2me_socket_Protocol_init *******************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_com_sun_cldc_io_j2me_socket_Protocol_init(void)
-{
-       utf *u;
-       u = utf_new_char("com/sun/cldc/io/j2me/socket/Protocol");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     com/sun/cldc/io/j2me/socket/Protocol
- * Method:    open0
- * Signature: ([BII)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_open0(JNIEnv *env, jclass clazz, java_handle_bytearray_t *hostname, s4 port, s4 mode)
-{
-       struct hostent *phostent;
-    struct sockaddr_in serv_addr;
-       char           *name;
-       s4              sockfd;
-       s4              result;
-
-       /* The hostname byte-array is a NULL terminated C-string. */
-
-       name = (char *) &(LLNI_array_data(hostname));
-
-       /* get the host */
-
-       phostent = gethostbyname(name);
-
-       if (phostent == NULL)
-               return -1;
-
-       /* fill the sockaddr structure */
-
-       serv_addr.sin_family = AF_INET;
-       serv_addr.sin_port   = htons(port);
-
-       MCOPY(&serv_addr.sin_addr, phostent->h_addr, u1, phostent->h_length);
-
-       /* create the socket */
-
-       sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
-       if (sockfd < 0)
-               return -1;
-
-       /* connect the socket */
-
-       result = connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
-
-       if (result < 0)
-               return -1;
-
-       return sockfd;
-}
-
-
-/*
- * Class:     com/sun/cldc/io/j2me/socket/Protocol
- * Method:    readBuf
- * Signature: (I[BII)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf(JNIEnv *env, jclass clazz, s4 handle, java_handle_bytearray_t *b, s4 off, s4 len)
-{
-       void    *buf;
-       ssize_t  result;
-
-       /* get pointer to the buffer */
-
-       buf = &(LLNI_array_direct(b, off));
-
-       /* receive from the socket */
-
-       result = recv(handle, buf, len, 0);
-
-       if (result == 0) {
-               /* the peer has performed an orderly shutdown */
-
-               return -1;
-       }
-       else if (result < 0) {
-               vm_abort("Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf: recv failed: %s", strerror(errno));
-       }
-
-       return result;
-}
-
-
-/*
- * Class:     com/sun/cldc/io/j2me/socket/Protocol
- * Method:    readByte
- * Signature: (I)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_readByte(JNIEnv *env, jclass clazz, s4 handle) {
-       
-       char    byte;
-       ssize_t result;
-       
-       /* receive from the socket */
-
-       result = recv(handle, &byte, 1, 0);
-
-       if (result == 0) {
-               /* the peer has performed an orderly shutdown */
-
-               return -1;
-       }
-       else if (result < 0) {
-               /* should throw an IOException */
-
-               vm_abort("Java_com_sun_cldc_io_j2me_socket_Protocol_readByte: recv failed: %s", strerror(errno));
-       }
-
-       return byte;
-}
-
-
-/*
- * Class:     com/sun/cldc/io/j2me/socket/Protocol
- * Method:    writeBuf
- * Signature: (I[BII)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf(JNIEnv *env, jclass clazz, s4 handle, java_handle_bytearray_t * b, s4 off, s4 len) {
-
-       void    *buf;
-       ssize_t  result;
-
-       /* get pointer to the buffer */
-
-       buf = &(LLNI_array_direct(b, off));
-       
-       /* send the given byte to the socket */
-
-       result = send(handle, buf, len, 0);
-
-       if (result < 0)
-               /* should throw an IOException */
-
-               vm_abort("Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf: send failed: %s", strerror(errno));
-
-       return result;
-
-}
-
-
-/*
- * Class:     com/sun/cldc/io/j2me/socket/Protocol
- * Method:    writeByte
- * Signature: (II)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte(JNIEnv *env, jclass clazz, s4 handle, s4 b)
-{
-       char    byte;
-       ssize_t result;
-
-       byte = (char) b;
-
-       /* send the given byte to the socket */
-
-       result = send(handle, &byte, 1, 0);
-
-       if (result < 0)
-               vm_abort("Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte: send failed: %s", strerror(errno));
-
-       return result;
-}
-
-
-/*
- * Class:     com/sun/cldc/io/j2me/socket/Protocol
- * Method:    available0
- * Signature: (I)I
- */
-JNIEXPORT s4 JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_available0(JNIEnv *env, jclass clazz, s4 handle)
-{
-       /* NOTE: Sun doesn't have an implementation too */
-
-       return 0;
-}
-
-
-/*
- * Class:     com/sun/cldc/io/j2me/socket/Protocol
- * Method:    close0
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_close0(JNIEnv *env, jclass clazz, s4 handle)
-{
-       int result;
-
-       /* close the file descriptor */
-
-       result = close(handle);
-
-       if (result < 0)
-               vm_abort("Java_com_sun_cldc_io_j2me_socket_Protocol_close0: close failed: %s", strerror(errno));
-}
-
-
-/*
- * 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/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.cpp b/src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.cpp
new file mode 100644 (file)
index 0000000..9373b6b
--- /dev/null
@@ -0,0 +1,266 @@
+/* src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.cpp
+
+   Copyright (C) 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 <stdint.h>
+#include <errno.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/com_sun_cldc_io_j2me_socket_Protocol.h"
+#endif
+
+#include "vm/global.h"
+#include "vm/vm.hpp" /* REMOVE ME: temporarily */
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     com/sun/cldc/io/j2me/socket/Protocol
+ * Method:    open0
+ * Signature: ([BII)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_open0(JNIEnv *env, jclass clazz, jbyteArray hostname, jint port, jint mode)
+{
+       struct hostent *phostent;
+    struct sockaddr_in serv_addr;
+
+       // The hostname byte-array is a NULL terminated C-string.
+       // XXX Not GC safe.
+       char* name = (char*) &(LLNI_array_data((java_handle_bytearray_t*) hostname));
+
+       /* get the host */
+
+       phostent = gethostbyname(name);
+
+       if (phostent == NULL)
+               return -1;
+
+       /* fill the sockaddr structure */
+
+       serv_addr.sin_family = AF_INET;
+       serv_addr.sin_port   = htons(port);
+
+       MCOPY(&serv_addr.sin_addr, phostent->h_addr, u1, phostent->h_length);
+
+       /* create the socket */
+
+       int sockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+       if (sockfd < 0)
+               return -1;
+
+       /* connect the socket */
+
+       int result = connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr));
+
+       if (result < 0)
+               return -1;
+
+       return sockfd;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/j2me/socket/Protocol
+ * Method:    readBuf
+ * Signature: (I[BII)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf(JNIEnv *env, jclass clazz, jint handle, jbyteArray b, jint off, jint len)
+{
+       // Get pointer to the buffer.
+       // XXX Not GC safe.
+       void* buf = &(LLNI_array_direct((java_handle_bytearray_t*) b, off));
+
+       // Receive from the socket.
+       ssize_t result = recv(handle, buf, len, 0);
+
+       if (result == 0) {
+               // The peer has performed an orderly shutdown.
+               return -1;
+       }
+       else if (result < 0) {
+               vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf: recv failed");
+       }
+
+       return result;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/j2me/socket/Protocol
+ * Method:    readByte
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_readByte(JNIEnv *env, jclass clazz, jint handle)
+{
+       char byte;
+       
+       // Receive from the socket.
+       ssize_t result = recv(handle, &byte, 1, 0);
+
+       if (result == 0) {
+               // The peer has performed an orderly shutdown.
+               return -1;
+       }
+       else if (result < 0) {
+               // TODO Should throw an IOException.
+               vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_readByte: recv failed");
+       }
+
+       return byte;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/j2me/socket/Protocol
+ * Method:    writeBuf
+ * Signature: (I[BII)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf(JNIEnv *env, jclass clazz, jint handle, jbyteArray b, jint off, jint len)
+{
+       // Get pointer to the buffer.
+       // XXX Not GC safe.
+       void* buf = &(LLNI_array_direct((java_handle_bytearray_t*) b, off));
+       
+       // Send the given byte to the socket.
+       ssize_t result = send(handle, buf, len, 0);
+
+       if (result < 0) {
+               // TODO Should throw an IOException.
+               vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf: send failed");
+       }
+
+       return result;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/j2me/socket/Protocol
+ * Method:    writeByte
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte(JNIEnv *env, jclass clazz, jint handle, jint b)
+{
+       char byte = (char) b;
+
+       // Send the given byte to the socket.
+       ssize_t result = send(handle, &byte, 1, 0);
+
+       if (result < 0)
+               vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte: send failed");
+
+       return result;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/j2me/socket/Protocol
+ * Method:    available0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_available0(JNIEnv *env, jclass clazz, jint handle)
+{
+       // NOTE: Sun doesn't have an implementation too.
+       return 0;
+}
+
+
+/*
+ * Class:     com/sun/cldc/io/j2me/socket/Protocol
+ * Method:    close0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sun_cldc_io_j2me_socket_Protocol_close0(JNIEnv *env, jclass clazz, jint handle)
+{
+       // Close the file descriptor.
+       int result = close(handle);
+
+       if (result < 0)
+               vm_abort_errno("Java_com_sun_cldc_io_j2me_socket_Protocol_close0: close failed");
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "open0",      (char*) "([BII)I",  (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_open0      },
+       { (char*) "readBuf",    (char*) "(I[BII)I", (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf    },
+       { (char*) "readByte",   (char*) "(I)I",     (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_readByte   },
+       { (char*) "writeBuf",   (char*) "(I[BII)I", (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf   },
+       { (char*) "writeByte",  (char*) "(II)I",    (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte  },
+       { (char*) "available0", (char*) "(I)I",     (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_available0 },
+       { (char*) "close0",     (char*) "(I)V",     (void*) (uintptr_t) &Java_com_sun_cldc_io_j2me_socket_Protocol_close0     },
+};
+
+/* _Jv_com_sun_cldc_io_j2me_socket_Protocol_init *******************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" {
+void _Jv_com_sun_cldc_io_j2me_socket_Protocol_init(void)
+{
+       utf *u;
+       u = utf_new_char("com/sun/cldc/io/j2me/socket/Protocol");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/com_sun_cldchi_io_ConsoleOutputStream.c b/src/native/vm/cldc1.1/com_sun_cldchi_io_ConsoleOutputStream.c
deleted file mode 100644 (file)
index fc642a1..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* src/native/vm/cldc1.1/com_sun_cldchi_io_ConsoleOutputStream.c
-
-   Copyright (C) 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
-
-   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 "vm/types.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/com_sun_cldchi_io_ConsoleOutputStream.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "write", "(I)V", (void *) (ptrint) &Java_com_sun_cldchi_io_ConsoleOutputStream_write },
-};
-
-/* _Jv_com_sun_cldchi_io_ConsoleOutputStream_init ******************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_com_sun_cldchi_io_ConsoleOutputStream_init(void)
-{
-       utf *u;
-       u = utf_new_char("com/sun/cldchi/io/ConsoleOutputStream");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     com/sun/cldchi/io/ConsoleOutputStream
- * Method:    write
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_com_sun_cldchi_io_ConsoleOutputStream_write(JNIEnv *env, com_sun_cldchi_io_ConsoleOutputStream *this, s4 c)
-{
-       (void) fputc(c, stdout);
-}
-
-
-/*
- * 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/native/vm/cldc1.1/com_sun_cldchi_io_ConsoleOutputStream.cpp b/src/native/vm/cldc1.1/com_sun_cldchi_io_ConsoleOutputStream.cpp
new file mode 100644 (file)
index 0000000..8fcae40
--- /dev/null
@@ -0,0 +1,95 @@
+/* src/native/vm/cldc1.1/com_sun_cldchi_io_ConsoleOutputStream.cpp
+
+   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 <stdint.h>
+#include <stdio.h>
+
+#include "vm/types.h"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/com_sun_cldchi_io_ConsoleOutputStream.h"
+#endif
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     com/sun/cldchi/io/ConsoleOutputStream
+ * Method:    write
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_sun_cldchi_io_ConsoleOutputStream_write(JNIEnv *env, jobject _this, jint c)
+{
+       (void) fputc(c, stdout);
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "write", (char*) "(I)V", (void*) (uintptr_t) &Java_com_sun_cldchi_io_ConsoleOutputStream_write },
+};
+
+/* _Jv_com_sun_cldchi_io_ConsoleOutputStream_init ******************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" { 
+void _Jv_com_sun_cldchi_io_ConsoleOutputStream_init(void)
+{
+       utf *u;
+       u = utf_new_char("com/sun/cldchi/io/ConsoleOutputStream");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.c b/src/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.c
deleted file mode 100644 (file)
index b5b113a..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* src/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.c
-
-   Copyright (C) 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 "vm/types.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_String.h"
-
-#include "native/include/com_sun_cldchi_jvm_JVM.h"
-
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "loadLibrary", "(Ljava/lang/String;)V", (void *) (ptrint) &Java_com_sun_cldchi_jvm_JVM_loadLibrary },
-};
-
-
-/* _Jv_com_sun_cldchi_jvm_JVM_init *********************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_com_sun_cldchi_jvm_JVM_init(void)
-{
-       utf *u;
-       u = utf_new_char("com/sun/cldchi/jvm/JVM");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     com/sun/cldchi/jvm/JVM
- * Method:    loadLibrary
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_com_sun_cldchi_jvm_JVM_loadLibrary(JNIEnv *env, jclass clazz, java_lang_String *libName)
-{
-       int  result;
-       utf *name;
-
-       /* REMOVEME When we use Java-strings internally. */
-
-       if (libName == NULL) {
-               exceptions_throw_nullpointerexception();
-               return;
-       }
-
-       name = javastring_toutf((java_handle_t *) libName, false);
-
-       result = native_library_load(env, name, NULL);
-
-       /* Check for error and throw an exception in case. */
-
-       if (result == 0) {
-               exceptions_throw_unsatisfiedlinkerror(name);
-       }
-}
-
-
-/*
- * 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/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.cpp b/src/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.cpp
new file mode 100644 (file)
index 0000000..3416c45
--- /dev/null
@@ -0,0 +1,110 @@
+/* src/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.cpp
+
+   Copyright (C) 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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/com_sun_cldchi_jvm_JVM.h"
+#endif
+
+#include "vm/exceptions.hpp"
+#include "vm/string.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     com/sun/cldchi/jvm/JVM
+ * Method:    loadLibrary
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_sun_cldchi_jvm_JVM_loadLibrary(JNIEnv *env, jclass clazz, jstring libName)
+{
+       if (libName == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
+       /* REMOVEME When we use Java-strings internally. */
+
+       utf* name = javastring_toutf((java_handle_t *) libName, false);
+
+       int result = native_library_load(env, name, NULL);
+
+       /* Check for error and throw an exception in case. */
+
+       if (result == 0) {
+               exceptions_throw_unsatisfiedlinkerror(name);
+       }
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "loadLibrary", (char*) "(Ljava/lang/String;)V", (void*) (uintptr_t) &Java_com_sun_cldchi_jvm_JVM_loadLibrary },
+};
+
+
+/* _Jv_com_sun_cldchi_jvm_JVM_init *********************************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" { 
+void _Jv_com_sun_cldchi_jvm_JVM_init(void)
+{
+       utf *u;
+       u = utf_new_char("com/sun/cldchi/jvm/JVM");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_Class.c b/src/native/vm/cldc1.1/java_lang_Class.c
deleted file mode 100644 (file)
index 3d438a7..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_Class.c
-
-   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 "vm/types.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_String.h"             /* required by j.l.C */
-#include "native/include/java_lang_Object.h"
-
-#include "native/include/java_lang_Class.h"
-
-#include "vm/exceptions.h"
-#include "vm/initialize.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "forName",          "(Ljava/lang/String;)Ljava/lang/Class;",(void *) (ptrint) &Java_java_lang_Class_forName          },
-       { "newInstance",      "()Ljava/lang/Object;",                 (void *) (ptrint) &Java_java_lang_Class_newInstance      },
-       { "isInstance",       "(Ljava/lang/Object;)Z",                (void *) (ptrint) &Java_java_lang_Class_isInstance       },
-       { "isAssignableFrom", "(Ljava/lang/Class;)Z",                 (void *) (ptrint) &Java_java_lang_Class_isAssignableFrom },
-       { "isInterface",      "()Z",                                  (void *) (ptrint) &Java_java_lang_Class_isInterface      },
-       { "isArray",          "()Z",                                  (void *) (ptrint) &Java_java_lang_Class_isArray          },
-       { "getName",          "()Ljava/lang/String;",                 (void *) (ptrint) &Java_java_lang_Class_getName          },
-};
-
-/* _Jv_java_lang_Class_init ****************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_Class_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/Class");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    forName
- * Signature: (Ljava/lang/String;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_Class_forName(JNIEnv *env, jclass clazz, java_lang_String *name)
-{
-       utf       *ufile;
-       utf       *uname;
-       classinfo *c;
-       u2        *pos;
-       s4         i;
-
-       /* illegal argument */
-
-       if (name == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* create utf string in which '.' is replaced by '/' */
-
-       ufile = javastring_toutf((java_handle_t *) name, true);
-       uname = javastring_toutf((java_handle_t *) name, false);
-
-       /* name must not contain '/' (mauve test) */
-
-       for (i = 0, pos = LLNI_field_direct(name, value)->data + LLNI_field_direct(name, offset); i < LLNI_field_direct(name, count); i++, pos++) {
-               if (*pos == '/') {
-                       exceptions_throw_classnotfoundexception(uname);
-                       return NULL;
-               }
-       }
-
-       /* try to load, ... */
-
-       c = load_class_bootstrap(ufile);
-
-       if (c == NULL)
-           return NULL;
-
-       /* link, ... */
-
-       if (!link_class(c))
-               return NULL;
-       
-       /* ...and initialize it. */
-
-       if (!initialize_class(c))
-               return NULL;
-
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    newInstance
- * Signature: ()Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_Class_newInstance(JNIEnv *env, java_lang_Class* this)
-{
-       classinfo     *c;
-       java_handle_t *o;
-
-       c = LLNI_classinfo_unwrap(this);
-
-       o = native_new_and_init(c);
-
-       return (java_lang_Object *) o;
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    isInstance
- * Signature: (Ljava/lang/Object;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_Class_isInstance(JNIEnv *env, java_lang_Class *this, java_lang_Object *obj)
-{
-       classinfo     *c;
-       java_handle_t *h;
-
-       c = LLNI_classinfo_unwrap(this);
-       h = (java_handle_t *) obj;
-
-       return class_is_instance(c, h);
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    isAssignableFrom
- * Signature: (Ljava/lang/Class;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_Class_isAssignableFrom(JNIEnv *env, java_lang_Class *this, java_lang_Class *cls)
-{
-       classinfo *to;
-       classinfo *from;
-
-       to   = LLNI_classinfo_unwrap(this);
-       from = LLNI_classinfo_unwrap(cls);
-
-       if (from == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       return class_is_assignable_from(to, from);
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    isInterface
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_Class_isInterface(JNIEnv *env, java_lang_Class *this)
-{
-       classinfo *c;
-
-       c = LLNI_classinfo_unwrap(this);
-
-       return class_is_interface(c);
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    isArray
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_Class_isArray(JNIEnv *env, java_lang_Class *this)
-{
-       classinfo *c;
-
-       c = LLNI_classinfo_unwrap(this);
-
-       return class_is_array(c);
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    getName
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_Class_getName(JNIEnv *env, java_lang_Class *this)
-{
-       classinfo *c;
-
-       c = LLNI_classinfo_unwrap(this);
-
-       return (java_lang_String*) class_get_classname(c);
-}
-
-
-/*
- * 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/native/vm/cldc1.1/java_lang_Class.cpp b/src/native/vm/cldc1.1/java_lang_Class.cpp
new file mode 100644 (file)
index 0000000..49d459d
--- /dev/null
@@ -0,0 +1,248 @@
+/* src/native/vm/cldc1.1/java_lang_Class.cpp
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_Class.h"
+#endif
+
+#include "vm/exceptions.hpp"
+#include "vm/initialize.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/Class
+ * Method:    forName
+ * Signature: (Ljava/lang/String;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_Class_forName(JNIEnv *env, jclass clazz, jstring name)
+{
+       utf       *ufile;
+       utf       *uname;
+       classinfo *c;
+       char*      pos;
+       int32_t    i;
+
+       /* illegal argument */
+
+       if (name == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* create utf string in which '.' is replaced by '/' */
+
+       ufile = javastring_toutf((java_handle_t *) name, true);
+       uname = javastring_toutf((java_handle_t *) name, false);
+
+       /* name must not contain '/' (mauve test) */
+
+       // FIXME Move this check into a function.
+       for (i = 0, pos = uname->text; i < uname->blength; i++, pos++) {
+               if (*pos == '/') {
+                       exceptions_throw_classnotfoundexception(uname);
+                       return NULL;
+               }
+       }
+
+       /* try to load, ... */
+
+       c = load_class_bootstrap(ufile);
+
+       if (c == NULL)
+           return NULL;
+
+       /* link, ... */
+
+       if (!link_class(c))
+               return NULL;
+       
+       /* ...and initialize it. */
+
+       if (!initialize_class(c))
+               return NULL;
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/*
+ * Class:     java/lang/Class
+ * Method:    newInstance
+ * Signature: ()Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_Class_newInstance(JNIEnv *env, jclass _this)
+{
+       classinfo     *c;
+       java_handle_t *o;
+
+       c = LLNI_classinfo_unwrap(_this);
+
+       o = native_new_and_init(c);
+
+       return (jobject) o;
+}
+
+
+/*
+ * Class:     java/lang/Class
+ * Method:    isInstance
+ * Signature: (Ljava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_Class_isInstance(JNIEnv *env, jclass _this, jobject obj)
+{
+       classinfo     *c;
+       java_handle_t *h;
+
+       c = LLNI_classinfo_unwrap(_this);
+       h = (java_handle_t *) obj;
+
+       return class_is_instance(c, h);
+}
+
+
+/*
+ * Class:     java/lang/Class
+ * Method:    isAssignableFrom
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_Class_isAssignableFrom(JNIEnv *env, jclass _this, jclass cls)
+{
+       classinfo *to;
+       classinfo *from;
+
+       to   = LLNI_classinfo_unwrap(_this);
+       from = LLNI_classinfo_unwrap(cls);
+
+       if (from == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       return class_is_assignable_from(to, from);
+}
+
+
+/*
+ * Class:     java/lang/Class
+ * Method:    isInterface
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_Class_isInterface(JNIEnv *env, jclass _this)
+{
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(_this);
+
+       return class_is_interface(c);
+}
+
+
+/*
+ * Class:     java/lang/Class
+ * Method:    isArray
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_Class_isArray(JNIEnv *env, jclass _this)
+{
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(_this);
+
+       return class_is_array(c);
+}
+
+
+/*
+ * Class:     java/lang/Class
+ * Method:    getName
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_Class_getName(JNIEnv *env, jclass _this)
+{
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(_this);
+
+       return (jstring) class_get_classname(c);
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "forName",          (char*) "(Ljava/lang/String;)Ljava/lang/Class;",(void*) (uintptr_t) &Java_java_lang_Class_forName          },
+       { (char*) "newInstance",      (char*) "()Ljava/lang/Object;",                 (void*) (uintptr_t) &Java_java_lang_Class_newInstance      },
+       { (char*) "isInstance",       (char*) "(Ljava/lang/Object;)Z",                (void*) (uintptr_t) &Java_java_lang_Class_isInstance       },
+       { (char*) "isAssignableFrom", (char*) "(Ljava/lang/Class;)Z",                 (void*) (uintptr_t) &Java_java_lang_Class_isAssignableFrom },
+       { (char*) "isInterface",      (char*) "()Z",                                  (void*) (uintptr_t) &Java_java_lang_Class_isInterface      },
+       { (char*) "isArray",          (char*) "()Z",                                  (void*) (uintptr_t) &Java_java_lang_Class_isArray          },
+       { (char*) "getName",          (char*) "()Ljava/lang/String;",                 (void*) (uintptr_t) &Java_java_lang_Class_getName          },
+};
+
+/* _Jv_java_lang_Class_init ****************************************************
+   Register native functions.
+*******************************************************************************/
+
+// FIXME
+extern "C" { 
+void _Jv_java_lang_Class_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/Class");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_Double.c b/src/native/vm/cldc1.1/java_lang_Double.c
deleted file mode 100644 (file)
index 99f3195..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_Double.c
-
-   Copyright (C) 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
-
-   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 "vm/types.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Double.h"
-
-#include "vm/builtin.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "doubleToLongBits", "(D)J", (void *) (ptrint) &Java_java_lang_Double_doubleToLongBits },
-       { "longBitsToDouble", "(J)D", (void *) (ptrint) &Java_java_lang_Double_longBitsToDouble },
-};
-/* _Jv_java_lang_Double_init ***************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_Double_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/Double");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/Double
- * Method:    doubleToLongBits
- * Signature: (D)J
- */
-JNIEXPORT s8 JNICALL Java_java_lang_Double_doubleToLongBits(JNIEnv *env, jclass clazz, double doubleValue)
-{
-       jvalue val;
-       s8  e, f;
-       val.d = doubleValue;
-
-#if defined(__IEEE_BYTES_LITTLE_ENDIAN)
-       /* On little endian ARM processors when using FPA, word order of
-          doubles is still big endian. So take that into account here. When
-          using VFP, word order of doubles follows byte order. */
-
-#define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
-
-       val.j = SWAP_DOUBLE(val.j);
-#endif
-
-       e = val.j & 0x7ff0000000000000LL;
-       f = val.j & 0x000fffffffffffffLL;
-
-       if (e == DBL_POSINF && f != 0L)
-               val.j = DBL_NAN;
-
-       return val.j;
-}
-
-
-/*
- * Class:     java/lang/Double
- * Method:    longBitsToDouble
- * Signature: (J)D
- */
-JNIEXPORT double JNICALL Java_java_lang_Double_longBitsToDouble(JNIEnv *env, jclass clazz, s8 longValue)
-{
-       jvalue val;
-       val.j = longValue;
-
-#if defined(__IEEE_BYTES_LITTLE_ENDIAN)
-       val.j = SWAP_DOUBLE(val.j);
-#endif
-
-       return val.d;
-}
-
-
-/*
- * 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/native/vm/cldc1.1/java_lang_Double.cpp b/src/native/vm/cldc1.1/java_lang_Double.cpp
new file mode 100644 (file)
index 0000000..772b603
--- /dev/null
@@ -0,0 +1,132 @@
+/* src/native/vm/cldc1.1/java_lang_Double.c
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_Double.h"
+#endif
+
+#include "vm/builtin.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/Double
+ * Method:    doubleToLongBits
+ * Signature: (D)J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_Double_doubleToLongBits(JNIEnv *env, jclass clazz, jdouble doubleValue)
+{
+       jvalue val;
+       s8  e, f;
+       val.d = doubleValue;
+
+#if defined(__IEEE_BYTES_LITTLE_ENDIAN)
+       /* On little endian ARM processors when using FPA, word order of
+          doubles is still big endian. So take that into account here. When
+          using VFP, word order of doubles follows byte order. */
+
+#define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
+
+       val.j = SWAP_DOUBLE(val.j);
+#endif
+
+       e = val.j & 0x7ff0000000000000LL;
+       f = val.j & 0x000fffffffffffffLL;
+
+       if (e == DBL_POSINF && f != 0L)
+               val.j = DBL_NAN;
+
+       return val.j;
+}
+
+
+/*
+ * Class:     java/lang/Double
+ * Method:    longBitsToDouble
+ * Signature: (J)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_Double_longBitsToDouble(JNIEnv *env, jclass clazz, jlong longValue)
+{
+       jvalue val;
+       val.j = longValue;
+
+#if defined(__IEEE_BYTES_LITTLE_ENDIAN)
+       val.j = SWAP_DOUBLE(val.j);
+#endif
+
+       return val.d;
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "doubleToLongBits", (char*) "(D)J", (void*) (uintptr_t) &Java_java_lang_Double_doubleToLongBits },
+       { (char*) "longBitsToDouble", (char*) "(J)D", (void*) (uintptr_t) &Java_java_lang_Double_longBitsToDouble },
+};
+/* _Jv_java_lang_Double_init ***************************************************
+   Register native functions.
+*******************************************************************************/
+
+// FIXME
+extern "C" { 
+void _Jv_java_lang_Double_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/Double");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_Float.c b/src/native/vm/cldc1.1/java_lang_Float.c
deleted file mode 100644 (file)
index 67cb004..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_Float.c
-
-   Copyright (C) 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
-
-   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 "vm/types.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Float.h"
-
-#include "vm/builtin.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "floatToIntBits", "(F)I",     (void *) (ptrint) &Java_java_lang_Float_floatToIntBits },
-};
-/* _Jv_java_lang_Float_init ****************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_Float_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/Float");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-/*
- * Class:     java/lang/Float
- * Method:    floatToIntBits
- * Signature: (F)I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_Float_floatToIntBits(JNIEnv *env, jclass clazz, float value)
-{
-       imm_union val;
-       int e, f;
-
-       val.f = value;
-
-       e = val.i & 0x7f800000;
-       f = val.i & 0x007fffff;
-
-       if (e == FLT_POSINF && f != 0)
-               return FLT_NAN;
-
-       return val.i;
-}
-
-
-/*
- * 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/native/vm/cldc1.1/java_lang_Float.cpp b/src/native/vm/cldc1.1/java_lang_Float.cpp
new file mode 100644 (file)
index 0000000..bea50c0
--- /dev/null
@@ -0,0 +1,104 @@
+/* src/native/vm/cldc1.1/java_lang_Float.cpp
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_Float.h"
+#endif
+
+#include "vm/builtin.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/Float
+ * Method:    floatToIntBits
+ * Signature: (F)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_Float_floatToIntBits(JNIEnv *env, jclass clazz, jfloat value)
+{
+       imm_union val;
+       int e, f;
+
+       val.f = value;
+
+       e = val.i & 0x7f800000;
+       f = val.i & 0x007fffff;
+
+       if (e == FLT_POSINF && f != 0)
+               return FLT_NAN;
+
+       return val.i;
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "floatToIntBits", (char*) "(F)I", (void*) (uintptr_t) &Java_java_lang_Float_floatToIntBits },
+};
+/* _Jv_java_lang_Float_init ****************************************************
+   Register native functions.
+*******************************************************************************/
+
+// FIXME
+extern "C" { 
+void _Jv_java_lang_Float_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/Float");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_Math.c b/src/native/vm/cldc1.1/java_lang_Math.c
deleted file mode 100644 (file)
index 9d542b7..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_Math.c
-
-   Copyright (C) 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
-
-   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 "vm/types.h"
-
-#include "fdlibm/fdlibm.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Math.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "ceil",  "(D)D", (void *) (ptrint) &Java_java_lang_Math_ceil  },
-       { "cos",   "(D)D", (void *) (ptrint) &Java_java_lang_Math_cos   },
-       { "floor", "(D)D", (void *) (ptrint) &Java_java_lang_Math_floor },
-       { "sin",   "(D)D", (void *) (ptrint) &Java_java_lang_Math_sin   },
-       { "sqrt",  "(D)D", (void *) (ptrint) &Java_java_lang_Math_sqrt  },
-       { "tan",   "(D)D", (void *) (ptrint) &Java_java_lang_Math_tan   },
-};
-/* _Jv_java_lang_Math_init *****************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_Math_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/Math");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/Math
- * Method:    ceil
- * Signature: (D)D
- */
-JNIEXPORT double JNICALL Java_java_lang_Math_ceil(JNIEnv *env, jclass clazz, double a)
-{
-       return ceil(a);
-}
-
-
-/*
- * Class:     java/lang/Math
- * Method:    cos
- * Signature: (D)D
- */
-JNIEXPORT double JNICALL Java_java_lang_Math_cos(JNIEnv *env, jclass clazz, double a)
-{
-       return cos(a);
-}
-
-
-/*
- * Class:     java/lang/Math
- * Method:    floor
- * Signature: (D)D
- */
-JNIEXPORT double JNICALL Java_java_lang_Math_floor(JNIEnv *env, jclass clazz, double a)
-{
-       return floor(a);
-}
-
-
-/*
- * Class:     java/lang/Math
- * Method:    sin
- * Signature: (D)D
- */
-JNIEXPORT double JNICALL Java_java_lang_Math_sin(JNIEnv *env, jclass clazz, double a)
-{
-       return sin(a);
-}
-
-
-/*
- * Class:     java/lang/Math
- * Method:    sqrt
- * Signature: (D)D
- */
-JNIEXPORT double JNICALL Java_java_lang_Math_sqrt(JNIEnv *env, jclass clazz, double a)
-{
-       return sqrt(a);
-}
-
-
-/*
- * Class:     java/lang/Math
- * Method:    tan
- * Signature: (D)D
- */
-JNIEXPORT double JNICALL Java_java_lang_Math_tan(JNIEnv *env, jclass clazz, double a)
-{
-       return tan(a);
-}
-
-
-/*
- * 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/native/vm/cldc1.1/java_lang_Math.cpp b/src/native/vm/cldc1.1/java_lang_Math.cpp
new file mode 100644 (file)
index 0000000..f65adb5
--- /dev/null
@@ -0,0 +1,154 @@
+/* src/native/vm/cldc1.1/java_lang_Math.cpp
+
+   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 <stdint.h>
+
+#include "fdlibm/fdlibm.h"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_Math.h"
+#endif
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/Math
+ * Method:    ceil
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_Math_ceil(JNIEnv *env, jclass clazz, jdouble a)
+{
+       return ceil(a);
+}
+
+
+/*
+ * Class:     java/lang/Math
+ * Method:    cos
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_Math_cos(JNIEnv *env, jclass clazz, jdouble a)
+{
+       return cos(a);
+}
+
+
+/*
+ * Class:     java/lang/Math
+ * Method:    floor
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_Math_floor(JNIEnv *env, jclass clazz, jdouble a)
+{
+       return floor(a);
+}
+
+
+/*
+ * Class:     java/lang/Math
+ * Method:    sin
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_Math_sin(JNIEnv *env, jclass clazz, jdouble a)
+{
+       return sin(a);
+}
+
+
+/*
+ * Class:     java/lang/Math
+ * Method:    sqrt
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_Math_sqrt(JNIEnv *env, jclass clazz, jdouble a)
+{
+       return sqrt(a);
+}
+
+
+/*
+ * Class:     java/lang/Math
+ * Method:    tan
+ * Signature: (D)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_Math_tan(JNIEnv *env, jclass clazz, jdouble a)
+{
+       return tan(a);
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "ceil",  (char*) "(D)D", (void*) (uintptr_t) &Java_java_lang_Math_ceil  },
+       { (char*) "cos",   (char*) "(D)D", (void*) (uintptr_t) &Java_java_lang_Math_cos   },
+       { (char*) "floor", (char*) "(D)D", (void*) (uintptr_t) &Java_java_lang_Math_floor },
+       { (char*) "sin",   (char*) "(D)D", (void*) (uintptr_t) &Java_java_lang_Math_sin   },
+       { (char*) "sqrt",  (char*) "(D)D", (void*) (uintptr_t) &Java_java_lang_Math_sqrt  },
+       { (char*) "tan",   (char*) "(D)D", (void*) (uintptr_t) &Java_java_lang_Math_tan   },
+};
+/* _Jv_java_lang_Math_init *****************************************************
+   Register native functions.
+*******************************************************************************/
+
+// FIXME
+extern "C" { 
+void _Jv_java_lang_Math_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/Math");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_Object.c b/src/native/vm/cldc1.1/java_lang_Object.c
deleted file mode 100644 (file)
index 26808ea..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_Object.c
-
-   Copyright (C) 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
-
-   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 "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_String.h"             /* required by j.l.C */
-#include "native/include/java_lang_Class.h"
-
-#include "native/include/java_lang_Object.h"
-
-#include "threads/lock-common.h"
-
-#include "vm/exceptions.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "getClass",  "()Ljava/lang/Class;",                   (void *) (ptrint) &Java_java_lang_Object_getClass  },
-       { "hashCode",  "()I",                                   (void *) (ptrint) &Java_java_lang_Object_hashCode  },
-       { "notify",    "()V",                                   (void *) (ptrint) &Java_java_lang_Object_notify    },
-       { "notifyAll", "()V",                                   (void *) (ptrint) &Java_java_lang_Object_notifyAll },
-       { "wait",      "(J)V",                                  (void *) (ptrint) &Java_java_lang_Object_wait      },
-};
-/* _Jv_java_lang_Object_init ***************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_Object_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/Object");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/Object
- * Method:    getClass
- * Signature: ()Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_Object_getClass(JNIEnv *env, java_lang_Object *obj)
-{
-       classinfo *c;
-
-       if (obj == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       LLNI_class_get(obj, c);
-
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * Class:     java/lang/Object
- * Method:    hashCode
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_Object_hashCode(JNIEnv *env, java_lang_Object *this)
-{
-#if defined(ENABLE_GC_CACAO)
-       assert(0);
-#else
-       return (int32_t) ((intptr_t) this);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Object
- * Method:    notify
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Object_notify(JNIEnv *env, java_lang_Object *this)
-{
-#if defined(ENABLE_THREADS)
-       lock_notify_object((java_handle_t *) this);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Object
- * Method:    notifyAll
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Object_notifyAll(JNIEnv *env, java_lang_Object *this)
-{
-#if defined(ENABLE_THREADS)
-       lock_notify_all_object((java_handle_t *) this);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Object
- * Method:    wait
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_java_lang_Object_wait(JNIEnv *env, java_lang_Object *this, s8 timeout)
-{
-#if defined(ENABLE_JVMTI)
-       /* Monitor Wait */
-       if (jvmti) jvmti_MonitorWaiting(true, this, timeout);
-#endif
-
-#if defined(ENABLE_THREADS)
-       lock_wait_for_object((java_handle_t *) this, timeout, 0);
-#endif
-
-#if defined(ENABLE_JVMTI)
-       /* Monitor Waited */
-       /* XXX: How do you know if wait timed out ?*/
-       if (jvmti) jvmti_MonitorWaiting(false, this, 0);
-#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/native/vm/cldc1.1/java_lang_Object.cpp b/src/native/vm/cldc1.1/java_lang_Object.cpp
new file mode 100644 (file)
index 0000000..83d6df8
--- /dev/null
@@ -0,0 +1,176 @@
+/* src/native/vm/cldc1.1/java_lang_Object.c
+
+   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 <stdint.h>
+#include <stdlib.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_Object.h"
+#endif
+
+#include "threads/lock-common.h"
+
+#include "vm/exceptions.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/Object
+ * Method:    getClass
+ * Signature: ()Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_Object_getClass(JNIEnv *env, jobject obj)
+{
+       classinfo *c;
+
+       if (obj == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       LLNI_class_get(obj, c);
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/*
+ * Class:     java/lang/Object
+ * Method:    hashCode
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_Object_hashCode(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_GC_CACAO)
+       assert(0);
+#else
+       return (int32_t) ((uintptr_t) _this);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/Object
+ * Method:    notify
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Object_notify(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       lock_notify_object((java_handle_t *) _this);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/Object
+ * Method:    notifyAll
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Object_notifyAll(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       lock_notify_all_object((java_handle_t *) _this);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/Object
+ * Method:    wait
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Object_wait(JNIEnv *env, jobject _this, jlong timeout)
+{
+#if defined(ENABLE_JVMTI)
+       /* Monitor Wait */
+       if (jvmti) jvmti_MonitorWaiting(true, _this, timeout);
+#endif
+
+#if defined(ENABLE_THREADS)
+       lock_wait_for_object((java_handle_t *) _this, timeout, 0);
+#endif
+
+#if defined(ENABLE_JVMTI)
+       /* Monitor Waited */
+       /* XXX: How do you know if wait timed out ?*/
+       if (jvmti) jvmti_MonitorWaiting(false, _this, 0);
+#endif
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "getClass",  (char*) "()Ljava/lang/Class;", (void*) (uintptr_t) &Java_java_lang_Object_getClass  },
+       { (char*) "hashCode",  (char*) "()I",                 (void*) (uintptr_t) &Java_java_lang_Object_hashCode  },
+       { (char*) "notify",    (char*) "()V",                 (void*) (uintptr_t) &Java_java_lang_Object_notify    },
+       { (char*) "notifyAll", (char*) "()V",                 (void*) (uintptr_t) &Java_java_lang_Object_notifyAll },
+       { (char*) "wait",      (char*) "(J)V",                (void*) (uintptr_t) &Java_java_lang_Object_wait      },
+};
+/* _Jv_java_lang_Object_init ***************************************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" {
+void _Jv_java_lang_Object_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/Object");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_Runtime.c b/src/native/vm/cldc1.1/java_lang_Runtime.c
deleted file mode 100644 (file)
index 838c683..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_Runtime.c
-
-   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 <stdint.h>
-
-#include "mm/gc-common.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Runtime.h"
-
-#include "vm/vm.h"
-
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "exitInternal", "(I)V", (void *) (intptr_t) &Java_java_lang_Runtime_exitInternal },
-       { "freeMemory",   "()J",  (void *) (intptr_t) &Java_java_lang_Runtime_freeMemory   },
-       { "totalMemory",  "()J",  (void *) (intptr_t) &Java_java_lang_Runtime_totalMemory  },
-       { "gc",           "()V",  (void *) (intptr_t) &Java_java_lang_Runtime_gc           },
-};
-/* _Jv_java_lang_Runtime_init **************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_Runtime_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/Runtime");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    exitInternal
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_java_lang_Runtime_exitInternal(JNIEnv *env, java_lang_Runtime *this, int32_t status)
-{
-       vm_shutdown(status);
-}
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    freeMemory
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_java_lang_Runtime_freeMemory(JNIEnv *env, java_lang_Runtime *this)
-{
-       return gc_get_free_bytes();
-}
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    totalMemory
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_java_lang_Runtime_totalMemory(JNIEnv *env, java_lang_Runtime *this)
-{
-       return gc_get_heap_size();
-}
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    gc
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Runtime_gc(JNIEnv *env, java_lang_Runtime *this)
-{
-       gc_call();
-}
-
-
-/*
- * 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/native/vm/cldc1.1/java_lang_Runtime.cpp b/src/native/vm/cldc1.1/java_lang_Runtime.cpp
new file mode 100644 (file)
index 0000000..fce3463
--- /dev/null
@@ -0,0 +1,133 @@
+/* src/native/vm/cldc1.1/java_lang_Runtime.cpp
+
+   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 <stdint.h>
+
+#include "mm/gc.hpp"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_Runtime.h"
+#endif
+
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/Runtime
+ * Method:    exitInternal
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Runtime_exitInternal(JNIEnv *env, jobject _this, jint status)
+{
+       vm_shutdown(status);
+}
+
+
+/*
+ * Class:     java/lang/Runtime
+ * Method:    freeMemory
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject _this)
+{
+       return gc_get_free_bytes();
+}
+
+
+/*
+ * Class:     java/lang/Runtime
+ * Method:    totalMemory
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_Runtime_totalMemory(JNIEnv *env, jobject _this)
+{
+       return gc_get_heap_size();
+}
+
+
+/*
+ * Class:     java/lang/Runtime
+ * Method:    gc
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Runtime_gc(JNIEnv *env, jobject _this)
+{
+       gc_call();
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "exitInternal", (char*) "(I)V", (void*) (uintptr_t) &Java_java_lang_Runtime_exitInternal },
+       { (char*) "freeMemory",   (char*) "()J",  (void*) (uintptr_t) &Java_java_lang_Runtime_freeMemory   },
+       { (char*) "totalMemory",  (char*) "()J",  (void*) (uintptr_t) &Java_java_lang_Runtime_totalMemory  },
+       { (char*) "gc",           (char*) "()V",  (void*) (uintptr_t) &Java_java_lang_Runtime_gc           },
+};
+/* _Jv_java_lang_Runtime_init **************************************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" {
+void _Jv_java_lang_Runtime_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/Runtime");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_String.c b/src/native/vm/cldc1.1/java_lang_String.c
deleted file mode 100644 (file)
index c0ba6ad..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_String.c
-
-   Copyright (C) 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
-
-   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 <string.h>
-
-#include "vm/types.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-
-#include "native/include/java_lang_String.h"
-
-#include "vm/stringlocal.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "hashCode",    "()I",                    (void *) (ptrint) &Java_java_lang_String_hashCode        },
-       { "indexOf",     "(I)I",                   (void *) (ptrint) &Java_java_lang_String_indexOf__I      },
-       { "indexOf",     "(II)I",                  (void *) (ptrint) &Java_java_lang_String_indexOf__II     },
-       { "lastIndexOf", "(I)I",                   (void *) (ptrint) &Java_java_lang_String_lastIndexOf__I  },
-       { "lastIndexOf", "(II)I",                  (void *) (ptrint) &Java_java_lang_String_lastIndexOf__II },
-#if 0
-       { "equals",      "(Ljava/lang/Object;)Z;", (void *) (ptrint) &Java_java_lang_String_equals          },
-#endif
-       { "intern",      "()Ljava/lang/String;",   (void *) (ptrint) &Java_java_lang_String_intern          },
-};
-
-
-/* _Jv_java_lang_String_init ***************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_String_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/String");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/String
- * Method:    hashCode
- * Signature: ()I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_String_hashCode(JNIEnv *env, java_lang_String *this)
-{
-       java_handle_chararray_t *value;
-       int32_t                 offset;
-       int32_t                 count;
-       s4                              hash;
-       s4                              i;
-
-       /* get values from Java object */
-       
-       LLNI_field_get_val(this, offset, offset);
-       LLNI_field_get_val(this, count, count);
-       LLNI_field_get_ref(this, value, value);
-
-       hash = 0;
-
-       for (i = 0; i < count; i++) {
-               hash = (31 * hash) + LLNI_array_direct(value, offset + i);
-       }
-
-       return hash;
-}
-
-
-/*
- * Class:     java/lang/String
- * Method:    indexOf
- * Signature: (I)I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_String_indexOf__I(JNIEnv *env, java_lang_String *this, s4 ch)
-{
-       java_handle_chararray_t *value;
-       int32_t                 offset;
-       int32_t                 count;
-       s4                              i;
-
-       /* get values from Java object */
-
-       LLNI_field_get_val(this, offset, offset);
-       LLNI_field_get_val(this, count, count);
-       LLNI_field_get_ref(this, value, value);
-
-       for (i = 0; i < count; i++) {
-               if (LLNI_array_direct(value, offset + i) == ch) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-
-/*
- * Class:     java/lang/String
- * Method:    indexOf
- * Signature: (II)I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_String_indexOf__II(JNIEnv *env, java_lang_String *this, s4 ch, s4 fromIndex)
-{
-       java_handle_chararray_t *value;
-       int32_t                 offset;
-       int32_t                 count;
-       s4                              i;
-
-       /* get values from Java object */
-
-       LLNI_field_get_val(this, offset, offset);
-       LLNI_field_get_val(this, count, count);
-       LLNI_field_get_ref(this, value, value);
-
-       if (fromIndex < 0) {
-               fromIndex = 0;
-       }
-       else if (fromIndex >= count) {
-               /* Note: fromIndex might be near -1>>>1. */
-               return -1;
-       }
-
-       for (i = fromIndex ; i < count ; i++) {
-               if (LLNI_array_direct(value, offset + i) == ch) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-
-/*
- * Class:     java/lang/String
- * Method:    lastIndexOf
- * Signature: (I)I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_String_lastIndexOf__I(JNIEnv *env, java_lang_String *this, s4 ch)
-{
-       int32_t count;
-       
-       LLNI_field_get_val(this, count, count);
-       
-       return Java_java_lang_String_lastIndexOf__II(env, this, ch, count - 1);
-}
-
-
-/*
- * Class:     java/lang/String
- * Method:    lastIndexOf
- * Signature: (II)I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_String_lastIndexOf__II(JNIEnv *env, java_lang_String *this, s4 ch, s4 fromIndex)
-{
-       java_handle_chararray_t *value;
-       int32_t                 offset;
-       int32_t                 count;
-       s4                              start;
-       s4                              i;
-
-       /* get values from Java object */
-
-       LLNI_field_get_val(this, offset, offset);
-       LLNI_field_get_val(this, count, count);
-       LLNI_field_get_ref(this, value, value);
-
-       start = ((fromIndex >= count) ? count - 1 : fromIndex);
-
-       for (i = start; i >= 0; i--) {
-               if (LLNI_array_direct(value, offset + i) == ch) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-
-#if 0
-/*
- * Class:     java/lang/String
- * Method:    equals
- * Signature: (Ljava/lang/Object;)Z;
- */
-JNIEXPORT s4 JNICALL Java_java_lang_String_equals(JNIEnv *env, java_lang_String* this, java_lang_Object *o)
-{
-       java_lang_String*               s;
-       java_handle_chararray_t *value;
-       int32_t                 offset;
-       int32_t                 count;
-       java_handle_chararray_t *dvalue;
-       int32_t                 doffset;
-       int32_t                 dcount;
-       classinfo                       *c;
-       
-       LLNI_field_get_val(this, offset, offset);
-       LLNI_field_get_val(this, count, count);
-       LLNI_field_get_ref(this, value, value);
-       LLNI_class_get(o, c);
-
-       /* TODO: is this the correct implementation for short-circuiting on object identity? */
-       if ((java_lang_Object*)this == o)
-               return 1;
-       
-       if (c != class_java_lang_String) 
-               return 0;
-
-       s = (java_lang_String *) o;
-       LLNI_field_get_val(this, offset, doffset);
-       LLNI_field_get_val(this, count, dcount);
-       LLNI_field_get_ref(this, value, dvalue);
-
-       if (count != dcount)
-               return 0;
-
-       return ( 0 == memcmp((void*)(LLNI_array_direct(value, offset)),
-                                                (void*)(LLNI_array_direct(dvalue, doffset),
-                                                count) );
-
-}
-#endif
-
-
-/*
- * Class:     java/lang/String
- * Method:    intern
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_String_intern(JNIEnv *env, java_lang_String *this)
-{
-       if (this == NULL)
-               return NULL;
-
-       return (java_lang_String *) javastring_intern((java_handle_t *) this);
-}
-
-
-/*
- * 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/native/vm/cldc1.1/java_lang_String.cpp b/src/native/vm/cldc1.1/java_lang_String.cpp
new file mode 100644 (file)
index 0000000..e0cb351
--- /dev/null
@@ -0,0 +1,225 @@
+/* src/native/vm/cldc1.1/java_lang_String.cpp
+
+   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 <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_String.h"
+#endif
+
+#include "vm/javaobjects.hpp"
+#include "vm/string.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/String
+ * Method:    hashCode
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_String_hashCode(JNIEnv *env, jstring _this)
+{
+       java_lang_String jls(_this);
+
+       java_handle_chararray_t* value = jls.get_value();
+       int32_t offset = jls.get_offset();
+       int32_t count  = jls.get_count();
+
+       int32_t hash = 0;
+
+       for (int32_t i = 0; i < count; i++) {
+               hash = (31 * hash) + LLNI_array_direct(value, offset + i);
+       }
+
+       return hash;
+}
+
+
+/*
+ * Class:     java/lang/String
+ * Method:    indexOf
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_String_indexOf__I(JNIEnv *env, jstring _this, jint ch)
+{
+       java_lang_String jls(_this);
+
+       java_handle_chararray_t* value = jls.get_value();
+       int32_t offset = jls.get_offset();
+       int32_t count  = jls.get_count();
+
+       for (int32_t i = 0; i < count; i++) {
+               if (LLNI_array_direct(value, offset + i) == ch) {
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+
+/*
+ * Class:     java/lang/String
+ * Method:    indexOf
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_String_indexOf__II(JNIEnv *env, jstring _this, jint ch, jint fromIndex)
+{
+       java_lang_String jls(_this);
+
+       java_handle_chararray_t* value = jls.get_value();
+       int32_t offset = jls.get_offset();
+       int32_t count  = jls.get_count();
+
+       if (fromIndex < 0) {
+               fromIndex = 0;
+       }
+       else if (fromIndex >= count) {
+               // Note: fromIndex might be near -1>>>1.
+               return -1;
+       }
+
+       for (int32_t i = fromIndex ; i < count ; i++) {
+               if (LLNI_array_direct(value, offset + i) == ch) {
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+
+/*
+ * Class:     java/lang/String
+ * Method:    lastIndexOf
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_String_lastIndexOf__II(JNIEnv *env, jstring _this, jint ch, jint fromIndex)
+{
+       java_lang_String jls(_this);
+
+       java_handle_chararray_t* value = jls.get_value();
+       int32_t offset = jls.get_offset();
+       int32_t count  = jls.get_count();
+
+       int32_t start = ((fromIndex >= count) ? count - 1 : fromIndex);
+
+       for (int32_t i = start; i >= 0; i--) {
+               if (LLNI_array_direct(value, offset + i) == ch) {
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+
+/*
+ * Class:     java/lang/String
+ * Method:    lastIndexOf
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_String_lastIndexOf__I(JNIEnv *env, jstring _this, jint ch)
+{
+       java_lang_String jls(_this);
+       
+       return Java_java_lang_String_lastIndexOf__II(env, _this, ch, jls.get_count() - 1);
+}
+
+
+/*
+ * Class:     java/lang/String
+ * Method:    intern
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_String_intern(JNIEnv *env, jstring _this)
+{
+       java_lang_String jls(_this);
+
+       if (jls.is_null())
+               return NULL;
+
+       return (jstring) javastring_intern(jls.get_handle());
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "hashCode",    (char*) "()I",                    (void*) (uintptr_t) &Java_java_lang_String_hashCode        },
+       { (char*) "indexOf",     (char*) "(I)I",                   (void*) (uintptr_t) &Java_java_lang_String_indexOf__I      },
+       { (char*) "indexOf",     (char*) "(II)I",                  (void*) (uintptr_t) &Java_java_lang_String_indexOf__II     },
+       { (char*) "lastIndexOf", (char*) "(II)I",                  (void*) (uintptr_t) &Java_java_lang_String_lastIndexOf__II },
+       { (char*) "lastIndexOf", (char*) "(I)I",                   (void*) (uintptr_t) &Java_java_lang_String_lastIndexOf__I  },
+#if 0
+       { (char*) "equals",      (char*) "(Ljava/lang/Object;)Z;", (void*) (uintptr_t) &Java_java_lang_String_equals          },
+#endif
+       { (char*) "intern",      (char*) "()Ljava/lang/String;",   (void*) (uintptr_t) &Java_java_lang_String_intern          },
+};
+
+
+/* _Jv_java_lang_String_init ***************************************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" {
+void _Jv_java_lang_String_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/String");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_System.c b/src/native/vm/cldc1.1/java_lang_System.c
deleted file mode 100644 (file)
index 7a14f9e..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_System.c
-
-   Copyright (C) 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
-
-   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 "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-
-#include "native/include/java_lang_System.h"
-
-#include "vm/builtin.h"
-#include "vm/properties.h"
-#include "vm/stringlocal.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "arraycopy",    "(Ljava/lang/Object;ILjava/lang/Object;II)V", (void *) (ptrint) &Java_java_lang_System_arraycopy    },
-       { "getProperty0", "(Ljava/lang/String;)Ljava/lang/String;",     (void *) (ptrint) &Java_java_lang_System_getProperty0 },
-};
-
-
-/* _Jv_java_lang_System_init ***************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_System_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/System");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/System
- * Method:    arraycopy
- * Signature: (Ljava/lang/Object;ILjava/lang/Object;II)V
- */
-JNIEXPORT void JNICALL Java_java_lang_System_arraycopy(JNIEnv *env, jclass clazz, java_lang_Object *src, s4 srcStart, java_lang_Object *dest, s4 destStart, s4 len)
-{
-       builtin_arraycopy((java_handle_t *) src, srcStart,
-                                         (java_handle_t *) dest, destStart, len);
-}
-
-
-/*
- * Class:     java/lang/System
- * Method:    getProperty0
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
-
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_System_getProperty0(JNIEnv *env, jclass clazz, java_lang_String *s)
-{
-       java_handle_t *so;
-       char*          key;
-       char*          value;
-       java_handle_t *result;
-
-       so = (java_handle_t *) s;
-
-       /* build an ASCII string out of the java/lang/String passed */
-
-       key = javastring_tochar(so);
-
-       /* get the property from the internal table */
-
-       value = properties_get(key);
-
-       /* release the memory allocated in javastring_tochar */
-
-       MFREE(key, char, 0);
-
-       if (value == NULL)
-               return NULL;
-
-       result = javastring_new_from_ascii(value);
-
-       return (java_lang_String *) result;
-}
-
-
-/*
- * 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/native/vm/cldc1.1/java_lang_System.cpp b/src/native/vm/cldc1.1/java_lang_System.cpp
new file mode 100644 (file)
index 0000000..e334d9b
--- /dev/null
@@ -0,0 +1,136 @@
+/* src/native/vm/cldc1.1/java_lang_System.cpp
+
+   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 <stdint.h>
+#include <stdlib.h>
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_System.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/properties.h"
+#include "vm/string.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/System
+ * Method:    arraycopy
+ * Signature: (Ljava/lang/Object;ILjava/lang/Object;II)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_System_arraycopy(JNIEnv *env, jclass clazz, jobject src, jint srcStart, jobject dest, jint destStart, jint len)
+{
+       builtin_arraycopy((java_handle_t *) src, srcStart,
+                                         (java_handle_t *) dest, destStart, len);
+}
+
+
+/*
+ * Class:     java/lang/System
+ * Method:    getProperty0
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+
+JNIEXPORT jstring JNICALL Java_java_lang_System_getProperty0(JNIEnv *env, jclass clazz, jstring s)
+{
+       java_handle_t *so;
+       char*          key;
+       const char*    value;
+       java_handle_t *result;
+
+       so = (java_handle_t *) s;
+
+       /* build an ASCII string out of the java/lang/String passed */
+
+       key = javastring_tochar(so);
+
+       /* get the property from the internal table */
+
+       value = properties_get(key);
+
+       /* release the memory allocated in javastring_tochar */
+
+       MFREE(key, char, 0);
+
+       if (value == NULL)
+               return NULL;
+
+       result = javastring_new_from_ascii(value);
+
+       return (jstring) result;
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+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 },
+};
+
+
+/* _Jv_java_lang_System_init ***************************************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" {
+void _Jv_java_lang_System_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/System");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_Thread.c b/src/native/vm/cldc1.1/java_lang_Thread.c
deleted file mode 100644 (file)
index da9ffd0..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_Thread.c
-
-   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 <stdint.h>
-
-#include "vm/types.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Thread.h"
-
-#include "threads/thread.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/builtin.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "currentThread", "()Ljava/lang/Thread;", (void *) (ptrint) &Java_java_lang_Thread_currentThread },
-       { "setPriority0",  "(II)V",                (void *) (ptrint) &Java_java_lang_Thread_setPriority0  },
-       { "sleep",         "(J)V",                 (void *) (ptrint) &Java_java_lang_Thread_sleep         },
-       { "start0",        "()V",                  (void *) (ptrint) &Java_java_lang_Thread_start0        },
-       { "isAlive",       "()Z",                  (void *) (ptrint) &Java_java_lang_Thread_isAlive       },
-#if 0
-       { "activeCount",   "()I",                  (void *) (ptrint) &Java_java_lang_Thread_activeCount   },
-       { "setPriority0",  "(II)V",                (void *) (ptrint) &Java_java_lang_Thread_setPriority0  },
-       { "interrupt0",    "()V",                  (void *) (ptrint) &Java_java_lang_Thread_interrupt0    },
-       { "internalExit",  "()V",                  (void *) (ptrint) &Java_java_lang_Thread_internalExit  },
-#endif
-       { "yield",         "()V",                  (void *) (ptrint) &Java_java_lang_Thread_yield         },
-};
-
-
-/* _Jv_java_lang_Thread_init ***************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_Thread_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/Thread");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    currentThread
- * Signature: ()Ljava/lang/Thread;
- */
-JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_Thread_currentThread(JNIEnv *env, jclass clazz)
-{
-       java_lang_Thread *to;
-
-       to = (java_lang_Thread *) thread_get_current_object();
-
-       return to;
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    setPriority0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_lang_Thread_setPriority0(JNIEnv *env, java_lang_Thread *this, s4 oldPriority, s4 newPriority)
-{
-#if defined(ENABLE_THREADS)
-       threadobject *t;
-
-       t = (threadobject *) this->vm_thread;
-
-       /* The threadobject is null when a thread is created in Java. The
-          priority is set later during startup. */
-
-       if (t == NULL)
-               return;
-
-       threads_set_thread_priority(t->tid, newPriority);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    sleep
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_java_lang_Thread_sleep(JNIEnv *env, jclass clazz, s8 millis)
-{
-#if defined(ENABLE_THREADS)
-       threads_sleep(millis, 0);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    start0
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Thread_start0(JNIEnv *env, java_lang_Thread *this)
-{
-#if defined(ENABLE_THREADS)
-       threads_thread_start((java_handle_t *) this);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    isAlive
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_Thread_isAlive(JNIEnv *env, java_lang_Thread *this)
-{
-#if defined(ENABLE_THREADS)
-       threadobject *t;
-       bool          result;
-
-       t = (threadobject *) this->vm_thread;
-
-       if (t == NULL)
-               return 0;
-
-       result = threads_thread_is_alive(t);
-
-       return result;
-#else
-       /* If threads are disabled, the only thread running is alive. */
-
-       return 1;
-#endif
-}
-
-
-#if 0
-/*
- * Class:     java/lang/Thread
- * Method:    activeCount
- * Signature: ()I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_Thread_activeCount(JNIEnv *env, jclass clazz)
-{
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    setPriority0
- * Signature: (II)V
- */
-JNIEXPORT void JNICALL Java_java_lang_Thread_setPriority0(JNIEnv *env, struct java_lang_Thread* this, s4 par1, s4 par2)
-{
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    interrupt0
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Thread_interrupt0(JNIEnv *env, struct java_lang_Thread* this)
-{
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    internalExit
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Thread_internalExit(JNIEnv *env, struct java_lang_Thread* this)
-{
-}
-#endif
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    yield
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Thread_yield(JNIEnv *env, jclass clazz)
-{
-#if defined(ENABLE_THREADS)
-       threads_yield();
-#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/native/vm/cldc1.1/java_lang_Thread.cpp b/src/native/vm/cldc1.1/java_lang_Thread.cpp
new file mode 100644 (file)
index 0000000..5ee1120
--- /dev/null
@@ -0,0 +1,227 @@
+/* src/native/vm/cldc1.1/java_lang_Thread.cpp
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_Thread.h"
+#endif
+
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
+#include "vm/javaobjects.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/Thread
+ * Method:    currentThread
+ * Signature: ()Ljava/lang/Thread;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_Thread_currentThread(JNIEnv *env, jclass clazz)
+{
+       return (jobject) thread_get_current_object();
+}
+
+
+/*
+ * Class:     java/lang/Thread
+ * Method:    setPriority0
+ * Signature: (II)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_setPriority0(JNIEnv *env, jobject _this, jint oldPriority, jint newPriority)
+{
+#if defined(ENABLE_THREADS)
+       java_lang_Thread jlt(_this);
+       threadobject* t = jlt.get_vm_thread();
+
+       // The threadobject is null when a thread is created in Java. The
+       // priority is set later during startup.
+       if (t == NULL)
+               return;
+
+       threads_set_thread_priority(t->tid, newPriority);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/Thread
+ * Method:    sleep
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_sleep(JNIEnv *env, jclass clazz, jlong millis)
+{
+#if defined(ENABLE_THREADS)
+       threads_sleep(millis, 0);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/Thread
+ * Method:    start0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_start0(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       java_lang_Thread jlt(_this);
+       threads_thread_start(jlt.get_handle());
+#endif
+}
+
+
+/*
+ * Class:     java/lang/Thread
+ * Method:    isAlive
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_Thread_isAlive(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       java_lang_Thread jlt(_this);
+       threadobject* t = jlt.get_vm_thread();
+
+       if (t == NULL)
+               return 0;
+
+       bool result = threads_thread_is_alive(t);
+
+       return result;
+#else
+       // If threads are disabled, the only thread running is alive.
+       return 1;
+#endif
+}
+
+
+#if 0
+/*
+ * Class:     java/lang/Thread
+ * Method:    activeCount
+ * Signature: ()I
+ */
+JNIEXPORT s4 JNICALL Java_java_lang_Thread_activeCount(JNIEnv *env, jclass clazz)
+{
+}
+
+
+/*
+ * Class:     java/lang/Thread
+ * Method:    interrupt0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_interrupt0(JNIEnv *env, jobject _this)
+{
+}
+
+
+/*
+ * Class:     java/lang/Thread
+ * Method:    internalExit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_internalExit(JNIEnv *env, jobject _this)
+{
+}
+#endif
+
+
+/*
+ * Class:     java/lang/Thread
+ * Method:    yield
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Thread_yield(JNIEnv *env, jclass clazz)
+{
+#if defined(ENABLE_THREADS)
+       threads_yield();
+#endif
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "currentThread", (char*) "()Ljava/lang/Thread;", (void*) (uintptr_t) &Java_java_lang_Thread_currentThread },
+       { (char*) "setPriority0",  (char*) "(II)V",                (void*) (uintptr_t) &Java_java_lang_Thread_setPriority0  },
+       { (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    },
+       { (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         },
+};
+
+
+/* _Jv_java_lang_Thread_init ***************************************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" {
+void _Jv_java_lang_Thread_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/Thread");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/cldc1.1/java_lang_Throwable.c b/src/native/vm/cldc1.1/java_lang_Throwable.c
deleted file mode 100644 (file)
index 35885d1..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/* src/native/vm/cldc1.1/java_lang_Throwable.c - java/lang/Throwable
-
-   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/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Throwable.h"
-
-#include "vm/exceptions.h"
-#include "vm/jit/stacktrace.h"
-
-
-/* native methods implemented by this file ************************************/
-static JNINativeMethod methods[] = {
-       { "printStackTrace",  "()V", (void *) (uintptr_t) &Java_java_lang_Throwable_printStackTrace  },
-       { "fillInStackTrace", "()V", (void *) (uintptr_t) &Java_java_lang_Throwable_fillInStackTrace },
-};
-
-
-/* _Jv_java_lang_Throwable_init ************************************************
-   Register native functions.
-*******************************************************************************/
-void _Jv_java_lang_Throwable_init(void)
-{
-       utf *u;
-       u = utf_new_char("java/lang/Throwable");
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/Throwable
- * Method:    printStackTrace
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Throwable_printStackTrace(JNIEnv *env, java_lang_Throwable *this)
-{
-       java_handle_t *o;
-
-       o = (java_handle_t *) this;
-
-       exceptions_print_exception(o);
-       stacktrace_print_exception(o);
-}
-
-
-/*
- * Class:     java/lang/Throwable
- * Method:    fillInStackTrace
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_Throwable_fillInStackTrace(JNIEnv *env, java_lang_Throwable *this)
-{
-       java_handle_bytearray_t *ba;
-
-       ba = stacktrace_get_current();
-
-       if (ba == NULL)
-               return;
-
-       LLNI_field_set_ref(this, backtrace, (java_lang_Object *) ba);
-}
-
-
-/*
- * 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/native/vm/cldc1.1/java_lang_Throwable.cpp b/src/native/vm/cldc1.1/java_lang_Throwable.cpp
new file mode 100644 (file)
index 0000000..10993c0
--- /dev/null
@@ -0,0 +1,119 @@
+/* src/native/vm/cldc1.1/java_lang_Throwable.cpp
+
+   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/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_lang_Throwable.h"
+#endif
+
+#include "vm/exceptions.hpp"
+#include "vm/javaobjects.hpp"
+
+#include "vm/jit/stacktrace.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/Throwable
+ * Method:    printStackTrace
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Throwable_printStackTrace(JNIEnv *env, jobject _this)
+{
+       java_lang_Throwable jlt(_this);
+
+       exceptions_print_exception(jlt.get_handle());
+       stacktrace_print_exception(jlt.get_handle());
+}
+
+
+/*
+ * Class:     java/lang/Throwable
+ * Method:    fillInStackTrace
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_Throwable_fillInStackTrace(JNIEnv *env, jobject _this)
+{
+       java_handle_bytearray_t* ba = stacktrace_get_current();
+
+       if (ba == NULL)
+               return;
+
+       java_lang_Throwable jlt(_this);
+       jlt.set_backtrace(ba);
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+static JNINativeMethod methods[] = {
+       { (char*) "printStackTrace",  (char*) "()V", (void*) (uintptr_t) &Java_java_lang_Throwable_printStackTrace  },
+       { (char*) "fillInStackTrace", (char*) "()V", (void*) (uintptr_t) &Java_java_lang_Throwable_fillInStackTrace },
+};
+
+
+/* _Jv_java_lang_Throwable_init ************************************************
+   Register native functions.
+*******************************************************************************/
+// FIXME
+extern "C" {
+void _Jv_java_lang_Throwable_init(void)
+{
+       utf *u;
+       u = utf_new_char("java/lang/Throwable");
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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 219f88d5ea8bcba0284f962f6f308d410c3e3319..c592f30773618a11a665b5ef65b07b27339e5eda 100644 (file)
@@ -1,4 +1,4 @@
-## src/native/vm/gnu/Makefile.am
+## src/native/vm/gnuclasspath/Makefile.am
 ##
 ## Copyright (C) 1996-2005, 2006, 2008
 ## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
@@ -35,32 +35,32 @@ endif
 
 if ENABLE_ANNOTATIONS
 SUN_REFLECT_SOURCES = \
-       sun_reflect_ConstantPool.c
+       sun_reflect_ConstantPool.cpp
 endif
 
 libnativevmcore_la_SOURCES = \
-       gnu_classpath_VMStackWalker.c \
-       gnu_classpath_VMSystemProperties.c \
-       gnu_java_lang_VMCPStringBuilder.c \
-       gnu_java_lang_management_VMClassLoadingMXBeanImpl.c \
-       gnu_java_lang_management_VMMemoryMXBeanImpl.c \
-       gnu_java_lang_management_VMRuntimeMXBeanImpl.c \
-       gnu_java_lang_management_VMThreadMXBeanImpl.c \
-       java_lang_VMClass.c \
-       java_lang_VMClassLoader.c \
-       java_lang_VMObject.c \
-       java_lang_VMRuntime.c \
-       java_lang_VMString.c \
-       java_lang_VMSystem.c \
-       java_lang_VMThread.c \
-       java_lang_VMThrowable.c \
+       gnu_classpath_VMStackWalker.cpp \
+       gnu_classpath_VMSystemProperties.cpp \
+       gnu_java_lang_VMCPStringBuilder.cpp \
+       gnu_java_lang_management_VMClassLoadingMXBeanImpl.cpp \
+       gnu_java_lang_management_VMMemoryMXBeanImpl.cpp \
+       gnu_java_lang_management_VMRuntimeMXBeanImpl.cpp \
+       gnu_java_lang_management_VMThreadMXBeanImpl.cpp \
+       java_lang_VMClass.cpp \
+       java_lang_VMClassLoader.cpp \
+       java_lang_VMObject.cpp \
+       java_lang_VMRuntime.cpp \
+       java_lang_VMString.cpp \
+       java_lang_VMSystem.cpp \
+       java_lang_VMThread.cpp \
+       java_lang_VMThrowable.cpp \
        java_lang_management_VMManagementFactory.c \
-       java_lang_reflect_VMConstructor.c \
-       java_lang_reflect_VMField.c \
-       java_lang_reflect_VMMethod.c \
+       java_lang_reflect_VMConstructor.cpp \
+       java_lang_reflect_VMField.cpp \
+       java_lang_reflect_VMMethod.cpp \
        java_lang_reflect_VMProxy.c \
-       java_security_VMAccessController.c \
-       java_util_concurrent_atomic_AtomicLong.c \
+       java_security_VMAccessController.cpp \
+       java_util_concurrent_atomic_AtomicLong.cpp \
        $(SUN_REFLECT_SOURCES)
 
 if ENABLE_JVMTI
diff --git a/src/native/vm/gnuclasspath/gnu_classpath_VMStackWalker.c b/src/native/vm/gnuclasspath/gnu_classpath_VMStackWalker.c
deleted file mode 100644 (file)
index eca8f53..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/* src/native/vm/gnu/gnu_classpath_VMStackWalker.c
-
-   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 "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_ClassLoader.h"
-
-#include "native/include/gnu_classpath_VMStackWalker.h"
-
-#include "vm/global.h"
-
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getClassContext",         "()[Ljava/lang/Class;",      (void *) (ptrint) &Java_gnu_classpath_VMStackWalker_getClassContext         },
-       { "getCallingClass",         "()Ljava/lang/Class;",       (void *) (ptrint) &Java_gnu_classpath_VMStackWalker_getCallingClass         },
-       { "getCallingClassLoader",   "()Ljava/lang/ClassLoader;", (void *) (ptrint) &Java_gnu_classpath_VMStackWalker_getCallingClassLoader   },
-       { "firstNonNullClassLoader", "()Ljava/lang/ClassLoader;", (void *) (ptrint) &Java_gnu_classpath_VMStackWalker_firstNonNullClassLoader },
-};
-
-
-/* _Jv_gnu_classpath_VMStackWalker_init ****************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_gnu_classpath_VMStackWalker_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("gnu/classpath/VMStackWalker");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     gnu/classpath/VMStackWalker
- * Method:    getClassContext
- * Signature: ()[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_gnu_classpath_VMStackWalker_getClassContext(JNIEnv *env, jclass clazz)
-{
-       java_handle_objectarray_t *oa;
-
-       oa = stacktrace_getClassContext();
-
-       return oa;
-}
-
-
-/*
- * Class:     gnu/classpath/VMStackWalker
- * Method:    getCallingClass
- * Signature: ()Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_gnu_classpath_VMStackWalker_getCallingClass(JNIEnv *env, jclass clazz)
-{
-       classinfo *c;
-
-       c = stacktrace_get_caller_class(2);
-
-       return (java_lang_Class *) c;
-}
-
-
-/*
- * Class:     gnu/classpath/VMStackWalker
- * Method:    getCallingClassLoader
- * Signature: ()Ljava/lang/ClassLoader;
- */
-JNIEXPORT java_lang_ClassLoader* JNICALL Java_gnu_classpath_VMStackWalker_getCallingClassLoader(JNIEnv *env, jclass clazz)
-{
-       classinfo     *c;
-       classloader_t *cl;
-
-       c  = stacktrace_get_caller_class(2);
-       cl = class_get_classloader(c);
-
-       return (java_lang_ClassLoader *) cl;
-}
-
-
-/*
- * Class:     gnu/classpath/VMStackWalker
- * Method:    firstNonNullClassLoader
- * Signature: ()Ljava/lang/ClassLoader;
- */
-JNIEXPORT java_lang_ClassLoader* JNICALL Java_gnu_classpath_VMStackWalker_firstNonNullClassLoader(JNIEnv *env, jclass clazz)
-{
-       classloader_t *cl;
-
-       cl = stacktrace_first_nonnull_classloader();
-
-       return (java_lang_ClassLoader *) cl;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/gnu_classpath_VMStackWalker.cpp b/src/native/vm/gnuclasspath/gnu_classpath_VMStackWalker.cpp
new file mode 100644 (file)
index 0000000..ee0646a
--- /dev/null
@@ -0,0 +1,152 @@
+/* src/native/vm/gnuclasspath/gnu_classpath_VMStackWalker.cpp
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/gnu_classpath_VMStackWalker.h"
+#endif
+
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/utf8.h"
+
+#include "vm/jit/stacktrace.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     gnu/classpath/VMStackWalker
+ * Method:    getClassContext
+ * Signature: ()[Ljava/lang/Class;
+ */
+JNIEXPORT jobjectArray JNICALL Java_gnu_classpath_VMStackWalker_getClassContext(JNIEnv *env, jclass clazz)
+{
+       java_handle_objectarray_t *oa;
+
+       oa = stacktrace_getClassContext();
+
+       return (jobjectArray) oa;
+}
+
+
+/*
+ * Class:     gnu/classpath/VMStackWalker
+ * Method:    getCallingClass
+ * Signature: ()Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_gnu_classpath_VMStackWalker_getCallingClass(JNIEnv *env, jclass clazz)
+{
+       classinfo *c;
+
+       c = stacktrace_get_caller_class(2);
+
+       return (jclass) c;
+}
+
+
+/*
+ * Class:     gnu/classpath/VMStackWalker
+ * Method:    getCallingClassLoader
+ * Signature: ()Ljava/lang/ClassLoader;
+ */
+JNIEXPORT jobject JNICALL Java_gnu_classpath_VMStackWalker_getCallingClassLoader(JNIEnv *env, jclass clazz)
+{
+       classinfo     *c;
+       classloader_t *cl;
+
+       c  = stacktrace_get_caller_class(2);
+       cl = class_get_classloader(c);
+
+       return (jobject) cl;
+}
+
+
+/*
+ * Class:     gnu/classpath/VMStackWalker
+ * Method:    firstNonNullClassLoader
+ * Signature: ()Ljava/lang/ClassLoader;
+ */
+JNIEXPORT jobject JNICALL Java_gnu_classpath_VMStackWalker_firstNonNullClassLoader(JNIEnv *env, jclass clazz)
+{
+       classloader_t *cl;
+
+       cl = stacktrace_first_nonnull_classloader();
+
+       return (jobject) cl;
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getClassContext",         (char*) "()[Ljava/lang/Class;",      (void*) (uintptr_t) &Java_gnu_classpath_VMStackWalker_getClassContext         },
+       { (char*) "getCallingClass",         (char*) "()Ljava/lang/Class;",       (void*) (uintptr_t) &Java_gnu_classpath_VMStackWalker_getCallingClass         },
+       { (char*) "getCallingClassLoader",   (char*) "()Ljava/lang/ClassLoader;", (void*) (uintptr_t) &Java_gnu_classpath_VMStackWalker_getCallingClassLoader   },
+       { (char*) "firstNonNullClassLoader", (char*) "()Ljava/lang/ClassLoader;", (void*) (uintptr_t) &Java_gnu_classpath_VMStackWalker_firstNonNullClassLoader },
+};
+
+
+/* _Jv_gnu_classpath_VMStackWalker_init ****************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_gnu_classpath_VMStackWalker_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("gnu/classpath/VMStackWalker");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/gnu_classpath_VMSystemProperties.c b/src/native/vm/gnuclasspath/gnu_classpath_VMSystemProperties.c
deleted file mode 100644 (file)
index 5517c6c..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/* src/native/vm/gnu/gnu_classpath_VMSystemProperties.c
-
-   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 <string.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_util_Properties.h"
-
-#include "native/include/gnu_classpath_VMSystemProperties.h"
-
-#include "vm/exceptions.h"
-#include "vm/properties.h"
-#include "vm/vm.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "preInit",  "(Ljava/util/Properties;)V", (void *) (ptrint) &Java_gnu_classpath_VMSystemProperties_preInit  },
-       { "postInit", "(Ljava/util/Properties;)V", (void *) (ptrint) &Java_gnu_classpath_VMSystemProperties_postInit },
-};
-
-
-/* _Jv_gnu_classpat_VMSystemProperties_init ************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_gnu_classpath_VMSystemProperties_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("gnu/classpath/VMSystemProperties");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     gnu/classpath/VMSystemProperties
- * Method:    preInit
- * Signature: (Ljava/util/Properties;)V
- */
-JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_preInit(JNIEnv *env, jclass clazz, java_util_Properties *properties)
-{
-       java_handle_t *p;
-
-       p = (java_handle_t *) properties;
-
-       if (p == NULL) {
-               exceptions_throw_nullpointerexception();
-               return;
-       }
-
-       /* fill the java.util.Properties object */
-
-       properties_system_add_all(p);
-}
-
-
-/*
- * Class:     gnu/classpath/VMSystemProperties
- * Method:    postInit
- * Signature: (Ljava/util/Properties;)V
- */
-JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_postInit(JNIEnv *env, jclass clazz, java_util_Properties *properties)
-{
-       java_handle_t *p;
-#if defined(ENABLE_JRE_LAYOUT)
-       char *java_home;
-       char *path;
-       s4    len;
-#endif
-
-       p = (java_handle_t *) properties;
-
-       if (p == NULL) {
-               exceptions_throw_nullpointerexception();
-               return;
-       }
-
-       /* post-set some properties */
-
-#if defined(ENABLE_JRE_LAYOUT)
-       /* XXX when we do it that way, we can't set these properties on
-          commandline */
-
-       java_home = properties_get("java.home");
-
-       properties_system_add(p, "gnu.classpath.home", java_home);
-
-       len =
-               strlen("file://") +
-               strlen(java_home) +
-               strlen("/lib") +
-               strlen("0");
-
-       path = MNEW(char, len);
-
-       strcpy(path, "file://");
-       strcat(path, java_home);
-       strcat(path, "/lib");
-
-       properties_system_add(p, "gnu.classpath.home.url", path);
-
-       MFREE(path, char, len);
-#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/native/vm/gnuclasspath/gnu_classpath_VMSystemProperties.cpp b/src/native/vm/gnuclasspath/gnu_classpath_VMSystemProperties.cpp
new file mode 100644 (file)
index 0000000..ebd09b0
--- /dev/null
@@ -0,0 +1,162 @@
+/* src/native/vm/gnuclasspath/gnu_classpath_VMSystemProperties.cpp
+
+   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 <string.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/gnu_classpath_VMSystemProperties.h"
+#endif
+
+#include "vm/exceptions.hpp"
+#include "vm/properties.h"
+#include "vm/vm.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     gnu/classpath/VMSystemProperties
+ * Method:    preInit
+ * Signature: (Ljava/util/Properties;)V
+ */
+JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_preInit(JNIEnv *env, jclass clazz, jobject properties)
+{
+       java_handle_t *p;
+
+       p = (java_handle_t *) properties;
+
+       if (p == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
+       /* fill the java.util.Properties object */
+
+       properties_system_add_all(p);
+}
+
+
+/*
+ * Class:     gnu/classpath/VMSystemProperties
+ * Method:    postInit
+ * Signature: (Ljava/util/Properties;)V
+ */
+JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_postInit(JNIEnv *env, jclass clazz, jobject properties)
+{
+       java_handle_t *p;
+#if defined(ENABLE_JRE_LAYOUT)
+       const char *java_home;
+       char *path;
+       s4    len;
+#endif
+
+       p = (java_handle_t *) properties;
+
+       if (p == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
+       /* post-set some properties */
+
+#if defined(ENABLE_JRE_LAYOUT)
+       /* XXX when we do it that way, we can't set these properties on
+          commandline */
+
+       java_home = properties_get("java.home");
+
+       properties_system_add(p, "gnu.classpath.home", java_home);
+
+       len =
+               strlen("file://") +
+               strlen(java_home) +
+               strlen("/lib") +
+               strlen("0");
+
+       path = MNEW(char, len);
+
+       strcpy(path, "file://");
+       strcat(path, java_home);
+       strcat(path, "/lib");
+
+       properties_system_add(p, "gnu.classpath.home.url", path);
+
+       MFREE(path, char, len);
+#endif
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "preInit",  (char*) "(Ljava/util/Properties;)V", (void*) (uintptr_t) &Java_gnu_classpath_VMSystemProperties_preInit  },
+       { (char*) "postInit", (char*) "(Ljava/util/Properties;)V", (void*) (uintptr_t) &Java_gnu_classpath_VMSystemProperties_postInit },
+};
+
+
+/* _Jv_gnu_classpat_VMSystemProperties_init ************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_gnu_classpath_VMSystemProperties_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("gnu/classpath/VMSystemProperties");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/gnu_java_lang_VMCPStringBuilder.c b/src/native/vm/gnuclasspath/gnu_java_lang_VMCPStringBuilder.c
deleted file mode 100644 (file)
index 0511085..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/* src/native/vm/gnu/java_lang_reflect_VMConstructor.c
-
-   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 <stdint.h>
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_String.h"
-
-#include "native/include/gnu_java_lang_VMCPStringBuilder.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "toString", "([CII)Ljava/lang/String;", (void *) (intptr_t) &Java_gnu_java_lang_VMCPStringBuilder_toString },
-};
-
-
-/* _Jv_gnu_java_lang_VMCPStringBuilder *****************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_gnu_java_lang_VMCPStringBuilder_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("gnu/java/lang/VMCPStringBuilder");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     gnu/java/lang/VMCPStringBuilder
- * Method:    toString
- * Signature: ([CII)Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_gnu_java_lang_VMCPStringBuilder_toString(JNIEnv *env, jclass clazz, java_handle_chararray_t *value, int32_t startIndex, int32_t count)
-{
-       int32_t          length;
-       java_handle_t    *o;
-       java_lang_String *s;
-
-       /* This is a native version of
-          java.lang.String.<init>([CIIZ)Ljava/lang/String; */
-
-    if (startIndex < 0) {
-/*             exceptions_throw_stringindexoutofboundsexception("offset: " + offset); */
-               exceptions_throw_stringindexoutofboundsexception();
-               return NULL;
-       }
-
-    if (count < 0) {
-/*             exceptions_throw_stringindexoutofboundsexception("count: " + count); */
-               exceptions_throw_stringindexoutofboundsexception();
-               return NULL;
-       }
-
-    /* equivalent to: offset + count < 0 || offset + count > data.length */
-
-       LLNI_CRITICAL_START;
-       length = LLNI_array_size(value);
-       LLNI_CRITICAL_END;
-
-    if (length - startIndex < count) {
-/*             exceptions_throw_stringindexoutofboundsexception("offset + count: " + (offset + count)); */
-               exceptions_throw_stringindexoutofboundsexception();
-               return NULL;
-       }
-
-       o = builtin_new(class_java_lang_String);
-
-       if (o == NULL)
-               return NULL;
-
-       s = (java_lang_String *) o;
-
-       LLNI_field_set_ref(s, value,  value);
-       LLNI_field_set_val(s, count,  count);
-       LLNI_field_set_val(s, offset, startIndex);
-
-       return s;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/gnu_java_lang_VMCPStringBuilder.cpp b/src/native/vm/gnuclasspath/gnu_java_lang_VMCPStringBuilder.cpp
new file mode 100644 (file)
index 0000000..1d4b014
--- /dev/null
@@ -0,0 +1,128 @@
+/* src/native/vm/gnuclasspath/gnu_java_lang_VMCPStringBuilder.cpp
+
+   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.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/gnu_java_lang_VMCPStringBuilder.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+
+
+/*
+ * Class:     gnu/java/lang/VMCPStringBuilder
+ * Method:    toString
+ * Signature: ([CII)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_gnu_java_lang_VMCPStringBuilder_toString(JNIEnv *env, jclass clazz, jcharArray value, jint startIndex, jint count)
+{
+       /* This is a native version of
+          java.lang.String.<init>([CIIZ)Ljava/lang/String; */
+
+    if (startIndex < 0) {
+/*             exceptions_throw_stringindexoutofboundsexception("offset: " + offset); */
+               exceptions_throw_stringindexoutofboundsexception();
+               return NULL;
+       }
+
+    if (count < 0) {
+/*             exceptions_throw_stringindexoutofboundsexception("count: " + count); */
+               exceptions_throw_stringindexoutofboundsexception();
+               return NULL;
+       }
+
+    /* equivalent to: offset + count < 0 || offset + count > data.length */
+
+       java_handle_chararray_t* ca = (java_handle_chararray_t*) value;
+
+       LLNI_CRITICAL_START;
+       int32_t length = LLNI_array_size(ca);
+       LLNI_CRITICAL_END;
+
+    if (length - startIndex < count) {
+/*             exceptions_throw_stringindexoutofboundsexception("offset + count: " + (offset + count)); */
+               exceptions_throw_stringindexoutofboundsexception();
+               return NULL;
+       }
+
+       java_handle_t* h = builtin_new(class_java_lang_String);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_String s(h, ca, (int32_t) count, (int32_t) startIndex);
+
+       return (jstring) s.get_handle();
+}
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "toString", (char*) "([CII)Ljava/lang/String;", (void*) (uintptr_t) &Java_gnu_java_lang_VMCPStringBuilder_toString },
+};
+
+
+/* _Jv_gnu_java_lang_VMCPStringBuilder *****************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_gnu_java_lang_VMCPStringBuilder_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("gnu/java/lang/VMCPStringBuilder");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/gnu_java_lang_management_VMClassLoadingMXBeanImpl.c b/src/native/vm/gnuclasspath/gnu_java_lang_management_VMClassLoadingMXBeanImpl.c
deleted file mode 100644 (file)
index ce3b6b4..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* src/native/vm/gnu/gnu_java_lang_management_VMClassLoadingMXBeanImpl.c
-
-   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
-
-   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 <stdint.h>
-
-#include "mm/gc-common.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/gnu_java_lang_management_VMClassLoadingMXBeanImpl.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/vm.h"
-
-#include "vmcore/classcache.h"
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getLoadedClassCount",   "()I",  (void *) (intptr_t) &Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getLoadedClassCount   },
-       { "getUnloadedClassCount", "()J",  (void *) (intptr_t) &Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getUnloadedClassCount },
-       { "isVerbose",             "()Z",  (void *) (intptr_t) &Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_isVerbose             },
-       { "setVerbose",            "(Z)V", (void *) (intptr_t) &Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_setVerbose            },
-};
-
-
-/* _Jv_gnu_java_lang_management_VMClassLoadingMXBeanImpl_init ******************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_gnu_java_lang_management_VMClassLoadingMXBeanImpl_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("gnu/java/lang/management/VMClassLoadingMXBeanImpl");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
- * Method:    getLoadedClassCount
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getLoadedClassCount(JNIEnv *env, jclass clazz)
-{
-       int32_t count;
-
-       count = classcache_get_loaded_class_count();
-
-       return count;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
- * Method:    getUnloadedClassCount
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getUnloadedClassCount(JNIEnv *env, jclass clazz)
-{
-       log_println("Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getUnloadedClassCount: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
- * Method:    isVerbose
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_isVerbose(JNIEnv *env, jclass clazz)
-{
-       return _Jv_jvm->Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_verbose;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
- * Method:    setVerbose
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_setVerbose(JNIEnv *env, jclass clazz, int32_t verbose)
-{
-       _Jv_jvm->Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_verbose = verbose;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/gnu_java_lang_management_VMClassLoadingMXBeanImpl.cpp b/src/native/vm/gnuclasspath/gnu_java_lang_management_VMClassLoadingMXBeanImpl.cpp
new file mode 100644 (file)
index 0000000..a6b0f3a
--- /dev/null
@@ -0,0 +1,146 @@
+/* src/native/vm/gnuclasspath/gnu_java_lang_management_VMClassLoadingMXBeanImpl.cpp
+
+   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 <stdint.h>
+
+#include "mm/gc.hpp"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/gnu_java_lang_management_VMClassLoadingMXBeanImpl.h"
+#endif
+
+#include "toolbox/logging.h"
+
+#include "vm/classcache.h"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
+ * Method:    getLoadedClassCount
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getLoadedClassCount(JNIEnv *env, jclass clazz)
+{
+       int32_t count;
+
+       count = classcache_get_loaded_class_count();
+
+       return count;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
+ * Method:    getUnloadedClassCount
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getUnloadedClassCount(JNIEnv *env, jclass clazz)
+{
+       log_println("Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getUnloadedClassCount: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
+ * Method:    isVerbose
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_isVerbose(JNIEnv *env, jclass clazz)
+{
+/*     return _Jv_jvm->Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_verbose; */
+#warning Move to C++
+       log_println("Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_isVerbose: MOVE TO C++!");
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
+ * Method:    setVerbose
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_setVerbose(JNIEnv *env, jclass clazz, jboolean verbose)
+{
+/*     _Jv_jvm->Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_verbose = verbose; */
+#warning Move to C++
+       log_println("Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_setVerbose: MOVE TO C++!");
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getLoadedClassCount",   (char*) "()I",  (void*) (uintptr_t) &Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getLoadedClassCount   },
+       { (char*) "getUnloadedClassCount", (char*) "()J",  (void*) (uintptr_t) &Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_getUnloadedClassCount },
+       { (char*) "isVerbose",             (char*) "()Z",  (void*) (uintptr_t) &Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_isVerbose             },
+       { (char*) "setVerbose",            (char*) "(Z)V", (void*) (uintptr_t) &Java_gnu_java_lang_management_VMClassLoadingMXBeanImpl_setVerbose            },
+};
+
+
+/* _Jv_gnu_java_lang_management_VMClassLoadingMXBeanImpl_init ******************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_gnu_java_lang_management_VMClassLoadingMXBeanImpl_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("gnu/java/lang/management/VMClassLoadingMXBeanImpl");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/gnu_java_lang_management_VMMemoryMXBeanImpl.c b/src/native/vm/gnuclasspath/gnu_java_lang_management_VMMemoryMXBeanImpl.c
deleted file mode 100644 (file)
index 4c05838..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/* src/native/vm/gnu/gnu_java_lang_management_VMMemoryMXBeanImpl.c
-
-   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 <stdint.h>
-
-#include "mm/gc-common.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_management_MemoryUsage.h"
-
-#include "native/include/gnu_java_lang_management_VMMemoryMXBeanImpl.h"
-
-#include "vm/builtin.h"
-#include "vm/global.h"
-#include "vm/vm.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"               /* XXX only for load_class_bootstrap */
-#include "vmcore/options.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getHeapMemoryUsage",                "()Ljava/lang/management/MemoryUsage;", (void *) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getHeapMemoryUsage                },
-       { "getNonHeapMemoryUsage",             "()Ljava/lang/management/MemoryUsage;", (void *) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage             },
-       { "getObjectPendingFinalizationCount", "()I",                                  (void *) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount },
-       { "isVerbose",                         "()Z",                                  (void *) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose                         },
-       { "setVerbose",                        "(Z)V",                                 (void *) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose                        },
-};
-
-
-/* _Jv_gnu_java_lang_management_VMMemoryMXBeanImpl_init ************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_gnu_java_lang_management_VMMemoryMXBeanImpl_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("gnu/java/lang/management/VMMemoryMXBeanImpl");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
- * Method:    getHeapMemoryUsage
- * Signature: ()Ljava/lang/management/MemoryUsage;
- */
-JNIEXPORT java_lang_management_MemoryUsage* JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getHeapMemoryUsage(JNIEnv *env, jclass clazz)
-{
-       classinfo                        *class_java_lang_management_MemoryUsage;
-       java_handle_t                    *o;
-       java_lang_management_MemoryUsage *mu;
-       methodinfo                       *m;
-       int64_t                           init;
-       int64_t                           used;
-       int64_t                           commited;
-       int64_t                           maximum;
-
-       /* get the class */
-       /* XXX optimize me! sometime... */
-
-       if (!(class_java_lang_management_MemoryUsage = load_class_bootstrap(utf_new_char("java/lang/management/MemoryUsage"))))
-               return false;
-
-       /* create the object */
-
-       o = builtin_new(class_java_lang_management_MemoryUsage);
-       
-       if (o == NULL)
-               return NULL;
-
-       /* cast the object to a MemoryUsage object (for debugability) */
-
-       mu = (java_lang_management_MemoryUsage *) o;
-
-       /* find initializer */
-
-       m = class_findmethod(class_java_lang_management_MemoryUsage,
-                                                utf_init, utf_new_char("(JJJJ)V"));
-                                                     
-       /* initializer not found */
-
-       if (m == NULL)
-               return NULL;
-
-       /* get values from the VM */
-       /* XXX if we ever support more than one VM, change this */
-
-       init     = opt_heapstartsize;
-       used     = gc_get_total_bytes();
-       commited = gc_get_heap_size();
-       maximum  = gc_get_max_heap_size();
-
-       /* call initializer */
-
-       (void) vm_call_method(m, o, init, used, commited, maximum);
-
-       return mu;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
- * Method:    getNonHeapMemoryUsage
- * Signature: ()Ljava/lang/management/MemoryUsage;
- */
-JNIEXPORT java_lang_management_MemoryUsage* JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage(JNIEnv *env, jclass clazz)
-{
-       log_println("Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
- * Method:    getObjectPendingFinalizationCount
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount(JNIEnv *env, jclass clazz)
-{
-       log_println("Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
- * Method:    isVerbose
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose(JNIEnv *env, jclass clazz)
-{
-       return _Jv_jvm->Java_gnu_java_lang_management_VMMemoryMXBeanImpl_verbose;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
- * Method:    setVerbose
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose(JNIEnv *env, jclass clazz, int32_t verbose)
-{
-       _Jv_jvm->Java_gnu_java_lang_management_VMMemoryMXBeanImpl_verbose = verbose;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/gnu_java_lang_management_VMMemoryMXBeanImpl.cpp b/src/native/vm/gnuclasspath/gnu_java_lang_management_VMMemoryMXBeanImpl.cpp
new file mode 100644 (file)
index 0000000..a48af39
--- /dev/null
@@ -0,0 +1,201 @@
+/* src/native/vm/gnuclasspath/gnu_java_lang_management_VMMemoryMXBeanImpl.cpp
+
+   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 <stdint.h>
+
+#include "mm/gc.hpp"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/gnu_java_lang_management_VMMemoryMXBeanImpl.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/loader.h"               /* XXX only for load_class_bootstrap */
+#include "vm/options.h"
+#include "vm/vm.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
+ * Method:    getHeapMemoryUsage
+ * Signature: ()Ljava/lang/management/MemoryUsage;
+ */
+JNIEXPORT jobject JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getHeapMemoryUsage(JNIEnv *env, jclass clazz)
+{
+       classinfo     *class_java_lang_management_MemoryUsage;
+       java_handle_t *o;
+       methodinfo    *m;
+       int64_t        init;
+       int64_t        used;
+       int64_t        commited;
+       int64_t        maximum;
+
+       /* get the class */
+       /* XXX optimize me! sometime... */
+
+       if (!(class_java_lang_management_MemoryUsage = load_class_bootstrap(utf_new_char("java/lang/management/MemoryUsage"))))
+               return false;
+
+       /* create the object */
+
+       o = builtin_new(class_java_lang_management_MemoryUsage);
+       
+       if (o == NULL)
+               return NULL;
+
+       /* find initializer */
+
+       m = class_findmethod(class_java_lang_management_MemoryUsage,
+                                                utf_init, utf_new_char("(JJJJ)V"));
+                                                     
+       /* initializer not found */
+
+       if (m == NULL)
+               return NULL;
+
+       /* get values from the VM */
+       /* XXX if we ever support more than one VM, change this */
+
+       init     = opt_heapstartsize;
+       used     = gc_get_total_bytes();
+       commited = gc_get_heap_size();
+       maximum  = gc_get_max_heap_size();
+
+       /* call initializer */
+
+       (void) vm_call_method(m, o, init, used, commited, maximum);
+
+       return (jobject) o;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
+ * Method:    getNonHeapMemoryUsage
+ * Signature: ()Ljava/lang/management/MemoryUsage;
+ */
+JNIEXPORT jobject JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage(JNIEnv *env, jclass clazz)
+{
+       log_println("Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
+ * Method:    getObjectPendingFinalizationCount
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount(JNIEnv *env, jclass clazz)
+{
+       log_println("Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
+ * Method:    isVerbose
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose(JNIEnv *env, jclass clazz)
+{
+/*     return _Jv_jvm->Java_gnu_java_lang_management_VMMemoryMXBeanImpl_verbose; */
+#warning Move to C++
+       log_println("Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose: MOVE TO C++!");
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
+ * Method:    setVerbose
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose(JNIEnv *env, jclass clazz, jboolean verbose)
+{
+/*     _Jv_jvm->Java_gnu_java_lang_management_VMMemoryMXBeanImpl_verbose = verbose; */
+#warning Move to C++
+       log_println("Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose: MOVE TO C++!");
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getHeapMemoryUsage",                (char*) "()Ljava/lang/management/MemoryUsage;", (void*) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getHeapMemoryUsage                },
+       { (char*) "getNonHeapMemoryUsage",             (char*) "()Ljava/lang/management/MemoryUsage;", (void*) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage             },
+       { (char*) "getObjectPendingFinalizationCount", (char*) "()I",                                  (void*) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount },
+       { (char*) "isVerbose",                         (char*) "()Z",                                  (void*) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose                         },
+       { (char*) "setVerbose",                        (char*) "(Z)V",                                 (void*) (uintptr_t) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose                        },
+};
+
+
+/* _Jv_gnu_java_lang_management_VMMemoryMXBeanImpl_init ************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_gnu_java_lang_management_VMMemoryMXBeanImpl_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("gnu/java/lang/management/VMMemoryMXBeanImpl");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/gnu_java_lang_management_VMRuntimeMXBeanImpl.c b/src/native/vm/gnuclasspath/gnu_java_lang_management_VMRuntimeMXBeanImpl.c
deleted file mode 100644 (file)
index cbd1e96..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* src/native/vm/gnu/gnu_java_lang_management_VMRuntimeMXBeanImpl.c
-
-   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
-
-   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 <stdint.h>
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/gnu_java_lang_management_VMRuntimeMXBeanImpl.h"
-
-#include "vm/builtin.h"
-#include "vm/global.h"
-#include "vm/vm.h"
-
-#include "vmcore/class.h"
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getInputArguments", "()[Ljava/lang/String;", (void *) (intptr_t) &Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments },
-       { "getStartTime",      "()J",                   (void *) (intptr_t) &Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getStartTime      },
-};
-
-
-/* _Jv_gnu_java_lang_management_VMRuntimeMXBeanImpl_init ***********************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_gnu_java_lang_management_VMRuntimeMXBeanImpl_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("gnu/java/lang/management/VMRuntimeMXBeanImpl");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMRuntimeMXBeanImpl
- * Method:    getInputArguments
- * Signature: ()[Ljava/lang/String;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments(JNIEnv *env, jclass clazz)
-{
-       log_println("Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments: IMPLEMENT ME!");
-
-       return builtin_anewarray(0, class_java_lang_String);
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMRuntimeMXBeanImpl
- * Method:    getStartTime
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getStartTime(JNIEnv *env, jclass clazz)
-{
-       return _Jv_jvm->starttime;
-}
-
-/*
- * 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/native/vm/gnuclasspath/gnu_java_lang_management_VMRuntimeMXBeanImpl.cpp b/src/native/vm/gnuclasspath/gnu_java_lang_management_VMRuntimeMXBeanImpl.cpp
new file mode 100644 (file)
index 0000000..2b9e3c4
--- /dev/null
@@ -0,0 +1,112 @@
+/* src/native/vm/gnuclasspath/gnu_java_lang_management_VMRuntimeMXBeanImpl.cpp
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/gnu_java_lang_management_VMRuntimeMXBeanImpl.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     gnu/java/lang/management/VMRuntimeMXBeanImpl
+ * Method:    getInputArguments
+ * Signature: ()[Ljava/lang/String;
+ */
+JNIEXPORT java_handle_objectarray_t* JNICALL Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments(JNIEnv *env, jclass clazz)
+{
+       log_println("Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments: IMPLEMENT ME!");
+
+       return builtin_anewarray(0, class_java_lang_String);
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMRuntimeMXBeanImpl
+ * Method:    getStartTime
+ * Signature: ()J
+ */
+JNIEXPORT int64_t JNICALL Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getStartTime(JNIEnv *env, jclass clazz)
+{
+       return vm->get_starttime();
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getInputArguments", (char*) "()[Ljava/lang/String;", (void*) (uintptr_t) &Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getInputArguments },
+       { (char*) "getStartTime",      (char*) "()J",                   (void*) (uintptr_t) &Java_gnu_java_lang_management_VMRuntimeMXBeanImpl_getStartTime      },
+};
+
+
+/* _Jv_gnu_java_lang_management_VMRuntimeMXBeanImpl_init ***********************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_gnu_java_lang_management_VMRuntimeMXBeanImpl_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("gnu/java/lang/management/VMRuntimeMXBeanImpl");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.c b/src/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.c
deleted file mode 100644 (file)
index 862ed07..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/* src/native/vm/gnu/gnu_java_lang_management_VMThreadMXBeanImpl.c
-
-   Copyright (C) 1996-2005, 2006 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
-
-   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 <stdint.h>
-
-#include "mm/gc-common.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Throwable.h"
-#include "native/include/java_lang_management_ThreadInfo.h"
-
-#include "native/include/gnu_java_lang_management_VMThreadMXBeanImpl.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/vm.h"
-
-#include "vmcore/classcache.h"
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "findMonitorDeadlockedThreads", "()[J",                                  (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_findMonitorDeadlockedThreads },
-       { "getCurrentThreadCpuTime",      "()J",                                   (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadCpuTime      },
-       { "getCurrentThreadUserTime",     "()J",                                   (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadUserTime     },
-       { "getPeakThreadCount",           "()I",                                   (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getPeakThreadCount           },
-       { "getThreadCpuTime",             "(J)J",                                  (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadCpuTime             },
-       { "getThreadInfoForId",           "(JI)Ljava/lang/management/ThreadInfo;", (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadInfoForId           },
-       { "getThreadUserTime",            "(J)J",                                  (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadUserTime            },
-       { "getTotalStartedThreadCount",   "()J",                                   (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getTotalStartedThreadCount   },
-       { "resetPeakThreadCount",         "()V",                                   (void *) (intptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_resetPeakThreadCount         },
-};
-
-
-/* _Jv_gnu_java_lang_management_VMThreadMXBeanImpl_init ************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_gnu_java_lang_management_VMThreadMXBeanImpl_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("gnu/java/lang/management/VMThreadMXBeanImpl");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    findMonitorDeadlockedThreads
- * Signature: ()[J
- */
-JNIEXPORT java_handle_longarray_t* JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_findMonitorDeadlockedThreads(JNIEnv *env, jclass clazz)
-{
-       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_findMonitorDeadlockedThreads: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    getCurrentThreadCpuTime
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadCpuTime(JNIEnv *env, jclass clazz)
-{
-       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadCpuTime: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    getCurrentThreadUserTime
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadUserTime(JNIEnv *env, jclass clazz)
-{
-       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadUserTime: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    getPeakThreadCount
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getPeakThreadCount(JNIEnv *env, jclass clazz)
-{
-       return _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    getThreadCpuTime
- * Signature: (J)J
- */
-JNIEXPORT int64_t JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadCpuTime(JNIEnv *env, jclass clazz, int64_t id)
-{
-       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadCpuTime: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    getThreadInfoForId
- * Signature: (JI)Ljava/lang/management/ThreadInfo;
- */
-JNIEXPORT java_lang_management_ThreadInfo* JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadInfoForId(JNIEnv *env, jclass clazz, int64_t id, int32_t maxDepth)
-{
-       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadInfoForId: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    getThreadUserTime
- * Signature: (J)J
- */
-JNIEXPORT int64_t JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadUserTime(JNIEnv *env, jclass clazz, int64_t par1)
-{
-       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadUserTime: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    getTotalStartedThreadCount
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getTotalStartedThreadCount(JNIEnv *env, jclass clazz)
-{
-       return _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount;
-}
-
-
-/*
- * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
- * Method:    resetPeakThreadCount
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_resetPeakThreadCount(JNIEnv *env, jclass clazz)
-{
-       _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
-               _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.cpp b/src/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.cpp
new file mode 100644 (file)
index 0000000..e8f3916
--- /dev/null
@@ -0,0 +1,217 @@
+/* src/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.cpp
+
+   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.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "mm/gc.hpp"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/gnu_java_lang_management_VMThreadMXBeanImpl.h"
+#endif
+
+#include "toolbox/logging.h"
+
+#include "vm/classcache.h"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    findMonitorDeadlockedThreads
+ * Signature: ()[J
+ */
+JNIEXPORT jlongArray JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_findMonitorDeadlockedThreads(JNIEnv *env, jclass clazz)
+{
+       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_findMonitorDeadlockedThreads: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    getCurrentThreadCpuTime
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadCpuTime(JNIEnv *env, jclass clazz)
+{
+       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadCpuTime: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    getCurrentThreadUserTime
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadUserTime(JNIEnv *env, jclass clazz)
+{
+       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadUserTime: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    getPeakThreadCount
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getPeakThreadCount(JNIEnv *env, jclass clazz)
+{
+/*     return _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount; */
+#warning Move to C++
+       log_println("Java_gnu_java_lang_management_ThreadMXBean_getPeakThreadCount: MOVE TO C++!");
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    getThreadCpuTime
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadCpuTime(JNIEnv *env, jclass clazz, jlong id)
+{
+       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadCpuTime: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    getThreadInfoForId
+ * Signature: (JI)Ljava/lang/management/ThreadInfo;
+ */
+JNIEXPORT jobject JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadInfoForId(JNIEnv *env, jclass clazz, jlong id, jint maxDepth)
+{
+       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadInfoForId: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    getThreadUserTime
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadUserTime(JNIEnv *env, jclass clazz, jlong par1)
+{
+       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadUserTime: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    getTotalStartedThreadCount
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_getTotalStartedThreadCount(JNIEnv *env, jclass clazz)
+{
+/*     return _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount; */
+#warning Move to C++
+       log_println("Java_gnu_java_lang_management_ThreadMXBean_getTotalStartedThreadCount: MOVE TO C++!");
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
+ * Method:    resetPeakThreadCount
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_gnu_java_lang_management_VMThreadMXBeanImpl_resetPeakThreadCount(JNIEnv *env, jclass clazz)
+{
+/*     _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
+/*             _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
+#warning Move to C++
+       log_println("Java_gnu_java_lang_management_VMThreadMXBeanImpl_resetPeakThreadCount: MOVE TO C++!");
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "findMonitorDeadlockedThreads", (char*) "()[J",                                  (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_findMonitorDeadlockedThreads },
+       { (char*) "getCurrentThreadCpuTime",      (char*) "()J",                                   (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadCpuTime      },
+       { (char*) "getCurrentThreadUserTime",     (char*) "()J",                                   (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getCurrentThreadUserTime     },
+       { (char*) "getPeakThreadCount",           (char*) "()I",                                   (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getPeakThreadCount           },
+       { (char*) "getThreadCpuTime",             (char*) "(J)J",                                  (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadCpuTime             },
+       { (char*) "getThreadInfoForId",           (char*) "(JI)Ljava/lang/management/ThreadInfo;", (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadInfoForId           },
+       { (char*) "getThreadUserTime",            (char*) "(J)J",                                  (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getThreadUserTime            },
+       { (char*) "getTotalStartedThreadCount",   (char*) "()J",                                   (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_getTotalStartedThreadCount   },
+       { (char*) "resetPeakThreadCount",         (char*) "()V",                                   (void*) (uintptr_t) &Java_gnu_java_lang_management_VMThreadMXBeanImpl_resetPeakThreadCount         },
+};
+
+
+/* _Jv_gnu_java_lang_management_VMThreadMXBeanImpl_init ************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_gnu_java_lang_management_VMThreadMXBeanImpl_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("gnu/java/lang/management/VMThreadMXBeanImpl");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_VMClass.c b/src/native/vm/gnuclasspath/java_lang_VMClass.c
deleted file mode 100644 (file)
index c61e4cc..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/* src/native/vm/gnuclasspath/java_lang_VMClass.c
-
-   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 <stdint.h>
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_ClassLoader.h"
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
-#include "native/include/java_lang_reflect_Constructor.h"
-#include "native/include/java_lang_reflect_Method.h"
-
-#include "native/include/java_lang_VMClass.h"
-
-#include "vm/exceptions.h"
-#include "vm/initialize.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/class.h"
-
-#if defined(ENABLE_ANNOTATIONS)
-#include "native/include/sun_reflect_ConstantPool.h"
-
-#include "vm/vm.h"
-
-#include "vmcore/annotation.h"
-#endif
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "isInstance",              "(Ljava/lang/Class;Ljava/lang/Object;)Z",                        (void *) (uintptr_t) &Java_java_lang_VMClass_isInstance              },
-       { "isAssignableFrom",        "(Ljava/lang/Class;Ljava/lang/Class;)Z",                         (void *) (uintptr_t) &Java_java_lang_VMClass_isAssignableFrom        },
-       { "isInterface",             "(Ljava/lang/Class;)Z",                                          (void *) (uintptr_t) &Java_java_lang_VMClass_isInterface             },
-       { "isPrimitive",             "(Ljava/lang/Class;)Z",                                          (void *) (uintptr_t) &Java_java_lang_VMClass_isPrimitive             },
-       { "getName",                 "(Ljava/lang/Class;)Ljava/lang/String;",                         (void *) (uintptr_t) &Java_java_lang_VMClass_getName                 },
-       { "getSuperclass",           "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void *) (uintptr_t) &Java_java_lang_VMClass_getSuperclass           },
-       { "getInterfaces",           "(Ljava/lang/Class;)[Ljava/lang/Class;",                         (void *) (uintptr_t) &Java_java_lang_VMClass_getInterfaces           },
-       { "getComponentType",        "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void *) (uintptr_t) &Java_java_lang_VMClass_getComponentType        },
-       { "getModifiers",            "(Ljava/lang/Class;Z)I",                                         (void *) (uintptr_t) &Java_java_lang_VMClass_getModifiers            },
-       { "getDeclaringClass",       "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void *) (uintptr_t) &Java_java_lang_VMClass_getDeclaringClass       },
-       { "getDeclaredClasses",      "(Ljava/lang/Class;Z)[Ljava/lang/Class;",                        (void *) (uintptr_t) &Java_java_lang_VMClass_getDeclaredClasses      },
-       { "getDeclaredFields",       "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;",                (void *) (uintptr_t) &Java_java_lang_VMClass_getDeclaredFields       },
-       { "getDeclaredMethods",      "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;",               (void *) (uintptr_t) &Java_java_lang_VMClass_getDeclaredMethods      },
-       { "getDeclaredConstructors", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;",          (void *) (uintptr_t) &Java_java_lang_VMClass_getDeclaredConstructors },
-       { "getClassLoader",          "(Ljava/lang/Class;)Ljava/lang/ClassLoader;",                    (void *) (uintptr_t) &Java_java_lang_VMClass_getClassLoader          },
-       { "forName",                 "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;", (void *) (uintptr_t) &Java_java_lang_VMClass_forName                 },
-       { "isArray",                 "(Ljava/lang/Class;)Z",                                          (void *) (uintptr_t) &Java_java_lang_VMClass_isArray                 },
-       { "throwException",          "(Ljava/lang/Throwable;)V",                                      (void *) (uintptr_t) &Java_java_lang_VMClass_throwException          },
-#if defined(ENABLE_ANNOTATIONS)
-       { "getDeclaredAnnotations",  "(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;",         (void *) (uintptr_t) &Java_java_lang_VMClass_getDeclaredAnnotations  },
-#endif
-       { "getEnclosingClass",       "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void *) (uintptr_t) &Java_java_lang_VMClass_getEnclosingClass       },
-       { "getEnclosingConstructor", "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;",            (void *) (uintptr_t) &Java_java_lang_VMClass_getEnclosingConstructor },
-       { "getEnclosingMethod",      "(Ljava/lang/Class;)Ljava/lang/reflect/Method;",                 (void *) (uintptr_t) &Java_java_lang_VMClass_getEnclosingMethod      },
-       { "getClassSignature",       "(Ljava/lang/Class;)Ljava/lang/String;",                         (void *) (uintptr_t) &Java_java_lang_VMClass_getClassSignature       },
-       { "isAnonymousClass",        "(Ljava/lang/Class;)Z",                                          (void *) (uintptr_t) &Java_java_lang_VMClass_isAnonymousClass        },
-       { "isLocalClass",            "(Ljava/lang/Class;)Z",                                          (void *) (uintptr_t) &Java_java_lang_VMClass_isLocalClass            },
-       { "isMemberClass",           "(Ljava/lang/Class;)Z",                                          (void *) (uintptr_t) &Java_java_lang_VMClass_isMemberClass           },
-};
-
-
-/* _Jv_java_lang_VMClass_init **************************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_VMClass_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/VMClass");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    isInstance
- * Signature: (Ljava/lang/Class;Ljava/lang/Object;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Object *o)
-{
-       classinfo     *c;
-       java_handle_t *h;
-
-       c = LLNI_classinfo_unwrap(klass);
-       h = (java_handle_t *) o;
-
-       return class_is_instance(c, h);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    isAssignableFrom
- * Signature: (Ljava/lang/Class;Ljava/lang/Class;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Class *c)
-{
-       classinfo *to;
-       classinfo *from;
-
-       to   = LLNI_classinfo_unwrap(klass);
-       from = LLNI_classinfo_unwrap(c);
-
-       if (from == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       return class_is_assignable_from(to, from);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    isInterface
- * Signature: (Ljava/lang/Class;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo *c;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       return class_is_interface(c);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    isPrimitive
- * Signature: (Ljava/lang/Class;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo *c;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       return class_is_primitive(c);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getName
- * Signature: (Ljava/lang/Class;)Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getName(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo* c;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       return (java_lang_String*) class_get_classname(c);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getSuperclass
- * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo *c;
-       classinfo *super;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       super = class_get_superclass(c);
-
-       return LLNI_classinfo_wrap(super);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getInterfaces
- * Signature: (Ljava/lang/Class;)[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       oa = class_get_interfaces(c);
-
-       return oa;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getComponentType
- * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo *c;
-       classinfo *component;
-       
-       c = LLNI_classinfo_unwrap(klass);
-       
-       component = class_get_componenttype(c);
-
-       return LLNI_classinfo_wrap(component);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getModifiers
- * Signature: (Ljava/lang/Class;Z)I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_getModifiers(JNIEnv *env, jclass clazz, java_lang_Class *klass, int32_t ignoreInnerClassesAttrib)
-{
-       classinfo *c;
-       int32_t    flags;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       flags = class_get_modifiers(c, ignoreInnerClassesAttrib);
-
-       return flags;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getDeclaringClass
- * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo *c;
-       classinfo *dc;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       dc = class_get_declaringclass(c);
-
-       return LLNI_classinfo_wrap(dc);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getDeclaredClasses
- * Signature: (Ljava/lang/Class;Z)[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JNIEnv *env, jclass clazz, java_lang_Class *klass, int32_t publicOnly)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       oa = class_get_declaredclasses(c, publicOnly);
-
-       return oa;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getDeclaredFields
- * Signature: (Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredFields(JNIEnv *env, jclass clazz, java_lang_Class *klass, int32_t publicOnly)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       oa = class_get_declaredfields(c, publicOnly);
-
-       return oa;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getDeclaredMethods
- * Signature: (Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JNIEnv *env, jclass clazz, java_lang_Class *klass, int32_t publicOnly)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       oa = class_get_declaredmethods(c, publicOnly);
-
-       return oa;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getDeclaredConstructors
- * Signature: (Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz, java_lang_Class *klass, int32_t publicOnly)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       oa = class_get_declaredconstructors(c, publicOnly);
-
-       return oa;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getClassLoader
- * Signature: (Ljava/lang/Class;)Ljava/lang/ClassLoader;
- */
-JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo     *c;
-       classloader_t *cl;
-
-       c  = LLNI_classinfo_unwrap(klass);
-       cl = class_get_classloader(c);
-
-       return (java_lang_ClassLoader *) cl;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    forName
- * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, java_lang_String *name, int32_t initialize, java_lang_ClassLoader *loader)
-{
-       classloader_t *cl;
-       utf           *ufile;
-       utf           *uname;
-       classinfo     *c;
-       u2            *pos;
-       int32_t        i;
-
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-
-       /* illegal argument */
-
-       if (name == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* create utf string in which '.' is replaced by '/' */
-
-       ufile = javastring_toutf((java_handle_t *) name, true);
-       uname = javastring_toutf((java_handle_t *) name, false);
-
-       /* name must not contain '/' (mauve test) */
-
-       for (i = 0, pos = LLNI_field_direct(name, value)->data + LLNI_field_direct(name, offset); i < LLNI_field_direct(name, count); i++, pos++) {
-               if (*pos == '/') {
-                       exceptions_throw_classnotfoundexception(uname);
-                       return NULL;
-               }
-       }
-
-       /* try to load, ... */
-
-       c = load_class_from_classloader(ufile, cl);
-
-       if (c == NULL)
-           return NULL;
-
-       /* link, ... */
-
-       if (!link_class(c))
-               return NULL;
-       
-       /* ...and initialize it, if required */
-
-       if (initialize)
-               if (!initialize_class(c))
-                       return NULL;
-
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    isArray
- * Signature: (Ljava/lang/Class;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo *c;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       return class_is_array(c);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    throwException
- * Signature: (Ljava/lang/Throwable;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
-{
-       java_handle_t *o;
-
-       o = (java_handle_t *) t;
-
-       exceptions_set_exception(o);
-}
-
-
-#if defined(ENABLE_ANNOTATIONS)
-/*
- * Class:     java/lang/VMClass
- * Method:    getDeclaredAnnotations
- * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredAnnotations(JNIEnv *env, jclass clazz, java_lang_Class* klass)
-{
-       classinfo                *c               = NULL; /* classinfo for the java.lang.Class object 'klass'       */
-       static methodinfo        *m_parseAnnotationsIntoArray   = NULL; /* parser method (cached, therefore static) */
-       utf                      *utf_parseAnnotationsIntoArray = NULL; /* parser method name     */
-       utf                      *utf_desc        = NULL;               /* parser method descriptor (signature)     */
-       java_handle_bytearray_t  *annotations     = NULL;               /* unparsed annotations   */
-       sun_reflect_ConstantPool *constantPool    = NULL;               /* constant pool of klass */
-       java_lang_Object         *constantPoolOop = (java_lang_Object*)klass; /* constantPoolOop field of */
-                                                                             /* sun.reflect.ConstantPool */
-
-       if (klass == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-       
-       c = LLNI_classinfo_unwrap(klass);
-
-       /* get annotations: */
-       annotations = class_get_annotations(c);
-
-       constantPool = 
-               (sun_reflect_ConstantPool*)native_new_and_init(
-                       class_sun_reflect_ConstantPool);
-       
-       if (constantPool == NULL) {
-               /* out of memory */
-               return NULL;
-       }
-
-       LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
-
-       /* only resolve the parser method the first time */
-       if (m_parseAnnotationsIntoArray == NULL) {
-               utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
-               utf_desc = utf_new_char(
-                       "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
-                       "[Ljava/lang/annotation/Annotation;");
-
-               if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
-                       /* out of memory */
-                       return NULL;
-               }
-
-               m_parseAnnotationsIntoArray = class_resolveclassmethod(
-                       class_sun_reflect_annotation_AnnotationParser,
-                       utf_parseAnnotationsIntoArray,
-                       utf_desc,
-                       class_java_lang_Class,
-                       true);
-
-               if (m_parseAnnotationsIntoArray == NULL) {
-                       /* method not found */
-                       return NULL;
-               }
-       }
-
-       return (java_handle_objectarray_t*)vm_call_method(
-               m_parseAnnotationsIntoArray, NULL,
-               annotations, constantPool, klass);
-}
-#endif
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getEnclosingClass
- * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getEnclosingClass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo *c;
-       classinfo *result;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       result = class_get_enclosingclass(c);
-
-       return LLNI_classinfo_wrap(result);
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getEnclosingConstructor
- * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
- */
-JNIEXPORT java_lang_reflect_Constructor* JNICALL Java_java_lang_VMClass_getEnclosingConstructor(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo*     c;
-       java_handle_t* h;
-
-       c = LLNI_classinfo_unwrap(klass);
-       h = class_get_enclosingconstructor(c);
-
-       return (java_lang_reflect_Constructor*) h;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getEnclosingMethod
- * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
- */
-JNIEXPORT java_lang_reflect_Method* JNICALL Java_java_lang_VMClass_getEnclosingMethod(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       classinfo*     c;
-       java_handle_t* h;
-
-       c = LLNI_classinfo_unwrap(klass);
-       h = class_get_enclosingmethod(c);
-
-       return (java_lang_reflect_Method*) h;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    getClassSignature
- * Signature: (Ljava/lang/Class;)Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getClassSignature(JNIEnv *env, jclass clazz, java_lang_Class* klass)
-{
-       classinfo     *c;
-       utf           *u;
-       java_handle_t *s;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       u = class_get_signature(c);
-
-       if (u == NULL)
-               return NULL;
-
-       s = javastring_new(u);
-
-       /* in error case s is NULL */
-
-       return (java_lang_String *) s;
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    isAnonymousClass
- * Signature: (Ljava/lang/Class;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isAnonymousClass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       return class_is_anonymousclass(LLNI_classinfo_unwrap(klass));
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    isLocalClass
- * Signature: (Ljava/lang/Class;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isLocalClass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       return class_is_localclass(LLNI_classinfo_unwrap(klass));
-}
-
-
-/*
- * Class:     java/lang/VMClass
- * Method:    isMemberClass
- * Signature: (Ljava/lang/Class;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isMemberClass(JNIEnv *env, jclass clazz, java_lang_Class *klass)
-{
-       return class_is_memberclass(LLNI_classinfo_unwrap(klass));
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/java_lang_VMClass.cpp b/src/native/vm/gnuclasspath/java_lang_VMClass.cpp
new file mode 100644 (file)
index 0000000..7056865
--- /dev/null
@@ -0,0 +1,643 @@
+/* src/native/vm/gnuclasspath/java_lang_VMClass.cpp
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_VMClass.h"
+#endif
+
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+#include "vm/string.hpp"
+
+#if defined(ENABLE_ANNOTATIONS)
+#include "vm/annotation.h"
+#include "vm/vm.hpp"
+#endif
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    isInstance
+ * Signature: (Ljava/lang/Class;Ljava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, jclass klass, jobject o)
+{
+       classinfo     *c;
+       java_handle_t *h;
+
+       c = LLNI_classinfo_unwrap(klass);
+       h = (java_handle_t *) o;
+
+       return class_is_instance(c, h);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    isAssignableFrom
+ * Signature: (Ljava/lang/Class;Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, jclass klass, jclass c)
+{
+       classinfo *to;
+       classinfo *from;
+
+       to   = LLNI_classinfo_unwrap(klass);
+       from = LLNI_classinfo_unwrap(c);
+
+       if (from == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       return class_is_assignable_from(to, from);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    isInterface
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       return class_is_interface(c);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    isPrimitive
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       return class_is_primitive(c);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getName
+ * Signature: (Ljava/lang/Class;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_VMClass_getName(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo* c;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       return (jstring) class_get_classname(c);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getSuperclass
+ * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo *c;
+       classinfo *super;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       super = class_get_superclass(c);
+
+       return (jclass) LLNI_classinfo_wrap(super);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getInterfaces
+ * Signature: (Ljava/lang/Class;)[Ljava/lang/Class;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       oa = class_get_interfaces(c);
+
+       return (jobjectArray) oa;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getComponentType
+ * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo *c;
+       classinfo *component;
+       
+       c = LLNI_classinfo_unwrap(klass);
+       
+       component = class_get_componenttype(c);
+
+       return (jclass) LLNI_classinfo_wrap(component);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getModifiers
+ * Signature: (Ljava/lang/Class;Z)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_VMClass_getModifiers(JNIEnv *env, jclass clazz, jclass klass, jboolean ignoreInnerClassesAttrib)
+{
+       classinfo *c;
+       int32_t    flags;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       flags = class_get_modifiers(c, ignoreInnerClassesAttrib);
+
+       return flags;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getDeclaringClass
+ * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo *c;
+       classinfo *dc;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       dc = class_get_declaringclass(c);
+
+       return (jclass) LLNI_classinfo_wrap(dc);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getDeclaredClasses
+ * Signature: (Ljava/lang/Class;Z)[Ljava/lang/Class;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_VMClass_getDeclaredClasses(JNIEnv *env, jclass clazz, jclass klass, jboolean publicOnly)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       oa = class_get_declaredclasses(c, publicOnly);
+
+       return (jobjectArray) oa;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getDeclaredFields
+ * Signature: (Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_VMClass_getDeclaredFields(JNIEnv *env, jclass clazz, jclass klass, jboolean publicOnly)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       oa = class_get_declaredfields(c, publicOnly);
+
+       return (jobjectArray) oa;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getDeclaredMethods
+ * Signature: (Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_VMClass_getDeclaredMethods(JNIEnv *env, jclass clazz, jclass klass, jboolean publicOnly)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       oa = class_get_declaredmethods(c, publicOnly);
+
+       return (jobjectArray) oa;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getDeclaredConstructors
+ * Signature: (Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz, jclass klass, jboolean publicOnly)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       oa = class_get_declaredconstructors(c, publicOnly);
+
+       return (jobjectArray) oa;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getClassLoader
+ * Signature: (Ljava/lang/Class;)Ljava/lang/ClassLoader;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo     *c;
+       classloader_t *cl;
+
+       c  = LLNI_classinfo_unwrap(klass);
+       cl = class_get_classloader(c);
+
+       return (jobject) cl;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    forName
+ * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, jstring name, jboolean initialize, jobject loader)
+{
+       classloader_t *cl;
+       utf           *ufile;
+       utf           *uname;
+       classinfo     *c;
+       char*          pos;
+       int32_t        i;
+
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
+
+       /* illegal argument */
+
+       if (name == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* create utf string in which '.' is replaced by '/' */
+
+       ufile = javastring_toutf((java_handle_t *) name, true);
+       uname = javastring_toutf((java_handle_t *) name, false);
+
+       /* name must not contain '/' (mauve test) */
+
+       // FIXME Move this check into a function.
+       for (i = 0, pos = uname->text; i < uname->blength; i++, pos++) {
+               if (*pos == '/') {
+                       exceptions_throw_classnotfoundexception(uname);
+                       return NULL;
+               }
+       }
+
+       /* try to load, ... */
+
+       c = load_class_from_classloader(ufile, cl);
+
+       if (c == NULL)
+           return NULL;
+
+       /* link, ... */
+
+       if (!link_class(c))
+               return NULL;
+       
+       /* ...and initialize it, if required */
+
+       if (initialize)
+               if (!initialize_class(c))
+                       return NULL;
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    isArray
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       return class_is_array(c);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    throwException
+ * Signature: (Ljava/lang/Throwable;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, jobject t)
+{
+       java_handle_t *o;
+
+       o = (java_handle_t *) t;
+
+       exceptions_set_exception(o);
+}
+
+
+#if defined(ENABLE_ANNOTATIONS)
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getDeclaredAnnotations
+ * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_VMClass_getDeclaredAnnotations(JNIEnv *env, jclass clazz, jclass klass)
+{
+       static methodinfo* m_parseAnnotationsIntoArray = NULL;
+
+       if (klass == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+       
+       classinfo* c = LLNI_classinfo_unwrap(klass);
+
+       /* get annotations: */
+       java_handle_bytearray_t* annotations = class_get_annotations(c);
+
+       java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
+       
+       if (h == NULL)
+               return NULL;
+
+       sun_reflect_ConstantPool cp(h);
+       cp.set_constantPoolOop(klass);
+
+       /* only resolve the parser method the first time */
+       if (m_parseAnnotationsIntoArray == NULL) {
+               utf* utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
+               utf* utf_desc = utf_new_char("([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
+                                                                        "[Ljava/lang/annotation/Annotation;");
+
+               if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
+                       /* out of memory */
+                       return NULL;
+               }
+
+               m_parseAnnotationsIntoArray = class_resolveclassmethod(
+                       class_sun_reflect_annotation_AnnotationParser,
+                       utf_parseAnnotationsIntoArray,
+                       utf_desc,
+                       class_java_lang_Class,
+                       true);
+
+               if (m_parseAnnotationsIntoArray == NULL) {
+                       /* method not found */
+                       return NULL;
+               }
+       }
+
+       java_handle_objectarray_t* oa = (java_handle_objectarray_t*) vm_call_method(m_parseAnnotationsIntoArray, NULL, annotations, cp.get_handle(), klass);
+       return (jobjectArray) oa;
+}
+#endif
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getEnclosingClass
+ * Signature: (Ljava/lang/Class;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClass_getEnclosingClass(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo *c;
+       classinfo *result;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       result = class_get_enclosingclass(c);
+
+       return (jclass) LLNI_classinfo_wrap(result);
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getEnclosingConstructor
+ * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMClass_getEnclosingConstructor(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo*     c;
+       java_handle_t* h;
+
+       c = LLNI_classinfo_unwrap(klass);
+       h = class_get_enclosingconstructor(c);
+
+       return (jobject) h;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getEnclosingMethod
+ * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMClass_getEnclosingMethod(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo*     c;
+       java_handle_t* h;
+
+       c = LLNI_classinfo_unwrap(klass);
+       h = class_get_enclosingmethod(c);
+
+       return (jobject) h;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    getClassSignature
+ * Signature: (Ljava/lang/Class;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_VMClass_getClassSignature(JNIEnv *env, jclass clazz, jclass klass)
+{
+       classinfo     *c;
+       utf           *u;
+       java_handle_t *s;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       u = class_get_signature(c);
+
+       if (u == NULL)
+               return NULL;
+
+       s = javastring_new(u);
+
+       /* in error case s is NULL */
+
+       return (jstring) s;
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    isAnonymousClass
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isAnonymousClass(JNIEnv *env, jclass clazz, jclass klass)
+{
+       return class_is_anonymousclass(LLNI_classinfo_unwrap(klass));
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    isLocalClass
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isLocalClass(JNIEnv *env, jclass clazz, jclass klass)
+{
+       return class_is_localclass(LLNI_classinfo_unwrap(klass));
+}
+
+
+/*
+ * Class:     java/lang/VMClass
+ * Method:    isMemberClass
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClass_isMemberClass(JNIEnv *env, jclass clazz, jclass klass)
+{
+       return class_is_memberclass(LLNI_classinfo_unwrap(klass));
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "isInstance",              (char*) "(Ljava/lang/Class;Ljava/lang/Object;)Z",                        (void*) (uintptr_t) &Java_java_lang_VMClass_isInstance              },
+       { (char*) "isAssignableFrom",        (char*) "(Ljava/lang/Class;Ljava/lang/Class;)Z",                         (void*) (uintptr_t) &Java_java_lang_VMClass_isAssignableFrom        },
+       { (char*) "isInterface",             (char*) "(Ljava/lang/Class;)Z",                                          (void*) (uintptr_t) &Java_java_lang_VMClass_isInterface             },
+       { (char*) "isPrimitive",             (char*) "(Ljava/lang/Class;)Z",                                          (void*) (uintptr_t) &Java_java_lang_VMClass_isPrimitive             },
+       { (char*) "getName",                 (char*) "(Ljava/lang/Class;)Ljava/lang/String;",                         (void*) (uintptr_t) &Java_java_lang_VMClass_getName                 },
+       { (char*) "getSuperclass",           (char*) "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void*) (uintptr_t) &Java_java_lang_VMClass_getSuperclass           },
+       { (char*) "getInterfaces",           (char*) "(Ljava/lang/Class;)[Ljava/lang/Class;",                         (void*) (uintptr_t) &Java_java_lang_VMClass_getInterfaces           },
+       { (char*) "getComponentType",        (char*) "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void*) (uintptr_t) &Java_java_lang_VMClass_getComponentType        },
+       { (char*) "getModifiers",            (char*) "(Ljava/lang/Class;Z)I",                                         (void*) (uintptr_t) &Java_java_lang_VMClass_getModifiers            },
+       { (char*) "getDeclaringClass",       (char*) "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void*) (uintptr_t) &Java_java_lang_VMClass_getDeclaringClass       },
+       { (char*) "getDeclaredClasses",      (char*) "(Ljava/lang/Class;Z)[Ljava/lang/Class;",                        (void*) (uintptr_t) &Java_java_lang_VMClass_getDeclaredClasses      },
+       { (char*) "getDeclaredFields",       (char*) "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;",                (void*) (uintptr_t) &Java_java_lang_VMClass_getDeclaredFields       },
+       { (char*) "getDeclaredMethods",      (char*) "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;",               (void*) (uintptr_t) &Java_java_lang_VMClass_getDeclaredMethods      },
+       { (char*) "getDeclaredConstructors", (char*) "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;",          (void*) (uintptr_t) &Java_java_lang_VMClass_getDeclaredConstructors },
+       { (char*) "getClassLoader",          (char*) "(Ljava/lang/Class;)Ljava/lang/ClassLoader;",                    (void*) (uintptr_t) &Java_java_lang_VMClass_getClassLoader          },
+       { (char*) "forName",                 (char*) "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;", (void*) (uintptr_t) &Java_java_lang_VMClass_forName                 },
+       { (char*) "isArray",                 (char*) "(Ljava/lang/Class;)Z",                                          (void*) (uintptr_t) &Java_java_lang_VMClass_isArray                 },
+       { (char*) "throwException",          (char*) "(Ljava/lang/Throwable;)V",                                      (void*) (uintptr_t) &Java_java_lang_VMClass_throwException          },
+#if defined(ENABLE_ANNOTATIONS)
+       { (char*) "getDeclaredAnnotations",  (char*) "(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;",         (void*) (uintptr_t) &Java_java_lang_VMClass_getDeclaredAnnotations  },
+#endif
+       { (char*) "getEnclosingClass",       (char*) "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void*) (uintptr_t) &Java_java_lang_VMClass_getEnclosingClass       },
+       { (char*) "getEnclosingConstructor", (char*) "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;",            (void*) (uintptr_t) &Java_java_lang_VMClass_getEnclosingConstructor },
+       { (char*) "getEnclosingMethod",      (char*) "(Ljava/lang/Class;)Ljava/lang/reflect/Method;",                 (void*) (uintptr_t) &Java_java_lang_VMClass_getEnclosingMethod      },
+       { (char*) "getClassSignature",       (char*) "(Ljava/lang/Class;)Ljava/lang/String;",                         (void*) (uintptr_t) &Java_java_lang_VMClass_getClassSignature       },
+       { (char*) "isAnonymousClass",        (char*) "(Ljava/lang/Class;)Z",                                          (void*) (uintptr_t) &Java_java_lang_VMClass_isAnonymousClass        },
+       { (char*) "isLocalClass",            (char*) "(Ljava/lang/Class;)Z",                                          (void*) (uintptr_t) &Java_java_lang_VMClass_isLocalClass            },
+       { (char*) "isMemberClass",           (char*) "(Ljava/lang/Class;)Z",                                          (void*) (uintptr_t) &Java_java_lang_VMClass_isMemberClass           },
+};
+
+
+/* _Jv_java_lang_VMClass_init **************************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_VMClass_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/VMClass");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_VMClassLoader.c b/src/native/vm/gnuclasspath/java_lang_VMClassLoader.c
deleted file mode 100644 (file)
index 6f6547b..0000000
+++ /dev/null
@@ -1,628 +0,0 @@
-/* src/native/vm/gnu/java_lang_VMClassLoader.c
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-#include <sys/stat.h>
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_security_ProtectionDomain.h"  /* required by... */
-#include "native/include/java_lang_ClassLoader.h"
-#include "native/include/java_util_Vector.h"
-#include "native/include/java_util_HashMap.h"
-#include "native/include/java_util_Map.h"
-#include "native/include/java_lang_Boolean.h"
-
-#include "native/include/java_lang_VMClassLoader.h"
-
-#include "toolbox/logging.h"
-#include "toolbox/list.h"
-
-#if defined(ENABLE_ASSERTION)
-#include "vm/assertion.h"
-#endif
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/initialize.h"
-#include "vm/primitive.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/asmpart.h"
-
-#include "vmcore/class.h"
-#include "vmcore/classcache.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-#include "vmcore/suck.h"
-#include "vmcore/zip.h"
-
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/cacaodbg.h"
-#endif
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "defineClass",                "(Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (uintptr_t) &Java_java_lang_VMClassLoader_defineClass                },
-       { "getPrimitiveClass",          "(C)Ljava/lang/Class;",                                                                             (void *) (uintptr_t) &Java_java_lang_VMClassLoader_getPrimitiveClass          },
-       { "resolveClass",               "(Ljava/lang/Class;)V",                                                                             (void *) (uintptr_t) &Java_java_lang_VMClassLoader_resolveClass               },
-       { "loadClass",                  "(Ljava/lang/String;Z)Ljava/lang/Class;",                                                           (void *) (uintptr_t) &Java_java_lang_VMClassLoader_loadClass                  },
-       { "nativeGetResources",         "(Ljava/lang/String;)Ljava/util/Vector;",                                                           (void *) (uintptr_t) &Java_java_lang_VMClassLoader_nativeGetResources         },
-       { "defaultAssertionStatus",     "()Z",                                                                                              (void *) (uintptr_t) &Java_java_lang_VMClassLoader_defaultAssertionStatus     },
-       { "defaultUserAssertionStatus", "()Z",                                                                                              (void *) (uintptr_t) &Java_java_lang_VMClassLoader_defaultUserAssertionStatus },
-       { "packageAssertionStatus0",    "(Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;",                                          (void *) (uintptr_t) &Java_java_lang_VMClassLoader_packageAssertionStatus0    },
-       { "classAssertionStatus0",      "(Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;",                                          (void *) (uintptr_t) &Java_java_lang_VMClassLoader_classAssertionStatus0      },
-       { "findLoadedClass",            "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;",                                     (void *) (uintptr_t) &Java_java_lang_VMClassLoader_findLoadedClass            },
-};
-
-
-/* _Jv_java_lang_VMClassLoader_init ********************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_VMClassLoader_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/VMClassLoader");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    defineClass
- * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *cl, java_lang_String *name, java_handle_bytearray_t *data, int32_t offset, int32_t len, java_security_ProtectionDomain *pd)
-{
-       utf             *utfname;
-       classinfo       *c;
-       classloader_t   *loader;
-       java_lang_Class *o;
-
-#if defined(ENABLE_JVMTI)
-       jint new_class_data_len = 0;
-       unsigned char* new_class_data = NULL;
-#endif
-
-       /* check if data was passed */
-
-       if (data == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* check the indexes passed */
-
-       if ((offset < 0) || (len < 0) || ((offset + len) > LLNI_array_size(data))) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       /* add classloader to classloader hashtable */
-
-       loader = loader_hashtable_classloader_add((java_handle_t *) cl);
-
-       if (name != NULL) {
-               /* convert '.' to '/' in java string */
-
-               utfname = javastring_toutf((java_handle_t *) name, true);
-       } 
-       else {
-               utfname = NULL;
-       }
-
-#if defined(ENABLE_JVMTI)
-       /* XXX again this will not work because of the indirection cell for classloaders */
-       assert(0);
-       /* fire Class File Load Hook JVMTI event */
-
-       if (jvmti)
-               jvmti_ClassFileLoadHook(utfname, len, (unsigned char *) data->data, 
-                                                               loader, (java_handle_t *) pd, 
-                                                               &new_class_data_len, &new_class_data);
-#endif
-
-       /* define the class */
-
-#if defined(ENABLE_JVMTI)
-       /* check if the JVMTI wants to modify the class */
-
-       if (new_class_data == NULL)
-               c = class_define(utfname, loader, new_class_data_len, new_class_data, pd); 
-       else
-#endif
-               c = class_define(utfname, loader, len, (uint8_t *) &LLNI_array_direct(data, offset), (java_handle_t *) pd);
-
-       if (c == NULL)
-               return NULL;
-
-       /* for convenience */
-
-       o = LLNI_classinfo_wrap(c);
-
-       /* set ProtectionDomain */
-
-       LLNI_field_set_ref(o, pd, pd);
-
-       return o;
-}
-
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    getPrimitiveClass
- * Signature: (C)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, int32_t type)
-{
-       classinfo *c;
-
-       c = primitive_class_get_by_char(type);
-
-       if (c == NULL) {
-               exceptions_throw_classnotfoundexception(utf_null);
-               return NULL;
-       }
-
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    resolveClass
- * Signature: (Ljava/lang/Class;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jclass clazz, java_lang_Class *c)
-{
-       classinfo *ci;
-
-       ci = LLNI_classinfo_unwrap(c);
-
-       if (!ci) {
-               exceptions_throw_nullpointerexception();
-               return;
-       }
-
-       /* link the class */
-
-       if (!(ci->state & CLASS_LINKED))
-               (void) link_class(ci);
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    loadClass
- * Signature: (Ljava/lang/String;Z)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, int32_t resolve)
-{
-       classinfo *c;
-       utf       *u;
-
-       if (name == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* create utf string in which '.' is replaced by '/' */
-
-       u = javastring_toutf((java_handle_t *) name, true);
-
-       /* load class */
-
-       c = load_class_bootstrap(u);
-
-       if (c == NULL)
-               return NULL;
-
-       /* resolve class -- if requested */
-
-/*     if (resolve) */
-               if (!link_class(c))
-                       return NULL;
-
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    nativeGetResources
- * Signature: (Ljava/lang/String;)Ljava/util/Vector;
- */
-JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResources(JNIEnv *env, jclass clazz, java_lang_String *name)
-{
-       java_handle_t        *o;         /* vector being created     */
-       methodinfo           *m;         /* "add" method of vector   */
-       java_handle_t        *path;      /* path to be added         */
-       list_classpath_entry *lce;       /* classpath entry          */
-       utf                  *utfname;   /* utf to look for          */
-       char                 *buffer;    /* char buffer              */
-       char                 *namestart; /* start of name to use     */
-       char                 *tmppath;   /* temporary buffer         */
-       int32_t               namelen;   /* length of name to use    */
-       int32_t               searchlen; /* length of name to search */
-       int32_t               bufsize;   /* size of buffer allocated */
-       int32_t               pathlen;   /* name of path to assemble */
-       struct stat           buf;       /* buffer for stat          */
-       jboolean              ret;       /* return value of "add"    */
-
-       /* get the resource name as utf string */
-
-       utfname = javastring_toutf((java_handle_t *) name, false);
-
-       if (utfname == NULL)
-               return NULL;
-
-       /* copy it to a char buffer */
-
-       namelen   = utf_bytes(utfname);
-       searchlen = namelen;
-       bufsize   = namelen + strlen("0");
-       buffer    = MNEW(char, bufsize);
-
-       utf_copy(buffer, utfname);
-       namestart = buffer;
-
-       /* skip leading '/' */
-
-       if (namestart[0] == '/') {
-               namestart++;
-               namelen--;
-               searchlen--;
-       }
-
-       /* remove trailing `.class' */
-
-       if (namelen >= 6 && strcmp(namestart + (namelen - 6), ".class") == 0) {
-               searchlen -= 6;
-       }
-
-       /* create a new needle to look for, if necessary */
-
-       if (searchlen != bufsize-1) {
-               utfname = utf_new(namestart, searchlen);
-               if (utfname == NULL)
-                       goto return_NULL;
-       }
-                       
-       /* new Vector() */
-
-       o = native_new_and_init(class_java_util_Vector);
-
-       if (o == NULL)
-               goto return_NULL;
-
-       /* get Vector.add() method */
-
-       m = class_resolveclassmethod(class_java_util_Vector,
-                                                                utf_add,
-                                                                utf_new_char("(Ljava/lang/Object;)Z"),
-                                                                NULL,
-                                                                true);
-
-       if (m == NULL)
-               goto return_NULL;
-
-       /* iterate over all classpath entries */
-
-       for (lce = list_first(list_classpath_entries); lce != NULL;
-                lce = list_next(list_classpath_entries, lce)) {
-               /* clear path pointer */
-               path = NULL;
-
-#if defined(ENABLE_ZLIB)
-               if (lce->type == CLASSPATH_ARCHIVE) {
-
-                       if (zip_find(lce, utfname)) {
-                               pathlen = strlen("jar:file://") + lce->pathlen + strlen("!/") +
-                                       namelen + strlen("0");
-
-                               tmppath = MNEW(char, pathlen);
-
-                               sprintf(tmppath, "jar:file://%s!/%s", lce->path, namestart);
-                               path = javastring_new_from_utf_string(tmppath),
-
-                               MFREE(tmppath, char, pathlen);
-                       }
-
-               } else {
-#endif /* defined(ENABLE_ZLIB) */
-                       pathlen = strlen("file://") + lce->pathlen + namelen + strlen("0");
-
-                       tmppath = MNEW(char, pathlen);
-
-                       sprintf(tmppath, "file://%s%s", lce->path, namestart);
-
-                       /* Does this file exist? */
-
-                       if (stat(tmppath + strlen("file://") - 1, &buf) == 0)
-                               if (!S_ISDIR(buf.st_mode))
-                                       path = javastring_new_from_utf_string(tmppath);
-
-                       MFREE(tmppath, char, pathlen);
-#if defined(ENABLE_ZLIB)
-               }
-#endif
-
-               /* if a resource was found, add it to the vector */
-
-               if (path != NULL) {
-                       ret = vm_call_method_int(m, o, path);
-
-                       if (exceptions_get_exception() != NULL)
-                               goto return_NULL;
-
-                       if (ret == 0) 
-                               goto return_NULL;
-               }
-       }
-
-       MFREE(buffer, char, bufsize);
-
-       return (java_util_Vector *) o;
-
-return_NULL:
-       MFREE(buffer, char, bufsize);
-
-       return NULL;
-}
-
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    defaultAssertionStatus
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv *env, jclass clazz)
-{
-#if defined(ENABLE_ASSERTION)
-       return assertion_system_enabled;
-#else
-       return false;
-#endif
-}
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    userAssertionStatus
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMClassLoader_defaultUserAssertionStatus(JNIEnv *env, jclass clazz)
-{
-#if defined(ENABLE_ASSERTION)
-       return assertion_user_enabled;
-#else
-       return false;
-#endif
-}
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    packageAssertionStatus
- * Signature: ()Ljava_util_Map;
- */
-JNIEXPORT java_util_Map* JNICALL Java_java_lang_VMClassLoader_packageAssertionStatus0(JNIEnv *env, jclass clazz, java_lang_Boolean *jtrue, java_lang_Boolean *jfalse)
-{
-       java_handle_t     *hm;
-#if defined(ENABLE_ASSERTION)
-       java_handle_t     *js;
-       methodinfo        *m;
-       assertion_name_t  *item;
-#endif
-
-       /* new HashMap() */
-
-       hm = native_new_and_init(class_java_util_HashMap);
-       if (hm == NULL) {
-               return NULL;
-       }
-
-#if defined(ENABLE_ASSERTION)
-       /* if nothing todo, return now */
-
-       if (assertion_package_count == 0) {
-               return (java_util_Map *) hm;
-       }
-
-       /* get HashMap.put method */
-
-       m = class_resolveclassmethod(class_java_util_HashMap,
-                                 utf_put,
-                                 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
-                                 NULL,
-                                 true);
-
-       if (m == NULL) {
-               return NULL;
-       }
-
-       item = (assertion_name_t *)list_first(list_assertion_names);
-
-       while (item != NULL) {
-               if (item->package == false) {
-                       item = (assertion_name_t *)list_next(list_assertion_names, item);
-                       continue;
-               }
-               
-               if (strcmp(item->name, "") == 0) {
-                       /* unnamed package wanted */
-                       js = NULL;
-               }
-               else {
-                       js = javastring_new_from_ascii(item->name);
-                       if (js == NULL) {
-                               return NULL;
-                       }
-               }
-
-               if (item->enabled == true) {
-                       vm_call_method(m, hm, js, jtrue);
-               }
-               else {
-                       vm_call_method(m, hm, js, jfalse);
-               }
-
-               item = (assertion_name_t *)list_next(list_assertion_names, item);
-       }
-#endif
-
-       return (java_util_Map *) hm;
-}
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    classAssertionStatus
- * Signature: ()Ljava_util_Map;
- */
-JNIEXPORT java_util_Map* JNICALL Java_java_lang_VMClassLoader_classAssertionStatus0(JNIEnv *env, jclass clazz, java_lang_Boolean *jtrue, java_lang_Boolean *jfalse)
-{
-       java_handle_t     *hm;
-#if defined(ENABLE_ASSERTION)
-       java_handle_t     *js;
-       methodinfo        *m;
-       assertion_name_t  *item;
-#endif
-
-       /* new HashMap() */
-
-       hm = native_new_and_init(class_java_util_HashMap);
-       if (hm == NULL) {
-               return NULL;
-       }
-
-#if defined(ENABLE_ASSERTION)
-       /* if nothing todo, return now */
-
-       if (assertion_class_count == 0) {
-               return (java_util_Map *) hm;
-       }
-
-       /* get HashMap.put method */
-
-       m = class_resolveclassmethod(class_java_util_HashMap,
-                                 utf_put,
-                                 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
-                                 NULL,
-                                 true);
-
-       if (m == NULL) {
-               return NULL;
-       }
-
-       item = (assertion_name_t *)list_first(list_assertion_names);
-
-       while (item != NULL) {
-               if (item->package == true) {
-                       item = (assertion_name_t *)list_next(list_assertion_names, item);
-                       continue;
-               }
-
-               js = javastring_new_from_ascii(item->name);
-               if (js == NULL) {
-                       return NULL;
-               }
-
-               if (item->enabled == true) {
-                       vm_call_method(m, hm, js, jtrue);
-               }
-               else {
-                       vm_call_method(m, hm, js, jfalse);
-               }
-
-               item = (assertion_name_t *)list_next(list_assertion_names, item);
-       }
-#endif
-
-       return (java_util_Map *) hm;
-}
-
-
-/*
- * Class:     java/lang/VMClassLoader
- * Method:    findLoadedClass
- * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_findLoadedClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *loader, java_lang_String *name)
-{
-       classloader_t *cl;
-       classinfo     *c;
-       utf           *u;
-
-       /* XXX is it correct to add the classloader to the hashtable here? */
-
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-
-       /* replace `.' by `/', this is required by the classcache */
-
-       u = javastring_toutf((java_handle_t *) name, true);
-
-       /* lookup for defining classloader */
-
-       c = classcache_lookup_defined(cl, u);
-
-       /* if not found, lookup for initiating classloader */
-
-       if (c == NULL)
-               c = classcache_lookup(cl, u);
-
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp b/src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp
new file mode 100644 (file)
index 0000000..6acc53b
--- /dev/null
@@ -0,0 +1,636 @@
+/* src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/stat.h>
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_VMClassLoader.h"
+#endif
+
+#include "toolbox/logging.h"
+#include "toolbox/list.h"
+
+#if defined(ENABLE_ASSERTION)
+#include "vm/assertion.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/statistics.h"
+#include "vm/string.hpp"
+#include "vm/suck.h"
+#include "vm/vm.hpp"
+#include "vm/zip.h"
+
+#include "vm/jit/asmpart.h"
+
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/cacaodbg.h"
+#endif
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    defineClass
+ * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, jobject cl, jstring name, jbyteArray data, jint offset, jint len, jobject pd)
+{
+       utf             *utfname;
+       classinfo       *c;
+       classloader_t   *loader;
+       java_handle_bytearray_t* ba;
+       uint8_t*                 stream;
+
+#if defined(ENABLE_JVMTI)
+       jint new_class_data_len = 0;
+       unsigned char* new_class_data = NULL;
+#endif
+
+       /* check if data was passed */
+
+       if (data == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* check the indexes passed */
+
+       if ((offset < 0) || (len < 0) || ((offset + len) > LLNI_array_size(data))) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return NULL;
+       }
+
+       /* add classloader to classloader hashtable */
+
+       loader = loader_hashtable_classloader_add((java_handle_t *) cl);
+
+       if (name != NULL) {
+               /* convert '.' to '/' in java string */
+
+               utfname = javastring_toutf((java_handle_t *) name, true);
+       } 
+       else {
+               utfname = NULL;
+       }
+
+#if defined(ENABLE_JVMTI)
+       /* XXX again this will not work because of the indirection cell for classloaders */
+       assert(0);
+       /* fire Class File Load Hook JVMTI event */
+
+       if (jvmti)
+               jvmti_ClassFileLoadHook(utfname, len, (unsigned char *) data->data, 
+                                                               loader, (java_handle_t *) pd, 
+                                                               &new_class_data_len, &new_class_data);
+#endif
+
+       /* define the class */
+
+#if defined(ENABLE_JVMTI)
+       /* check if the JVMTI wants to modify the class */
+
+       if (new_class_data == NULL)
+               c = class_define(utfname, loader, new_class_data_len, new_class_data, pd); 
+       else
+#endif
+       {
+               ba = (java_handle_bytearray_t*) data;
+               stream = (uint8_t *) &LLNI_array_direct(ba, offset);
+               c = class_define(utfname, loader, len, stream, (java_handle_t *) pd);
+       }
+
+       if (c == NULL)
+               return NULL;
+
+       // REMOVEME
+       java_handle_t* h = LLNI_classinfo_wrap(c);
+
+       // Set ProtectionDomain.
+       java_lang_Class jlc(h);
+       jlc.set_pd(pd);
+
+       return (jclass) jlc.get_handle();
+}
+
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    getPrimitiveClass
+ * Signature: (C)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, jchar type)
+{
+       classinfo *c;
+
+       c = Primitive::get_class_by_char(type);
+
+       if (c == NULL) {
+               exceptions_throw_classnotfoundexception(utf_null);
+               return NULL;
+       }
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    resolveClass
+ * Signature: (Ljava/lang/Class;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jclass clazz, jclass c)
+{
+       classinfo *ci;
+
+       ci = LLNI_classinfo_unwrap(c);
+
+       if (!ci) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
+       /* link the class */
+
+       if (!(ci->state & CLASS_LINKED))
+               (void) link_class(ci);
+
+       return;
+}
+
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    loadClass
+ * Signature: (Ljava/lang/String;Z)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, jstring name, jboolean resolve)
+{
+       classinfo *c;
+       utf       *u;
+
+       if (name == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* create utf string in which '.' is replaced by '/' */
+
+       u = javastring_toutf((java_handle_t *) name, true);
+
+       /* load class */
+
+       c = load_class_bootstrap(u);
+
+       if (c == NULL)
+               return NULL;
+
+       /* resolve class -- if requested */
+
+/*     if (resolve) */
+               if (!link_class(c))
+                       return NULL;
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    nativeGetResources
+ * Signature: (Ljava/lang/String;)Ljava/util/Vector;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMClassLoader_nativeGetResources(JNIEnv *env, jclass clazz, jstring name)
+{
+       java_handle_t        *o;         /* vector being created     */
+       methodinfo           *m;         /* "add" method of vector   */
+       java_handle_t        *path;      /* path to be added         */
+       list_classpath_entry *lce;       /* classpath entry          */
+       utf                  *utfname;   /* utf to look for          */
+       char                 *buffer;    /* char buffer              */
+       char                 *namestart; /* start of name to use     */
+       char                 *tmppath;   /* temporary buffer         */
+       int32_t               namelen;   /* length of name to use    */
+       int32_t               searchlen; /* length of name to search */
+       int32_t               bufsize;   /* size of buffer allocated */
+       int32_t               pathlen;   /* name of path to assemble */
+       struct stat           buf;       /* buffer for stat          */
+       jboolean              ret;       /* return value of "add"    */
+
+       /* get the resource name as utf string */
+
+       utfname = javastring_toutf((java_handle_t *) name, false);
+
+       if (utfname == NULL)
+               return NULL;
+
+       /* copy it to a char buffer */
+
+       namelen   = utf_bytes(utfname);
+       searchlen = namelen;
+       bufsize   = namelen + strlen("0");
+       buffer    = MNEW(char, bufsize);
+
+       utf_copy(buffer, utfname);
+       namestart = buffer;
+
+       /* skip leading '/' */
+
+       if (namestart[0] == '/') {
+               namestart++;
+               namelen--;
+               searchlen--;
+       }
+
+       /* remove trailing `.class' */
+
+       if (namelen >= 6 && strcmp(namestart + (namelen - 6), ".class") == 0) {
+               searchlen -= 6;
+       }
+
+       /* create a new needle to look for, if necessary */
+
+       if (searchlen != bufsize-1) {
+               utfname = utf_new(namestart, searchlen);
+               if (utfname == NULL)
+                       goto return_NULL;
+       }
+                       
+       /* new Vector() */
+
+       o = native_new_and_init(class_java_util_Vector);
+
+       if (o == NULL)
+               goto return_NULL;
+
+       /* get Vector.add() method */
+
+       m = class_resolveclassmethod(class_java_util_Vector,
+                                                                utf_add,
+                                                                utf_new_char("(Ljava/lang/Object;)Z"),
+                                                                NULL,
+                                                                true);
+
+       if (m == NULL)
+               goto return_NULL;
+
+       /* iterate over all classpath entries */
+
+       for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL;
+                lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
+               /* clear path pointer */
+               path = NULL;
+
+#if defined(ENABLE_ZLIB)
+               if (lce->type == CLASSPATH_ARCHIVE) {
+
+                       if (zip_find(lce, utfname)) {
+                               pathlen = strlen("jar:file://") + lce->pathlen + strlen("!/") +
+                                       namelen + strlen("0");
+
+                               tmppath = MNEW(char, pathlen);
+
+                               sprintf(tmppath, "jar:file://%s!/%s", lce->path, namestart);
+                               path = javastring_new_from_utf_string(tmppath),
+
+                               MFREE(tmppath, char, pathlen);
+                       }
+
+               } else {
+#endif /* defined(ENABLE_ZLIB) */
+                       pathlen = strlen("file://") + lce->pathlen + namelen + strlen("0");
+
+                       tmppath = MNEW(char, pathlen);
+
+                       sprintf(tmppath, "file://%s%s", lce->path, namestart);
+
+                       /* Does this file exist? */
+
+                       if (stat(tmppath + strlen("file://") - 1, &buf) == 0)
+                               if (!S_ISDIR(buf.st_mode))
+                                       path = javastring_new_from_utf_string(tmppath);
+
+                       MFREE(tmppath, char, pathlen);
+#if defined(ENABLE_ZLIB)
+               }
+#endif
+
+               /* if a resource was found, add it to the vector */
+
+               if (path != NULL) {
+                       ret = vm_call_method_int(m, o, path);
+
+                       if (exceptions_get_exception() != NULL)
+                               goto return_NULL;
+
+                       if (ret == 0) 
+                               goto return_NULL;
+               }
+       }
+
+       MFREE(buffer, char, bufsize);
+
+       return (jobject) o;
+
+return_NULL:
+       MFREE(buffer, char, bufsize);
+
+       return NULL;
+}
+
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    defaultAssertionStatus
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv *env, jclass clazz)
+{
+#if defined(ENABLE_ASSERTION)
+       return assertion_system_enabled;
+#else
+       return false;
+#endif
+}
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    userAssertionStatus
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMClassLoader_defaultUserAssertionStatus(JNIEnv *env, jclass clazz)
+{
+#if defined(ENABLE_ASSERTION)
+       return assertion_user_enabled;
+#else
+       return false;
+#endif
+}
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    packageAssertionStatus
+ * Signature: (Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMClassLoader_packageAssertionStatus0(JNIEnv *env, jclass clazz, jobject jtrue, jobject jfalse)
+{
+       java_handle_t     *hm;
+#if defined(ENABLE_ASSERTION)
+       java_handle_t     *js;
+       methodinfo        *m;
+       assertion_name_t  *item;
+#endif
+
+       /* new HashMap() */
+
+       hm = native_new_and_init(class_java_util_HashMap);
+       if (hm == NULL) {
+               return NULL;
+       }
+
+#if defined(ENABLE_ASSERTION)
+       /* if nothing todo, return now */
+
+       if (assertion_package_count == 0) {
+               return (jobject) hm;
+       }
+
+       /* get HashMap.put method */
+
+       m = class_resolveclassmethod(class_java_util_HashMap,
+                                 utf_put,
+                                 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
+                                 NULL,
+                                 true);
+
+       if (m == NULL) {
+               return NULL;
+       }
+
+       item = (assertion_name_t *)list_first(list_assertion_names);
+
+       while (item != NULL) {
+               if (item->package == false) {
+                       item = (assertion_name_t *)list_next(list_assertion_names, item);
+                       continue;
+               }
+               
+               if (strcmp(item->name, "") == 0) {
+                       /* unnamed package wanted */
+                       js = NULL;
+               }
+               else {
+                       js = javastring_new_from_ascii(item->name);
+                       if (js == NULL) {
+                               return NULL;
+                       }
+               }
+
+               if (item->enabled == true) {
+                       vm_call_method(m, hm, js, jtrue);
+               }
+               else {
+                       vm_call_method(m, hm, js, jfalse);
+               }
+
+               item = (assertion_name_t *)list_next(list_assertion_names, item);
+       }
+#endif
+
+       return (jobject) hm;
+}
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    classAssertionStatus
+ * Signature: (Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMClassLoader_classAssertionStatus0(JNIEnv *env, jclass clazz, jobject jtrue, jobject jfalse)
+{
+       java_handle_t     *hm;
+#if defined(ENABLE_ASSERTION)
+       java_handle_t     *js;
+       methodinfo        *m;
+       assertion_name_t  *item;
+#endif
+
+       /* new HashMap() */
+
+       hm = native_new_and_init(class_java_util_HashMap);
+       if (hm == NULL) {
+               return NULL;
+       }
+
+#if defined(ENABLE_ASSERTION)
+       /* if nothing todo, return now */
+
+       if (assertion_class_count == 0) {
+               return (jobject) hm;
+       }
+
+       /* get HashMap.put method */
+
+       m = class_resolveclassmethod(class_java_util_HashMap,
+                                 utf_put,
+                                 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
+                                 NULL,
+                                 true);
+
+       if (m == NULL) {
+               return NULL;
+       }
+
+       item = (assertion_name_t *)list_first(list_assertion_names);
+
+       while (item != NULL) {
+               if (item->package == true) {
+                       item = (assertion_name_t *)list_next(list_assertion_names, item);
+                       continue;
+               }
+
+               js = javastring_new_from_ascii(item->name);
+               if (js == NULL) {
+                       return NULL;
+               }
+
+               if (item->enabled == true) {
+                       vm_call_method(m, hm, js, jtrue);
+               }
+               else {
+                       vm_call_method(m, hm, js, jfalse);
+               }
+
+               item = (assertion_name_t *)list_next(list_assertion_names, item);
+       }
+#endif
+
+       return (jobject) hm;
+}
+
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    findLoadedClass
+ * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMClassLoader_findLoadedClass(JNIEnv *env, jclass clazz, jobject loader, jstring name)
+{
+       classloader_t *cl;
+       classinfo     *c;
+       utf           *u;
+
+       /* XXX is it correct to add the classloader to the hashtable here? */
+
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
+
+       /* replace `.' by `/', this is required by the classcache */
+
+       u = javastring_toutf((java_handle_t *) name, true);
+
+       /* lookup for defining classloader */
+
+       c = classcache_lookup_defined(cl, u);
+
+       /* if not found, lookup for initiating classloader */
+
+       if (c == NULL)
+               c = classcache_lookup(cl, u);
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "defineClass",                (char*) "(Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;", (void*) (uintptr_t) &Java_java_lang_VMClassLoader_defineClass                },
+       { (char*) "getPrimitiveClass",          (char*) "(C)Ljava/lang/Class;",                                                                             (void*) (uintptr_t) &Java_java_lang_VMClassLoader_getPrimitiveClass          },
+       { (char*) "resolveClass",               (char*) "(Ljava/lang/Class;)V",                                                                             (void*) (uintptr_t) &Java_java_lang_VMClassLoader_resolveClass               },
+       { (char*) "loadClass",                  (char*) "(Ljava/lang/String;Z)Ljava/lang/Class;",                                                           (void*) (uintptr_t) &Java_java_lang_VMClassLoader_loadClass                  },
+       { (char*) "nativeGetResources",         (char*) "(Ljava/lang/String;)Ljava/util/Vector;",                                                           (void*) (uintptr_t) &Java_java_lang_VMClassLoader_nativeGetResources         },
+       { (char*) "defaultAssertionStatus",     (char*) "()Z",                                                                                              (void*) (uintptr_t) &Java_java_lang_VMClassLoader_defaultAssertionStatus     },
+       { (char*) "defaultUserAssertionStatus", (char*) "()Z",                                                                                              (void*) (uintptr_t) &Java_java_lang_VMClassLoader_defaultUserAssertionStatus },
+       { (char*) "packageAssertionStatus0",    (char*) "(Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;",                                          (void*) (uintptr_t) &Java_java_lang_VMClassLoader_packageAssertionStatus0    },
+       { (char*) "classAssertionStatus0",      (char*) "(Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;",                                          (void*) (uintptr_t) &Java_java_lang_VMClassLoader_classAssertionStatus0      },
+       { (char*) "findLoadedClass",            (char*) "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;",                                     (void*) (uintptr_t) &Java_java_lang_VMClassLoader_findLoadedClass            },
+};
+
+
+/* _Jv_java_lang_VMClassLoader_init ********************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_VMClassLoader_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/VMClassLoader");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_VMObject.c b/src/native/vm/gnuclasspath/java_lang_VMObject.c
deleted file mode 100644 (file)
index ea0ba0e..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* src/native/vm/gnu/java_lang_VMObject.c - java/lang/VMObject
-
-   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
-
-   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 <stdint.h>
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Class.h"            /* required by j.l.VMO */
-#include "native/include/java_lang_Cloneable.h"        /* required by j.l.VMO */
-#include "native/include/java_lang_Object.h"           /* required by j.l.VMO */
-
-#include "native/include/java_lang_VMObject.h"
-
-#include "threads/lock-common.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getClass",  "(Ljava/lang/Object;)Ljava/lang/Class;",     (void *) (intptr_t) &Java_java_lang_VMObject_getClass  },
-       { "clone",     "(Ljava/lang/Cloneable;)Ljava/lang/Object;", (void *) (intptr_t) &Java_java_lang_VMObject_clone     },
-       { "notify",    "(Ljava/lang/Object;)V",                     (void *) (intptr_t) &Java_java_lang_VMObject_notify    },
-       { "notifyAll", "(Ljava/lang/Object;)V",                     (void *) (intptr_t) &Java_java_lang_VMObject_notifyAll },
-       { "wait",      "(Ljava/lang/Object;JI)V",                   (void *) (intptr_t) &Java_java_lang_VMObject_wait      },
-};
-
-
-/* _Jv_java_lang_VMObject_init *************************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_VMObject_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/VMObject");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/VMObject
- * Method:    getClass
- * Signature: (Ljava/lang/Object;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMObject_getClass(JNIEnv *env, jclass clazz, java_lang_Object *obj)
-{
-       classinfo *c;
-
-       if (obj == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       LLNI_class_get(obj, c);
-
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * Class:     java/lang/VMObject
- * Method:    clone
- * Signature: (Ljava/lang/Cloneable;)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_VMObject_clone(JNIEnv *env, jclass clazz, java_lang_Cloneable *this)
-{
-       java_handle_t *o;
-       java_handle_t *co;
-
-       o = (java_handle_t *) this;
-
-       co = builtin_clone(NULL, o);
-
-       return (java_lang_Object *) co;
-}
-
-
-/*
- * Class:     java/lang/VMObject
- * Method:    notify
- * Signature: (Ljava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMObject_notify(JNIEnv *env, jclass clazz, java_lang_Object *this)
-{
-#if defined(ENABLE_THREADS)
-       lock_notify_object((java_handle_t *) this);
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMObject
- * Method:    notifyAll
- * Signature: (Ljava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMObject_notifyAll(JNIEnv *env, jclass clazz, java_lang_Object *this)
-{
-#if defined(ENABLE_THREADS)
-       lock_notify_all_object((java_handle_t *) this);
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMObject
- * Method:    wait
- * Signature: (Ljava/lang/Object;JI)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMObject_wait(JNIEnv *env, jclass clazz, java_lang_Object *o, int64_t ms, int32_t ns)
-{
-#if defined(ENABLE_JVMTI)
-       /* Monitor Wait */
-       if (jvmti) jvmti_MonitorWaiting(true, o, ms);
-#endif
-
-#if defined(ENABLE_THREADS)
-       lock_wait_for_object((java_handle_t *) o, ms, ns);
-#endif
-
-#if defined(ENABLE_JVMTI)
-       /* Monitor Waited */
-       /* XXX: How do you know if wait timed out ?*/
-       if (jvmti) jvmti_MonitorWaiting(false, o, 0);
-#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/native/vm/gnuclasspath/java_lang_VMObject.cpp b/src/native/vm/gnuclasspath/java_lang_VMObject.cpp
new file mode 100644 (file)
index 0000000..5b63de2
--- /dev/null
@@ -0,0 +1,179 @@
+/* src/native/vm/gnuclasspath/java_lang_VMObject.cpp - java/lang/VMObject
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_VMObject.h"
+#endif
+
+#include "threads/lock-common.h"
+
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/utf8.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/VMObject
+ * Method:    getClass
+ * Signature: (Ljava/lang/Object;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_VMObject_getClass(JNIEnv *env, jclass clazz, jobject obj)
+{
+       classinfo *c;
+
+       if (obj == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       LLNI_class_get(obj, c);
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/*
+ * Class:     java/lang/VMObject
+ * Method:    clone
+ * Signature: (Ljava/lang/Cloneable;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMObject_clone(JNIEnv *env, jclass clazz, jobject _this)
+{
+       java_handle_t *o;
+       java_handle_t *co;
+
+       o = (java_handle_t *) _this;
+
+       co = builtin_clone(NULL, o);
+
+       return (jobject) co;
+}
+
+
+/*
+ * Class:     java/lang/VMObject
+ * Method:    notify
+ * Signature: (Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMObject_notify(JNIEnv *env, jclass clazz, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       lock_notify_object((java_handle_t *) _this);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMObject
+ * Method:    notifyAll
+ * Signature: (Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMObject_notifyAll(JNIEnv *env, jclass clazz, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       lock_notify_all_object((java_handle_t *) _this);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMObject
+ * Method:    wait
+ * Signature: (Ljava/lang/Object;JI)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMObject_wait(JNIEnv *env, jclass clazz, jobject o, jlong ms, jint ns)
+{
+#if defined(ENABLE_JVMTI)
+       /* Monitor Wait */
+       if (jvmti) jvmti_MonitorWaiting(true, o, ms);
+#endif
+
+#if defined(ENABLE_THREADS)
+       lock_wait_for_object((java_handle_t *) o, ms, ns);
+#endif
+
+#if defined(ENABLE_JVMTI)
+       /* Monitor Waited */
+       /* XXX: How do you know if wait timed out ?*/
+       if (jvmti) jvmti_MonitorWaiting(false, o, 0);
+#endif
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getClass",  (char*) "(Ljava/lang/Object;)Ljava/lang/Class;",     (void*) (uintptr_t) &Java_java_lang_VMObject_getClass  },
+       { (char*) "clone",     (char*) "(Ljava/lang/Cloneable;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_java_lang_VMObject_clone     },
+       { (char*) "notify",    (char*) "(Ljava/lang/Object;)V",                     (void*) (uintptr_t) &Java_java_lang_VMObject_notify    },
+       { (char*) "notifyAll", (char*) "(Ljava/lang/Object;)V",                     (void*) (uintptr_t) &Java_java_lang_VMObject_notifyAll },
+       { (char*) "wait",      (char*) "(Ljava/lang/Object;JI)V",                   (void*) (uintptr_t) &Java_java_lang_VMObject_wait      },
+};
+
+
+/* _Jv_java_lang_VMObject_init *************************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_VMObject_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/VMObject");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_VMRuntime.c b/src/native/vm/gnuclasspath/java_lang_VMRuntime.c
deleted file mode 100644 (file)
index 2ab5bd0..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-/* src/native/vm/gnu/java_lang_VMRuntime.c
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/utsname.h>
-
-#if defined(__DARWIN__)
-# if defined(__POWERPC__)
-#  define OS_INLINE    /* required for <libkern/ppc/OSByteOrder.h> */
-# endif
-# include <mach/mach.h>
-#endif
-
-#include "mm/dumpmemory.h"
-#include "mm/gc-common.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_io_File.h"
-#include "native/include/java_lang_ClassLoader.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Process.h"
-
-#include "native/include/java_lang_VMRuntime.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/system.h"
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "exit",                   "(I)V",                                         (void *) (intptr_t) &Java_java_lang_VMRuntime_exit                   },
-       { "freeMemory",             "()J",                                          (void *) (intptr_t) &Java_java_lang_VMRuntime_freeMemory             },
-       { "totalMemory",            "()J",                                          (void *) (intptr_t) &Java_java_lang_VMRuntime_totalMemory            },
-       { "maxMemory",              "()J",                                          (void *) (intptr_t) &Java_java_lang_VMRuntime_maxMemory              },
-       { "gc",                     "()V",                                          (void *) (intptr_t) &Java_java_lang_VMRuntime_gc                     },
-       { "runFinalization",        "()V",                                          (void *) (intptr_t) &Java_java_lang_VMRuntime_runFinalization        },
-       { "runFinalizersOnExit",    "(Z)V",                                         (void *) (intptr_t) &Java_java_lang_VMRuntime_runFinalizersOnExit    },
-       { "runFinalizationForExit", "()V",                                          (void *) (intptr_t) &Java_java_lang_VMRuntime_runFinalizationForExit },
-       { "traceInstructions",      "(Z)V",                                         (void *) (intptr_t) &Java_java_lang_VMRuntime_traceInstructions      },
-       { "traceMethodCalls",       "(Z)V",                                         (void *) (intptr_t) &Java_java_lang_VMRuntime_traceMethodCalls       },
-       { "availableProcessors",    "()I",                                          (void *) (intptr_t) &Java_java_lang_VMRuntime_availableProcessors    },
-       { "nativeLoad",             "(Ljava/lang/String;Ljava/lang/ClassLoader;)I", (void *) (intptr_t) &Java_java_lang_VMRuntime_nativeLoad             },
-       { "mapLibraryName",         "(Ljava/lang/String;)Ljava/lang/String;",       (void *) (intptr_t) &Java_java_lang_VMRuntime_mapLibraryName         },
-};
-
-
-/* _Jv_java_lang_VMRuntime_init ************************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_VMRuntime_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/VMRuntime");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-static bool finalizeOnExit = false;
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    exit
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, int32_t status)
-{
-       if (finalizeOnExit)
-               gc_finalize_all();
-
-       vm_shutdown(status);
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    freeMemory
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
-{
-       return gc_get_free_bytes();
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    totalMemory
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
-{
-       return gc_get_heap_size();
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    maxMemory
- * Signature: ()J
- */
-JNIEXPORT int64_t JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
-{
-       return gc_get_max_heap_size();
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    gc
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
-{
-       gc_call();
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    runFinalization
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jclass clazz)
-{
-       gc_invoke_finalizers();
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    runFinalizersOnExit
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, int32_t value)
-{
-       /* XXX threading */
-
-       finalizeOnExit = value;
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    runFinalizationsForExit
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *env, jclass clazz)
-{
-/*     if (finalizeOnExit) { */
-/*             gc_call(); */
-       /* gc_finalize_all(); */
-/*     } */
-/*     log_text("Java_java_lang_VMRuntime_runFinalizationForExit called"); */
-       /*gc_finalize_all();*/
-       /*gc_invoke_finalizers();*/
-       /*gc_call();*/
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    traceInstructions
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions(JNIEnv *env, jclass clazz, int32_t par1)
-{
-       /* not supported */
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    traceMethodCalls
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceMethodCalls(JNIEnv *env, jclass clazz, int32_t par1)
-{
-       /* not supported */
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    availableProcessors
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, jclass clazz)
-{
-       return system_processors_online();
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    nativeLoad
- * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *libname, java_lang_ClassLoader *loader)
-{
-       classloader_t *cl;
-       utf           *name;
-
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-
-       /* REMOVEME When we use Java-strings internally. */
-
-       if (libname == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       name = javastring_toutf((java_handle_t *) libname, false);
-
-       return native_library_load(env, name, cl);
-}
-
-
-/*
- * Class:     java/lang/VMRuntime
- * Method:    mapLibraryName
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_mapLibraryName(JNIEnv *env, jclass clazz, java_lang_String *libname)
-{
-       utf           *u;
-       char          *buffer;
-       int32_t        buffer_len;
-       java_handle_t *o;
-       int32_t        dumpmarker;
-
-       if (libname == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       u = javastring_toutf((java_handle_t *) libname, false);
-
-       /* calculate length of library name */
-
-       buffer_len =
-               strlen(NATIVE_LIBRARY_PREFIX) +
-               utf_bytes(u) +
-               strlen(NATIVE_LIBRARY_SUFFIX) +
-               strlen("0");
-
-       DMARKER;
-
-       buffer = DMNEW(char, buffer_len);
-
-       /* generate library name */
-
-       strcpy(buffer, NATIVE_LIBRARY_PREFIX);
-       utf_cat(buffer, u);
-       strcat(buffer, NATIVE_LIBRARY_SUFFIX);
-
-       o = javastring_new_from_utf_string(buffer);
-
-       /* release memory */
-
-       DRELEASE;
-
-       return (java_lang_String *) o;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/java_lang_VMRuntime.cpp b/src/native/vm/gnuclasspath/java_lang_VMRuntime.cpp
new file mode 100644 (file)
index 0000000..84f13d5
--- /dev/null
@@ -0,0 +1,324 @@
+/* src/native/vm/gnuclasspath/java_lang_VMRuntime.cpp
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+#if defined(__DARWIN__)
+# if defined(__POWERPC__)
+#  define OS_INLINE    /* required for <libkern/ppc/OSByteOrder.h> */
+# endif
+# include <mach/mach.h>
+#endif
+
+#include "mm/dumpmemory.h"
+#include "mm/gc.hpp"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_VMRuntime.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/os.hpp"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+static bool finalizeOnExit = false;
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    exit
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, jint status)
+{
+       if (finalizeOnExit)
+               gc_finalize_all();
+
+       vm_shutdown(status);
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    freeMemory
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
+{
+       return gc_get_free_bytes();
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    totalMemory
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
+{
+       return gc_get_heap_size();
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    maxMemory
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
+{
+       return gc_get_max_heap_size();
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    gc
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
+{
+       gc_call();
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    runFinalization
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jclass clazz)
+{
+       gc_invoke_finalizers();
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    runFinalizersOnExit
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, jboolean value)
+{
+       /* XXX threading */
+
+       finalizeOnExit = value;
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    runFinalizationsForExit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *env, jclass clazz)
+{
+/*     if (finalizeOnExit) { */
+/*             gc_call(); */
+       /* gc_finalize_all(); */
+/*     } */
+/*     log_text("Java_java_lang_VMRuntime_runFinalizationForExit called"); */
+       /*gc_finalize_all();*/
+       /*gc_invoke_finalizers();*/
+       /*gc_call();*/
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    traceInstructions
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions(JNIEnv *env, jclass clazz, jboolean par1)
+{
+       /* not supported */
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    traceMethodCalls
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceMethodCalls(JNIEnv *env, jclass clazz, jboolean par1)
+{
+       /* not supported */
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    availableProcessors
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, jclass clazz)
+{
+       return os::processors_online();
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    nativeLoad
+ * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, jstring libname, jobject loader)
+{
+       classloader_t *cl;
+       utf           *name;
+
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
+
+       /* REMOVEME When we use Java-strings internally. */
+
+       if (libname == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       name = javastring_toutf((java_handle_t *) libname, false);
+
+       return native_library_load(env, name, cl);
+}
+
+
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    mapLibraryName
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_VMRuntime_mapLibraryName(JNIEnv *env, jclass clazz, jstring libname)
+{
+       utf           *u;
+       char          *buffer;
+       int32_t        buffer_len;
+       java_handle_t *o;
+       int32_t        dumpmarker;
+
+       if (libname == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       u = javastring_toutf((java_handle_t *) libname, false);
+
+       /* calculate length of library name */
+
+       buffer_len =
+               strlen(NATIVE_LIBRARY_PREFIX) +
+               utf_bytes(u) +
+               strlen(NATIVE_LIBRARY_SUFFIX) +
+               strlen("0");
+
+       DMARKER;
+
+       buffer = DMNEW(char, buffer_len);
+
+       /* generate library name */
+
+       strcpy(buffer, NATIVE_LIBRARY_PREFIX);
+       utf_cat(buffer, u);
+       strcat(buffer, NATIVE_LIBRARY_SUFFIX);
+
+       o = javastring_new_from_utf_string(buffer);
+
+       /* release memory */
+
+       DRELEASE;
+
+       return (jstring) o;
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "exit",                   (char*) "(I)V",                                         (void*) (uintptr_t) &Java_java_lang_VMRuntime_exit                   },
+       { (char*) "freeMemory",             (char*) "()J",                                          (void*) (uintptr_t) &Java_java_lang_VMRuntime_freeMemory             },
+       { (char*) "totalMemory",            (char*) "()J",                                          (void*) (uintptr_t) &Java_java_lang_VMRuntime_totalMemory            },
+       { (char*) "maxMemory",              (char*) "()J",                                          (void*) (uintptr_t) &Java_java_lang_VMRuntime_maxMemory              },
+       { (char*) "gc",                     (char*) "()V",                                          (void*) (uintptr_t) &Java_java_lang_VMRuntime_gc                     },
+       { (char*) "runFinalization",        (char*) "()V",                                          (void*) (uintptr_t) &Java_java_lang_VMRuntime_runFinalization        },
+       { (char*) "runFinalizersOnExit",    (char*) "(Z)V",                                         (void*) (uintptr_t) &Java_java_lang_VMRuntime_runFinalizersOnExit    },
+       { (char*) "runFinalizationForExit", (char*) "()V",                                          (void*) (uintptr_t) &Java_java_lang_VMRuntime_runFinalizationForExit },
+       { (char*) "traceInstructions",      (char*) "(Z)V",                                         (void*) (uintptr_t) &Java_java_lang_VMRuntime_traceInstructions      },
+       { (char*) "traceMethodCalls",       (char*) "(Z)V",                                         (void*) (uintptr_t) &Java_java_lang_VMRuntime_traceMethodCalls       },
+       { (char*) "availableProcessors",    (char*) "()I",                                          (void*) (uintptr_t) &Java_java_lang_VMRuntime_availableProcessors    },
+       { (char*) "nativeLoad",             (char*) "(Ljava/lang/String;Ljava/lang/ClassLoader;)I", (void*) (uintptr_t) &Java_java_lang_VMRuntime_nativeLoad             },
+       { (char*) "mapLibraryName",         (char*) "(Ljava/lang/String;)Ljava/lang/String;",       (void*) (uintptr_t) &Java_java_lang_VMRuntime_mapLibraryName         },
+};
+
+
+/* _Jv_java_lang_VMRuntime_init ************************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_VMRuntime_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/VMRuntime");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_VMString.c b/src/native/vm/gnuclasspath/java_lang_VMString.c
deleted file mode 100644 (file)
index 993b661..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* src/native/vm/gnu/java_lang_VMString.c - java/lang/VMString
-
-   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
-
-   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 "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_VMString.h"
-
-#include "vm/stringlocal.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "intern", "(Ljava/lang/String;)Ljava/lang/String;", (void *) (ptrint) &Java_java_lang_VMString_intern },
-};
-
-
-/* _Jv_java_lang_VMString_init *************************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_VMString_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/VMString");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/VMString
- * Method:    intern
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMString_intern(JNIEnv *env, jclass clazz, java_lang_String *str)
-{
-       if (str == NULL)
-               return NULL;
-
-       return (java_lang_String *) javastring_intern((java_handle_t *) str);
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/java_lang_VMString.cpp b/src/native/vm/gnuclasspath/java_lang_VMString.cpp
new file mode 100644 (file)
index 0000000..632c429
--- /dev/null
@@ -0,0 +1,97 @@
+/* src/native/vm/gnuclasspath/java_lang_VMString.cpp - java/lang/VMString
+
+   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 <stdint.h>
+#include <stdlib.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_VMString.h"
+#endif
+
+#include "vm/string.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/VMString
+ * Method:    intern
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_VMString_intern(JNIEnv *env, jclass clazz, jstring str)
+{
+       if (str == NULL)
+               return NULL;
+
+       return (jstring) javastring_intern((java_handle_t *) str);
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "intern", (char*) "(Ljava/lang/String;)Ljava/lang/String;", (void*) (uintptr_t) &Java_java_lang_VMString_intern },
+};
+
+
+/* _Jv_java_lang_VMString_init *************************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_VMString_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/VMString");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_VMSystem.c b/src/native/vm/gnuclasspath/java_lang_VMSystem.c
deleted file mode 100644 (file)
index 40c978c..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/* src/native/vm/gnu/java_lang_VMSystem.c - java/lang/VMSystem
-
-   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 <stdint.h>
-#include <string.h>
-
-#include "mm/gc-common.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_io_InputStream.h"        /* required by j.l.VMS */
-#include "native/include/java_io_PrintStream.h"        /* required by j.l.VMS */
-
-#include "native/include/java_lang_VMSystem.h"
-
-#include "vm/builtin.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "arraycopy",        "(Ljava/lang/Object;ILjava/lang/Object;II)V", (void *) (uintptr_t) &Java_java_lang_VMSystem_arraycopy },
-       { "identityHashCode", "(Ljava/lang/Object;)I",                      (void *) (uintptr_t) &Java_java_lang_VMSystem_identityHashCode },
-};
-
-
-/* _Jv_java_lang_VMSystem_init *************************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_VMSystem_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/VMSystem");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/VMSystem
- * Method:    arraycopy
- * Signature: (Ljava/lang/Object;ILjava/lang/Object;II)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMSystem_arraycopy(JNIEnv *env, jclass clazz, java_lang_Object *src, int32_t srcStart, java_lang_Object *dest, int32_t destStart, int32_t len)
-{
-       builtin_arraycopy((java_handle_t *) src, srcStart,
-                                         (java_handle_t *) dest, destStart, len);
-}
-
-
-/*
- * Class:     java/lang/VMSystem
- * Method:    identityHashCode
- * Signature: (Ljava/lang/Object;)I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMSystem_identityHashCode(JNIEnv *env, jclass clazz, java_lang_Object *o)
-{
-       int32_t hashcode;
-
-       LLNI_CRITICAL_START;
-
-       hashcode = heap_hashcode(LLNI_UNWRAP((java_handle_t *) o));
-
-       LLNI_CRITICAL_END;
-
-       return hashcode;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/java_lang_VMSystem.cpp b/src/native/vm/gnuclasspath/java_lang_VMSystem.cpp
new file mode 100644 (file)
index 0000000..fcdc273
--- /dev/null
@@ -0,0 +1,119 @@
+/* src/native/vm/gnuclasspath/java_lang_VMSystem.cpp - java/lang/VMSystem
+
+   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 <stdint.h>
+#include <string.h>
+
+#include "mm/gc.hpp"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vminclude/java_lang_VMSystem.h"
+#endif
+
+#include "vm/builtin.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/VMSystem
+ * Method:    arraycopy
+ * Signature: (Ljava/lang/Object;ILjava/lang/Object;II)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMSystem_arraycopy(JNIEnv *env, jclass clazz, jobject src, jint srcStart, jobject dest, jint destStart, jint len)
+{
+       builtin_arraycopy((java_handle_t *) src, srcStart,
+                                         (java_handle_t *) dest, destStart, len);
+}
+
+
+/*
+ * Class:     java/lang/VMSystem
+ * Method:    identityHashCode
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_VMSystem_identityHashCode(JNIEnv *env, jclass clazz, jobject o)
+{
+       int32_t hashcode;
+
+       // XXX This critical section should be inside the heap function.
+       LLNI_CRITICAL_START;
+
+       hashcode = heap_hashcode(LLNI_UNWRAP((java_handle_t *) o));
+
+       LLNI_CRITICAL_END;
+
+       return hashcode;
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "arraycopy",        (char*) "(Ljava/lang/Object;ILjava/lang/Object;II)V", (void*) (uintptr_t) &Java_java_lang_VMSystem_arraycopy },
+       { (char*) "identityHashCode", (char*) "(Ljava/lang/Object;)I",                      (void*) (uintptr_t) &Java_java_lang_VMSystem_identityHashCode },
+};
+
+
+/* _Jv_java_lang_VMSystem_init *************************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_VMSystem_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/VMSystem");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_VMThread.c b/src/native/vm/gnuclasspath/java_lang_VMThread.c
deleted file mode 100644 (file)
index 9956ef3..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/* src/native/vm/gnu/java_lang_VMThread.c
-
-   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 <stdint.h>
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_ThreadGroup.h"
-#include "native/include/java_lang_Object.h"            /* java_lang_Thread.h */
-#include "native/include/java_lang_Throwable.h"         /* java_lang_Thread.h */
-#include "native/include/java_lang_VMThread.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Thread.h"
-
-#include "threads/lock-common.h"
-#include "threads/thread.h"
-
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "countStackFrames",  "()I",                      (void *) (intptr_t) &Java_java_lang_VMThread_countStackFrames  },
-       { "start",             "(J)V",                     (void *) (intptr_t) &Java_java_lang_VMThread_start             },
-       { "interrupt",         "()V",                      (void *) (intptr_t) &Java_java_lang_VMThread_interrupt         },
-       { "isInterrupted",     "()Z",                      (void *) (intptr_t) &Java_java_lang_VMThread_isInterrupted     },
-       { "suspend",           "()V",                      (void *) (intptr_t) &Java_java_lang_VMThread_suspend           },
-       { "resume",            "()V",                      (void *) (intptr_t) &Java_java_lang_VMThread_resume            },
-       { "nativeSetPriority", "(I)V",                     (void *) (intptr_t) &Java_java_lang_VMThread_nativeSetPriority },
-       { "nativeStop",        "(Ljava/lang/Throwable;)V", (void *) (intptr_t) &Java_java_lang_VMThread_nativeStop        },
-       { "currentThread",     "()Ljava/lang/Thread;",     (void *) (intptr_t) &Java_java_lang_VMThread_currentThread     },
-       { "yield",             "()V",                      (void *) (intptr_t) &Java_java_lang_VMThread_yield             },
-       { "interrupted",       "()Z",                      (void *) (intptr_t) &Java_java_lang_VMThread_interrupted       },
-       { "holdsLock",         "(Ljava/lang/Object;)Z",    (void *) (intptr_t) &Java_java_lang_VMThread_holdsLock         },
-       { "getState",          "()Ljava/lang/String;",     (void *) (intptr_t) &Java_java_lang_VMThread_getState          },
-};
-
-
-/* _Jv_java_lang_VMThread_init *************************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_VMThread_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/VMThread");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    countStackFrames
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_countStackFrames(JNIEnv *env, java_lang_VMThread *this)
-{
-       log_println("Java_java_lang_VMThread_countStackFrames: Deprecated.  Not implemented.");
-
-    return 0;
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    start
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_start(JNIEnv *env, java_lang_VMThread *this, int64_t stacksize)
-{
-       java_lang_Thread *thread;
-
-       LLNI_field_get_ref(this, thread, thread);
-
-#if defined(ENABLE_THREADS)
-       threads_thread_start((java_handle_t *) thread);
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    interrupt
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(JNIEnv *env, java_lang_VMThread *this)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *h;
-       threadobject  *t;
-
-       h = (java_handle_t *) this;
-       t = thread_get_thread(h);
-
-       threads_thread_interrupt(t);
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    isInterrupted
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, java_lang_VMThread *this)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *h;
-       threadobject  *t;
-
-       h = (java_handle_t *) this;
-       t = thread_get_thread(h);
-
-       return thread_is_interrupted(t);
-#else
-       return 0;
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    suspend
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_suspend(JNIEnv *env, java_lang_VMThread *this)
-{
-#if defined(ENABLE_THREADS)
-       log_println("Java_java_lang_VMThread_suspend: Deprecated.  Not implemented.");
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    resume
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_resume(JNIEnv *env, java_lang_VMThread *this)
-{
-#if defined(ENABLE_THREADS)
-       log_println("Java_java_lang_VMThread_resume: Deprecated.  Not implemented.");
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    nativeSetPriority
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, java_lang_VMThread *this, int32_t priority)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *h;
-       threadobject  *t;
-
-       h = (java_handle_t *) this;
-       t = thread_get_thread(h);
-
-       threads_set_thread_priority(t->tid, priority);
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    nativeStop
- * Signature: (Ljava/lang/Throwable;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeStop(JNIEnv *env, java_lang_VMThread *this, java_lang_Throwable *t)
-{
-#if defined(ENABLE_THREADS)
-       log_println("Java_java_lang_VMThread_nativeStop: Deprecated.  Not implemented.");
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    currentThread
- * Signature: ()Ljava/lang/Thread;
- */
-JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv *env, jclass clazz)
-{
-       java_lang_Thread *to;
-
-       to = (java_lang_Thread *) thread_get_current_object();
-
-       return to;
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    yield
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_yield(JNIEnv *env, jclass clazz)
-{
-#if defined(ENABLE_THREADS)
-       threads_yield();
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    interrupted
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_interrupted(JNIEnv *env, jclass clazz)
-{
-#if defined(ENABLE_THREADS)
-       threadobject *t;
-       int32_t       interrupted;
-
-       t = thread_get_current();
-
-       interrupted = thread_is_interrupted(t);
-
-       if (interrupted)
-               thread_set_interrupted(t, false);
-
-       return interrupted;
-#else
-       return 0;
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    holdsLock
- * Signature: (Ljava/lang/Object;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_holdsLock(JNIEnv *env, jclass clazz, java_lang_Object* o)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *h;
-
-       h = (java_handle_t *) o;
-
-       if (h == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       return lock_is_held_by_current_thread(h);
-#else
-       return 0;
-#endif
-}
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    getState
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMThread_getState(JNIEnv *env, java_lang_VMThread *this)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *h;
-       threadobject  *t;
-       int            state;
-       utf           *u;
-       java_handle_t *o;
-
-       h = (java_handle_t *) this;
-       t = thread_get_thread(h);
-
-       state = cacaothread_get_state(t);
-       
-       switch (state) {
-       case THREAD_STATE_NEW:
-               u = utf_new_char("NEW");
-               break;
-       case THREAD_STATE_RUNNABLE:
-               u = utf_new_char("RUNNABLE");
-               break;
-       case THREAD_STATE_BLOCKED:
-               u = utf_new_char("BLOCKED");
-               break;
-       case THREAD_STATE_WAITING:
-               u = utf_new_char("WAITING");
-               break;
-       case THREAD_STATE_TIMED_WAITING:
-               u = utf_new_char("TIMED_WAITING");
-               break;
-       case THREAD_STATE_TERMINATED:
-               u = utf_new_char("TERMINATED");
-               break;
-       default:
-               vm_abort("Java_java_lang_VMThread_getState: unknown thread state %d", state);
-
-               /* Keep compiler happy. */
-
-               u = NULL;
-       }
-
-       o = javastring_new(u);
-
-       return (java_lang_String *) o;
-#else
-       return NULL;
-#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/native/vm/gnuclasspath/java_lang_VMThread.cpp b/src/native/vm/gnuclasspath/java_lang_VMThread.cpp
new file mode 100644 (file)
index 0000000..dde8384
--- /dev/null
@@ -0,0 +1,373 @@
+/* src/native/vm/gnuclasspath/java_lang_VMThread.cpp
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_VMThread.h"
+#endif
+
+#include "threads/lock-common.h"
+#include "threads/thread.hpp"
+
+#include "vm/exceptions.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    countStackFrames
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_VMThread_countStackFrames(JNIEnv *env, jobject _this)
+{
+       log_println("Java_java_lang_VMThread_countStackFrames: Deprecated.  Not implemented.");
+
+    return 0;
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    start
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMThread_start(JNIEnv *env, jobject _this, jlong stacksize)
+{
+#if defined(ENABLE_THREADS)
+       java_lang_VMThread jlvmt(_this);
+
+       threads_thread_start(jlvmt.get_thread());
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    interrupt
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       java_handle_t *h;
+       threadobject  *t;
+
+       h = (java_handle_t *) _this;
+       t = thread_get_thread(h);
+
+       threads_thread_interrupt(t);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    isInterrupted
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       java_handle_t *h;
+       threadobject  *t;
+
+       h = (java_handle_t *) _this;
+       t = thread_get_thread(h);
+
+       return thread_is_interrupted(t);
+#else
+       return 0;
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    suspend
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMThread_suspend(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       log_println("Java_java_lang_VMThread_suspend: Deprecated.  Not implemented.");
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    resume
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMThread_resume(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       log_println("Java_java_lang_VMThread_resume: Deprecated.  Not implemented.");
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    nativeSetPriority
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, jobject _this, jint priority)
+{
+#if defined(ENABLE_THREADS)
+       java_handle_t *h;
+       threadobject  *t;
+
+       h = (java_handle_t *) _this;
+       t = thread_get_thread(h);
+
+       threads_set_thread_priority(t->tid, priority);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    nativeStop
+ * Signature: (Ljava/lang/Throwable;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeStop(JNIEnv *env, jobject _this, jobject t)
+{
+#if defined(ENABLE_THREADS)
+       log_println("Java_java_lang_VMThread_nativeStop: Deprecated.  Not implemented.");
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    currentThread
+ * Signature: ()Ljava/lang/Thread;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMThread_currentThread(JNIEnv *env, jclass clazz)
+{
+       java_handle_t* h;
+
+       h = thread_get_current_object();
+
+       return (jobject) h;
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    yield
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMThread_yield(JNIEnv *env, jclass clazz)
+{
+#if defined(ENABLE_THREADS)
+       threads_yield();
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    sleep
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMThread_sleep(JNIEnv *env, jclass clazz, int64_t ms, int32_t ns)
+{
+#if defined(ENABLE_THREADS)
+       threads_sleep(ms, ns);
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    interrupted
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMThread_interrupted(JNIEnv *env, jclass clazz)
+{
+#if defined(ENABLE_THREADS)
+       threadobject *t;
+       int32_t       interrupted;
+
+       t = thread_get_current();
+
+       interrupted = thread_is_interrupted(t);
+
+       if (interrupted)
+               thread_set_interrupted(t, false);
+
+       return interrupted;
+#else
+       return 0;
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    holdsLock
+ * Signature: (Ljava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_VMThread_holdsLock(JNIEnv *env, jclass clazz, jobject o)
+{
+#if defined(ENABLE_THREADS)
+       java_handle_t *h;
+
+       h = (java_handle_t *) o;
+
+       if (h == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       return lock_is_held_by_current_thread(h);
+#else
+       return 0;
+#endif
+}
+
+
+/*
+ * Class:     java/lang/VMThread
+ * Method:    getState
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_VMThread_getState(JNIEnv *env, jobject _this)
+{
+#if defined(ENABLE_THREADS)
+       java_handle_t *h;
+       threadobject  *t;
+       int            state;
+       utf           *u;
+       java_handle_t *o;
+
+       h = (java_handle_t *) _this;
+       t = thread_get_thread(h);
+
+       state = cacaothread_get_state(t);
+       
+       switch (state) {
+       case THREAD_STATE_NEW:
+               u = utf_new_char("NEW");
+               break;
+       case THREAD_STATE_RUNNABLE:
+               u = utf_new_char("RUNNABLE");
+               break;
+       case THREAD_STATE_BLOCKED:
+               u = utf_new_char("BLOCKED");
+               break;
+       case THREAD_STATE_WAITING:
+               u = utf_new_char("WAITING");
+               break;
+       case THREAD_STATE_TIMED_WAITING:
+               u = utf_new_char("TIMED_WAITING");
+               break;
+       case THREAD_STATE_TERMINATED:
+               u = utf_new_char("TERMINATED");
+               break;
+       default:
+               vm_abort("Java_java_lang_VMThread_getState: unknown thread state %d", state);
+
+               /* Keep compiler happy. */
+
+               u = NULL;
+       }
+
+       o = javastring_new(u);
+
+       return (jstring) o;
+#else
+       return NULL;
+#endif
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "countStackFrames",  (char*) "()I",                      (void*) (uintptr_t) &Java_java_lang_VMThread_countStackFrames  },
+       { (char*) "start",             (char*) "(J)V",                     (void*) (uintptr_t) &Java_java_lang_VMThread_start             },
+       { (char*) "interrupt",         (char*) "()V",                      (void*) (uintptr_t) &Java_java_lang_VMThread_interrupt         },
+       { (char*) "isInterrupted",     (char*) "()Z",                      (void*) (uintptr_t) &Java_java_lang_VMThread_isInterrupted     },
+       { (char*) "suspend",           (char*) "()V",                      (void*) (uintptr_t) &Java_java_lang_VMThread_suspend           },
+       { (char*) "resume",            (char*) "()V",                      (void*) (uintptr_t) &Java_java_lang_VMThread_resume            },
+       { (char*) "nativeSetPriority", (char*) "(I)V",                     (void*) (uintptr_t) &Java_java_lang_VMThread_nativeSetPriority },
+       { (char*) "nativeStop",        (char*) "(Ljava/lang/Throwable;)V", (void*) (uintptr_t) &Java_java_lang_VMThread_nativeStop        },
+       { (char*) "currentThread",     (char*) "()Ljava/lang/Thread;",     (void*) (uintptr_t) &Java_java_lang_VMThread_currentThread     },
+       { (char*) "yield",             (char*) "()V",                      (void*) (uintptr_t) &Java_java_lang_VMThread_yield             },
+       { (char*) "sleep",             (char*) "(JI)V",                    (void*) (uintptr_t) &Java_java_lang_VMThread_sleep             },
+       { (char*) "interrupted",       (char*) "()Z",                      (void*) (uintptr_t) &Java_java_lang_VMThread_interrupted       },
+       { (char*) "holdsLock",         (char*) "(Ljava/lang/Object;)Z",    (void*) (uintptr_t) &Java_java_lang_VMThread_holdsLock         },
+       { (char*) "getState",          (char*) "()Ljava/lang/String;",     (void*) (uintptr_t) &Java_java_lang_VMThread_getState          },
+};
+
+
+/* _Jv_java_lang_VMThread_init *************************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_VMThread_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/VMThread");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_VMThrowable.c b/src/native/vm/gnuclasspath/java_lang_VMThrowable.c
deleted file mode 100644 (file)
index 29d6f65..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/* src/native/vm/gnu/java_lang_VMThrowable.c
-
-   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 "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_StackTraceElement.h"
-#include "native/include/java_lang_Throwable.h"
-
-#include "native/include/java_lang_VMThrowable.h"
-
-#include "vm/array.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-
-#include "vm/jit/code.h"
-#include "vm/jit/linenumbertable.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "fillInStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/VMThrowable;",        (void *) (ptrint) &Java_java_lang_VMThrowable_fillInStackTrace },
-       { "getStackTrace",    "(Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;", (void *) (ptrint) &Java_java_lang_VMThrowable_getStackTrace    },
-};
-
-
-/* _Jv_java_lang_VMThrowable_init **********************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_VMThrowable_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/VMThrowable");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/VMThrowable
- * Method:    fillInStackTrace
- * Signature: (Ljava/lang/Throwable;)Ljava/lang/VMThrowable;
- */
-JNIEXPORT java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
-{
-       java_lang_VMThrowable   *vmto;
-       java_handle_bytearray_t *ba;
-       java_lang_Object        *o;
-
-       vmto = (java_lang_VMThrowable *)
-               native_new_and_init(class_java_lang_VMThrowable);
-
-       if (vmto == NULL)
-               return NULL;
-
-       ba = stacktrace_get_current();
-
-       if (ba == NULL)
-               return NULL;
-
-       o = (java_lang_Object *) ba;
-
-       LLNI_field_set_ref(vmto, vmdata, o);
-
-       return vmto;
-}
-
-
-/*
- * Class:     java/lang/VMThrowable
- * Method:    getStackTrace
- * Signature: (Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, java_lang_VMThrowable *this, java_lang_Throwable *t)
-{
-       java_lang_Object            *o;
-       java_handle_bytearray_t     *ba;
-       stacktrace_t                *st;
-       stacktrace_entry_t          *ste;
-       java_handle_objectarray_t   *oa;
-       java_lang_StackTraceElement *steo;
-       codeinfo                    *code;
-       methodinfo                  *m;
-       java_lang_String            *filename;
-       s4                           linenumber;
-       java_handle_t               *declaringclass;
-       int                          i;
-
-       /* Get the stacktrace from the VMThrowable object. */
-
-       LLNI_field_get_ref(this, vmdata, o);
-
-       ba = (java_handle_bytearray_t *) o;
-
-       st = (stacktrace_t *) LLNI_array_data(ba);
-
-       assert(st != NULL);
-
-       ste = st->entries;
-
-       /* Create the stacktrace element array. */
-
-       oa = builtin_anewarray(st->length, class_java_lang_StackTraceElement);
-
-       if (oa == NULL)
-               return NULL;
-
-       for (i = 0; i < st->length; i++, ste++) {
-               /* allocate a new stacktrace element */
-
-               steo = (java_lang_StackTraceElement *)
-                       builtin_new(class_java_lang_StackTraceElement);
-
-               if (steo == NULL)
-                       return NULL;
-
-               /* Get the codeinfo and methodinfo. */
-
-               code = ste->code;
-               m    = code->m;
-
-               /* Get filename. */
-
-               if (!(m->flags & ACC_NATIVE)) {
-                       if (m->clazz->sourcefile)
-                               filename = (java_lang_String *) javastring_new(m->clazz->sourcefile);
-                       else
-                               filename = NULL;
-               }
-               else
-                       filename = NULL;
-
-               /* get line number */
-
-               if (m->flags & ACC_NATIVE) {
-                       linenumber = -1;
-               }
-               else {
-                       /* FIXME The linenumbertable_linenumber_for_pc could
-                          change the methodinfo pointer when hitting an inlined
-                          method. */
-
-                       linenumber = linenumbertable_linenumber_for_pc(&m, code, ste->pc);
-                       linenumber = (linenumber == 0) ? -1 : linenumber;
-               }
-
-               /* get declaring class name */
-
-               declaringclass = class_get_classname(m->clazz);
-
-               /* Fill the java.lang.StackTraceElement object. */
-
-               LLNI_field_set_ref(steo, fileName      , filename);
-               LLNI_field_set_val(steo, lineNumber    , linenumber);
-               LLNI_field_set_ref(steo, declaringClass, (java_lang_String*) declaringclass);
-               LLNI_field_set_ref(steo, methodName    , (java_lang_String *) javastring_new(m->name));
-               LLNI_field_set_val(steo, isNative      , (m->flags & ACC_NATIVE) ? 1 : 0);
-
-               array_objectarray_element_set(oa, i, (java_handle_t *) steo);
-       }
-
-       return oa;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/java_lang_VMThrowable.cpp b/src/native/vm/gnuclasspath/java_lang_VMThrowable.cpp
new file mode 100644 (file)
index 0000000..64247cd
--- /dev/null
@@ -0,0 +1,207 @@
+/* src/native/vm/gnuclasspath/java_lang_VMThrowable.cpp
+
+   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 <stdint.h>
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_VMThrowable.h"
+#endif
+
+#include "vm/array.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/loader.h"
+#include "vm/string.hpp"
+
+#include "vm/jit/code.h"
+#include "vm/jit/linenumbertable.h"
+#include "vm/jit/stacktrace.hpp"
+
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/VMThrowable
+ * Method:    fillInStackTrace
+ * Signature: (Ljava/lang/Throwable;)Ljava/lang/VMThrowable;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, jobject t)
+{
+       java_handle_t* h;
+       java_handle_bytearray_t* ba;
+
+       h = native_new_and_init(class_java_lang_VMThrowable);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_VMThrowable vmt(h);
+
+       ba = stacktrace_get_current();
+
+       if (ba == NULL)
+               return NULL;
+
+       vmt.set_vmdata(ba);
+
+       return (jobject) vmt.get_handle();
+}
+
+
+/*
+ * Class:     java/lang/VMThrowable
+ * Method:    getStackTrace
+ * Signature: (Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, jobject _this, jobject t)
+{
+       java_lang_VMThrowable vmt(_this);
+
+       // Get the stacktrace from the VMThrowable object.
+
+       java_handle_bytearray_t* ba = vmt.get_vmdata();
+
+       // XXX Critical GC section?
+       stacktrace_t* st = (stacktrace_t*) LLNI_array_data(ba);
+
+       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 The linenumbertable_linenumber_for_pc could
+                          change the methodinfo pointer when hitting an inlined
+                          method. */
+
+                       linenumber = linenumbertable_linenumber_for_pc(&m, code, 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;
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "fillInStackTrace", (char*) "(Ljava/lang/Throwable;)Ljava/lang/VMThrowable;",        (void*) (uintptr_t) &Java_java_lang_VMThrowable_fillInStackTrace },
+       { (char*) "getStackTrace",    (char*) "(Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;", (void*) (uintptr_t) &Java_java_lang_VMThrowable_getStackTrace    },
+};
+
+
+/* _Jv_java_lang_VMThrowable_init **********************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+extern "C" {
+void _Jv_java_lang_VMThrowable_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/VMThrowable");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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 62e1a8ff815ffb95afb5d0ff95a5842c807bd395..8d1130ae560759b137f3c154acadfb93519d463c 100644 (file)
@@ -1,9 +1,7 @@
-/* src/native/vm/gnu/java_lang_management_VMManagementFactory.c
+/* src/native/vm/gnuclasspath/java_lang_management_VMManagementFactory.c
 
-   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.
 
 #include "native/jni.h"
 #include "native/native.h"
 
-#include "native/include/java_lang_management_VMManagementFactory.h"
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_management_VMManagementFactory.h"
+#endif
 
 #include "toolbox/logging.h"
 
 #include "vm/builtin.h"
-
-#include "vmcore/class.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getMemoryPoolNames",       "()[Ljava/lang/String;", (void *) (ptrint) &Java_java_lang_management_VMManagementFactory_getMemoryPoolNames       },
-       { "getMemoryManagerNames",    "()[Ljava/lang/String;", (void *) (ptrint) &Java_java_lang_management_VMManagementFactory_getMemoryManagerNames    },
-       { "getGarbageCollectorNames", "()[Ljava/lang/String;", (void *) (ptrint) &Java_java_lang_management_VMManagementFactory_getGarbageCollectorNames },
-};
-
-
-/* _Jv_java_lang_management_VMManagementFactory_init ***************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_management_VMManagementFactory_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/management/VMManagementFactory");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
+#include "vm/globals.hpp"
 
 
 /*
@@ -73,7 +47,7 @@ void _Jv_java_lang_management_VMManagementFactory_init(void)
  * Method:    getMemoryPoolNames
  * Signature: ()[Ljava/lang/String;
  */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_management_VMManagementFactory_getMemoryPoolNames(JNIEnv *env, jclass clazz)
+JNIEXPORT jobjectArray JNICALL Java_java_lang_management_VMManagementFactory_getMemoryPoolNames(JNIEnv *env, jclass clazz)
 {
        java_handle_objectarray_t *oa;
 
@@ -90,7 +64,7 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_management_VMManagem
  * Method:    getMemoryManagerNames
  * Signature: ()[Ljava/lang/String;
  */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_management_VMManagementFactory_getMemoryManagerNames(JNIEnv *env, jclass clazz)
+JNIEXPORT jobjectArray JNICALL Java_java_lang_management_VMManagementFactory_getMemoryManagerNames(JNIEnv *env, jclass clazz)
 {
        java_handle_objectarray_t *oa;
 
@@ -107,7 +81,7 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_management_VMManagem
  * Method:    getGarbageCollectorNames
  * Signature: ()[Ljava/lang/String;
  */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_management_VMManagementFactory_getGarbageCollectorNames(JNIEnv *env, jclass clazz)
+JNIEXPORT jobjectArray JNICALL Java_java_lang_management_VMManagementFactory_getGarbageCollectorNames(JNIEnv *env, jclass clazz)
 {
        java_handle_objectarray_t *oa;
 
@@ -119,6 +93,31 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_management_VMManagem
 }
 
 
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { "getMemoryPoolNames",       "()[Ljava/lang/String;", (void*) (uintptr_t) &Java_java_lang_management_VMManagementFactory_getMemoryPoolNames       },
+       { "getMemoryManagerNames",    "()[Ljava/lang/String;", (void*) (uintptr_t) &Java_java_lang_management_VMManagementFactory_getMemoryManagerNames    },
+       { "getGarbageCollectorNames", "()[Ljava/lang/String;", (void*) (uintptr_t) &Java_java_lang_management_VMManagementFactory_getGarbageCollectorNames },
+};
+
+
+/* _Jv_java_lang_management_VMManagementFactory_init ***************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+void _Jv_java_lang_management_VMManagementFactory_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/management/VMManagementFactory");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+
+
 /*
  * 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
diff --git a/src/native/vm/gnuclasspath/java_lang_reflect_VMConstructor.c b/src/native/vm/gnuclasspath/java_lang_reflect_VMConstructor.c
deleted file mode 100644 (file)
index db90cf9..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/* src/native/vm/gnu/java_lang_reflect_VMConstructor.c
-
-   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 <stdlib.h>
-
-#if defined(ENABLE_ANNOTATIONS)
-#include "vm/vm.h"
-#include "vm/exceptions.h"
-#endif
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-
-#if defined(ENABLE_ANNOTATIONS)
-# include "native/include/java_util_Map.h"
-# include "native/include/sun_reflect_ConstantPool.h"
-#endif
-
-#include "native/include/java_lang_reflect_Constructor.h"
-#include "native/include/java_lang_reflect_VMConstructor.h"
-
-#include "native/vm/reflect.h"
-
-#include "vm/stringlocal.h"
-
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getModifiersInternal",    "()I",                                                       (void *) (intptr_t) &Java_java_lang_reflect_VMConstructor_getModifiersInternal    },
-       { "getParameterTypes",       "()[Ljava/lang/Class;",                                      (void *) (intptr_t) &Java_java_lang_reflect_VMConstructor_getParameterTypes       },
-       { "getExceptionTypes",       "()[Ljava/lang/Class;",                                      (void *) (intptr_t) &Java_java_lang_reflect_VMConstructor_getExceptionTypes       },
-       { "construct",               "([Ljava/lang/Object;)Ljava/lang/Object;",                   (void *) (intptr_t) &Java_java_lang_reflect_VMConstructor_construct               },
-       { "getSignature",            "()Ljava/lang/String;",                                      (void *) (intptr_t) &Java_java_lang_reflect_VMConstructor_getSignature            },
-#if defined(ENABLE_ANNOTATIONS)
-       { "declaredAnnotations",     "()Ljava/util/Map;",                                         (void *) (intptr_t) &Java_java_lang_reflect_VMConstructor_declaredAnnotations     },
-       { "getParameterAnnotations", "()[[Ljava/lang/annotation/Annotation;",                     (void *) (intptr_t) &Java_java_lang_reflect_VMConstructor_getParameterAnnotations },
-#endif
-};
-
-
-/* _Jv_java_lang_reflect_VMConstructor_init ************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_reflect_VMConstructor_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/reflect/VMConstructor");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/reflect/VMConstructor
- * Method:    getModifiersInternal
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMConstructor_getModifiersInternal(JNIEnv *env, java_lang_reflect_VMConstructor *this)
-{
-       classinfo  *c;
-       methodinfo *m;
-       int32_t     slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot,  slot);
-
-       m = &(c->methods[slot]);
-
-       return m->flags;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMConstructor
- * Method:    getParameterTypes
- * Signature: ()[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_reflect_VMConstructor_getParameterTypes(JNIEnv *env, java_lang_reflect_VMConstructor *this)
-{
-       classinfo  *c;
-       methodinfo *m;
-       int32_t     slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot,  slot);
-
-       m = &(c->methods[slot]);
-
-       return method_get_parametertypearray(m);
-}
-
-
-/*
- * Class:     java/lang/reflect/VMConstructor
- * Method:    getExceptionTypes
- * Signature: ()[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_reflect_VMConstructor_getExceptionTypes(JNIEnv *env, java_lang_reflect_VMConstructor *this)
-{
-       classinfo  *c;
-       methodinfo *m;
-       int32_t     slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot,  slot);
-
-       m = &(c->methods[slot]);
-
-       return method_get_exceptionarray(m);
-}
-
-
-/*
- * Class:     java/lang/reflect/VMConstructor
- * Method:    construct
- * Signature: ([Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_VMConstructor_construct(JNIEnv *env, java_lang_reflect_VMConstructor *this, java_handle_objectarray_t *args)
-{
-       classinfo                     *c;
-       int32_t                        slot;
-       java_lang_reflect_Constructor *rc;
-       int32_t                        override;
-       methodinfo                    *m;
-       java_handle_t                 *o;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot,  slot);
-
-       LLNI_field_get_ref(this, cons,  rc);
-       LLNI_field_get_val(rc,   flag,  override);
-
-       m = &(c->methods[slot]);
-
-       o = reflect_constructor_newinstance(m, args, override);
-
-       return (java_lang_Object *) o;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMConstructor
- * Method:    getSignature
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_VMConstructor_getSignature(JNIEnv *env, java_lang_reflect_VMConstructor *this)
-{
-       classinfo     *c;
-       methodinfo    *m;
-       java_handle_t *o;
-       int32_t        slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot,  slot);
-
-       m = &(c->methods[slot]);
-
-       if (m->signature == NULL)
-               return NULL;
-
-       o = javastring_new(m->signature);
-
-       /* In error case o is NULL. */
-
-       return (java_lang_String *) o;
-}
-
-
-#if defined(ENABLE_ANNOTATIONS)
-/*
- * Class:     java/lang/reflect/VMConstructor
- * Method:    declaredAnnotations
- * Signature: ()Ljava/util/Map;
- *
- * Parses the annotations (if they aren't parsed yet) and stores them into
- * the declaredAnnotations map and return this map.
- */
-JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_VMConstructor_declaredAnnotations(JNIEnv *env, java_lang_reflect_VMConstructor *this)
-{
-       java_util_Map           *declaredAnnotations = NULL; /* parsed annotations                                */
-       java_handle_bytearray_t *annotations         = NULL; /* unparsed annotations                              */
-       java_lang_Class         *declaringClass      = NULL; /* the constant pool of this class is used           */
-       classinfo               *referer             = NULL; /* class, which calles the annotation parser         */
-                                                            /* (for the parameter 'referer' of vm_call_method()) */
-
-       LLNI_field_get_ref(this, declaredAnnotations, declaredAnnotations);
-
-       /* are the annotations parsed yet? */
-       if (declaredAnnotations == NULL) {
-               LLNI_field_get_ref(this, annotations, annotations);
-               LLNI_field_get_ref(this, clazz, declaringClass);
-               LLNI_class_get(this, referer);
-
-               declaredAnnotations = reflect_get_declaredannotatios(annotations, declaringClass, referer);
-
-               LLNI_field_set_ref(this, declaredAnnotations, declaredAnnotations);
-       }
-
-       return declaredAnnotations;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMConstructor
- * Method:    getParameterAnnotations
- * Signature: ()[[Ljava/lang/annotation/Annotation;
- *
- * Parses the parameter annotations and returns them in an 2 dimensional array.
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_reflect_VMConstructor_getParameterAnnotations(JNIEnv *env, java_lang_reflect_VMConstructor *this)
-{
-       java_handle_bytearray_t *parameterAnnotations = NULL; /* unparsed parameter annotations                    */
-       int32_t                  slot                 = -1;   /* slot of the method                                */
-       java_lang_Class         *declaringClass       = NULL; /* the constant pool of this class is used           */
-       classinfo               *referer              = NULL; /* class, which calles the annotation parser         */
-                                                             /* (for the parameter 'referer' of vm_call_method()) */
-
-       LLNI_field_get_ref(this, parameterAnnotations, parameterAnnotations);
-       LLNI_field_get_val(this, slot, slot);
-       LLNI_field_get_ref(this, clazz, declaringClass);
-       LLNI_class_get(this, referer);
-
-       return reflect_get_parameterannotations((java_handle_t*)parameterAnnotations, slot, declaringClass, referer);
-}
-#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/native/vm/gnuclasspath/java_lang_reflect_VMConstructor.cpp b/src/native/vm/gnuclasspath/java_lang_reflect_VMConstructor.cpp
new file mode 100644 (file)
index 0000000..a22bdac
--- /dev/null
@@ -0,0 +1,234 @@
+/* src/native/vm/gnuclasspath/java_lang_reflect_VMConstructor.cpp
+
+   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 <stdlib.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_reflect_VMConstructor.h"
+#endif
+
+#include "native/vm/reflection.hpp"
+
+#include "vm/javaobjects.hpp"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/reflect/VMConstructor
+ * Method:    getModifiersInternal
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_reflect_VMConstructor_getModifiersInternal(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMConstructor rvmc(_this);
+       methodinfo* m = rvmc.get_method();
+       return m->flags;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMConstructor
+ * Method:    getParameterTypes
+ * Signature: ()[Ljava/lang/Class;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMConstructor_getParameterTypes(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMConstructor rvmc(_this);
+       methodinfo* m = rvmc.get_method();
+
+       java_handle_objectarray_t* hoa = method_get_parametertypearray(m);
+
+       return (jobjectArray) hoa;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMConstructor
+ * Method:    getExceptionTypes
+ * Signature: ()[Ljava/lang/Class;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMConstructor_getExceptionTypes(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMConstructor rvmc(_this);
+       methodinfo* m = rvmc.get_method();
+
+       java_handle_objectarray_t* hoa = method_get_exceptionarray(m);
+
+       return (jobjectArray) hoa;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMConstructor
+ * Method:    construct
+ * Signature: ([Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMConstructor_construct(JNIEnv *env, jobject _this, jobjectArray args)
+{
+       java_lang_reflect_VMConstructor jlrvmc(_this);
+       java_lang_reflect_Constructor jlrc(jlrvmc.get_cons());
+
+       java_handle_t* o = jlrc.new_instance((java_handle_objectarray_t*) args);
+
+       return (jobject) o;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMConstructor
+ * Method:    getSignature
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_reflect_VMConstructor_getSignature(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMConstructor rvmc(_this);
+       methodinfo* m = rvmc.get_method();
+       java_handle_t *o;
+
+       if (m->signature == NULL)
+               return NULL;
+
+       o = javastring_new(m->signature);
+
+       /* In error case o is NULL. */
+
+       return (jstring) o;
+}
+
+
+#if defined(ENABLE_ANNOTATIONS)
+/*
+ * Class:     java/lang/reflect/VMConstructor
+ * Method:    declaredAnnotations
+ * Signature: ()Ljava/util/Map;
+ *
+ * Parses the annotations (if they aren't parsed yet) and stores them into
+ * the declaredAnnotations map and return this map.
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMConstructor_declaredAnnotations(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMConstructor rvmc(_this);
+
+       java_handle_t* declaredAnnotations = rvmc.get_declaredAnnotations();
+
+       /* are the annotations parsed yet? */
+       if (declaredAnnotations == NULL) {
+               java_handle_bytearray_t* annotations    = rvmc.get_annotations();
+               classinfo*               declaringClass = rvmc.get_clazz();
+
+               classinfo *referer;
+               LLNI_class_get(_this, referer);
+
+               declaredAnnotations = Reflection::get_declaredannotations(annotations, declaringClass, referer);
+
+               rvmc.set_declaredAnnotations(declaredAnnotations);
+       }
+
+       return (jobject) declaredAnnotations;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMConstructor
+ * Method:    getParameterAnnotations
+ * Signature: ()[[Ljava/lang/annotation/Annotation;
+ *
+ * Parses the parameter annotations and returns them in an 2 dimensional array.
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMConstructor_getParameterAnnotations(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMConstructor rvmc(_this);
+
+       java_handle_bytearray_t* parameterAnnotations = rvmc.get_parameterAnnotations();
+       methodinfo* m = rvmc.get_method();
+
+       classinfo* referer;
+       LLNI_class_get((java_lang_reflect_VMConstructor*) _this, referer);
+
+       java_handle_objectarray_t* oa = Reflection::get_parameterannotations(parameterAnnotations, m, referer);
+
+       return (jobjectArray) oa;
+}
+#endif
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getModifiersInternal",    (char*) "()I",                                     (void*) (uintptr_t) &Java_java_lang_reflect_VMConstructor_getModifiersInternal    },
+       { (char*) "getParameterTypes",       (char*) "()[Ljava/lang/Class;",                    (void*) (uintptr_t) &Java_java_lang_reflect_VMConstructor_getParameterTypes       },
+       { (char*) "getExceptionTypes",       (char*) "()[Ljava/lang/Class;",                    (void*) (uintptr_t) &Java_java_lang_reflect_VMConstructor_getExceptionTypes       },
+       { (char*) "construct",               (char*) "([Ljava/lang/Object;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_java_lang_reflect_VMConstructor_construct               },
+       { (char*) "getSignature",            (char*) "()Ljava/lang/String;",                    (void*) (uintptr_t) &Java_java_lang_reflect_VMConstructor_getSignature            },
+#if defined(ENABLE_ANNOTATIONS)
+       { (char*) "declaredAnnotations",     (char*) "()Ljava/util/Map;",                       (void*) (uintptr_t) &Java_java_lang_reflect_VMConstructor_declaredAnnotations     },
+       { (char*) "getParameterAnnotations", (char*) "()[[Ljava/lang/annotation/Annotation;",   (void*) (uintptr_t) &Java_java_lang_reflect_VMConstructor_getParameterAnnotations },
+#endif
+};
+
+
+/* _Jv_java_lang_reflect_VMConstructor_init ************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+extern "C" {
+void _Jv_java_lang_reflect_VMConstructor_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/reflect/VMConstructor");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_reflect_VMField.c b/src/native/vm/gnuclasspath/java_lang_reflect_VMField.c
deleted file mode 100644 (file)
index b3da621..0000000
+++ /dev/null
@@ -1,1345 +0,0 @@
-/* src/native/vm/gnu/java_lang_reflect_VMField.c
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Boolean.h"
-#include "native/include/java_lang_Byte.h"
-#include "native/include/java_lang_Character.h"
-#include "native/include/java_lang_Short.h"
-#include "native/include/java_lang_Integer.h"
-#include "native/include/java_lang_Long.h"
-#include "native/include/java_lang_Float.h"
-#include "native/include/java_lang_Double.h"
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_String.h"
-
-#include "native/include/java_lang_reflect_Field.h"
-#include "native/include/java_lang_reflect_VMField.h"
-
-#if defined(ENABLE_ANNOTATIONS)
-#include "native/include/java_util_Map.h"
-#include "native/include/sun_reflect_ConstantPool.h"
-#include "native/vm/reflect.h"
-#endif
-
-#include "vm/access.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/initialize.h"
-#include "vm/primitive.h"
-#include "vm/resolve.h"
-#include "vm/stringlocal.h"
-
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/loader.h"
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getModifiersInternal", "()I",                                     (void *) (intptr_t) &Java_java_lang_reflect_VMField_getModifiersInternal },
-       { "getType",              "()Ljava/lang/Class;",                     (void *) (intptr_t) &Java_java_lang_reflect_VMField_getType              },
-       { "get",                  "(Ljava/lang/Object;)Ljava/lang/Object;",  (void *) (intptr_t) &Java_java_lang_reflect_VMField_get                  },
-       { "getBoolean",           "(Ljava/lang/Object;)Z",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getBoolean           },
-       { "getByte",              "(Ljava/lang/Object;)B",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getByte              },
-       { "getChar",              "(Ljava/lang/Object;)C",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getChar              },
-       { "getShort",             "(Ljava/lang/Object;)S",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getShort             },
-       { "getInt",               "(Ljava/lang/Object;)I",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getInt               },
-       { "getLong",              "(Ljava/lang/Object;)J",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getLong              },
-       { "getFloat",             "(Ljava/lang/Object;)F",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getFloat             },
-       { "getDouble",            "(Ljava/lang/Object;)D",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getDouble            },
-       { "set",                  "(Ljava/lang/Object;Ljava/lang/Object;)V", (void *) (intptr_t) &Java_java_lang_reflect_VMField_set                  },
-       { "setBoolean",           "(Ljava/lang/Object;Z)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setBoolean           },
-       { "setByte",              "(Ljava/lang/Object;B)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setByte              },
-       { "setChar",              "(Ljava/lang/Object;C)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setChar              },
-       { "setShort",             "(Ljava/lang/Object;S)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setShort             },
-       { "setInt",               "(Ljava/lang/Object;I)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setInt               },
-       { "setLong",              "(Ljava/lang/Object;J)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setLong              },
-       { "setFloat",             "(Ljava/lang/Object;F)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setFloat             },
-       { "setDouble",            "(Ljava/lang/Object;D)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setDouble            },
-       { "getSignature",         "()Ljava/lang/String;",                    (void *) (intptr_t) &Java_java_lang_reflect_VMField_getSignature         },
-#if defined(ENABLE_ANNOTATIONS)
-       { "declaredAnnotations",  "()Ljava/util/Map;",                       (void *) (intptr_t) &Java_java_lang_reflect_VMField_declaredAnnotations  },
-#endif
-};
-
-
-/* _Jv_java_lang_reflect_VMField_init ******************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_reflect_VMField_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/reflect/VMField");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/* _field_access_check *********************************************************
-
-   Checks if the field can be accessed.
-
-   RETURN VALUE:
-      true......field can be accessed, or
-      false.....otherwise (maybe an Exception was thrown).
-
-*******************************************************************************/
-
-static bool _field_access_check(java_lang_reflect_VMField *this,
-                                                               fieldinfo *f, classinfo *c, java_handle_t *o)
-{
-       java_lang_reflect_Field *rf;
-       int32_t                  flag;
-
-       /* check if we should bypass security checks (AccessibleObject) */
-
-       LLNI_field_get_ref(this, f, rf);
-       LLNI_field_get_val(rf, flag, flag);
-
-       if (flag == false) {
-               /* This function is always called like this:
-                      [0] java.lang.reflect.VMField.xxx (Native Method)
-                      [1] java.lang.reflect.Field.xxx
-                      [2] <caller>
-               */
-
-               if (!access_check_field(f, 2))
-                       return false;
-       }
-
-       /* some general checks */
-
-       if (f->flags & ACC_STATIC) {
-               /* initialize class if required */
-
-               if (!(c->state & CLASS_INITIALIZED))
-                       if (!initialize_class(c))
-                               return false;
-
-               /* everything is ok */
-
-               return true;
-       }
-       else {
-               /* obj is required for not-static fields */
-
-               if (o == NULL) {
-                       exceptions_throw_nullpointerexception();
-                       return false;
-               }
-       
-               if (builtin_instanceof(o, c))
-                       return true;
-       }
-
-       /* exception path */
-
-       exceptions_throw_illegalargumentexception();
-       return false;
-}
-
-
-/* _field_get_type *************************************************************
-
-   Returns the content of the given field.
-
-*******************************************************************************/
-
-#define _FIELD_GET_TYPE(name, type, uniontype) \
-static inline type _field_get_##name(fieldinfo *f, java_lang_Object *o) \
-{ \
-       type ret; \
-       if (f->flags & ACC_STATIC) { \
-               ret = f->value->uniontype; \
-       } else { \
-               LLNI_CRITICAL_START; \
-               ret = *(type *) (((intptr_t) LLNI_DIRECT(o)) + f->offset); \
-               LLNI_CRITICAL_END; \
-       } \
-       return ret; \
-}
-
-static inline java_handle_t *_field_get_handle(fieldinfo *f, java_lang_Object *o)
-{
-       java_object_t *obj;
-       java_handle_t *hdl;
-
-       LLNI_CRITICAL_START;
-
-       if (f->flags & ACC_STATIC) {
-               obj = f->value->a;
-       } else {
-               obj = *(java_object_t **) (((intptr_t) LLNI_DIRECT(o)) + f->offset);
-       }
-
-       hdl = LLNI_WRAP(obj);
-
-       LLNI_CRITICAL_END;
-
-       return hdl;
-}
-
-_FIELD_GET_TYPE(int,    int32_t, i)
-_FIELD_GET_TYPE(long,   int64_t, l)
-_FIELD_GET_TYPE(float,  float,   f)
-_FIELD_GET_TYPE(double, double,  d)
-
-
-/* _field_set_type *************************************************************
-
-   Sets the content of the given field to the given value.
-
-*******************************************************************************/
-
-#define _FIELD_SET_TYPE(name, type, uniontype) \
-static inline void _field_set_##name(fieldinfo *f, java_lang_Object *o, type value) \
-{ \
-       if (f->flags & ACC_STATIC) { \
-               f->value->uniontype = value; \
-       } else { \
-               LLNI_CRITICAL_START; \
-               *(type *) (((intptr_t) LLNI_DIRECT(o)) + f->offset) = value; \
-               LLNI_CRITICAL_END; \
-       } \
-}
-
-static inline void _field_set_handle(fieldinfo *f, java_lang_Object *o, java_handle_t *value)
-{
-       LLNI_CRITICAL_START;
-
-       if (f->flags & ACC_STATIC) {
-               f->value->a = LLNI_DIRECT(value);
-       } else {
-               *(java_object_t **) (((intptr_t) LLNI_DIRECT(o)) + f->offset) = LLNI_DIRECT(value);
-       }
-
-       LLNI_CRITICAL_END;
-}
-
-_FIELD_SET_TYPE(int,    int32_t, i)
-_FIELD_SET_TYPE(long,   int64_t, l)
-_FIELD_SET_TYPE(float,  float,   f)
-_FIELD_SET_TYPE(double, double,  d)
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getModifiersInternal
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getModifiersInternal(JNIEnv *env, java_lang_reflect_VMField *this)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &(c->fields[slot]);
-
-       return f->flags;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getType
- * Signature: ()Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_VMField_getType(JNIEnv *env, java_lang_reflect_VMField *this)
-{
-       classinfo *c;
-       typedesc  *desc;
-       classinfo *ret;
-       int32_t    slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       desc = c->fields[slot].parseddesc;
-
-       if (desc == NULL)
-               return NULL;
-
-       if (!resolve_class_from_typedesc(desc, true, false, &ret))
-               return NULL;
-       
-       return LLNI_classinfo_wrap(ret);
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    get
- * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_VMField_get(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-       imm_union  value;
-       java_handle_t *object;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return NULL;
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BOOLEAN:
-       case PRIMITIVETYPE_BYTE:
-       case PRIMITIVETYPE_CHAR:
-       case PRIMITIVETYPE_SHORT:
-       case PRIMITIVETYPE_INT:
-               value.i = _field_get_int(f, o);
-               break;
-
-       case PRIMITIVETYPE_LONG:
-               value.l = _field_get_long(f, o);
-               break;
-
-       case PRIMITIVETYPE_FLOAT:
-               value.f = _field_get_float(f, o);
-               break;
-
-       case PRIMITIVETYPE_DOUBLE:
-               value.d = _field_get_double(f, o);
-               break;
-
-       case TYPE_ADR:
-               return (java_lang_Object *) _field_get_handle(f, o);
-       }
-
-       /* Now box the primitive types. */
-
-       object = primitive_box(f->parseddesc->decltype, value);
-
-       return (java_lang_Object *) object;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getBoolean
- * Signature: (Ljava/lang/Object;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getBoolean(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return 0;
-
-       /* check the field type and return the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BOOLEAN:
-               return (int32_t) _field_get_int(f, o);
-       default:
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getByte
- * Signature: (Ljava/lang/Object;)B
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getByte(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return 0;
-
-       /* check the field type and return the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BYTE:
-               return (int32_t) _field_get_int(f, o);
-       default:
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getChar
- * Signature: (Ljava/lang/Object;)C
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getChar(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return 0;
-
-       /* check the field type and return the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_CHAR:
-               return (int32_t) _field_get_int(f, o);
-       default:
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getShort
- * Signature: (Ljava/lang/Object;)S
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getShort(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return 0;
-
-       /* check the field type and return the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BYTE:
-       case PRIMITIVETYPE_SHORT:
-               return (int32_t) _field_get_int(f, o);
-       default:
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getInt
- * Signature: (Ljava/lang/Object;)I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getInt(JNIEnv *env , java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return 0;
-
-       /* check the field type and return the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BYTE:
-       case PRIMITIVETYPE_CHAR:
-       case PRIMITIVETYPE_SHORT:
-       case PRIMITIVETYPE_INT:
-               return (int32_t) _field_get_int(f, o);
-       default:
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getLong
- * Signature: (Ljava/lang/Object;)J
- */
-JNIEXPORT int64_t JNICALL Java_java_lang_reflect_VMField_getLong(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return 0;
-
-       /* check the field type and return the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BYTE:
-       case PRIMITIVETYPE_CHAR:
-       case PRIMITIVETYPE_SHORT:
-       case PRIMITIVETYPE_INT:
-               return (int64_t) _field_get_int(f, o);
-       case PRIMITIVETYPE_LONG:
-               return (int64_t) _field_get_long(f, o);
-       default:
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getFloat
- * Signature: (Ljava/lang/Object;)F
- */
-JNIEXPORT float JNICALL Java_java_lang_reflect_VMField_getFloat(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return 0;
-
-       /* check the field type and return the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BYTE:
-       case PRIMITIVETYPE_CHAR:
-       case PRIMITIVETYPE_SHORT:
-       case PRIMITIVETYPE_INT:
-               return (float) _field_get_int(f, o);
-       case PRIMITIVETYPE_LONG:
-               return (float) _field_get_long(f, o);
-       case PRIMITIVETYPE_FLOAT:
-               return (float) _field_get_float(f, o);
-       default:
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getDouble
- * Signature: (Ljava/lang/Object;)D
- */
-JNIEXPORT double JNICALL Java_java_lang_reflect_VMField_getDouble(JNIEnv *env , java_lang_reflect_VMField *this, java_lang_Object *o)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return 0;
-
-       /* check the field type and return the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BYTE:
-       case PRIMITIVETYPE_CHAR:
-       case PRIMITIVETYPE_SHORT:
-       case PRIMITIVETYPE_INT:
-               return (double) _field_get_int(f, o);
-       case PRIMITIVETYPE_LONG:
-               return (double) _field_get_long(f, o);
-       case PRIMITIVETYPE_FLOAT:
-               return (double) _field_get_float(f, o);
-       case PRIMITIVETYPE_DOUBLE:
-               return (double) _field_get_double(f, o);
-       default:
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    set
- * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_set(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, java_lang_Object *value)
-{
-       classinfo *sc;
-       classinfo *dc;
-       fieldinfo *sf;
-       fieldinfo *df;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, dc);
-       LLNI_field_get_val(this, slot , slot);
-       df = &dc->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, df, dc, (java_handle_t *) o))
-               return;
-
-       /* get the source classinfo from the object */
-
-       if (value == NULL)
-               sc = NULL;
-       else
-               LLNI_class_get(value, sc);
-
-       /* The fieldid is used to set the new value, for primitive
-          types the value has to be retrieved from the wrapping
-          object */
-
-       switch (df->parseddesc->decltype) {
-       case PRIMITIVETYPE_BOOLEAN: {
-               int32_t val;
-
-               /* determine the field to read the value */
-
-               if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_Z)))
-                       break;
-
-               switch (sf->parseddesc->decltype) {
-               case PRIMITIVETYPE_BOOLEAN:
-                       LLNI_field_get_val((java_lang_Boolean *) value, value, val);
-                       break;
-               default:
-                       exceptions_throw_illegalargumentexception();
-                       return;
-               }
-
-               _field_set_int(df, o, val);
-               return;
-       }
-
-       case PRIMITIVETYPE_BYTE: {
-               int32_t val;
-
-               if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_B)))
-                       break;
-
-               switch (sf->parseddesc->decltype) {
-               case PRIMITIVETYPE_BYTE:
-                       LLNI_field_get_val((java_lang_Byte *) value, value, val);
-                       break;
-               default:        
-                       exceptions_throw_illegalargumentexception();
-                       return;
-               }
-
-               _field_set_int(df, o, val);
-               return;
-       }
-
-       case PRIMITIVETYPE_CHAR: {
-               int32_t val;
-
-               if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_C)))
-                       break;
-                                  
-               switch (sf->parseddesc->decltype) {
-               case PRIMITIVETYPE_CHAR:
-                       LLNI_field_get_val((java_lang_Character *) value, value, val);
-                       break;
-               default:
-                       exceptions_throw_illegalargumentexception();
-                       return;
-               }
-
-               _field_set_int(df, o, val);
-               return;
-       }
-
-       case PRIMITIVETYPE_SHORT: {
-               int32_t val;
-
-               /* get field only by name, it can be one of B, S */
-
-               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
-                       break;
-                                  
-               switch (sf->parseddesc->decltype) {
-               case PRIMITIVETYPE_BYTE:
-                       LLNI_field_get_val((java_lang_Byte *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_SHORT:
-                       LLNI_field_get_val((java_lang_Short *) value, value, val);
-                       break;
-               default:
-                       exceptions_throw_illegalargumentexception();
-                       return;
-               }
-
-               _field_set_int(df, o, val);
-               return;
-       }
-
-       case PRIMITIVETYPE_INT: {
-               int32_t val;
-
-               /* get field only by name, it can be one of B, S, C, I */
-
-               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
-                       break;
-
-               switch (sf->parseddesc->decltype) {
-               case PRIMITIVETYPE_BYTE:
-                       LLNI_field_get_val((java_lang_Byte *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_CHAR:
-                       LLNI_field_get_val((java_lang_Character *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_SHORT:
-                       LLNI_field_get_val((java_lang_Short *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_INT:
-                       LLNI_field_get_val((java_lang_Integer *) value, value, val);
-                       break;
-               default:
-                       exceptions_throw_illegalargumentexception();
-                       return;
-               }
-
-               _field_set_int(df, o, val);
-               return;
-       }
-
-       case PRIMITIVETYPE_LONG: {
-               int64_t val;
-
-               /* get field only by name, it can be one of B, S, C, I, J */
-
-               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
-                       break;
-
-               switch (sf->parseddesc->decltype) {
-               case PRIMITIVETYPE_BYTE:
-                       LLNI_field_get_val((java_lang_Byte *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_CHAR:
-                       LLNI_field_get_val((java_lang_Character *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_SHORT:
-                       LLNI_field_get_val((java_lang_Short *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_INT:
-                       LLNI_field_get_val((java_lang_Integer *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_LONG:
-                       LLNI_field_get_val((java_lang_Long *) value, value, val);
-                       break;
-               default:
-                       exceptions_throw_illegalargumentexception();
-                       return;
-               }
-
-               _field_set_long(df, o, val);
-               return;
-       }
-
-       case PRIMITIVETYPE_FLOAT: {
-               float val;
-
-               /* get field only by name, it can be one of B, S, C, I, J, F */
-
-               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
-                       break;
-
-               switch (sf->parseddesc->decltype) {
-               case PRIMITIVETYPE_BYTE:
-                       LLNI_field_get_val((java_lang_Byte *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_CHAR:
-                       LLNI_field_get_val((java_lang_Character *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_SHORT:
-                       LLNI_field_get_val((java_lang_Short *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_INT:
-                       LLNI_field_get_val((java_lang_Integer *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_LONG:
-                       LLNI_field_get_val((java_lang_Long *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_FLOAT:
-                       LLNI_field_get_val((java_lang_Float *) value, value, val);
-                       break;
-               default:
-                       exceptions_throw_illegalargumentexception();
-                       return;
-               }
-
-               _field_set_float(df, o, val);
-               return;
-       }
-
-       case PRIMITIVETYPE_DOUBLE: {
-               double val;
-
-               /* get field only by name, it can be one of B, S, C, I, J, F, D */
-
-               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
-                       break;
-
-               switch (sf->parseddesc->decltype) {
-               case PRIMITIVETYPE_BYTE:
-                       LLNI_field_get_val((java_lang_Byte *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_CHAR:
-                       LLNI_field_get_val((java_lang_Character *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_SHORT:
-                       LLNI_field_get_val((java_lang_Short *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_INT:
-                       LLNI_field_get_val((java_lang_Integer *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_LONG:
-                       LLNI_field_get_val((java_lang_Long *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_FLOAT:
-                       LLNI_field_get_val((java_lang_Float *) value, value, val);
-                       break;
-               case PRIMITIVETYPE_DOUBLE:
-                       LLNI_field_get_val((java_lang_Double *) value, value, val);
-                       break;
-               default:
-                       exceptions_throw_illegalargumentexception();
-                       return;
-               }
-
-               _field_set_double(df, o, val);
-               return;
-       }
-
-       case TYPE_ADR:
-               /* check if value is an instance of the destination class */
-
-               /* XXX TODO */
-               /*                      if (!builtin_instanceof((java_handle_t *) value, df->class)) */
-               /*                              break; */
-
-               _field_set_handle(df, o, (java_handle_t *) value);
-               return;
-       }
-
-       /* raise exception */
-
-       exceptions_throw_illegalargumentexception();
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    setBoolean
- * Signature: (Ljava/lang/Object;Z)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setBoolean(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return;
-
-       /* check the field type and set the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BOOLEAN:
-               _field_set_int(f, o, value);
-               break;
-       default:
-               exceptions_throw_illegalargumentexception();
-       }
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    setByte
- * Signature: (Ljava/lang/Object;B)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setByte(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return;
-
-       /* check the field type and set the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_BYTE:
-       case PRIMITIVETYPE_SHORT:
-       case PRIMITIVETYPE_INT:
-               _field_set_int(f, o, value);
-               break;
-       case PRIMITIVETYPE_LONG:
-               _field_set_long(f, o, value);
-               break;
-       case PRIMITIVETYPE_FLOAT:
-               _field_set_float(f, o, value);
-               break;
-       case PRIMITIVETYPE_DOUBLE:
-               _field_set_double(f, o, value);
-               break;
-       default:
-               exceptions_throw_illegalargumentexception();
-       }
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    setChar
- * Signature: (Ljava/lang/Object;C)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setChar(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return;
-
-       /* check the field type and set the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_CHAR:
-       case PRIMITIVETYPE_INT:
-               _field_set_int(f, o, value);
-               break;
-       case PRIMITIVETYPE_LONG:
-               _field_set_long(f, o, value);
-               break;
-       case PRIMITIVETYPE_FLOAT:
-               _field_set_float(f, o, value);
-               break;
-       case PRIMITIVETYPE_DOUBLE:
-               _field_set_double(f, o, value);
-               break;
-       default:
-               exceptions_throw_illegalargumentexception();
-       }
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    setShort
- * Signature: (Ljava/lang/Object;S)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setShort(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return;
-
-       /* check the field type and set the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_SHORT:
-       case PRIMITIVETYPE_INT:
-               _field_set_int(f, o, value);
-               break;
-       case PRIMITIVETYPE_LONG:
-               _field_set_long(f, o, value);
-               break;
-       case PRIMITIVETYPE_FLOAT:
-               _field_set_float(f, o, value);
-               break;
-       case PRIMITIVETYPE_DOUBLE:
-               _field_set_double(f, o, value);
-               break;
-       default:
-               exceptions_throw_illegalargumentexception();
-       }
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    setInt
- * Signature: (Ljava/lang/Object;I)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setInt(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return;
-
-       /* check the field type and set the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_INT:
-               _field_set_int(f, o, value);
-               break;
-       case PRIMITIVETYPE_LONG:
-               _field_set_long(f, o, value);
-               break;
-       case PRIMITIVETYPE_FLOAT:
-               _field_set_float(f, o, value);
-               break;
-       case PRIMITIVETYPE_DOUBLE:
-               _field_set_double(f, o, value);
-               break;
-       default:
-               exceptions_throw_illegalargumentexception();
-       }
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    setLong
- * Signature: (Ljava/lang/Object;J)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setLong(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int64_t value)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return;
-
-       /* check the field type and set the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_LONG:
-               _field_set_long(f, o, value);
-               break;
-       case PRIMITIVETYPE_FLOAT:
-               _field_set_float(f, o, value);
-               break;
-       case PRIMITIVETYPE_DOUBLE:
-               _field_set_double(f, o, value);
-               break;
-       default:
-               exceptions_throw_illegalargumentexception();
-       }
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    setFloat
- * Signature: (Ljava/lang/Object;F)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setFloat(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, float value)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return;
-
-       /* check the field type and set the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_FLOAT:
-               _field_set_float(f, o, value);
-               break;
-       case PRIMITIVETYPE_DOUBLE:
-               _field_set_double(f, o, value);
-               break;
-       default:
-               exceptions_throw_illegalargumentexception();
-       }
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    setDouble
- * Signature: (Ljava/lang/Object;D)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setDouble(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, double value)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       /* check if the field can be accessed */
-
-       if (!_field_access_check(this, f, c, (java_handle_t *) o))
-               return;
-
-       /* check the field type and set the value */
-
-       switch (f->parseddesc->decltype) {
-       case PRIMITIVETYPE_DOUBLE:
-               _field_set_double(f, o, value);
-               break;
-       default:
-               exceptions_throw_illegalargumentexception();
-       }
-
-       return;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    getSignature
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_VMField_getSignature(JNIEnv *env, java_lang_reflect_VMField* this)
-{
-       classinfo     *c;
-       fieldinfo     *f;
-       java_handle_t *o;
-       int32_t        slot;
-
-       /* get the class and the field */
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       f = &c->fields[slot];
-
-       if (f->signature == NULL)
-               return NULL;
-
-       o = javastring_new(f->signature);
-
-       /* in error case o is NULL */
-
-       return (java_lang_String *) o;
-}
-
-
-#if defined(ENABLE_ANNOTATIONS)
-/*
- * Class:     java/lang/reflect/VMField
- * Method:    declaredAnnotations
- * Signature: ()Ljava/util/Map;
- */
-JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_VMField_declaredAnnotations(JNIEnv *env, java_lang_reflect_VMField *this)
-{
-       java_util_Map           *declaredAnnotations = NULL; /* parsed annotations                                */
-       java_handle_bytearray_t *annotations         = NULL; /* unparsed annotations                              */
-       java_lang_Class         *declaringClass      = NULL; /* the constant pool of this class is used           */
-       classinfo               *referer             = NULL; /* class, which calles the annotation parser         */
-                                                            /* (for the parameter 'referer' of vm_call_method()) */
-
-       LLNI_field_get_ref(this, declaredAnnotations, declaredAnnotations);
-
-       /* are the annotations parsed yet? */
-       if (declaredAnnotations == NULL) {
-               LLNI_field_get_ref(this, annotations, annotations);
-               LLNI_field_get_ref(this, clazz, declaringClass);
-               LLNI_class_get(this, referer);
-
-               declaredAnnotations = reflect_get_declaredannotatios(annotations, declaringClass, referer);
-
-               LLNI_field_set_ref(this, declaredAnnotations, declaredAnnotations);
-       }
-
-       return declaredAnnotations;
-}
-#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/native/vm/gnuclasspath/java_lang_reflect_VMField.cpp b/src/native/vm/gnuclasspath/java_lang_reflect_VMField.cpp
new file mode 100644 (file)
index 0000000..d30e703
--- /dev/null
@@ -0,0 +1,1214 @@
+/* src/native/vm/gnuclasspath/java_lang_reflect_VMField.cpp
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_reflect_VMField.h"
+#endif
+
+#if defined(ENABLE_ANNOTATIONS)
+// REMOVEME
+# include "native/vm/reflection.hpp"
+#endif
+
+#include "vm/access.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+#include "vm/loader.h"
+#include "vm/primitive.hpp"
+#include "vm/resolve.h"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+
+
+/* _field_access_check *********************************************************
+
+   Checks if the field can be accessed.
+
+   RETURN VALUE:
+      true......field can be accessed, or
+      false.....otherwise (maybe an Exception was thrown).
+
+*******************************************************************************/
+
+static bool _field_access_check(const java_lang_reflect_VMField& rvmf, fieldinfo *f, java_handle_t *o)
+{
+       // Check if we should bypass security checks (AccessibleObject).
+
+       java_lang_reflect_Field rf(rvmf.get_f());
+       int32_t override = rf.get_flag();
+
+       if (override == false) {
+               /* This function is always called like this:
+                      [0] java.lang.reflect.VMField.xxx (Native Method)
+                      [1] java.lang.reflect.Field.xxx
+                      [2] <caller>
+               */
+
+               if (!access_check_field(f, 2))
+                       return false;
+       }
+
+       /* some general checks */
+
+       if (f->flags & ACC_STATIC) {
+               /* initialize class if required */
+
+               if (!(f->clazz->state & CLASS_INITIALIZED))
+                       if (!initialize_class(f->clazz))
+                               return false;
+
+               /* everything is ok */
+
+               return true;
+       }
+       else {
+               /* obj is required for not-static fields */
+
+               if (o == NULL) {
+                       exceptions_throw_nullpointerexception();
+                       return false;
+               }
+       
+               if (builtin_instanceof(o, f->clazz))
+                       return true;
+       }
+
+       /* exception path */
+
+       exceptions_throw_illegalargumentexception();
+       return false;
+}
+
+
+/* _field_get_type *************************************************************
+
+   Returns the content of the given field.
+
+*******************************************************************************/
+
+#define _FIELD_GET_TYPE(name, type, uniontype) \
+static inline type _field_get_##name(fieldinfo *f, java_handle_t* h) \
+{ \
+       type ret; \
+       if (f->flags & ACC_STATIC) { \
+               ret = f->value->uniontype; \
+       } else { \
+               LLNI_CRITICAL_START; \
+               ret = *(type *) (((intptr_t) LLNI_DIRECT(h)) + f->offset); \
+               LLNI_CRITICAL_END; \
+       } \
+       return ret; \
+}
+
+static inline java_handle_t *_field_get_handle(fieldinfo *f, java_handle_t* h)
+{
+       java_object_t* result;
+       java_handle_t* hresult;
+
+       LLNI_CRITICAL_START;
+
+       if (f->flags & ACC_STATIC) {
+               result = (java_object_t*) f->value->a;
+       } else {
+               result = *(java_object_t**) (((intptr_t) LLNI_DIRECT(h)) + f->offset);
+       }
+
+       hresult = LLNI_WRAP(result);
+
+       LLNI_CRITICAL_END;
+
+       return hresult;
+}
+
+_FIELD_GET_TYPE(int,    int32_t, i)
+_FIELD_GET_TYPE(long,   int64_t, l)
+_FIELD_GET_TYPE(float,  float,   f)
+_FIELD_GET_TYPE(double, double,  d)
+
+
+/* _field_set_type *************************************************************
+
+   Sets the content of the given field to the given value.
+
+*******************************************************************************/
+
+#define _FIELD_SET_TYPE(name, type, uniontype) \
+static inline void _field_set_##name(fieldinfo* f, java_handle_t* h, type value) \
+{ \
+       if (f->flags & ACC_STATIC) { \
+               f->value->uniontype = value; \
+       } else { \
+               LLNI_CRITICAL_START; \
+               *(type *) (((intptr_t) LLNI_DIRECT(h)) + f->offset) = value; \
+               LLNI_CRITICAL_END; \
+       } \
+}
+
+static inline void _field_set_handle(fieldinfo* f, java_handle_t* h, java_handle_t* hvalue)
+{
+       LLNI_CRITICAL_START;
+
+       if (f->flags & ACC_STATIC) {
+               f->value->a = LLNI_DIRECT(hvalue);
+       } else {
+               *(java_object_t**) (((intptr_t) LLNI_DIRECT(h)) + f->offset) = LLNI_DIRECT(hvalue);
+       }
+
+       LLNI_CRITICAL_END;
+}
+
+_FIELD_SET_TYPE(int,    int32_t, i)
+_FIELD_SET_TYPE(long,   int64_t, l)
+_FIELD_SET_TYPE(float,  float,   f)
+_FIELD_SET_TYPE(double, double,  d)
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getModifiersInternal
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_reflect_VMField_getModifiersInternal(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+       return f->flags;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getType
+ * Signature: ()Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_reflect_VMField_getType(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+       classinfo *ret;
+
+       typedesc* desc = f->parseddesc;
+
+       if (desc == NULL)
+               return NULL;
+
+       if (!resolve_class_from_typedesc(desc, true, false, &ret))
+               return NULL;
+       
+       return (jclass) LLNI_classinfo_wrap(ret);
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    get
+ * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMField_get(JNIEnv *env, jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return NULL;
+
+       imm_union value;
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BOOLEAN:
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               value.i = _field_get_int(f, ho);
+               break;
+
+       case PRIMITIVETYPE_LONG:
+               value.l = _field_get_long(f, ho);
+               break;
+
+       case PRIMITIVETYPE_FLOAT:
+               value.f = _field_get_float(f, ho);
+               break;
+
+       case PRIMITIVETYPE_DOUBLE:
+               value.d = _field_get_double(f, ho);
+               break;
+
+       case TYPE_ADR:
+               return (jobject) _field_get_handle(f, ho);
+       }
+
+       /* Now box the primitive types. */
+
+       java_handle_t* object = Primitive::box(f->parseddesc->primitivetype, value);
+
+       return (jobject) object;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getBoolean
+ * Signature: (Ljava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_reflect_VMField_getBoolean(JNIEnv *env, jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return 0;
+
+       /* check the field type and return the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BOOLEAN:
+               return (int32_t) _field_get_int(f, ho);
+       default:
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getByte
+ * Signature: (Ljava/lang/Object;)B
+ */
+JNIEXPORT jbyte JNICALL Java_java_lang_reflect_VMField_getByte(JNIEnv *env, jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return 0;
+
+       /* check the field type and return the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BYTE:
+               return (int32_t) _field_get_int(f, ho);
+       default:
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getChar
+ * Signature: (Ljava/lang/Object;)C
+ */
+JNIEXPORT jchar JNICALL Java_java_lang_reflect_VMField_getChar(JNIEnv *env, jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return 0;
+
+       /* check the field type and return the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_CHAR:
+               return (int32_t) _field_get_int(f, ho);
+       default:
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getShort
+ * Signature: (Ljava/lang/Object;)S
+ */
+JNIEXPORT jshort JNICALL Java_java_lang_reflect_VMField_getShort(JNIEnv *env, jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return 0;
+
+       /* check the field type and return the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_SHORT:
+               return (int32_t) _field_get_int(f, ho);
+       default:
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getInt
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_reflect_VMField_getInt(JNIEnv *env , jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return 0;
+
+       /* check the field type and return the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               return (int32_t) _field_get_int(f, ho);
+       default:
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getLong
+ * Signature: (Ljava/lang/Object;)J
+ */
+JNIEXPORT jlong JNICALL Java_java_lang_reflect_VMField_getLong(JNIEnv *env, jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return 0;
+
+       /* check the field type and return the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               return (int64_t) _field_get_int(f, ho);
+       case PRIMITIVETYPE_LONG:
+               return (int64_t) _field_get_long(f, ho);
+       default:
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getFloat
+ * Signature: (Ljava/lang/Object;)F
+ */
+JNIEXPORT jfloat JNICALL Java_java_lang_reflect_VMField_getFloat(JNIEnv *env, jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return 0;
+
+       /* check the field type and return the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               return (float) _field_get_int(f, ho);
+       case PRIMITIVETYPE_LONG:
+               return (float) _field_get_long(f, ho);
+       case PRIMITIVETYPE_FLOAT:
+               return (float) _field_get_float(f, ho);
+       default:
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getDouble
+ * Signature: (Ljava/lang/Object;)D
+ */
+JNIEXPORT jdouble JNICALL Java_java_lang_reflect_VMField_getDouble(JNIEnv *env , jobject _this, jobject o)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return 0;
+
+       /* check the field type and return the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               return (jdouble) _field_get_int(f, ho);
+       case PRIMITIVETYPE_LONG:
+               return (jdouble) _field_get_long(f, ho);
+       case PRIMITIVETYPE_FLOAT:
+               return (jdouble) _field_get_float(f, ho);
+       case PRIMITIVETYPE_DOUBLE:
+               return (jdouble) _field_get_double(f, ho);
+       default:
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    set
+ * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_set(JNIEnv *env, jobject _this, jobject o, jobject value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* df = rvmf.get_field();
+
+       java_handle_t* ho     = (java_handle_t*) o;
+       java_handle_t* hvalue = (java_handle_t*) value;
+
+       classinfo *sc;
+       fieldinfo *sf;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, df, ho))
+               return;
+
+       /* get the source classinfo from the object */
+
+       if (hvalue == NULL)
+               sc = NULL;
+       else
+               LLNI_class_get(hvalue, sc);
+
+       /* The fieldid is used to set the new value, for primitive
+          types the value has to be retrieved from the wrapping
+          object */
+
+       switch (df->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BOOLEAN: {
+               int32_t val;
+
+               /* determine the field to read the value */
+
+               if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_Z)))
+                       break;
+
+               switch (sf->parseddesc->primitivetype) {
+               case PRIMITIVETYPE_BOOLEAN:
+                       val = java_lang_Boolean(hvalue).get_value();
+                       break;
+               default:
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+
+               _field_set_int(df, ho, val);
+               return;
+       }
+
+       case PRIMITIVETYPE_BYTE: {
+               int32_t val;
+
+               if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_B)))
+                       break;
+
+               switch (sf->parseddesc->primitivetype) {
+               case PRIMITIVETYPE_BYTE:
+                       val = java_lang_Byte(hvalue).get_value();
+                       break;
+               default:        
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+
+               _field_set_int(df, ho, val);
+               return;
+       }
+
+       case PRIMITIVETYPE_CHAR: {
+               int32_t val;
+
+               if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_C)))
+                       break;
+                                  
+               switch (sf->parseddesc->primitivetype) {
+               case PRIMITIVETYPE_CHAR:
+                       val = java_lang_Character(hvalue).get_value();
+                       break;
+               default:
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+
+               _field_set_int(df, ho, val);
+               return;
+       }
+
+       case PRIMITIVETYPE_SHORT: {
+               int32_t val;
+
+               /* get field only by name, it can be one of B, S */
+
+               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
+                       break;
+                                  
+               switch (sf->parseddesc->primitivetype) {
+               case PRIMITIVETYPE_BYTE:
+                       val = java_lang_Byte(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_SHORT:
+                       val = java_lang_Short(hvalue).get_value();
+                       break;
+               default:
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+
+               _field_set_int(df, ho, val);
+               return;
+       }
+
+       case PRIMITIVETYPE_INT: {
+               int32_t val;
+
+               /* get field only by name, it can be one of B, S, C, I */
+
+               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
+                       break;
+
+               switch (sf->parseddesc->primitivetype) {
+               case PRIMITIVETYPE_BYTE:
+                       val = java_lang_Byte(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_CHAR:
+                       val = java_lang_Character(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_SHORT:
+                       val = java_lang_Short(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_INT:
+                       val = java_lang_Integer(hvalue).get_value();
+                       break;
+               default:
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+
+               _field_set_int(df, ho, val);
+               return;
+       }
+
+       case PRIMITIVETYPE_LONG: {
+               int64_t val;
+
+               /* get field only by name, it can be one of B, S, C, I, J */
+
+               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
+                       break;
+
+               switch (sf->parseddesc->primitivetype) {
+               case PRIMITIVETYPE_BYTE:
+                       val = java_lang_Byte(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_CHAR:
+                       val = java_lang_Character(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_SHORT:
+                       val = java_lang_Short(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_INT:
+                       val = java_lang_Integer(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_LONG:
+                       val = java_lang_Long(hvalue).get_value();
+                       break;
+               default:
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+
+               _field_set_long(df, ho, val);
+               return;
+       }
+
+       case PRIMITIVETYPE_FLOAT: {
+               float val;
+
+               /* get field only by name, it can be one of B, S, C, I, J, F */
+
+               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
+                       break;
+
+               switch (sf->parseddesc->primitivetype) {
+               case PRIMITIVETYPE_BYTE:
+                       val = java_lang_Byte(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_CHAR:
+                       val = java_lang_Character(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_SHORT:
+                       val = java_lang_Short(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_INT:
+                       val = java_lang_Integer(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_LONG:
+                       val = java_lang_Long(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_FLOAT:
+                       val = java_lang_Float(hvalue).get_value();
+                       break;
+               default:
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+
+               _field_set_float(df, ho, val);
+               return;
+       }
+
+       case PRIMITIVETYPE_DOUBLE: {
+               double val;
+
+               /* get field only by name, it can be one of B, S, C, I, J, F, D */
+
+               if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
+                       break;
+
+               switch (sf->parseddesc->primitivetype) {
+               case PRIMITIVETYPE_BYTE:
+                       val = java_lang_Byte(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_CHAR:
+                       val = java_lang_Character(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_SHORT:
+                       val = java_lang_Short(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_INT:
+                       val = java_lang_Integer(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_LONG:
+                       val = java_lang_Long(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_FLOAT:
+                       val = java_lang_Float(hvalue).get_value();
+                       break;
+               case PRIMITIVETYPE_DOUBLE:
+                       val = java_lang_Double(hvalue).get_value();
+                       break;
+               default:
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+
+               _field_set_double(df, ho, val);
+               return;
+       }
+
+       case TYPE_ADR:
+               /* check if value is an instance of the destination class */
+
+               /* XXX TODO */
+               /*                      if (!builtin_instanceof((java_handle_t *) value, df->class)) */
+               /*                              break; */
+
+               _field_set_handle(df, ho, hvalue);
+               return;
+       }
+
+       /* raise exception */
+
+       exceptions_throw_illegalargumentexception();
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    setBoolean
+ * Signature: (Ljava/lang/Object;Z)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setBoolean(JNIEnv *env, jobject _this, jobject o, jboolean value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return;
+
+       /* check the field type and set the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BOOLEAN:
+               _field_set_int(f, ho, value);
+               break;
+       default:
+               exceptions_throw_illegalargumentexception();
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    setByte
+ * Signature: (Ljava/lang/Object;B)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setByte(JNIEnv *env, jobject _this, jobject o, jbyte value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return;
+
+       /* check the field type and set the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               _field_set_int(f, ho, value);
+               break;
+       case PRIMITIVETYPE_LONG:
+               _field_set_long(f, ho, value);
+               break;
+       case PRIMITIVETYPE_FLOAT:
+               _field_set_float(f, ho, value);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               _field_set_double(f, ho, value);
+               break;
+       default:
+               exceptions_throw_illegalargumentexception();
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    setChar
+ * Signature: (Ljava/lang/Object;C)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setChar(JNIEnv *env, jobject _this, jobject o, jchar value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return;
+
+       /* check the field type and set the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_INT:
+               _field_set_int(f, ho, value);
+               break;
+       case PRIMITIVETYPE_LONG:
+               _field_set_long(f, ho, value);
+               break;
+       case PRIMITIVETYPE_FLOAT:
+               _field_set_float(f, ho, value);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               _field_set_double(f, ho, value);
+               break;
+       default:
+               exceptions_throw_illegalargumentexception();
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    setShort
+ * Signature: (Ljava/lang/Object;S)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setShort(JNIEnv *env, jobject _this, jobject o, jshort value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return;
+
+       /* check the field type and set the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               _field_set_int(f, ho, value);
+               break;
+       case PRIMITIVETYPE_LONG:
+               _field_set_long(f, ho, value);
+               break;
+       case PRIMITIVETYPE_FLOAT:
+               _field_set_float(f, ho, value);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               _field_set_double(f, ho, value);
+               break;
+       default:
+               exceptions_throw_illegalargumentexception();
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    setInt
+ * Signature: (Ljava/lang/Object;I)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setInt(JNIEnv *env, jobject _this, jobject o, jint value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return;
+
+       /* check the field type and set the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_INT:
+               _field_set_int(f, ho, value);
+               break;
+       case PRIMITIVETYPE_LONG:
+               _field_set_long(f, ho, value);
+               break;
+       case PRIMITIVETYPE_FLOAT:
+               _field_set_float(f, ho, value);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               _field_set_double(f, ho, value);
+               break;
+       default:
+               exceptions_throw_illegalargumentexception();
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    setLong
+ * Signature: (Ljava/lang/Object;J)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setLong(JNIEnv *env, jobject _this, jobject o, jlong value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return;
+
+       /* check the field type and set the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_LONG:
+               _field_set_long(f, ho, value);
+               break;
+       case PRIMITIVETYPE_FLOAT:
+               _field_set_float(f, ho, value);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               _field_set_double(f, ho, value);
+               break;
+       default:
+               exceptions_throw_illegalargumentexception();
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    setFloat
+ * Signature: (Ljava/lang/Object;F)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setFloat(JNIEnv *env, jobject _this, jobject o, jfloat value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return;
+
+       /* check the field type and set the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_FLOAT:
+               _field_set_float(f, ho, value);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               _field_set_double(f, ho, value);
+               break;
+       default:
+               exceptions_throw_illegalargumentexception();
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    setDouble
+ * Signature: (Ljava/lang/Object;D)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setDouble(JNIEnv *env, jobject _this, jobject o, jdouble value)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       java_handle_t* ho = (java_handle_t*) o;
+
+       /* check if the field can be accessed */
+
+       if (!_field_access_check(rvmf, f, ho))
+               return;
+
+       /* check the field type and set the value */
+
+       switch (f->parseddesc->primitivetype) {
+       case PRIMITIVETYPE_DOUBLE:
+               _field_set_double(f, ho, value);
+               break;
+       default:
+               exceptions_throw_illegalargumentexception();
+       }
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    getSignature
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_reflect_VMField_getSignature(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMField rvmf(_this);
+       fieldinfo* f = rvmf.get_field();
+
+       if (f->signature == NULL)
+               return NULL;
+
+       java_handle_t* o = javastring_new(f->signature);
+
+       /* in error case o is NULL */
+
+       return (jstring) o;
+}
+
+
+#if defined(ENABLE_ANNOTATIONS)
+/*
+ * Class:     java/lang/reflect/VMField
+ * Method:    declaredAnnotations
+ * Signature: ()Ljava/util/Map;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMField_declaredAnnotations(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMField rvmf(_this);
+
+       java_handle_t* declaredAnnotations = rvmf.get_declaredAnnotations();
+
+       // Are the annotations parsed yet?
+       if (declaredAnnotations == NULL) {
+               java_handle_bytearray_t* annotations    = rvmf.get_annotations();
+               classinfo*               declaringClass = rvmf.get_clazz();
+
+               classinfo* referer;
+               LLNI_class_get(_this, referer);
+
+               declaredAnnotations = Reflection::get_declaredannotations(annotations, declaringClass, referer);
+
+               rvmf.set_declaredAnnotations(declaredAnnotations);
+       }
+
+       return (jobject) declaredAnnotations;
+}
+#endif
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static const JNINativeMethod methods[] = {
+       { (char*) "getModifiersInternal", (char*) "()I",                                     (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getModifiersInternal },
+       { (char*) "getType",              (char*) "()Ljava/lang/Class;",                     (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getType              },
+       { (char*) "get",                  (char*) "(Ljava/lang/Object;)Ljava/lang/Object;",  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_get                  },
+       { (char*) "getBoolean",           (char*) "(Ljava/lang/Object;)Z",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getBoolean           },
+       { (char*) "getByte",              (char*) "(Ljava/lang/Object;)B",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getByte              },
+       { (char*) "getChar",              (char*) "(Ljava/lang/Object;)C",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getChar              },
+       { (char*) "getShort",             (char*) "(Ljava/lang/Object;)S",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getShort             },
+       { (char*) "getInt",               (char*) "(Ljava/lang/Object;)I",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getInt               },
+       { (char*) "getLong",              (char*) "(Ljava/lang/Object;)J",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getLong              },
+       { (char*) "getFloat",             (char*) "(Ljava/lang/Object;)F",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getFloat             },
+       { (char*) "getDouble",            (char*) "(Ljava/lang/Object;)D",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getDouble            },
+       { (char*) "set",                  (char*) "(Ljava/lang/Object;Ljava/lang/Object;)V", (void*) (uintptr_t) &Java_java_lang_reflect_VMField_set                  },
+       { (char*) "setBoolean",           (char*) "(Ljava/lang/Object;Z)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setBoolean           },
+       { (char*) "setByte",              (char*) "(Ljava/lang/Object;B)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setByte              },
+       { (char*) "setChar",              (char*) "(Ljava/lang/Object;C)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setChar              },
+       { (char*) "setShort",             (char*) "(Ljava/lang/Object;S)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setShort             },
+       { (char*) "setInt",               (char*) "(Ljava/lang/Object;I)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setInt               },
+       { (char*) "setLong",              (char*) "(Ljava/lang/Object;J)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setLong              },
+       { (char*) "setFloat",             (char*) "(Ljava/lang/Object;F)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setFloat             },
+       { (char*) "setDouble",            (char*) "(Ljava/lang/Object;D)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setDouble            },
+       { (char*) "getSignature",         (char*) "()Ljava/lang/String;",                    (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getSignature         },
+#if defined(ENABLE_ANNOTATIONS)
+       { (char*) "declaredAnnotations",  (char*) "()Ljava/util/Map;",                       (void*) (uintptr_t) &Java_java_lang_reflect_VMField_declaredAnnotations  },
+#endif
+};
+
+
+/* _Jv_java_lang_reflect_VMField_init ******************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_reflect_VMField_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/reflect/VMField");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_lang_reflect_VMMethod.c b/src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.c
deleted file mode 100644 (file)
index 8b1853f..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/* src/native/vm/gnu/java_lang_reflect_VMMethod.c
-
-   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 <stdint.h>
-
-#if defined(ENABLE_ANNOTATIONS)
-#include "vm/vm.h"
-#endif
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_String.h"
-
-#if defined(ENABLE_ANNOTATIONS)
-# include "native/include/java_util_Map.h"
-# include "native/include/sun_reflect_ConstantPool.h"
-#endif
-
-#include "native/include/java_lang_reflect_Method.h"
-#include "native/include/java_lang_reflect_VMMethod.h"
-
-#include "native/vm/reflect.h"
-
-#include "vm/access.h"
-#include "vm/global.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/initialize.h"
-#include "vm/resolve.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/method.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getModifiersInternal",    "()I",                                                       (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_getModifiersInternal    },
-       { "getReturnType",           "()Ljava/lang/Class;",                                       (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_getReturnType           },
-       { "getParameterTypes",       "()[Ljava/lang/Class;",                                      (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterTypes       },
-       { "getExceptionTypes",       "()[Ljava/lang/Class;",                                      (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_getExceptionTypes       },
-       { "invoke",                  "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_invoke                  },
-       { "getSignature",            "()Ljava/lang/String;",                                      (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_getSignature            },
-#if defined(ENABLE_ANNOTATIONS)
-       { "getDefaultValue",         "()Ljava/lang/Object;",                                      (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_getDefaultValue         },
-       { "declaredAnnotations",     "()Ljava/util/Map;",                                         (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_declaredAnnotations     },
-       { "getParameterAnnotations", "()[[Ljava/lang/annotation/Annotation;",                     (void *) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterAnnotations },
-#endif
-};
-
-
-/* _Jv_java_lang_reflect_VMMethod_init *******************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_reflect_VMMethod_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/reflect/VMMethod");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    getModifiersInternal
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMMethod_getModifiersInternal(JNIEnv *env, java_lang_reflect_VMMethod *this)
-{
-       classinfo  *c;
-       methodinfo *m;
-       int32_t     slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       m = &(c->methods[slot]);
-
-       return m->flags;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    getReturnType
- * Signature: ()Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_VMMethod_getReturnType(JNIEnv *env, java_lang_reflect_VMMethod *this)
-{
-       classinfo  *c;
-       methodinfo *m;
-       classinfo  *result;
-       int32_t     slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       m = &(c->methods[slot]);
-
-       result = method_returntype_get(m);
-
-       return LLNI_classinfo_wrap(result);
-}
-
-
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    getParameterTypes
- * Signature: ()[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_reflect_VMMethod_getParameterTypes(JNIEnv *env, java_lang_reflect_VMMethod *this)
-{
-       classinfo  *c;
-       methodinfo *m;
-       int32_t     slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       m = &(c->methods[slot]);
-
-       return method_get_parametertypearray(m);
-}
-
-
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    getExceptionTypes
- * Signature: ()[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_reflect_VMMethod_getExceptionTypes(JNIEnv *env, java_lang_reflect_VMMethod *this)
-{
-       classinfo  *c;
-       methodinfo *m;
-       int32_t     slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       m = &(c->methods[slot]);
-
-       return method_get_exceptionarray(m);
-}
-
-
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    invoke
- * Signature: (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_VMMethod_invoke(JNIEnv *env, java_lang_reflect_VMMethod *this, java_lang_Object *o, java_handle_objectarray_t *args)
-{
-       classinfo                *c;
-       int32_t                   slot;
-       java_lang_reflect_Method *rm;
-       int32_t                   override;
-       methodinfo               *m;
-       java_handle_t            *ro;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot,  slot);
-
-       LLNI_field_get_ref(this, m,     rm);
-       LLNI_field_get_val(rm,   flag,  override);
-
-       m = &(c->methods[slot]);
-
-       ro = reflect_method_invoke(m, (java_handle_t *) o, args, override);
-
-       return (java_lang_Object *) ro;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    getSignature
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_VMMethod_getSignature(JNIEnv *env, java_lang_reflect_VMMethod* this)
-{
-       classinfo     *c;
-       methodinfo    *m;
-       java_handle_t *o;
-       int32_t        slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       m = &(c->methods[slot]);
-
-       if (m->signature == NULL)
-               return NULL;
-
-       o = javastring_new(m->signature);
-
-       /* in error case o is NULL */
-
-       return (java_lang_String *) o;
-}
-
-#if defined(ENABLE_ANNOTATIONS)
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    getDefaultValue
- * Signature: ()Ljava/lang/Object;
- *
- * Parses the annotation default value and returnes it (boxed, if it's a primitive).
- */
-JNIEXPORT struct java_lang_Object* JNICALL Java_java_lang_reflect_VMMethod_getDefaultValue(JNIEnv *env, struct java_lang_reflect_VMMethod* this)
-{
-       java_handle_bytearray_t  *annotationDefault          = NULL; /* unparsed annotation default value                 */
-       static methodinfo        *m_parseAnnotationDefault   = NULL; /* parser method (will be chached, therefore static) */
-       utf                      *utf_parseAnnotationDefault = NULL; /* parser method name                                */
-       utf                      *utf_desc        = NULL;            /* parser method descriptor (signature)              */
-       sun_reflect_ConstantPool *constantPool    = NULL;            /* constant pool object to use                       */
-       java_lang_Class          *constantPoolOop = NULL;            /* methods declaring class                           */
-       classinfo                *referer         = NULL;            /* class, which calles the annotation parser         */
-                                                                    /* (for the parameter 'referer' of vm_call_method()) */
-       java_lang_reflect_Method* rm;
-       java_handle_t*            h;
-
-       if (this == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       constantPool = 
-               (sun_reflect_ConstantPool*)native_new_and_init(
-                       class_sun_reflect_ConstantPool);
-       
-       if (constantPool == NULL) {
-               /* out of memory */
-               return NULL;
-       }
-
-       LLNI_field_get_ref(this, clazz, constantPoolOop);
-       LLNI_field_set_ref(constantPool, constantPoolOop, (java_lang_Object*)constantPoolOop);
-
-       /* only resolve the parser method the first time */
-       if (m_parseAnnotationDefault == NULL) {
-               utf_parseAnnotationDefault = utf_new_char("parseAnnotationDefault");
-               utf_desc = utf_new_char(
-                       "(Ljava/lang/reflect/Method;[BLsun/reflect/ConstantPool;)"
-                       "Ljava/lang/Object;");
-
-               if (utf_parseAnnotationDefault == NULL || utf_desc == NULL) {
-                       /* out of memory */
-                       return NULL;
-               }
-
-               LLNI_class_get(this, referer);
-
-               m_parseAnnotationDefault = class_resolveclassmethod(
-                       class_sun_reflect_annotation_AnnotationParser,
-                       utf_parseAnnotationDefault,
-                       utf_desc,
-                       referer,
-                       true);
-
-               if (m_parseAnnotationDefault == NULL) {
-                       /* method not found */
-                       return NULL;
-               }
-       }
-
-       LLNI_field_get_ref(this, m,                 rm);
-       LLNI_field_get_ref(this, annotationDefault, annotationDefault);
-
-       h = vm_call_method(m_parseAnnotationDefault, NULL, rm, annotationDefault, constantPool);
-
-       return (java_lang_Object*) h;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    declaredAnnotations
- * Signature: ()Ljava/util/Map;
- *
- * Parses the annotations (if they aren't parsed yet) and stores them into
- * the declaredAnnotations map and return this map.
- */
-JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_VMMethod_declaredAnnotations(JNIEnv *env, java_lang_reflect_VMMethod *this)
-{
-       java_util_Map           *declaredAnnotations = NULL; /* parsed annotations                                */
-       java_handle_bytearray_t *annotations         = NULL; /* unparsed annotations                              */
-       java_lang_Class         *declaringClass      = NULL; /* the constant pool of this class is used           */
-       classinfo               *referer             = NULL; /* class, which calles the annotation parser         */
-                                                            /* (for the parameter 'referer' of vm_call_method()) */
-
-       LLNI_field_get_ref(this, declaredAnnotations, declaredAnnotations);
-
-       /* are the annotations parsed yet? */
-       if (declaredAnnotations == NULL) {
-               LLNI_field_get_ref(this, annotations, annotations);
-               LLNI_field_get_ref(this, clazz, declaringClass);
-               LLNI_class_get(this, referer);
-
-               declaredAnnotations = reflect_get_declaredannotatios(annotations, declaringClass, referer);
-
-               LLNI_field_set_ref(this, declaredAnnotations, declaredAnnotations);
-       }
-
-       return declaredAnnotations;
-}
-
-
-/*
- * Class:     java/lang/reflect/VMMethod
- * Method:    getParameterAnnotations
- * Signature: ()[[Ljava/lang/annotation/Annotation;
- *
- * Parses the parameter annotations and returns them in an 2 dimensional array.
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_reflect_VMMethod_getParameterAnnotations(JNIEnv *env, java_lang_reflect_VMMethod *this)
-{
-       java_handle_bytearray_t *parameterAnnotations = NULL; /* unparsed parameter annotations                    */
-       int32_t                  slot                 = -1;   /* slot of the method                                */
-       java_lang_Class         *declaringClass       = NULL; /* the constant pool of this class is used           */
-       classinfo               *referer              = NULL; /* class, which calles the annotation parser         */
-                                                             /* (for the parameter 'referer' of vm_call_method()) */
-
-       LLNI_field_get_ref(this, parameterAnnotations, parameterAnnotations);
-       LLNI_field_get_val(this, slot, slot);
-       LLNI_field_get_ref(this, clazz, declaringClass);
-       LLNI_class_get(this, referer);
-
-       return reflect_get_parameterannotations((java_handle_t*)parameterAnnotations, slot, declaringClass, referer);
-}
-#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/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp b/src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp
new file mode 100644 (file)
index 0000000..cafb699
--- /dev/null
@@ -0,0 +1,317 @@
+/* src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp
+
+   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 <stdint.h>
+
+#if defined(ENABLE_ANNOTATIONS)
+#include "vm/vm.hpp"
+#endif
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_lang_reflect_VMMethod.h"
+#endif
+
+#include "native/vm/reflection.hpp"
+
+#include "vm/access.h"
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+#include "vm/method.h"
+#include "vm/resolve.h"
+#include "vm/string.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    getModifiersInternal
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_reflect_VMMethod_getModifiersInternal(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMMethod rvmm(_this);
+       methodinfo* m = rvmm.get_method();
+       return m->flags;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    getReturnType
+ * Signature: ()Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_java_lang_reflect_VMMethod_getReturnType(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMMethod rvmm(_this);
+       methodinfo* m = rvmm.get_method();
+       classinfo*  c = method_returntype_get(m);
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    getParameterTypes
+ * Signature: ()[Ljava/lang/Class;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getParameterTypes(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMMethod rvmm(_this);
+       methodinfo* m = rvmm.get_method();
+       java_handle_objectarray_t* oa = method_get_parametertypearray(m);
+       return (jobjectArray) oa;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    getExceptionTypes
+ * Signature: ()[Ljava/lang/Class;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getExceptionTypes(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMMethod rvmm(_this);
+       methodinfo* m = rvmm.get_method();
+       java_handle_objectarray_t* oa = method_get_exceptionarray(m);
+       return (jobjectArray) oa;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    invoke
+ * Signature: (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_invoke(JNIEnv *env, jobject _this, jobject o, jobjectArray args)
+{
+       java_lang_reflect_VMMethod jlrvmm(_this);
+       java_lang_reflect_Method jlrm(jlrvmm.get_m());
+
+       java_handle_t* result = jlrm.invoke((java_handle_t*) o, (java_handle_objectarray_t*) args);
+
+       return (jobject) result;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    getSignature
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_java_lang_reflect_VMMethod_getSignature(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMMethod rvmm(_this);
+       methodinfo* m = rvmm.get_method();
+
+       if (m->signature == NULL)
+               return NULL;
+
+       java_handle_t* s = javastring_new(m->signature);
+
+       /* in error case o is NULL */
+
+       return (jstring) s;
+}
+
+
+#if defined(ENABLE_ANNOTATIONS)
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    getDefaultValue
+ * Signature: ()Ljava/lang/Object;
+ *
+ * Parses the annotation default value and returnes it (boxed, if it's a primitive).
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_getDefaultValue(JNIEnv *env, jobject _this)
+{
+       static methodinfo        *m_parseAnnotationDefault   = NULL; /* parser method (will be chached, therefore static) */
+       utf                      *utf_parseAnnotationDefault = NULL; /* parser method name                                */
+       utf                      *utf_desc        = NULL;            /* parser method descriptor (signature)              */
+
+       if (_this == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       // TODO Use a constructor.
+       java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
+
+       if (h == NULL)
+               return NULL;
+
+       sun_reflect_ConstantPool cp(h);
+       
+       java_lang_reflect_VMMethod rvmm(_this);
+       classinfo* declaringClass = rvmm.get_clazz();
+       cp.set_constantPoolOop(declaringClass);
+
+       /* only resolve the parser method the first time */
+       if (m_parseAnnotationDefault == NULL) {
+               utf_parseAnnotationDefault = utf_new_char("parseAnnotationDefault");
+               utf_desc = utf_new_char(
+                       "(Ljava/lang/reflect/Method;[BLsun/reflect/ConstantPool;)"
+                       "Ljava/lang/Object;");
+
+               if (utf_parseAnnotationDefault == NULL || utf_desc == NULL) {
+                       /* out of memory */
+                       return NULL;
+               }
+
+               classinfo *referer;
+               LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
+
+               m_parseAnnotationDefault = class_resolveclassmethod(
+                       class_sun_reflect_annotation_AnnotationParser,
+                       utf_parseAnnotationDefault,
+                       utf_desc,
+                       referer,
+                       true);
+
+               if (m_parseAnnotationDefault == NULL) {
+                       /* method not found */
+                       return NULL;
+               }
+       }
+
+       java_lang_reflect_Method rm(rvmm.get_m());
+       java_handle_bytearray_t* annotationDefault = rvmm.get_annotationDefault();
+
+       java_handle_t* result = vm_call_method(m_parseAnnotationDefault, NULL, rm.get_handle(), annotationDefault, cp.get_handle());
+
+       return (jobject) result;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    declaredAnnotations
+ * Signature: ()Ljava/util/Map;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMMethod_declaredAnnotations(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMMethod rvmm(_this);
+       java_handle_t* declaredAnnotations = rvmm.get_declaredAnnotations();
+
+       // Are the annotations parsed yet?
+       if (declaredAnnotations == NULL) {
+               java_handle_bytearray_t* annotations    = rvmm.get_annotations();
+               classinfo*               declaringClass = rvmm.get_clazz();
+
+               classinfo *referer;
+               LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
+
+               declaredAnnotations = Reflection::get_declaredannotations(annotations, declaringClass, referer);
+
+               rvmm.set_declaredAnnotations(declaredAnnotations);
+       }
+
+       return (jobject) declaredAnnotations;
+}
+
+
+/*
+ * Class:     java/lang/reflect/VMMethod
+ * Method:    getParameterAnnotations
+ * Signature: ()[[Ljava/lang/annotation/Annotation;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_lang_reflect_VMMethod_getParameterAnnotations(JNIEnv *env, jobject _this)
+{
+       java_lang_reflect_VMMethod rvmm(_this);
+       java_handle_bytearray_t* parameterAnnotations = rvmm.get_parameterAnnotations();
+       methodinfo* m = rvmm.get_method();
+
+       classinfo* referer;
+       LLNI_class_get((java_lang_reflect_VMMethod *) _this, referer);
+
+       java_handle_objectarray_t* oa = Reflection::get_parameterannotations(parameterAnnotations, m, referer);
+       return (jobjectArray) oa;
+}
+#endif
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getModifiersInternal",    (char*) "()I",                                                       (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getModifiersInternal    },
+       { (char*) "getReturnType",           (char*) "()Ljava/lang/Class;",                                       (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getReturnType           },
+       { (char*) "getParameterTypes",       (char*) "()[Ljava/lang/Class;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterTypes       },
+       { (char*) "getExceptionTypes",       (char*) "()[Ljava/lang/Class;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getExceptionTypes       },
+       { (char*) "invoke",                  (char*) "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_invoke                  },
+       { (char*) "getSignature",            (char*) "()Ljava/lang/String;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getSignature            },
+#if defined(ENABLE_ANNOTATIONS)
+       { (char*) "getDefaultValue",         (char*) "()Ljava/lang/Object;",                                      (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getDefaultValue         },
+       { (char*) "declaredAnnotations",     (char*) "()Ljava/util/Map;",                                         (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_declaredAnnotations     },
+       { (char*) "getParameterAnnotations", (char*) "()[[Ljava/lang/annotation/Annotation;",                     (void*) (uintptr_t) &Java_java_lang_reflect_VMMethod_getParameterAnnotations },
+#endif
+};
+
+
+/* _Jv_java_lang_reflect_VMMethod_init *****************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_lang_reflect_VMMethod_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/lang/reflect/VMMethod");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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 b2138421ff66adbabdd081eb927781ee559f3c1b..f40678c1489795bc1abe303b2036248d4596bdc6 100644 (file)
@@ -1,9 +1,7 @@
-/* src/native/vm/gnu/java_lang_reflect_VMProxy.c - java/lang/reflect/VMProxy
+/* src/native/vm/gnuclasspath/java_lang_reflect_VMProxy.c - java/lang/reflect/VMProxy
 
-   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.
 
 #include "native/jni.h"
 #include "native/native.h"
 
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_ClassLoader.h"
-
-#include "native/include/java_lang_reflect_VMProxy.h"
+// FIXME
+//#include "native/include/java_lang_reflect_VMProxy.h"
 
 
 /* native methods implemented by this file ************************************/
diff --git a/src/native/vm/gnuclasspath/java_security_VMAccessController.c b/src/native/vm/gnuclasspath/java_security_VMAccessController.c
deleted file mode 100644 (file)
index 7e86b68..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* src/native/vm/gnu/java_security_VMAccessController.c
-
-   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
-
-   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 <stdint.h>
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_security_VMAccessController.h"
-
-#include "vm/global.h"
-
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getStack", "()[[Ljava/lang/Object;", (void *) (uintptr_t) &Java_java_security_VMAccessController_getStack },
-};
-
-
-/* _Jv_java_security_VMAccessController_init ***********************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_security_VMAccessController_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/security/VMAccessController");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/security/VMAccessController
- * Method:    getStack
- * Signature: ()[[Ljava/lang/Object;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_security_VMAccessController_getStack(JNIEnv *env, jclass clazz)
-{
-       return stacktrace_get_stack();
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/java_security_VMAccessController.cpp b/src/native/vm/gnuclasspath/java_security_VMAccessController.cpp
new file mode 100644 (file)
index 0000000..abd1ed6
--- /dev/null
@@ -0,0 +1,96 @@
+/* src/native/vm/gnuclasspath/java_security_VMAccessController.cpp
+
+   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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/vm/include/java_security_VMAccessController.h"
+#endif
+
+#include "vm/global.h"
+#include "vm/utf8.h"
+
+#include "vm/jit/stacktrace.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/security/VMAccessController
+ * Method:    getStack
+ * Signature: ()[[Ljava/lang/Object;
+ */
+JNIEXPORT jobjectArray JNICALL Java_java_security_VMAccessController_getStack(JNIEnv *env, jclass clazz)
+{
+       return (jobjectArray) stacktrace_get_stack();
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getStack", (char*) "()[[Ljava/lang/Object;", (void*) (uintptr_t) &Java_java_security_VMAccessController_getStack },
+};
+
+
+/* _Jv_java_security_VMAccessController_init ***********************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_security_VMAccessController_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/security/VMAccessController");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/java_util_concurrent_atomic_AtomicLong.c b/src/native/vm/gnuclasspath/java_util_concurrent_atomic_AtomicLong.c
deleted file mode 100644 (file)
index 7105e65..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* src/native/vm/gnu/java_util_concurrent_atomic_AtomicLong.c
-
-   Copyright (C) 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
-
-   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 <stdint.h>
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_util_concurrent_atomic_AtomicLong.h"
-
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "VMSupportsCS8", "()Z", (void *) (intptr_t) &Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8 },
-};
-
-
-/* _Jv_java_util_concurrent_atomic_AtomicLong_init *****************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_util_concurrent_atomic_AtomicLong_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/util/concurrent/atomic/AtomicLong");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/util/concurrent/atomic/AtomicLong
- * Method:    VMSupportsCS8
- * Signature: ()Z
- */
-JNIEXPORT int32_t JNICALL Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(JNIEnv *env, jclass clazz)
-{
-       /* IMPLEMENT ME */
-
-       return 0;
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/java_util_concurrent_atomic_AtomicLong.cpp b/src/native/vm/gnuclasspath/java_util_concurrent_atomic_AtomicLong.cpp
new file mode 100644 (file)
index 0000000..c95ad18
--- /dev/null
@@ -0,0 +1,94 @@
+/* src/native/vm/gnuclasspath/java_util_concurrent_atomic_AtomicLong.cpp
+
+   Copyright (C) 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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/java_util_concurrent_atomic_AtomicLong.h"
+#endif
+
+#include "vm/utf8.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     java/util/concurrent/atomic/AtomicLong
+ * Method:    VMSupportsCS8
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(JNIEnv *env, jclass clazz)
+{
+       // IMPLEMENT ME
+       return 0;
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "VMSupportsCS8", (char*) "()Z", (void*) (uintptr_t) &Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8 },
+};
+
+
+/* _Jv_java_util_concurrent_atomic_AtomicLong_init *****************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_java_util_concurrent_atomic_AtomicLong_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("java/util/concurrent/atomic/AtomicLong");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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/native/vm/gnuclasspath/sun_reflect_ConstantPool.c b/src/native/vm/gnuclasspath/sun_reflect_ConstantPool.c
deleted file mode 100644 (file)
index 66b7ac4..0000000
+++ /dev/null
@@ -1,427 +0,0 @@
-/* src/native/vm/gnu/sun_reflect_ConstantPool.c
-
-   Copyright (C) 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, M. S. Panzenböck Institut f. Computersprachen - TU Wien
-
-   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.
-
-*/
-
-/*******************************************************************************
-
-   XXX: The Methods in this file are very redundant to thouse in
-        src/native/vm/sun/jvm.c Unless someone has a good idea how to cover
-        such redundancy I leave it how it is.
-
-  The ConstantPool class represents an interface to the constant pool of a
-  class and is used by the annotations parser (sun.reflect.annotation.
-  AnnotationParser) to get the values of the constants refered by the
-  annotations.
-
-*******************************************************************************/
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Class.h"
-#include "native/include/sun_reflect_ConstantPool.h"
-
-#include "native/vm/reflect.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/vm.h"
-#include "vm/exceptions.h"
-#include "vm/resolve.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/class.h"
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getSize0",             "(Ljava/lang/Object;I)I",                          (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getSize0             },
-       { "getClassAt0",          "(Ljava/lang/Object;I)Ljava/lang/Class;",          (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getClassAt0          },
-       { "getClassAtIfLoaded0",  "(Ljava/lang/Object;I)Ljava/lang/Class;",          (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getClassAtIfLoaded0  },
-       { "getMethodAt0",         "(Ljava/lang/Object;I)Ljava/lang/reflect/Member;", (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getMethodAt0         },
-       { "getMethodAtIfLoaded0", "(Ljava/lang/Object;I)Ljava/lang/reflect/Member;", (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getMethodAtIfLoaded0 },
-       { "getFieldAt0",          "(Ljava/lang/Object;I)Ljava/lang/reflect/Field;",  (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getFieldAt0          },
-       { "getFieldAtIfLoaded0",  "(Ljava/lang/Object;I)Ljava/lang/reflect/Field;",  (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getFieldAtIfLoaded0  },
-       { "getMemberRefInfoAt0",  "(Ljava/lang/Object;I)[Ljava/lang/String;",        (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getMemberRefInfoAt0  },
-       { "getIntAt0",            "(Ljava/lang/Object;I)I",                          (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getIntAt0            },
-       { "getLongAt0",           "(Ljava/lang/Object;I)J",                          (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getLongAt0           },
-       { "getFloatAt0",          "(Ljava/lang/Object;I)F",                          (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getFloatAt0          },
-       { "getDoubleAt0",         "(Ljava/lang/Object;I)D",                          (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getDoubleAt0         },
-       { "getStringAt0",         "(Ljava/lang/Object;I)Ljava/lang/String;",         (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getStringAt0         },
-       { "getUTF8At0",           "(Ljava/lang/Object;I)Ljava/lang/String;",         (void *) (intptr_t) &Java_sun_reflect_ConstantPool_getUTF8At0           }, 
-};
-
-
-/* _Jv_sun_reflect_ConstantPool_init ******************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_sun_reflect_ConstantPool_init(void)
-{
-       native_method_register(utf_new_char("sun/reflect/ConstantPool"), methods, NATIVE_METHODS_COUNT);
-}
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getSize0
- * Signature: (Ljava/lang/Object;)I
- */
-JNIEXPORT int32_t JNICALL Java_sun_reflect_ConstantPool_getSize0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool)
-{
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-       return cls->cpcount;
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getClassAt0
- * Signature: (Ljava/lang/Object;I)Ljava/lang/Class;
- */
-JNIEXPORT struct java_lang_Class* JNICALL Java_sun_reflect_ConstantPool_getClassAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_classref *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_classref*)class_getconstant(
-               cls, index, CONSTANT_Class);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       return LLNI_classinfo_wrap(resolve_classref_eager(ref));
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getClassAtIfLoaded0
- * Signature: (Ljava/lang/Object;I)Ljava/lang/Class;
- */
-JNIEXPORT struct java_lang_Class* JNICALL Java_sun_reflect_ConstantPool_getClassAtIfLoaded0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_classref *ref;
-       classinfo *c = NULL;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_classref*)class_getconstant(
-               cls, index, CONSTANT_Class);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-       
-       if (!resolve_classref(NULL,ref,resolveLazy,true,true,&c)) {
-               return NULL;
-       }
-
-       if (c == NULL || !(c->state & CLASS_LOADED)) {
-               return NULL;
-       }
-       
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getMethodAt0
- * Signature: (Ljava/lang/Object;I)Ljava/lang/reflect/Member;
- */
-JNIEXPORT struct java_lang_reflect_Member* JNICALL Java_sun_reflect_ConstantPool_getMethodAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_FMIref *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-       
-       ref = (constant_FMIref*)class_getconstant(
-               cls, index, CONSTANT_Methodref);
-       
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* XXX: is that right? or do I have to use resolve_method_*? */
-       return (jobject)reflect_method_new(ref->p.method);
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getMethodAtIfLoaded0
- * Signature: (Ljava/lang/Object;I)Ljava/lang/reflect/Member;
- */
-JNIEXPORT struct java_lang_reflect_Member* JNICALL Java_sun_reflect_ConstantPool_getMethodAtIfLoaded0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_FMIref *ref;
-       classinfo *c = NULL;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_FMIref*)class_getconstant(
-               cls, index, CONSTANT_Methodref);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       if (!resolve_classref(NULL,ref->p.classref,resolveLazy,true,true,&c)) {
-               return NULL;
-       }
-
-       if (c == NULL || !(c->state & CLASS_LOADED)) {
-               return NULL;
-       }
-
-       return (jobject)reflect_method_new(ref->p.method);
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getFieldAt0
- * Signature: (Ljava/lang/Object;I)Ljava/lang/reflect/Field;
- */
-JNIEXPORT struct java_lang_reflect_Field* JNICALL Java_sun_reflect_ConstantPool_getFieldAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_FMIref *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_FMIref*)class_getconstant(
-               cls, index, CONSTANT_Fieldref);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       return (jobject)reflect_field_new(ref->p.field);
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getFieldAtIfLoaded0
- * Signature: (Ljava/lang/Object;I)Ljava/lang/reflect/Field;
- */
-JNIEXPORT struct java_lang_reflect_Field* JNICALL Java_sun_reflect_ConstantPool_getFieldAtIfLoaded0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_FMIref *ref;
-       classinfo *c;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_FMIref*)class_getconstant(
-               cls, index, CONSTANT_Fieldref);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       if (!resolve_classref(NULL,ref->p.classref,resolveLazy,true,true,&c)) {
-               return NULL;
-       }
-
-       if (c == NULL || !(c->state & CLASS_LOADED)) {
-               return NULL;
-       }
-
-       return (jobject)reflect_field_new(ref->p.field);
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getMemberRefInfoAt0
- * Signature: (Ljava/lang/Object;I)[Ljava/lang/String;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_sun_reflect_ConstantPool_getMemberRefInfoAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       log_println("Java_sun_reflect_ConstantPool_getMemberRefInfoAt0(env=%p, jcpool=%p, index=%d): IMPLEMENT ME!", env, jcpool, index);
-       return NULL;
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getIntAt0
- * Signature: (Ljava/lang/Object;I)I
- */
-JNIEXPORT int32_t JNICALL Java_sun_reflect_ConstantPool_getIntAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_integer *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_integer*)class_getconstant(
-               cls, index, CONSTANT_Integer);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       return ref->value;
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getLongAt0
- * Signature: (Ljava/lang/Object;I)J
- */
-JNIEXPORT int64_t JNICALL Java_sun_reflect_ConstantPool_getLongAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_long *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_long*)class_getconstant(
-               cls, index, CONSTANT_Long);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       return ref->value;
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getFloatAt0
- * Signature: (Ljava/lang/Object;I)F
- */
-JNIEXPORT float JNICALL Java_sun_reflect_ConstantPool_getFloatAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_float *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_float*)class_getconstant(
-               cls, index, CONSTANT_Float);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       return ref->value;
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getDoubleAt0
- * Signature: (Ljava/lang/Object;I)D
- */
-JNIEXPORT double JNICALL Java_sun_reflect_ConstantPool_getDoubleAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       constant_double *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_double*)class_getconstant(
-               cls, index, CONSTANT_Double);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       return ref->value;
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getStringAt0
- * Signature: (Ljava/lang/Object;I)Ljava/lang/String;
- */
-JNIEXPORT struct java_lang_String* JNICALL Java_sun_reflect_ConstantPool_getStringAt0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       utf *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-       
-       ref = (utf*)class_getconstant(cls, index, CONSTANT_String);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* XXX: I hope literalstring_new is the right Function. */
-       return (java_lang_String*)literalstring_new(ref);
-}
-
-
-/*
- * Class:     sun/reflect/ConstantPool
- * Method:    getUTF8At0
- * Signature: (Ljava/lang/Object;I)Ljava/lang/String;
- */
-JNIEXPORT struct java_lang_String* JNICALL Java_sun_reflect_ConstantPool_getUTF8At0(JNIEnv *env, struct sun_reflect_ConstantPool* this, struct java_lang_Object* jcpool, int32_t index)
-{
-       utf *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (utf*)class_getconstant(cls, index, CONSTANT_Utf8);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* XXX: I hope literalstring_new is the right Function. */
-       return (java_lang_String*)literalstring_new(ref);
-}
-
-
-/*
- * 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/native/vm/gnuclasspath/sun_reflect_ConstantPool.cpp b/src/native/vm/gnuclasspath/sun_reflect_ConstantPool.cpp
new file mode 100644 (file)
index 0000000..ad48b2f
--- /dev/null
@@ -0,0 +1,440 @@
+/* src/native/vm/gnuclasspath/sun_reflect_ConstantPool.cpp
+
+   Copyright (C) 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.
+
+*/
+
+/*******************************************************************************
+
+   XXX: The Methods in this file are very redundant to thouse in
+        src/native/vm/sun/jvm.c Unless someone has a good idea how to cover
+        such redundancy I leave it how it is.
+
+  The ConstantPool class represents an interface to the constant pool of a
+  class and is used by the annotations parser (sun.reflect.annotation.
+  AnnotationParser) to get the values of the constants refered by the
+  annotations.
+
+*******************************************************************************/
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+// FIXME
+//#include "native/include/sun_reflect_ConstantPool.h"
+
+#include "native/vm/reflection.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/resolve.h"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getSize0
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_reflect_ConstantPool_getSize0(JNIEnv *env, jobject _this, jobject jcpool)
+{
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       return cls->cpcount;
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getClassAt0
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_sun_reflect_ConstantPool_getClassAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_classref *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_classref*)class_getconstant(
+               cls, index, CONSTANT_Class);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       return (jclass) LLNI_classinfo_wrap(resolve_classref_eager(ref));
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getClassAtIfLoaded0
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_sun_reflect_ConstantPool_getClassAtIfLoaded0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_classref *ref;
+       classinfo *c = NULL;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_classref*)class_getconstant(
+               cls, index, CONSTANT_Class);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+       
+       if (!resolve_classref(NULL,ref,resolveLazy,true,true,&c)) {
+               return NULL;
+       }
+
+       if (c == NULL || !(c->state & CLASS_LOADED)) {
+               return NULL;
+       }
+       
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getMethodAt0
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/reflect/Member;
+ */
+JNIEXPORT jobject JNICALL Java_sun_reflect_ConstantPool_getMethodAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_FMIref *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       
+       ref = (constant_FMIref*)class_getconstant(
+               cls, index, CONSTANT_Methodref);
+       
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       /* XXX: is that right? or do I have to use resolve_method_*? */
+       java_lang_reflect_Method jlrm(ref->p.method);
+
+       return (jobject) jlrm.get_handle();
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getMethodAtIfLoaded0
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/reflect/Member;
+ */
+JNIEXPORT jobject JNICALL Java_sun_reflect_ConstantPool_getMethodAtIfLoaded0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_FMIref *ref;
+       classinfo *c = NULL;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_FMIref*)class_getconstant(
+               cls, index, CONSTANT_Methodref);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       if (!resolve_classref(NULL,ref->p.classref,resolveLazy,true,true,&c)) {
+               return NULL;
+       }
+
+       if (c == NULL || !(c->state & CLASS_LOADED)) {
+               return NULL;
+       }
+
+       java_lang_reflect_Method jlrm(ref->p.method);
+
+       return (jobject) jlrm.get_handle();
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getFieldAt0
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/reflect/Field;
+ */
+JNIEXPORT jobject JNICALL Java_sun_reflect_ConstantPool_getFieldAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_FMIref *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_FMIref*) class_getconstant(cls, index, CONSTANT_Fieldref);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       // Create a new java.lang.reflect.Field Java object.
+       java_lang_reflect_Field jlrf(ref->p.field);
+
+       return (jobject) jlrf.get_handle();
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getFieldAtIfLoaded0
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/reflect/Field;
+ */
+JNIEXPORT jobject JNICALL Java_sun_reflect_ConstantPool_getFieldAtIfLoaded0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_FMIref *ref;
+       classinfo *c;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_FMIref*) class_getconstant(cls, index, CONSTANT_Fieldref);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       if (!resolve_classref(NULL,ref->p.classref,resolveLazy,true,true,&c)) {
+               return NULL;
+       }
+
+       if (c == NULL || !(c->state & CLASS_LOADED)) {
+               return NULL;
+       }
+
+       // Create a new java.lang.reflect.Field Java object.
+       java_lang_reflect_Field jlrf(ref->p.field);
+
+       return (jobject) jlrf.get_handle();
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getMemberRefInfoAt0
+ * Signature: (Ljava/lang/Object;I)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_sun_reflect_ConstantPool_getMemberRefInfoAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       log_println("Java_sun_reflect_ConstantPool_getMemberRefInfoAt0(env=%p, jcpool=%p, index=%d): IMPLEMENT ME!", env, jcpool, index);
+       return NULL;
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getIntAt0
+ * Signature: (Ljava/lang/Object;I)I
+ */
+JNIEXPORT jint JNICALL Java_sun_reflect_ConstantPool_getIntAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_integer *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_integer*) class_getconstant(cls, index, CONSTANT_Integer);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       return ref->value;
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getLongAt0
+ * Signature: (Ljava/lang/Object;I)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_reflect_ConstantPool_getLongAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_long *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_long*)class_getconstant(
+               cls, index, CONSTANT_Long);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       return ref->value;
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getFloatAt0
+ * Signature: (Ljava/lang/Object;I)F
+ */
+JNIEXPORT float JNICALL Java_sun_reflect_ConstantPool_getFloatAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_float *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_float*)class_getconstant(
+               cls, index, CONSTANT_Float);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       return ref->value;
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getDoubleAt0
+ * Signature: (Ljava/lang/Object;I)D
+ */
+JNIEXPORT double JNICALL Java_sun_reflect_ConstantPool_getDoubleAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       constant_double *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_double*)class_getconstant(
+               cls, index, CONSTANT_Double);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       return ref->value;
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getStringAt0
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_sun_reflect_ConstantPool_getStringAt0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       utf *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       
+       ref = (utf*)class_getconstant(cls, index, CONSTANT_String);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       /* XXX: I hope literalstring_new is the right Function. */
+       return (jstring) literalstring_new(ref);
+}
+
+
+/*
+ * Class:     sun/reflect/ConstantPool
+ * Method:    getUTF8At0
+ * Signature: (Ljava/lang/Object;I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_sun_reflect_ConstantPool_getUTF8At0(JNIEnv *env, jobject _this, jobject jcpool, jint index)
+{
+       utf *ref;
+       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (utf*)class_getconstant(cls, index, CONSTANT_Utf8);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       /* XXX: I hope literalstring_new is the right Function. */
+       return (jstring) literalstring_new(ref);
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "getSize0",             (char*) "(Ljava/lang/Object;I)I",                          (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getSize0             },
+       { (char*) "getClassAt0",          (char*) "(Ljava/lang/Object;I)Ljava/lang/Class;",          (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getClassAt0          },
+       { (char*) "getClassAtIfLoaded0",  (char*) "(Ljava/lang/Object;I)Ljava/lang/Class;",          (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getClassAtIfLoaded0  },
+       { (char*) "getMethodAt0",         (char*) "(Ljava/lang/Object;I)Ljava/lang/reflect/Member;", (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getMethodAt0         },
+       { (char*) "getMethodAtIfLoaded0", (char*) "(Ljava/lang/Object;I)Ljava/lang/reflect/Member;", (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getMethodAtIfLoaded0 },
+       { (char*) "getFieldAt0",          (char*) "(Ljava/lang/Object;I)Ljava/lang/reflect/Field;",  (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getFieldAt0          },
+       { (char*) "getFieldAtIfLoaded0",  (char*) "(Ljava/lang/Object;I)Ljava/lang/reflect/Field;",  (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getFieldAtIfLoaded0  },
+       { (char*) "getMemberRefInfoAt0",  (char*) "(Ljava/lang/Object;I)[Ljava/lang/String;",        (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getMemberRefInfoAt0  },
+       { (char*) "getIntAt0",            (char*) "(Ljava/lang/Object;I)I",                          (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getIntAt0            },
+       { (char*) "getLongAt0",           (char*) "(Ljava/lang/Object;I)J",                          (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getLongAt0           },
+       { (char*) "getFloatAt0",          (char*) "(Ljava/lang/Object;I)F",                          (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getFloatAt0          },
+       { (char*) "getDoubleAt0",         (char*) "(Ljava/lang/Object;I)D",                          (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getDoubleAt0         },
+       { (char*) "getStringAt0",         (char*) "(Ljava/lang/Object;I)Ljava/lang/String;",         (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getStringAt0         },
+       { (char*) "getUTF8At0",           (char*) "(Ljava/lang/Object;I)Ljava/lang/String;",         (void*) (uintptr_t) &Java_sun_reflect_ConstantPool_getUTF8At0           }, 
+};
+
+
+/* _Jv_sun_reflect_ConstantPool_init ******************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_sun_reflect_ConstantPool_init(void)
+{
+       native_method_register(utf_new_char("sun/reflect/ConstantPool"), methods, NATIVE_METHODS_COUNT);
+}
+}
+
+
+/*
+ * 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 defffab17908eda060fc92871961545796a169b0..563cce47d47430ee5f21dd2fc0d3efa790b0a1b0 100644 (file)
 
 #include "native/vm/nativevm.h"
 
+#include "vm/class.h"
 #include "vm/initialize.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/system.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
 
 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
 # include "mm/memory.h"
 
 # include "native/vm/openjdk/hpi.h"
 
+# include "vm/globals.hpp"
 # include "vm/properties.h"
-# include "vm/vm.h"
-
-# include "vmcore/utf8.h"
+# include "vm/utf8.h"
+# include "vm/vm.hpp"
 #endif
 
 
@@ -95,7 +94,7 @@ void nativevm_preinit(void)
 
 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
 
-       char* boot_library_path;
+       const char* boot_library_path;
        int   len;
        char* p;
        utf*  u;
@@ -108,14 +107,14 @@ void nativevm_preinit(void)
        boot_library_path = properties_get("sun.boot.library.path");
 
        len =
-               system_strlen(boot_library_path) +
-               system_strlen("/libjava.so") +
-               system_strlen("0");
+               os_strlen(boot_library_path) +
+               os_strlen("/libjava.so") +
+               os_strlen("0");
 
        p = MNEW(char, len);
 
-       system_strcpy(p, boot_library_path);
-       system_strcat(p, "/libjava.so");
+       os_strcpy(p, boot_library_path);
+       os_strcat(p, "/libjava.so");
 
        u = utf_new_char(p);
 
index db22ee65070d08d2d8d3a432e363a8fa296d9ac7..de4ba48a101b0fb4a320bd7ecf630e4cd04cbf57 100644 (file)
 #define _NATIVEVM_H
 
 #include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/types.h"
 
 #include "vm/global.h"
@@ -97,8 +102,13 @@ void _Jv_java_lang_Throwable_init();
 # error unknown Java configuration
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _NATIVEVM_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
index 1f1753140d188af5bfe7fe41af157071becfe6c4..49677897a94bc12b82aeef1f2bced9f6ebb84264 100644 (file)
@@ -1,4 +1,4 @@
-## src/native/vm/sun/Makefile.am
+## src/native/vm/openjdk/Makefile.am
 ##
 ## Copyright (C) 2007, 2008
 ## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
@@ -31,7 +31,7 @@ noinst_LTLIBRARIES = \
 libnativevmcore_la_SOURCES = \
        hpi.c \
        hpi.h \
-       jvm.c
+       jvm.cpp
 
 
 ## Local variables:
index d55bae037dbe528b3eddb4bb255358f4acc5033a..7b89c594ae59419cf60009127e22c412e62c7e87 100644 (file)
 #include "native/jni.h"
 #include "native/native.h"
 
-#include "vm/properties.h"
-#include "vm/vm.h"
+#include "native/vm/openjdk/hpi.h"
 
-#include "vmcore/options.h"
-#include "vmcore/system.h"
-#include "vmcore/utf8.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
+#include "vm/properties.h"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
 
 
 /* VM callback functions ******************************************************/
@@ -78,7 +79,7 @@ HPI_SystemInterface  *hpi_system        = NULL;
 
 void hpi_initialize(void)
 {
-       char* boot_library_path;
+       const char* boot_library_path;
        int   len;
        char* p;
        utf*  u;
@@ -95,14 +96,14 @@ void hpi_initialize(void)
        boot_library_path = properties_get("sun.boot.library.path");
 
        len =
-               system_strlen(boot_library_path) +
-               system_strlen("/native_threads/libhpi.so") +
-               system_strlen("0");
+               os_strlen(boot_library_path) +
+               os_strlen("/native_threads/libhpi.so") +
+               os_strlen("0");
 
        p = MNEW(char, len);
 
-       system_strcpy(p, boot_library_path);
-       system_strcat(p, "/native_threads/libhpi.so");
+       os_strcpy(p, boot_library_path);
+       os_strcat(p, "/native_threads/libhpi.so");
 
        u = utf_new_char(p);
 
@@ -119,13 +120,12 @@ void hpi_initialize(void)
 
        /* Resolve the DLL_Initialize function from the library. */
 
-       dll_initialize = system_dlsym(handle, "DLL_Initialize");
+       dll_initialize = os_dlsym(handle, "DLL_Initialize");
 
     DLL_Initialize = (jint (JNICALL *)(GetInterfaceFunc *, void *)) (intptr_t) dll_initialize;
 
     if (opt_TraceHPI && DLL_Initialize == NULL)
-               log_println("hpi_init: HPI dlsym of DLL_Initialize failed: %s",
-                                       system_dlerror());
+               log_println("hpi_init: HPI dlsym of DLL_Initialize failed: %s", os_dlerror());
 
     if (DLL_Initialize == NULL ||
         (*DLL_Initialize)(&hpi_get_interface, &callbacks) < 0) {
index 03880e6f12babee52da8f244017273b232b12b74..356b8358e56e31189f672656efaf94fb63178024 100644 (file)
 #ifndef _HPI_H
 #define _HPI_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "config.h"
 
 /* HPI headers *****************************************************************
@@ -56,6 +60,10 @@ extern HPI_SystemInterface  *hpi_system;
 void hpi_initialize(void);
 int  hpi_initialize_socket_library(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _HPI_H */
 
 
diff --git a/src/native/vm/openjdk/jvm.c b/src/native/vm/openjdk/jvm.c
deleted file mode 100644 (file)
index 2c946b7..0000000
+++ /dev/null
@@ -1,3737 +0,0 @@
-/* src/native/vm/openjdk/jvm.c - HotSpot JVM interface functions
-
-   Copyright (C) 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 <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#if defined(HAVE_SYS_IOCTL_H)
-#define BSD_COMP /* Get FIONREAD on Solaris2 */
-#include <sys/ioctl.h>
-#endif
-
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_AssertionStatusDirectives.h"
-#include "native/include/java_lang_String.h"            /* required by j.l.CL */
-#include "native/include/java_nio_ByteBuffer.h"         /* required by j.l.CL */
-#include "native/include/java_lang_ClassLoader.h"        /* required by j.l.C */
-#include "native/include/java_lang_StackTraceElement.h"
-#include "native/include/java_lang_Throwable.h"
-#include "native/include/java_security_ProtectionDomain.h"
-
-#if defined(ENABLE_ANNOTATIONS)
-#include "native/include/sun_reflect_ConstantPool.h"
-#endif
-
-#include "native/vm/reflect.h"
-
-#include "native/vm/openjdk/hpi.h"
-
-#include "threads/lock-common.h"
-#include "threads/thread.h"
-
-#include "toolbox/logging.h"
-#include "toolbox/list.h"
-
-#include "vm/array.h"
-
-#if defined(ENABLE_ASSERTION)
-#include "vm/assertion.h"
-#endif
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/initialize.h"
-#include "vm/package.hpp"
-#include "vm/primitive.h"
-#include "vm/properties.h"
-#include "vm/resolve.h"
-#include "vm/signallocal.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/classcache.h"
-#include "vmcore/options.h"
-#include "vmcore/system.h"
-
-
-/* debugging macros ***********************************************************/
-
-#if !defined(NDEBUG)
-
-# define TRACEJVMCALLS(x)                                                                              \
-    do {                                                                                                               \
-        if (opt_TraceJVMCalls || opt_TraceJVMCallsVerbose) {   \
-            log_println x;                                                                             \
-        }                                                                                                              \
-    } while (0)
-
-# define TRACEJVMCALLSENTER(x)                                                                 \
-    do {                                                                                                               \
-        if (opt_TraceJVMCalls || opt_TraceJVMCallsVerbose) {   \
-                       log_start();                                                                            \
-            log_print x;                                                                               \
-        }                                                                                                              \
-    } while (0)
-
-# define TRACEJVMCALLSEXIT(x)                                                                  \
-    do {                                                                                                               \
-        if (opt_TraceJVMCalls || opt_TraceJVMCallsVerbose) {   \
-                       log_print x;                                                                            \
-                       log_finish();                                                                           \
-        }                                                                                                              \
-    } while (0)
-
-# define TRACEJVMCALLSVERBOSE(x)                               \
-    do {                                                                               \
-        if (opt_TraceJVMCallsVerbose) {                        \
-            log_println x;                                             \
-        }                                                                              \
-    } while (0)
-
-# define PRINTJVMWARNINGS(x)
-/*     do { \ */
-/*         if (opt_PrintJVMWarnings) { \ */
-/*             log_println x; \ */
-/*         } \ */
-/*     } while (0) */
-
-#else
-
-# define TRACEJVMCALLS(x)
-# define TRACEJVMCALLSENTER(x)
-# define TRACEJVMCALLSEXIT(x)
-# define TRACEJVMCALLSVERBOSE(x)
-# define PRINTJVMWARNINGS(x)
-
-#endif
-
-
-typedef struct {
-    /* Naming convention of RE build version string: n.n.n[_uu[c]][-<identifier>]-bxx */
-    unsigned int jvm_version;   /* Consists of major, minor, micro (n.n.n) */
-                                /* and build number (xx) */
-    unsigned int update_version : 8;         /* Update release version (uu) */
-    unsigned int special_update_version : 8; /* Special update release version (c) */
-    unsigned int reserved1 : 16; 
-    unsigned int reserved2; 
-
-    /* The following bits represents JVM supports that JDK has dependency on.
-     * JDK can use these bits to determine which JVM version
-     * and support it has to maintain runtime compatibility.
-     *
-     * When a new bit is added in a minor or update release, make sure
-     * the new bit is also added in the main/baseline.
-     */
-    unsigned int is_attachable : 1;
-    unsigned int : 31;
-    unsigned int : 32;
-    unsigned int : 32;
-} jvm_version_info;
-
-
-/*
- * A structure used to a capture exception table entry in a Java method.
- */
-typedef struct {
-    jint start_pc;
-    jint end_pc;
-    jint handler_pc;
-    jint catchType;
-} JVM_ExceptionTableEntryType;
-
-
-int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
-{
-       if ((intptr_t) count <= 0)
-               return -1;
-
-       return vsnprintf(str, count, fmt, args);
-}
-
-
-int jio_snprintf(char *str, size_t count, const char *fmt, ...)
-{
-       va_list ap;
-       int     len;
-
-       va_start(ap, fmt);
-       len = jio_vsnprintf(str, count, fmt, ap);
-       va_end(ap);
-
-       return len;
-}
-
-
-int jio_fprintf(FILE* f, const char *fmt, ...)
-{
-       log_println("jio_fprintf: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-int jio_vfprintf(FILE* f, const char *fmt, va_list args)
-{
-       log_println("jio_vfprintf: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-int jio_printf(const char *fmt, ...)
-{
-       log_println("jio_printf: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetInterfaceVersion */
-
-jint JVM_GetInterfaceVersion()
-{
-       /* This is defined in hotspot/src/share/vm/prims/jvm.h */
-
-#define JVM_INTERFACE_VERSION 4
-
-       return JVM_INTERFACE_VERSION;
-}
-
-
-/* JVM_CurrentTimeMillis */
-
-jlong JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored)
-{
-       TRACEJVMCALLS(("JVM_CurrentTimeMillis(env=%p, ignored=%p)", env, ignored));
-
-       return (jlong) builtin_currenttimemillis();
-}
-
-
-/* JVM_NanoTime */
-
-jlong JVM_NanoTime(JNIEnv *env, jclass ignored)
-{
-       TRACEJVMCALLS(("JVM_NanoTime(env=%p, ignored=%p)", env, ignored));
-
-       return (jlong) builtin_nanotime();
-}
-
-
-/* JVM_ArrayCopy */
-
-void JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobject dst, jint dst_pos, jint length)
-{
-       java_handle_t *s;
-       java_handle_t *d;
-
-       s = (java_handle_t *) src;
-       d = (java_handle_t *) dst;
-
-       TRACEJVMCALLSVERBOSE(("JVM_ArrayCopy(env=%p, ignored=%p, src=%p, src_pos=%d, dst=%p, dst_pos=%d, length=%d)", env, ignored, src, src_pos, dst, dst_pos, length));
-
-       builtin_arraycopy(s, src_pos, d, dst_pos, length);
-}
-
-
-/* JVM_InitProperties */
-
-jobject JVM_InitProperties(JNIEnv *env, jobject properties)
-{
-       java_handle_t *h;
-       char           buf[256];
-
-       TRACEJVMCALLS(("JVM_InitProperties(env=%p, properties=%p)", env, properties));
-
-       h = (java_handle_t *) properties;
-
-       /* Convert the -XX:MaxDirectMemorySize= command line flag to the
-          sun.nio.MaxDirectMemorySize property.  Do this after setting
-          user properties to prevent people from setting the value with a
-          -D option, as requested. */
-
-       jio_snprintf(buf, sizeof(buf), PRINTF_FORMAT_INT64_T, opt_MaxDirectMemorySize);
-       properties_add("sun.nio.MaxDirectMemorySize", buf);
-
-       /* Add all properties. */
-
-       properties_system_add_all(h);
-
-       return properties;
-}
-
-
-/* JVM_Exit */
-
-void JVM_Exit(jint code)
-{
-       log_println("JVM_Exit: IMPLEMENT ME!");
-}
-
-
-/* JVM_Halt */
-
-void JVM_Halt(jint code)
-{
-       TRACEJVMCALLS(("JVM_Halt(code=%d)", code));
-
-/*     vm_exit(code); */
-       vm_shutdown(code);
-}
-
-
-/* JVM_OnExit(void (*func)) */
-
-void JVM_OnExit(void (*func)(void))
-{
-       log_println("JVM_OnExit(void (*func): IMPLEMENT ME!");
-}
-
-
-/* JVM_GC */
-
-void JVM_GC(void)
-{
-       TRACEJVMCALLS(("JVM_GC()"));
-
-       gc_call();
-}
-
-
-/* JVM_MaxObjectInspectionAge */
-
-jlong JVM_MaxObjectInspectionAge(void)
-{
-       log_println("JVM_MaxObjectInspectionAge: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_TraceInstructions */
-
-void JVM_TraceInstructions(jboolean on)
-{
-       log_println("JVM_TraceInstructions: IMPLEMENT ME!");
-}
-
-
-/* JVM_TraceMethodCalls */
-
-void JVM_TraceMethodCalls(jboolean on)
-{
-       log_println("JVM_TraceMethodCalls: IMPLEMENT ME!");
-}
-
-
-/* JVM_TotalMemory */
-
-jlong JVM_TotalMemory(void)
-{
-       TRACEJVMCALLS(("JVM_TotalMemory()"));
-
-       return gc_get_heap_size();
-}
-
-
-/* JVM_FreeMemory */
-
-jlong JVM_FreeMemory(void)
-{
-       TRACEJVMCALLS(("JVM_FreeMemory()"));
-
-       return gc_get_free_bytes();
-}
-
-
-/* JVM_MaxMemory */
-
-jlong JVM_MaxMemory(void)
-{
-       TRACEJVMCALLS(("JVM_MaxMemory()"));
-
-       return gc_get_max_heap_size();
-}
-
-
-/* JVM_ActiveProcessorCount */
-
-jint JVM_ActiveProcessorCount(void)
-{
-       TRACEJVMCALLS(("JVM_ActiveProcessorCount()"));
-
-       return system_processors_online();
-}
-
-
-/* JVM_FillInStackTrace */
-
-void JVM_FillInStackTrace(JNIEnv *env, jobject receiver)
-{
-       java_lang_Throwable     *o;
-       java_handle_bytearray_t *ba;
-
-       TRACEJVMCALLS(("JVM_FillInStackTrace(env=%p, receiver=%p)", env, receiver));
-
-       o = (java_lang_Throwable *) receiver;
-
-       ba = stacktrace_get_current();
-
-       if (ba == NULL)
-               return;
-
-       LLNI_field_set_ref(o, backtrace, (java_lang_Object *) ba);
-}
-
-
-/* JVM_PrintStackTrace */
-
-void JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable)
-{
-       log_println("JVM_PrintStackTrace: IMPLEMENT ME!");
-}
-
-
-/* JVM_GetStackTraceDepth */
-
-jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
-{
-       java_lang_Throwable     *to;
-       java_lang_Object        *o;
-       java_handle_bytearray_t *ba;
-       stacktrace_t            *st;
-       int32_t                  depth;
-
-       TRACEJVMCALLS(("JVM_GetStackTraceDepth(env=%p, throwable=%p)", env, throwable));
-
-       if (throwable == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       to = (java_lang_Throwable *) throwable;
-
-       LLNI_field_get_ref(to, backtrace, o);
-
-       ba = (java_handle_bytearray_t *) o;
-
-       if (ba == NULL)
-               return 0;
-
-       /* We need a critical section here as the stacktrace structure is
-          mapped onto a Java byte-array. */
-
-       LLNI_CRITICAL_START;
-
-       st = (stacktrace_t *) LLNI_array_data(ba);
-
-       depth = st->length;
-
-       LLNI_CRITICAL_END;
-
-       return depth;
-}
-
-
-/* JVM_GetStackTraceElement */
-
-jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
-{
-       java_lang_Throwable         *to;
-       java_lang_Object            *o;
-       java_handle_bytearray_t     *ba;
-       stacktrace_t                *st;
-       stacktrace_entry_t          *ste;
-       codeinfo                    *code;
-       methodinfo                  *m;
-       classinfo                   *c;
-       java_lang_StackTraceElement *steo;
-       java_handle_t*               declaringclass;
-       java_lang_String            *filename;
-       int32_t                      linenumber;
-
-       TRACEJVMCALLS(("JVM_GetStackTraceElement(env=%p, throwable=%p, index=%d)", env, throwable, index));
-
-       to = (java_lang_Throwable *) throwable;
-
-       LLNI_field_get_ref(to, backtrace, o);
-
-       ba = (java_handle_bytearray_t *) o;
-
-       /* FIXME critical section */
-
-       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. */
-
-       ste = &(st->entries[index]);
-
-       /* Get the codeinfo, methodinfo and classinfo. */
-
-       code = ste->code;
-       m    = code->m;
-       c    = m->clazz;
-
-       /* allocate a new StackTraceElement */
-
-       steo = (java_lang_StackTraceElement *)
-               builtin_new(class_java_lang_StackTraceElement);
-
-       if (steo == NULL)
-               return NULL;
-
-       /* get filename */
-
-       if (!(m->flags & ACC_NATIVE)) {
-               if (c->sourcefile != NULL)
-                       filename = (java_lang_String *) javastring_new(c->sourcefile);
-               else
-                       filename = NULL;
-       }
-       else
-               filename = NULL;
-
-       /* get line number */
-
-       if (m->flags & ACC_NATIVE) {
-               linenumber = -2;
-       }
-       else {
-               /* FIXME The linenumbertable_linenumber_for_pc could change
-                  the methodinfo pointer when hitting an inlined method. */
-
-               linenumber = linenumbertable_linenumber_for_pc(&m, code, ste->pc);
-               linenumber = (linenumber == 0) ? -1 : linenumber;
-       }
-
-       /* get declaring class name */
-
-       declaringclass = class_get_classname(c);
-
-       /* fill the java.lang.StackTraceElement element */
-
-       /* FIXME critical section */
-
-       steo->declaringClass = (java_lang_String*) declaringclass;
-       steo->methodName     = (java_lang_String*) javastring_new(m->name);
-       steo->fileName       = filename;
-       steo->lineNumber     = linenumber;
-
-       return (jobject) steo;
-}
-
-
-/* JVM_IHashCode */
-
-jint JVM_IHashCode(JNIEnv* env, jobject handle)
-{
-       TRACEJVMCALLS(("JVM_IHashCode(env=%p, jobject=%p)", env, handle));
-
-       return (jint) ((ptrint) handle);
-}
-
-
-/* JVM_MonitorWait */
-
-void JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *o;
-#endif
-
-       TRACEJVMCALLS(("JVM_MonitorWait(env=%p, handle=%p, ms=%ld)", env, handle, ms));
-    if (ms < 0) {
-/*             exceptions_throw_illegalargumentexception("argument out of range"); */
-               exceptions_throw_illegalargumentexception();
-               return;
-       }
-
-#if defined(ENABLE_THREADS)
-       o = (java_handle_t *) handle;
-
-       lock_wait_for_object(o, ms, 0);
-#endif
-}
-
-
-/* JVM_MonitorNotify */
-
-void JVM_MonitorNotify(JNIEnv* env, jobject handle)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *o;
-#endif
-
-       TRACEJVMCALLS(("JVM_MonitorNotify(env=%p, handle=%p)", env, handle));
-
-#if defined(ENABLE_THREADS)
-       o = (java_handle_t *) handle;
-
-       lock_notify_object(o);
-#endif
-}
-
-
-/* JVM_MonitorNotifyAll */
-
-void JVM_MonitorNotifyAll(JNIEnv* env, jobject handle)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *o;
-#endif
-
-       TRACEJVMCALLS(("JVM_MonitorNotifyAll(env=%p, handle=%p)", env, handle));
-
-#if defined(ENABLE_THREADS)
-       o = (java_handle_t *) handle;
-
-       lock_notify_all_object(o);
-#endif
-}
-
-
-/* JVM_Clone */
-
-jobject JVM_Clone(JNIEnv* env, jobject handle)
-{
-       TRACEJVMCALLS(("JVM_Clone(env=%p, handle=%p)", env, handle));
-
-       return (jobject) builtin_clone(env, (java_handle_t *) handle);
-}
-
-
-/* JVM_InitializeCompiler  */
-
-void JVM_InitializeCompiler (JNIEnv *env, jclass compCls)
-{
-       log_println("JVM_InitializeCompiler : IMPLEMENT ME!");
-}
-
-
-/* JVM_IsSilentCompiler */
-
-jboolean JVM_IsSilentCompiler(JNIEnv *env, jclass compCls)
-{
-       log_println("JVM_IsSilentCompiler: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_CompileClass */
-
-jboolean JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls)
-{
-       log_println("JVM_CompileClass: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_CompileClasses */
-
-jboolean JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname)
-{
-       log_println("JVM_CompileClasses: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_CompilerCommand */
-
-jobject JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg)
-{
-       log_println("JVM_CompilerCommand: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_EnableCompiler */
-
-void JVM_EnableCompiler(JNIEnv *env, jclass compCls)
-{
-       TRACEJVMCALLS(("JVM_EnableCompiler(env=%p, compCls=%p)", env, compCls));
-       PRINTJVMWARNINGS(("JVM_EnableCompiler not supported"));
-}
-
-
-/* JVM_DisableCompiler */
-
-void JVM_DisableCompiler(JNIEnv *env, jclass compCls)
-{
-       TRACEJVMCALLS(("JVM_DisableCompiler(env=%p, compCls=%p)", env, compCls));
-       PRINTJVMWARNINGS(("JVM_DisableCompiler not supported"));
-}
-
-
-/* JVM_GetLastErrorString */
-
-jint JVM_GetLastErrorString(char *buf, int len)
-{
-       TRACEJVMCALLS(("JVM_GetLastErrorString(buf=%p, len=%d", buf, len));
-
-       return hpi_system->GetLastErrorString(buf, len);
-}
-
-
-/* JVM_NativePath */
-
-char *JVM_NativePath(char *path)
-{
-       TRACEJVMCALLS(("JVM_NativePath(path=%s)", path));
-
-       return hpi_file->NativePath(path);
-}
-
-
-/* JVM_GetCallerClass */
-
-jclass JVM_GetCallerClass(JNIEnv* env, int depth)
-{
-       classinfo *c;
-
-       TRACEJVMCALLS(("JVM_GetCallerClass(env=%p, depth=%d)", env, depth));
-
-       c = stacktrace_get_caller_class(depth);
-
-       return (jclass) c;
-}
-
-
-/* JVM_FindPrimitiveClass */
-
-jclass JVM_FindPrimitiveClass(JNIEnv* env, const char* s)
-{
-       classinfo *c;
-       utf       *u;
-
-       TRACEJVMCALLS(("JVM_FindPrimitiveClass(env=%p, s=%s)", env, s));
-
-       u = utf_new_char(s);
-       c = primitive_class_get_by_name(u);
-
-       return (jclass) LLNI_classinfo_wrap(c);
-}
-
-
-/* JVM_ResolveClass */
-
-void JVM_ResolveClass(JNIEnv* env, jclass cls)
-{
-       TRACEJVMCALLS(("JVM_ResolveClass(env=%p, cls=%p)", env, cls));
-       PRINTJVMWARNINGS(("JVM_ResolveClass not implemented"));
-}
-
-
-/* JVM_FindClassFromClassLoader */
-
-jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init, jobject loader, jboolean throwError)
-{
-       classinfo     *c;
-       utf           *u;
-       classloader_t *cl;
-
-       TRACEJVMCALLS(("JVM_FindClassFromClassLoader(name=%s, init=%d, loader=%p, throwError=%d)", name, init, loader, throwError));
-
-       /* As of now, OpenJDK does not call this function with throwError
-          is true. */
-
-       assert(throwError == false);
-
-       u  = utf_new_char(name);
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-
-       c = load_class_from_classloader(u, cl);
-
-       if (c == NULL)
-               return NULL;
-
-       if (init)
-               if (!(c->state & CLASS_INITIALIZED))
-                       if (!initialize_class(c))
-                               return NULL;
-
-       return (jclass) LLNI_classinfo_wrap(c);
-}
-
-
-/* JVM_FindClassFromClass */
-
-jclass JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jclass from)
-{
-       log_println("JVM_FindClassFromClass: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_DefineClass */
-
-jclass JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd)
-{
-       log_println("JVM_DefineClass: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_DefineClassWithSource */
-
-jclass JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source)
-{
-       classinfo     *c;
-       utf           *u;
-       classloader_t *cl;
-
-       TRACEJVMCALLS(("JVM_DefineClassWithSource(env=%p, name=%s, loader=%p, buf=%p, len=%d, pd=%p, source=%s)", env, name, loader, buf, len, pd, source));
-
-       if (name != NULL)
-               u = utf_new_char(name);
-       else
-               u = NULL;
-
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-
-       /* XXX do something with source */
-
-       c = class_define(u, cl, len, (uint8_t *) buf, (java_handle_t *) pd);
-
-       return (jclass) LLNI_classinfo_wrap(c);
-}
-
-
-/* JVM_FindLoadedClass */
-
-jclass JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
-{
-       classloader_t *cl;
-       utf           *u;
-       classinfo     *c;
-
-       TRACEJVMCALLS(("JVM_FindLoadedClass(env=%p, loader=%p, name=%p)", env, loader, name));
-
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-
-       u = javastring_toutf((java_handle_t *) name, true);
-       c = classcache_lookup(cl, u);
-
-       return (jclass) LLNI_classinfo_wrap(c);
-}
-
-
-/* JVM_GetClassName */
-
-jstring JVM_GetClassName(JNIEnv *env, jclass cls)
-{
-       classinfo* c;
-
-       TRACEJVMCALLS(("JVM_GetClassName(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       return (jstring) class_get_classname(c);
-}
-
-
-/* JVM_GetClassInterfaces */
-
-jobjectArray JVM_GetClassInterfaces(JNIEnv *env, jclass cls)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       TRACEJVMCALLS(("JVM_GetClassInterfaces(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       oa = class_get_interfaces(c);
-
-       return (jobjectArray) oa;
-}
-
-
-/* JVM_GetClassLoader */
-
-jobject JVM_GetClassLoader(JNIEnv *env, jclass cls)
-{
-       classinfo     *c;
-       classloader_t *cl;
-
-       TRACEJVMCALLSENTER(("JVM_GetClassLoader(env=%p, cls=%p)", env, cls));
-
-       c  = LLNI_classinfo_unwrap(cls);
-       cl = class_get_classloader(c);
-
-       TRACEJVMCALLSEXIT(("->%p", cl));
-
-       return (jobject) cl;
-}
-
-
-/* JVM_IsInterface */
-
-jboolean JVM_IsInterface(JNIEnv *env, jclass cls)
-{
-       classinfo *c;
-
-       TRACEJVMCALLS(("JVM_IsInterface(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       return class_is_interface(c);
-}
-
-
-/* JVM_GetClassSigners */
-
-jobjectArray JVM_GetClassSigners(JNIEnv *env, jclass cls)
-{
-       log_println("JVM_GetClassSigners: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_SetClassSigners */
-
-void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *hoa;
-
-       TRACEJVMCALLS(("JVM_SetClassSigners(env=%p, cls=%p, signers=%p)", env, cls, signers));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       hoa = (java_handle_objectarray_t *) signers;
-
-    /* This call is ignored for primitive types and arrays.  Signers
-          are only set once, ClassLoader.java, and thus shouldn't be
-          called with an array.  Only the bootstrap loader creates
-          arrays. */
-
-       if (class_is_primitive(c) || class_is_array(c))
-               return;
-
-       LLNI_classinfo_field_set(c, signers, hoa);
-}
-
-
-/* JVM_GetProtectionDomain */
-
-jobject JVM_GetProtectionDomain(JNIEnv *env, jclass cls)
-{
-       classinfo *c;
-
-       TRACEJVMCALLS(("JVM_GetProtectionDomain(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       if (c == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-    /* Primitive types do not have a protection domain. */
-
-       if (class_is_primitive(c))
-               return NULL;
-
-       return (jobject) c->protectiondomain;
-}
-
-
-/* JVM_SetProtectionDomain */
-
-void JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)
-{
-       log_println("JVM_SetProtectionDomain: IMPLEMENT ME!");
-}
-
-
-/* JVM_DoPrivileged */
-
-jobject JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)
-{
-       java_handle_t *h;
-       classinfo     *c;
-       methodinfo    *m;
-       java_handle_t *result;
-       java_handle_t *e;
-
-       TRACEJVMCALLS(("JVM_DoPrivileged(env=%p, cls=%p, action=%p, context=%p, wrapException=%d)", env, cls, action, context, wrapException));
-
-       h = (java_handle_t *) action;
-       LLNI_class_get(h, c);
-
-       if (action == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* lookup run() method (throw no exceptions) */
-
-       m = class_resolveclassmethod(c, utf_run, utf_void__java_lang_Object, c,
-                                                                false);
-
-       if ((m == NULL) || !(m->flags & ACC_PUBLIC) || (m->flags & ACC_STATIC)) {
-               exceptions_throw_internalerror("No run method");
-               return NULL;
-       }
-
-       /* XXX It seems something with a privileged stack needs to be done
-          here. */
-
-       result = vm_call_method(m, h);
-
-       e = exceptions_get_exception();
-
-       if (e != NULL) {
-               if ( builtin_instanceof(e, class_java_lang_Exception) &&
-                       !builtin_instanceof(e, class_java_lang_RuntimeException)) {
-                       exceptions_clear_exception();
-                       exceptions_throw_privilegedactionexception(e);
-               }
-
-               return NULL;
-       }
-
-       return (jobject) result;
-}
-
-
-/* JVM_GetInheritedAccessControlContext */
-
-jobject JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)
-{
-       log_println("JVM_GetInheritedAccessControlContext: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetStackAccessControlContext */
-
-jobject JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls)
-{
-       TRACEJVMCALLS(("JVM_GetStackAccessControlContext(env=%p, cls=%p): IMPLEMENT ME!", env, cls));
-
-       /* XXX All stuff I tested so far works without that function.  At
-          some point we have to implement it, but I disable the output
-          for now to make IcedTea happy. */
-
-       return NULL;
-}
-
-
-/* JVM_IsArrayClass */
-
-jboolean JVM_IsArrayClass(JNIEnv *env, jclass cls)
-{
-       classinfo *c;
-
-       TRACEJVMCALLS(("JVM_IsArrayClass(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       return class_is_array(c);
-}
-
-
-/* JVM_IsPrimitiveClass */
-
-jboolean JVM_IsPrimitiveClass(JNIEnv *env, jclass cls)
-{
-       classinfo *c;
-
-       TRACEJVMCALLS(("JVM_IsPrimitiveClass(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       return class_is_primitive(c);
-}
-
-
-/* JVM_GetComponentType */
-
-jclass JVM_GetComponentType(JNIEnv *env, jclass cls)
-{
-       classinfo *component;
-       classinfo *c;
-       
-       TRACEJVMCALLS(("JVM_GetComponentType(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-       
-       component = class_get_componenttype(c);
-
-       return (jclass) LLNI_classinfo_wrap(component);
-}
-
-
-/* JVM_GetClassModifiers */
-
-jint JVM_GetClassModifiers(JNIEnv *env, jclass cls)
-{
-       classinfo *c;
-       int32_t    flags;
-
-       TRACEJVMCALLS(("JVM_GetClassModifiers(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       flags = class_get_modifiers(c, false);
-
-       return flags;
-}
-
-
-/* JVM_GetDeclaredClasses */
-
-jobjectArray JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       TRACEJVMCALLS(("JVM_GetDeclaredClasses(env=%p, ofClass=%p)", env, ofClass));
-
-       c = LLNI_classinfo_unwrap(ofClass);
-
-       oa = class_get_declaredclasses(c, false);
-
-       return (jobjectArray) oa;
-}
-
-
-/* JVM_GetDeclaringClass */
-
-jclass JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass)
-{
-       classinfo *c;
-       classinfo *dc;
-
-       TRACEJVMCALLS(("JVM_GetDeclaringClass(env=%p, ofClass=%p)", env, ofClass));
-
-       c = LLNI_classinfo_unwrap(ofClass);
-
-       dc = class_get_declaringclass(c);
-
-       return (jclass) LLNI_classinfo_wrap(dc);
-}
-
-
-/* JVM_GetClassSignature */
-
-jstring JVM_GetClassSignature(JNIEnv *env, jclass cls)
-{
-       classinfo     *c;
-       utf           *u;
-       java_handle_t *s;
-
-       TRACEJVMCALLS(("JVM_GetClassSignature(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       /* Get the signature of the class. */
-
-       u = class_get_signature(c);
-
-       if (u == NULL)
-               return NULL;
-
-       /* Convert UTF-string to a Java-string. */
-
-       s = javastring_new(u);
-
-       return (jstring) s;
-}
-
-
-/* JVM_GetClassAnnotations */
-
-jbyteArray JVM_GetClassAnnotations(JNIEnv *env, jclass cls)
-{
-       classinfo               *c           = NULL; /* classinfo for 'cls'  */
-       java_handle_bytearray_t *annotations = NULL; /* unparsed annotations */
-
-       TRACEJVMCALLS(("JVM_GetClassAnnotations: cls=%p", cls));
-
-       if (cls == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-       
-       c = LLNI_classinfo_unwrap(cls);
-
-       /* get annotations: */
-       annotations = class_get_annotations(c);
-
-       return (jbyteArray)annotations;
-}
-
-
-/* JVM_GetFieldAnnotations */
-
-jbyteArray JVM_GetFieldAnnotations(JNIEnv *env, jobject field)
-{
-       java_lang_reflect_Field *rf = NULL; /* java.lang.reflect.Field for 'field' */
-       java_handle_bytearray_t *ba = NULL; /* unparsed annotations */
-
-       TRACEJVMCALLS(("JVM_GetFieldAnnotations: field=%p", field));
-
-       if (field == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       rf = (java_lang_reflect_Field*)field;
-
-       LLNI_field_get_ref(rf, annotations, ba);
-
-       return (jbyteArray)ba;
-}
-
-
-/* JVM_GetMethodAnnotations */
-
-jbyteArray JVM_GetMethodAnnotations(JNIEnv *env, jobject method)
-{
-       java_lang_reflect_Method *rm = NULL; /* java.lang.reflect.Method for 'method' */
-       java_handle_bytearray_t  *ba = NULL; /* unparsed annotations */
-
-       TRACEJVMCALLS(("JVM_GetMethodAnnotations: method=%p", method));
-
-       if (method == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       rm = (java_lang_reflect_Method*)method;
-
-       LLNI_field_get_ref(rm, annotations, ba);
-
-       return (jbyteArray)ba;
-}
-
-
-/* JVM_GetMethodDefaultAnnotationValue */
-
-jbyteArray JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method)
-{
-       java_lang_reflect_Method *rm = NULL; /* java.lang.reflect.Method for 'method' */
-       java_handle_bytearray_t  *ba = NULL; /* unparsed annotation default value */
-
-       TRACEJVMCALLS(("JVM_GetMethodDefaultAnnotationValue: method=%p", method));
-
-       if (method == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       rm = (java_lang_reflect_Method*)method;
-
-       LLNI_field_get_ref(rm, annotationDefault, ba);
-
-       return (jbyteArray)ba;
-}
-
-
-/* JVM_GetMethodParameterAnnotations */
-
-jbyteArray JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method)
-{
-       java_lang_reflect_Method *rm = NULL; /* java.lang.reflect.Method for 'method' */
-       java_handle_bytearray_t  *ba = NULL; /* unparsed parameter annotations */
-
-       TRACEJVMCALLS(("JVM_GetMethodParameterAnnotations: method=%p", method));
-
-       if (method == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       rm = (java_lang_reflect_Method*)method;
-
-       LLNI_field_get_ref(rm, parameterAnnotations, ba);
-
-       return (jbyteArray)ba;
-}
-
-
-/* JVM_GetClassDeclaredFields */
-
-jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       TRACEJVMCALLS(("JVM_GetClassDeclaredFields(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly));
-
-       c = LLNI_classinfo_unwrap(ofClass);
-
-       oa = class_get_declaredfields(c, publicOnly);
-
-       return (jobjectArray) oa;
-}
-
-
-/* JVM_GetClassDeclaredMethods */
-
-jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       TRACEJVMCALLS(("JVM_GetClassDeclaredMethods(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly));
-
-       c = LLNI_classinfo_unwrap(ofClass);
-
-       oa = class_get_declaredmethods(c, publicOnly);
-
-       return (jobjectArray) oa;
-}
-
-
-/* JVM_GetClassDeclaredConstructors */
-
-jobjectArray JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;
-
-       TRACEJVMCALLS(("JVM_GetClassDeclaredConstructors(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly));
-
-       c = LLNI_classinfo_unwrap(ofClass);
-
-       oa = class_get_declaredconstructors(c, publicOnly);
-
-       return (jobjectArray) oa;
-}
-
-
-/* JVM_GetClassAccessFlags */
-
-jint JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)
-{
-       classinfo *c;
-
-       TRACEJVMCALLS(("JVM_GetClassAccessFlags(env=%p, cls=%p)", env, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       /* Primitive type classes have the correct access flags. */
-
-       return c->flags & ACC_CLASS_REFLECT_MASK;
-}
-
-
-/* JVM_GetClassConstantPool */
-
-jobject JVM_GetClassConstantPool(JNIEnv *env, jclass cls)
-{
-#if defined(ENABLE_ANNOTATIONS)
-       sun_reflect_ConstantPool *constantPool    = NULL;
-                     /* constant pool object for the class refered by 'cls' */
-       java_lang_Object         *constantPoolOop = (java_lang_Object*)cls;
-                     /* constantPoolOop field of the constant pool object   */
-
-       TRACEJVMCALLS(("JVM_GetClassConstantPool(env=%p, cls=%p)", env, cls));
-
-       constantPool = 
-               (sun_reflect_ConstantPool*)native_new_and_init(
-                       class_sun_reflect_ConstantPool);
-       
-       if (constantPool == NULL) {
-               /* out of memory */
-               return NULL;
-       }
-       
-       LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
-
-       return (jobject)constantPool;
-#else
-       log_println("JVM_GetClassConstantPool(env=%p, cls=%p): not implemented in this configuration!", env, cls);
-       return NULL;
-#endif
-}
-
-
-/* JVM_ConstantPoolGetSize */
-
-jint JVM_ConstantPoolGetSize(JNIEnv *env, jobject unused, jobject jcpool)
-{
-       classinfo *c; /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetSize(env=%p, unused=%p, jcpool=%p)", env, unused, jcpool));
-
-       c = LLNI_classinfo_unwrap(jcpool);
-
-       return c->cpcount;
-}
-
-
-/* JVM_ConstantPoolGetClassAt */
-
-jclass JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_classref *ref;    /* classref to the class at constant pool index 'index' */
-       classinfo         *c;      /* classinfo of the class for which 'this' is the constant pool */
-       classinfo         *result; /* classinfo of the class at constant pool index 'index' */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetClassAt(env=%p, jcpool=%p, index=%d)", env, jcpool, index));
-
-       c = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_classref *) class_getconstant(c, index, CONSTANT_Class);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       result = resolve_classref_eager(ref);
-
-       return (jclass) LLNI_classinfo_wrap(result);
-}
-
-
-/* JVM_ConstantPoolGetClassAtIfLoaded */
-
-jclass JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_classref *ref;    /* classref to the class at constant pool index 'index' */
-       classinfo         *c;      /* classinfo of the class for which 'this' is the constant pool */
-       classinfo         *result; /* classinfo of the class at constant pool index 'index' */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetClassAtIfLoaded(env=%p, unused=%p, jcpool=%p, index=%d)", env, unused, jcpool, index));
-
-       c = LLNI_classinfo_unwrap(jcpool);
-
-       ref = (constant_classref *) class_getconstant(c, index, CONSTANT_Class);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-       
-       if (!resolve_classref(NULL, ref, resolveLazy, true, true, &result)) {
-               return NULL;
-       }
-
-       if ((result == NULL) || !(result->state & CLASS_LOADED)) {
-               return NULL;
-       }
-       
-       return (jclass) LLNI_classinfo_wrap(result);
-}
-
-
-/* JVM_ConstantPoolGetMethodAt */
-
-jobject JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_FMIref *ref; /* reference to the method in constant pool at index 'index' */
-       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
-       
-       TRACEJVMCALLS(("JVM_ConstantPoolGetMethodAt: jcpool=%p, index=%d", jcpool, index));
-       
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Methodref);
-       
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* XXX: is that right? or do I have to use resolve_method_*? */
-       return (jobject)reflect_method_new(ref->p.method);
-}
-
-
-/* JVM_ConstantPoolGetMethodAtIfLoaded */
-
-jobject JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_FMIref *ref; /* reference to the method in constant pool at index 'index' */
-       classinfo *c = NULL;  /* resolved declaring class of the method */
-       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetMethodAtIfLoaded: jcpool=%p, index=%d", jcpool, index));
-
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Methodref);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       if (!resolve_classref(NULL, ref->p.classref, resolveLazy, true, true, &c)) {
-               return NULL;
-       }
-
-       if (c == NULL || !(c->state & CLASS_LOADED)) {
-               return NULL;
-       }
-
-       return (jobject)reflect_method_new(ref->p.method);
-}
-
-
-/* JVM_ConstantPoolGetFieldAt */
-
-jobject JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_FMIref *ref; /* reference to the field in constant pool at index 'index' */
-       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
-       
-       TRACEJVMCALLS(("JVM_ConstantPoolGetFieldAt: jcpool=%p, index=%d", jcpool, index));
-
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Fieldref);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       return (jobject)reflect_field_new(ref->p.field);
-}
-
-
-/* JVM_ConstantPoolGetFieldAtIfLoaded */
-
-jobject JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_FMIref *ref; /* reference to the field in constant pool at index 'index' */
-       classinfo *c;         /* resolved declaring class for the field */
-       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetFieldAtIfLoaded: jcpool=%p, index=%d", jcpool, index));
-
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Fieldref);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       if (!resolve_classref(NULL, ref->p.classref, resolveLazy, true, true, &c)) {
-               return NULL;
-       }
-
-       if (c == NULL || !(c->state & CLASS_LOADED)) {
-               return NULL;
-       }
-
-       return (jobject)reflect_field_new(ref->p.field);
-}
-
-
-/* JVM_ConstantPoolGetMemberRefInfoAt */
-
-jobjectArray JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       log_println("JVM_ConstantPoolGetMemberRefInfoAt: jcpool=%p, index=%d, IMPLEMENT ME!", jcpool, index);
-
-       /* TODO: implement. (this is yet unused be OpenJDK but, so very low priority) */
-
-       return NULL;
-}
-
-
-/* JVM_ConstantPoolGetIntAt */
-
-jint JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_integer *ref; /* reference to the int value in constant pool at index 'index' */
-       classinfo *cls;        /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetIntAt: jcpool=%p, index=%d", jcpool, index));
-
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (constant_integer*)class_getconstant(cls, index, CONSTANT_Integer);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       return ref->value;
-}
-
-
-/* JVM_ConstantPoolGetLongAt */
-
-jlong JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_long *ref; /* reference to the long value in constant pool at index 'index' */
-       classinfo *cls;     /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetLongAt: jcpool=%p, index=%d", jcpool, index));
-
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (constant_long*)class_getconstant(cls, index, CONSTANT_Long);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       return ref->value;
-}
-
-
-/* JVM_ConstantPoolGetFloatAt */
-
-jfloat JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_float *ref; /* reference to the float value in constant pool at index 'index' */
-       classinfo *cls;      /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetFloatAt: jcpool=%p, index=%d", jcpool, index));
-
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (constant_float*)class_getconstant(cls, index, CONSTANT_Float);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       return ref->value;
-}
-
-
-/* JVM_ConstantPoolGetDoubleAt */
-
-jdouble JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       constant_double *ref; /* reference to the double value in constant pool at index 'index' */
-       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetDoubleAt: jcpool=%p, index=%d", jcpool, index));
-
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (constant_double*)class_getconstant(cls, index, CONSTANT_Double);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       return ref->value;
-}
-
-
-/* JVM_ConstantPoolGetStringAt */
-
-jstring JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       utf *ref;       /* utf object for the string in constant pool at index 'index' */
-       classinfo *cls; /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetStringAt: jcpool=%p, index=%d", jcpool, index));
-       
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (utf*)class_getconstant(cls, index, CONSTANT_String);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* XXX: I hope literalstring_new is the right Function. */
-       return (jstring)literalstring_new(ref);
-}
-
-
-/* JVM_ConstantPoolGetUTF8At */
-
-jstring JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject unused, jobject jcpool, jint index)
-{
-       utf *ref; /* utf object for the utf8 data in constant pool at index 'index' */
-       classinfo *cls; /* classinfo of the class for which 'this' is the constant pool */
-
-       TRACEJVMCALLS(("JVM_ConstantPoolGetUTF8At: jcpool=%p, index=%d", jcpool, index));
-
-       cls = LLNI_classinfo_unwrap(jcpool);
-       ref = (utf*)class_getconstant(cls, index, CONSTANT_Utf8);
-
-       if (ref == NULL) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* XXX: I hope literalstring_new is the right Function. */
-       return (jstring)literalstring_new(ref);
-}
-
-
-/* JVM_DesiredAssertionStatus */
-
-jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)
-{
-#if defined(ENABLE_ASSERTION)
-       assertion_name_t  *item;
-       classinfo         *c;
-       jboolean           status;
-       utf               *name;
-
-       TRACEJVMCALLS(("JVM_DesiredAssertionStatus(env=%p, unused=%p, cls=%p)", env, unused, cls));
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       if (c->classloader == NULL) {
-               status = (jboolean)assertion_system_enabled;
-       }
-       else {
-               status = (jboolean)assertion_user_enabled;
-       }
-
-       if (list_assertion_names != NULL) {
-               item = (assertion_name_t *)list_first(list_assertion_names);
-               while (item != NULL) {
-                       name = utf_new_char(item->name);
-                       if (name == c->packagename) {
-                               status = (jboolean)item->enabled;
-                       }
-                       else if (name == c->name) {
-                               status = (jboolean)item->enabled;
-                       }
-
-                       item = (assertion_name_t *)list_next(list_assertion_names, item);
-               }
-       }
-
-       return status;
-#else
-       return (jboolean)false;
-#endif
-}
-
-
-/* JVM_AssertionStatusDirectives */
-
-jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
-{
-       classinfo                             *c;
-       java_lang_AssertionStatusDirectives   *o;
-       java_handle_objectarray_t             *classes;
-       java_handle_objectarray_t             *packages;
-       java_booleanarray_t                   *classEnabled;
-       java_booleanarray_t                   *packageEnabled;
-#if defined(ENABLE_ASSERTION)
-       assertion_name_t                      *item;
-       java_handle_t                         *js;
-       s4                                     i, j;
-#endif
-
-       TRACEJVMCALLS(("JVM_AssertionStatusDirectives(env=%p, unused=%p)", env, unused));
-
-       c = load_class_bootstrap(utf_new_char("java/lang/AssertionStatusDirectives"));
-
-       if (c == NULL)
-               return NULL;
-
-       o = (java_lang_AssertionStatusDirectives *) builtin_new(c);
-
-       if (o == NULL)
-               return NULL;
-
-#if defined(ENABLE_ASSERTION)
-       classes = builtin_anewarray(assertion_class_count, class_java_lang_Object);
-#else
-       classes = builtin_anewarray(0, class_java_lang_Object);
-#endif
-       if (classes == NULL)
-               return NULL;
-
-#if defined(ENABLE_ASSERTION)
-       packages = builtin_anewarray(assertion_package_count, class_java_lang_Object);
-#else
-       packages = builtin_anewarray(0, class_java_lang_Object);
-#endif
-       if (packages == NULL)
-               return NULL;
-       
-#if defined(ENABLE_ASSERTION)
-       classEnabled = builtin_newarray_boolean(assertion_class_count);
-#else
-       classEnabled = builtin_newarray_boolean(0);
-#endif
-       if (classEnabled == NULL)
-               return NULL;
-
-#if defined(ENABLE_ASSERTION)
-       packageEnabled = builtin_newarray_boolean(assertion_package_count);
-#else
-       packageEnabled = builtin_newarray_boolean(0);
-#endif
-       if (packageEnabled == NULL)
-               return NULL;
-
-#if defined(ENABLE_ASSERTION)
-       /* initialize arrays */
-
-       if (list_assertion_names != NULL) {
-               i = 0;
-               j = 0;
-               
-               item = (assertion_name_t *)list_first(list_assertion_names);
-               while (item != NULL) {
-                       js = javastring_new_from_ascii(item->name);
-                       if (js == NULL) {
-                               return NULL;
-                       }
-
-                       if (item->package == false) {
-                               classes->data[i] = js;
-                               classEnabled->data[i] = (jboolean) item->enabled;
-                               i += 1;
-                       }
-                       else {
-                               packages->data[j] = js;
-                               packageEnabled->data[j] = (jboolean) item->enabled;
-                               j += 1;
-                       }
-
-                       item = (assertion_name_t *)list_next(list_assertion_names, item);
-               }
-       }
-#endif
-
-       /* set instance fields */
-
-       o->classes  = classes;
-       o->packages = packages;
-       o->classEnabled = classEnabled;
-       o->packageEnabled = packageEnabled;
-
-       return (jobject) o;
-}
-
-
-/* JVM_GetClassNameUTF */
-
-const char *JVM_GetClassNameUTF(JNIEnv *env, jclass cls)
-{
-       log_println("JVM_GetClassNameUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetClassCPTypes */
-
-void JVM_GetClassCPTypes(JNIEnv *env, jclass cls, unsigned char *types)
-{
-       log_println("JVM_GetClassCPTypes: IMPLEMENT ME!");
-}
-
-
-/* JVM_GetClassCPEntriesCount */
-
-jint JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls)
-{
-       log_println("JVM_GetClassCPEntriesCount: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetClassFieldsCount */
-
-jint JVM_GetClassFieldsCount(JNIEnv *env, jclass cls)
-{
-       log_println("JVM_GetClassFieldsCount: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetClassMethodsCount */
-
-jint JVM_GetClassMethodsCount(JNIEnv *env, jclass cls)
-{
-       log_println("JVM_GetClassMethodsCount: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetMethodIxExceptionIndexes */
-
-void JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cls, jint method_index, unsigned short *exceptions)
-{
-       log_println("JVM_GetMethodIxExceptionIndexes: IMPLEMENT ME!");
-}
-
-
-/* JVM_GetMethodIxExceptionsCount */
-
-jint JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cls, jint method_index)
-{
-       log_println("JVM_GetMethodIxExceptionsCount: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetMethodIxByteCode */
-
-void JVM_GetMethodIxByteCode(JNIEnv *env, jclass cls, jint method_index, unsigned char *code)
-{
-       log_println("JVM_GetMethodIxByteCode: IMPLEMENT ME!");
-}
-
-
-/* JVM_GetMethodIxByteCodeLength */
-
-jint JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cls, jint method_index)
-{
-       log_println("JVM_GetMethodIxByteCodeLength: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetMethodIxExceptionTableEntry */
-
-void JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cls, jint method_index, jint entry_index, JVM_ExceptionTableEntryType *entry)
-{
-       log_println("JVM_GetMethodIxExceptionTableEntry: IMPLEMENT ME!");
-}
-
-
-/* JVM_GetMethodIxExceptionTableLength */
-
-jint JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_index)
-{
-       log_println("JVM_GetMethodIxExceptionTableLength: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetMethodIxModifiers */
-
-jint JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index)
-{
-       log_println("JVM_GetMethodIxModifiers: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetFieldIxModifiers */
-
-jint JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)
-{
-       log_println("JVM_GetFieldIxModifiers: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetMethodIxLocalsCount */
-
-jint JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index)
-{
-       log_println("JVM_GetMethodIxLocalsCount: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetMethodIxArgsSize */
-
-jint JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index)
-{
-       log_println("JVM_GetMethodIxArgsSize: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetMethodIxMaxStack */
-
-jint JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index)
-{
-       log_println("JVM_GetMethodIxMaxStack: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_IsConstructorIx */
-
-jboolean JVM_IsConstructorIx(JNIEnv *env, jclass cls, int method_index)
-{
-       log_println("JVM_IsConstructorIx: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetMethodIxNameUTF */
-
-const char *JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index)
-{
-       log_println("JVM_GetMethodIxNameUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetMethodIxSignatureUTF */
-
-const char *JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index)
-{
-       log_println("JVM_GetMethodIxSignatureUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetCPFieldNameUTF */
-
-const char *JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index)
-{
-       log_println("JVM_GetCPFieldNameUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetCPMethodNameUTF */
-
-const char *JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index)
-{
-       log_println("JVM_GetCPMethodNameUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetCPMethodSignatureUTF */
-
-const char *JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
-{
-       log_println("JVM_GetCPMethodSignatureUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetCPFieldSignatureUTF */
-
-const char *JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
-{
-       log_println("JVM_GetCPFieldSignatureUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetCPClassNameUTF */
-
-const char *JVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
-{
-       log_println("JVM_GetCPClassNameUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetCPFieldClassNameUTF */
-
-const char *JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
-{
-       log_println("JVM_GetCPFieldClassNameUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetCPMethodClassNameUTF */
-
-const char *JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
-{
-       log_println("JVM_GetCPMethodClassNameUTF: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetCPFieldModifiers */
-
-jint JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)
-{
-       log_println("JVM_GetCPFieldModifiers: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetCPMethodModifiers */
-
-jint JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)
-{
-       log_println("JVM_GetCPMethodModifiers: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_ReleaseUTF */
-
-void JVM_ReleaseUTF(const char *utf)
-{
-       log_println("JVM_ReleaseUTF: IMPLEMENT ME!");
-}
-
-
-/* JVM_IsSameClassPackage */
-
-jboolean JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2)
-{
-       log_println("JVM_IsSameClassPackage: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_Open */
-
-/* Taken from: hotspot/src/share/vm/prims/jvm.h */
-
-/*
- * JVM I/O error codes
- */
-#define JVM_EEXIST       -100
-
-jint JVM_Open(const char *fname, jint flags, jint mode)
-{
-       int result;
-
-       TRACEJVMCALLS(("JVM_Open(fname=%s, flags=%d, mode=%d)", fname, flags, mode));
-
-       result = hpi_file->Open(fname, flags, mode);
-
-       if (result >= 0) {
-               return result;
-       }
-       else {
-               switch (errno) {
-               case EEXIST:
-                       return JVM_EEXIST;
-               default:
-                       return -1;
-               }
-       }
-}
-
-
-/* JVM_Close */
-
-jint JVM_Close(jint fd)
-{
-       TRACEJVMCALLS(("JVM_Close(fd=%d)", fd));
-
-       return hpi_file->Close(fd);
-}
-
-
-/* JVM_Read */
-
-jint JVM_Read(jint fd, char *buf, jint nbytes)
-{
-       TRACEJVMCALLS(("JVM_Read(fd=%d, buf=%p, nbytes=%d)", fd, buf, nbytes));
-
-       return (jint) hpi_file->Read(fd, buf, nbytes);
-}
-
-
-/* JVM_Write */
-
-jint JVM_Write(jint fd, char *buf, jint nbytes)
-{
-       TRACEJVMCALLS(("JVM_Write(fd=%d, buf=%s, nbytes=%d)", fd, buf, nbytes));
-
-       return (jint) hpi_file->Write(fd, buf, nbytes);
-}
-
-
-/* JVM_Available */
-
-jint JVM_Available(jint fd, jlong *pbytes)
-{
-       TRACEJVMCALLS(("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes));
-
-       return hpi_file->Available(fd, pbytes);
-}
-
-
-/* JVM_Lseek */
-
-jlong JVM_Lseek(jint fd, jlong offset, jint whence)
-{
-       TRACEJVMCALLS(("JVM_Lseek(fd=%d, offset=%ld, whence=%d)", fd, offset, whence));
-
-       return hpi_file->Seek(fd, (off_t) offset, whence);
-}
-
-
-/* JVM_SetLength */
-
-jint JVM_SetLength(jint fd, jlong length)
-{
-       TRACEJVMCALLS(("JVM_SetLength(fd=%d, length=%ld)", length));
-
-       return hpi_file->SetLength(fd, length);
-}
-
-
-/* JVM_Sync */
-
-jint JVM_Sync(jint fd)
-{
-       TRACEJVMCALLS(("JVM_Sync(fd=%d)", fd));
-
-       return hpi_file->Sync(fd);
-}
-
-
-/* JVM_StartThread */
-
-void JVM_StartThread(JNIEnv* env, jobject jthread)
-{
-       TRACEJVMCALLS(("JVM_StartThread(env=%p, jthread=%p)", env, jthread));
-
-       threads_thread_start((java_handle_t *) jthread);
-}
-
-
-/* JVM_StopThread */
-
-void JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)
-{
-       log_println("JVM_StopThread: Deprecated.  Not implemented.");
-}
-
-
-/* JVM_IsThreadAlive */
-
-jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread)
-{
-       java_handle_t *h;
-       threadobject  *t;
-       bool           result;
-
-       TRACEJVMCALLS(("JVM_IsThreadAlive(env=%p, jthread=%p)", env, 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. */
-
-       if (t == NULL)
-               return 0;
-
-       result = threads_thread_is_alive(t);
-
-       return result;
-}
-
-
-/* JVM_SuspendThread */
-
-void JVM_SuspendThread(JNIEnv* env, jobject jthread)
-{
-       log_println("JVM_SuspendThread: Deprecated.  Not implemented.");
-}
-
-
-/* JVM_ResumeThread */
-
-void JVM_ResumeThread(JNIEnv* env, jobject jthread)
-{
-       log_println("JVM_ResumeThread: Deprecated.  Not implemented.");
-}
-
-
-/* JVM_SetThreadPriority */
-
-void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio)
-{
-       java_handle_t *h;
-       threadobject  *t;
-
-       TRACEJVMCALLS(("JVM_SetThreadPriority(env=%p, jthread=%p, prio=%d)", env, jthread, prio));
-
-       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. */
-
-       if (t == NULL)
-               return;
-
-       threads_set_thread_priority(t->tid, prio);
-}
-
-
-/* JVM_Yield */
-
-void JVM_Yield(JNIEnv *env, jclass threadClass)
-{
-       TRACEJVMCALLS(("JVM_Yield(env=%p, threadClass=%p)", env, threadClass));
-
-       threads_yield();
-}
-
-
-/* JVM_Sleep */
-
-void JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis)
-{
-       TRACEJVMCALLS(("JVM_Sleep(env=%p, threadClass=%p, millis=%ld)", env, threadClass, millis));
-
-       threads_sleep(millis, 0);
-}
-
-
-/* JVM_CurrentThread */
-
-jobject JVM_CurrentThread(JNIEnv* env, jclass threadClass)
-{
-       java_object_t *o;
-
-       TRACEJVMCALLSVERBOSE(("JVM_CurrentThread(env=%p, threadClass=%p)", env, threadClass));
-
-       o = thread_get_current_object();
-
-       return (jobject) o;
-}
-
-
-/* JVM_CountStackFrames */
-
-jint JVM_CountStackFrames(JNIEnv* env, jobject jthread)
-{
-       log_println("JVM_CountStackFrames: Deprecated.  Not implemented.");
-
-       return 0;
-}
-
-
-/* JVM_Interrupt */
-
-void JVM_Interrupt(JNIEnv* env, jobject jthread)
-{
-       java_handle_t *h;
-       threadobject  *t;
-
-       TRACEJVMCALLS(("JVM_Interrupt(env=%p, jthread=%p)", env, jthread));
-
-       h = (java_handle_t *) jthread;
-       t = thread_get_thread(h);
-
-       if (t == NULL)
-               return;
-
-       threads_thread_interrupt(t);
-}
-
-
-/* JVM_IsInterrupted */
-
-jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted)
-{
-       java_handle_t *h;
-       threadobject  *t;
-       jboolean       interrupted;
-
-       TRACEJVMCALLS(("JVM_IsInterrupted(env=%p, jthread=%p, clear_interrupted=%d)", env, jthread, clear_interrupted));
-
-       h = (java_handle_t *) jthread;
-       t = thread_get_thread(h);
-
-       interrupted = thread_is_interrupted(t);
-
-       if (interrupted && clear_interrupted)
-               thread_set_interrupted(t, false);
-
-       return interrupted;
-}
-
-
-/* JVM_HoldsLock */
-
-jboolean JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj)
-{
-       java_handle_t *h;
-       bool           result;
-
-       TRACEJVMCALLS(("JVM_HoldsLock(env=%p, threadClass=%p, obj=%p)", env, threadClass, obj));
-
-       h = (java_handle_t *) obj;
-
-       if (h == NULL) {
-               exceptions_throw_nullpointerexception();
-               return JNI_FALSE;
-       }
-
-       result = lock_is_held_by_current_thread(h);
-
-       return result;
-}
-
-
-/* JVM_DumpAllStacks */
-
-void JVM_DumpAllStacks(JNIEnv* env, jclass unused)
-{
-       log_println("JVM_DumpAllStacks: IMPLEMENT ME!");
-}
-
-
-/* JVM_CurrentLoadedClass */
-
-jclass JVM_CurrentLoadedClass(JNIEnv *env)
-{
-       log_println("JVM_CurrentLoadedClass: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_CurrentClassLoader */
-
-jobject JVM_CurrentClassLoader(JNIEnv *env)
-{
-    /* XXX if a method in a class in a trusted loader is in a
-          doPrivileged, return NULL */
-
-       log_println("JVM_CurrentClassLoader: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetClassContext */
-
-jobjectArray JVM_GetClassContext(JNIEnv *env)
-{
-       TRACEJVMCALLS(("JVM_GetClassContext(env=%p)", env));
-
-       return (jobjectArray) stacktrace_getClassContext();
-}
-
-
-/* JVM_ClassDepth */
-
-jint JVM_ClassDepth(JNIEnv *env, jstring name)
-{
-       log_println("JVM_ClassDepth: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_ClassLoaderDepth */
-
-jint JVM_ClassLoaderDepth(JNIEnv *env)
-{
-       log_println("JVM_ClassLoaderDepth: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetSystemPackage */
-
-jstring JVM_GetSystemPackage(JNIEnv *env, jstring name)
-{
-       java_handle_t *s;
-       utf *u;
-       utf *result;
-
-       TRACEJVMCALLS(("JVM_GetSystemPackage(env=%p, name=%p)", env, name));
-
-/*     s = Package_find(name); */
-       u = javastring_toutf((java_handle_t *) name, false);
-
-       result = Package_find(u);
-
-       if (result != NULL)
-               s = javastring_new(result);
-       else
-               s = NULL;
-
-       return (jstring) s;
-}
-
-
-/* JVM_GetSystemPackages */
-
-jobjectArray JVM_GetSystemPackages(JNIEnv *env)
-{
-       log_println("JVM_GetSystemPackages: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_AllocateNewObject */
-
-jobject JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, jclass initClass)
-{
-       log_println("JVM_AllocateNewObject: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_AllocateNewArray */
-
-jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint length)
-{
-       log_println("JVM_AllocateNewArray: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_LatestUserDefinedLoader */
-
-jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
-{
-       classloader_t *cl;
-
-       TRACEJVMCALLS(("JVM_LatestUserDefinedLoader(env=%p)", env));
-
-       cl = stacktrace_first_nonnull_classloader();
-
-       return (jobject) cl;
-}
-
-
-/* JVM_LoadClass0 */
-
-jclass JVM_LoadClass0(JNIEnv *env, jobject receiver, jclass currClass, jstring currClassName)
-{
-       log_println("JVM_LoadClass0: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetArrayLength */
-
-jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
-{
-       java_handle_t *a;
-
-       TRACEJVMCALLS(("JVM_GetArrayLength(arr=%p)", arr));
-
-       a = (java_handle_t *) arr;
-
-       return array_length_get(a);
-}
-
-
-/* JVM_GetArrayElement */
-
-jobject JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index)
-{
-       java_handle_t *a;
-       java_handle_t *o;
-
-       TRACEJVMCALLS(("JVM_GetArrayElement(env=%p, arr=%p, index=%d)", env, arr, index));
-
-       a = (java_handle_t *) arr;
-
-/*     if (!class_is_array(a->objheader.vftbl->class)) { */
-/*             exceptions_throw_illegalargumentexception(); */
-/*             return NULL; */
-/*     } */
-
-       o = array_element_get(a, index);
-
-       return (jobject) o;
-}
-
-
-/* JVM_GetPrimitiveArrayElement */
-
-jvalue JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode)
-{
-       jvalue jv;
-
-       log_println("JVM_GetPrimitiveArrayElement: IMPLEMENT ME!");
-
-       jv.l = NULL;
-
-       return jv;
-}
-
-
-/* JVM_SetArrayElement */
-
-void JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val)
-{
-       java_handle_t *a;
-       java_handle_t *value;
-
-       TRACEJVMCALLS(("JVM_SetArrayElement(env=%p, arr=%p, index=%d, val=%p)", env, arr, index, val));
-
-       a     = (java_handle_t *) arr;
-       value = (java_handle_t *) val;
-
-       array_element_set(a, index, value);
-}
-
-
-/* JVM_SetPrimitiveArrayElement */
-
-void JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, unsigned char vCode)
-{
-       log_println("JVM_SetPrimitiveArrayElement: IMPLEMENT ME!");
-}
-
-
-/* JVM_NewArray */
-
-jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
-{
-       classinfo                 *c;
-       classinfo                 *pc;
-       java_handle_t             *a;
-       java_handle_objectarray_t *oa;
-
-       TRACEJVMCALLS(("JVM_NewArray(env=%p, eltClass=%p, length=%d)", env, eltClass, length));
-
-       if (eltClass == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* NegativeArraySizeException is checked in builtin_newarray. */
-
-       c = LLNI_classinfo_unwrap(eltClass);
-
-       /* Create primitive or object array. */
-
-       if (class_is_primitive(c)) {
-               pc = primitive_arrayclass_get_by_name(c->name);
-
-               /* void arrays are not allowed. */
-
-               if (pc == NULL) {
-                       exceptions_throw_illegalargumentexception();
-                       return NULL;
-               }
-
-               a = builtin_newarray(length, pc);
-
-               return (jobject) a;
-       }
-       else {
-               oa = builtin_anewarray(length, c);
-
-               return (jobject) oa;
-       }
-}
-
-
-/* JVM_NewMultiArray */
-
-jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
-{
-       classinfo                 *c;
-       java_handle_intarray_t    *ia;
-       int32_t                    length;
-       long                      *dims;
-       int32_t                    value;
-       int32_t                    i;
-       classinfo                 *ac;
-       java_handle_objectarray_t *a;
-
-       TRACEJVMCALLS(("JVM_NewMultiArray(env=%p, eltClass=%p, dim=%p)", env, eltClass, dim));
-
-       if (eltClass == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* NegativeArraySizeException is checked in builtin_newarray. */
-
-       c = LLNI_classinfo_unwrap(eltClass);
-
-       ia = (java_handle_intarray_t *) dim;
-
-       length = array_length_get((java_handle_t *) ia);
-
-       /* We check here for exceptions thrown in array_length_get,
-          otherwise these exceptions get overwritten by the following
-          IllegalArgumentException. */
-
-       if (length < 0)
-               return NULL;
-
-       if ((length <= 0) || (length > /* MAX_DIM */ 255)) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* XXX This is just a quick hack to get it working. */
-
-       dims = MNEW(long, length);
-
-       for (i = 0; i < length; i++) {
-               value = LLNI_array_direct(ia, i);
-               dims[i] = (long) value;
-       }
-
-       /* Create an array-class if necessary. */
-
-       if (class_is_primitive(c))
-               ac = primitive_arrayclass_get_by_name(c->name);
-       else
-               ac = class_array_of(c, true);
-
-       if (ac == NULL)
-               return NULL;
-
-       a = builtin_multianewarray(length, (java_handle_t *) ac, dims);
-
-       return (jobject) a;
-}
-
-
-/* JVM_InitializeSocketLibrary */
-
-jint JVM_InitializeSocketLibrary()
-{
-       TRACEJVMCALLS(("JVM_InitializeSocketLibrary()"));
-
-       return hpi_initialize_socket_library();
-}
-
-
-/* JVM_Socket */
-
-jint JVM_Socket(jint domain, jint type, jint protocol)
-{
-       TRACEJVMCALLS(("JVM_Socket(domain=%d, type=%d, protocol=%d)", domain, type, protocol));
-
-       return system_socket(domain, type, protocol);
-}
-
-
-/* JVM_SocketClose */
-
-jint JVM_SocketClose(jint fd)
-{
-       TRACEJVMCALLS(("JVM_SocketClose(fd=%d)", fd));
-
-       return system_close(fd);
-}
-
-
-/* JVM_SocketShutdown */
-
-jint JVM_SocketShutdown(jint fd, jint howto)
-{
-       TRACEJVMCALLS(("JVM_SocketShutdown(fd=%d, howto=%d)", fd, howto));
-
-       return system_shutdown(fd, howto);
-}
-
-
-/* JVM_Recv */
-
-jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
-{
-       log_println("JVM_Recv: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_Send */
-
-jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
-{
-       log_println("JVM_Send: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_Timeout */
-
-jint JVM_Timeout(int fd, long timeout)
-{
-       log_println("JVM_Timeout: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_Listen */
-
-jint JVM_Listen(jint fd, jint count)
-{
-       TRACEJVMCALLS(("JVM_Listen(fd=%d, count=%d)", fd, count));
-
-       return system_listen(fd, count);
-}
-
-
-/* JVM_Connect */
-
-jint JVM_Connect(jint fd, struct sockaddr *him, jint len)
-{
-       TRACEJVMCALLS(("JVM_Connect(fd=%d, him=%p, len=%d)", fd, him, len));
-
-       return system_connect(fd, him, len);
-}
-
-
-/* JVM_Bind */
-
-jint JVM_Bind(jint fd, struct sockaddr *him, jint len)
-{
-       log_println("JVM_Bind: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_Accept */
-
-jint JVM_Accept(jint fd, struct sockaddr *him, jint *len)
-{
-       TRACEJVMCALLS(("JVM_Accept(fd=%d, him=%p, len=%p)", fd, him, len));
-
-       return system_accept(fd, him, (socklen_t *) len);
-}
-
-
-/* JVM_RecvFrom */
-
-jint JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen)
-{
-       log_println("JVM_RecvFrom: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetSockName */
-
-jint JVM_GetSockName(jint fd, struct sockaddr *him, int *len)
-{
-       TRACEJVMCALLS(("JVM_GetSockName(fd=%d, him=%p, len=%p)", fd, him, len));
-
-       return system_getsockname(fd, him, (socklen_t *) len);
-}
-
-
-/* JVM_SendTo */
-
-jint JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int tolen)
-{
-       log_println("JVM_SendTo: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_SocketAvailable */
-
-jint JVM_SocketAvailable(jint fd, jint *pbytes)
-{
-#if defined(FIONREAD)
-       int bytes;
-       int result;
-
-       TRACEJVMCALLS(("JVM_SocketAvailable(fd=%d, pbytes=%p)", fd, pbytes));
-
-       *pbytes = 0;
-
-       result = ioctl(fd, FIONREAD, &bytes);
-
-       if (result < 0)
-               return 0;
-
-       *pbytes = bytes;
-
-       return 1;
-#else
-# error FIONREAD not defined
-#endif
-}
-
-
-/* JVM_GetSockOpt */
-
-jint JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen)
-{
-       TRACEJVMCALLS(("JVM_GetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%p)", fd, level, optname, optval, optlen));
-
-       return system_getsockopt(fd, level, optname, optval, (socklen_t *) optlen);
-}
-
-
-/* JVM_SetSockOpt */
-
-jint JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen)
-{
-       TRACEJVMCALLS(("JVM_SetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%d)", fd, level, optname, optval, optlen));
-
-       return system_setsockopt(fd, level, optname, optval, optlen);
-}
-
-
-/* JVM_GetHostName */
-
-int JVM_GetHostName(char *name, int namelen)
-{
-       int result;
-
-       TRACEJVMCALLSENTER(("JVM_GetHostName(name=%s, namelen=%d)", name, namelen));
-
-       result = system_gethostname(name, namelen);
-
-       TRACEJVMCALLSEXIT(("->%d (name=%s)", result, name));
-
-       return result;
-}
-
-
-/* JVM_GetHostByAddr */
-
-struct hostent *JVM_GetHostByAddr(const char* name, int len, int type)
-{
-       log_println("JVM_GetHostByAddr: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetHostByName */
-
-struct hostent *JVM_GetHostByName(char* name)
-{
-       log_println("JVM_GetHostByName: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetProtoByName */
-
-struct protoent *JVM_GetProtoByName(char* name)
-{
-       log_println("JVM_GetProtoByName: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_LoadLibrary */
-
-void *JVM_LoadLibrary(const char *name)
-{
-       utf*  u;
-       void* handle;
-
-       TRACEJVMCALLSENTER(("JVM_LoadLibrary(name=%s)", name));
-
-       u = utf_new_char(name);
-
-       handle = native_library_open(u);
-
-       TRACEJVMCALLSEXIT(("->%p", handle));
-
-       return handle;
-}
-
-
-/* JVM_UnloadLibrary */
-
-void JVM_UnloadLibrary(void* handle)
-{
-       TRACEJVMCALLS(("JVM_UnloadLibrary(handle=%p)", handle));
-
-       native_library_close(handle);
-}
-
-
-/* JVM_FindLibraryEntry */
-
-void *JVM_FindLibraryEntry(void *handle, const char *name)
-{
-       void* symbol;
-
-       TRACEJVMCALLSENTER(("JVM_FindLibraryEntry(handle=%p, name=%s)", handle, name));
-
-       symbol = hpi_library->FindLibraryEntry(handle, name);
-
-       TRACEJVMCALLSEXIT(("->%p", symbol));
-
-       return symbol;
-}
-
-
-/* JVM_IsNaN */
-
-jboolean JVM_IsNaN(jdouble a)
-{
-       log_println("JVM_IsNaN: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_IsSupportedJNIVersion */
-
-jboolean JVM_IsSupportedJNIVersion(jint version)
-{
-       TRACEJVMCALLS(("JVM_IsSupportedJNIVersion(version=%d)", version));
-
-       return jni_version_check(version);
-}
-
-
-/* JVM_InternString */
-
-jstring JVM_InternString(JNIEnv *env, jstring str)
-{
-       TRACEJVMCALLS(("JVM_InternString(env=%p, str=%p)", env, str));
-
-       return (jstring) javastring_intern((java_handle_t *) str);
-}
-
-
-/* JVM_RawMonitorCreate */
-
-JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void)
-{
-       java_object_t *o;
-
-       TRACEJVMCALLS(("JVM_RawMonitorCreate()"));
-
-       o = NEW(java_object_t);
-
-       lock_init_object_lock(o);
-
-       return o;
-}
-
-
-/* JVM_RawMonitorDestroy */
-
-JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon)
-{
-       TRACEJVMCALLS(("JVM_RawMonitorDestroy(mon=%p)", mon));
-
-       FREE(mon, java_object_t);
-}
-
-
-/* JVM_RawMonitorEnter */
-
-JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon)
-{
-       TRACEJVMCALLS(("JVM_RawMonitorEnter(mon=%p)", mon));
-
-       (void) lock_monitor_enter((java_object_t *) mon);
-
-       return 0;
-}
-
-
-/* JVM_RawMonitorExit */
-
-JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon)
-{
-       TRACEJVMCALLS(("JVM_RawMonitorExit(mon=%p)", mon));
-
-       (void) lock_monitor_exit((java_object_t *) mon);
-}
-
-
-/* JVM_SetPrimitiveFieldValues */
-
-void JVM_SetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, jlongArray fieldIDs, jcharArray typecodes, jbyteArray data)
-{
-       log_println("JVM_SetPrimitiveFieldValues: IMPLEMENT ME!");
-}
-
-
-/* JVM_GetPrimitiveFieldValues */
-
-void JVM_GetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, jlongArray fieldIDs, jcharArray typecodes, jbyteArray data)
-{
-       log_println("JVM_GetPrimitiveFieldValues: IMPLEMENT ME!");
-}
-
-
-/* JVM_AccessVMBooleanFlag */
-
-jboolean JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get)
-{
-       log_println("JVM_AccessVMBooleanFlag: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_AccessVMIntFlag */
-
-jboolean JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get)
-{
-       log_println("JVM_AccessVMIntFlag: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_VMBreakPoint */
-
-void JVM_VMBreakPoint(JNIEnv *env, jobject obj)
-{
-       log_println("JVM_VMBreakPoint: IMPLEMENT ME!");
-}
-
-
-/* JVM_GetClassFields */
-
-jobjectArray JVM_GetClassFields(JNIEnv *env, jclass cls, jint which)
-{
-       log_println("JVM_GetClassFields: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetClassMethods */
-
-jobjectArray JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which)
-{
-       log_println("JVM_GetClassMethods: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetClassConstructors */
-
-jobjectArray JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which)
-{
-       log_println("JVM_GetClassConstructors: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetClassField */
-
-jobject JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which)
-{
-       log_println("JVM_GetClassField: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetClassMethod */
-
-jobject JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types, jint which)
-{
-       log_println("JVM_GetClassMethod: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetClassConstructor */
-
-jobject JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jint which)
-{
-       log_println("JVM_GetClassConstructor: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_NewInstance */
-
-jobject JVM_NewInstance(JNIEnv *env, jclass cls)
-{
-       log_println("JVM_NewInstance: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetField */
-
-jobject JVM_GetField(JNIEnv *env, jobject field, jobject obj)
-{
-       log_println("JVM_GetField: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetPrimitiveField */
-
-jvalue JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj, unsigned char wCode)
-{
-       jvalue jv;
-
-       log_println("JVM_GetPrimitiveField: IMPLEMENT ME!");
-
-       jv.l = NULL;
-
-       return jv;
-}
-
-
-/* JVM_SetField */
-
-void JVM_SetField(JNIEnv *env, jobject field, jobject obj, jobject val)
-{
-       log_println("JVM_SetField: IMPLEMENT ME!");
-}
-
-
-/* JVM_SetPrimitiveField */
-
-void JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v, unsigned char vCode)
-{
-       log_println("JVM_SetPrimitiveField: IMPLEMENT ME!");
-}
-
-
-/* JVM_InvokeMethod */
-
-jobject JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)
-{
-       java_lang_reflect_Method *rm;
-       classinfo     *c;
-       int32_t        slot;
-       int32_t        override;
-       methodinfo    *m;
-       java_handle_t *ro;
-
-       TRACEJVMCALLS(("JVM_InvokeMethod(env=%p, method=%p, obj=%p, args0=%p)", env, method, obj, args0));
-
-       rm = (java_lang_reflect_Method *) method;
-
-       LLNI_field_get_cls(rm, clazz,    c);
-       LLNI_field_get_val(rm, slot,     slot);
-       LLNI_field_get_val(rm, override, override);
-
-       m = &(c->methods[slot]);
-
-       ro = reflect_method_invoke(m, (java_handle_t *) obj, (java_handle_objectarray_t *) args0, override);
-
-       return (jobject) ro;
-}
-
-
-/* JVM_NewInstanceFromConstructor */
-
-jobject JVM_NewInstanceFromConstructor(JNIEnv *env, jobject con, jobjectArray args0)
-{
-       java_lang_reflect_Constructor *rc;
-       classinfo                     *c;
-       int32_t                        slot;
-       int32_t                        override;
-       methodinfo                    *m;
-       java_handle_t                 *o;
-
-       TRACEJVMCALLS(("JVM_NewInstanceFromConstructor(env=%p, c=%p, args0=%p)", env, con, args0));
-
-       rc = (java_lang_reflect_Constructor *) con;
-
-       LLNI_field_get_cls(rc, clazz,    c);
-       LLNI_field_get_val(rc, slot,     slot);
-       LLNI_field_get_val(rc, override, override);
-
-       m = &(c->methods[slot]);
-
-       o = reflect_constructor_newinstance(m, (java_handle_objectarray_t *) args0, override);
-
-       return (jobject) o;
-}
-
-
-/* JVM_SupportsCX8 */
-
-jboolean JVM_SupportsCX8()
-{
-       TRACEJVMCALLS(("JVM_SupportsCX8()"));
-
-       /* IMPLEMENT ME */
-
-       return 0;
-}
-
-
-/* JVM_CX8Field */
-
-jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlong newVal)
-{
-       log_println("JVM_CX8Field: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-/* JVM_GetAllThreads */
-
-jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
-{
-       log_println("JVM_GetAllThreads: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_DumpThreads */
-
-jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)
-{
-       log_println("JVM_DumpThreads: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetManagement */
-
-void *JVM_GetManagement(jint version)
-{
-       TRACEJVMCALLS(("JVM_GetManagement(version=%d)", version));
-
-       /* TODO We current don't support the management interface. */
-
-       return NULL;
-}
-
-
-/* JVM_InitAgentProperties */
-
-jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties)
-{
-       log_println("JVM_InitAgentProperties: IMPLEMENT ME!");
-
-       return NULL;
-}
-
-
-/* JVM_GetEnclosingMethodInfo */
-
-jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
-{
-       classinfo                 *c;
-       methodinfo                *m;
-       java_handle_objectarray_t *oa;
-
-       TRACEJVMCALLS(("JVM_GetEnclosingMethodInfo(env=%p, ofClass=%p)", env, ofClass));
-
-       c = LLNI_classinfo_unwrap(ofClass);
-
-       if ((c == NULL) || class_is_primitive(c))
-               return NULL;
-
-       m = class_get_enclosingmethod_raw(c);
-
-       if (m == NULL)
-               return NULL;
-
-       oa = builtin_anewarray(3, class_java_lang_Object);
-
-       if (oa == NULL)
-               return NULL;
-
-       array_objectarray_element_set(oa, 0, (java_handle_t *) LLNI_classinfo_wrap(m->clazz));
-       array_objectarray_element_set(oa, 1, javastring_new(m->name));
-       array_objectarray_element_set(oa, 2, javastring_new(m->descriptor));
-
-       return (jobjectArray) oa;
-}
-
-
-/* JVM_GetThreadStateValues */
-
-jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
-{
-       java_handle_intarray_t *ia;
-
-       TRACEJVMCALLS(("JVM_GetThreadStateValues(env=%p, javaThreadState=%d)",
-                                 env, javaThreadState));
-
-       /* If new thread states are added in future JDK and VM versions,
-          this should check if the JDK version is compatible with thread
-          states supported by the VM.  Return NULL if not compatible.
-       
-          This function must map the VM java_lang_Thread::ThreadStatus
-          to the Java thread state that the JDK supports. */
-
-       switch (javaThreadState) {
-    case THREAD_STATE_NEW:
-               ia = builtin_newarray_int(1);
-
-               if (ia == NULL)
-                       return NULL;
-
-               array_intarray_element_set(ia, 0, THREAD_STATE_NEW);
-               break; 
-
-    case THREAD_STATE_RUNNABLE:
-               ia = builtin_newarray_int(1);
-
-               if (ia == NULL)
-                       return NULL;
-
-               array_intarray_element_set(ia, 0, THREAD_STATE_RUNNABLE);
-               break; 
-
-    case THREAD_STATE_BLOCKED:
-               ia = builtin_newarray_int(1);
-
-               if (ia == NULL)
-                       return NULL;
-
-               array_intarray_element_set(ia, 0, THREAD_STATE_BLOCKED);
-               break; 
-
-    case THREAD_STATE_WAITING:
-               ia = builtin_newarray_int(2);
-
-               if (ia == NULL)
-                       return NULL;
-
-               array_intarray_element_set(ia, 0, THREAD_STATE_WAITING);
-               /* XXX Implement parked stuff. */
-/*             array_intarray_element_set(ia, 1, PARKED); */
-               break; 
-
-    case THREAD_STATE_TIMED_WAITING:
-               ia = builtin_newarray_int(3);
-
-               if (ia == NULL)
-                       return NULL;
-
-               /* 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); */
-               break; 
-
-    case THREAD_STATE_TERMINATED:
-               ia = builtin_newarray_int(1);
-
-               if (ia == NULL)
-                       return NULL;
-
-               array_intarray_element_set(ia, 0, THREAD_STATE_TERMINATED);
-               break; 
-
-    default:
-               /* Unknown state - probably incompatible JDK version */
-               return NULL;
-       }
-
-       return (jintArray) ia;
-}
-
-
-/* JVM_GetThreadStateNames */
-
-jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values)
-{
-       java_handle_intarray_t    *ia;
-       java_handle_objectarray_t *oa;
-       java_object_t             *s;
-
-       TRACEJVMCALLS(("JVM_GetThreadStateNames(env=%p, javaThreadState=%d, values=%p)",
-                                 env, javaThreadState, values));
-
-       ia = (java_handle_intarray_t *) values;
-
-       /* If new thread states are added in future JDK and VM versions,
-          this should check if the JDK version is compatible with thread
-          states supported by the VM.  Return NULL if not compatible.
-       
-          This function must map the VM java_lang_Thread::ThreadStatus
-          to the Java thread state that the JDK supports. */
-
-       if (values == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       switch (javaThreadState) {
-    case THREAD_STATE_NEW:
-               assert(ia->header.size == 1 && ia->data[0] == THREAD_STATE_NEW);
-
-               oa = builtin_anewarray(1, class_java_lang_String);
-
-               if (oa == NULL)
-                       return NULL;
-
-               s = javastring_new(utf_new_char("NEW"));
-
-               if (s == NULL)
-                       return NULL;
-
-               array_objectarray_element_set(oa, 0, s);
-               break; 
-
-    case THREAD_STATE_RUNNABLE:
-               oa = builtin_anewarray(1, class_java_lang_String);
-
-               if (oa == NULL)
-                       return NULL;
-
-               s = javastring_new(utf_new_char("RUNNABLE"));
-
-               if (s == NULL)
-                       return NULL;
-
-               array_objectarray_element_set(oa, 0, s);
-               break; 
-
-    case THREAD_STATE_BLOCKED:
-               oa = builtin_anewarray(1, class_java_lang_String);
-
-               if (oa == NULL)
-                       return NULL;
-
-               s = javastring_new(utf_new_char("BLOCKED"));
-
-               if (s == NULL)
-                       return NULL;
-
-               array_objectarray_element_set(oa, 0, s);
-               break; 
-
-    case THREAD_STATE_WAITING:
-               oa = builtin_anewarray(2, class_java_lang_String);
-
-               if (oa == NULL)
-                       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); */
-               break; 
-
-    case THREAD_STATE_TIMED_WAITING:
-               oa = builtin_anewarray(3, 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); */
-               break; 
-
-    case THREAD_STATE_TERMINATED:
-               oa = builtin_anewarray(1, class_java_lang_String);
-
-               if (oa == NULL)
-                       return NULL;
-
-               s = javastring_new(utf_new_char("TERMINATED"));
-
-               if (s == NULL)
-                       return NULL;
-
-               array_objectarray_element_set(oa, 0, s);
-               break; 
-
-       default:
-               /* Unknown state - probably incompatible JDK version */
-               return NULL;
-       }
-
-       return (jobjectArray) oa;
-}
-
-
-/* JVM_GetVersionInfo */
-
-void JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size)
-{
-       log_println("JVM_GetVersionInfo: IMPLEMENT ME!");
-}
-
-
-/* OS: JVM_RegisterSignal */
-
-void *JVM_RegisterSignal(jint sig, void *handler)
-{
-       functionptr newHandler;
-
-       TRACEJVMCALLS(("JVM_RegisterSignal(sig=%d, handler=%p)", sig, handler));
-
-       if (handler == (void *) 2)
-               newHandler = (functionptr) signal_thread_handler;
-       else
-               newHandler = (functionptr) (uintptr_t) handler;
-
-       switch (sig) {
-    case SIGILL:
-    case SIGFPE:
-    case SIGUSR1:
-    case SIGSEGV:
-               /* These signals are already used by the VM. */
-               return (void *) -1;
-
-    case SIGQUIT:
-               /* This signal is used by the VM to dump thread stacks unless
-                  ReduceSignalUsage is set, in which case the user is allowed
-                  to set his own _native_ handler for this signal; thus, in
-                  either case, we do not allow JVM_RegisterSignal to change
-                  the handler. */
-               return (void *) -1;
-
-       case SIGHUP:
-       case SIGINT:
-       case SIGTERM:
-               break;
-       }
-
-       signal_register_signal(sig, newHandler, 0);
-
-       /* XXX Should return old handler. */
-
-       return (void *) 2;
-}
-
-
-/* OS: JVM_RaiseSignal */
-
-jboolean JVM_RaiseSignal(jint sig)
-{
-       log_println("JVM_RaiseSignal: IMPLEMENT ME! sig=%s", sig);
-
-       return false;
-}
-
-
-/* OS: JVM_FindSignal */
-
-jint JVM_FindSignal(const char *name)
-{
-       TRACEJVMCALLS(("JVM_FindSignal(name=%s)", name));
-
-#if defined(__LINUX__)
-       if (strcmp(name, "HUP") == 0)
-               return SIGHUP;
-
-       if (strcmp(name, "INT") == 0)
-               return SIGINT;
-
-       if (strcmp(name, "TERM") == 0)
-               return SIGTERM;
-#else
-# error not implemented for this OS
-#endif
-
-       return -1;
-}
-
-
-/*
- * 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/native/vm/openjdk/jvm.cpp b/src/native/vm/openjdk/jvm.cpp
new file mode 100644 (file)
index 0000000..8a7a1d7
--- /dev/null
@@ -0,0 +1,3635 @@
+/* src/native/vm/openjdk/jvm.cpp - HotSpot VM interface functions
+
+   Copyright (C) 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 <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(HAVE_SYS_IOCTL_H)
+#define BSD_COMP /* Get FIONREAD on Solaris2 */
+#include <sys/ioctl.h>
+#endif
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#include "native/vm/reflection.hpp"
+
+#include "native/vm/openjdk/hpi.h"
+
+#include "threads/lock-common.h"
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+#include "toolbox/list.h"
+
+#include "vm/array.h"
+
+#if defined(ENABLE_ASSERTION)
+#include "vm/assertion.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+#include "vm/options.h"
+#include "vm/os.hpp"
+#include "vm/package.hpp"
+#include "vm/primitive.hpp"
+#include "vm/properties.h"
+#include "vm/resolve.h"
+#include "vm/signallocal.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+#include "vm/jit/stacktrace.hpp"
+
+
+/* debugging macros ***********************************************************/
+
+#if !defined(NDEBUG)
+
+# define TRACEJVMCALLS(x)                                                                              \
+    do {                                                                                                               \
+        if (opt_TraceJVMCalls || opt_TraceJVMCallsVerbose) {   \
+            log_println x;                                                                             \
+        }                                                                                                              \
+    } while (0)
+
+# define TRACEJVMCALLSENTER(x)                                                                 \
+    do {                                                                                                               \
+        if (opt_TraceJVMCalls || opt_TraceJVMCallsVerbose) {   \
+                       log_start();                                                                            \
+            log_print x;                                                                               \
+        }                                                                                                              \
+    } while (0)
+
+# define TRACEJVMCALLSEXIT(x)                                                                  \
+    do {                                                                                                               \
+        if (opt_TraceJVMCalls || opt_TraceJVMCallsVerbose) {   \
+                       log_print x;                                                                            \
+                       log_finish();                                                                           \
+        }                                                                                                              \
+    } while (0)
+
+# define TRACEJVMCALLSVERBOSE(x)                               \
+    do {                                                                               \
+        if (opt_TraceJVMCallsVerbose) {                        \
+            log_println x;                                             \
+        }                                                                              \
+    } while (0)
+
+# define PRINTJVMWARNINGS(x)
+/*     do { \ */
+/*         if (opt_PrintJVMWarnings) { \ */
+/*             log_println x; \ */
+/*         } \ */
+/*     } while (0) */
+
+#else
+
+# define TRACEJVMCALLS(x)
+# define TRACEJVMCALLSENTER(x)
+# define TRACEJVMCALLSEXIT(x)
+# define TRACEJVMCALLSVERBOSE(x)
+# define PRINTJVMWARNINGS(x)
+
+#endif
+
+
+typedef struct {
+    /* Naming convention of RE build version string: n.n.n[_uu[c]][-<identifier>]-bxx */
+    unsigned int jvm_version;   /* Consists of major, minor, micro (n.n.n) */
+                                /* and build number (xx) */
+    unsigned int update_version : 8;         /* Update release version (uu) */
+    unsigned int special_update_version : 8; /* Special update release version (c) */
+    unsigned int reserved1 : 16; 
+    unsigned int reserved2; 
+
+    /* The following bits represents JVM supports that JDK has dependency on.
+     * JDK can use these bits to determine which JVM version
+     * and support it has to maintain runtime compatibility.
+     *
+     * When a new bit is added in a minor or update release, make sure
+     * the new bit is also added in the main/baseline.
+     */
+    unsigned int is_attachable : 1;
+    unsigned int : 31;
+    unsigned int : 32;
+    unsigned int : 32;
+} jvm_version_info;
+
+
+/*
+ * A structure used to a capture exception table entry in a Java method.
+ */
+typedef struct {
+    jint start_pc;
+    jint end_pc;
+    jint handler_pc;
+    jint catchType;
+} JVM_ExceptionTableEntryType;
+
+
+// Interface functions are exported as C functions.
+extern "C" {
+
+int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
+{
+       if ((intptr_t) count <= 0)
+               return -1;
+
+       return vsnprintf(str, count, fmt, args);
+}
+
+
+int jio_snprintf(char *str, size_t count, const char *fmt, ...)
+{
+       va_list ap;
+       int     len;
+
+       va_start(ap, fmt);
+       len = jio_vsnprintf(str, count, fmt, ap);
+       va_end(ap);
+
+       return len;
+}
+
+
+int jio_fprintf(FILE* f, const char *fmt, ...)
+{
+       log_println("jio_fprintf: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+int jio_vfprintf(FILE* f, const char *fmt, va_list args)
+{
+       log_println("jio_vfprintf: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+int jio_printf(const char *fmt, ...)
+{
+       log_println("jio_printf: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetInterfaceVersion */
+
+jint JVM_GetInterfaceVersion()
+{
+       /* This is defined in hotspot/src/share/vm/prims/jvm.h */
+
+#define JVM_INTERFACE_VERSION 4
+
+       return JVM_INTERFACE_VERSION;
+}
+
+
+/* JVM_CurrentTimeMillis */
+
+jlong JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored)
+{
+       TRACEJVMCALLS(("JVM_CurrentTimeMillis(env=%p, ignored=%p)", env, ignored));
+
+       return (jlong) builtin_currenttimemillis();
+}
+
+
+/* JVM_NanoTime */
+
+jlong JVM_NanoTime(JNIEnv *env, jclass ignored)
+{
+       TRACEJVMCALLS(("JVM_NanoTime(env=%p, ignored=%p)", env, ignored));
+
+       return (jlong) builtin_nanotime();
+}
+
+
+/* JVM_ArrayCopy */
+
+void JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobject dst, jint dst_pos, jint length)
+{
+       java_handle_t *s;
+       java_handle_t *d;
+
+       s = (java_handle_t *) src;
+       d = (java_handle_t *) dst;
+
+       TRACEJVMCALLSVERBOSE(("JVM_ArrayCopy(env=%p, ignored=%p, src=%p, src_pos=%d, dst=%p, dst_pos=%d, length=%d)", env, ignored, src, src_pos, dst, dst_pos, length));
+
+       builtin_arraycopy(s, src_pos, d, dst_pos, length);
+}
+
+
+/* JVM_InitProperties */
+
+jobject JVM_InitProperties(JNIEnv *env, jobject properties)
+{
+       java_handle_t *h;
+       char           buf[256];
+
+       TRACEJVMCALLS(("JVM_InitProperties(env=%p, properties=%p)", env, properties));
+
+       h = (java_handle_t *) properties;
+
+       /* Convert the -XX:MaxDirectMemorySize= command line flag to the
+          sun.nio.MaxDirectMemorySize property.  Do this after setting
+          user properties to prevent people from setting the value with a
+          -D option, as requested. */
+
+       jio_snprintf(buf, sizeof(buf), PRINTF_FORMAT_INT64_T, opt_MaxDirectMemorySize);
+       properties_add("sun.nio.MaxDirectMemorySize", buf);
+
+       /* Add all properties. */
+
+       properties_system_add_all(h);
+
+       return properties;
+}
+
+
+/* JVM_Exit */
+
+void JVM_Exit(jint code)
+{
+       log_println("JVM_Exit: IMPLEMENT ME!");
+}
+
+
+/* JVM_Halt */
+
+void JVM_Halt(jint code)
+{
+       TRACEJVMCALLS(("JVM_Halt(code=%d)", code));
+
+/*     vm_exit(code); */
+       vm_shutdown(code);
+}
+
+
+/* JVM_OnExit(void (*func)) */
+
+void JVM_OnExit(void (*func)(void))
+{
+       log_println("JVM_OnExit(void (*func): IMPLEMENT ME!");
+}
+
+
+/* JVM_GC */
+
+void JVM_GC(void)
+{
+       TRACEJVMCALLS(("JVM_GC()"));
+
+       gc_call();
+}
+
+
+/* JVM_MaxObjectInspectionAge */
+
+jlong JVM_MaxObjectInspectionAge(void)
+{
+       log_println("JVM_MaxObjectInspectionAge: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_TraceInstructions */
+
+void JVM_TraceInstructions(jboolean on)
+{
+       log_println("JVM_TraceInstructions: IMPLEMENT ME!");
+}
+
+
+/* JVM_TraceMethodCalls */
+
+void JVM_TraceMethodCalls(jboolean on)
+{
+       log_println("JVM_TraceMethodCalls: IMPLEMENT ME!");
+}
+
+
+/* JVM_TotalMemory */
+
+jlong JVM_TotalMemory(void)
+{
+       TRACEJVMCALLS(("JVM_TotalMemory()"));
+
+       return gc_get_heap_size();
+}
+
+
+/* JVM_FreeMemory */
+
+jlong JVM_FreeMemory(void)
+{
+       TRACEJVMCALLS(("JVM_FreeMemory()"));
+
+       return gc_get_free_bytes();
+}
+
+
+/* JVM_MaxMemory */
+
+jlong JVM_MaxMemory(void)
+{
+       TRACEJVMCALLS(("JVM_MaxMemory()"));
+
+       return gc_get_max_heap_size();
+}
+
+
+/* JVM_ActiveProcessorCount */
+
+jint JVM_ActiveProcessorCount(void)
+{
+       TRACEJVMCALLS(("JVM_ActiveProcessorCount()"));
+
+       return os::processors_online();
+}
+
+
+/* JVM_FillInStackTrace */
+
+void JVM_FillInStackTrace(JNIEnv *env, jobject receiver)
+{
+       TRACEJVMCALLS(("JVM_FillInStackTrace(env=%p, receiver=%p)", env, receiver));
+
+       java_handle_bytearray_t* ba = stacktrace_get_current();
+
+       if (ba == NULL)
+               return;
+
+       java_lang_Throwable jlt(receiver, ba);
+}
+
+
+/* JVM_PrintStackTrace */
+
+void JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable)
+{
+       log_println("JVM_PrintStackTrace: IMPLEMENT ME!");
+}
+
+
+/* JVM_GetStackTraceDepth */
+
+jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
+{
+       TRACEJVMCALLS(("JVM_GetStackTraceDepth(env=%p, throwable=%p)", env, throwable));
+
+       java_lang_Throwable jlt(throwable);
+
+       if (jlt.is_null()) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       java_handle_bytearray_t* ba = jlt.get_backtrace();
+
+       if (ba == NULL)
+               return 0;
+
+       // 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);
+
+       int32_t depth = st->length;
+
+       LLNI_CRITICAL_END;
+
+       return depth;
+}
+
+
+/* JVM_GetStackTraceElement */
+
+jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
+{
+       TRACEJVMCALLS(("JVM_GetStackTraceElement(env=%p, throwable=%p, index=%d)", env, throwable, 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
+       // 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 The linenumbertable_linenumber_for_pc could change
+                  the methodinfo pointer when hitting an inlined method. */
+
+               linenumber = linenumbertable_linenumber_for_pc(&m, code, 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();
+}
+
+
+/* JVM_IHashCode */
+
+jint JVM_IHashCode(JNIEnv* env, jobject handle)
+{
+       TRACEJVMCALLS(("JVM_IHashCode(env=%p, jobject=%p)", env, handle));
+
+       return (jint) ((ptrint) handle);
+}
+
+
+/* JVM_MonitorWait */
+
+void JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)
+{
+#if defined(ENABLE_THREADS)
+       java_handle_t *o;
+#endif
+
+       TRACEJVMCALLS(("JVM_MonitorWait(env=%p, handle=%p, ms=%ld)", env, handle, ms));
+    if (ms < 0) {
+/*             exceptions_throw_illegalargumentexception("argument out of range"); */
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+#if defined(ENABLE_THREADS)
+       o = (java_handle_t *) handle;
+
+       lock_wait_for_object(o, ms, 0);
+#endif
+}
+
+
+/* JVM_MonitorNotify */
+
+void JVM_MonitorNotify(JNIEnv* env, jobject handle)
+{
+#if defined(ENABLE_THREADS)
+       java_handle_t *o;
+#endif
+
+       TRACEJVMCALLS(("JVM_MonitorNotify(env=%p, handle=%p)", env, handle));
+
+#if defined(ENABLE_THREADS)
+       o = (java_handle_t *) handle;
+
+       lock_notify_object(o);
+#endif
+}
+
+
+/* JVM_MonitorNotifyAll */
+
+void JVM_MonitorNotifyAll(JNIEnv* env, jobject handle)
+{
+#if defined(ENABLE_THREADS)
+       java_handle_t *o;
+#endif
+
+       TRACEJVMCALLS(("JVM_MonitorNotifyAll(env=%p, handle=%p)", env, handle));
+
+#if defined(ENABLE_THREADS)
+       o = (java_handle_t *) handle;
+
+       lock_notify_all_object(o);
+#endif
+}
+
+
+/* JVM_Clone */
+
+jobject JVM_Clone(JNIEnv* env, jobject handle)
+{
+       TRACEJVMCALLS(("JVM_Clone(env=%p, handle=%p)", env, handle));
+
+       return (jobject) builtin_clone(env, (java_handle_t *) handle);
+}
+
+
+/* JVM_InitializeCompiler  */
+
+void JVM_InitializeCompiler (JNIEnv *env, jclass compCls)
+{
+       log_println("JVM_InitializeCompiler : IMPLEMENT ME!");
+}
+
+
+/* JVM_IsSilentCompiler */
+
+jboolean JVM_IsSilentCompiler(JNIEnv *env, jclass compCls)
+{
+       log_println("JVM_IsSilentCompiler: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_CompileClass */
+
+jboolean JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls)
+{
+       log_println("JVM_CompileClass: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_CompileClasses */
+
+jboolean JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname)
+{
+       log_println("JVM_CompileClasses: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_CompilerCommand */
+
+jobject JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg)
+{
+       log_println("JVM_CompilerCommand: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_EnableCompiler */
+
+void JVM_EnableCompiler(JNIEnv *env, jclass compCls)
+{
+       TRACEJVMCALLS(("JVM_EnableCompiler(env=%p, compCls=%p)", env, compCls));
+       PRINTJVMWARNINGS(("JVM_EnableCompiler not supported"));
+}
+
+
+/* JVM_DisableCompiler */
+
+void JVM_DisableCompiler(JNIEnv *env, jclass compCls)
+{
+       TRACEJVMCALLS(("JVM_DisableCompiler(env=%p, compCls=%p)", env, compCls));
+       PRINTJVMWARNINGS(("JVM_DisableCompiler not supported"));
+}
+
+
+/* JVM_GetLastErrorString */
+
+jint JVM_GetLastErrorString(char *buf, int len)
+{
+       TRACEJVMCALLS(("JVM_GetLastErrorString(buf=%p, len=%d", buf, len));
+
+       return hpi_system->GetLastErrorString(buf, len);
+}
+
+
+/* JVM_NativePath */
+
+char *JVM_NativePath(char *path)
+{
+       TRACEJVMCALLS(("JVM_NativePath(path=%s)", path));
+
+       return hpi_file->NativePath(path);
+}
+
+
+/* JVM_GetCallerClass */
+
+jclass JVM_GetCallerClass(JNIEnv* env, int depth)
+{
+       classinfo *c;
+
+       TRACEJVMCALLS(("JVM_GetCallerClass(env=%p, depth=%d)", env, depth));
+
+       c = stacktrace_get_caller_class(depth);
+
+       return (jclass) c;
+}
+
+
+/* JVM_FindPrimitiveClass */
+
+jclass JVM_FindPrimitiveClass(JNIEnv* env, const char* s)
+{
+       classinfo *c;
+       utf       *u;
+
+       TRACEJVMCALLS(("JVM_FindPrimitiveClass(env=%p, s=%s)", env, s));
+
+       u = utf_new_char(s);
+       c = Primitive::get_class_by_name(u);
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/* JVM_ResolveClass */
+
+void JVM_ResolveClass(JNIEnv* env, jclass cls)
+{
+       TRACEJVMCALLS(("JVM_ResolveClass(env=%p, cls=%p)", env, cls));
+       PRINTJVMWARNINGS(("JVM_ResolveClass not implemented"));
+}
+
+
+/* JVM_FindClassFromClassLoader */
+
+jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init, jobject loader, jboolean throwError)
+{
+       classinfo     *c;
+       utf           *u;
+       classloader_t *cl;
+
+       TRACEJVMCALLS(("JVM_FindClassFromClassLoader(name=%s, init=%d, loader=%p, throwError=%d)", name, init, loader, throwError));
+
+       /* As of now, OpenJDK does not call this function with throwError
+          is true. */
+
+       assert(throwError == false);
+
+       u  = utf_new_char(name);
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
+
+       c = load_class_from_classloader(u, cl);
+
+       if (c == NULL)
+               return NULL;
+
+       if (init)
+               if (!(c->state & CLASS_INITIALIZED))
+                       if (!initialize_class(c))
+                               return NULL;
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/* JVM_FindClassFromClass */
+
+jclass JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jclass from)
+{
+       log_println("JVM_FindClassFromClass: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_DefineClass */
+
+jclass JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd)
+{
+       log_println("JVM_DefineClass: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_DefineClassWithSource */
+
+jclass JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source)
+{
+       classinfo     *c;
+       utf           *u;
+       classloader_t *cl;
+
+       TRACEJVMCALLS(("JVM_DefineClassWithSource(env=%p, name=%s, loader=%p, buf=%p, len=%d, pd=%p, source=%s)", env, name, loader, buf, len, pd, source));
+
+       if (name != NULL)
+               u = utf_new_char(name);
+       else
+               u = NULL;
+
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
+
+       /* XXX do something with source */
+
+       c = class_define(u, cl, len, (uint8_t *) buf, (java_handle_t *) pd);
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/* JVM_FindLoadedClass */
+
+jclass JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
+{
+       classloader_t *cl;
+       utf           *u;
+       classinfo     *c;
+
+       TRACEJVMCALLS(("JVM_FindLoadedClass(env=%p, loader=%p, name=%p)", env, loader, name));
+
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
+
+       u = javastring_toutf((java_handle_t *) name, true);
+       c = classcache_lookup(cl, u);
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
+/* JVM_GetClassName */
+
+jstring JVM_GetClassName(JNIEnv *env, jclass cls)
+{
+       classinfo* c;
+
+       TRACEJVMCALLS(("JVM_GetClassName(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       return (jstring) class_get_classname(c);
+}
+
+
+/* JVM_GetClassInterfaces */
+
+jobjectArray JVM_GetClassInterfaces(JNIEnv *env, jclass cls)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       TRACEJVMCALLS(("JVM_GetClassInterfaces(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       oa = class_get_interfaces(c);
+
+       return (jobjectArray) oa;
+}
+
+
+/* JVM_GetClassLoader */
+
+jobject JVM_GetClassLoader(JNIEnv *env, jclass cls)
+{
+       classinfo     *c;
+       classloader_t *cl;
+
+       TRACEJVMCALLSENTER(("JVM_GetClassLoader(env=%p, cls=%p)", env, cls));
+
+       c  = LLNI_classinfo_unwrap(cls);
+       cl = class_get_classloader(c);
+
+       TRACEJVMCALLSEXIT(("->%p", cl));
+
+       return (jobject) cl;
+}
+
+
+/* JVM_IsInterface */
+
+jboolean JVM_IsInterface(JNIEnv *env, jclass cls)
+{
+       classinfo *c;
+
+       TRACEJVMCALLS(("JVM_IsInterface(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       return class_is_interface(c);
+}
+
+
+/* JVM_GetClassSigners */
+
+jobjectArray JVM_GetClassSigners(JNIEnv *env, jclass cls)
+{
+       log_println("JVM_GetClassSigners: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_SetClassSigners */
+
+void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *hoa;
+
+       TRACEJVMCALLS(("JVM_SetClassSigners(env=%p, cls=%p, signers=%p)", env, cls, signers));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       hoa = (java_handle_objectarray_t *) signers;
+
+    /* This call is ignored for primitive types and arrays.  Signers
+          are only set once, ClassLoader.java, and thus shouldn't be
+          called with an array.  Only the bootstrap loader creates
+          arrays. */
+
+       if (class_is_primitive(c) || class_is_array(c))
+               return;
+
+       LLNI_classinfo_field_set(c, signers, hoa);
+}
+
+
+/* JVM_GetProtectionDomain */
+
+jobject JVM_GetProtectionDomain(JNIEnv *env, jclass cls)
+{
+       classinfo *c;
+
+       TRACEJVMCALLS(("JVM_GetProtectionDomain(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       if (c == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+    /* Primitive types do not have a protection domain. */
+
+       if (class_is_primitive(c))
+               return NULL;
+
+       return (jobject) c->protectiondomain;
+}
+
+
+/* JVM_SetProtectionDomain */
+
+void JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)
+{
+       log_println("JVM_SetProtectionDomain: IMPLEMENT ME!");
+}
+
+
+/* JVM_DoPrivileged */
+
+jobject JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)
+{
+       java_handle_t *h;
+       classinfo     *c;
+       methodinfo    *m;
+       java_handle_t *result;
+       java_handle_t *e;
+
+       TRACEJVMCALLS(("JVM_DoPrivileged(env=%p, cls=%p, action=%p, context=%p, wrapException=%d)", env, cls, action, context, wrapException));
+
+       h = (java_handle_t *) action;
+       LLNI_class_get(h, c);
+
+       if (action == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* lookup run() method (throw no exceptions) */
+
+       m = class_resolveclassmethod(c, utf_run, utf_void__java_lang_Object, c,
+                                                                false);
+
+       if ((m == NULL) || !(m->flags & ACC_PUBLIC) || (m->flags & ACC_STATIC)) {
+               exceptions_throw_internalerror("No run method");
+               return NULL;
+       }
+
+       /* XXX It seems something with a privileged stack needs to be done
+          here. */
+
+       result = vm_call_method(m, h);
+
+       e = exceptions_get_exception();
+
+       if (e != NULL) {
+               if ( builtin_instanceof(e, class_java_lang_Exception) &&
+                       !builtin_instanceof(e, class_java_lang_RuntimeException)) {
+                       exceptions_clear_exception();
+                       exceptions_throw_privilegedactionexception(e);
+               }
+
+               return NULL;
+       }
+
+       return (jobject) result;
+}
+
+
+/* JVM_GetInheritedAccessControlContext */
+
+jobject JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)
+{
+       log_println("JVM_GetInheritedAccessControlContext: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetStackAccessControlContext */
+
+jobject JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls)
+{
+       TRACEJVMCALLS(("JVM_GetStackAccessControlContext(env=%p, cls=%p): IMPLEMENT ME!", env, cls));
+
+       /* XXX All stuff I tested so far works without that function.  At
+          some point we have to implement it, but I disable the output
+          for now to make IcedTea happy. */
+
+       return NULL;
+}
+
+
+/* JVM_IsArrayClass */
+
+jboolean JVM_IsArrayClass(JNIEnv *env, jclass cls)
+{
+       classinfo *c;
+
+       TRACEJVMCALLS(("JVM_IsArrayClass(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       return class_is_array(c);
+}
+
+
+/* JVM_IsPrimitiveClass */
+
+jboolean JVM_IsPrimitiveClass(JNIEnv *env, jclass cls)
+{
+       classinfo *c;
+
+       TRACEJVMCALLS(("JVM_IsPrimitiveClass(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       return class_is_primitive(c);
+}
+
+
+/* JVM_GetComponentType */
+
+jclass JVM_GetComponentType(JNIEnv *env, jclass cls)
+{
+       classinfo *component;
+       classinfo *c;
+       
+       TRACEJVMCALLS(("JVM_GetComponentType(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+       
+       component = class_get_componenttype(c);
+
+       return (jclass) LLNI_classinfo_wrap(component);
+}
+
+
+/* JVM_GetClassModifiers */
+
+jint JVM_GetClassModifiers(JNIEnv *env, jclass cls)
+{
+       classinfo *c;
+       int32_t    flags;
+
+       TRACEJVMCALLS(("JVM_GetClassModifiers(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       flags = class_get_modifiers(c, false);
+
+       return flags;
+}
+
+
+/* JVM_GetDeclaredClasses */
+
+jobjectArray JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       TRACEJVMCALLS(("JVM_GetDeclaredClasses(env=%p, ofClass=%p)", env, ofClass));
+
+       c = LLNI_classinfo_unwrap(ofClass);
+
+       oa = class_get_declaredclasses(c, false);
+
+       return (jobjectArray) oa;
+}
+
+
+/* JVM_GetDeclaringClass */
+
+jclass JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass)
+{
+       classinfo *c;
+       classinfo *dc;
+
+       TRACEJVMCALLS(("JVM_GetDeclaringClass(env=%p, ofClass=%p)", env, ofClass));
+
+       c = LLNI_classinfo_unwrap(ofClass);
+
+       dc = class_get_declaringclass(c);
+
+       return (jclass) LLNI_classinfo_wrap(dc);
+}
+
+
+/* JVM_GetClassSignature */
+
+jstring JVM_GetClassSignature(JNIEnv *env, jclass cls)
+{
+       classinfo     *c;
+       utf           *u;
+       java_handle_t *s;
+
+       TRACEJVMCALLS(("JVM_GetClassSignature(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       /* Get the signature of the class. */
+
+       u = class_get_signature(c);
+
+       if (u == NULL)
+               return NULL;
+
+       /* Convert UTF-string to a Java-string. */
+
+       s = javastring_new(u);
+
+       return (jstring) s;
+}
+
+
+/* JVM_GetClassAnnotations */
+
+jbyteArray JVM_GetClassAnnotations(JNIEnv *env, jclass cls)
+{
+       TRACEJVMCALLS(("JVM_GetClassAnnotations(env=%p, cls=%p)", env, cls));
+
+       if (cls == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+       
+       classinfo* c = LLNI_classinfo_unwrap(cls);
+
+       /* get annotations: */
+       java_handle_bytearray_t* annotations = class_get_annotations(c);
+
+       return (jbyteArray) annotations;
+}
+
+
+/* JVM_GetFieldAnnotations */
+
+jbyteArray JVM_GetFieldAnnotations(JNIEnv *env, jobject field)
+{
+       TRACEJVMCALLS(("JVM_GetFieldAnnotations(env=%p, field=%p)", env, field));
+
+       java_lang_reflect_Field jlrf(field);
+
+       if (jlrf.is_null()) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       return (jbyteArray) jlrf.get_annotations();
+}
+
+
+/* JVM_GetMethodAnnotations */
+
+jbyteArray JVM_GetMethodAnnotations(JNIEnv *env, jobject method)
+{
+       TRACEJVMCALLS(("JVM_GetMethodAnnotations(env=%p, method=%p)", env, method));
+
+       java_lang_reflect_Method jlrm(method);
+
+       if (jlrm.is_null()) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       return (jbyteArray) jlrm.get_annotations();
+}
+
+
+/* JVM_GetMethodDefaultAnnotationValue */
+
+jbyteArray JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method)
+{
+       TRACEJVMCALLS(("JVM_GetMethodDefaultAnnotationValue(env=%p, method=%p)", env, method));
+
+       java_lang_reflect_Method jlrm(method);
+
+       if (jlrm.is_null()) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       return (jbyteArray) jlrm.get_annotationDefault();
+}
+
+
+/* JVM_GetMethodParameterAnnotations */
+
+jbyteArray JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method)
+{
+       TRACEJVMCALLS(("JVM_GetMethodParameterAnnotations(env=%p, method=%p)", env, method));
+
+       java_lang_reflect_Method jlrm(method);
+
+       if (jlrm.is_null()) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       return (jbyteArray) jlrm.get_parameterAnnotations();
+}
+
+
+/* JVM_GetClassDeclaredFields */
+
+jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       TRACEJVMCALLS(("JVM_GetClassDeclaredFields(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly));
+
+       c = LLNI_classinfo_unwrap(ofClass);
+
+       oa = class_get_declaredfields(c, publicOnly);
+
+       return (jobjectArray) oa;
+}
+
+
+/* JVM_GetClassDeclaredMethods */
+
+jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)
+{
+       TRACEJVMCALLS(("JVM_GetClassDeclaredMethods(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly));
+
+       classinfo* c = LLNI_classinfo_unwrap(ofClass);
+
+       java_handle_objectarray_t* oa = class_get_declaredmethods(c, publicOnly);
+
+       return (jobjectArray) oa;
+}
+
+
+/* JVM_GetClassDeclaredConstructors */
+
+jobjectArray JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)
+{
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       TRACEJVMCALLS(("JVM_GetClassDeclaredConstructors(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly));
+
+       c = LLNI_classinfo_unwrap(ofClass);
+
+       oa = class_get_declaredconstructors(c, publicOnly);
+
+       return (jobjectArray) oa;
+}
+
+
+/* JVM_GetClassAccessFlags */
+
+jint JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)
+{
+       classinfo *c;
+
+       TRACEJVMCALLS(("JVM_GetClassAccessFlags(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       /* Primitive type classes have the correct access flags. */
+
+       return c->flags & ACC_CLASS_REFLECT_MASK;
+}
+
+
+/* JVM_GetClassConstantPool */
+
+jobject JVM_GetClassConstantPool(JNIEnv *env, jclass cls)
+{
+#if defined(ENABLE_ANNOTATIONS)
+       TRACEJVMCALLS(("JVM_GetClassConstantPool(env=%p, cls=%p)", env, cls));
+
+       java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
+       sun_reflect_ConstantPool cp(h, cls);
+       
+       if (cp.is_null()) {
+               return NULL;
+       }
+       
+       return (jobject) cp.get_handle();
+#else
+       log_println("JVM_GetClassConstantPool(env=%p, cls=%p): not implemented in this configuration!", env, cls);
+       return NULL;
+#endif
+}
+
+
+/* JVM_ConstantPoolGetSize */
+
+jint JVM_ConstantPoolGetSize(JNIEnv *env, jobject unused, jobject jcpool)
+{
+       classinfo *c; /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetSize(env=%p, unused=%p, jcpool=%p)", env, unused, jcpool));
+
+       c = LLNI_classinfo_unwrap(jcpool);
+
+       return c->cpcount;
+}
+
+
+/* JVM_ConstantPoolGetClassAt */
+
+jclass JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_classref *ref;    /* classref to the class at constant pool index 'index' */
+       classinfo         *c;      /* classinfo of the class for which 'this' is the constant pool */
+       classinfo         *result; /* classinfo of the class at constant pool index 'index' */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetClassAt(env=%p, jcpool=%p, index=%d)", env, jcpool, index));
+
+       c = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_classref *) class_getconstant(c, index, CONSTANT_Class);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       result = resolve_classref_eager(ref);
+
+       return (jclass) LLNI_classinfo_wrap(result);
+}
+
+
+/* JVM_ConstantPoolGetClassAtIfLoaded */
+
+jclass JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_classref *ref;    /* classref to the class at constant pool index 'index' */
+       classinfo         *c;      /* classinfo of the class for which 'this' is the constant pool */
+       classinfo         *result; /* classinfo of the class at constant pool index 'index' */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetClassAtIfLoaded(env=%p, unused=%p, jcpool=%p, index=%d)", env, unused, jcpool, index));
+
+       c = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_classref *) class_getconstant(c, index, CONSTANT_Class);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+       
+       if (!resolve_classref(NULL, ref, resolveLazy, true, true, &result)) {
+               return NULL;
+       }
+
+       if ((result == NULL) || !(result->state & CLASS_LOADED)) {
+               return NULL;
+       }
+       
+       return (jclass) LLNI_classinfo_wrap(result);
+}
+
+
+/* JVM_ConstantPoolGetMethodAt */
+
+jobject JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_FMIref *ref; /* reference to the method in constant pool at index 'index' */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
+       
+       TRACEJVMCALLS(("JVM_ConstantPoolGetMethodAt: jcpool=%p, index=%d", jcpool, index));
+       
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Methodref);
+       
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       // Create a new java.lang.reflect.Method Java object.
+       /* XXX: is that right? or do I have to use resolve_method_*? */
+       java_lang_reflect_Method jlrm(ref->p.method);
+
+       return (jobject) jlrm.get_handle();
+}
+
+
+/* JVM_ConstantPoolGetMethodAtIfLoaded */
+
+jobject JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_FMIref *ref; /* reference to the method in constant pool at index 'index' */
+       classinfo *c = NULL;  /* resolved declaring class of the method */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetMethodAtIfLoaded: jcpool=%p, index=%d", jcpool, index));
+
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Methodref);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       if (!resolve_classref(NULL, ref->p.classref, resolveLazy, true, true, &c)) {
+               return NULL;
+       }
+
+       if (c == NULL || !(c->state & CLASS_LOADED)) {
+               return NULL;
+       }
+
+       // Create a new java.lang.reflect.Method Java object.
+       java_lang_reflect_Method jlrm(ref->p.method);
+
+       return (jobject) jlrm.get_handle();
+}
+
+
+/* JVM_ConstantPoolGetFieldAt */
+
+jobject JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_FMIref *ref; /* reference to the field in constant pool at index 'index' */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
+       
+       TRACEJVMCALLS(("JVM_ConstantPoolGetFieldAt: jcpool=%p, index=%d", jcpool, index));
+
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Fieldref);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       // Create a new java.lang.reflect.Field Java object.
+       java_lang_reflect_Field jlrf(ref->p.field);
+
+       return (jobject) jlrf.get_handle();
+}
+
+
+/* JVM_ConstantPoolGetFieldAtIfLoaded */
+
+jobject JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_FMIref *ref; /* reference to the field in constant pool at index 'index' */
+       classinfo *c;         /* resolved declaring class for the field */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetFieldAtIfLoaded: jcpool=%p, index=%d", jcpool, index));
+
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Fieldref);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       if (!resolve_classref(NULL, ref->p.classref, resolveLazy, true, true, &c)) {
+               return NULL;
+       }
+
+       if (c == NULL || !(c->state & CLASS_LOADED)) {
+               return NULL;
+       }
+
+       // Create a new java.lang.reflect.Field Java object.
+       java_lang_reflect_Field jlrf(ref->p.field);
+
+       return (jobject) jlrf.get_handle();
+}
+
+
+/* JVM_ConstantPoolGetMemberRefInfoAt */
+
+jobjectArray JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       log_println("JVM_ConstantPoolGetMemberRefInfoAt: jcpool=%p, index=%d, IMPLEMENT ME!", jcpool, index);
+
+       /* TODO: implement. (this is yet unused be OpenJDK but, so very low priority) */
+
+       return NULL;
+}
+
+
+/* JVM_ConstantPoolGetIntAt */
+
+jint JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_integer *ref; /* reference to the int value in constant pool at index 'index' */
+       classinfo *cls;        /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetIntAt: jcpool=%p, index=%d", jcpool, index));
+
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (constant_integer*)class_getconstant(cls, index, CONSTANT_Integer);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       return ref->value;
+}
+
+
+/* JVM_ConstantPoolGetLongAt */
+
+jlong JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_long *ref; /* reference to the long value in constant pool at index 'index' */
+       classinfo *cls;     /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetLongAt: jcpool=%p, index=%d", jcpool, index));
+
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (constant_long*)class_getconstant(cls, index, CONSTANT_Long);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       return ref->value;
+}
+
+
+/* JVM_ConstantPoolGetFloatAt */
+
+jfloat JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_float *ref; /* reference to the float value in constant pool at index 'index' */
+       classinfo *cls;      /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetFloatAt: jcpool=%p, index=%d", jcpool, index));
+
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (constant_float*)class_getconstant(cls, index, CONSTANT_Float);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       return ref->value;
+}
+
+
+/* JVM_ConstantPoolGetDoubleAt */
+
+jdouble JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       constant_double *ref; /* reference to the double value in constant pool at index 'index' */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetDoubleAt: jcpool=%p, index=%d", jcpool, index));
+
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (constant_double*)class_getconstant(cls, index, CONSTANT_Double);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       return ref->value;
+}
+
+
+/* JVM_ConstantPoolGetStringAt */
+
+jstring JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       utf *ref;       /* utf object for the string in constant pool at index 'index' */
+       classinfo *cls; /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetStringAt: jcpool=%p, index=%d", jcpool, index));
+       
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (utf*)class_getconstant(cls, index, CONSTANT_String);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       /* XXX: I hope literalstring_new is the right Function. */
+       return (jstring)literalstring_new(ref);
+}
+
+
+/* JVM_ConstantPoolGetUTF8At */
+
+jstring JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject unused, jobject jcpool, jint index)
+{
+       utf *ref; /* utf object for the utf8 data in constant pool at index 'index' */
+       classinfo *cls; /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS(("JVM_ConstantPoolGetUTF8At: jcpool=%p, index=%d", jcpool, index));
+
+       cls = LLNI_classinfo_unwrap(jcpool);
+       ref = (utf*)class_getconstant(cls, index, CONSTANT_Utf8);
+
+       if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       /* XXX: I hope literalstring_new is the right Function. */
+       return (jstring)literalstring_new(ref);
+}
+
+
+/* JVM_DesiredAssertionStatus */
+
+jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)
+{
+#if defined(ENABLE_ASSERTION)
+       assertion_name_t  *item;
+       classinfo         *c;
+       jboolean           status;
+       utf               *name;
+
+       TRACEJVMCALLS(("JVM_DesiredAssertionStatus(env=%p, unused=%p, cls=%p)", env, unused, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       if (c->classloader == NULL) {
+               status = (jboolean)assertion_system_enabled;
+       }
+       else {
+               status = (jboolean)assertion_user_enabled;
+       }
+
+       if (list_assertion_names != NULL) {
+               item = (assertion_name_t *)list_first(list_assertion_names);
+               while (item != NULL) {
+                       name = utf_new_char(item->name);
+                       if (name == c->packagename) {
+                               status = (jboolean)item->enabled;
+                       }
+                       else if (name == c->name) {
+                               status = (jboolean)item->enabled;
+                       }
+
+                       item = (assertion_name_t *)list_next(list_assertion_names, item);
+               }
+       }
+
+       return status;
+#else
+       return (jboolean)false;
+#endif
+}
+
+
+/* JVM_AssertionStatusDirectives */
+
+jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
+{
+       java_handle_objectarray_t             *classes;
+       java_handle_objectarray_t             *packages;
+       java_booleanarray_t                   *classEnabled;
+       java_booleanarray_t                   *packageEnabled;
+#if defined(ENABLE_ASSERTION)
+       assertion_name_t                      *item;
+       java_handle_t                         *js;
+       s4                                     i, j;
+#endif
+
+       TRACEJVMCALLS(("JVM_AssertionStatusDirectives(env=%p, unused=%p)", env, unused));
+
+#if defined(ENABLE_ASSERTION)
+       classes = builtin_anewarray(assertion_class_count, class_java_lang_Object);
+#else
+       classes = builtin_anewarray(0, class_java_lang_Object);
+#endif
+       if (classes == NULL)
+               return NULL;
+
+#if defined(ENABLE_ASSERTION)
+       packages = builtin_anewarray(assertion_package_count, class_java_lang_Object);
+#else
+       packages = builtin_anewarray(0, class_java_lang_Object);
+#endif
+       if (packages == NULL)
+               return NULL;
+       
+#if defined(ENABLE_ASSERTION)
+       classEnabled = builtin_newarray_boolean(assertion_class_count);
+#else
+       classEnabled = builtin_newarray_boolean(0);
+#endif
+       if (classEnabled == NULL)
+               return NULL;
+
+#if defined(ENABLE_ASSERTION)
+       packageEnabled = builtin_newarray_boolean(assertion_package_count);
+#else
+       packageEnabled = builtin_newarray_boolean(0);
+#endif
+       if (packageEnabled == NULL)
+               return NULL;
+
+#if defined(ENABLE_ASSERTION)
+       /* initialize arrays */
+
+       if (list_assertion_names != NULL) {
+               i = 0;
+               j = 0;
+               
+               item = (assertion_name_t *)list_first(list_assertion_names);
+               while (item != NULL) {
+                       js = javastring_new_from_ascii(item->name);
+                       if (js == NULL) {
+                               return NULL;
+                       }
+
+                       if (item->package == false) {
+                               classes->data[i] = js;
+                               classEnabled->data[i] = (jboolean) item->enabled;
+                               i += 1;
+                       }
+                       else {
+                               packages->data[j] = js;
+                               packageEnabled->data[j] = (jboolean) item->enabled;
+                               j += 1;
+                       }
+
+                       item = (assertion_name_t *)list_next(list_assertion_names, item);
+               }
+       }
+#endif
+
+       /* set instance fields */
+
+       java_lang_AssertionStatusDirectives jlasd(classes, classEnabled, packages, packageEnabled);
+
+       return (jobject) jlasd.get_handle();
+}
+
+
+/* JVM_GetClassNameUTF */
+
+const char *JVM_GetClassNameUTF(JNIEnv *env, jclass cls)
+{
+       log_println("JVM_GetClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetClassCPTypes */
+
+void JVM_GetClassCPTypes(JNIEnv *env, jclass cls, unsigned char *types)
+{
+       log_println("JVM_GetClassCPTypes: IMPLEMENT ME!");
+}
+
+
+/* JVM_GetClassCPEntriesCount */
+
+jint JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls)
+{
+       log_println("JVM_GetClassCPEntriesCount: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetClassFieldsCount */
+
+jint JVM_GetClassFieldsCount(JNIEnv *env, jclass cls)
+{
+       log_println("JVM_GetClassFieldsCount: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetClassMethodsCount */
+
+jint JVM_GetClassMethodsCount(JNIEnv *env, jclass cls)
+{
+       log_println("JVM_GetClassMethodsCount: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetMethodIxExceptionIndexes */
+
+void JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cls, jint method_index, unsigned short *exceptions)
+{
+       log_println("JVM_GetMethodIxExceptionIndexes: IMPLEMENT ME!");
+}
+
+
+/* JVM_GetMethodIxExceptionsCount */
+
+jint JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cls, jint method_index)
+{
+       log_println("JVM_GetMethodIxExceptionsCount: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetMethodIxByteCode */
+
+void JVM_GetMethodIxByteCode(JNIEnv *env, jclass cls, jint method_index, unsigned char *code)
+{
+       log_println("JVM_GetMethodIxByteCode: IMPLEMENT ME!");
+}
+
+
+/* JVM_GetMethodIxByteCodeLength */
+
+jint JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cls, jint method_index)
+{
+       log_println("JVM_GetMethodIxByteCodeLength: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetMethodIxExceptionTableEntry */
+
+void JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cls, jint method_index, jint entry_index, JVM_ExceptionTableEntryType *entry)
+{
+       log_println("JVM_GetMethodIxExceptionTableEntry: IMPLEMENT ME!");
+}
+
+
+/* JVM_GetMethodIxExceptionTableLength */
+
+jint JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_index)
+{
+       log_println("JVM_GetMethodIxExceptionTableLength: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetMethodIxModifiers */
+
+jint JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index)
+{
+       log_println("JVM_GetMethodIxModifiers: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetFieldIxModifiers */
+
+jint JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)
+{
+       log_println("JVM_GetFieldIxModifiers: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetMethodIxLocalsCount */
+
+jint JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index)
+{
+       log_println("JVM_GetMethodIxLocalsCount: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetMethodIxArgsSize */
+
+jint JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index)
+{
+       log_println("JVM_GetMethodIxArgsSize: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetMethodIxMaxStack */
+
+jint JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index)
+{
+       log_println("JVM_GetMethodIxMaxStack: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_IsConstructorIx */
+
+jboolean JVM_IsConstructorIx(JNIEnv *env, jclass cls, int method_index)
+{
+       log_println("JVM_IsConstructorIx: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetMethodIxNameUTF */
+
+const char *JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index)
+{
+       log_println("JVM_GetMethodIxNameUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetMethodIxSignatureUTF */
+
+const char *JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index)
+{
+       log_println("JVM_GetMethodIxSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetCPFieldNameUTF */
+
+const char *JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+{
+       log_println("JVM_GetCPFieldNameUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetCPMethodNameUTF */
+
+const char *JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+{
+       log_println("JVM_GetCPMethodNameUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetCPMethodSignatureUTF */
+
+const char *JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
+{
+       log_println("JVM_GetCPMethodSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetCPFieldSignatureUTF */
+
+const char *JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
+{
+       log_println("JVM_GetCPFieldSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetCPClassNameUTF */
+
+const char *JVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+{
+       log_println("JVM_GetCPClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetCPFieldClassNameUTF */
+
+const char *JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+{
+       log_println("JVM_GetCPFieldClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetCPMethodClassNameUTF */
+
+const char *JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+{
+       log_println("JVM_GetCPMethodClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetCPFieldModifiers */
+
+jint JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)
+{
+       log_println("JVM_GetCPFieldModifiers: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetCPMethodModifiers */
+
+jint JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)
+{
+       log_println("JVM_GetCPMethodModifiers: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_ReleaseUTF */
+
+void JVM_ReleaseUTF(const char *utf)
+{
+       log_println("JVM_ReleaseUTF: IMPLEMENT ME!");
+}
+
+
+/* JVM_IsSameClassPackage */
+
+jboolean JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2)
+{
+       log_println("JVM_IsSameClassPackage: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_Open */
+
+/* Taken from: hotspot/src/share/vm/prims/jvm.h */
+
+/*
+ * JVM I/O error codes
+ */
+#define JVM_EEXIST       -100
+
+jint JVM_Open(const char *fname, jint flags, jint mode)
+{
+       int result;
+
+       TRACEJVMCALLS(("JVM_Open(fname=%s, flags=%d, mode=%d)", fname, flags, mode));
+
+       result = hpi_file->Open(fname, flags, mode);
+
+       if (result >= 0) {
+               return result;
+       }
+       else {
+               switch (errno) {
+               case EEXIST:
+                       return JVM_EEXIST;
+               default:
+                       return -1;
+               }
+       }
+}
+
+
+/* JVM_Close */
+
+jint JVM_Close(jint fd)
+{
+       TRACEJVMCALLS(("JVM_Close(fd=%d)", fd));
+
+       return hpi_file->Close(fd);
+}
+
+
+/* JVM_Read */
+
+jint JVM_Read(jint fd, char *buf, jint nbytes)
+{
+       TRACEJVMCALLS(("JVM_Read(fd=%d, buf=%p, nbytes=%d)", fd, buf, nbytes));
+
+       return (jint) hpi_file->Read(fd, buf, nbytes);
+}
+
+
+/* JVM_Write */
+
+jint JVM_Write(jint fd, char *buf, jint nbytes)
+{
+       TRACEJVMCALLS(("JVM_Write(fd=%d, buf=%s, nbytes=%d)", fd, buf, nbytes));
+
+       return (jint) hpi_file->Write(fd, buf, nbytes);
+}
+
+
+/* JVM_Available */
+
+jint JVM_Available(jint fd, jlong *pbytes)
+{
+       TRACEJVMCALLS(("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes));
+
+       return hpi_file->Available(fd, pbytes);
+}
+
+
+/* JVM_Lseek */
+
+jlong JVM_Lseek(jint fd, jlong offset, jint whence)
+{
+       TRACEJVMCALLS(("JVM_Lseek(fd=%d, offset=%ld, whence=%d)", fd, offset, whence));
+
+       return hpi_file->Seek(fd, (off_t) offset, whence);
+}
+
+
+/* JVM_SetLength */
+
+jint JVM_SetLength(jint fd, jlong length)
+{
+       TRACEJVMCALLS(("JVM_SetLength(fd=%d, length=%ld)", length));
+
+       return hpi_file->SetLength(fd, length);
+}
+
+
+/* JVM_Sync */
+
+jint JVM_Sync(jint fd)
+{
+       TRACEJVMCALLS(("JVM_Sync(fd=%d)", fd));
+
+       return hpi_file->Sync(fd);
+}
+
+
+/* JVM_StartThread */
+
+void JVM_StartThread(JNIEnv* env, jobject jthread)
+{
+       TRACEJVMCALLS(("JVM_StartThread(env=%p, jthread=%p)", env, jthread));
+
+       threads_thread_start((java_handle_t *) jthread);
+}
+
+
+/* JVM_StopThread */
+
+void JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)
+{
+       log_println("JVM_StopThread: Deprecated.  Not implemented.");
+}
+
+
+/* JVM_IsThreadAlive */
+
+jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread)
+{
+       java_handle_t *h;
+       threadobject  *t;
+       bool           result;
+
+       TRACEJVMCALLS(("JVM_IsThreadAlive(env=%p, jthread=%p)", env, 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. */
+
+       if (t == NULL)
+               return 0;
+
+       result = threads_thread_is_alive(t);
+
+       return result;
+}
+
+
+/* JVM_SuspendThread */
+
+void JVM_SuspendThread(JNIEnv* env, jobject jthread)
+{
+       log_println("JVM_SuspendThread: Deprecated.  Not implemented.");
+}
+
+
+/* JVM_ResumeThread */
+
+void JVM_ResumeThread(JNIEnv* env, jobject jthread)
+{
+       log_println("JVM_ResumeThread: Deprecated.  Not implemented.");
+}
+
+
+/* JVM_SetThreadPriority */
+
+void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio)
+{
+       java_handle_t *h;
+       threadobject  *t;
+
+       TRACEJVMCALLS(("JVM_SetThreadPriority(env=%p, jthread=%p, prio=%d)", env, jthread, prio));
+
+       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. */
+
+       if (t == NULL)
+               return;
+
+       threads_set_thread_priority(t->tid, prio);
+}
+
+
+/* JVM_Yield */
+
+void JVM_Yield(JNIEnv *env, jclass threadClass)
+{
+       TRACEJVMCALLS(("JVM_Yield(env=%p, threadClass=%p)", env, threadClass));
+
+       threads_yield();
+}
+
+
+/* JVM_Sleep */
+
+void JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis)
+{
+       TRACEJVMCALLS(("JVM_Sleep(env=%p, threadClass=%p, millis=%ld)", env, threadClass, millis));
+
+       threads_sleep(millis, 0);
+}
+
+
+/* JVM_CurrentThread */
+
+jobject JVM_CurrentThread(JNIEnv* env, jclass threadClass)
+{
+       java_object_t *o;
+
+       TRACEJVMCALLSVERBOSE(("JVM_CurrentThread(env=%p, threadClass=%p)", env, threadClass));
+
+       o = thread_get_current_object();
+
+       return (jobject) o;
+}
+
+
+/* JVM_CountStackFrames */
+
+jint JVM_CountStackFrames(JNIEnv* env, jobject jthread)
+{
+       log_println("JVM_CountStackFrames: Deprecated.  Not implemented.");
+
+       return 0;
+}
+
+
+/* JVM_Interrupt */
+
+void JVM_Interrupt(JNIEnv* env, jobject jthread)
+{
+       java_handle_t *h;
+       threadobject  *t;
+
+       TRACEJVMCALLS(("JVM_Interrupt(env=%p, jthread=%p)", env, jthread));
+
+       h = (java_handle_t *) jthread;
+       t = thread_get_thread(h);
+
+       if (t == NULL)
+               return;
+
+       threads_thread_interrupt(t);
+}
+
+
+/* JVM_IsInterrupted */
+
+jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted)
+{
+       java_handle_t *h;
+       threadobject  *t;
+       jboolean       interrupted;
+
+       TRACEJVMCALLS(("JVM_IsInterrupted(env=%p, jthread=%p, clear_interrupted=%d)", env, jthread, clear_interrupted));
+
+       h = (java_handle_t *) jthread;
+       t = thread_get_thread(h);
+
+       interrupted = thread_is_interrupted(t);
+
+       if (interrupted && clear_interrupted)
+               thread_set_interrupted(t, false);
+
+       return interrupted;
+}
+
+
+/* JVM_HoldsLock */
+
+jboolean JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj)
+{
+       java_handle_t *h;
+       bool           result;
+
+       TRACEJVMCALLS(("JVM_HoldsLock(env=%p, threadClass=%p, obj=%p)", env, threadClass, obj));
+
+       h = (java_handle_t *) obj;
+
+       if (h == NULL) {
+               exceptions_throw_nullpointerexception();
+               return JNI_FALSE;
+       }
+
+       result = lock_is_held_by_current_thread(h);
+
+       return result;
+}
+
+
+/* JVM_DumpAllStacks */
+
+void JVM_DumpAllStacks(JNIEnv* env, jclass unused)
+{
+       log_println("JVM_DumpAllStacks: IMPLEMENT ME!");
+}
+
+
+/* JVM_CurrentLoadedClass */
+
+jclass JVM_CurrentLoadedClass(JNIEnv *env)
+{
+       log_println("JVM_CurrentLoadedClass: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_CurrentClassLoader */
+
+jobject JVM_CurrentClassLoader(JNIEnv *env)
+{
+    /* XXX if a method in a class in a trusted loader is in a
+          doPrivileged, return NULL */
+
+       log_println("JVM_CurrentClassLoader: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetClassContext */
+
+jobjectArray JVM_GetClassContext(JNIEnv *env)
+{
+       TRACEJVMCALLS(("JVM_GetClassContext(env=%p)", env));
+
+       return (jobjectArray) stacktrace_getClassContext();
+}
+
+
+/* JVM_ClassDepth */
+
+jint JVM_ClassDepth(JNIEnv *env, jstring name)
+{
+       log_println("JVM_ClassDepth: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_ClassLoaderDepth */
+
+jint JVM_ClassLoaderDepth(JNIEnv *env)
+{
+       log_println("JVM_ClassLoaderDepth: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetSystemPackage */
+
+jstring JVM_GetSystemPackage(JNIEnv *env, jstring name)
+{
+       java_handle_t *s;
+       utf *u;
+       utf *result;
+
+       TRACEJVMCALLS(("JVM_GetSystemPackage(env=%p, name=%p)", env, name));
+
+/*     s = Package::find(name); */
+       u = javastring_toutf((java_handle_t *) name, false);
+
+       result = Package::find(u);
+
+       if (result != NULL)
+               s = javastring_new(result);
+       else
+               s = NULL;
+
+       return (jstring) s;
+}
+
+
+/* JVM_GetSystemPackages */
+
+jobjectArray JVM_GetSystemPackages(JNIEnv *env)
+{
+       log_println("JVM_GetSystemPackages: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_AllocateNewObject */
+
+jobject JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, jclass initClass)
+{
+       log_println("JVM_AllocateNewObject: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_AllocateNewArray */
+
+jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint length)
+{
+       log_println("JVM_AllocateNewArray: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_LatestUserDefinedLoader */
+
+jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
+{
+       classloader_t *cl;
+
+       TRACEJVMCALLS(("JVM_LatestUserDefinedLoader(env=%p)", env));
+
+       cl = stacktrace_first_nonnull_classloader();
+
+       return (jobject) cl;
+}
+
+
+/* JVM_LoadClass0 */
+
+jclass JVM_LoadClass0(JNIEnv *env, jobject receiver, jclass currClass, jstring currClassName)
+{
+       log_println("JVM_LoadClass0: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetArrayLength */
+
+jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
+{
+       java_handle_t *a;
+
+       TRACEJVMCALLS(("JVM_GetArrayLength(arr=%p)", arr));
+
+       a = (java_handle_t *) arr;
+
+       return array_length_get(a);
+}
+
+
+/* JVM_GetArrayElement */
+
+jobject JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index)
+{
+       java_handle_t *a;
+       java_handle_t *o;
+
+       TRACEJVMCALLS(("JVM_GetArrayElement(env=%p, arr=%p, index=%d)", env, arr, index));
+
+       a = (java_handle_t *) arr;
+
+/*     if (!class_is_array(a->objheader.vftbl->class)) { */
+/*             exceptions_throw_illegalargumentexception(); */
+/*             return NULL; */
+/*     } */
+
+       o = array_element_get(a, index);
+
+       return (jobject) o;
+}
+
+
+/* JVM_GetPrimitiveArrayElement */
+
+jvalue JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode)
+{
+       jvalue jv;
+
+       log_println("JVM_GetPrimitiveArrayElement: IMPLEMENT ME!");
+
+       jv.l = NULL;
+
+       return jv;
+}
+
+
+/* JVM_SetArrayElement */
+
+void JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val)
+{
+       java_handle_t *a;
+       java_handle_t *value;
+
+       TRACEJVMCALLS(("JVM_SetArrayElement(env=%p, arr=%p, index=%d, val=%p)", env, arr, index, val));
+
+       a     = (java_handle_t *) arr;
+       value = (java_handle_t *) val;
+
+       array_element_set(a, index, value);
+}
+
+
+/* JVM_SetPrimitiveArrayElement */
+
+void JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, unsigned char vCode)
+{
+       log_println("JVM_SetPrimitiveArrayElement: IMPLEMENT ME!");
+}
+
+
+/* JVM_NewArray */
+
+jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
+{
+       classinfo                 *c;
+       classinfo                 *pc;
+       java_handle_t             *a;
+       java_handle_objectarray_t *oa;
+
+       TRACEJVMCALLS(("JVM_NewArray(env=%p, eltClass=%p, length=%d)", env, eltClass, length));
+
+       if (eltClass == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* NegativeArraySizeException is checked in builtin_newarray. */
+
+       c = LLNI_classinfo_unwrap(eltClass);
+
+       /* Create primitive or object array. */
+
+       if (class_is_primitive(c)) {
+               pc = Primitive::get_arrayclass_by_name(c->name);
+
+               /* void arrays are not allowed. */
+
+               if (pc == NULL) {
+                       exceptions_throw_illegalargumentexception();
+                       return NULL;
+               }
+
+               a = builtin_newarray(length, pc);
+
+               return (jobject) a;
+       }
+       else {
+               oa = builtin_anewarray(length, c);
+
+               return (jobject) oa;
+       }
+}
+
+
+/* JVM_NewMultiArray */
+
+jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
+{
+       classinfo                 *c;
+       java_handle_intarray_t    *ia;
+       int32_t                    length;
+       long                      *dims;
+       int32_t                    value;
+       int32_t                    i;
+       classinfo                 *ac;
+       java_handle_objectarray_t *a;
+
+       TRACEJVMCALLS(("JVM_NewMultiArray(env=%p, eltClass=%p, dim=%p)", env, eltClass, dim));
+
+       if (eltClass == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* NegativeArraySizeException is checked in builtin_newarray. */
+
+       c = LLNI_classinfo_unwrap(eltClass);
+
+       ia = (java_handle_intarray_t *) dim;
+
+       length = array_length_get((java_handle_t *) ia);
+
+       /* We check here for exceptions thrown in array_length_get,
+          otherwise these exceptions get overwritten by the following
+          IllegalArgumentException. */
+
+       if (length < 0)
+               return NULL;
+
+       if ((length <= 0) || (length > /* MAX_DIM */ 255)) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       /* XXX This is just a quick hack to get it working. */
+
+       dims = MNEW(long, length);
+
+       for (i = 0; i < length; i++) {
+               value = LLNI_array_direct(ia, i);
+               dims[i] = (long) value;
+       }
+
+       /* Create an array-class if necessary. */
+
+       if (class_is_primitive(c))
+               ac = Primitive::get_arrayclass_by_name(c->name);
+       else
+               ac = class_array_of(c, true);
+
+       if (ac == NULL)
+               return NULL;
+
+       a = builtin_multianewarray(length, (java_handle_t *) ac, dims);
+
+       return (jobject) a;
+}
+
+
+/* JVM_InitializeSocketLibrary */
+
+jint JVM_InitializeSocketLibrary()
+{
+       TRACEJVMCALLS(("JVM_InitializeSocketLibrary()"));
+
+       return hpi_initialize_socket_library();
+}
+
+
+/* JVM_Socket */
+
+jint JVM_Socket(jint domain, jint type, jint protocol)
+{
+       TRACEJVMCALLS(("JVM_Socket(domain=%d, type=%d, protocol=%d)", domain, type, protocol));
+
+       return os::socket(domain, type, protocol);
+}
+
+
+/* JVM_SocketClose */
+
+jint JVM_SocketClose(jint fd)
+{
+       TRACEJVMCALLS(("JVM_SocketClose(fd=%d)", fd));
+
+       return os::close(fd);
+}
+
+
+/* JVM_SocketShutdown */
+
+jint JVM_SocketShutdown(jint fd, jint howto)
+{
+       TRACEJVMCALLS(("JVM_SocketShutdown(fd=%d, howto=%d)", fd, howto));
+
+       return os::shutdown(fd, howto);
+}
+
+
+/* JVM_Recv */
+
+jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
+{
+       log_println("JVM_Recv: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_Send */
+
+jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
+{
+       log_println("JVM_Send: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_Timeout */
+
+jint JVM_Timeout(int fd, long timeout)
+{
+       log_println("JVM_Timeout: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_Listen */
+
+jint JVM_Listen(jint fd, jint count)
+{
+       TRACEJVMCALLS(("JVM_Listen(fd=%d, count=%d)", fd, count));
+
+       return os::listen(fd, count);
+}
+
+
+/* JVM_Connect */
+
+jint JVM_Connect(jint fd, struct sockaddr *him, jint len)
+{
+       TRACEJVMCALLS(("JVM_Connect(fd=%d, him=%p, len=%d)", fd, him, len));
+
+       return os::connect(fd, him, len);
+}
+
+
+/* JVM_Bind */
+
+jint JVM_Bind(jint fd, struct sockaddr *him, jint len)
+{
+       log_println("JVM_Bind: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_Accept */
+
+jint JVM_Accept(jint fd, struct sockaddr *him, jint *len)
+{
+       TRACEJVMCALLS(("JVM_Accept(fd=%d, him=%p, len=%p)", fd, him, len));
+
+       return os::accept(fd, him, (socklen_t *) len);
+}
+
+
+/* JVM_RecvFrom */
+
+jint JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen)
+{
+       log_println("JVM_RecvFrom: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetSockName */
+
+jint JVM_GetSockName(jint fd, struct sockaddr *him, int *len)
+{
+       TRACEJVMCALLS(("JVM_GetSockName(fd=%d, him=%p, len=%p)", fd, him, len));
+
+       return os::getsockname(fd, him, (socklen_t *) len);
+}
+
+
+/* JVM_SendTo */
+
+jint JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int tolen)
+{
+       log_println("JVM_SendTo: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_SocketAvailable */
+
+jint JVM_SocketAvailable(jint fd, jint *pbytes)
+{
+#if defined(FIONREAD)
+       int bytes;
+       int result;
+
+       TRACEJVMCALLS(("JVM_SocketAvailable(fd=%d, pbytes=%p)", fd, pbytes));
+
+       *pbytes = 0;
+
+       result = ioctl(fd, FIONREAD, &bytes);
+
+       if (result < 0)
+               return 0;
+
+       *pbytes = bytes;
+
+       return 1;
+#else
+# error FIONREAD not defined
+#endif
+}
+
+
+/* JVM_GetSockOpt */
+
+jint JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen)
+{
+       TRACEJVMCALLS(("JVM_GetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%p)", fd, level, optname, optval, optlen));
+
+       return os::getsockopt(fd, level, optname, optval, (socklen_t *) optlen);
+}
+
+
+/* JVM_SetSockOpt */
+
+jint JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen)
+{
+       TRACEJVMCALLS(("JVM_SetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%d)", fd, level, optname, optval, optlen));
+
+       return os::setsockopt(fd, level, optname, optval, optlen);
+}
+
+
+/* JVM_GetHostName */
+
+int JVM_GetHostName(char *name, int namelen)
+{
+       int result;
+
+       TRACEJVMCALLSENTER(("JVM_GetHostName(name=%s, namelen=%d)", name, namelen));
+
+       result = os::gethostname(name, namelen);
+
+       TRACEJVMCALLSEXIT(("->%d (name=%s)", result, name));
+
+       return result;
+}
+
+
+/* JVM_GetHostByAddr */
+
+struct hostent *JVM_GetHostByAddr(const char* name, int len, int type)
+{
+       log_println("JVM_GetHostByAddr: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetHostByName */
+
+struct hostent *JVM_GetHostByName(char* name)
+{
+       log_println("JVM_GetHostByName: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetProtoByName */
+
+struct protoent *JVM_GetProtoByName(char* name)
+{
+       log_println("JVM_GetProtoByName: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_LoadLibrary */
+
+void *JVM_LoadLibrary(const char *name)
+{
+       utf*  u;
+       void* handle;
+
+       TRACEJVMCALLSENTER(("JVM_LoadLibrary(name=%s)", name));
+
+       u = utf_new_char(name);
+
+       handle = native_library_open(u);
+
+       TRACEJVMCALLSEXIT(("->%p", handle));
+
+       return handle;
+}
+
+
+/* JVM_UnloadLibrary */
+
+void JVM_UnloadLibrary(void* handle)
+{
+       TRACEJVMCALLS(("JVM_UnloadLibrary(handle=%p)", handle));
+
+       native_library_close(handle);
+}
+
+
+/* JVM_FindLibraryEntry */
+
+void *JVM_FindLibraryEntry(void *handle, const char *name)
+{
+       void* symbol;
+
+       TRACEJVMCALLSENTER(("JVM_FindLibraryEntry(handle=%p, name=%s)", handle, name));
+
+       symbol = hpi_library->FindLibraryEntry(handle, name);
+
+       TRACEJVMCALLSEXIT(("->%p", symbol));
+
+       return symbol;
+}
+
+
+/* JVM_IsNaN */
+
+jboolean JVM_IsNaN(jdouble a)
+{
+       log_println("JVM_IsNaN: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_IsSupportedJNIVersion */
+
+jboolean JVM_IsSupportedJNIVersion(jint version)
+{
+       TRACEJVMCALLS(("JVM_IsSupportedJNIVersion(version=%d)", version));
+
+       return jni_version_check(version);
+}
+
+
+/* JVM_InternString */
+
+jstring JVM_InternString(JNIEnv *env, jstring str)
+{
+       TRACEJVMCALLS(("JVM_InternString(env=%p, str=%p)", env, str));
+
+       return (jstring) javastring_intern((java_handle_t *) str);
+}
+
+
+/* JVM_RawMonitorCreate */
+
+JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void)
+{
+       java_object_t *o;
+
+       TRACEJVMCALLS(("JVM_RawMonitorCreate()"));
+
+       o = NEW(java_object_t);
+
+       lock_init_object_lock(o);
+
+       return o;
+}
+
+
+/* JVM_RawMonitorDestroy */
+
+JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon)
+{
+       TRACEJVMCALLS(("JVM_RawMonitorDestroy(mon=%p)", mon));
+
+       FREE(mon, java_object_t);
+}
+
+
+/* JVM_RawMonitorEnter */
+
+JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon)
+{
+       TRACEJVMCALLS(("JVM_RawMonitorEnter(mon=%p)", mon));
+
+       (void) lock_monitor_enter((java_object_t *) mon);
+
+       return 0;
+}
+
+
+/* JVM_RawMonitorExit */
+
+JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon)
+{
+       TRACEJVMCALLS(("JVM_RawMonitorExit(mon=%p)", mon));
+
+       (void) lock_monitor_exit((java_object_t *) mon);
+}
+
+
+/* JVM_SetPrimitiveFieldValues */
+
+void JVM_SetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, jlongArray fieldIDs, jcharArray typecodes, jbyteArray data)
+{
+       log_println("JVM_SetPrimitiveFieldValues: IMPLEMENT ME!");
+}
+
+
+/* JVM_GetPrimitiveFieldValues */
+
+void JVM_GetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, jlongArray fieldIDs, jcharArray typecodes, jbyteArray data)
+{
+       log_println("JVM_GetPrimitiveFieldValues: IMPLEMENT ME!");
+}
+
+
+/* JVM_AccessVMBooleanFlag */
+
+jboolean JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get)
+{
+       log_println("JVM_AccessVMBooleanFlag: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_AccessVMIntFlag */
+
+jboolean JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get)
+{
+       log_println("JVM_AccessVMIntFlag: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_VMBreakPoint */
+
+void JVM_VMBreakPoint(JNIEnv *env, jobject obj)
+{
+       log_println("JVM_VMBreakPoint: IMPLEMENT ME!");
+}
+
+
+/* JVM_GetClassFields */
+
+jobjectArray JVM_GetClassFields(JNIEnv *env, jclass cls, jint which)
+{
+       log_println("JVM_GetClassFields: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetClassMethods */
+
+jobjectArray JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which)
+{
+       log_println("JVM_GetClassMethods: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetClassConstructors */
+
+jobjectArray JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which)
+{
+       log_println("JVM_GetClassConstructors: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetClassField */
+
+jobject JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which)
+{
+       log_println("JVM_GetClassField: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetClassMethod */
+
+jobject JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types, jint which)
+{
+       log_println("JVM_GetClassMethod: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetClassConstructor */
+
+jobject JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jint which)
+{
+       log_println("JVM_GetClassConstructor: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_NewInstance */
+
+jobject JVM_NewInstance(JNIEnv *env, jclass cls)
+{
+       log_println("JVM_NewInstance: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetField */
+
+jobject JVM_GetField(JNIEnv *env, jobject field, jobject obj)
+{
+       log_println("JVM_GetField: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetPrimitiveField */
+
+jvalue JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj, unsigned char wCode)
+{
+       jvalue jv;
+
+       log_println("JVM_GetPrimitiveField: IMPLEMENT ME!");
+
+       jv.l = NULL;
+
+       return jv;
+}
+
+
+/* JVM_SetField */
+
+void JVM_SetField(JNIEnv *env, jobject field, jobject obj, jobject val)
+{
+       log_println("JVM_SetField: IMPLEMENT ME!");
+}
+
+
+/* JVM_SetPrimitiveField */
+
+void JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v, unsigned char vCode)
+{
+       log_println("JVM_SetPrimitiveField: IMPLEMENT ME!");
+}
+
+
+/* JVM_InvokeMethod */
+
+jobject JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)
+{
+       TRACEJVMCALLS(("JVM_InvokeMethod(env=%p, method=%p, obj=%p, args0=%p)", env, method, obj, args0));
+
+       java_lang_reflect_Method jlrm(method);
+       
+       java_handle_t* result = jlrm.invoke((java_handle_t*) obj, (java_handle_objectarray_t*) args0);
+
+       return (jobject) result;
+}
+
+
+/* JVM_NewInstanceFromConstructor */
+
+jobject JVM_NewInstanceFromConstructor(JNIEnv *env, jobject con, jobjectArray args0)
+{
+       TRACEJVMCALLS(("JVM_NewInstanceFromConstructor(env=%p, c=%p, args0=%p)", env, con, args0));
+
+       java_lang_reflect_Constructor jlrc(con);
+       java_handle_t* o = jlrc.new_instance((java_handle_objectarray_t*) args0);
+
+       return (jobject) o;
+}
+
+
+/* JVM_SupportsCX8 */
+
+jboolean JVM_SupportsCX8()
+{
+       TRACEJVMCALLS(("JVM_SupportsCX8()"));
+
+       /* IMPLEMENT ME */
+
+       return 0;
+}
+
+
+/* JVM_CX8Field */
+
+jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlong newVal)
+{
+       log_println("JVM_CX8Field: IMPLEMENT ME!");
+
+       return 0;
+}
+
+
+/* JVM_GetAllThreads */
+
+jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
+{
+       log_println("JVM_GetAllThreads: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_DumpThreads */
+
+jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)
+{
+       log_println("JVM_DumpThreads: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetManagement */
+
+void *JVM_GetManagement(jint version)
+{
+       TRACEJVMCALLS(("JVM_GetManagement(version=%d)", version));
+
+       /* TODO We current don't support the management interface. */
+
+       return NULL;
+}
+
+
+/* JVM_InitAgentProperties */
+
+jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties)
+{
+       log_println("JVM_InitAgentProperties: IMPLEMENT ME!");
+
+       return NULL;
+}
+
+
+/* JVM_GetEnclosingMethodInfo */
+
+jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
+{
+       classinfo                 *c;
+       methodinfo                *m;
+       java_handle_objectarray_t *oa;
+
+       TRACEJVMCALLS(("JVM_GetEnclosingMethodInfo(env=%p, ofClass=%p)", env, ofClass));
+
+       c = LLNI_classinfo_unwrap(ofClass);
+
+       if ((c == NULL) || class_is_primitive(c))
+               return NULL;
+
+       m = class_get_enclosingmethod_raw(c);
+
+       if (m == NULL)
+               return NULL;
+
+       oa = builtin_anewarray(3, class_java_lang_Object);
+
+       if (oa == NULL)
+               return NULL;
+
+       array_objectarray_element_set(oa, 0, (java_handle_t *) LLNI_classinfo_wrap(m->clazz));
+       array_objectarray_element_set(oa, 1, javastring_new(m->name));
+       array_objectarray_element_set(oa, 2, javastring_new(m->descriptor));
+
+       return (jobjectArray) oa;
+}
+
+
+/* JVM_GetThreadStateValues */
+
+jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
+{
+       java_handle_intarray_t *ia;
+
+       TRACEJVMCALLS(("JVM_GetThreadStateValues(env=%p, javaThreadState=%d)",
+                                 env, javaThreadState));
+
+       /* If new thread states are added in future JDK and VM versions,
+          this should check if the JDK version is compatible with thread
+          states supported by the VM.  Return NULL if not compatible.
+       
+          This function must map the VM java_lang_Thread::ThreadStatus
+          to the Java thread state that the JDK supports. */
+
+       switch (javaThreadState) {
+    case THREAD_STATE_NEW:
+               ia = builtin_newarray_int(1);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_NEW);
+               break; 
+
+    case THREAD_STATE_RUNNABLE:
+               ia = builtin_newarray_int(1);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_RUNNABLE);
+               break; 
+
+    case THREAD_STATE_BLOCKED:
+               ia = builtin_newarray_int(1);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_BLOCKED);
+               break; 
+
+    case THREAD_STATE_WAITING:
+               ia = builtin_newarray_int(2);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_WAITING);
+               /* XXX Implement parked stuff. */
+/*             array_intarray_element_set(ia, 1, PARKED); */
+               break; 
+
+    case THREAD_STATE_TIMED_WAITING:
+               ia = builtin_newarray_int(3);
+
+               if (ia == NULL)
+                       return NULL;
+
+               /* 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); */
+               break; 
+
+    case THREAD_STATE_TERMINATED:
+               ia = builtin_newarray_int(1);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_TERMINATED);
+               break; 
+
+    default:
+               /* Unknown state - probably incompatible JDK version */
+               return NULL;
+       }
+
+       return (jintArray) ia;
+}
+
+
+/* JVM_GetThreadStateNames */
+
+jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values)
+{
+       java_handle_intarray_t    *ia;
+       java_handle_objectarray_t *oa;
+       java_object_t             *s;
+
+       TRACEJVMCALLS(("JVM_GetThreadStateNames(env=%p, javaThreadState=%d, values=%p)",
+                                 env, javaThreadState, values));
+
+       ia = (java_handle_intarray_t *) values;
+
+       /* If new thread states are added in future JDK and VM versions,
+          this should check if the JDK version is compatible with thread
+          states supported by the VM.  Return NULL if not compatible.
+       
+          This function must map the VM java_lang_Thread::ThreadStatus
+          to the Java thread state that the JDK supports. */
+
+       if (values == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       switch (javaThreadState) {
+    case THREAD_STATE_NEW:
+               assert(ia->header.size == 1 && ia->data[0] == THREAD_STATE_NEW);
+
+               oa = builtin_anewarray(1, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("NEW"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+               break; 
+
+    case THREAD_STATE_RUNNABLE:
+               oa = builtin_anewarray(1, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("RUNNABLE"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+               break; 
+
+    case THREAD_STATE_BLOCKED:
+               oa = builtin_anewarray(1, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("BLOCKED"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+               break; 
+
+    case THREAD_STATE_WAITING:
+               oa = builtin_anewarray(2, class_java_lang_String);
+
+               if (oa == NULL)
+                       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); */
+               break; 
+
+    case THREAD_STATE_TIMED_WAITING:
+               oa = builtin_anewarray(3, 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); */
+               break; 
+
+    case THREAD_STATE_TERMINATED:
+               oa = builtin_anewarray(1, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("TERMINATED"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+               break; 
+
+       default:
+               /* Unknown state - probably incompatible JDK version */
+               return NULL;
+       }
+
+       return (jobjectArray) oa;
+}
+
+
+/* JVM_GetVersionInfo */
+
+void JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size)
+{
+       log_println("JVM_GetVersionInfo: IMPLEMENT ME!");
+}
+
+
+/* OS: JVM_RegisterSignal */
+
+void *JVM_RegisterSignal(jint sig, void *handler)
+{
+       functionptr newHandler;
+
+       TRACEJVMCALLS(("JVM_RegisterSignal(sig=%d, handler=%p)", sig, handler));
+
+       if (handler == (void *) 2)
+               newHandler = (functionptr) signal_thread_handler;
+       else
+               newHandler = (functionptr) (uintptr_t) handler;
+
+       switch (sig) {
+    case SIGILL:
+    case SIGFPE:
+    case SIGUSR1:
+    case SIGSEGV:
+               /* These signals are already used by the VM. */
+               return (void *) -1;
+
+    case SIGQUIT:
+               /* This signal is used by the VM to dump thread stacks unless
+                  ReduceSignalUsage is set, in which case the user is allowed
+                  to set his own _native_ handler for this signal; thus, in
+                  either case, we do not allow JVM_RegisterSignal to change
+                  the handler. */
+               return (void *) -1;
+
+       case SIGHUP:
+       case SIGINT:
+       case SIGTERM:
+               break;
+       }
+
+       signal_register_signal(sig, newHandler, SA_RESTART | SA_SIGINFO);
+
+       /* XXX Should return old handler. */
+
+       return (void *) 2;
+}
+
+
+/* OS: JVM_RaiseSignal */
+
+jboolean JVM_RaiseSignal(jint sig)
+{
+       log_println("JVM_RaiseSignal: IMPLEMENT ME! sig=%s", sig);
+
+       return false;
+}
+
+
+/* OS: JVM_FindSignal */
+
+jint JVM_FindSignal(const char *name)
+{
+       TRACEJVMCALLS(("JVM_FindSignal(name=%s)", name));
+
+#if defined(__LINUX__)
+       if (strcmp(name, "HUP") == 0)
+               return SIGHUP;
+
+       if (strcmp(name, "INT") == 0)
+               return SIGINT;
+
+       if (strcmp(name, "TERM") == 0)
+               return SIGTERM;
+#elif defined(__SOLARIS__)
+       int signum;
+
+       if (os::str2sig(name, &signum) == -1)
+               return -1;
+
+       return signum;
+#else
+# error Not implemented for this OS.
+#endif
+
+       return -1;
+}
+
+} // extern "C"
+
+
+/*
+ * 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/native/vm/reflect.c b/src/native/vm/reflect.c
deleted file mode 100644 (file)
index 90b1729..0000000
+++ /dev/null
@@ -1,700 +0,0 @@
-/* src/native/vm/reflect.c - helper functions for java/lang/reflect
-
-   Copyright (C) 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 <stdint.h>
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-/* keep this order of the native includes */
-
-#include "native/include/java_lang_String.h"
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-# include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
-#endif
-#include "native/include/java_lang_ClassLoader.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_reflect_Constructor.h"
-#include "native/include/java_lang_reflect_Field.h"
-#include "native/include/java_lang_reflect_Method.h"
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# include "native/include/java_lang_reflect_VMConstructor.h"
-# include "native/include/java_lang_reflect_VMField.h"
-# include "native/include/java_lang_reflect_VMMethod.h"
-#endif
-
-#if defined(ENABLE_ANNOTATIONS) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# include "vm/vm.h"
-# include "native/include/sun_reflect_ConstantPool.h"
-#endif
-
-#include "native/vm/reflect.h"
-
-#include "vm/access.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/initialize.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/method.h"
-
-
-/* reflect_constructor_new *****************************************************
-
-   Allocates a new java.lang.reflect.Constructor object and
-   initializes the fields with the method passed.
-
-*******************************************************************************/
-
-java_lang_reflect_Constructor *reflect_constructor_new(methodinfo *m)
-{
-       java_handle_t                   *o;
-       java_lang_reflect_Constructor   *rc;
-       int32_t                          slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_reflect_VMConstructor *rvmc;
-#endif
-
-       /* Allocate a java.lang.reflect.Constructor object. */
-
-       o = builtin_new(class_java_lang_reflect_Constructor);
-
-       if (o == NULL)
-               return NULL;
-
-       /* Initialize instance fields. */
-
-       rc = (java_lang_reflect_Constructor *) o;
-
-       /* Calculate the slot. */
-
-       slot = m - m->clazz->methods;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Allocate a java.lang.reflect.VMConstructor object. */
-
-       o = builtin_new(class_java_lang_reflect_VMConstructor);
-
-       if (o == NULL)
-               return NULL;
-
-       rvmc = (java_lang_reflect_VMConstructor *) o;
-
-       /* Link the two Java objects. */
-
-       LLNI_field_set_ref(rc,   cons, rvmc);
-       LLNI_field_set_ref(rvmc, cons, rc);
-
-       /* Set Java object instance fields. */
-
-       LLNI_field_set_cls(rvmc, clazz,                m->clazz);
-       LLNI_field_set_val(rvmc, slot,                 slot);
-       LLNI_field_set_ref(rvmc, annotations,          method_get_annotations(m));
-       LLNI_field_set_ref(rvmc, parameterAnnotations, method_get_parameterannotations(m));
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       /* Set Java object instance fields. */
-
-       LLNI_field_set_cls(rc, clazz               , m->clazz);
-       LLNI_field_set_ref(rc, parameterTypes      , method_get_parametertypearray(m));
-       LLNI_field_set_ref(rc, exceptionTypes      , method_get_exceptionarray(m));
-       LLNI_field_set_val(rc, modifiers           , m->flags & ACC_CLASS_REFLECT_MASK);
-       LLNI_field_set_val(rc, slot                , slot);
-       LLNI_field_set_ref(rc, signature           , m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
-       LLNI_field_set_ref(rc, annotations         , method_get_annotations(m));
-       LLNI_field_set_ref(rc, parameterAnnotations, method_get_parameterannotations(m));
-
-#else
-# error unknown classpath configuration
-#endif
-
-       return rc;
-}
-
-
-/* reflect_field_new ***********************************************************
-
-   Allocates a new java.lang.reflect.Field object and initializes the
-   fields with the field passed.
-
-*******************************************************************************/
-
-java_lang_reflect_Field *reflect_field_new(fieldinfo *f)
-{
-       java_handle_t             *o;
-       java_lang_reflect_Field   *rf;
-       int32_t                    slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_reflect_VMField *rvmf;
-#endif
-
-       /* Allocate a java.lang.reflect.Field object. */
-
-       o = builtin_new(class_java_lang_reflect_Field);
-
-       if (o == NULL)
-               return NULL;
-
-       /* initialize instance fields */
-
-       rf = (java_lang_reflect_Field *) o;
-
-       /* Calculate the slot. */
-
-       slot = f - f->clazz->fields;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Allocate a java.lang.reflect.VMField object. */
-
-       o = builtin_new(class_java_lang_reflect_VMField);
-
-       if (o == NULL)
-               return NULL;
-
-       rvmf = (java_lang_reflect_VMField *) o;
-
-       /* Link the two Java objects. */
-
-       LLNI_field_set_ref(rf,   f, rvmf);
-       LLNI_field_set_ref(rvmf, f, rf);
-
-       /* Set the Java object fields. */
-
-       LLNI_field_set_cls(rvmf, clazz,       f->clazz);
-
-       /* The name needs to be interned */
-       /* XXX implement me better! */
-
-       LLNI_field_set_ref(rvmf, name,        (java_lang_String *) javastring_intern(javastring_new(f->name)));
-       LLNI_field_set_val(rvmf, slot,        slot);
-       LLNI_field_set_ref(rvmf, annotations, field_get_annotations(f));
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       /* Set the Java object fields. */
-
-       LLNI_field_set_cls(rf, clazz,       f->clazz);
-
-       /* The name needs to be interned */
-       /* XXX implement me better! */
-
-       LLNI_field_set_ref(rf, name,        (java_lang_String *) javastring_intern(javastring_new(f->name)));
-       LLNI_field_set_cls(rf, type,        (java_lang_Class *) field_get_type(f));
-       LLNI_field_set_val(rf, modifiers,   f->flags);
-       LLNI_field_set_val(rf, slot,        slot);
-       LLNI_field_set_ref(rf, signature,   f->signature ? (java_lang_String *) javastring_new(f->signature) : NULL);
-       LLNI_field_set_ref(rf, annotations, field_get_annotations(f));
-
-#else
-# error unknown classpath configuration
-#endif
-
-       return rf;
-}
-
-
-/* reflect_method_new **********************************************************
-
-   Allocates a new java.lang.reflect.Method object and initializes the
-   fields with the method passed.
-
-*******************************************************************************/
-
-java_lang_reflect_Method *reflect_method_new(methodinfo *m)
-{
-       java_handle_t              *o;
-       java_lang_reflect_Method   *rm;
-       int32_t                     slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_reflect_VMMethod *rvmm;
-#endif
-
-       /* Allocate a java.lang.reflect.Method object. */
-
-       o = builtin_new(class_java_lang_reflect_Method);
-
-       if (o == NULL)
-               return NULL;
-
-       /* initialize instance fields */
-
-       rm = (java_lang_reflect_Method *) o;
-
-       /* Calculate the slot. */
-
-       slot = m - m->clazz->methods;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Allocate a java.lang.reflect.VMMethod object. */
-
-       o = builtin_new(class_java_lang_reflect_VMMethod);
-
-       if (o == NULL)
-               return NULL;
-
-       rvmm = (java_lang_reflect_VMMethod *) o;
-
-       /* Link the two Java objects. */
-
-       LLNI_field_set_ref(rm,   m, rvmm);
-       LLNI_field_set_ref(rvmm, m, rm);
-
-       /* Set Java object instance fields. */
-
-       LLNI_field_set_cls(rvmm, clazz,                m->clazz);
-
-       /* The name needs to be interned */
-       /* XXX implement me better! */
-
-       LLNI_field_set_ref(rvmm, name,                 (java_lang_String *) javastring_intern(javastring_new(m->name)));
-       LLNI_field_set_val(rvmm, slot,                 slot);
-       LLNI_field_set_ref(rvmm, annotations,          method_get_annotations(m));
-       LLNI_field_set_ref(rvmm, parameterAnnotations, method_get_parameterannotations(m));
-       LLNI_field_set_ref(rvmm, annotationDefault,    method_get_annotationdefault(m));
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       LLNI_field_set_cls(rm, clazz,                m->clazz);
-
-       /* The name needs to be interned */
-       /* XXX implement me better! */
-
-       LLNI_field_set_ref(rm, name,                 (java_lang_String *) javastring_intern(javastring_new(m->name)));
-       LLNI_field_set_ref(rm, parameterTypes,       method_get_parametertypearray(m));
-       LLNI_field_set_cls(rm, returnType,           (java_lang_Class *) method_returntype_get(m));
-       LLNI_field_set_ref(rm, exceptionTypes,       method_get_exceptionarray(m));
-       LLNI_field_set_val(rm, modifiers,            m->flags & ACC_CLASS_REFLECT_MASK);
-       LLNI_field_set_val(rm, slot,                 slot);
-       LLNI_field_set_ref(rm, signature,            m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
-       LLNI_field_set_ref(rm, annotations,          method_get_annotations(m));
-       LLNI_field_set_ref(rm, parameterAnnotations, method_get_parameterannotations(m));
-       LLNI_field_set_ref(rm, annotationDefault,    method_get_annotationdefault(m));
-
-#else
-# error unknown classpath configuration
-#endif
-
-       return rm;
-}
-
-
-/* reflect_invoke **************************************************************
-
-   Invoke a method on the given object with the given arguments.
-
-   For instance methods OBJ must be != NULL and the method is looked up
-   in the vftbl of the object.
-
-   For static methods, OBJ is ignored.
-
-*******************************************************************************/
-
-static java_handle_t *reflect_invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params)
-{
-       methodinfo    *resm;
-       java_handle_t *ro;
-       int            argcount;
-       int            paramcount;
-
-       /* Sanity check. */
-
-       assert(m != NULL);
-
-       argcount = m->parseddesc->paramcount;
-       paramcount = argcount;
-
-       /* If method is non-static, remove the `this' pointer. */
-
-       if (!(m->flags & ACC_STATIC))
-               paramcount--;
-
-       /* For instance methods the object has to be an instance of the
-          class the method belongs to. For static methods the obj
-          parameter is ignored. */
-
-       if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->clazz))) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* check if we got the right number of arguments */
-
-       if (((params == NULL) && (paramcount != 0)) ||
-               (params && (LLNI_array_size(params) != paramcount))) 
-       {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-
-       /* for instance methods we need an object */
-
-       if (!(m->flags & ACC_STATIC) && (o == NULL)) {
-               /* XXX not sure if that is the correct exception */
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* for static methods, zero object to make subsequent code simpler */
-       if (m->flags & ACC_STATIC)
-               o = NULL;
-
-       if (o != NULL) {
-               /* for instance methods we must do a vftbl lookup */
-               resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
-       }
-       else {
-               /* for static methods, just for convenience */
-               resm = m;
-       }
-
-       ro = vm_call_method_objectarray(resm, o, params);
-
-       return ro;
-}
-
-
-/* reflect_constructor_newinstance ********************************************
-
-   Creates an Java object instance of the given constructor.
-
-   ARGUMENTS:
-      m .......... methodinfo of the constructor
-      args ....... constructor arguments
-      override ... override security checks
-
-   RETURN:
-      constructed Java object
-
-*******************************************************************************/
-
-java_handle_t *reflect_constructor_newinstance(methodinfo *m, java_handle_objectarray_t *args, bool override)
-{
-       java_handle_t *o;
-
-       /* Should we bypass security the checks (AccessibleObject)? */
-
-       if (override == false) {
-               /* This method is always called like this:
-                      [0] java.lang.reflect.Constructor.constructNative (Native Method)
-                      [1] java.lang.reflect.Constructor.newInstance
-                      [2] <caller>
-               */
-
-               if (!access_check_method(m, 2))
-                       return NULL;
-       }
-
-       /* Create a Java object. */
-
-       o = builtin_new(m->clazz);
-
-       if (o == NULL)
-               return NULL;
-        
-       /* Call initializer. */
-
-       (void) reflect_invoke(m, o, args);
-
-       return o;
-}
-
-
-/* reflect_method_invoke *******************************************************
-
-   Invokes the given method.
-
-   ARGUMENTS:
-      m .......... methodinfo
-      args ....... method arguments
-      override ... override security checks
-
-   RETURN:
-      return value of the method
-
-*******************************************************************************/
-
-java_handle_t *reflect_method_invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *args, bool override)
-{
-       java_handle_t *ro;
-
-       /* Should we bypass security the checks (AccessibleObject)? */
-
-       if (override == false) {
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-               /* This method is always called like this:
-                      [0] java.lang.reflect.Method.invokeNative (Native Method)
-                      [1] java.lang.reflect.Method.invoke (Method.java:329)
-                      [2] <caller>
-               */
-
-               if (!access_check_method(m, 2))
-                       return NULL;
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-               /* We only pass 1 here as stacktrace_get_caller_class, which
-                  is called from access_check_method, skips
-                  java.lang.reflect.Method.invoke(). */
-
-               if (!access_check_method(m, 1))
-                       return NULL;
-#else
-# error unknown classpath configuration
-#endif
-       }
-
-       /* Check if method class is initialized. */
-
-       if (!(m->clazz->state & CLASS_INITIALIZED))
-               if (!initialize_class(m->clazz))
-                       return NULL;
-
-       /* Call the Java method. */
-
-       ro = reflect_invoke(m, o, args);
-
-       return ro;
-}
-
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) && defined(ENABLE_ANNOTATIONS)
-/* reflect_get_declaredannotatios *********************************************
-
-   Calls the annotation parser with the unparsed annotations and returnes
-   the parsed annotations as a map.
-   
-   IN:
-       annotations........the unparsed annotations
-       declaringClass.....the class in which the annotated element is declared
-       referer............the calling class (for the 'referer' parameter of
-                          vm_call_method())
-
-   RETURN VALUE:
-       The parsed annotations as a
-          java.util.Map<Class<? extends Annotation>, Annotation>.
-
-*******************************************************************************/
-
-struct java_util_Map* reflect_get_declaredannotatios(
-       java_handle_bytearray_t *annotations,
-       java_lang_Class         *declaringClass,
-       classinfo               *referer)
-{
-       static methodinfo        *m_parseAnnotations   = NULL;
-                                   /* parser method (chached, therefore static)  */
-       utf                      *utf_parseAnnotations = NULL;
-                                   /* parser method name                         */
-       utf                      *utf_desc             = NULL;
-                                   /* parser method descriptor (signature)       */
-       sun_reflect_ConstantPool *constantPool         = NULL;
-                                   /* constant pool of the declaring class       */
-       java_lang_Object         *constantPoolOop      = (java_lang_Object*)declaringClass;
-                                   /* constantPoolOop field of the constant pool */
-                                   /* object (sun.reflect.ConstantPool)          */
-
-       constantPool = 
-               (sun_reflect_ConstantPool*)native_new_and_init(
-                       class_sun_reflect_ConstantPool);
-               
-       if(constantPool == NULL) {
-               /* out of memory */
-               return NULL;
-       }
-               
-       LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
-               
-       /* only resolve the parser method the first time */
-       if (m_parseAnnotations == NULL) {
-               utf_parseAnnotations = utf_new_char("parseAnnotations");
-               utf_desc = utf_new_char(
-                       "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
-                       "Ljava/util/Map;");
-
-               if (utf_parseAnnotations == NULL || utf_desc == NULL) {
-                       /* out of memory */
-                       return NULL;
-               }
-               
-               m_parseAnnotations = class_resolveclassmethod(
-                       class_sun_reflect_annotation_AnnotationParser,
-                       utf_parseAnnotations,
-                       utf_desc,
-                       referer,
-                       true);
-       
-               if (m_parseAnnotations == NULL) {
-                       /* method not found */
-                       return NULL;
-               }
-       }
-       
-       return (struct java_util_Map*)vm_call_method(
-                       m_parseAnnotations, NULL, annotations,
-                       constantPool, declaringClass);
-}
-
-
-/* reflect_get_parameterannotations *******************************************
-
-   Calls the annotation parser with the unparsed parameter annotations of
-   a method and returnes the parsed parameter annotations in a 2 dimensional
-   array.
-   
-   IN:
-       parameterAnnotations....the unparsed parameter annotations
-          slot....................the slot of the method
-       declaringClass..........the class in which the annotated element is
-                                  declared
-       referer.................the calling class (for the 'referer' parameter
-                               of vm_call_method())
-
-   RETURN VALUE:
-       The parsed parameter annotations in a 2 dimensional array.
-
-*******************************************************************************/
-
-java_handle_objectarray_t* reflect_get_parameterannotations(
-       java_handle_t     *parameterAnnotations,
-       int32_t            slot,
-       java_lang_Class   *declaringClass,
-       classinfo         *referer)
-{
-       /* This method in java would be basically the following.
-        * We don't do it in java because we don't want to make a
-        * public method with wich you can get a ConstantPool, because
-        * with that you could read any kind of constants (even private
-        * ones).
-        *
-        * ConstantPool constPool = new ConstantPool();
-        * constPool.constantPoolOop = method.getDeclaringClass();
-        * return sun.reflect.AnnotationParser.parseParameterAnnotations(
-        *        parameterAnnotations,
-        *        constPool,
-        *        method.getDeclaringClass(),
-        *        method.getParameterTypes().length);
-        */
-       static methodinfo        *m_parseParameterAnnotations   = NULL;
-                            /* parser method (cached, therefore static)          */
-       utf                      *utf_parseParameterAnnotations = NULL;
-                            /* parser method name                                */
-       utf                      *utf_desc        = NULL;
-                            /* parser method descriptor (signature)              */
-       sun_reflect_ConstantPool *constantPool    = NULL;
-                            /* constant pool of the declaring class              */
-       java_lang_Object         *constantPoolOop = (java_lang_Object*)declaringClass;
-                            /* constantPoolOop field of the constant pool object */
-       classinfo                *c               = NULL;
-                            /* classinfo of the decaring class                   */
-       methodinfo               *m               = NULL;
-                            /* method info of the annotated method               */
-       int32_t                   numParameters   = -1;
-                            /* parameter count of the annotated method           */
-
-       /* get parameter count */
-
-       c = LLNI_classinfo_unwrap(declaringClass);
-       m = &(c->methods[slot]);
-
-       numParameters = method_get_parametercount(m);
-
-       if (numParameters < 0) {
-               /* error parsing descriptor */
-               return NULL;
-       }
-
-       /* get ConstantPool */
-
-       constantPool = 
-               (sun_reflect_ConstantPool*)native_new_and_init(
-                       class_sun_reflect_ConstantPool);
-       
-       if(constantPool == NULL) {
-               /* out of memory */
-               return NULL;
-       }
-
-       LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
-
-       /* only resolve the parser method the first time */
-       if (m_parseParameterAnnotations == NULL) {
-               utf_parseParameterAnnotations = utf_new_char("parseParameterAnnotations");
-               utf_desc = utf_new_char(
-                       "([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)"
-                       "[[Ljava/lang/annotation/Annotation;");
-
-               if (utf_parseParameterAnnotations == NULL || utf_desc == NULL) {
-                       /* out of memory */
-                       return NULL;
-               }
-
-               /* get parser method */
-
-               m_parseParameterAnnotations = class_resolveclassmethod(
-                       class_sun_reflect_annotation_AnnotationParser,
-                       utf_parseParameterAnnotations,
-                       utf_desc,
-                       referer,
-                       true);
-
-               if (m_parseParameterAnnotations == NULL)
-               {
-                       /* method not found */
-                       return NULL;
-               }
-       }
-
-       return (java_handle_objectarray_t*)vm_call_method(
-               m_parseParameterAnnotations, NULL, parameterAnnotations,
-               constantPool, declaringClass, numParameters);
-}
-#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/native/vm/reflect.h b/src/native/vm/reflect.h
deleted file mode 100644 (file)
index 6c6b451..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* src/native/vm/reflect.h - helper functions for java/lang/reflect
-
-   Copyright (C) 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 _REFLECT_H
-#define _REFLECT_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "native/jni.h"
-#include "native/native.h"
-
-/* Keep this order of the native includes. */
-
-#include "native/include/java_lang_String.h"
-
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-#  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
-# endif
-# include "native/include/java_lang_ClassLoader.h"
-#endif
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Class.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_reflect_Constructor.h"
-# include "native/include/java_lang_reflect_Field.h"
-# include "native/include/java_lang_reflect_Method.h"
-#endif
-
-#include "vmcore/field.h"
-#include "vmcore/method.h"
-
-
-/* function prototypes ********************************************************/
-
-java_lang_reflect_Constructor *reflect_constructor_new(methodinfo *m);
-java_lang_reflect_Field       *reflect_field_new(fieldinfo *f);
-java_lang_reflect_Method      *reflect_method_new(methodinfo *m);
-java_handle_t                 *reflect_constructor_newinstance(methodinfo *m, java_handle_objectarray_t *args, bool override);
-java_handle_t                 *reflect_method_invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *args, bool override);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) && defined(ENABLE_ANNOTATIONS)
-struct java_util_Map* reflect_get_declaredannotatios(
-       java_handle_bytearray_t *annotations,
-       java_lang_Class         *declaringClass,
-       classinfo               *referer);
-
-java_handle_objectarray_t* reflect_get_parameterannotations(
-       java_handle_t   *parameterAnnotations,
-       int32_t          slot,
-       java_lang_Class *declaringClass,
-       classinfo       *referer);
-#endif
-
-#endif /* _REFLECT_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/native/vm/reflection.cpp b/src/native/vm/reflection.cpp
new file mode 100644 (file)
index 0000000..421467f
--- /dev/null
@@ -0,0 +1,270 @@
+/* src/native/vm/reflection.cpp - helper functions for java/lang/reflect
+
+   Copyright (C) 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 <stdint.h>
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_ANNOTATIONS) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+# include "vm/vm.hpp"
+#endif
+
+#include "native/vm/reflection.hpp"
+
+#include "vm/access.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+#include "vm/method.h"
+#include "vm/string.hpp"
+
+
+/**
+ * Invoke a method on the given object with the given arguments.
+ *
+ * For instance methods OBJ must be != NULL and the method is looked up
+ * in the vftbl of the object.
+ *
+ * For static methods, OBJ is ignored.
+ */
+java_handle_t* Reflection::invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params)
+{
+       methodinfo    *resm;
+       java_handle_t *ro;
+       int            argcount;
+       int            paramcount;
+
+       /* Sanity check. */
+
+       assert(m != NULL);
+
+       argcount = m->parseddesc->paramcount;
+       paramcount = argcount;
+
+       /* If method is non-static, remove the `this' pointer. */
+
+       if (!(m->flags & ACC_STATIC))
+               paramcount--;
+
+       /* For instance methods the object has to be an instance of the
+          class the method belongs to. For static methods the obj
+          parameter is ignored. */
+
+       if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->clazz))) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       /* check if we got the right number of arguments */
+
+       if (((params == NULL) && (paramcount != 0)) ||
+               (params && (LLNI_array_size(params) != paramcount))) 
+       {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       /* for instance methods we need an object */
+
+       if (!(m->flags & ACC_STATIC) && (o == NULL)) {
+               /* XXX not sure if that is the correct exception */
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* for static methods, zero object to make subsequent code simpler */
+       if (m->flags & ACC_STATIC)
+               o = NULL;
+
+       if (o != NULL) {
+               /* for instance methods we must do a vftbl lookup */
+               resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
+       }
+       else {
+               /* for static methods, just for convenience */
+               resm = m;
+       }
+
+       ro = vm_call_method_objectarray(resm, o, params);
+
+       return ro;
+}
+
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) && defined(ENABLE_ANNOTATIONS)
+/* reflect_get_declaredannotations *********************************************
+
+   Calls the annotation parser with the unparsed annotations and returnes
+   the parsed annotations as a map.
+   
+   IN:
+       annotations........the unparsed annotations
+       declaringClass.....the class in which the annotated element is declared
+       referer............the calling class (for the 'referer' parameter of
+                          vm_call_method())
+
+   RETURN VALUE:
+       The parsed annotations as a
+          java.util.Map<Class<? extends Annotation>, Annotation>.
+
+*******************************************************************************/
+
+java_handle_t* Reflection::get_declaredannotations(java_handle_bytearray_t *annotations, classinfo* declaringClass, classinfo *referer)
+{
+       static methodinfo* m_parseAnnotations = NULL;
+
+       java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
+               
+       if (h == NULL)
+               return NULL;
+
+       sun_reflect_ConstantPool cp(h);
+       cp.set_constantPoolOop(declaringClass);
+               
+       /* only resolve the parser method the first time */
+       if (m_parseAnnotations == NULL) {
+               // FIXME Use globals.
+               utf* utf_parseAnnotations = utf_new_char("parseAnnotations");
+               utf* utf_desc = utf_new_char("([BLsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/util/Map;");
+
+               if (utf_parseAnnotations == NULL || utf_desc == NULL)
+                       return NULL;
+               
+               m_parseAnnotations = class_resolveclassmethod(
+                       class_sun_reflect_annotation_AnnotationParser,
+                       utf_parseAnnotations,
+                       utf_desc,
+                       referer,
+                       true);
+       
+               if (m_parseAnnotations == NULL)
+                       return NULL;
+       }
+       
+       return (java_handle_t*) vm_call_method(m_parseAnnotations, NULL, annotations, cp.get_handle(), declaringClass);
+}
+
+
+/* reflect_get_parameterannotations *******************************************
+
+   Calls the annotation parser with the unparsed parameter annotations of
+   a method and returnes the parsed parameter annotations in a 2 dimensional
+   array.
+   
+   IN:
+       parameterAnnotations....the unparsed parameter annotations
+          slot....................the slot of the method
+       declaringClass..........the class in which the annotated element is
+                                  declared
+       referer.................the calling class (for the 'referer' parameter
+                               of vm_call_method())
+
+   RETURN VALUE:
+       The parsed parameter annotations in a 2 dimensional array.
+
+*******************************************************************************/
+
+java_handle_objectarray_t* Reflection::get_parameterannotations(java_handle_bytearray_t* parameterAnnotations, methodinfo* m, classinfo* referer)
+{
+       /* This method in java would be basically the following.
+        * We don't do it in java because we don't want to make a
+        * public method with wich you can get a ConstantPool, because
+        * with that you could read any kind of constants (even private
+        * ones).
+        *
+        * ConstantPool constPool = new ConstantPool();
+        * constPool.constantPoolOop = method.getDeclaringClass();
+        * return sun.reflect.AnnotationParser.parseParameterAnnotations(
+        *        parameterAnnotations,
+        *        constPool,
+        *        method.getDeclaringClass(),
+        *        method.getParameterTypes().length);
+        */
+
+       static methodinfo* m_parseParameterAnnotations = NULL;
+
+       /* get parameter count */
+
+       int32_t numParameters = method_get_parametercount(m);
+
+       if (numParameters < 0)
+               return NULL;
+
+       /* get ConstantPool */
+
+       java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
+       
+       if (h == NULL)
+               return NULL;
+
+       sun_reflect_ConstantPool cp(h);
+       cp.set_constantPoolOop(m->clazz);
+
+       /* only resolve the parser method the first time */
+       if (m_parseParameterAnnotations == NULL) {
+               utf* utf_parseParameterAnnotations = utf_new_char("parseParameterAnnotations");
+               utf* utf_desc = utf_new_char("([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)[[Ljava/lang/annotation/Annotation;");
+
+               if (utf_parseParameterAnnotations == NULL || utf_desc == NULL)
+                       return NULL;
+
+               /* get parser method */
+
+               m_parseParameterAnnotations = class_resolveclassmethod(
+                       class_sun_reflect_annotation_AnnotationParser,
+                       utf_parseParameterAnnotations,
+                       utf_desc,
+                       referer,
+                       true);
+
+               if (m_parseParameterAnnotations == NULL)
+                       return NULL;
+       }
+
+       return (java_handle_objectarray_t*) vm_call_method(m_parseParameterAnnotations, NULL, parameterAnnotations, cp.get_handle(), m->clazz, numParameters);
+}
+#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/native/vm/reflection.hpp b/src/native/vm/reflection.hpp
new file mode 100644 (file)
index 0000000..39418ab
--- /dev/null
@@ -0,0 +1,65 @@
+/* src/native/vm/reflection.hpp - helper functions for java/lang/reflect
+
+   Copyright (C) 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 _REFLECTION_HPP
+#define _REFLECTION_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#include "vm/field.h"
+#include "vm/method.h"
+
+
+class Reflection {
+public:
+       static java_handle_t* invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) && defined(ENABLE_ANNOTATIONS)
+       static java_handle_t* get_declaredannotations(java_handle_bytearray_t *annotations, classinfo* declaringClass, classinfo *referer);
+       static java_handle_objectarray_t* get_parameterannotations(java_handle_bytearray_t* parameterAnnotations, methodinfo* m, classinfo *referer);
+#endif
+};
+
+#endif // _REFLECTION_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:
+ */
diff --git a/src/native/vm/sun_misc_Unsafe.c b/src/native/vm/sun_misc_Unsafe.c
deleted file mode 100644 (file)
index 737559d..0000000
+++ /dev/null
@@ -1,1381 +0,0 @@
-/* src/native/vm/sun_misc_Unsafe.c - sun/misc/Unsafe
-
-   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 <stdint.h>
-#include <unistd.h>
-
-#include "machine-instr.h"
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"                  /* before c.l.C */
-#include "native/include/java_lang_String.h"            /* required by j.l.CL */
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-# include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
-#endif
-
-#include "native/include/java_lang_ClassLoader.h"        /* required by j.l.C */
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_reflect_Field.h"
-#include "native/include/java_lang_Thread.h"             /* required by s.m.U */
-#include "native/include/java_lang_Throwable.h"
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# include "native/include/java_lang_reflect_VMField.h"
-#endif
-
-#include "native/include/java_security_ProtectionDomain.h" /* required by smU */
-
-#include "native/include/sun_misc_Unsafe.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/initialize.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/system.h"
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "registerNatives",        "()V",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_registerNatives                },
-       { "getInt",                 "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J   },
-       { "putInt",                 "(Ljava/lang/Object;JI)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI  },
-       { "getObject",              "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObject                      },
-       { "putObject",              "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putObject                      },
-       { "getBoolean",             "(Ljava/lang/Object;J)Z",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getBoolean                     },
-       { "putBoolean",             "(Ljava/lang/Object;JZ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putBoolean                     },
-       { "getByte",                "(Ljava/lang/Object;J)B",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J  },
-       { "putByte",                "(Ljava/lang/Object;JB)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB },
-       { "getShort",               "(Ljava/lang/Object;J)S",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J },
-       { "putShort",               "(Ljava/lang/Object;JS)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS },
-       { "getChar",                "(Ljava/lang/Object;J)C",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J  },
-       { "putChar",                "(Ljava/lang/Object;JC)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC },
-       { "getLong",                "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J  },
-       { "putLong",                "(Ljava/lang/Object;JJ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ },
-       { "getFloat",               "(Ljava/lang/Object;J)F",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J },
-       { "putFloat",               "(Ljava/lang/Object;JF)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF },
-       { "getDouble",              "(Ljava/lang/Object;J)D",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J },
-       { "putDouble",              "(Ljava/lang/Object;JD)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putDouble__Ljava_lang_Object_2JD },
-       { "getByte",                "(J)B",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J                     },
-       { "putByte",                "(JB)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__JB                    },
-       { "getShort",               "(J)S",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getShort__J                    },
-       { "putShort",               "(JS)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putShort__JS                   },
-       { "getChar",                "(J)C",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__J                     },
-       { "putChar",                "(JC)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__JC                    },
-       { "getInt",                 "(J)I",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J                      },
-       { "putInt",                 "(JI)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__JI                     },
-       { "getLong",                "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J                     },
-       { "putLong",                "(JJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ                    },
-       { "getFloat",               "(J)F",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getFloat__J                    },
-       { "objectFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset              },
-       { "allocateMemory",         "(J)J",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory                 },
-#if 0
-       /* OpenJDK 7 */
-       { "setMemory",              "(Ljava/lang/Object;JJB)V",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_setMemory                      },
-       { "copyMemory",             "(Ljava/lang/Object;JLjava/lang/Object;JJ)V",                 (void *) (intptr_t) &Java_sun_misc_Unsafe_copyMemory                     },
-#else
-       { "setMemory",              "(JJB)V",                                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_setMemory                      },
-       { "copyMemory",             "(JJJ)V",                                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_copyMemory                     },
-#endif
-       { "freeMemory",             "(J)V",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory                     },
-       { "staticFieldOffset",      "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset              },
-       { "staticFieldBase",        "(Ljava/lang/reflect/Field;)Ljava/lang/Object;",              (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase                },
-       { "ensureClassInitialized", "(Ljava/lang/Class;)V",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized         },
-       { "arrayBaseOffset",        "(Ljava/lang/Class;)I",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset                },
-       { "arrayIndexScale",        "(Ljava/lang/Class;)I",                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayIndexScale                },
-       { "addressSize",            "()I",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_addressSize                    },
-       { "pageSize",               "()I",                                                        (void *) (intptr_t) &Java_sun_misc_Unsafe_pageSize                       },
-       { "defineClass",            "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (intptr_t) &Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2 },
-       { "allocateInstance",       "(Ljava/lang/Class;)Ljava/lang/Object;",                      (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateInstance               },
-       { "throwException",         "(Ljava/lang/Throwable;)V",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException                 },
-       { "compareAndSwapObject",   "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject           },
-       { "compareAndSwapInt",      "(Ljava/lang/Object;JII)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt              },
-       { "compareAndSwapLong",     "(Ljava/lang/Object;JJJ)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong             },
-       { "getObjectVolatile",      "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile              },
-       { "putObjectVolatile",      "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putObjectVolatile              },
-       { "getIntVolatile",         "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile                 },
-       { "putIntVolatile",         "(Ljava/lang/Object;JI)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putIntVolatile                 },
-       { "getLongVolatile",        "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLongVolatile                },
-       { "putLongVolatile",        "(Ljava/lang/Object;JJ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putLongVolatile                },
-       { "putOrderedObject",       "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedObject               },
-       { "putOrderedInt",          "(Ljava/lang/Object;JI)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedInt                  },
-       { "putOrderedLong",         "(Ljava/lang/Object;JJ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedLong                 },
-       { "unpark",                 "(Ljava/lang/Object;)V",                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark                         },
-       { "park",                   "(ZJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_park                           },
-};
-
-
-/* _Jv_sun_misc_Unsafe_init ****************************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_sun_misc_Unsafe_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("sun/misc/Unsafe");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    registerNatives
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
-{
-       /* The native methods of this function are already registered in
-          _Jv_sun_misc_Unsafe_init() which is called during VM
-          startup. */
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getInt
- * Signature: (Ljava/lang/Object;J)I
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       int32_t *p;
-       int32_t  value;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putInt
- * Signature: (Ljava/lang/Object;JI)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
-{
-       int32_t *p;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getObject
- * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       void **p;
-       void  *value;
-
-       p = (void **) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putObject
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x)
-{
-       void **p;
-
-       p = (void **) (((uint8_t *) o) + offset);
-
-       *p = (void *) x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getBoolean
- * Signature: (Ljava/lang/Object;J)Z
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       int32_t *p;
-       int32_t  value;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putBoolean
- * Signature: (Ljava/lang/Object;JZ)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
-{
-       int32_t *p;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getByte
- * Signature: (Ljava/lang/Object;J)B
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       int32_t *p;
-       int32_t  value;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putByte
- * Signature: (Ljava/lang/Object;JB)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
-{
-       int32_t *p;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getShort
- * Signature: (Ljava/lang/Object;J)S
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       int32_t *p;
-       int32_t  value;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putShort
- * Signature: (Ljava/lang/Object;JS)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
-{
-       int32_t *p;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getChar
- * Signature: (Ljava/lang/Object;J)C
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       int32_t *p;
-       int32_t  value;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putChar
- * Signature: (Ljava/lang/Object;JC)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
-{
-       int32_t *p;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getLong
- * Signature: (Ljava/lang/Object;J)J
- */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       int64_t *p;
-       int64_t  value;
-
-       p = (int64_t *) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putLong
- * Signature: (Ljava/lang/Object;JJ)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t x)
-{
-       int64_t *p;
-
-       p = (int64_t *) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getFloat
- * Signature: (Ljava/lang/Object;J)F
- */
-JNIEXPORT float JNICALL Java_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       float *p;
-       float  value;
-
-       p = (float *) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putFloat
- * Signature: (Ljava/lang/Object;JF)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, float x)
-{
-       float *p;
-
-       p = (float *) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getDouble
- * Signature: (Ljava/lang/Object;J)D
- */
-JNIEXPORT double JNICALL Java_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       double *p;
-       double  value;
-
-       p = (double *) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putDouble
- * Signature: (Ljava/lang/Object;JD)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putDouble__Ljava_lang_Object_2JD(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, double x)
-{
-       double *p;
-
-       p = (double *) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getByte
- * Signature: (J)B
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
-{
-       int8_t *p;
-       int8_t  value;
-
-       p = (int8_t *) (intptr_t) address;
-
-       value = *p;
-
-       return (int32_t) value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putByte
- * Signature: (JB)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__JB(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value)
-{
-       int8_t *p;
-
-       p = (int8_t *) (intptr_t) address;
-
-       *p = (int8_t) value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getShort
- * Signature: (J)S
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getShort__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
-{
-       int16_t *p;
-       int16_t  value;
-
-       p = (int16_t *) (intptr_t) address;
-
-       value = *p;
-
-       return (int32_t) value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putShort
- * Signature: (JS)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__JS(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value)
-{
-       int16_t *p;
-
-       p = (int16_t *) (intptr_t) address;
-
-       *p = (int16_t) value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getChar
- * Signature: (J)C
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
-{
-       uint16_t *p;
-       uint16_t  value;
-
-       p = (uint16_t *) (intptr_t) address;
-
-       value = *p;
-
-       return (int32_t) value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putChar
- * Signature: (JC)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__JC(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value)
-{
-       uint16_t *p;
-
-       p = (uint16_t *) (intptr_t) address;
-
-       *p = (uint16_t) value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getInt
- * Signature: (J)I
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
-{
-       int32_t *p;
-       int32_t  value;
-
-       p = (int32_t *) (intptr_t) address;
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putInt
- * Signature: (JI)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__JI(JNIEnv *env, struct sun_misc_Unsafe* this, int64_t address, int32_t value)
-{
-       int32_t *p;
-
-       p = (int32_t *) (intptr_t) address;
-
-       *p = value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getLong
- * Signature: (J)J
- */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
-{
-       int64_t *p;
-       int64_t  value;
-
-       p = (int64_t *) (intptr_t) address;
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putLong
- * Signature: (JJ)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value)
-{
-       int64_t *p;
-
-       p = (int64_t *) (intptr_t) address;
-
-       *p = value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getFloat
- * Signature: (J)F
- */
-JNIEXPORT float JNICALL Java_sun_misc_Unsafe_getFloat__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
-{
-       float *p;
-       float  value;
-
-       p = (float *) (intptr_t) address;
-
-       value = *p;
-
-       return value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    objectFieldOffset
- * Signature: (Ljava/lang/reflect/Field;)J
- */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_reflect_VMField *rvmf;
-#endif
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       LLNI_field_get_ref(field, f,     rvmf);
-       LLNI_field_get_cls(rvmf,  clazz, c);
-       LLNI_field_get_val(rvmf,  slot , slot);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       LLNI_field_get_cls(field, clazz, c);
-       LLNI_field_get_val(field, slot , slot);
-
-#else
-# error unknown configuration
-#endif
-
-       f = &(c->fields[slot]);
-
-       return (int64_t) f->offset;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    allocateMemory
- * Signature: (J)J
- */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes)
-{
-       size_t  length;
-       void   *p;
-
-       length = (size_t) bytes;
-
-       if ((length != (uint64_t) bytes) || (bytes < 0)) {
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
-
-       p = MNEW(uint8_t, length);
-
-       return (int64_t) (intptr_t) p;
-}
-
-
-#if 0
-/* OpenJDK 7 */
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    setMemory
- * Signature: (Ljava/lang/Object;JJB)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t bytes, int32_t value)
-{
-       size_t  length;
-       void   *p;
-
-       length = (size_t) bytes;
-
-       if ((length != (uint64_t) bytes) || (bytes < 0)) {
-               exceptions_throw_illegalargumentexception();
-               return;
-       }
-
-       /* XXX Missing LLNI: we need to unwrap this object. */
-
-       p = (void *) (((uint8_t *) o) + offset);
-
-       /* XXX Not sure this is correct. */
-
-       system_memset(p, value, length);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    copyMemory
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;JJ)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *srcBase, int64_t srcOffset, java_lang_Object *destBase, int64_t destOffset, int64_t bytes)
-{
-       size_t  length;
-       void   *src;
-       void   *dest;
-
-       if (bytes == 0)
-               return;
-
-       length = (size_t) bytes;
-
-       if ((length != (uint64_t) bytes) || (bytes < 0)) {
-               exceptions_throw_illegalargumentexception();
-               return;
-       }
-
-       /* XXX Missing LLNI: We need to unwrap these objects. */
-
-       src  = (void *) (((uint8_t *) srcBase) + srcOffset);
-       dest = (void *) (((uint8_t *) destBase) + destOffset);
-
-       system_memcpy(dest, src, length);
-}
-#else
-/*
- * Class:     sun/misc/Unsafe
- * Method:    setMemory
- * Signature: (JJB)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t bytes, int32_t value)
-{
-       size_t  length;
-       void   *p;
-
-       length = (size_t) bytes;
-
-       if ((length != (uint64_t) bytes) || (bytes < 0)) {
-               exceptions_throw_illegalargumentexception();
-               return;
-       }
-
-       p = (void *) (intptr_t) address;
-
-       /* XXX Not sure this is correct. */
-
-       system_memset(p, value, length);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    copyMemory
- * Signature: (JJJ)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t srcAddress, int64_t destAddress, int64_t bytes)
-{
-       size_t  length;
-       void   *src;
-       void   *dest;
-
-       if (bytes == 0)
-               return;
-
-       length = (size_t) bytes;
-
-       if ((length != (uint64_t) bytes) || (bytes < 0)) {
-               exceptions_throw_illegalargumentexception();
-               return;
-       }
-
-       src  = (void *) (intptr_t) srcAddress;
-       dest = (void *) (intptr_t) destAddress;
-
-       system_memcpy(dest, src, length);
-}
-#endif
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    freeMemory
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
-{
-       void *p;
-
-       p = (void *) (intptr_t) address;
-
-       if (p == NULL)
-               return;
-
-       /* we pass length 1 to trick the free function */
-
-       MFREE(p, uint8_t, 1);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    staticFieldOffset
- * Signature: (Ljava/lang/reflect/Field;)J
- */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f)
-{
-       /* The offset of static fields is 0. */
-
-       return 0;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    staticFieldBase
- * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *rf)
-{
-       classinfo *c;
-       fieldinfo *f;
-       int32_t    slot;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_reflect_VMField *rvmf;
-#endif
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       LLNI_field_get_ref(rf,   f,     rvmf);
-       LLNI_field_get_cls(rvmf, clazz, c);
-       LLNI_field_get_val(rvmf, slot , slot);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       LLNI_field_get_cls(rf, clazz, c);
-       LLNI_field_get_val(rf, slot , slot);
-
-#else
-# error unknown configuration
-#endif
-
-       f = &(c->fields[slot]);
-
-       return (java_lang_Object *) (f->value);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    ensureClassInitialized
- * Signature: (Ljava/lang/Class;)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class)
-{
-       classinfo *c;
-
-       c = LLNI_classinfo_unwrap(class);
-
-       if (!(c->state & CLASS_INITIALIZED))
-               initialize_class(c);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    arrayBaseOffset
- * Signature: (Ljava/lang/Class;)I
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
-{
-       classinfo       *c;
-       arraydescriptor *ad;
-
-       c  = LLNI_classinfo_unwrap(arrayClass);
-       ad = c->vftbl->arraydesc;
-
-       if (ad == NULL) {
-               /* XXX does that exception exist? */
-               exceptions_throw_internalerror("java/lang/InvalidClassException");
-               return 0;
-       }
-
-       return ad->dataoffset;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    arrayIndexScale
- * Signature: (Ljava/lang/Class;)I
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass)
-{
-       classinfo       *c;
-       arraydescriptor *ad;
-
-       c  = LLNI_classinfo_unwrap(arrayClass);
-       ad = c->vftbl->arraydesc;
-
-       if (ad == NULL) {
-               /* XXX does that exception exist? */
-               exceptions_throw_internalerror("java/lang/InvalidClassException");
-               return 0;
-       }
-
-       return ad->componentsize;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    addressSize
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_addressSize(JNIEnv *env, sun_misc_Unsafe *this)
-{
-       return SIZEOF_VOID_P;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    pageSize
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_pageSize(JNIEnv *env, sun_misc_Unsafe *this)
-{
-       int sz;
-
-       sz = getpagesize();
-
-       return sz;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    defineClass
- * Signature: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(JNIEnv *env, sun_misc_Unsafe *this, java_lang_String *name, java_handle_bytearray_t *b, int32_t off, int32_t len, java_lang_ClassLoader *loader, java_security_ProtectionDomain *protectionDomain)
-{
-       classloader_t   *cl;
-       utf             *utfname;
-       classinfo       *c;
-       java_lang_Class *o;
-
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-
-       /* check if data was passed */
-
-       if (b == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       /* check the indexes passed */
-
-       if ((off < 0) || (len < 0) || ((off + len) > LLNI_array_size(b))) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       if (name != NULL) {
-               /* convert '.' to '/' in java string */
-
-               utfname = javastring_toutf((java_handle_t *) name, true);
-       } 
-       else {
-               utfname = NULL;
-       }
-
-       /* define the class */
-
-       c = class_define(utfname, cl, len, (uint8_t *) &(LLNI_array_direct(b, off)),
-                                        (java_handle_t *) protectionDomain);
-
-       if (c == NULL)
-               return NULL;
-
-       /* for convenience */
-
-       o = LLNI_classinfo_wrap(c);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       /* set ProtectionDomain */
-
-       LLNI_field_set_ref(o, pd, protectionDomain);
-#endif
-
-       return o;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    allocateInstance
- * Signature: (Ljava/lang/Class;)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_allocateInstance(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *cls)
-{
-       classinfo     *c;
-       java_handle_t *o;
-
-       c = LLNI_classinfo_unwrap(cls);
-
-       o = builtin_new(c);
-
-       return (java_lang_Object *) o;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    throwException
- * Signature: (Ljava/lang/Throwable;)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee)
-{
-       java_handle_t *o;
-
-       o = (java_handle_t *) ee;
-
-       exceptions_set_exception(o);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    compareAndSwapObject
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *expected, java_lang_Object *x)
-{
-#if 1
-       void **p;
-       void  *value;
-
-       p = (void **) (((uint8_t *) o) + offset);
-
-       /* XXX this should be atomic */
-
-       value = *p;
-
-       if (value == expected) {
-               *p = x;
-
-               return true;
-       }
-
-       return false;
-#else
-       volatile void **p;
-       void           *result;
-
-       /* XXX Use LLNI */
-
-       p = (volatile void **) (((uint8_t *) o) + offset);
-
-       result = atomic_compare_and_swap_address(p, expected, x);
-
-       if (result == expected)
-               return true;
-
-       return false;
-#endif
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    compareAndSwapInt
- * Signature: (Ljava/lang/Object;JII)Z
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, sun_misc_Unsafe* this, java_lang_Object* o, int64_t offset, int32_t expected, int32_t x)
-{
-#if 1
-       int32_t *p;
-       int32_t  value;
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       /* XXX this should be atomic */
-
-       value = *p;
-
-       if (value == expected) {
-               *p = x;
-
-               return true;
-       }
-
-       return false;
-#else
-       int32_t *p;
-       int32_t  result;
-
-       /* XXX Use LLNI */
-
-       p = (int32_t *) (((uint8_t *) o) + offset);
-
-       result = atomic_compare_and_swap_int(p, expected, x);
-
-       if (result == expected)
-               return true;
-
-       return false;
-#endif
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    compareAndSwapLong
- * Signature: (Ljava/lang/Object;JJJ)Z
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t expected, int64_t x)
-{
-       int64_t *p;
-       int64_t  value;
-
-       p = (int64_t *) (((uint8_t *) o) + offset);
-
-       /* XXX this should be atomic */
-
-       value = *p;
-
-       if (value == expected) {
-               *p = x;
-
-               return true;
-       }
-
-       return false;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getObjectVolatile
- * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       volatile void **p;
-       volatile void  *value;
-
-       p = (volatile void **) (((uint8_t *) o) + offset);
-
-       value = *p;
-
-       return (java_lang_Object *) value;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putObjectVolatile
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x)
-{
-       volatile void **p;
-
-       p = (volatile void **) (((uint8_t *) o) + offset);
-
-       *p = x;
-}
-
-
-#define UNSAFE_GET_VOLATILE(type)                                                      \
-       java_handle_t *_h;                                                                              \
-       java_object_t *_o;                                                                              \
-       volatile type *_p;                                                                              \
-       volatile type  _x;                                                                              \
-                                                                                                                       \
-       _h = (java_handle_t *) o;                                                               \
-                                                                                                                       \
-       LLNI_CRITICAL_START;                                                                    \
-                                                                                                                       \
-       _o = LLNI_UNWRAP(_h);                                                                   \
-       _p = (volatile type *) (((uint8_t *) _o) + offset);             \
-                                                                                                                       \
-       _x = *_p;                                                                                               \
-                                                                                                                       \
-       LLNI_CRITICAL_END;                                                                              \
-                                                                                                                       \
-       return _x;
-
-
-#define UNSAFE_PUT_VOLATILE(type)                                                      \
-       java_handle_t *_h;                                                                              \
-       java_object_t *_o;                                                                              \
-       volatile type *_p;                                                                              \
-                                                                                                                       \
-       _h = (java_handle_t *) o;                                                               \
-                                                                                                                       \
-       LLNI_CRITICAL_START;                                                                    \
-                                                                                                                       \
-       _o = LLNI_UNWRAP(_h);                                                                   \
-       _p = (volatile type *) (((uint8_t *) _o) + offset);             \
-                                                                                                                       \
-       *_p = x;                                                                                                \
-                                                                                                                       \
-       MEMORY_BARRIER();                                                                               \
-                                                                                                                       \
-       LLNI_CRITICAL_END;
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getIntVolatile
- * Signature: (Ljava/lang/Object;J)I
- */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       UNSAFE_GET_VOLATILE(int32_t);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putIntVolatile
- * Signature: (Ljava/lang/Object;JI)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
-{
-       UNSAFE_PUT_VOLATILE(int32_t);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    getLongVolatile
- * Signature: (Ljava/lang/Object;J)J
- */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLongVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
-{
-       UNSAFE_GET_VOLATILE(int64_t);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putLongVolatile
- * Signature: (Ljava/lang/Object;JJ)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLongVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t x)
-{
-       UNSAFE_PUT_VOLATILE(int64_t);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putOrderedObject
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x)
-{
-       java_handle_t  *_h;
-       java_handle_t  *_hx;
-       java_object_t  *_o;
-       java_object_t  *_x;
-       volatile void **_p;
-
-       _h  = (java_handle_t *) o;
-       _hx = (java_handle_t *) x;
-
-       LLNI_CRITICAL_START;
-
-       _o = LLNI_UNWRAP(_h);
-       _x = LLNI_UNWRAP(_hx);
-       _p = (volatile void **) (((uint8_t *) _o) + offset);
-
-       *_p = _x;
-
-       MEMORY_BARRIER();
-
-       LLNI_CRITICAL_END;
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putOrderedInt
- * Signature: (Ljava/lang/Object;JI)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedInt(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x)
-{
-       UNSAFE_PUT_VOLATILE(int32_t);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    putOrderedLong
- * Signature: (Ljava/lang/Object;JJ)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedLong(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t x)
-{
-       UNSAFE_PUT_VOLATILE(int64_t);
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    unpark
- * Signature: (Ljava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *thread)
-{
-       /* XXX IMPLEMENT ME */
-}
-
-
-/*
- * Class:     sun/misc/Unsafe
- * Method:    park
- * Signature: (ZJ)V
- */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, sun_misc_Unsafe *this, int32_t isAbsolute, int64_t time)
-{
-       /* XXX IMPLEMENT ME */
-}
-
-
-/*
- * 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/native/vm/sun_misc_Unsafe.cpp b/src/native/vm/sun_misc_Unsafe.cpp
new file mode 100644 (file)
index 0000000..4544393
--- /dev/null
@@ -0,0 +1,1335 @@
+/* src/native/vm/sun_misc_Unsafe.cpp - sun/misc/Unsafe
+
+   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 <stdint.h>
+#include <unistd.h>
+
+#include "threads/atomic.hpp"
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#if defined(ENABLE_JNI_HEADERS)
+# include "native/include/sun_misc_Unsafe.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+#include "vm/os.hpp"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+
+
+// Native functions are exported as C functions.
+extern "C" {
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    registerNatives
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
+{
+       /* The native methods of this function are already registered in
+          _Jv_sun_misc_Unsafe_init() which is called during VM
+          startup. */
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getInt
+ * Signature: (Ljava/lang/Object;J)I
+ */
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       int32_t *p;
+       int32_t  value;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putInt
+ * Signature: (Ljava/lang/Object;JI)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI(JNIEnv *env, jobject _this, jobject o, jlong offset, jint x)
+{
+       int32_t *p;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getObject
+ * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_sun_misc_Unsafe_getObject(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       void **p;
+       void  *value;
+
+       p = (void **) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return (jobject) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putObject
+ * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObject(JNIEnv *env, jobject _this, jobject o, jlong offset, jobject x)
+{
+       void **p;
+
+       p = (void **) (((uint8_t *) o) + offset);
+
+       *p = (void *) x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getBoolean
+ * Signature: (Ljava/lang/Object;J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       int32_t *p;
+       int32_t  value;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putBoolean
+ * Signature: (Ljava/lang/Object;JZ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(JNIEnv *env, jobject _this, jobject o, jlong offset, jboolean x)
+{
+       int32_t *p;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getByte
+ * Signature: (Ljava/lang/Object;J)B
+ */
+JNIEXPORT jbyte JNICALL Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       int32_t *p;
+       int32_t  value;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putByte
+ * Signature: (Ljava/lang/Object;JB)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(JNIEnv *env, jobject _this, jobject o, jlong offset, jbyte x)
+{
+       int32_t *p;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getShort
+ * Signature: (Ljava/lang/Object;J)S
+ */
+JNIEXPORT jshort JNICALL Java_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       int32_t *p;
+       int32_t  value;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putShort
+ * Signature: (Ljava/lang/Object;JS)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS(JNIEnv *env, jobject _this, jobject o, jlong offset, jshort x)
+{
+       int32_t *p;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getChar
+ * Signature: (Ljava/lang/Object;J)C
+ */
+JNIEXPORT jchar JNICALL Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       int32_t *p;
+       int32_t  value;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putChar
+ * Signature: (Ljava/lang/Object;JC)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(JNIEnv *env, jobject _this, jobject o, jlong offset, jchar x)
+{
+       int32_t *p;
+
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getLong
+ * Signature: (Ljava/lang/Object;J)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       int64_t *p;
+       int64_t  value;
+
+       p = (int64_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putLong
+ * Signature: (Ljava/lang/Object;JJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ(JNIEnv *env, jobject _this, jobject o, jlong offset, jlong x)
+{
+       int64_t *p;
+
+       p = (int64_t *) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getFloat
+ * Signature: (Ljava/lang/Object;J)F
+ */
+JNIEXPORT jfloat JNICALL Java_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       float *p;
+       float  value;
+
+       p = (float *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putFloat
+ * Signature: (Ljava/lang/Object;JF)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF(JNIEnv *env, jobject _this, jobject o, jlong offset, jfloat x)
+{
+       float *p;
+
+       p = (float *) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getDouble
+ * Signature: (Ljava/lang/Object;J)D
+ */
+JNIEXPORT jdouble JNICALL Java_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       double *p;
+       double  value;
+
+       p = (double *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putDouble
+ * Signature: (Ljava/lang/Object;JD)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putDouble__Ljava_lang_Object_2JD(JNIEnv *env, jobject _this, jobject o, jlong offset, jdouble x)
+{
+       double *p;
+
+       p = (double *) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getByte
+ * Signature: (J)B
+ */
+JNIEXPORT jbyte JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, jobject _this, jlong address)
+{
+       int8_t *p;
+       int8_t  value;
+
+       p = (int8_t *) (intptr_t) address;
+
+       value = *p;
+
+       return (int32_t) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putByte
+ * Signature: (JB)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__JB(JNIEnv *env, jobject _this, jlong address, jbyte value)
+{
+       int8_t *p;
+
+       p = (int8_t *) (intptr_t) address;
+
+       *p = (int8_t) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getShort
+ * Signature: (J)S
+ */
+JNIEXPORT jshort JNICALL Java_sun_misc_Unsafe_getShort__J(JNIEnv *env, jobject _this, jlong address)
+{
+       int16_t *p;
+       int16_t  value;
+
+       p = (int16_t *) (intptr_t) address;
+
+       value = *p;
+
+       return (int32_t) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putShort
+ * Signature: (JS)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__JS(JNIEnv *env, jobject _this, jlong address, jshort value)
+{
+       int16_t *p;
+
+       p = (int16_t *) (intptr_t) address;
+
+       *p = (int16_t) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getChar
+ * Signature: (J)C
+ */
+JNIEXPORT jchar JNICALL Java_sun_misc_Unsafe_getChar__J(JNIEnv *env, jobject _this, jlong address)
+{
+       uint16_t *p;
+       uint16_t  value;
+
+       p = (uint16_t *) (intptr_t) address;
+
+       value = *p;
+
+       return (int32_t) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putChar
+ * Signature: (JC)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__JC(JNIEnv *env, jobject _this, jlong address, jchar value)
+{
+       uint16_t *p;
+
+       p = (uint16_t *) (intptr_t) address;
+
+       *p = (uint16_t) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getInt
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, jobject _this, jlong address)
+{
+       int32_t *p;
+       int32_t  value;
+
+       p = (int32_t *) (intptr_t) address;
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putInt
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__JI(JNIEnv *env, jobject _this, jlong address, jint value)
+{
+       int32_t *p;
+
+       p = (int32_t *) (intptr_t) address;
+
+       *p = value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getLong
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, jobject _this, jlong address)
+{
+       int64_t *p;
+       int64_t  value;
+
+       p = (int64_t *) (intptr_t) address;
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putLong
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, jobject _this, jlong address, jlong value)
+{
+       int64_t *p;
+
+       p = (int64_t *) (intptr_t) address;
+
+       *p = value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getFloat
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL Java_sun_misc_Unsafe_getFloat__J(JNIEnv *env, jobject _this, jlong address)
+{
+       float *p;
+       float  value;
+
+       p = (float *) (intptr_t) address;
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putFloat
+ * Signature: (JF)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putFloat__JF(JNIEnv *env, jobject _this, jlong address, jfloat value)
+{
+       float* p;
+
+       p = (float*) (intptr_t) address;
+
+       *p = value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    objectFieldOffset
+ * Signature: (Ljava/lang/reflect/Field;)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, jobject _this, jobject field)
+{
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       java_lang_reflect_Field rf(field);
+       java_lang_reflect_VMField rvmf(rf.get_f());
+       fieldinfo* f = rvmf.get_field();
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       java_lang_reflect_Field rf(field);
+       fieldinfo* f = rf.get_field();
+
+#else
+# error unknown configuration
+#endif
+
+       return (jlong) f->offset;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    allocateMemory
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, jobject _this, jlong bytes)
+{
+       size_t  length;
+       void   *p;
+
+       length = (size_t) bytes;
+
+       if ((length != (uint64_t) bytes) || (bytes < 0)) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       p = MNEW(uint8_t, length);
+
+       return (int64_t) (intptr_t) p;
+}
+
+
+#if 0
+/* OpenJDK 7 */
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    setMemory
+ * Signature: (Ljava/lang/Object;JJB)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, jobject _this, jobject o, jlong offset, jlong bytes, jbyte value)
+{
+       size_t  length;
+       void   *p;
+
+       length = (size_t) bytes;
+
+       if ((length != (uint64_t) bytes) || (bytes < 0)) {
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+       /* XXX Missing LLNI: we need to unwrap _this object. */
+
+       p = (void *) (((uint8_t *) o) + offset);
+
+       /* XXX Not sure this is correct. */
+
+       os::memset(p, value, length);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    copyMemory
+ * Signature: (Ljava/lang/Object;JLjava/lang/Object;JJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory(JNIEnv *env, jobject _this, jobject srcBase, jlong srcOffset, jobject destBase, jlong destOffset, jlong bytes)
+{
+       size_t  length;
+       void   *src;
+       void   *dest;
+
+       if (bytes == 0)
+               return;
+
+       length = (size_t) bytes;
+
+       if ((length != (uint64_t) bytes) || (bytes < 0)) {
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+       /* XXX Missing LLNI: We need to unwrap these objects. */
+
+       src  = (void *) (((uint8_t *) srcBase) + srcOffset);
+       dest = (void *) (((uint8_t *) destBase) + destOffset);
+
+       os::memcpy(dest, src, length);
+}
+#else
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    setMemory
+ * Signature: (JJB)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, jobject _this, jlong address, jlong bytes, jbyte value)
+{
+       size_t  length;
+       void   *p;
+
+       length = (size_t) bytes;
+
+       if ((length != (uint64_t) bytes) || (bytes < 0)) {
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+       p = (void *) (intptr_t) address;
+
+       /* XXX Not sure this is correct. */
+
+       os::memset(p, value, length);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    copyMemory
+ * Signature: (JJJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory(JNIEnv *env, jobject _this, jlong srcAddress, jlong destAddress, jlong bytes)
+{
+       size_t  length;
+       void   *src;
+       void   *dest;
+
+       if (bytes == 0)
+               return;
+
+       length = (size_t) bytes;
+
+       if ((length != (uint64_t) bytes) || (bytes < 0)) {
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+       src  = (void *) (intptr_t) srcAddress;
+       dest = (void *) (intptr_t) destAddress;
+
+       os::memcpy(dest, src, length);
+}
+#endif
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    freeMemory
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, jobject _this, jlong address)
+{
+       void *p;
+
+       p = (void *) (intptr_t) address;
+
+       if (p == NULL)
+               return;
+
+       /* we pass length 1 to trick the free function */
+
+       MFREE(p, uint8_t, 1);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    staticFieldOffset
+ * Signature: (Ljava/lang/reflect/Field;)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, jobject _this, jobject f)
+{
+       /* The offset of static fields is 0. */
+
+       return 0;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    staticFieldBase
+ * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, jobject _this, jobject field)
+{
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       java_lang_reflect_Field rf(field);
+       java_lang_reflect_VMField rvmf(rf.get_f());
+       fieldinfo* f = rvmf.get_field();
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       java_lang_reflect_Field rf(field);
+       fieldinfo* f = rf.get_field();
+
+#else
+# error unknown configuration
+#endif
+
+       return (jobject) (f->value);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    ensureClassInitialized
+ * Signature: (Ljava/lang/Class;)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, jobject _this, jclass clazz)
+{
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(clazz);
+
+       if (!(c->state & CLASS_INITIALIZED))
+               initialize_class(c);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    arrayBaseOffset
+ * Signature: (Ljava/lang/Class;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, jobject _this, jclass arrayClass)
+{
+       classinfo       *c;
+       arraydescriptor *ad;
+
+       c  = LLNI_classinfo_unwrap(arrayClass);
+       ad = c->vftbl->arraydesc;
+
+       if (ad == NULL) {
+               /* XXX does that exception exist? */
+               exceptions_throw_internalerror("java/lang/InvalidClassException");
+               return 0;
+       }
+
+       return ad->dataoffset;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    arrayIndexScale
+ * Signature: (Ljava/lang/Class;)I
+ */
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, jobject _this, jclass arrayClass)
+{
+       classinfo       *c;
+       arraydescriptor *ad;
+
+       c  = LLNI_classinfo_unwrap(arrayClass);
+       ad = c->vftbl->arraydesc;
+
+       if (ad == NULL) {
+               /* XXX does that exception exist? */
+               exceptions_throw_internalerror("java/lang/InvalidClassException");
+               return 0;
+       }
+
+       return ad->componentsize;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    addressSize
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_addressSize(JNIEnv *env, jobject _this)
+{
+       return SIZEOF_VOID_P;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    pageSize
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_pageSize(JNIEnv *env, jobject _this)
+{
+       int sz;
+
+       sz = getpagesize();
+
+       return sz;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    defineClass
+ * Signature: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;
+ */
+JNIEXPORT jclass JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(JNIEnv *env, jobject _this, jstring name, jbyteArray b, jint off, jint len, jobject loader, jobject protectionDomain)
+{
+       classloader_t   *cl;
+       utf             *utfname;
+       classinfo       *c;
+
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
+
+       /* check if data was passed */
+
+       if (b == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* check the indexes passed */
+
+       if ((off < 0) || (len < 0) || ((off + len) > LLNI_array_size(b))) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return NULL;
+       }
+
+       if (name != NULL) {
+               /* convert '.' to '/' in java string */
+
+               utfname = javastring_toutf((java_handle_t *) name, true);
+       } 
+       else {
+               utfname = NULL;
+       }
+
+       /* define the class */
+
+       c = class_define(utfname, cl, len, (uint8_t *) &(LLNI_array_direct((java_handle_bytearray_t*) b, off)),
+                                        (java_handle_t *) protectionDomain);
+
+       if (c == NULL)
+               return NULL;
+
+       java_handle_t* h = LLNI_classinfo_wrap(c);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       // Set ProtectionDomain.
+       java_lang_Class jlc(h);
+       jlc.set_pd(protectionDomain);
+#endif
+
+       return (jclass) h;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    allocateInstance
+ * Signature: (Ljava/lang/Class;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_sun_misc_Unsafe_allocateInstance(JNIEnv *env, jobject _this, jclass cls)
+{
+       classinfo     *c;
+       java_handle_t *o;
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       o = builtin_new(c);
+
+       return (jobject ) o;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    throwException
+ * Signature: (Ljava/lang/Throwable;)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, jobject _this, jobject ee)
+{
+       java_handle_t *o;
+
+       o = (java_handle_t *) ee;
+
+       exceptions_set_exception(o);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    compareAndSwapObject
+ * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, jobject _this, jobject o, jlong offset, jobject expected, jobject x)
+{
+       volatile void **p;
+       void           *result;
+
+       /* XXX Use LLNI */
+
+       p = (volatile void **) (((uint8_t *) o) + offset);
+
+       result = Atomic::compare_and_swap(p, expected, x);
+
+       if (result == expected)
+               return true;
+
+       return false;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    compareAndSwapInt
+ * Signature: (Ljava/lang/Object;JII)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, jobject _this, jobject o, jlong offset, jint expected, jint x)
+{
+       uint32_t *p;
+       uint32_t  result;
+
+       /* XXX Use LLNI */
+
+       p = (uint32_t *) (((uint8_t *) o) + offset);
+
+       result = Atomic::compare_and_swap(p, expected, x);
+
+       if (result == (uint32_t) expected)
+               return true;
+
+       return false;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    compareAndSwapLong
+ * Signature: (Ljava/lang/Object;JJJ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, jobject _this, jobject o, jlong offset, jlong expected, jlong x)
+{
+       uint64_t *p;
+       uint64_t  result;
+
+       /* XXX Use LLNI */
+
+       p = (uint64_t *) (((uint8_t *) o) + offset);
+
+       result = Atomic::compare_and_swap(p, expected, x);
+
+       if (result == (uint64_t) expected)
+               return true;
+
+       return false;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getObjectVolatile
+ * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       volatile void **p;
+       volatile void  *value;
+
+       p = (volatile void **) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return (jobject ) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putObjectVolatile
+ * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(JNIEnv *env, jobject _this, jobject o, jlong offset, jobject x)
+{
+       volatile void **p;
+
+       p = (volatile void **) (((uint8_t *) o) + offset);
+
+       *p = x;
+}
+
+
+#define UNSAFE_GET_VOLATILE(type)                                                      \
+       java_handle_t *_h;                                                                              \
+       java_object_t *_o;                                                                              \
+       volatile type *_p;                                                                              \
+       volatile type  _x;                                                                              \
+                                                                                                                       \
+       _h = (java_handle_t *) o;                                                               \
+                                                                                                                       \
+       LLNI_CRITICAL_START;                                                                    \
+                                                                                                                       \
+       _o = LLNI_UNWRAP(_h);                                                                   \
+       _p = (volatile type *) (((uint8_t *) _o) + offset);             \
+                                                                                                                       \
+       _x = *_p;                                                                                               \
+                                                                                                                       \
+       LLNI_CRITICAL_END;                                                                              \
+                                                                                                                       \
+       return _x;
+
+
+#define UNSAFE_PUT_VOLATILE(type)                                                      \
+       java_handle_t *_h;                                                                              \
+       java_object_t *_o;                                                                              \
+       volatile type *_p;                                                                              \
+                                                                                                                       \
+       _h = (java_handle_t *) o;                                                               \
+                                                                                                                       \
+       LLNI_CRITICAL_START;                                                                    \
+                                                                                                                       \
+       _o = LLNI_UNWRAP(_h);                                                                   \
+       _p = (volatile type *) (((uint8_t *) _o) + offset);             \
+                                                                                                                       \
+       *_p = x;                                                                                                \
+                                                                                                                       \
+       Atomic::memory_barrier();                                                               \
+                                                                                                                       \
+       LLNI_CRITICAL_END;
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getIntVolatile
+ * Signature: (Ljava/lang/Object;J)I
+ */
+JNIEXPORT jint JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       UNSAFE_GET_VOLATILE(int32_t);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putIntVolatile
+ * Signature: (Ljava/lang/Object;JI)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putIntVolatile(JNIEnv *env, jobject _this, jobject o, jlong offset, jint x)
+{
+       UNSAFE_PUT_VOLATILE(int32_t);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getLongVolatile
+ * Signature: (Ljava/lang/Object;J)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_getLongVolatile(JNIEnv *env, jobject _this, jobject o, jlong offset)
+{
+       UNSAFE_GET_VOLATILE(int64_t);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putLongVolatile
+ * Signature: (Ljava/lang/Object;JJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLongVolatile(JNIEnv *env, jobject _this, jobject o, jlong offset, jlong x)
+{
+       UNSAFE_PUT_VOLATILE(int64_t);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getDoubleVolatile
+ * Signature: (Ljava/lang/Object;J)D
+ */
+JNIEXPORT jdouble JNICALL Java_sun_misc_Unsafe_getDoubleVolatile(JNIEnv *env, jobject __this, jobject o, jlong offset)
+{
+       UNSAFE_GET_VOLATILE(double);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putOrderedObject
+ * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedObject(JNIEnv *env, jobject _this, jobject o, jlong offset, jobject x)
+{
+       java_handle_t  *_h;
+       java_handle_t  *_hx;
+       java_object_t  *_o;
+       java_object_t  *_x;
+       volatile void **_p;
+
+       _h  = (java_handle_t *) o;
+       _hx = (java_handle_t *) x;
+
+       LLNI_CRITICAL_START;
+
+       _o = LLNI_UNWRAP(_h);
+       _x = LLNI_UNWRAP(_hx);
+       _p = (volatile void **) (((uint8_t *) _o) + offset);
+
+       *_p = _x;
+
+       Atomic::memory_barrier();
+
+       LLNI_CRITICAL_END;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putOrderedInt
+ * Signature: (Ljava/lang/Object;JI)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedInt(JNIEnv *env, jobject _this, jobject o, jlong offset, jint x)
+{
+       UNSAFE_PUT_VOLATILE(int32_t);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putOrderedLong
+ * Signature: (Ljava/lang/Object;JJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedLong(JNIEnv *env, jobject _this, jobject o, jlong offset, jlong x)
+{
+       UNSAFE_PUT_VOLATILE(int64_t);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    unpark
+ * Signature: (Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, jobject _this, jobject thread)
+{
+       /* XXX IMPLEMENT ME */
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    park
+ * Signature: (ZJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, jobject _this, jboolean isAbsolute, jlong time)
+{
+       /* XXX IMPLEMENT ME */
+}
+
+} // extern "C"
+
+
+/* native methods implemented by this file ************************************/
+
+static JNINativeMethod methods[] = {
+       { (char*) "registerNatives",        (char*) "()V",                                                        (void*) (uintptr_t) &Java_sun_misc_Unsafe_registerNatives                  },
+       { (char*) "getInt",                 (char*) "(Ljava/lang/Object;J)I",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J     },
+       { (char*) "putInt",                 (char*) "(Ljava/lang/Object;JI)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI    },
+       { (char*) "getObject",              (char*) "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_getObject                        },
+       { (char*) "putObject",              (char*) "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void*) (uintptr_t) &Java_sun_misc_Unsafe_putObject                        },
+       { (char*) "getBoolean",             (char*) "(Ljava/lang/Object;J)Z",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getBoolean                       },
+       { (char*) "putBoolean",             (char*) "(Ljava/lang/Object;JZ)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putBoolean                       },
+       { (char*) "getByte",                (char*) "(Ljava/lang/Object;J)B",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J    },
+       { (char*) "putByte",                (char*) "(Ljava/lang/Object;JB)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB   },
+       { (char*) "getShort",               (char*) "(Ljava/lang/Object;J)S",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J   },
+       { (char*) "putShort",               (char*) "(Ljava/lang/Object;JS)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS  },
+       { (char*) "getChar",                (char*) "(Ljava/lang/Object;J)C",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J    },
+       { (char*) "putChar",                (char*) "(Ljava/lang/Object;JC)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC   },
+       { (char*) "getLong",                (char*) "(Ljava/lang/Object;J)J",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J    },
+       { (char*) "putLong",                (char*) "(Ljava/lang/Object;JJ)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ   },
+       { (char*) "getFloat",               (char*) "(Ljava/lang/Object;J)F",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J   },
+       { (char*) "putFloat",               (char*) "(Ljava/lang/Object;JF)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF  },
+       { (char*) "getDouble",              (char*) "(Ljava/lang/Object;J)D",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J  },
+       { (char*) "putDouble",              (char*) "(Ljava/lang/Object;JD)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putDouble__Ljava_lang_Object_2JD },
+       { (char*) "getByte",                (char*) "(J)B",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_getByte__J                       },
+       { (char*) "putByte",                (char*) "(JB)V",                                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_putByte__JB                      },
+       { (char*) "getShort",               (char*) "(J)S",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_getShort__J                      },
+       { (char*) "putShort",               (char*) "(JS)V",                                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_putShort__JS                     },
+       { (char*) "getChar",                (char*) "(J)C",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_getChar__J                       },
+       { (char*) "putChar",                (char*) "(JC)V",                                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_putChar__JC                      },
+       { (char*) "getInt",                 (char*) "(J)I",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_getInt__J                        },
+       { (char*) "putInt",                 (char*) "(JI)V",                                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_putInt__JI                       },
+       { (char*) "getLong",                (char*) "(J)J",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_getLong__J                       },
+       { (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*) "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
+       // OpenJDK 7
+       { (char*) "setMemory",              (char*) "(Ljava/lang/Object;JJB)V",                                   (void*) (uintptr_t) &Java_sun_misc_Unsafe_setMemory                        },
+       { (char*) "copyMemory",             (char*) "(Ljava/lang/Object;JLjava/lang/Object;JJ)V",                 (void*) (uintptr_t) &Java_sun_misc_Unsafe_copyMemory                       },
+#else
+       { (char*) "setMemory",              (char*) "(JJB)V",                                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_setMemory                        },
+       { (char*) "copyMemory",             (char*) "(JJJ)V",                                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_copyMemory                       },
+#endif
+       { (char*) "freeMemory",             (char*) "(J)V",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_freeMemory                       },
+       { (char*) "staticFieldOffset",      (char*) "(Ljava/lang/reflect/Field;)J",                               (void*) (uintptr_t) &Java_sun_misc_Unsafe_staticFieldOffset                },
+       { (char*) "staticFieldBase",        (char*) "(Ljava/lang/reflect/Field;)Ljava/lang/Object;",              (void*) (uintptr_t) &Java_sun_misc_Unsafe_staticFieldBase                  },
+       { (char*) "ensureClassInitialized", (char*) "(Ljava/lang/Class;)V",                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized           },
+       { (char*) "arrayBaseOffset",        (char*) "(Ljava/lang/Class;)I",                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset                  },
+       { (char*) "arrayIndexScale",        (char*) "(Ljava/lang/Class;)I",                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_arrayIndexScale                  },
+       { (char*) "addressSize",            (char*) "()I",                                                        (void*) (uintptr_t) &Java_sun_misc_Unsafe_addressSize                      },
+       { (char*) "pageSize",               (char*) "()I",                                                        (void*) (uintptr_t) &Java_sun_misc_Unsafe_pageSize                         },
+       { (char*) "defineClass",            (char*) "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", (void*) (uintptr_t) &Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2 },
+       { (char*) "allocateInstance",       (char*) "(Ljava/lang/Class;)Ljava/lang/Object;",                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_allocateInstance                 },
+       { (char*) "throwException",         (char*) "(Ljava/lang/Throwable;)V",                                   (void*) (uintptr_t) &Java_sun_misc_Unsafe_throwException                   },
+       { (char*) "compareAndSwapObject",   (char*) "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void*) (uintptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject             },
+       { (char*) "compareAndSwapInt",      (char*) "(Ljava/lang/Object;JII)Z",                                   (void*) (uintptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt                },
+       { (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*) "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                  },
+       { (char*) "putLongVolatile",        (char*) "(Ljava/lang/Object;JJ)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putLongVolatile                  },
+       { (char*) "getDoubleVolatile",      (char*) "(Ljava/lang/Object;J)D",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getDoubleVolatile                },
+       { (char*) "putOrderedObject",       (char*) "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void*) (uintptr_t) &Java_sun_misc_Unsafe_putOrderedObject                 },
+       { (char*) "putOrderedInt",          (char*) "(Ljava/lang/Object;JI)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putOrderedInt                    },
+       { (char*) "putOrderedLong",         (char*) "(Ljava/lang/Object;JJ)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putOrderedLong                   },
+       { (char*) "unpark",                 (char*) "(Ljava/lang/Object;)V",                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_unpark                           },
+       { (char*) "park",                   (char*) "(ZJ)V",                                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_park                             },
+};
+
+
+/* _Jv_sun_misc_Unsafe_init ****************************************************
+
+   Register native functions.
+
+*******************************************************************************/
+
+// FIXME
+extern "C" {
+void _Jv_sun_misc_Unsafe_init(void)
+{
+       utf *u;
+
+       u = utf_new_char("sun/misc/Unsafe");
+
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+}
+
+/*
+ * 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 b6cf86dd5bdfc94439964c1c0c7c11cd74faf3aa..68cdfd9ec4d5c5c5b8373aa33cc3a9fa55949196 100644 (file)
@@ -49,14 +49,16 @@ noinst_LTLIBRARIES = \
 
 if ENABLE_THREADS
 libthreads_la_SOURCES = \
-       critical.c \
-       critical.h \
+       atomic.cpp \
+       atomic.hpp \
+       condition.hpp \
        lock-common.h \
-       mutex.h \
+       removeme.cpp \
+       mutex.hpp \
        threadlist.c \
        threadlist.h \
-       thread.c \
-       thread.h
+       thread.cpp \
+       thread.hpp
 else
 libthreads_la_SOURCES =
 endif
diff --git a/src/threads/atomic.cpp b/src/threads/atomic.cpp
new file mode 100644 (file)
index 0000000..e5ca7c8
--- /dev/null
@@ -0,0 +1,159 @@
+/* src/threads/atomic.cpp - atomic instructions
+
+   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.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+#include "threads/mutex.hpp"
+
+// Gobal mutex for generic atomic instructions.
+static Mutex lock;
+
+
+/**
+ * A generic atomic compare and swap for 32-bit integer values.  This
+ * function is using a mutex to provide atomicity.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+uint32_t Atomic::generic_compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       uint32_t result;
+
+       lock.lock();
+
+       // Do the compare-and-swap.
+
+       result = *p;
+
+       if (oldval == result)
+               *p = newval;
+
+       lock.unlock();
+
+       return result;
+}
+
+
+/**
+ * A generic atomic compare and swap for 64-bit integer values.  This
+ * function is using a mutex to provide atomicity.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+uint64_t Atomic::generic_compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       uint64_t result;
+
+       lock.lock();
+
+       // Do the compare-and-swap.
+
+       result = *p;
+
+       if (oldval == result)
+               *p = newval;
+
+       lock.unlock();
+
+       return result;
+}
+
+
+/**
+ * A generic atomic compare and swap for pointer values.  This
+ * function is using a mutex to provide atomicity.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+void* Atomic::generic_compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       void* result;
+
+       lock.lock();
+
+       // Do the compare-and-swap.
+
+       result = (void*) *p;
+
+       if (oldval == result)
+               *p = newval;
+
+       lock.lock();
+
+       return result;
+}
+
+
+/**
+ * A generic memory barrier.  This function is using a mutex to
+ * provide atomicity.
+ */
+void Atomic::generic_memory_barrier(void)
+{
+       lock.lock();
+       lock.unlock();
+}
+
+
+// Legacy C interface.
+
+extern "C" {
+uint32_t Atomic_compare_and_swap_32(volatile uint32_t *p, uint32_t oldval, uint32_t newval) { return Atomic::compare_and_swap(p, oldval, newval); }
+uint64_t Atomic_compare_and_swap_64(volatile uint64_t *p, uint64_t oldval, uint64_t newval) { return Atomic::compare_and_swap(p, oldval, newval); }
+void*    Atomic_compare_and_swap_ptr(volatile void** p, void* oldval, void* newval) { return Atomic::compare_and_swap(p, oldval, newval); }
+void     Atomic_memory_barrier(void) { Atomic::memory_barrier(); }
+void     Atomic_write_memory_barrier(void) { Atomic::write_memory_barrier(); }
+void     Atomic_instruction_barrier(void) { Atomic::instruction_barrier(); }
+}
+
+
+/*
+ * 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/threads/atomic.hpp b/src/threads/atomic.hpp
new file mode 100644 (file)
index 0000000..382a872
--- /dev/null
@@ -0,0 +1,83 @@
+/* src/threads/atomic.hpp - atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _ATOMIC_HPP
+#define _ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+
+class Atomic {
+public:
+       // Generic functions.
+       static uint32_t generic_compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval);
+       static uint64_t generic_compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval);
+       static void*    generic_compare_and_swap(volatile void** p, void* oldval, void* newval);
+       static void     generic_memory_barrier(void);
+
+       // Machine dependent functions.
+       static uint32_t compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval);
+       static uint64_t compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval);
+       static void*    compare_and_swap(volatile void** p, void* oldval, void* newval);
+       static void     memory_barrier(void);
+       static void     write_memory_barrier(void);
+       static void     instruction_barrier(void);
+};
+
+// Include machine dependent implementation.
+#include "md-atomic.hpp"
+
+#else
+
+// Legacy C interface.
+
+uint32_t Atomic_compare_and_swap_32(volatile uint32_t *p, uint32_t oldval, uint32_t newval);
+uint64_t Atomic_compare_and_swap_64(volatile uint64_t *p, uint64_t oldval, uint64_t newval);
+void*    Atomic_compare_and_swap_ptr(volatile void** p, void* oldval, void* newval);
+void     Atomic_memory_barrier(void);
+void     Atomic_write_memory_barrier(void);
+void     Atomic_instruction_barrier(void);
+
+#endif
+
+#endif // _ATOMIC_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:
+ */
diff --git a/src/threads/condition.hpp b/src/threads/condition.hpp
new file mode 100644 (file)
index 0000000..b237835
--- /dev/null
@@ -0,0 +1,52 @@
+/* src/threads/condition.hpp - condition variable
+
+   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.
+
+*/
+
+
+#ifndef _CONDITION_HPP
+#define _CONDITION_HPP
+
+#include "config.h"
+
+#include "threads/mutex.hpp"
+
+#if defined(ENABLE_THREADS)
+# include "threads/posix/condition-posix.hpp"
+#endif
+
+#endif /* _CONDITION_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:
+ */
diff --git a/src/threads/critical.c b/src/threads/critical.c
deleted file mode 100644 (file)
index 51c3317..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/* src/threads/critical.c - restartable critical sections
-
-   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
-
-   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 <stddef.h>
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "threads/critical.h"
-
-#include "toolbox/avl.h"
-
-
-/* the AVL tree containing the critical sections */
-
-static avl_tree_t *criticaltree;
-
-
-/* prototypes *****************************************************************/
-
-static int critical_comparator(const void *treenode, const void *node);
-
-
-/* critical_init ***************************************************************
-
-   Init global data structures.
-
-*******************************************************************************/
-
-void critical_init(void)
-{
-    criticaltree = avl_create(&critical_comparator);
-}
-
-
-/* critical_comparator *********************************************************
-
-   Comparison function for AVL tree of critical section.
-
-   IN:
-       treenode....node in the tree
-          node........node to compare with tree-node
-
-   RETURN VALUE:
-       -1, 0, +1 for (pa <, ==, > pb)
-
-*******************************************************************************/
-
-static int critical_comparator(const void *treenode, const void *node)
-{
-       const critical_section_node_t *treecsn;
-       const critical_section_node_t *csn;
-
-       treecsn = treenode;
-       csn     = node;
-
-#ifdef __S390__
-#      define ADDR_MASK(x) ((u1 *)((s4)(x) & 0x7FFFFFFF))
-#else
-#      define ADDR_MASK(x) (x)
-#endif
-
-       /* compare for avl_find if we have found an entry */
-
-       if (
-               (ADDR_MASK(treecsn->start) <= ADDR_MASK(csn->start)) && 
-               (ADDR_MASK(csn->start) < ADDR_MASK(treecsn->end))
-       )
-               return 0;
-
-       /* these are for walking the tree */
-
-       if (ADDR_MASK(treecsn->start) < ADDR_MASK(csn->start))
-               return -1;
-       else
-               return 1;
-
-#undef ADDR_MASK
-}
-
-
-/* critical_section_register ***************************************************
-   Register a critical section.
-
-   IN:
-       csn....node for the critical section
-
-*******************************************************************************/
-
-void critical_section_register(critical_section_node_t *csn)
-{
-       (void) avl_insert(criticaltree, csn);
-}
-
-
-/* critical_find_restart_point *************************************************
-
-   Find a restart point for the given PC, in case it is in a critical
-   section.
-
-   IN:
-       pc.........PC
-
-   OUT:
-       PC of the restart point, or
-          NULL if the given mcodeptr is not in a critical section
-
-*******************************************************************************/
-
-u1 *critical_find_restart_point(u1 *pc)
-{
-       critical_section_node_t        csnpc;
-       const critical_section_node_t *csn;
-
-       /* fill the temporary node for comparison */
-
-       csnpc.start = pc;
-
-       /* see if there's an entry for that PC */
-
-       csn = avl_find(criticaltree, &csnpc);
-
-       if (csn == NULL)
-               return NULL;
-
-       return csn->restart;
-}
-
-
-/*
- * 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/threads/critical.h b/src/threads/critical.h
deleted file mode 100644 (file)
index 7bb2917..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* src/threads/native/critical.h - restartable critical sections
-
-   Copyright (C) 1996-2005, 2006 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
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Stefan Ring
-                       Edwin Steiner
-
-   Changes: Christian Thalinger
-
-*/
-
-
-#ifndef _CRITICAL_H
-#define _CRITICAL_H
-
-#include "config.h"
-
-#include <signal.h>   /* required on some older Darwin systems for ucontext.h */
-#include <ucontext.h>
-
-
-/* forward typedefs ***********************************************************/
-
-typedef struct critical_section_node_t critical_section_node_t;
-
-
-/* critical_section_node_t *****************************************************
-
-   A node representing a restartable critical section.
-
-*******************************************************************************/
-
-struct critical_section_node_t {
-       u1 *start;
-       u1 *end;
-       u1 *restart;
-};
-
-
-/* functions ******************************************************************/
-
-void  critical_init(void);
-void  critical_section_register(critical_section_node_t *);
-u1   *critical_find_restart_point(u1*);
-
-/* this is a machine dependent function (see src/vm/jit/$(ARCH_DIR)/md.c) */
-void  md_critical_section_restart(ucontext_t *_uc);
-
-#endif /* _CRITICAL_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 1bc3cdc2b5113aff49b579879a552f15544f0bfc..e0a8f674b7622ca695a83c223b136d3d39207528 100644 (file)
 #define _LOCK_COMMON_H
 
 #include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/types.h"
 
 #include "vm/global.h"
@@ -64,6 +69,10 @@ void lock_notify_all_object(java_handle_t *o);
 
 #endif /* ENABLE_THREADS */
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _LOCK_COMMON_H */
 
 
diff --git a/src/threads/mutex.h b/src/threads/mutex.h
deleted file mode 100644 (file)
index 7458b0d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* src/threads/mutex.h - machine independent mutual exclusion functions
-
-   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.
-
-*/
-
-
-#ifndef _MUTEX_H
-#define _MUTEX_H
-
-#include "config.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/posix/mutex-posix.h"
-#endif
-
-
-#endif /* _MUTEX_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/threads/mutex.hpp b/src/threads/mutex.hpp
new file mode 100644 (file)
index 0000000..e8bbce3
--- /dev/null
@@ -0,0 +1,50 @@
+/* src/threads/mutex.hpp - machine independent mutual exclusion functions
+
+   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.
+
+*/
+
+
+#ifndef _MUTEX_HPP
+#define _MUTEX_HPP
+
+#include "config.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/posix/mutex-posix.hpp"
+#endif
+
+#endif /* _MUTEX_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 8c333adaf254c1109a534d0e75d54db45c15b440..de21e8aed7278da8ff2d65fc403b290e03cec976 100644 (file)
@@ -27,9 +27,9 @@
 
 #include <stdint.h>
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* global variables ***********************************************************/
index cefeeacebc589cf37770ab75767c46192784ee28..bd149bc3773937a1c1f757ec837281df71a72e44 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "vm/builtin.h"
 
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* define some stuff we need to no-ops ****************************************/
index 880d47f293f9b8cf5e1c84e3cad1451e3f140eaa..c4a9f73613f84842d724fc677988ae6d575a63da 100644 (file)
@@ -29,11 +29,12 @@ noinst_LTLIBRARIES = \
        libthreadsposix.la
 
 libthreadsposix_la_SOURCES = \
+       condition-posix.hpp \
        lock.c \
        lock.h \
-       mutex-posix.h \
-       thread-posix.c \
-       thread-posix.h
+       mutex-posix.hpp \
+       thread-posix.cpp \
+       thread-posix.hpp
 
 
 ## Local variables:
diff --git a/src/threads/posix/condition-posix.hpp b/src/threads/posix/condition-posix.hpp
new file mode 100644 (file)
index 0000000..4c8afc0
--- /dev/null
@@ -0,0 +1,173 @@
+/* src/threads/posix/condition-posix.hpp - POSIX condition variable
+
+   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.
+
+*/
+
+
+#ifndef _CONDITION_POSIX_HPP
+#define _CONDITION_POSIX_HPP
+
+#include "config.h"
+
+#include <pthread.h>
+#include <time.h>
+
+#include "vm/vm.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * POSIX condition variable.
+ */
+class Condition {
+private:
+       // POSIX condition structure.
+       pthread_cond_t _cond;
+
+public:
+       Condition();
+       ~Condition();
+
+       void broadcast();
+       void signal();
+       void timedwait(Mutex* mutex, const struct timespec* abstime);
+       void wait(Mutex* mutex);
+};
+
+
+/**
+ * Initialize a POSIX condition variable.
+ */
+inline Condition::Condition()
+{
+       int result;
+
+       result = pthread_cond_init(&_cond, NULL);
+
+       if (result != 0)
+               vm_abort_errnum(result, "Condition::Condition(): pthread_cond_init failed");
+}
+
+
+/**
+ * Destroys a POSIX condition variable.
+ */
+inline Condition::~Condition()
+{
+       int result;
+
+       result = pthread_cond_destroy(&_cond);
+
+       if (result != 0)
+               vm_abort_errnum(result, "Condition::~Condition(): pthread_cond_destroy failed");
+}
+
+
+/**
+ * Restarts all the threads that are waiting on the condition
+ * variable.
+ */
+inline void Condition::broadcast()
+{
+       int result;
+
+       result = pthread_cond_broadcast(&_cond);
+
+       if (result != 0)
+               vm_abort_errnum(result, "Condition::broadcast(): pthread_cond_broadcast failed");
+}
+
+
+/**
+ * Restarts one of the threads that are waiting on this condition
+ * variable.
+ */
+inline void Condition::signal()
+{
+       int result;
+
+       result = pthread_cond_signal(&_cond);
+
+       if (result != 0)
+               vm_abort_errnum(result, "Condition::signal(): pthread_cond_signal failed");
+}
+
+
+/**
+ * Waits on the condition variable, as wait() does, but it also bounds
+ * the duration of the wait.
+ */
+inline void Condition::timedwait(Mutex* mutex, const struct timespec* abstime)
+{
+       // This function can return return values which are valid.
+       (void) pthread_cond_timedwait(&_cond, &(mutex->_mutex), abstime);
+}
+
+
+/**
+ * Waits for the condition variable.
+ */
+inline void Condition::wait(Mutex* mutex)
+{
+       int result;
+
+       result = pthread_cond_wait(&_cond, &(mutex->_mutex));
+
+       if (result != 0)
+               vm_abort_errnum(result, "Condition::wait(): pthread_cond_wait failed");
+}
+
+#else
+
+// This structure must have the same layout as the class above.
+typedef struct Condition {
+       pthread_mutex_t _mutex;
+       pthread_cond_t _cond;
+} Condition;
+
+Condition* Condition_new();
+void       Condition_delete(Condition* cond);
+void       Condition_lock(Condition* cond);
+void       Condition_unlock(Condition* cond);
+void       Condition_broadcast(Condition* cond);
+void       Condition_signal(Condition* cond);
+void       Condition_timedwait(Condition* cond, Mutex *mutex, const struct timespec* abstime);
+void       Condition_wait(Condition* cond, Mutex* mutex);
+
+#endif
+
+#endif /* _CONDITION_POSIX_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:
+ */
diff --git a/src/threads/posix/generic-primitives.h b/src/threads/posix/generic-primitives.h
deleted file mode 100644 (file)
index 2ab03a1..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* src/threads/native/generic-primitives.h - machine independent atomic
-                                             operations
-
-   Copyright (C) 1996-2005, 2006 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
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Anton Ertl
-
-   Changes: 
-
-
-*/
-
-
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-#include <pthread.h>
-
-#include "threads/mutex.h"
-
-
-extern mutex_t _cas_lock;
-extern mutex_t _mb_lock;
-
-
-static inline long compare_and_swap(volatile long *p, long oldval, long newval)
-{
-  long ret;
-
-  mutex_lock(&_cas_lock);
-
-  /* do the compare-and-swap */
-
-  ret = *p;
-
-  if (oldval == ret)
-    *p = newval;
-
-  mutex_unlock(&_cas_lock);
-
-  return ret;
-}
-
-
-#define MEMORY_BARRIER()                  (mutex_lock(&_mb_lock), \
-                                           mutex_unlock(&_mb_lock))
-#define STORE_ORDER_BARRIER()             MEMORY_BARRIER()
-#define MEMORY_BARRIER_AFTER_ATOMIC()     /* nothing */
-
-#endif /* _MACHINE_INSTR_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 71e5a0077132212fb2704d721e2057344bf81e7b..81c3633367845fc47b38900db23004e3e48d7a6d 100644 (file)
 #include "native/llni.h"
 
 #include "threads/lock-common.h"
-#include "threads/mutex.h"
+#include "threads/mutex.hpp"
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "threads/posix/lock.h"
 
 #include "toolbox/list.h"
 
-#include "vm/global.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/finalizer.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/options.h"
+#include "vm/global.h"
+#include "vm/options.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
 
 #if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
+# include "vm/statistics.h"
 #endif
 
 #if defined(ENABLE_VMLOG)
@@ -72,7 +71,7 @@
 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
 #include "threads/posix/generic-primitives.h"
 #else
-#include "machine-instr.h"
+#include "threads/atomic.hpp"
 #endif
 
 #if defined(ENABLE_JVMTI)
 
 #define LOCK_INITIAL_HASHTABLE_SIZE  1613  /* a prime in the middle between 1024 and 2048 */
 
-#define COMPARE_AND_SWAP_OLD_VALUE(address, oldvalue, newvalue) \
-       ((ptrint) compare_and_swap((long *)(address), (long)(oldvalue), (long)(newvalue)))
-
 
 /******************************************************************************/
 /* MACROS FOR THIN/FAT LOCKS                                                  */
@@ -273,7 +269,7 @@ static lock_record_t *lock_record_new(void)
 
        /* initialize the mutex */
 
-       mutex_init(&(lr->mutex));
+       lr->mutex = Mutex_new();
 
        DEBUGLOCKS(("[lock_record_new   : lr=%p]", (void *) lr));
 
@@ -296,7 +292,7 @@ static void lock_record_free(lock_record_t *lr)
 
        /* Destroy the mutex. */
 
-       mutex_destroy(&(lr->mutex));
+       Mutex_delete(lr->mutex);
 
 #if defined(ENABLE_GC_CACAO)
        /* unregister the lock object reference with the GC */
@@ -331,7 +327,7 @@ static void lock_record_free(lock_record_t *lr)
 
 static void lock_hashtable_init(void)
 {
-       mutex_init(&(lock_hashtable.mutex));
+       lock_hashtable.mutex = Mutex_new();
 
        lock_hashtable.size    = LOCK_INITIAL_HASHTABLE_SIZE;
        lock_hashtable.entries = 0;
@@ -434,7 +430,7 @@ void lock_hashtable_cleanup(void)
 
        /* lock the hashtable */
 
-       mutex_lock(&(lock_hashtable.mutex));
+       Mutex_lock(lock_hashtable.mutex);
 
        /* search the hashtable for cleared references */
 
@@ -470,7 +466,7 @@ void lock_hashtable_cleanup(void)
 
        /* unlock the hashtable */
 
-       mutex_unlock(&(lock_hashtable.mutex));
+       Mutex_unlock(lock_hashtable.mutex);
 }
 #endif
 
@@ -506,7 +502,7 @@ static lock_record_t *lock_hashtable_get(threadobject *t, java_handle_t *o)
 
        /* lock the hashtable */
 
-       mutex_lock(&(lock_hashtable.mutex));
+       Mutex_lock(lock_hashtable.mutex);
 
        /* lookup the lock record in the hashtable */
 
@@ -550,7 +546,7 @@ static lock_record_t *lock_hashtable_get(threadobject *t, java_handle_t *o)
 
        /* unlock the hashtable */
 
-       mutex_unlock(&(lock_hashtable.mutex));
+       Mutex_unlock(lock_hashtable.mutex);
 
        /* return the new lock record */
 
@@ -578,7 +574,7 @@ static void lock_hashtable_remove(threadobject *t, java_handle_t *o)
 
        /* lock the hashtable */
 
-       mutex_lock(&(lock_hashtable.mutex));
+       Mutex_lock(lock_hashtable.mutex);
 
        /* get lock record */
 
@@ -617,7 +613,7 @@ static void lock_hashtable_remove(threadobject *t, java_handle_t *o)
 
        /* unlock the hashtable */
 
-       mutex_unlock(&(lock_hashtable.mutex));
+       Mutex_unlock(lock_hashtable.mutex);
 
        /* free the lock record */
 
@@ -745,7 +741,7 @@ static inline void lock_lockword_set(threadobject *t, java_handle_t *o, uintptr_
 
 static inline void lock_record_enter(threadobject *t, lock_record_t *lr)
 {
-       mutex_lock(&(lr->mutex));
+       Mutex_lock(lr->mutex);
        lr->owner = t;
 }
 
@@ -767,7 +763,7 @@ static inline void lock_record_enter(threadobject *t, lock_record_t *lr)
 static inline void lock_record_exit(threadobject *t, lock_record_t *lr)
 {
        lr->owner = NULL;
-       mutex_unlock(&(lr->mutex));
+       Mutex_unlock(lr->mutex);
 }
 
 
@@ -848,7 +844,7 @@ static void sable_flc_waiting(ptrint lockword, threadobject *t, java_handle_t *o
 /*             failure, TODO: add statistics */
                return;
 
-       mutex_lock(&t_other->flc_lock);
+       Mutex_lock(t_other->flc_lock);
        old_flc = t_other->flc_bit;
        t_other->flc_bit = true;
 
@@ -856,7 +852,7 @@ static void sable_flc_waiting(ptrint lockword, threadobject *t, java_handle_t *o
                                t->index, t_other->index));
 
        /* Set FLC bit first, then read the lockword again */
-       MEMORY_BARRIER();
+       Atomic_memory_barrier();
 
        lockword = lock_lockword_get(t, o);
 
@@ -874,7 +870,7 @@ static void sable_flc_waiting(ptrint lockword, threadobject *t, java_handle_t *o
 
                        /* Wait until another thread sees the flc bit and notifies
                           us of unlocking. */
-                       pthread_cond_wait(&t->flc_cond, &t_other->flc_lock);
+                       Condition_wait(t->flc_cond, t_other->flc_lock);
 
                        /* Traverse FLC list looking if we're still there */
                        current = t_other->flc_list;
@@ -895,14 +891,14 @@ static void sable_flc_waiting(ptrint lockword, threadobject *t, java_handle_t *o
        else
                t_other->flc_bit = old_flc;
 
-       mutex_unlock(&t_other->flc_lock);
+       Mutex_unlock(t_other->flc_lock);
 }
 
 static void notify_flc_waiters(threadobject *t, java_handle_t *o)
 {
        threadobject *current;
 
-       mutex_lock(&t->flc_lock);
+       Mutex_lock(t->flc_lock);
 
        current = t->flc_list;
        while (current)
@@ -925,14 +921,14 @@ static void notify_flc_waiters(threadobject *t, java_handle_t *o)
                        }
                }
                /* Wake the waiting thread */
-               pthread_cond_broadcast(&current->flc_cond);
+               Condition_broadcast(current->flc_cond);
 
                current = current->flc_next;
        }
 
        t->flc_list = NULL;
        t->flc_bit = false;
-       mutex_unlock(&t->flc_lock);
+       Mutex_unlock(t->flc_lock);
 }
 
 /* lock_monitor_enter **********************************************************
@@ -973,14 +969,14 @@ retry:
        /* most common case: try to thin-lock an unlocked object */
 
        LLNI_CRITICAL_START_THREAD(t);
-       lockword = COMPARE_AND_SWAP_OLD_VALUE(&(LLNI_DIRECT(o)->lockword), THIN_UNLOCKED, thinlock);
+       lockword = Atomic_compare_and_swap_ptr(&(LLNI_DIRECT(o)->lockword), THIN_UNLOCKED, thinlock);
        LLNI_CRITICAL_END_THREAD(t);
 
        if (lockword == THIN_UNLOCKED) {
                /* success. we locked it */
                /* The Java Memory Model requires a memory barrier here: */
                /* Because of the CAS above, this barrier is a nop on x86 / x86_64 */
-               MEMORY_BARRIER_AFTER_ATOMIC();
+               Atomic_instruction_barrier();
                return true;
        }
 
@@ -1095,10 +1091,10 @@ bool lock_monitor_exit(java_handle_t *o)
 
        if (lockword == thinlock) {
                /* memory barrier for Java Memory Model */
-               STORE_ORDER_BARRIER();
+               Atomic_write_memory_barrier();
                lock_lockword_set(t, o, THIN_UNLOCKED);
-               /* memory barrier for thin locking */
-               MEMORY_BARRIER();
+               /* Memory barrier for thin locking. */
+               Atomic_memory_barrier();
 
                /* check if there has been a flat lock contention on this object */
 
@@ -1148,7 +1144,7 @@ bool lock_monitor_exit(java_handle_t *o)
                /* unlock this lock record */
 
                lr->owner = NULL;
-               mutex_unlock(&(lr->mutex));
+               Mutex_unlock(lr->mutex);
 
                return true;
        }
@@ -1416,12 +1412,12 @@ static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one)
 
                /* Enter the wait-mutex. */
 
-               mutex_lock(&(waitingthread->waitmutex));
+               Mutex_lock(waitingthread->waitmutex);
 
                DEBUGLOCKS(("[lock_record_notify: lr=%p, t=%p, waitingthread=%p, one=%d]",
                                        lr, t, waitingthread, one));
 
-               pthread_cond_signal(&(waitingthread->waitcond));
+               Condition_signal(waitingthread->waitcond);
 
                /* Mark the thread as signaled. */
 
@@ -1429,7 +1425,7 @@ static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one)
 
                /* Leave the wait-mutex. */
 
-               mutex_unlock(&(waitingthread->waitmutex));
+               Mutex_unlock(waitingthread->waitmutex);
 
                /* if we should only wake one, we are done */
 
index 56e17222c50a9489793d935526b1cc97757235fe..ddadd3f81a7e20ae314aef62fbe02a8500ee2dfd 100644 (file)
 
 #include "config.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <pthread.h>
 
 #include "vm/types.h"
 
 #include "native/llni.h"
 
-#include "threads/mutex.h"
+#include "threads/mutex.hpp"
 
 #include "toolbox/list.h"
 
@@ -71,7 +75,7 @@ struct lock_record_t {
        java_object_t       *object;             /* object for which this lock is */
        struct threadobject *owner;              /* current owner of this monitor */
        s4                   count;              /* recursive lock count          */
-       mutex_t              mutex;              /* mutex for synchronizing       */
+       Mutex*               mutex;              /* mutex for synchronizing       */
        list_t              *waiters;            /* list of threads waiting       */
        lock_record_t       *hashlink;           /* next record in hash chain     */
 };
@@ -84,7 +88,7 @@ struct lock_record_t {
 *******************************************************************************/
 
 struct lock_hashtable_t {
-       mutex_t              mutex;       /* mutex for synch. access to the table */
+    Mutex*               mutex;       /* mutex for synch. access to the table */
        u4                   size;        /* number of slots                      */
        u4                   entries;     /* current number of entries            */
        lock_record_t      **ptr;         /* the table of slots, uses ext. chain. */
@@ -101,6 +105,10 @@ struct lock_hashtable_t {
 #define LOCK_WAIT_FOREVER(o)     lock_wait_for_object((java_handle_t *) LLNI_QUICKWRAP(o), 0, 0)
 #define LOCK_NOTIFY(o)           lock_notify_object((java_handle_t *) LLNI_QUICKWRAP(o))
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _LOCK_H */
 
 
diff --git a/src/threads/posix/mutex-posix.h b/src/threads/posix/mutex-posix.h
deleted file mode 100644 (file)
index b178c51..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* src/threads/posix/mutex-posix.h - POSIX mutual exclusion functions
-
-   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.
-
-*/
-
-
-#ifndef _MUTEX_POSIX_H
-#define _MUTEX_POSIX_H
-
-#include "config.h"
-
-#include <pthread.h>
-
-#include "vm/vm.h"
-
-
-/* POSIX mutex object *********************************************************/
-
-typedef pthread_mutex_t mutex_t;
-
-
-/* static mutex initializer ***************************************************/
-
-#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-
-
-/* inline functions ***********************************************************/
-
-/* mutex_init ******************************************************************
-
-   Initializes the given mutex object and checks for errors.
-
-   ARGUMENTS:
-       mutex ... POSIX mutex object
-
-*******************************************************************************/
-
-inline static void mutex_init(mutex_t *mutex)
-{
-       int result;
-
-       result = pthread_mutex_init(mutex, NULL);
-
-       if (result != 0)
-               vm_abort_errnum(result, "mutex_init: pthread_mutex_init failed");
-}
-
-
-/* mutex_lock ******************************************************************
-
-   Locks the given mutex object and checks for errors. If the mutex is
-   already locked by another thread, the calling thread is suspended until
-   the mutex is unlocked.
-
-   If the mutex is already locked by the calling thread, the same applies,
-   thus effectively causing the calling thread to deadlock. (This is because
-   we use "fast" pthread mutexes without error checking.)
-
-   ARGUMENTS:
-       mutex ... POSIX mutex object
-
-*******************************************************************************/
-
-inline static void mutex_lock(mutex_t *mutex)
-{
-       int result;
-
-       result = pthread_mutex_lock(mutex);
-
-       if (result != 0)
-               vm_abort_errnum(result, "mutex_lock: pthread_mutex_lock failed");
-}
-
-
-/* mutex_unlock ****************************************************************
-
-   Unlocks the given mutex object and checks for errors. The mutex is
-   assumed to be locked and owned by the calling thread.
-
-   ARGUMENTS:
-       mutex ... POSIX mutex object
-
-*******************************************************************************/
-
-inline static void mutex_unlock(mutex_t *mutex)
-{
-       int result;
-
-       result = pthread_mutex_unlock(mutex);
-
-       if (result != 0)
-               vm_abort_errnum(result, "mutex_unlock: pthread_mutex_unlock failed");
-}
-
-
-/* mutex_destroy ***************************************************************
-
-   Destroys the given mutex object and checks for errors.
-
-   ARGUMENTS:
-       mutex ... POSIX mutex object
-
-*******************************************************************************/
-
-inline static void mutex_destroy(mutex_t *mutex)
-{
-       int result;
-
-       result = pthread_mutex_destroy(mutex);
-
-       if (result != 0)
-               vm_abort_errnum(result, "mutex_destroy: pthread_mutex_destroy failed");
-}
-
-
-#endif /* _MUTEX_POSIX_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/threads/posix/mutex-posix.hpp b/src/threads/posix/mutex-posix.hpp
new file mode 100644 (file)
index 0000000..3a262ae
--- /dev/null
@@ -0,0 +1,154 @@
+/* src/threads/posix/mutex-posix.hpp - POSIX mutual exclusion functions
+
+   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.
+
+*/
+
+
+#ifndef _MUTEX_POSIX_HPP
+#define _MUTEX_POSIX_HPP
+
+#include "config.h"
+
+#include <pthread.h>
+
+#include "vm/vm.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * POSIX implementation of a mutex.
+ */
+class Mutex {
+private:
+       // POSIX mutex structure.
+       pthread_mutex_t _mutex;
+
+       // Condition class needs to access _mutex for wait() and
+       // timedwait().
+       friend class Condition;
+       
+public:
+       Mutex();
+       ~Mutex();
+
+       void lock();
+       void unlock();
+};
+
+
+/* static mutex initializer ***************************************************/
+
+#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+
+
+/**
+ * Initializes the given mutex object and checks for errors.
+ */
+inline Mutex::Mutex()
+{
+       int result;
+
+       result = pthread_mutex_init(&_mutex, NULL);
+
+       if (result != 0)
+               vm_abort_errnum(result, "Mutex::Mutex(): pthread_mutex_init failed");
+}
+
+
+/**
+ * Destroys the given mutex object and checks for errors.
+ */
+inline Mutex::~Mutex()
+{
+       int result;
+
+       result = pthread_mutex_destroy(&_mutex);
+
+       if (result != 0)
+               vm_abort_errnum(result, "Mutex::~Mutex(): pthread_mutex_destroy failed");
+}
+
+
+/**
+ * Locks the given mutex object and checks for errors. If the mutex is
+ * already locked by another thread, the calling thread is suspended until
+ * the mutex is unlocked.
+ *
+ * If the mutex is already locked by the calling thread, the same applies,
+ * thus effectively causing the calling thread to deadlock. (This is because
+ * we use "fast" pthread mutexes without error checking.)
+ */
+inline void Mutex::lock()
+{
+       int result;
+
+       result = pthread_mutex_lock(&_mutex);
+
+       if (result != 0)
+               vm_abort_errnum(result, "Mutex::lock(): pthread_mutex_lock failed");
+}
+
+
+/**
+ * Unlocks the given mutex object and checks for errors. The mutex is
+ * assumed to be locked and owned by the calling thread.
+ */
+inline void Mutex::unlock()
+{
+       int result;
+
+       result = pthread_mutex_unlock(&_mutex);
+
+       if (result != 0)
+               vm_abort_errnum(result, "Mutex::unlock: pthread_mutex_unlock failed");
+}
+
+#else
+
+// This structure must have the same layout as the class above.
+typedef struct Mutex {
+       pthread_mutex_t _mutex;
+} Mutex;
+
+Mutex* Mutex_new();
+void   Mutex_delete(Mutex* mutex);
+void   Mutex_lock(Mutex* mutex);
+void   Mutex_unlock(Mutex* mutex);
+
+#endif
+
+#endif /* _MUTEX_POSIX_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:
+ */
diff --git a/src/threads/posix/thread-posix.c b/src/threads/posix/thread-posix.c
deleted file mode 100644 (file)
index d64e18d..0000000
+++ /dev/null
@@ -1,1853 +0,0 @@
-/* src/threads/posix/thread-posix.c - POSIX thread 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"
-
-/* XXX cleanup these includes */
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <time.h>
-#include <errno.h>
-
-#include <pthread.h>
-
-#include "vm/types.h"
-
-#include "arch.h"
-
-#if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
-# include "machine-instr.h"
-#else
-# include "threads/posix/generic-primitives.h"
-#endif
-
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#if defined(ENABLE_GC_CACAO)
-# include "mm/cacao-gc/gc.h"
-#endif
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
-#include "native/include/java_lang_Thread.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_ThreadGroup.h"
-#endif
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# include "native/include/java_lang_VMThread.h"
-#endif
-
-#include "threads/lock-common.h"
-#include "threads/mutex.h"
-#include "threads/threadlist.h"
-#include "threads/thread.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/asmpart.h"
-
-#include "vmcore/options.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#if !defined(__DARWIN__)
-# include <semaphore.h>
-#endif
-
-#if defined(__LINUX__)
-# define GC_LINUX_THREADS
-#elif defined(__IRIX__)
-# define GC_IRIX_THREADS
-#elif defined(__DARWIN__)
-# define GC_DARWIN_THREADS
-#endif
-
-#if defined(ENABLE_GC_BOEHM)
-/* We need to include Boehm's gc.h here because it overrides
-   pthread_create and friends. */
-# include "mm/boehm-gc/include/gc.h"
-#endif
-
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/cacaodbg.h"
-#endif
-
-#if defined(__DARWIN__)
-/* Darwin has no working semaphore implementation.  This one is taken
-   from Boehm-GC. */
-
-/*
-   This is a very simple semaphore implementation for darwin. It
-   is implemented in terms of pthreads calls so it isn't async signal
-   safe. This isn't a problem because signals aren't used to
-   suspend threads on darwin.
-*/
-   
-static int sem_init(sem_t *sem, int pshared, int value)
-{
-       if (pshared)
-               assert(0);
-
-       sem->value = value;
-    
-       mutex_init(&sem->mutex);
-
-       if (pthread_cond_init(&sem->cond, NULL) < 0)
-               return -1;
-
-       return 0;
-}
-
-static int sem_post(sem_t *sem)
-{
-       mutex_lock(&sem->mutex);
-
-       sem->value++;
-
-       if (pthread_cond_signal(&sem->cond) < 0) {
-               mutex_unlock(&sem->mutex);
-               return -1;
-       }
-
-       mutex_unlock(&sem->mutex);
-
-       return 0;
-}
-
-static int sem_wait(sem_t *sem)
-{
-       mutex_lock(&sem->mutex);
-
-       while (sem->value == 0) {
-               pthread_cond_wait(&sem->cond, &sem->mutex);
-       }
-
-       sem->value--;
-
-       mutex_unlock(&sem->mutex);
-
-       return 0;
-}
-
-static int sem_destroy(sem_t *sem)
-{
-       if (pthread_cond_destroy(&sem->cond) < 0)
-               return -1;
-
-       mutex_destroy(&sem->mutex);
-
-       return 0;
-}
-#endif /* defined(__DARWIN__) */
-
-
-/* internally used constants **************************************************/
-
-/* CAUTION: Do not change these values. Boehm GC code depends on them.        */
-#define STOPWORLD_FROM_GC               1
-#define STOPWORLD_FROM_CLASS_NUMBERING  2
-
-
-/* startupinfo *****************************************************************
-
-   Struct used to pass info from threads_start_thread to 
-   threads_startup_thread.
-
-******************************************************************************/
-
-typedef struct {
-       threadobject *thread;      /* threadobject for this thread             */
-       functionptr   function;    /* function to run in the new thread        */
-       sem_t        *psem;        /* signals when thread has been entered     */
-                                  /* in the thread list                       */
-       sem_t        *psem_first;  /* signals when pthread_create has returned */
-} startupinfo;
-
-
-/* prototypes *****************************************************************/
-
-static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
-
-
-/******************************************************************************/
-/* GLOBAL VARIABLES                                                           */
-/******************************************************************************/
-
-/* the thread object of the current thread                                    */
-/* This is either a thread-local variable defined with __thread, or           */
-/* a thread-specific value stored with key threads_current_threadobject_key.  */
-#if defined(HAVE___THREAD)
-__thread threadobject *thread_current;
-#else
-pthread_key_t thread_current_key;
-#endif
-
-/* global mutex for stop-the-world                                            */
-static mutex_t stopworldlock;
-
-#if defined(ENABLE_GC_CACAO)
-/* global mutex for the GC */
-static mutex_t mutex_gc;
-#endif
-
-/* global mutex and condition for joining threads on exit */
-static mutex_t mutex_join;
-static pthread_cond_t  cond_join;
-
-/* this is one of the STOPWORLD_FROM_ constants, telling why the world is     */
-/* being stopped                                                              */
-static volatile int stopworldwhere;
-
-#if defined(ENABLE_GC_CACAO)
-
-/* semaphore used for acknowleding thread suspension                          */
-static sem_t suspend_ack;
-#if defined(__IRIX__)
-static mutex_t suspend_ack_lock = MUTEX_INITIALIZER;
-static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
-#endif
-
-#endif /* ENABLE_GC_CACAO */
-
-/* mutexes used by the fake atomic instructions                               */
-#if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
-mutex_t _cas_lock = MUTEX_INITIALIZER;
-mutex_t _mb_lock = MUTEX_INITIALIZER;
-#endif
-
-
-/* threads_sem_init ************************************************************
-   Initialize a semaphore. Checks against errors and interruptions.
-
-   IN:
-       sem..............the semaphore to initialize
-          shared...........true if this semaphore will be shared between processes
-          value............the initial value for the semaphore
-   
-*******************************************************************************/
-
-void threads_sem_init(sem_t *sem, bool shared, int value)
-{
-       int r;
-
-       assert(sem);
-
-       do {
-               r = sem_init(sem, shared, value);
-               if (r == 0)
-                       return;
-       } while (errno == EINTR);
-
-       vm_abort("sem_init failed: %s", strerror(errno));
-}
-
-
-/* threads_sem_wait ************************************************************
-   Wait for a semaphore, non-interruptible.
-
-   IMPORTANT: Always use this function instead of `sem_wait` directly, as
-              `sem_wait` may be interrupted by signals!
-  
-   IN:
-       sem..............the semaphore to wait on
-   
-*******************************************************************************/
-
-void threads_sem_wait(sem_t *sem)
-{
-       int r;
-
-       assert(sem);
-
-       do {
-               r = sem_wait(sem);
-               if (r == 0)
-                       return;
-       } while (errno == EINTR);
-
-       vm_abort("sem_wait failed: %s", strerror(errno));
-}
-
-
-/* threads_sem_post ************************************************************
-   Increase the count of a semaphore. Checks for errors.
-
-   IN:
-       sem..............the semaphore to increase the count of
-   
-*******************************************************************************/
-
-void threads_sem_post(sem_t *sem)
-{
-       int r;
-
-       assert(sem);
-
-       /* unlike sem_wait, sem_post is not interruptible */
-
-       r = sem_post(sem);
-       if (r == 0)
-               return;
-
-       vm_abort("sem_post failed: %s", strerror(errno));
-}
-
-
-/* lock_stopworld **************************************************************
-
-   Enter the stopworld lock, specifying why the world shall be stopped.
-
-   IN:
-      where........ STOPWORLD_FROM_GC              (1) from within GC
-                    STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
-
-******************************************************************************/
-
-void lock_stopworld(int where)
-{
-       mutex_lock(&stopworldlock);
-/*     stopworldwhere = where; */
-}
-
-
-/* unlock_stopworld ************************************************************
-
-   Release the stopworld lock.
-
-******************************************************************************/
-
-void unlock_stopworld(void)
-{
-/*     stopworldwhere = 0; */
-       mutex_unlock(&stopworldlock);
-}
-
-/* XXX We disable that whole bunch of code until we have the exact-GC
-   running. Some of it may only be needed by the old Boehm-based
-   suspension handling. */
-
-#if 0
-
-#if !defined(__DARWIN__)
-/* Caller must hold threadlistlock */
-static s4 threads_cast_sendsignals(s4 sig)
-{
-       threadobject *t;
-       threadobject *self;
-       s4            count;
-
-       self = THREADOBJECT;
-
-       /* iterate over all started threads */
-
-       count = 0;
-
-       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
-               /* don't send the signal to ourself */
-
-               if (t == self)
-                       continue;
-
-               /* don't send the signal to NEW threads (because they are not
-                  completely initialized) */
-
-               if (t->state == THREAD_STATE_NEW)
-                       continue;
-
-               /* send the signal */
-
-               pthread_kill(t->tid, sig);
-
-               /* increase threads count */
-
-               count++;
-       }
-
-       return count;
-}
-
-#else
-
-static void threads_cast_darwinstop(void)
-{
-       threadobject *tobj = mainthreadobj;
-       threadobject *self = THREADOBJECT;
-
-       do {
-               if (tobj != self)
-               {
-                       thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
-                       mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
-#if defined(__I386__)
-                       i386_thread_state_t thread_state;
-#else
-                       ppc_thread_state_t thread_state;
-#endif
-                       mach_port_t thread = tobj->mach_thread;
-                       kern_return_t r;
-
-                       r = thread_suspend(thread);
-
-                       if (r != KERN_SUCCESS)
-                               vm_abort("thread_suspend failed");
-
-                       r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
-                                                                &thread_state_count);
-
-                       if (r != KERN_SUCCESS)
-                               vm_abort("thread_get_state failed");
-
-                       md_critical_section_restart((ucontext_t *) &thread_state);
-
-                       r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
-                                                                thread_state_count);
-
-                       if (r != KERN_SUCCESS)
-                               vm_abort("thread_set_state failed");
-               }
-
-               tobj = tobj->next;
-       } while (tobj != mainthreadobj);
-}
-
-static void threads_cast_darwinresume(void)
-{
-       threadobject *tobj = mainthreadobj;
-       threadobject *self = THREADOBJECT;
-
-       do {
-               if (tobj != self)
-               {
-                       mach_port_t thread = tobj->mach_thread;
-                       kern_return_t r;
-
-                       r = thread_resume(thread);
-
-                       if (r != KERN_SUCCESS)
-                               vm_abort("thread_resume failed");
-               }
-
-               tobj = tobj->next;
-       } while (tobj != mainthreadobj);
-}
-
-#endif
-
-#if defined(__IRIX__)
-static void threads_cast_irixresume(void)
-{
-       mutex_lock(&suspend_ack_lock);
-       pthread_cond_broadcast(&suspend_cond);
-       mutex_unlock(&suspend_ack_lock);
-}
-#endif
-
-#if defined(ENABLE_GC_BOEHM) && !defined(__DARWIN__)
-static void threads_sigsuspend_handler(ucontext_t *_uc)
-{
-       int sig;
-       sigset_t sigs;
-
-       /* XXX TWISTI: this is just a quick hack */
-#if defined(ENABLE_JIT)
-       md_critical_section_restart(_uc);
-#endif
-
-       /* Do as Boehm does. On IRIX a condition variable is used for wake-up
-          (not POSIX async-safe). */
-#if defined(__IRIX__)
-       mutex_lock(&suspend_ack_lock);
-       threads_sem_post(&suspend_ack);
-       pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
-       mutex_unlock(&suspend_ack_lock);
-#elif defined(__CYGWIN__)
-       /* TODO */
-       assert(0);
-#else
-
-       sig = GC_signum2();
-       sigfillset(&sigs);
-       sigdelset(&sigs, sig);
-       sigsuspend(&sigs);
-#endif
-}
-#endif
-
-
-/* threads_stopworld ***********************************************************
-
-   Stops the world from turning. All threads except the calling one
-   are suspended. The function returns as soon as all threads have
-   acknowledged their suspension.
-
-*******************************************************************************/
-
-void threads_stopworld(void)
-{
-#if !defined(__DARWIN__) && !defined(__CYGWIN__)
-       threadobject *t;
-       threadobject *self;
-       bool result;
-       s4 count, i;
-#endif
-
-       lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
-
-       /* lock the threads lists */
-
-       threadlist_lock();
-
-#if defined(__DARWIN__)
-       /*threads_cast_darwinstop();*/
-       assert(0);
-#elif defined(__CYGWIN__)
-       /* TODO */
-       assert(0);
-#else
-       self = THREADOBJECT;
-
-       DEBUGTHREADS("stops World", self);
-
-       count = 0;
-
-       /* suspend all running threads */
-       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
-               /* don't send the signal to ourself */
-
-               if (t == self)
-                       continue;
-
-               /* don't send the signal to NEW threads (because they are not
-                  completely initialized) */
-
-               if (t->state == THREAD_STATE_NEW)
-                       continue;
-
-               /* send the signal */
-
-               result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
-               assert(result);
-
-               /* increase threads count */
-
-               count++;
-       }
-
-       /* wait for all threads signaled to suspend */
-       for (i = 0; i < count; i++)
-               threads_sem_wait(&suspend_ack);
-#endif
-
-       /* ATTENTION: Don't unlock the threads-lists here so that
-          non-signaled NEW threads can't change their state and execute
-          code. */
-}
-
-
-/* threads_startworld **********************************************************
-
-   Starts the world again after it has previously been stopped. 
-
-*******************************************************************************/
-
-void threads_startworld(void)
-{
-#if !defined(__DARWIN__) && !defined(__CYGWIN__)
-       threadobject *t;
-       threadobject *self;
-       bool result;
-       s4 count, i;
-#endif
-
-#if defined(__DARWIN__)
-       /*threads_cast_darwinresume();*/
-       assert(0);
-#elif defined(__IRIX__)
-       threads_cast_irixresume();
-#elif defined(__CYGWIN__)
-       /* TODO */
-       assert(0);
-#else
-       self = THREADOBJECT;
-
-       DEBUGTHREADS("starts World", self);
-
-       count = 0;
-
-       /* resume all thread we haltet */
-       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
-               /* don't send the signal to ourself */
-
-               if (t == self)
-                       continue;
-
-               /* don't send the signal to NEW threads (because they are not
-                  completely initialized) */
-
-               if (t->state == THREAD_STATE_NEW)
-                       continue;
-
-               /* send the signal */
-
-               result = threads_resume_thread(t);
-               assert(result);
-
-               /* increase threads count */
-
-               count++;
-       }
-
-       /* wait for all threads signaled to suspend */
-       for (i = 0; i < count; i++)
-               threads_sem_wait(&suspend_ack);
-
-#endif
-
-       /* unlock the threads lists */
-
-       threadlist_unlock();
-
-       unlock_stopworld();
-}
-
-#endif
-
-
-/* threads_impl_thread_init ****************************************************
-
-   Initialize OS-level locking constructs in threadobject.
-
-   IN:
-      t....the threadobject
-
-*******************************************************************************/
-
-void threads_impl_thread_init(threadobject *t)
-{
-       int result;
-
-       /* initialize the mutex and the condition */
-
-       mutex_init(&t->flc_lock);
-
-       result = pthread_cond_init(&t->flc_cond, NULL);
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
-
-       mutex_init(&(t->waitmutex));
-
-       result = pthread_cond_init(&(t->waitcond), NULL);
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
-
-       mutex_init(&(t->suspendmutex));
-
-       result = pthread_cond_init(&(t->suspendcond), NULL);
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
-}
-
-/* threads_impl_thread_clear ***************************************************
-
-   Clears all fields in threadobject the way an MZERO would have
-   done. MZERO cannot be used anymore because it would mess up the
-   pthread_* bits.
-
-   IN:
-      t....the threadobject
-
-*******************************************************************************/
-
-void threads_impl_thread_clear(threadobject *t)
-{
-       t->object = NULL;
-
-       t->thinlock = 0;
-
-       t->index = 0;
-       t->flags = 0;
-       t->state = 0;
-
-       t->tid = 0;
-
-#if defined(__DARWIN__)
-       t->mach_thread = 0;
-#endif
-
-       t->interrupted = false;
-       t->signaled = false;
-
-       t->suspended = false;
-       t->suspend_reason = 0;
-
-       t->pc = NULL;
-
-       t->_exceptionptr = NULL;
-       t->_stackframeinfo = NULL;
-       t->_localref_table = NULL;
-
-#if defined(ENABLE_INTRP)
-       t->_global_sp = NULL;
-#endif
-
-#if defined(ENABLE_GC_CACAO)
-       t->gc_critical = false;
-
-       t->ss = NULL;
-       t->es = NULL;
-#endif
-
-       MZERO(&t->dumpinfo, dumpinfo_t, 1);
-}
-
-/* threads_impl_thread_reuse ***************************************************
-
-   Resets some implementation fields in threadobject. This was
-   previously done in threads_impl_thread_new.
-
-   IN:
-      t....the threadobject
-
-*******************************************************************************/
-
-void threads_impl_thread_reuse(threadobject *t)
-{
-       /* get the pthread id */
-
-       t->tid = pthread_self();
-
-#if defined(ENABLE_DEBUG_FILTER)
-       /* Initialize filter counters */
-       t->filterverbosecallctr[0] = 0;
-       t->filterverbosecallctr[1] = 0;
-#endif
-
-#if !defined(NDEBUG)
-       t->tracejavacallindent = 0;
-       t->tracejavacallcount = 0;
-#endif
-
-       t->flc_bit = false;
-       t->flc_next = NULL;
-       t->flc_list = NULL;
-
-/*     not really needed */
-       t->flc_object = NULL;
-}
-
-
-/* threads_impl_thread_free ****************************************************
-
-   Cleanup thread stuff.
-
-   IN:
-      t....the threadobject
-
-*******************************************************************************/
-
-#if 0
-/* never used */
-void threads_impl_thread_free(threadobject *t)
-{
-       int result;
-
-       /* Destroy the mutex and the condition. */
-
-       mutex_destroy(&(t->flc_lock));
-
-       result = pthread_cond_destroy(&(t->flc_cond));
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
-
-       mutex_destroy(&(t->waitmutex));
-
-       result = pthread_cond_destroy(&(t->waitcond));
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
-
-       mutex_destroy(&(t->suspendmutex));
-
-       result = pthread_cond_destroy(&(t->suspendcond));
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
-}
-#endif
-
-
-/* threads_impl_preinit ********************************************************
-
-   Do some early initialization of stuff required.
-
-   ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
-   is called AFTER this function!
-
-*******************************************************************************/
-
-void threads_impl_preinit(void)
-{
-       int result;
-
-       mutex_init(&stopworldlock);
-
-       /* initialize exit mutex and condition (on exit we join all
-          threads) */
-
-       mutex_init(&mutex_join);
-
-       result = pthread_cond_init(&cond_join, NULL);
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
-
-#if defined(ENABLE_GC_CACAO)
-       /* initialize the GC mutex & suspend semaphore */
-
-       mutex_init(&mutex_gc);
-       threads_sem_init(&suspend_ack, 0, 0);
-#endif
-
-#if !defined(HAVE___THREAD)
-       result = pthread_key_create(&thread_current_key, NULL);
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
-#endif
-}
-
-
-/* threads_mutex_gc_lock *******************************************************
-
-   Enter the global GC mutex.
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-void threads_mutex_gc_lock(void)
-{
-       mutex_lock(&mutex_gc);
-}
-#endif
-
-
-/* threads_mutex_gc_unlock *****************************************************
-
-   Leave the global GC mutex.
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-void threads_mutex_gc_unlock(void)
-{
-       mutex_unlock(&mutex_gc);
-}
-#endif
-
-/* threads_mutex_join_lock *****************************************************
-
-   Enter the join mutex.
-
-*******************************************************************************/
-
-void threads_mutex_join_lock(void)
-{
-       mutex_lock(&mutex_join);
-}
-
-
-/* threads_mutex_join_unlock ***************************************************
-
-   Leave the join mutex.
-
-*******************************************************************************/
-
-void threads_mutex_join_unlock(void)
-{
-       mutex_unlock(&mutex_join);
-}
-
-
-/* threads_impl_init ***********************************************************
-
-   Initializes the implementation specific bits.
-
-*******************************************************************************/
-
-void threads_impl_init(void)
-{
-       pthread_attr_t attr;
-       int            result;
-
-       threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
-
-       /* Initialize the thread attribute object. */
-
-       result = pthread_attr_init(&attr);
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
-
-       result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
-}
-
-
-/* threads_startup_thread ******************************************************
-
-   Thread startup function called by pthread_create.
-
-   Thread which have a startup.function != NULL are marked as internal
-   threads. All other threads are threated as normal Java threads.
-
-   NOTE: This function is not called directly by pthread_create. The Boehm GC
-         inserts its own GC_start_routine in between, which then calls
-                threads_startup.
-
-   IN:
-      arg..........the argument passed to pthread_create, ie. a pointer to
-                      a startupinfo struct. CAUTION: When the `psem` semaphore
-                                  is posted, the startupinfo struct becomes invalid! (It
-                                  is allocated on the stack of threads_start_thread.)
-
-******************************************************************************/
-
-static void *threads_startup_thread(void *arg)
-{
-       startupinfo        *startup;
-       threadobject       *t;
-       java_lang_Thread   *object;
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_VMThread *vmt;
-#endif
-       sem_t              *psem;
-       classinfo          *c;
-       methodinfo         *m;
-       java_handle_t      *o;
-       functionptr         function;
-
-#if defined(ENABLE_GC_BOEHM)
-# if !defined(__DARWIN__)
-       struct GC_stack_base sb;
-       int result;
-# endif
-#endif
-
-#if defined(ENABLE_INTRP)
-       u1 *intrp_thread_stack;
-#endif
-
-#if defined(ENABLE_INTRP)
-       /* create interpreter stack */
-
-       if (opt_intrp) {
-               intrp_thread_stack = GCMNEW(u1, opt_stacksize);
-               MSET(intrp_thread_stack, 0, u1, opt_stacksize);
-       }
-       else
-               intrp_thread_stack = NULL;
-#endif
-
-       /* get passed startupinfo structure and the values in there */
-
-       startup = arg;
-
-       t        = startup->thread;
-       function = startup->function;
-       psem     = startup->psem;
-
-       /* Seems like we've encountered a situation where thread->tid was
-          not set by pthread_create. We alleviate this problem by waiting
-          for pthread_create to return. */
-
-       threads_sem_wait(startup->psem_first);
-
-#if defined(__DARWIN__)
-       t->mach_thread = mach_thread_self();
-#endif
-
-       /* Now that we are in the new thread, we can store the internal
-          thread data-structure in the TSD. */
-
-       thread_set_current(t);
-
-#if defined(ENABLE_GC_BOEHM)
-# if defined(__DARWIN__)
-       // This is currently not implemented in Boehm-GC.  Just fail silently.
-# else
-       /* Register the thread with Boehm-GC.  This must happen before the
-          thread allocates any memory from the GC heap.*/
-
-       result = GC_get_stack_base(&sb);
-
-       if (result != 0)
-               vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
-
-       GC_register_my_thread(&sb);
-# endif
-#endif
-
-       /* get the java.lang.Thread object for this thread */
-
-       object = (java_lang_Thread *) thread_get_object(t);
-
-       /* set our priority */
-
-       threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
-
-       /* Thread is completely initialized. */
-
-       thread_set_state_runnable(t);
-
-       /* tell threads_startup_thread that we registered ourselves */
-       /* CAUTION: *startup becomes invalid with this!             */
-
-       startup = NULL;
-       threads_sem_post(psem);
-
-#if defined(ENABLE_INTRP)
-       /* set interpreter stack */
-
-       if (opt_intrp)
-               thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
-#endif
-
-#if defined(ENABLE_JVMTI)
-       /* fire thread start event */
-
-       if (jvmti) 
-               jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
-#endif
-
-       DEBUGTHREADS("starting", t);
-
-       /* find and run the Thread.run()V method if no other function was passed */
-
-       if (function == NULL) {
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-               /* We need to start the run method of
-                  java.lang.VMThread. Since this is a final class, we can use
-                  the class object directly. */
-
-               c = class_java_lang_VMThread;
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-               LLNI_class_get(object, c);
-#else
-# error unknown classpath configuration
-#endif
-
-               m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
-
-               if (m == NULL)
-                       vm_abort("threads_startup_thread: run() method not found in class");
-
-               /* set ThreadMXBean variables */
-
-               _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
-               _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
-
-               if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
-                       _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
-                       _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
-                               _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-               /* we need to start the run method of java.lang.VMThread */
-
-               LLNI_field_get_ref(object, vmThread, vmt);
-               o = (java_handle_t *) vmt;
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-               o = (java_handle_t *) object;
-#else
-# error unknown classpath configuration
-#endif
-
-               /* Run the thread. */
-
-               (void) vm_call_method(m, o);
-       }
-       else {
-               /* set ThreadMXBean variables */
-
-               _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
-               _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
-
-               if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
-                       _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
-                       _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
-                               _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
-
-               /* call passed function, e.g. finalizer_thread */
-
-               (function)();
-       }
-
-       DEBUGTHREADS("stopping", t);
-
-#if defined(ENABLE_JVMTI)
-       /* fire thread end event */
-
-       if (jvmti)
-               jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
-#endif
-
-       /* We ignore the return value. */
-
-       (void) thread_detach_current_thread();
-
-       /* set ThreadMXBean variables */
-
-       _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
-
-       return NULL;
-}
-
-
-/* threads_impl_thread_start ***************************************************
-
-   Start a thread in the JVM.  Both (vm internal and java) thread
-   objects exist.
-
-   IN:
-      thread....the thread object
-         f.........function to run in the new thread. NULL means that the
-                   "run" method of the object `t` should be called
-
-******************************************************************************/
-
-void threads_impl_thread_start(threadobject *thread, functionptr f)
-{
-       sem_t          sem;
-       sem_t          sem_first;
-       pthread_attr_t attr;
-       startupinfo    startup;
-       int            result;
-
-       /* fill startupinfo structure passed by pthread_create to
-        * threads_startup_thread */
-
-       startup.thread     = thread;
-       startup.function   = f;              /* maybe we don't call Thread.run()V */
-       startup.psem       = &sem;
-       startup.psem_first = &sem_first;
-
-       threads_sem_init(&sem, 0, 0);
-       threads_sem_init(&sem_first, 0, 0);
-
-       /* Initialize thread attributes. */
-
-       result = pthread_attr_init(&attr);
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
-
-    result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-    if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
-
-       /* initialize thread stacksize */
-
-       result = pthread_attr_setstacksize(&attr, opt_stacksize);
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
-
-       /* create the thread */
-
-       result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
-
-       /* destroy the thread attributes */
-
-       result = pthread_attr_destroy(&attr);
-
-       if (result != 0)
-               vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
-
-       /* signal that pthread_create has returned, so thread->tid is valid */
-
-       threads_sem_post(&sem_first);
-
-       /* wait here until the thread has entered itself into the thread list */
-
-       threads_sem_wait(&sem);
-
-       /* cleanup */
-
-       sem_destroy(&sem);
-       sem_destroy(&sem_first);
-}
-
-
-/* threads_set_thread_priority *************************************************
-
-   Set the priority of the given thread.
-
-   IN:
-      tid..........thread id
-         priority.....priority to set
-
-******************************************************************************/
-
-void threads_set_thread_priority(pthread_t tid, int priority)
-{
-       struct sched_param schedp;
-       int policy;
-
-       pthread_getschedparam(tid, &policy, &schedp);
-       schedp.sched_priority = priority;
-       pthread_setschedparam(tid, policy, &schedp);
-}
-
-
-/**
- * Detaches the current thread from the VM.
- *
- * @return true on success, false otherwise
- */
-bool thread_detach_current_thread(void)
-{
-       threadobject          *t;
-       bool                   result;
-       java_lang_Thread      *object;
-       java_handle_t         *o;
-#if defined(ENABLE_JAVASE)
-       java_lang_ThreadGroup *group;
-       java_handle_t         *e;
-       void                  *handler;
-       classinfo             *c;
-       methodinfo            *m;
-#endif
-
-       t = thread_get_current();
-
-       /* Sanity check. */
-
-       assert(t != NULL);
-
-    /* If the given thread has already been detached, this operation
-          is a no-op. */
-
-       result = thread_is_attached(t);
-
-       if (result == false)
-               return true;
-
-       DEBUGTHREADS("detaching", t);
-
-       object = (java_lang_Thread *) thread_get_object(t);
-
-#if defined(ENABLE_JAVASE)
-       LLNI_field_get_ref(object, group, group);
-
-    /* If there's an uncaught exception, call uncaughtException on the
-       thread's exception handler, or the thread's group if this is
-       unset. */
-
-       e = exceptions_get_and_clear_exception();
-
-    if (e != NULL) {
-               /* We use the type void* for handler here, as it's not trivial
-                  to build the java_lang_Thread_UncaughtExceptionHandler
-                  header file with cacaoh. */
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-               LLNI_field_get_ref(object, exceptionHandler, handler);
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-               LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
-# endif
-
-               if (handler != NULL) {
-                       LLNI_class_get(handler, c);
-                       o = (java_handle_t *) handler;
-               }
-               else {
-                       LLNI_class_get(group, c);
-                       o = (java_handle_t *) group;
-               }
-
-               m = class_resolveclassmethod(c,
-                                                                        utf_uncaughtException,
-                                                                        utf_java_lang_Thread_java_lang_Throwable__V,
-                                                                        NULL,
-                                                                        true);
-
-               if (m == NULL)
-                       return false;
-
-               (void) vm_call_method(m, o, object, e);
-
-               if (exceptions_get_exception())
-                       return false;
-    }
-
-       /* XXX TWISTI: should all threads be in a ThreadGroup? */
-
-       /* Remove thread from the thread group. */
-
-       if (group != NULL) {
-               LLNI_class_get(group, c);
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-               m = class_resolveclassmethod(c,
-                                                                        utf_removeThread,
-                                                                        utf_java_lang_Thread__V,
-                                                                        class_java_lang_ThreadGroup,
-                                                                        true);
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-               m = class_resolveclassmethod(c,
-                                                                        utf_remove,
-                                                                        utf_java_lang_Thread__V,
-                                                                        class_java_lang_ThreadGroup,
-                                                                        true);
-# else
-#  error unknown classpath configuration
-# endif
-
-               if (m == NULL)
-                       return false;
-
-               o = (java_handle_t *) group;
-
-               (void) vm_call_method(m, o, object);
-
-               if (exceptions_get_exception())
-                       return false;
-
-               /* Reset the threadgroup in the Java thread object (Mauve
-                  test: gnu/testlet/java/lang/Thread/getThreadGroup). */
-
-               LLNI_field_set_ref(object, group, NULL);
-       }
-#endif
-
-       /* Thread has terminated. */
-
-       thread_set_state_terminated(t);
-
-       /* Notify all threads waiting on this thread.  These are joining
-          this thread. */
-
-       o = (java_handle_t *) object;
-
-       /* XXX Care about exceptions? */
-       (void) lock_monitor_enter(o);
-       
-       lock_notify_all_object(o);
-
-       /* XXX Care about exceptions? */
-       (void) lock_monitor_exit(o);
-
-       /* Enter the join-mutex before calling thread_free, so
-          threads_join_all_threads gets the correct number of non-daemon
-          threads. */
-
-       threads_mutex_join_lock();
-
-       /* Free the internal thread data-structure. */
-
-       thread_free(t);
-
-       /* Signal that this thread has finished and leave the mutex. */
-
-       pthread_cond_signal(&cond_join);
-       threads_mutex_join_unlock();
-
-       return true;
-}
-
-
-#if defined(ENABLE_GC_CACAO)
-
-/* threads_suspend_thread ******************************************************
-
-   Suspend the passed thread. Execution stops until the thread
-   is explicitly resumend again.
-
-   IN:
-     reason.....Reason for suspending this thread.
-
-*******************************************************************************/
-
-bool threads_suspend_thread(threadobject *thread, s4 reason)
-{
-       /* acquire the suspendmutex */
-       mutex_lock(&(thread->suspendmutex));
-
-       if (thread->suspended) {
-               mutex_unlock(&(thread->suspendmutex));
-               return false;
-       }
-
-       /* set the reason for the suspension */
-       thread->suspend_reason = reason;
-
-       /* send the suspend signal to the thread */
-       assert(thread != THREADOBJECT);
-       if (pthread_kill(thread->tid, SIGUSR1) != 0)
-               vm_abort("threads_suspend_thread: pthread_kill failed: %s",
-                                strerror(errno));
-
-       /* REMEMBER: do not release the suspendmutex, this is done
-          by the thread itself in threads_suspend_ack().  */
-
-       return true;
-}
-
-
-/* threads_suspend_ack *********************************************************
-
-   Acknowledges the suspension of the current thread.
-
-   IN:
-     pc.....The PC where the thread suspended its execution.
-     sp.....The SP before the thread suspended its execution.
-
-*******************************************************************************/
-
-void threads_suspend_ack(u1* pc, u1* sp)
-{
-       threadobject *thread;
-
-       thread = THREADOBJECT;
-
-       assert(thread->suspend_reason != 0);
-
-       /* TODO: remember dump memory size */
-
-       /* inform the GC about the suspension */
-       if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
-
-               /* check if the GC wants to leave the thread running */
-               if (!gc_suspend(thread, pc, sp)) {
-
-                       /* REMEMBER: we do not unlock the suspendmutex because the thread
-                          will suspend itself again at a later time */
-                       return;
-
-               }
-       }
-
-       /* mark this thread as suspended and remember the PC */
-       thread->pc        = pc;
-       thread->suspended = true;
-
-       /* if we are stopping the world, we should send a global ack */
-       if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
-               threads_sem_post(&suspend_ack);
-       }
-
-       DEBUGTHREADS("suspending", thread);
-
-       /* release the suspension mutex and wait till we are resumed */
-       pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
-
-       DEBUGTHREADS("resuming", thread);
-
-       /* if we are stopping the world, we should send a global ack */
-       if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
-               threads_sem_post(&suspend_ack);
-       }
-
-       /* TODO: free dump memory */
-
-       /* release the suspendmutex */
-       mutex_unlock(&(thread->suspendmutex));
-}
-
-
-/* threads_resume_thread *******************************************************
-
-   Resumes the execution of the passed thread.
-
-*******************************************************************************/
-
-bool threads_resume_thread(threadobject *thread)
-{
-       /* acquire the suspendmutex */
-       mutex_lock(&(thread->suspendmutex));
-
-       if (!thread->suspended) {
-               mutex_unlock(&(thread->suspendmutex));
-               return false;
-       }
-
-       thread->suspended = false;
-
-       /* tell everyone that the thread should resume */
-       assert(thread != THREADOBJECT);
-       pthread_cond_broadcast(&(thread->suspendcond));
-
-       /* release the suspendmutex */
-       mutex_unlock(&(thread->suspendmutex));
-
-       return true;
-}
-
-#endif
-
-/* threads_join_all_threads ****************************************************
-
-   Join all non-daemon threads.
-
-*******************************************************************************/
-
-void threads_join_all_threads(void)
-{
-       threadobject *t;
-
-       /* get current thread */
-
-       t = THREADOBJECT;
-
-       /* This thread is waiting for all non-daemon threads to exit. */
-
-       thread_set_state_waiting(t);
-
-       /* enter join mutex */
-
-       threads_mutex_join_lock();
-
-       /* Wait for condition as long as we have non-daemon threads.  We
-          compare against 1 because the current (main thread) is also a
-          non-daemon thread. */
-
-       while (threadlist_get_non_daemons() > 1)
-               pthread_cond_wait(&cond_join, &mutex_join);
-
-       /* leave join mutex */
-
-       threads_mutex_join_unlock();
-}
-
-
-/* threads_timespec_earlier ****************************************************
-
-   Return true if timespec tv1 is earlier than timespec tv2.
-
-   IN:
-      tv1..........first timespec
-         tv2..........second timespec
-
-   RETURN VALUE:
-      true, if the first timespec is earlier
-
-*******************************************************************************/
-
-static inline bool threads_timespec_earlier(const struct timespec *tv1,
-                                                                                       const struct timespec *tv2)
-{
-       return (tv1->tv_sec < tv2->tv_sec)
-                               ||
-               (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
-}
-
-
-/* threads_current_time_is_earlier_than ****************************************
-
-   Check if the current time is earlier than the given timespec.
-
-   IN:
-      tv...........the timespec to compare against
-
-   RETURN VALUE:
-      true, if the current time is earlier
-
-*******************************************************************************/
-
-static bool threads_current_time_is_earlier_than(const struct timespec *tv)
-{
-       struct timeval tvnow;
-       struct timespec tsnow;
-
-       /* get current time */
-
-       if (gettimeofday(&tvnow, NULL) != 0)
-               vm_abort("gettimeofday failed: %s\n", strerror(errno));
-
-       /* convert it to a timespec */
-
-       tsnow.tv_sec = tvnow.tv_sec;
-       tsnow.tv_nsec = tvnow.tv_usec * 1000;
-
-       /* compare current time with the given timespec */
-
-       return threads_timespec_earlier(&tsnow, tv);
-}
-
-
-/* threads_wait_with_timeout ***************************************************
-
-   Wait until the given point in time on a monitor until either
-   we are notified, we are interrupted, or the time is up.
-
-   IN:
-      t............the current thread
-         wakeupTime...absolute (latest) wakeup time
-                          If both tv_sec and tv_nsec are zero, this function
-                                          waits for an unlimited amount of time.
-
-*******************************************************************************/
-
-static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
-{
-       /* acquire the waitmutex */
-
-       mutex_lock(&t->waitmutex);
-
-       /* wait on waitcond */
-
-       if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
-               /* with timeout */
-               while (!t->interrupted && !t->signaled
-                          && threads_current_time_is_earlier_than(wakeupTime))
-               {
-                       thread_set_state_timed_waiting(t);
-
-                       pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
-                                                                  wakeupTime);
-
-                       thread_set_state_runnable(t);
-               }
-       }
-       else {
-               /* no timeout */
-               while (!t->interrupted && !t->signaled) {
-                       thread_set_state_waiting(t);
-
-                       pthread_cond_wait(&t->waitcond, &t->waitmutex);
-
-                       thread_set_state_runnable(t);
-               }
-       }
-
-       /* release the waitmutex */
-
-       mutex_unlock(&t->waitmutex);
-}
-
-
-/* threads_wait_with_timeout_relative ******************************************
-
-   Wait for the given maximum amount of time on a monitor until either
-   we are notified, we are interrupted, or the time is up.
-
-   IN:
-      t............the current thread
-         millis.......milliseconds to wait
-         nanos........nanoseconds to wait
-
-*******************************************************************************/
-
-void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
-                                                                               s4 nanos)
-{
-       struct timespec wakeupTime;
-
-       /* calculate the the (latest) wakeup time */
-
-       threads_calc_absolute_time(&wakeupTime, millis, nanos);
-
-       /* wait */
-
-       threads_wait_with_timeout(thread, &wakeupTime);
-}
-
-
-/* threads_calc_absolute_time **************************************************
-
-   Calculate the absolute point in time a given number of ms and ns from now.
-
-   IN:
-      millis............milliseconds from now
-         nanos.............nanoseconds from now
-
-   OUT:
-      *tm...............receives the timespec of the absolute point in time
-
-*******************************************************************************/
-
-static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
-{
-       if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
-               struct timeval tv;
-               long nsec;
-               gettimeofday(&tv, NULL);
-               tv.tv_sec += millis / 1000;
-               millis %= 1000;
-               nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
-               tm->tv_sec = tv.tv_sec + nsec / 1000000000;
-               tm->tv_nsec = nsec % 1000000000;
-       }
-       else {
-               tm->tv_sec = 0;
-               tm->tv_nsec = 0;
-       }
-}
-
-
-/* threads_thread_interrupt ****************************************************
-
-   Interrupt the given thread.
-
-   The thread gets the "waitcond" signal and 
-   its interrupted flag is set to true.
-
-   IN:
-      thread............the thread to interrupt
-
-*******************************************************************************/
-
-void threads_thread_interrupt(threadobject *thread)
-{
-#if defined(__LINUX__) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       /* See openjdk/jdk/src/solaris/native/java/net/linux_close.c, "sigWakeup" */
-       int sig = (__SIGRTMAX - 2);
-#else
-       int sig = SIGHUP;
-#endif
-       /* Signal the thread a "waitcond" and tell it that it has been
-          interrupted. */
-
-       mutex_lock(&thread->waitmutex);
-
-       DEBUGTHREADS("interrupted", thread);
-
-       /* Interrupt blocking system call using a signal. */
-
-       pthread_kill(thread->tid, sig);
-
-       pthread_cond_signal(&thread->waitcond);
-
-       thread->interrupted = true;
-
-       mutex_unlock(&thread->waitmutex);
-}
-
-
-/* threads_sleep ***************************************************************
-
-   Sleep the current thread for the specified amount of time.
-
-*******************************************************************************/
-
-void threads_sleep(int64_t millis, int32_t nanos)
-{
-       threadobject    *t;
-       struct timespec  wakeupTime;
-       bool             interrupted;
-
-       if (millis < 0) {
-/*             exceptions_throw_illegalargumentexception("timeout value is negative"); */
-               exceptions_throw_illegalargumentexception();
-               return;
-       }
-
-       t = thread_get_current();
-
-       if (thread_is_interrupted(t) && !exceptions_get_exception()) {
-               /* Clear interrupted flag (Mauve test:
-                  gnu/testlet/java/lang/Thread/interrupt). */
-
-               thread_set_interrupted(t, false);
-
-/*             exceptions_throw_interruptedexception("sleep interrupted"); */
-               exceptions_throw_interruptedexception();
-               return;
-       }
-
-       threads_calc_absolute_time(&wakeupTime, millis, nanos);
-
-       threads_wait_with_timeout(t, &wakeupTime);
-
-       interrupted = thread_is_interrupted(t);
-
-       if (interrupted) {
-               thread_set_interrupted(t, false);
-
-               /* An other exception could have been thrown
-                  (e.g. ThreadDeathException). */
-
-               if (!exceptions_get_exception())
-                       exceptions_throw_interruptedexception();
-       }
-}
-
-
-/* threads_yield ***************************************************************
-
-   Yield to the scheduler.
-
-*******************************************************************************/
-
-void threads_yield(void)
-{
-       sched_yield();
-}
-
-
-/*
- * 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/threads/posix/thread-posix.cpp b/src/threads/posix/thread-posix.cpp
new file mode 100644 (file)
index 0000000..c896910
--- /dev/null
@@ -0,0 +1,1626 @@
+/* src/threads/posix/thread-posix.cpp - POSIX thread 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"
+
+/* XXX cleanup these includes */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include "vm/types.h"
+
+#include "arch.h"
+
+#include "mm/gc.hpp"
+#include "mm/memory.h"
+
+#if defined(ENABLE_GC_CACAO)
+# include "mm/cacao-gc/gc.h"
+#endif
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#include "threads/condition.hpp"
+#include "threads/lock-common.h"
+#include "threads/mutex.hpp"
+#include "threads/threadlist.h"
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/options.h"
+#include "vm/signallocal.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/jit/asmpart.h"
+
+#if !defined(__DARWIN__)
+# include <semaphore.h>
+#endif
+
+#if defined(__LINUX__)
+# define GC_LINUX_THREADS
+#elif defined(__IRIX__)
+# define GC_IRIX_THREADS
+#elif defined(__DARWIN__)
+# define GC_DARWIN_THREADS
+#endif
+
+#if defined(ENABLE_GC_BOEHM)
+/* We need to include Boehm's gc.h here because it overrides
+   pthread_create and friends. */
+# include "mm/boehm-gc/include/gc.h"
+#endif
+
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/cacaodbg.h"
+#endif
+
+
+// FIXME For now we export everything as C functions.
+extern "C" {
+
+#if defined(__DARWIN__)
+/* Darwin has no working semaphore implementation.  This one is taken
+   from Boehm-GC. */
+
+/*
+   This is a very simple semaphore implementation for Darwin. It
+   is implemented in terms of pthreads calls so it isn't async signal
+   safe. This isn't a problem because signals aren't used to
+   suspend threads on Darwin.
+*/
+   
+static int sem_init(sem_t *sem, int pshared, int value)
+{
+       if (pshared)
+               assert(0);
+
+       sem->mutex = new Mutex();
+       sem->cond  = new Condition();
+       sem->value = value;
+
+       return 0;
+}
+
+static int sem_post(sem_t *sem)
+{
+       sem->mutex->lock();
+       sem->value++;
+       sem->cond->signal();
+       sem->mutex->unlock();
+
+       return 0;
+}
+
+static int sem_wait(sem_t *sem)
+{
+       sem->mutex->lock();
+
+       while (sem->value == 0) {
+               sem->cond->wait(sem->mutex);
+       }
+
+       sem->value--;
+       sem->mutex->unlock();
+
+       return 0;
+}
+
+static int sem_destroy(sem_t *sem)
+{
+       delete sem->cond;
+       delete sem->mutex;
+
+       return 0;
+}
+#endif /* defined(__DARWIN__) */
+
+
+/* startupinfo *****************************************************************
+
+   Struct used to pass info from threads_start_thread to 
+   threads_startup_thread.
+
+******************************************************************************/
+
+typedef struct {
+       threadobject *thread;      /* threadobject for this thread             */
+       functionptr   function;    /* function to run in the new thread        */
+       sem_t        *psem;        /* signals when thread has been entered     */
+                                  /* in the thread list                       */
+       sem_t        *psem_first;  /* signals when pthread_create has returned */
+} startupinfo;
+
+
+/* prototypes *****************************************************************/
+
+static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
+
+
+/******************************************************************************/
+/* GLOBAL VARIABLES                                                           */
+/******************************************************************************/
+
+/* the thread object of the current thread                                    */
+/* This is either a thread-local variable defined with __thread, or           */
+/* a thread-specific value stored with key threads_current_threadobject_key.  */
+#if defined(HAVE___THREAD)
+__thread threadobject *thread_current;
+#else
+pthread_key_t thread_current_key;
+#endif
+
+/* global mutex for stop-the-world                                            */
+static Mutex* stopworldlock;
+
+#if defined(ENABLE_GC_CACAO)
+/* global mutex for the GC */
+static Mutex* mutex_gc;
+#endif
+
+/* global mutex and condition for joining threads on exit */
+static Mutex* mutex_join;
+static Condition* cond_join;
+
+#if defined(ENABLE_GC_CACAO)
+/* semaphore used for acknowleding thread suspension                          */
+static sem_t suspend_ack;
+#endif
+
+
+/* threads_sem_init ************************************************************
+   Initialize a semaphore. Checks against errors and interruptions.
+
+   IN:
+       sem..............the semaphore to initialize
+          shared...........true if this semaphore will be shared between processes
+          value............the initial value for the semaphore
+   
+*******************************************************************************/
+
+void threads_sem_init(sem_t *sem, bool shared, int value)
+{
+       int r;
+
+       assert(sem);
+
+       do {
+               r = sem_init(sem, shared, value);
+               if (r == 0)
+                       return;
+       } while (errno == EINTR);
+
+       vm_abort("sem_init failed: %s", strerror(errno));
+}
+
+
+/* threads_sem_wait ************************************************************
+   Wait for a semaphore, non-interruptible.
+
+   IMPORTANT: Always use this function instead of `sem_wait` directly, as
+              `sem_wait` may be interrupted by signals!
+  
+   IN:
+       sem..............the semaphore to wait on
+   
+*******************************************************************************/
+
+void threads_sem_wait(sem_t *sem)
+{
+       int r;
+
+       assert(sem);
+
+       do {
+               r = sem_wait(sem);
+               if (r == 0)
+                       return;
+       } while (errno == EINTR);
+
+       vm_abort("sem_wait failed: %s", strerror(errno));
+}
+
+
+/* threads_sem_post ************************************************************
+   Increase the count of a semaphore. Checks for errors.
+
+   IN:
+       sem..............the semaphore to increase the count of
+   
+*******************************************************************************/
+
+void threads_sem_post(sem_t *sem)
+{
+       int r;
+
+       assert(sem);
+
+       /* unlike sem_wait, sem_post is not interruptible */
+
+       r = sem_post(sem);
+       if (r == 0)
+               return;
+
+       vm_abort("sem_post failed: %s", strerror(errno));
+}
+
+
+/* threads_stopworld ***********************************************************
+
+   Stops the world from turning. All threads except the calling one
+   are suspended. The function returns as soon as all threads have
+   acknowledged their suspension.
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+void threads_stopworld(void)
+{
+#if !defined(__DARWIN__) && !defined(__CYGWIN__)
+       threadobject *t;
+       threadobject *self;
+       bool result;
+       s4 count, i;
+#endif
+
+       stopworldlock->lock();
+
+       /* lock the threads lists */
+
+       threadlist_lock();
+
+#if defined(__DARWIN__)
+       /*threads_cast_darwinstop();*/
+       assert(0);
+#elif defined(__CYGWIN__)
+       /* TODO */
+       assert(0);
+#else
+       self = THREADOBJECT;
+
+       DEBUGTHREADS("stops World", self);
+
+       count = 0;
+
+       /* suspend all running threads */
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               /* don't send the signal to ourself */
+
+               if (t == self)
+                       continue;
+
+               /* don't send the signal to NEW threads (because they are not
+                  completely initialized) */
+
+               if (t->state == THREAD_STATE_NEW)
+                       continue;
+
+               /* send the signal */
+
+               result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
+               assert(result);
+
+               /* increase threads count */
+
+               count++;
+       }
+
+       /* wait for all threads signaled to suspend */
+       for (i = 0; i < count; i++)
+               threads_sem_wait(&suspend_ack);
+#endif
+
+       /* ATTENTION: Don't unlock the threads-lists here so that
+          non-signaled NEW threads can't change their state and execute
+          code. */
+}
+#endif
+
+
+/* threads_startworld **********************************************************
+
+   Starts the world again after it has previously been stopped. 
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+void threads_startworld(void)
+{
+#if !defined(__DARWIN__) && !defined(__CYGWIN__)
+       threadobject *t;
+       threadobject *self;
+       bool result;
+       s4 count, i;
+#endif
+
+#if defined(__DARWIN__)
+       /*threads_cast_darwinresume();*/
+       assert(0);
+#elif defined(__IRIX__)
+       threads_cast_irixresume();
+#elif defined(__CYGWIN__)
+       /* TODO */
+       assert(0);
+#else
+       self = THREADOBJECT;
+
+       DEBUGTHREADS("starts World", self);
+
+       count = 0;
+
+       /* resume all thread we haltet */
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               /* don't send the signal to ourself */
+
+               if (t == self)
+                       continue;
+
+               /* don't send the signal to NEW threads (because they are not
+                  completely initialized) */
+
+               if (t->state == THREAD_STATE_NEW)
+                       continue;
+
+               /* send the signal */
+
+               result = threads_resume_thread(t);
+               assert(result);
+
+               /* increase threads count */
+
+               count++;
+       }
+
+       /* wait for all threads signaled to suspend */
+       for (i = 0; i < count; i++)
+               threads_sem_wait(&suspend_ack);
+
+#endif
+
+       /* unlock the threads lists */
+
+       threadlist_unlock();
+
+       stopworldlock->unlock();
+}
+#endif
+
+
+/* threads_impl_thread_init ****************************************************
+
+   Initialize OS-level locking constructs in threadobject.
+
+   IN:
+      t....the threadobject
+
+*******************************************************************************/
+
+void threads_impl_thread_init(threadobject *t)
+{
+       /* initialize the mutex and the condition */
+
+       t->flc_lock = new Mutex();
+       t->flc_cond = new Condition();
+
+       t->waitmutex = new Mutex();
+       t->waitcond = new Condition();
+
+       t->suspendmutex = new Mutex();
+       t->suspendcond = new Condition();
+
+#if defined(ENABLE_TLH)
+       tlh_init(&(t->tlh));
+#endif
+}
+
+/* threads_impl_thread_clear ***************************************************
+
+   Clears all fields in threadobject the way an MZERO would have
+   done. MZERO cannot be used anymore because it would mess up the
+   pthread_* bits.
+
+   IN:
+      t....the threadobject
+
+*******************************************************************************/
+
+void threads_impl_thread_clear(threadobject *t)
+{
+       t->object = NULL;
+
+       t->thinlock = 0;
+
+       t->index = 0;
+       t->flags = 0;
+       t->state = 0;
+
+       t->tid = 0;
+
+#if defined(__DARWIN__)
+       t->mach_thread = 0;
+#endif
+
+       t->interrupted = false;
+       t->signaled = false;
+
+       t->suspended = false;
+       t->suspend_reason = 0;
+
+       t->pc = NULL;
+
+       t->_exceptionptr = NULL;
+       t->_stackframeinfo = NULL;
+       t->_localref_table = NULL;
+
+#if defined(ENABLE_INTRP)
+       t->_global_sp = NULL;
+#endif
+
+#if defined(ENABLE_GC_CACAO)
+       t->gc_critical = false;
+
+       t->ss = NULL;
+       t->es = NULL;
+#endif
+
+       MZERO(&t->dumpinfo, dumpinfo_t, 1);
+}
+
+/* threads_impl_thread_reuse ***************************************************
+
+   Resets some implementation fields in threadobject. This was
+   previously done in threads_impl_thread_new.
+
+   IN:
+      t....the threadobject
+
+*******************************************************************************/
+
+void threads_impl_thread_reuse(threadobject *t)
+{
+       /* get the pthread id */
+
+       t->tid = pthread_self();
+
+#if defined(ENABLE_DEBUG_FILTER)
+       /* Initialize filter counters */
+       t->filterverbosecallctr[0] = 0;
+       t->filterverbosecallctr[1] = 0;
+#endif
+
+#if !defined(NDEBUG)
+       t->tracejavacallindent = 0;
+       t->tracejavacallcount = 0;
+#endif
+
+       t->flc_bit = false;
+       t->flc_next = NULL;
+       t->flc_list = NULL;
+
+/*     not really needed */
+       t->flc_object = NULL;
+
+#if defined(ENABLE_TLH)
+       tlh_destroy(&(t->tlh));
+       tlh_init(&(t->tlh));
+#endif
+}
+
+
+/* threads_impl_thread_free ****************************************************
+
+   Cleanup thread stuff.
+
+   IN:
+      t....the threadobject
+
+*******************************************************************************/
+
+#if 0
+/* never used */
+void threads_impl_thread_free(threadobject *t)
+{
+       int result;
+
+       /* Destroy the mutex and the condition. */
+
+       delete t->flc_lock;
+
+       result = pthread_cond_destroy(&(t->flc_cond));
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
+
+       delete t->waitmutex;
+
+       result = pthread_cond_destroy(&(t->waitcond));
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
+
+       delete t->suspendmutex;
+
+       result = pthread_cond_destroy(&(t->suspendcond));
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
+}
+#endif
+
+
+/* threads_impl_preinit ********************************************************
+
+   Do some early initialization of stuff required.
+
+   ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
+   is called AFTER this function!
+
+*******************************************************************************/
+
+void threads_impl_preinit(void)
+{
+       int result;
+
+       stopworldlock = new Mutex();
+
+       /* initialize exit mutex and condition (on exit we join all
+          threads) */
+
+       mutex_join = new Mutex();
+       cond_join = new Condition();
+
+#if defined(ENABLE_GC_CACAO)
+       /* initialize the GC mutex & suspend semaphore */
+
+       mutex_gc = new Mutex();
+       threads_sem_init(&suspend_ack, 0, 0);
+#endif
+
+#if !defined(HAVE___THREAD)
+       result = pthread_key_create(&thread_current_key, NULL);
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
+#endif
+}
+
+
+/* threads_mutex_gc_lock *******************************************************
+
+   Enter the global GC mutex.
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+void threads_mutex_gc_lock(void)
+{
+       mutex_gc->lock();
+}
+#endif
+
+
+/* threads_mutex_gc_unlock *****************************************************
+
+   Leave the global GC mutex.
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+void threads_mutex_gc_unlock(void)
+{
+       mutex_gc->unlock();
+}
+#endif
+
+/* threads_mutex_join_lock *****************************************************
+
+   Enter the join mutex.
+
+*******************************************************************************/
+
+void threads_mutex_join_lock(void)
+{
+       mutex_join->lock();
+}
+
+
+/* threads_mutex_join_unlock ***************************************************
+
+   Leave the join mutex.
+
+*******************************************************************************/
+
+void threads_mutex_join_unlock(void)
+{
+       mutex_join->unlock();
+}
+
+
+/* threads_impl_init ***********************************************************
+
+   Initializes the implementation specific bits.
+
+*******************************************************************************/
+
+void threads_impl_init(void)
+{
+       pthread_attr_t attr;
+       int            result;
+
+       threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
+
+       /* Initialize the thread attribute object. */
+
+       result = pthread_attr_init(&attr);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
+
+       result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
+}
+
+
+/* threads_startup_thread ******************************************************
+
+   Thread startup function called by pthread_create.
+
+   Thread which have a startup.function != NULL are marked as internal
+   threads. All other threads are threated as normal Java threads.
+
+   NOTE: This function is not called directly by pthread_create. The Boehm GC
+         inserts its own GC_start_routine in between, which then calls
+                threads_startup.
+
+   IN:
+      arg..........the argument passed to pthread_create, ie. a pointer to
+                      a startupinfo struct. CAUTION: When the `psem` semaphore
+                                  is posted, the startupinfo struct becomes invalid! (It
+                                  is allocated on the stack of threads_start_thread.)
+
+******************************************************************************/
+
+static void *threads_startup_thread(void *arg)
+{
+       startupinfo  *startup;
+       threadobject *t;
+       sem_t        *psem;
+       classinfo    *c;
+       methodinfo   *m;
+       functionptr   function;
+
+#if defined(ENABLE_GC_BOEHM)
+# if !defined(__DARWIN__)
+       struct GC_stack_base sb;
+       int result;
+# endif
+#endif
+
+#if defined(ENABLE_INTRP)
+       u1 *intrp_thread_stack;
+#endif
+
+#if defined(ENABLE_INTRP)
+       /* create interpreter stack */
+
+       if (opt_intrp) {
+               intrp_thread_stack = GCMNEW(u1, opt_stacksize);
+               MSET(intrp_thread_stack, 0, u1, opt_stacksize);
+       }
+       else
+               intrp_thread_stack = NULL;
+#endif
+
+       /* get passed startupinfo structure and the values in there */
+
+       startup = (startupinfo*) arg;
+
+       t        = startup->thread;
+       function = startup->function;
+       psem     = startup->psem;
+
+       /* Seems like we've encountered a situation where thread->tid was
+          not set by pthread_create. We alleviate this problem by waiting
+          for pthread_create to return. */
+
+       threads_sem_wait(startup->psem_first);
+
+#if defined(__DARWIN__)
+       t->mach_thread = mach_thread_self();
+#endif
+
+       /* Now that we are in the new thread, we can store the internal
+          thread data-structure in the TSD. */
+
+       thread_set_current(t);
+
+#if defined(ENABLE_GC_BOEHM)
+# if defined(__DARWIN__)
+       // This is currently not implemented in Boehm-GC.  Just fail silently.
+# else
+       /* Register the thread with Boehm-GC.  This must happen before the
+          thread allocates any memory from the GC heap.*/
+
+       result = GC_get_stack_base(&sb);
+
+       if (result != 0)
+               vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
+
+       GC_register_my_thread(&sb);
+# endif
+#endif
+
+       // Get the java.lang.Thread object for this thread.
+       java_handle_t* object = thread_get_object(t);
+       java_lang_Thread jlt(object);
+
+       /* set our priority */
+
+       threads_set_thread_priority(t->tid, jlt.get_priority());
+
+       /* Thread is completely initialized. */
+
+       thread_set_state_runnable(t);
+
+       /* tell threads_startup_thread that we registered ourselves */
+       /* CAUTION: *startup becomes invalid with this!             */
+
+       startup = NULL;
+       threads_sem_post(psem);
+
+#if defined(ENABLE_INTRP)
+       /* set interpreter stack */
+
+       if (opt_intrp)
+               thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
+#endif
+
+#if defined(ENABLE_JVMTI)
+       /* fire thread start event */
+
+       if (jvmti) 
+               jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
+#endif
+
+       DEBUGTHREADS("starting", t);
+
+       /* find and run the Thread.run()V method if no other function was passed */
+
+       if (function == NULL) {
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+               /* We need to start the run method of
+                  java.lang.VMThread. Since this is a final class, we can use
+                  the class object directly. */
+
+               c = class_java_lang_VMThread;
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+               LLNI_class_get(object, c);
+#else
+# error unknown classpath configuration
+#endif
+
+               m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
+
+               if (m == NULL)
+                       vm_abort("threads_startup_thread: run() method not found in class");
+
+               /* set ThreadMXBean variables */
+
+/*             _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
+/*             _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
+
+/*             if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
+/*                     _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
+/*                     _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
+/*                             _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
+#warning Move to C++
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+               // We need to start the run method of java.lang.VMThread.
+               java_lang_VMThread jlvmt(jlt.get_vmThread());
+               java_handle_t* h = jlvmt.get_handle();
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+               java_handle_t* h = jlt.get_handle();
+
+#else
+# error unknown classpath configuration
+#endif
+
+               /* Run the thread. */
+
+               (void) vm_call_method(m, h);
+       }
+       else {
+               /* set ThreadMXBean variables */
+
+/*             _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
+/*             _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
+
+/*             if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
+/*                     _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
+/*                     _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
+/*                             _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
+#warning Move to C++
+
+               /* call passed function, e.g. finalizer_thread */
+
+               (function)();
+       }
+
+       DEBUGTHREADS("stopping", t);
+
+#if defined(ENABLE_JVMTI)
+       /* fire thread end event */
+
+       if (jvmti)
+               jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
+#endif
+
+       /* We ignore the return value. */
+
+       (void) thread_detach_current_thread();
+
+       /* set ThreadMXBean variables */
+
+/*     _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--; */
+#warning Move to C++
+
+       return NULL;
+}
+
+
+/* threads_impl_thread_start ***************************************************
+
+   Start a thread in the JVM.  Both (vm internal and java) thread
+   objects exist.
+
+   IN:
+      thread....the thread object
+         f.........function to run in the new thread. NULL means that the
+                   "run" method of the object `t` should be called
+
+******************************************************************************/
+
+void threads_impl_thread_start(threadobject *thread, functionptr f)
+{
+       sem_t          sem;
+       sem_t          sem_first;
+       pthread_attr_t attr;
+       startupinfo    startup;
+       int            result;
+
+       /* fill startupinfo structure passed by pthread_create to
+        * threads_startup_thread */
+
+       startup.thread     = thread;
+       startup.function   = f;              /* maybe we don't call Thread.run()V */
+       startup.psem       = &sem;
+       startup.psem_first = &sem_first;
+
+       threads_sem_init(&sem, 0, 0);
+       threads_sem_init(&sem_first, 0, 0);
+
+       /* Initialize thread attributes. */
+
+       result = pthread_attr_init(&attr);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
+
+    result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    if (result != 0)
+               vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
+
+       /* initialize thread stacksize */
+
+       result = pthread_attr_setstacksize(&attr, opt_stacksize);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
+
+       /* create the thread */
+
+       result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
+
+       /* destroy the thread attributes */
+
+       result = pthread_attr_destroy(&attr);
+
+       if (result != 0)
+               vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
+
+       /* signal that pthread_create has returned, so thread->tid is valid */
+
+       threads_sem_post(&sem_first);
+
+       /* wait here until the thread has entered itself into the thread list */
+
+       threads_sem_wait(&sem);
+
+       /* cleanup */
+
+       sem_destroy(&sem);
+       sem_destroy(&sem_first);
+}
+
+
+/* threads_set_thread_priority *************************************************
+
+   Set the priority of the given thread.
+
+   IN:
+      tid..........thread id
+         priority.....priority to set
+
+******************************************************************************/
+
+void threads_set_thread_priority(pthread_t tid, int priority)
+{
+       struct sched_param schedp;
+       int policy;
+
+       pthread_getschedparam(tid, &policy, &schedp);
+       schedp.sched_priority = priority;
+       pthread_setschedparam(tid, policy, &schedp);
+}
+
+
+/**
+ * Detaches the current thread from the VM.
+ *
+ * @return true on success, false otherwise
+ */
+bool thread_detach_current_thread(void)
+{
+       threadobject* t = thread_get_current();
+
+       /* Sanity check. */
+
+       assert(t != NULL);
+
+    /* If the given thread has already been detached, this operation
+          is a no-op. */
+
+       if (thread_is_attached(t) == false)
+               return true;
+
+       DEBUGTHREADS("detaching", t);
+
+       java_handle_t* object = thread_get_object(t);
+       java_lang_Thread jlt(object);
+
+#if defined(ENABLE_JAVASE)
+       java_handle_t* group = jlt.get_group();
+
+    /* If there's an uncaught exception, call uncaughtException on the
+       thread's exception handler, or the thread's group if this is
+       unset. */
+
+       java_handle_t* e = exceptions_get_and_clear_exception();
+
+    if (e != NULL) {
+               /* We use the type void* for handler here, as it's not trivial
+                  to build the java_lang_Thread_UncaughtExceptionHandler
+                  header file with cacaoh. */
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+               java_handle_t* handler = jlt.get_exceptionHandler();
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+               java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
+
+# endif
+
+               classinfo*     c;
+               java_handle_t* h;
+
+               if (handler != NULL) {
+                       LLNI_class_get(handler, c);
+                       h = (java_handle_t *) handler;
+               }
+               else {
+                       LLNI_class_get(group, c);
+                       h = (java_handle_t *) group;
+               }
+
+               methodinfo* m = class_resolveclassmethod(c,
+                                                                                                utf_uncaughtException,
+                                                                                                utf_java_lang_Thread_java_lang_Throwable__V,
+                                                                                                NULL,
+                                                                                                true);
+
+               if (m == NULL)
+                       return false;
+
+               (void) vm_call_method(m, h, object, e);
+
+               if (exceptions_get_exception())
+                       return false;
+    }
+
+       /* XXX TWISTI: should all threads be in a ThreadGroup? */
+
+       /* Remove thread from the thread group. */
+
+       if (group != NULL) {
+               classinfo* c;
+               LLNI_class_get(group, c);
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+               methodinfo* m = class_resolveclassmethod(c,
+                                                                                                utf_removeThread,
+                                                                                                utf_java_lang_Thread__V,
+                                                                                                class_java_lang_ThreadGroup,
+                                                                                                true);
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+               methodinfo* m = class_resolveclassmethod(c,
+                                                                                                utf_remove,
+                                                                                                utf_java_lang_Thread__V,
+                                                                                                class_java_lang_ThreadGroup,
+                                                                                                true);
+# else
+#  error unknown classpath configuration
+# endif
+
+               if (m == NULL)
+                       return false;
+
+               (void) vm_call_method(m, group, object);
+
+               if (exceptions_get_exception())
+                       return false;
+
+               // Clear the ThreadGroup in the Java thread object (Mauve
+               // test: gnu/testlet/java/lang/Thread/getThreadGroup).
+               jlt.set_group(NULL);
+       }
+#endif
+
+       /* Thread has terminated. */
+
+       thread_set_state_terminated(t);
+
+       /* Notify all threads waiting on this thread.  These are joining
+          this thread. */
+
+       /* XXX Care about exceptions? */
+       (void) lock_monitor_enter(jlt.get_handle());
+       
+       lock_notify_all_object(jlt.get_handle());
+
+       /* XXX Care about exceptions? */
+       (void) lock_monitor_exit(jlt.get_handle());
+
+       /* Enter the join-mutex before calling thread_free, so
+          threads_join_all_threads gets the correct number of non-daemon
+          threads. */
+
+       threads_mutex_join_lock();
+
+       /* Free the internal thread data-structure. */
+
+       thread_free(t);
+
+       /* Signal that this thread has finished and leave the mutex. */
+
+       cond_join->signal();
+       threads_mutex_join_unlock();
+
+       return true;
+}
+
+
+/* threads_suspend_thread ******************************************************
+
+   Suspend the passed thread. Execution stops until the thread
+   is explicitly resumend again.
+
+   IN:
+     reason.....Reason for suspending this thread.
+
+*******************************************************************************/
+
+bool threads_suspend_thread(threadobject *thread, s4 reason)
+{
+       /* acquire the suspendmutex */
+       thread->suspendmutex->lock();
+
+       if (thread->suspended) {
+               thread->suspendmutex->unlock();
+               return false;
+       }
+
+       /* set the reason for the suspension */
+       thread->suspend_reason = reason;
+
+       /* send the suspend signal to the thread */
+       assert(thread != THREADOBJECT);
+       if (pthread_kill(thread->tid, SIGUSR1) != 0)
+               vm_abort("threads_suspend_thread: pthread_kill failed: %s",
+                                strerror(errno));
+
+       /* REMEMBER: do not release the suspendmutex, this is done
+          by the thread itself in threads_suspend_ack().  */
+
+       return true;
+}
+
+
+/* threads_suspend_ack *********************************************************
+
+   Acknowledges the suspension of the current thread.
+
+   IN:
+     pc.....The PC where the thread suspended its execution.
+     sp.....The SP before the thread suspended its execution.
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+void threads_suspend_ack(u1* pc, u1* sp)
+{
+       threadobject *thread;
+
+       thread = THREADOBJECT;
+
+       assert(thread->suspend_reason != 0);
+
+       /* TODO: remember dump memory size */
+
+       /* inform the GC about the suspension */
+       if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
+
+               /* check if the GC wants to leave the thread running */
+               if (!gc_suspend(thread, pc, sp)) {
+
+                       /* REMEMBER: we do not unlock the suspendmutex because the thread
+                          will suspend itself again at a later time */
+                       return;
+
+               }
+       }
+
+       /* mark this thread as suspended and remember the PC */
+       thread->pc        = pc;
+       thread->suspended = true;
+
+       /* if we are stopping the world, we should send a global ack */
+       if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
+               threads_sem_post(&suspend_ack);
+       }
+
+       DEBUGTHREADS("suspending", thread);
+
+       /* release the suspension mutex and wait till we are resumed */
+       thread->suspendcond->wait(thread->suspendmutex);
+
+       DEBUGTHREADS("resuming", thread);
+
+       /* if we are stopping the world, we should send a global ack */
+       if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
+               threads_sem_post(&suspend_ack);
+       }
+
+       /* TODO: free dump memory */
+
+       /* release the suspendmutex */
+       thread->suspendmutex->unlock();
+}
+#endif
+
+
+/* threads_resume_thread *******************************************************
+
+   Resumes the execution of the passed thread.
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+bool threads_resume_thread(threadobject *thread)
+{
+       /* acquire the suspendmutex */
+       thread->suspendmutex->lock();
+
+       if (!thread->suspended) {
+               thread->suspendmutex->unlock();
+               return false;
+       }
+
+       thread->suspended = false;
+
+       /* tell everyone that the thread should resume */
+       assert(thread != THREADOBJECT);
+       thread->suspendcond->broadcast();
+
+       /* release the suspendmutex */
+       thread->suspendmutex->unlock();
+
+       return true;
+}
+#endif
+
+
+/* threads_join_all_threads ****************************************************
+
+   Join all non-daemon threads.
+
+*******************************************************************************/
+
+void threads_join_all_threads(void)
+{
+       threadobject *t;
+
+       /* get current thread */
+
+       t = THREADOBJECT;
+
+       /* This thread is waiting for all non-daemon threads to exit. */
+
+       thread_set_state_waiting(t);
+
+       /* enter join mutex */
+
+       threads_mutex_join_lock();
+
+       /* Wait for condition as long as we have non-daemon threads.  We
+          compare against 1 because the current (main thread) is also a
+          non-daemon thread. */
+
+       while (threadlist_get_non_daemons() > 1)
+               cond_join->wait(mutex_join);
+
+       /* leave join mutex */
+
+       threads_mutex_join_unlock();
+}
+
+
+/* threads_timespec_earlier ****************************************************
+
+   Return true if timespec tv1 is earlier than timespec tv2.
+
+   IN:
+      tv1..........first timespec
+         tv2..........second timespec
+
+   RETURN VALUE:
+      true, if the first timespec is earlier
+
+*******************************************************************************/
+
+static inline bool threads_timespec_earlier(const struct timespec *tv1,
+                                                                                       const struct timespec *tv2)
+{
+       return (tv1->tv_sec < tv2->tv_sec)
+                               ||
+               (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
+}
+
+
+/* threads_current_time_is_earlier_than ****************************************
+
+   Check if the current time is earlier than the given timespec.
+
+   IN:
+      tv...........the timespec to compare against
+
+   RETURN VALUE:
+      true, if the current time is earlier
+
+*******************************************************************************/
+
+static bool threads_current_time_is_earlier_than(const struct timespec *tv)
+{
+       struct timeval tvnow;
+       struct timespec tsnow;
+
+       /* get current time */
+
+       if (gettimeofday(&tvnow, NULL) != 0)
+               vm_abort("gettimeofday failed: %s\n", strerror(errno));
+
+       /* convert it to a timespec */
+
+       tsnow.tv_sec = tvnow.tv_sec;
+       tsnow.tv_nsec = tvnow.tv_usec * 1000;
+
+       /* compare current time with the given timespec */
+
+       return threads_timespec_earlier(&tsnow, tv);
+}
+
+
+/* threads_wait_with_timeout ***************************************************
+
+   Wait until the given point in time on a monitor until either
+   we are notified, we are interrupted, or the time is up.
+
+   IN:
+      t............the current thread
+         wakeupTime...absolute (latest) wakeup time
+                          If both tv_sec and tv_nsec are zero, this function
+                                          waits for an unlimited amount of time.
+
+*******************************************************************************/
+
+static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
+{
+       // Acquire the waitmutex.
+       t->waitmutex->lock();
+
+       /* wait on waitcond */
+
+       if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
+               /* with timeout */
+               while (!t->interrupted && !t->signaled
+                          && threads_current_time_is_earlier_than(wakeupTime))
+               {
+                       thread_set_state_timed_waiting(t);
+
+                       t->waitcond->timedwait(t->waitmutex, wakeupTime);
+
+                       thread_set_state_runnable(t);
+               }
+       }
+       else {
+               /* no timeout */
+               while (!t->interrupted && !t->signaled) {
+                       thread_set_state_waiting(t);
+
+                       t->waitcond->wait(t->waitmutex);
+
+                       thread_set_state_runnable(t);
+               }
+       }
+
+       // Release the waitmutex.
+       t->waitmutex->unlock();
+}
+
+
+/* threads_wait_with_timeout_relative ******************************************
+
+   Wait for the given maximum amount of time on a monitor until either
+   we are notified, we are interrupted, or the time is up.
+
+   IN:
+      t............the current thread
+         millis.......milliseconds to wait
+         nanos........nanoseconds to wait
+
+*******************************************************************************/
+
+void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
+                                                                               s4 nanos)
+{
+       struct timespec wakeupTime;
+
+       /* calculate the the (latest) wakeup time */
+
+       threads_calc_absolute_time(&wakeupTime, millis, nanos);
+
+       /* wait */
+
+       threads_wait_with_timeout(thread, &wakeupTime);
+}
+
+
+/* threads_calc_absolute_time **************************************************
+
+   Calculate the absolute point in time a given number of ms and ns from now.
+
+   IN:
+      millis............milliseconds from now
+         nanos.............nanoseconds from now
+
+   OUT:
+      *tm...............receives the timespec of the absolute point in time
+
+*******************************************************************************/
+
+static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
+{
+       if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
+               struct timeval tv;
+               long nsec;
+               gettimeofday(&tv, NULL);
+               tv.tv_sec += millis / 1000;
+               millis %= 1000;
+               nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
+               tm->tv_sec = tv.tv_sec + nsec / 1000000000;
+               tm->tv_nsec = nsec % 1000000000;
+       }
+       else {
+               tm->tv_sec = 0;
+               tm->tv_nsec = 0;
+       }
+}
+
+
+/* threads_thread_interrupt ****************************************************
+
+   Interrupt the given thread.
+
+   The thread gets the "waitcond" signal and 
+   its interrupted flag is set to true.
+
+   IN:
+      thread............the thread to interrupt
+
+*******************************************************************************/
+
+void threads_thread_interrupt(threadobject *t)
+{
+       /* Signal the thread a "waitcond" and tell it that it has been
+          interrupted. */
+
+       t->waitmutex->lock();
+
+       DEBUGTHREADS("interrupted", t);
+
+       /* Interrupt blocking system call using a signal. */
+
+       pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
+
+       t->waitcond->signal();
+
+       t->interrupted = true;
+
+       t->waitmutex->unlock();
+}
+
+
+/**
+ * Sleep the current thread for the specified amount of time.
+ *
+ * @param millis Milliseconds to sleep.
+ * @param nanos  Nanoseconds to sleep.
+ */
+void threads_sleep(int64_t millis, int32_t nanos)
+{
+       threadobject    *t;
+       struct timespec  wakeupTime;
+       bool             interrupted;
+
+       if (millis < 0) {
+/*             exceptions_throw_illegalargumentexception("timeout value is negative"); */
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+       t = thread_get_current();
+
+       if (thread_is_interrupted(t) && !exceptions_get_exception()) {
+               /* Clear interrupted flag (Mauve test:
+                  gnu/testlet/java/lang/Thread/interrupt). */
+
+               thread_set_interrupted(t, false);
+
+/*             exceptions_throw_interruptedexception("sleep interrupted"); */
+               exceptions_throw_interruptedexception();
+               return;
+       }
+
+       // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
+       // Note: JDK treats a zero length sleep is like Thread.yield(),
+       // without checking the interrupted status of the thread.  It's
+       // unclear if this is a bug in the implementation or the spec.
+       // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
+       if (millis == 0 && nanos == 0) {
+               threads_yield();
+       }
+       else {
+               threads_calc_absolute_time(&wakeupTime, millis, nanos);
+
+               threads_wait_with_timeout(t, &wakeupTime);
+
+               interrupted = thread_is_interrupted(t);
+
+               if (interrupted) {
+                       thread_set_interrupted(t, false);
+
+                       // An other exception could have been thrown
+                       // (e.g. ThreadDeathException).
+                       if (!exceptions_get_exception())
+                               exceptions_throw_interruptedexception();
+               }
+       }
+}
+
+
+/* threads_yield ***************************************************************
+
+   Yield to the scheduler.
+
+*******************************************************************************/
+
+void threads_yield(void)
+{
+       sched_yield();
+}
+
+#if defined(ENABLE_TLH)
+
+void threads_tlh_add_frame() {
+       tlh_add_frame(&(THREADOBJECT->tlh));
+}
+
+void threads_tlh_remove_frame() {
+       tlh_remove_frame(&(THREADOBJECT->tlh));
+}
+
+#endif
+
+} // extern "C"
+
+
+/*
+ * 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/threads/posix/thread-posix.h b/src/threads/posix/thread-posix.h
deleted file mode 100644 (file)
index 45d05ec..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/* src/threads/posix/thread-posix.h - POSIX thread 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 _THREAD_POSIX_H
-#define _THREAD_POSIX_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct threadobject threadobject;
-
-
-#include "config.h"
-
-#include <pthread.h>
-#include <ucontext.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/localref.h"
-
-#include "threads/mutex.h"
-
-#include "threads/posix/lock.h"
-
-#include "vm/global.h"
-#include "vm/vm.h"
-
-#if defined(ENABLE_GC_CACAO)
-# include "vm/jit/replace.h"
-#endif
-
-#include "vm/jit/stacktrace.h"
-
-#if defined(ENABLE_INTRP)
-#include "vm/jit/intrp/intrp.h"
-#endif
-
-#if defined(__DARWIN__)
-# include <mach/mach.h>
-
-typedef struct {
-       mutex_t mutex;
-       pthread_cond_t cond;
-       int value;
-} sem_t;
-
-#else
-# include <semaphore.h>
-#endif
-
-
-/* current threadobject *******************************************************/
-
-#if defined(HAVE___THREAD)
-
-#define THREADOBJECT      thread_current
-
-extern __thread threadobject *thread_current;
-
-#else /* defined(HAVE___THREAD) */
-
-#define THREADOBJECT \
-       ((threadobject *) pthread_getspecific(thread_current_key))
-
-extern pthread_key_t thread_current_key;
-
-#endif /* defined(HAVE___THREAD) */
-
-
-/* threadobject ****************************************************************
-
-   Struct holding thread local variables.
-
-*******************************************************************************/
-
-#define THREAD_FLAG_JAVA        0x01    /* a normal Java thread               */
-#define THREAD_FLAG_INTERNAL    0x02    /* CACAO internal thread              */
-#define THREAD_FLAG_DAEMON      0x04    /* daemon thread                      */
-#define THREAD_FLAG_IN_NATIVE   0x08    /* currently executing native code    */
-
-#define SUSPEND_REASON_JNI       1      /* suspended from JNI                 */
-#define SUSPEND_REASON_STOPWORLD 2      /* suspended from stop-thw-world      */
-
-
-struct threadobject {
-       java_object_t        *object;       /* link to java.lang.Thread object    */
-
-       ptrint                thinlock;     /* pre-computed thin lock value       */
-
-       s4                    index;        /* thread index, starting with 1      */
-       u4                    flags;        /* flag field                         */
-       u4                    state;        /* state field                        */
-
-       pthread_t             tid;          /* pthread id                         */
-
-#if defined(__DARWIN__)
-       mach_port_t           mach_thread;       /* Darwin thread id              */
-#endif
-
-       /* for the sable tasuki lock extension */
-       bool                  flc_bit;
-       struct threadobject  *flc_list;     /* FLC list head for this thread      */
-       struct threadobject  *flc_next;     /* next pointer for FLC list          */
-       java_handle_t        *flc_object;
-       mutex_t               flc_lock;     /* controlling access to these fields */
-       pthread_cond_t        flc_cond;
-
-       /* these are used for the wait/notify implementation                      */
-       mutex_t               waitmutex;
-       pthread_cond_t        waitcond;
-
-       mutex_t               suspendmutex; /* lock before suspending this thread */
-       pthread_cond_t        suspendcond;  /* notify to resume this thread       */
-
-       bool                  interrupted;
-       bool                  signaled;
-
-       bool                  suspended;    /* is this thread suspended?          */
-       s4                    suspend_reason; /* reason for suspending            */
-
-       u1                   *pc;           /* current PC (used for profiling)    */
-
-       java_object_t        *_exceptionptr;     /* current exception             */
-       stackframeinfo_t     *_stackframeinfo;   /* current native stackframeinfo */
-       localref_table       *_localref_table;   /* JNI local references          */
-
-#if defined(ENABLE_INTRP)
-       Cell                 *_global_sp;        /* stack pointer for interpreter */
-#endif
-
-#if defined(ENABLE_GC_CACAO)
-       bool                  gc_critical;  /* indicates a critical section       */
-
-       sourcestate_t        *ss;
-       executionstate_t     *es;
-#endif
-
-       dumpinfo_t            dumpinfo;     /* dump memory info structure         */
-
-#if defined(ENABLE_DEBUG_FILTER)
-       u2                    filterverbosecallctr[2]; /* counters for verbose call filter */
-#endif
-
-#if !defined(NDEBUG)
-       s4                    tracejavacallindent;
-       u4                    tracejavacallcount;
-#endif
-
-       listnode_t            linkage;      /* threads-list                       */
-       listnode_t            linkage_free; /* free-list                          */
-};
-
-
-/* native-world flags *********************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-# define THREAD_NATIVEWORLD_ENTER THREADOBJECT->flags |=  THREAD_FLAG_IN_NATIVE
-# define THREAD_NATIVEWORLD_EXIT  THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE
-#else
-# define THREAD_NATIVEWORLD_ENTER /*nop*/
-# define THREAD_NATIVEWORLD_EXIT  /*nop*/
-#endif
-
-
-/* counter for verbose call filter ********************************************/
-
-#if defined(ENABLE_DEBUG_FILTER)
-#      define FILTERVERBOSECALLCTR (THREADOBJECT->filterverbosecallctr)
-#endif
-
-/* state for trace java call **************************************************/
-
-#if !defined(NDEBUG)
-#      define TRACEJAVACALLINDENT (THREADOBJECT->tracejavacallindent)
-#      define TRACEJAVACALLCOUNT (THREADOBJECT->tracejavacallcount)
-#endif
-
-
-/* inline functions ***********************************************************/
-
-/* thread_get_current **********************************************************
-
-   Return the threadobject of the current thread.
-   
-   RETURN:
-       the current threadobject *
-
-*******************************************************************************/
-
-inline static threadobject *thread_get_current(void)
-{
-       threadobject *t;
-
-#if defined(HAVE___THREAD)
-       t = thread_current;
-#else
-       t = (threadobject *) pthread_getspecific(thread_current_key);
-#endif
-
-       return t;
-}
-
-
-/* thread_set_current **********************************************************
-
-   Set the current thread object.
-   
-   IN:
-      t ... the thread object to set
-
-*******************************************************************************/
-
-inline static void thread_set_current(threadobject *t)
-{
-#if defined(HAVE___THREAD)
-       thread_current = t;
-#else
-       int result;
-
-       result = pthread_setspecific(thread_current_key, t);
-
-       if (result != 0)
-               vm_abort_errnum(result, "thread_set_current: pthread_setspecific failed");
-#endif
-}
-
-
-inline static stackframeinfo_t *threads_get_current_stackframeinfo(void)
-{
-       return THREADOBJECT->_stackframeinfo;
-}
-
-inline static void threads_set_current_stackframeinfo(stackframeinfo_t *sfi)
-{
-       THREADOBJECT->_stackframeinfo = sfi;
-}
-
-
-/* functions ******************************************************************/
-
-void threads_sem_init(sem_t *sem, bool shared, int value);
-void threads_sem_wait(sem_t *sem);
-void threads_sem_post(sem_t *sem);
-
-void threads_start_thread(threadobject *thread, functionptr function);
-
-void threads_set_thread_priority(pthread_t tid, int priority);
-
-#if defined(ENABLE_GC_CACAO)
-bool threads_suspend_thread(threadobject *thread, s4 reason);
-void threads_suspend_ack(u1* pc, u1* sp);
-bool threads_resume_thread(threadobject *thread);
-#endif
-
-void threads_join_all_threads(void);
-
-void threads_sleep(int64_t millis, int32_t nanos);
-
-void threads_wait_with_timeout_relative(threadobject *t, s8 millis, s4 nanos);
-
-void threads_thread_interrupt(threadobject *thread);
-
-#endif /* _THREAD_POSIX_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/threads/posix/thread-posix.hpp b/src/threads/posix/thread-posix.hpp
new file mode 100644 (file)
index 0000000..e1e412e
--- /dev/null
@@ -0,0 +1,330 @@
+/* src/threads/posix/thread-posix.hpp - POSIX thread 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 _THREAD_POSIX_HPP
+#define _THREAD_POSIX_HPP
+
+/* forward typedefs ***********************************************************/
+
+typedef struct threadobject threadobject;
+
+
+#include "config.h"
+
+#include <pthread.h>
+#include <ucontext.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#if defined(ENABLE_TLH)
+#include "mm/tlh.h"
+#endif
+
+#include "native/localref.h"
+
+#include "threads/condition.hpp"
+#include "threads/mutex.hpp"
+
+#include "threads/posix/lock.h"
+
+#include "vm/global.h"
+#include "vm/vm.hpp"
+
+#if defined(ENABLE_GC_CACAO)
+# include "vm/jit/executionstate.h"
+# include "vm/jit/replace.h"
+#endif
+
+#include "vm/jit/stacktrace.hpp"
+
+#if defined(ENABLE_INTRP)
+#include "vm/jit/intrp/intrp.h"
+#endif
+
+#if defined(__DARWIN__)
+# include <mach/mach.h>
+
+typedef struct {
+       Mutex* mutex;
+       Condition* cond;
+       int value;
+} sem_t;
+
+#else
+# include <semaphore.h>
+#endif
+
+
+// FIXME
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* current threadobject *******************************************************/
+
+#if defined(HAVE___THREAD)
+
+#define THREADOBJECT      thread_current
+
+extern __thread threadobject *thread_current;
+
+#else /* defined(HAVE___THREAD) */
+
+#define THREADOBJECT \
+       ((threadobject *) pthread_getspecific(thread_current_key))
+
+extern pthread_key_t thread_current_key;
+
+#endif /* defined(HAVE___THREAD) */
+
+
+/* threadobject ****************************************************************
+
+   Struct holding thread local variables.
+
+*******************************************************************************/
+
+#define THREAD_FLAG_JAVA        0x01    /* a normal Java thread               */
+#define THREAD_FLAG_INTERNAL    0x02    /* CACAO internal thread              */
+#define THREAD_FLAG_DAEMON      0x04    /* daemon thread                      */
+#define THREAD_FLAG_IN_NATIVE   0x08    /* currently executing native code    */
+
+#define SUSPEND_REASON_JNI       1      /* suspended from JNI                 */
+#define SUSPEND_REASON_STOPWORLD 2      /* suspended from stop-thw-world      */
+
+
+struct threadobject {
+       java_object_t        *object;       /* link to java.lang.Thread object    */
+
+       ptrint                thinlock;     /* pre-computed thin lock value       */
+
+       s4                    index;        /* thread index, starting with 1      */
+       u4                    flags;        /* flag field                         */
+       u4                    state;        /* state field                        */
+
+       pthread_t             tid;          /* pthread id                         */
+
+#if defined(__DARWIN__)
+       mach_port_t           mach_thread;       /* Darwin thread id              */
+#endif
+
+       /* for the sable tasuki lock extension */
+       bool                  flc_bit;
+       struct threadobject  *flc_list;     /* FLC list head for this thread      */
+       struct threadobject  *flc_next;     /* next pointer for FLC list          */
+       java_handle_t        *flc_object;
+       Mutex*                flc_lock;     /* controlling access to these fields */
+       Condition*            flc_cond;
+
+       /* these are used for the wait/notify implementation                      */
+       Mutex*                waitmutex;
+       Condition*            waitcond;
+
+       Mutex*                suspendmutex; /* lock before suspending this thread */
+       Condition*            suspendcond;  /* notify to resume this thread       */
+
+       bool                  interrupted;
+       bool                  signaled;
+
+       bool                  suspended;    /* is this thread suspended?          */
+       s4                    suspend_reason; /* reason for suspending            */
+
+       u1                   *pc;           /* current PC (used for profiling)    */
+
+       java_object_t        *_exceptionptr;     /* current exception             */
+       stackframeinfo_t     *_stackframeinfo;   /* current native stackframeinfo */
+       localref_table       *_localref_table;   /* JNI local references          */
+
+#if defined(ENABLE_INTRP)
+       Cell                 *_global_sp;        /* stack pointer for interpreter */
+#endif
+
+#if defined(ENABLE_GC_CACAO)
+       bool                  gc_critical;  /* indicates a critical section       */
+
+       sourcestate_t        *ss;
+       executionstate_t     *es;
+#endif
+
+       dumpinfo_t            dumpinfo;     /* dump memory info structure         */
+
+#if defined(ENABLE_DEBUG_FILTER)
+       u2                    filterverbosecallctr[2]; /* counters for verbose call filter */
+#endif
+
+#if !defined(NDEBUG)
+       s4                    tracejavacallindent;
+       u4                    tracejavacallcount;
+#endif
+
+#if defined(ENABLE_TLH)
+       tlh_t                 tlh;
+#endif
+
+#if defined(ENABLE_ESCAPE_REASON)
+       void *escape_reasons;
+#endif
+
+       listnode_t            linkage;      /* threads-list                       */
+       listnode_t            linkage_free; /* free-list                          */
+};
+
+
+/* native-world flags *********************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+# define THREAD_NATIVEWORLD_ENTER THREADOBJECT->flags |=  THREAD_FLAG_IN_NATIVE
+# define THREAD_NATIVEWORLD_EXIT  THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE
+#else
+# define THREAD_NATIVEWORLD_ENTER /*nop*/
+# define THREAD_NATIVEWORLD_EXIT  /*nop*/
+#endif
+
+
+/* counter for verbose call filter ********************************************/
+
+#if defined(ENABLE_DEBUG_FILTER)
+#      define FILTERVERBOSECALLCTR (THREADOBJECT->filterverbosecallctr)
+#endif
+
+/* state for trace java call **************************************************/
+
+#if !defined(NDEBUG)
+#      define TRACEJAVACALLINDENT (THREADOBJECT->tracejavacallindent)
+#      define TRACEJAVACALLCOUNT (THREADOBJECT->tracejavacallcount)
+#endif
+
+
+/* inline functions ***********************************************************/
+
+/* thread_get_current **********************************************************
+
+   Return the threadobject of the current thread.
+   
+   RETURN:
+       the current threadobject *
+
+*******************************************************************************/
+
+inline static threadobject *thread_get_current(void)
+{
+       threadobject *t;
+
+#if defined(HAVE___THREAD)
+       t = thread_current;
+#else
+       t = (threadobject *) pthread_getspecific(thread_current_key);
+#endif
+
+       return t;
+}
+
+
+/* thread_set_current **********************************************************
+
+   Set the current thread object.
+   
+   IN:
+      t ... the thread object to set
+
+*******************************************************************************/
+
+inline static void thread_set_current(threadobject *t)
+{
+#if defined(HAVE___THREAD)
+       thread_current = t;
+#else
+       int result;
+
+       result = pthread_setspecific(thread_current_key, t);
+
+       if (result != 0)
+               vm_abort_errnum(result, "thread_set_current: pthread_setspecific failed");
+#endif
+}
+
+
+inline static stackframeinfo_t *threads_get_current_stackframeinfo(void)
+{
+       return THREADOBJECT->_stackframeinfo;
+}
+
+inline static void threads_set_current_stackframeinfo(stackframeinfo_t *sfi)
+{
+       THREADOBJECT->_stackframeinfo = sfi;
+}
+
+
+/* functions ******************************************************************/
+
+void threads_sem_init(sem_t *sem, bool shared, int value);
+void threads_sem_wait(sem_t *sem);
+void threads_sem_post(sem_t *sem);
+
+void threads_start_thread(threadobject *thread, functionptr function);
+
+void threads_set_thread_priority(pthread_t tid, int priority);
+
+#if defined(ENABLE_GC_CACAO)
+bool threads_suspend_thread(threadobject *thread, s4 reason);
+void threads_suspend_ack(u1* pc, u1* sp);
+bool threads_resume_thread(threadobject *thread);
+#endif
+
+void threads_join_all_threads(void);
+
+void threads_sleep(int64_t millis, int32_t nanos);
+
+void threads_wait_with_timeout_relative(threadobject *t, s8 millis, s4 nanos);
+
+void threads_thread_interrupt(threadobject *thread);
+
+#if defined(ENABLE_TLH)
+void threads_tlh_add_frame();
+void threads_tlh_remove_frame();
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _THREAD_POSIX_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:
+ */
diff --git a/src/threads/removeme.cpp b/src/threads/removeme.cpp
new file mode 100644 (file)
index 0000000..60878ce
--- /dev/null
@@ -0,0 +1,61 @@
+/* src/threads/removeme.cpp
+
+   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.
+
+*/
+
+// XXX Remove me as soon as all using files have been converted to C++!
+
+#include "config.h"
+
+#include "threads/condition.hpp"
+#include "threads/mutex.hpp"
+
+extern "C" {
+
+Mutex* Mutex_new() { return new Mutex(); }
+void Mutex_delete(Mutex* mutex) { delete mutex; }
+void Mutex_lock(Mutex* mutex) { mutex->lock(); }
+void Mutex_unlock(Mutex* mutex) { mutex->unlock(); }
+
+Condition* Condition_new() { return new Condition(); }
+void Condition_delete(Condition* cond) { delete cond; }
+void Condition_broadcast(Condition* cond) { cond->broadcast(); }
+void Condition_signal(Condition* cond) { cond->signal(); }
+void Condition_timedwait(Condition* cond, Mutex* mutex, const struct timespec* abstime) { cond->timedwait(mutex, abstime); }
+void Condition_wait(Condition* cond, Mutex* mutex) { cond->wait(mutex); }
+
+}
+
+
+/*
+ * 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/threads/thread.c b/src/threads/thread.c
deleted file mode 100644 (file)
index 0bd495d..0000000
+++ /dev/null
@@ -1,1308 +0,0 @@
-/* src/threads/thread.c - machine independent thread functions
-
-   Copyright (C) 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 <unistd.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#if defined(ENABLE_GC_BOEHM)
-/* We need to include Boehm's gc.h here for GC_register_my_thread and
-   friends. */
-# include "mm/boehm-gc/include/gc.h"
-#endif
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Thread.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_ThreadGroup.h"
-#endif
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# include "native/include/java_lang_VMThread.h"
-#endif
-
-#include "threads/critical.h"
-#include "threads/lock-common.h"
-#include "threads/threadlist.h"
-#include "threads/thread.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#include "vmcore/utf8.h"
-
-
-/* global variables ***********************************************************/
-
-static methodinfo    *thread_method_init;
-static java_handle_t *threadgroup_system;
-static java_handle_t *threadgroup_main;
-
-#if defined(__LINUX__)
-/* XXX Remove for exact-GC. */
-bool threads_pthreads_implementation_nptl;
-#endif
-
-
-/* static functions ***********************************************************/
-
-static void          thread_create_initial_threadgroups(void);
-static void          thread_create_initial_thread(void);
-static threadobject *thread_new(void);
-
-
-/* threads_preinit *************************************************************
-
-   Do some early initialization of stuff required.
-
-*******************************************************************************/
-
-void threads_preinit(void)
-{
-       threadobject *mainthread;
-#if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
-       char         *pathbuf;
-       size_t        len;
-#endif
-
-       TRACESUBSYSTEMINITIALIZATION("threads_preinit");
-
-#if defined(__LINUX__)
-       /* XXX Remove for exact-GC. */
-
-       /* On Linux we need to check the pthread implementation. */
-
-       /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
-       /* If the glibc is a pre-2.3.2 version, we fall back to
-          linuxthreads. */
-
-# if defined(_CS_GNU_LIBPTHREAD_VERSION)
-       len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
-
-       /* Some systems return as length 0 (maybe cross-compilation
-          related).  In this case we also fall back to linuxthreads. */
-
-       if (len > 0) {
-               pathbuf = MNEW(char, len);
-
-               (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
-
-               if (strstr(pathbuf, "NPTL") != NULL)
-                       threads_pthreads_implementation_nptl = true;
-               else
-                       threads_pthreads_implementation_nptl = false;
-       }
-       else
-               threads_pthreads_implementation_nptl = false;
-# else
-       threads_pthreads_implementation_nptl = false;
-# endif
-#endif
-
-       /* Initialize the threads implementation (sets the thinlock on the
-          main thread). */
-
-       threads_impl_preinit();
-
-       /* Create internal thread data-structure for the main thread. */
-
-       mainthread = thread_new();
-
-       /* The main thread should always have index 1. */
-
-       if (mainthread->index != 1)
-               vm_abort("threads_preinit: main thread index not 1: %d != 1",
-                                mainthread->index);
-
-       /* thread is a Java thread and running */
-
-       mainthread->flags |= THREAD_FLAG_JAVA;
-       mainthread->state = THREAD_STATE_RUNNABLE;
-
-       /* Store the internal thread data-structure in the TSD. */
-
-       thread_set_current(mainthread);
-}
-
-
-/* threads_init ****************************************************************
-
-   Initialize the main thread.
-
-*******************************************************************************/
-
-void threads_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("threads_init");
-
-       /* Create the system and main thread groups. */
-
-       thread_create_initial_threadgroups();
-
-       /* Cache the java.lang.Thread initialization method. */
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       thread_method_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       thread_method_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       thread_method_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_java_lang_String__void,
-                                                                class_java_lang_Thread,
-                                                                true);
-
-#else
-# error unknown classpath configuration
-#endif
-
-       if (thread_method_init == NULL)
-               vm_abort("threads_init: failed to resolve thread init method");
-
-       thread_create_initial_thread();
-}
-
-
-/* thread_create_object ********************************************************
-
-   Create a Java thread object for the given thread data-structure,
-   initializes it and adds the thread to the threadgroup.
-
-   ARGUMENTS:
-
-       t ....... thread
-       name .... thread name
-       group ... threadgroup
-
-   RETURN:
-
-*******************************************************************************/
-
-static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
-{
-       java_handle_t    *o;
-       java_lang_Thread *to;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_VMThread    *vmto;
-       classinfo             *c;
-       methodinfo            *m;
-       bool                   isdaemon;
-#endif
-
-       /* Create a java.lang.Thread Java object. */
-
-       o = builtin_new(class_java_lang_Thread);
-
-       if (o == NULL)
-               return false;
-
-       to = (java_lang_Thread *) o;
-
-       /* Set the Java object in the thread data-structure.  This
-          indicates that the thread is attached to the VM. */
-
-       thread_set_object(t, (java_handle_t *) to);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Create a java.lang.VMThread Java object. */
-
-       vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
-
-       if (vmto == NULL)
-               return false;
-
-       /* Set the Java thread object in the Java VM-thread object. */
-
-       LLNI_field_set_ref(vmto, thread, to);
-
-       /* Set the thread data-structure in the Java VM-thread object. */
-
-       LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
-
-       /* Call:
-          java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
-
-       isdaemon = thread_is_daemon(t);
-
-       (void) vm_call_method(thread_method_init, o, vmto, name, NORM_PRIORITY,
-                                                 isdaemon);
-
-       if (exceptions_get_exception())
-               return false;
-
-       /* Set the threadgroup in the Java thread object. */
-
-       LLNI_field_set_ref(to, group, (java_lang_ThreadGroup *) group);
-
-       /* Add thread to the threadgroup. */
-
-       LLNI_class_get(group, c);
-
-       m = class_resolveclassmethod(c,
-                                                                utf_addThread,
-                                                                utf_java_lang_Thread__V,
-                                                                class_java_lang_ThreadGroup,
-                                                                true);
-
-       if (m == NULL)
-               return false;
-
-       (void) vm_call_method(m, group, to);
-
-       if (exceptions_get_exception())
-               return false;
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       /* OpenJDK's java.lang.Thread does not have a VMThread field in
-          the class.  Nothing to do here. */
-
-       /* Set the priority.  java.lang.Thread.<init> requires it because
-          it sets the priority of the current thread to the parent's one
-          (which is the current thread in this case). */
-
-       LLNI_field_set_val(to, priority, NORM_PRIORITY);
-
-       /* Call:
-          java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
-
-       (void) vm_call_method(thread_method_init, o, group, name);
-
-       if (exceptions_get_exception())
-               return false;
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       /* Set the thread data-structure in the Java thread object. */
-
-       LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
-
-       /* Call: public Thread(Ljava/lang/String;)V */
-
-       (void) vm_call_method(thread_method_init, o, name);
-
-       if (exceptions_get_exception())
-               return false;
-
-#else
-# error unknown classpath configuration
-#endif
-
-       return true;
-}
-
-
-/* thread_create_initial_threadgroups ******************************************
-
-   Create the initial threadgroups.
-
-   GNU Classpath:
-       Create the main threadgroup only and set the system
-       threadgroup to the main threadgroup.
-
-   SUN:
-       Create the system and main threadgroup.
-
-   CLDC:
-       This function is a no-op.
-
-*******************************************************************************/
-
-static void thread_create_initial_threadgroups(void)
-{
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Allocate and initialize the main thread group. */
-
-       threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
-
-       if (threadgroup_main == NULL)
-               vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
-
-       /* Use the same threadgroup for system as for main. */
-
-       threadgroup_system = threadgroup_main;
-
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       java_handle_t *name;
-       methodinfo    *m;
-
-       /* Allocate and initialize the system thread group. */
-
-       threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
-
-       if (threadgroup_system == NULL)
-               vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
-
-       /* Allocate and initialize the main thread group. */
-
-       threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
-
-       if (threadgroup_main == NULL)
-               vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
-
-       name = javastring_new(utf_main);
-
-       m = class_resolveclassmethod(class_java_lang_ThreadGroup,
-                                                                utf_init,
-                                                                utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
-                                                                class_java_lang_ThreadGroup,
-                                                                true);
-
-       if (m == NULL)
-               vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
-
-       (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
-
-       if (exceptions_get_exception())
-               vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
-
-# else
-#  error unknown classpath configuration
-# endif
-#endif
-}
-
-
-/* thread_create_initial_thread ***********************************************
-
-   Create the initial thread: main
-
-*******************************************************************************/
-
-static void thread_create_initial_thread(void)
-{
-       threadobject  *t;
-       java_handle_t *name;
-
-       /* Get the main-thread (NOTE: The main thread is always the first
-          thread in the list). */
-
-       t = threadlist_first();
-
-       /* The thread name. */
-
-       name = javastring_new(utf_main);
-
-#if defined(ENABLE_INTRP)
-       /* create interpreter stack */
-
-       if (opt_intrp) {
-               MSET(intrp_main_stack, 0, u1, opt_stacksize);
-               mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
-       }
-#endif
-
-       /* Create the Java thread object. */
-
-       if (!thread_create_object(t, name, threadgroup_main))
-               vm_abort("thread_create_initial_thread: failed to create Java object");
-
-       /* Initialize the implementation specific bits. */
-
-       threads_impl_init();
-
-       DEBUGTHREADS("starting (main)", t);
-}
-
-
-/* thread_new ******************************************************************
-
-   Allocates and initializes an internal thread data-structure and
-   adds it to the threads list.
-
-*******************************************************************************/
-
-static threadobject *thread_new(void)
-{
-       int32_t       index;
-       threadobject *t;
-       
-       /* Lock the thread lists */
-
-       threadlist_lock();
-
-       index = threadlist_get_free_index();
-
-       /* Allocate a thread data structure. */
-
-       /* First, try to get one from the free-list. */
-
-       t = threadlist_free_first();
-
-       if (t != NULL) {
-               /* Remove from free list. */
-
-               threadlist_free_remove(t);
-
-               /* Equivalent of MZERO on the else path */
-
-               threads_impl_thread_clear(t);
-       }
-       else {
-#if defined(ENABLE_GC_BOEHM)
-               t = GCNEW_UNCOLLECTABLE(threadobject, 1);
-#else
-               t = NEW(threadobject);
-#endif
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       size_threadobject += sizeof(threadobject);
-#endif
-
-               /* Clear memory. */
-
-               MZERO(t, threadobject, 1);
-
-#if defined(ENABLE_GC_CACAO)
-               /* Register reference to java.lang.Thread with the GC. */
-               /* FIXME is it ok to do this only once? */
-
-               gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
-               gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
-#endif
-
-               /* Initialize the implementation-specific bits. */
-
-               threads_impl_thread_init(t);
-       }
-
-       /* Pre-compute the thinlock-word. */
-
-       assert(index != 0);
-
-       t->index     = index;
-       t->thinlock  = lock_pre_compute_thinlock(t->index);
-       t->flags     = 0;
-       t->state     = THREAD_STATE_NEW;
-
-#if defined(ENABLE_GC_CACAO)
-       t->flags    |= THREAD_FLAG_IN_NATIVE; 
-#endif
-
-       /* Initialize the implementation-specific bits. */
-
-       threads_impl_thread_reuse(t);
-
-       /* Add the thread to the thread list. */
-
-       threadlist_add(t);
-
-       /* Unlock the thread lists. */
-
-       threadlist_unlock();
-
-       return t;
-}
-
-
-/* thread_free *****************************************************************
-
-   Remove the thread from the threads-list and free the internal
-   thread data structure.  The thread index is added to the
-   thread-index free-list.
-
-   IN:
-       t ... thread data structure
-
-*******************************************************************************/
-
-void thread_free(threadobject *t)
-{
-       /* Lock the thread lists. */
-
-       threadlist_lock();
-
-       /* Remove the thread from the thread-list. */
-
-       threadlist_remove(t);
-
-       /* Add the thread index to the free list. */
-
-       threadlist_index_add(t->index);
-
-       /* Set the reference to the Java object to NULL. */
-
-       thread_set_object(t, NULL);
-
-       /* Add the thread data structure to the free list. */
-
-       threadlist_free_add(t);
-
-       /* Unlock the thread lists. */
-
-       threadlist_unlock();
-}
-
-
-/* threads_thread_start_internal ***********************************************
-
-   Start an internal thread in the JVM.  No Java thread objects exists
-   so far.
-
-   IN:
-      name.......UTF-8 name of the thread
-      f..........function pointer to C function to start
-
-*******************************************************************************/
-
-bool threads_thread_start_internal(utf *name, functionptr f)
-{
-       threadobject *t;
-
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
-       /* Create internal thread data-structure. */
-
-       t = thread_new();
-
-       t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
-
-       /* The thread is flagged as (non-)daemon thread, we can leave the
-          mutex. */
-
-       threads_mutex_join_unlock();
-
-       /* Create the Java thread object. */
-
-       if (!thread_create_object(t, javastring_new(name), threadgroup_system))
-               return false;
-
-       /* Start the thread. */
-
-       threads_impl_thread_start(t, f);
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* threads_thread_start ********************************************************
-
-   Start a Java thread in the JVM.  Only the java thread object exists
-   so far.
-
-   IN:
-      object.....the java thread object java.lang.Thread
-
-*******************************************************************************/
-
-void threads_thread_start(java_handle_t *object)
-{
-       java_lang_Thread   *to;
-       threadobject       *t;
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_VMThread *vmto;
-#endif
-
-       to = (java_lang_Thread *) object;
-
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
-       /* Create internal thread data-structure. */
-
-       t = thread_new();
-
-       /* this is a normal Java thread */
-
-       t->flags |= THREAD_FLAG_JAVA;
-
-#if defined(ENABLE_JAVASE)
-       /* Is this a daemon thread? */
-
-       if (LLNI_field_direct(to, daemon) == true)
-               t->flags |= THREAD_FLAG_DAEMON;
-#endif
-
-       /* The thread is flagged and (non-)daemon thread, we can leave the
-          mutex. */
-
-       threads_mutex_join_unlock();
-
-       /* Link the two objects together. */
-
-       thread_set_object(t, object);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Get the java.lang.VMThread object and do some sanity checks. */
-
-       LLNI_field_get_ref(to, vmThread, vmto);
-
-       assert(vmto);
-       assert(LLNI_field_direct(vmto, vmdata) == NULL);
-
-       LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       /* Nothing to do. */
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
-
-#else
-# error unknown classpath configuration
-#endif
-
-       /* Start the thread.  Don't pass a function pointer (NULL) since
-          we want Thread.run()V here. */
-
-       threads_impl_thread_start(t, NULL);
-}
-
-
-/**
- * Attaches the current thread to the VM.
- *
- * @param vm_aargs Attach arguments.
- * @param isdaemon true if the attached thread should be a daemon
- *                 thread.
- *
- * @return true on success, false otherwise.
- */
-bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
-{
-       bool           result;
-       threadobject  *t;
-       utf           *u;
-       java_handle_t *name;
-       java_handle_t *group;
-
-    /* If the current thread has already been attached, this operation
-          is a no-op. */
-
-       result = thread_current_is_attached();
-
-       if (result == true)
-               return true;
-
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
-       /* Create internal thread data structure. */
-
-       t = thread_new();
-
-       /* Thread is a Java thread and running. */
-
-       t->flags = THREAD_FLAG_JAVA;
-
-       if (isdaemon)
-               t->flags |= THREAD_FLAG_DAEMON;
-
-       /* Store the internal thread data-structure in the TSD. */
-
-       thread_set_current(t);
-
-       /* The thread is flagged and (non-)daemon thread, we can leave the
-          mutex. */
-
-       threads_mutex_join_unlock();
-
-       DEBUGTHREADS("attaching", t);
-
-       /* Get the thread name. */
-
-       if (vm_aargs != NULL) {
-               u = utf_new_char(vm_aargs->name);
-       }
-       else {
-               u = utf_null;
-       }
-
-       name = javastring_new(u);
-
-#if defined(ENABLE_JAVASE)
-       /* Get the threadgroup. */
-
-       if (vm_aargs != NULL)
-               group = (java_handle_t *) vm_aargs->group;
-       else
-               group = NULL;
-
-       /* If no threadgroup was given, use the main threadgroup. */
-
-       if (group == NULL)
-               group = threadgroup_main;
-#endif
-
-#if defined(ENABLE_INTRP)
-       /* create interpreter stack */
-
-       if (opt_intrp) {
-               MSET(intrp_main_stack, 0, u1, opt_stacksize);
-               thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
-       }
-#endif
-
-       /* Create the Java thread object. */
-
-       if (!thread_create_object(t, name, group))
-               return false;
-
-       /* The thread is completely initialized. */
-
-       thread_set_state_runnable(t);
-
-       return true;
-}
-
-
-/**
- * Attaches the current external thread to the VM.  This function is
- * called by JNI's AttachCurrentThread.
- *
- * @param vm_aargs Attach arguments.
- * @param isdaemon true if the attached thread should be a daemon
- *                 thread.
- *
- * @return true on success, false otherwise.
- */
-bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
-{
-       int result;
-
-#if defined(ENABLE_GC_BOEHM)
-       struct GC_stack_base sb;
-#endif
-
-#if defined(ENABLE_GC_BOEHM)
-       /* Register the thread with Boehm-GC.  This must happen before the
-          thread allocates any memory from the GC heap.*/
-
-       result = GC_get_stack_base(&sb);
-
-       if (result != GC_SUCCESS)
-               vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
-
-       GC_register_my_thread(&sb);
-#endif
-
-       result = thread_attach_current_thread(vm_aargs, isdaemon);
-
-       if (result == false) {
-#if defined(ENABLE_GC_BOEHM)
-               /* Unregister the thread. */
-
-               GC_unregister_my_thread();
-#endif
-
-               return false;
-       }
-
-       return true;
-}
-
-
-/**
- * Detaches the current external thread from the VM.  This function is
- * called by JNI's DetachCurrentThread.
- *
- * @return true on success, false otherwise.
- */
-bool thread_detach_current_external_thread(void)
-{
-       int result;
-
-       result = thread_detach_current_thread();
-
-       if (result == false)
-               return false;
-
-#if defined(ENABLE_GC_BOEHM)
-       /* Unregister the thread with Boehm-GC.  This must happen after
-          the thread allocates any memory from the GC heap. */
-
-       /* Don't detach the main thread.  This is a workaround for
-          OpenJDK's java binary. */
-       if (thread_get_current()->index != 1)
-               GC_unregister_my_thread();
-#endif
-
-       return true;
-}
-
-
-/* thread_fprint_name **********************************************************
-
-   Print the name of the given thread to the given stream.
-
-   ARGUMENTS:
-       t ........ thread data-structure
-       stream ... stream to print to
-
-*******************************************************************************/
-
-void thread_fprint_name(threadobject *t, FILE *stream)
-{
-       java_lang_Thread *to;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_String *name;
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-       java_chararray_t *name;
-#endif
-
-       to = (java_lang_Thread *) thread_get_object(t);
-
-       if (to == NULL)
-               vm_abort("");
-
-       LLNI_field_get_ref(to, name, name);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       javastring_fprint((java_handle_t *) name, stream);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       /* FIXME: In OpenJDK and CLDC the name is a char[]. */
-       /* FIXME This prints to stdout. */
-       utf_display_printable_ascii(utf_null);
-
-#else
-# error unknown classpath configuration
-#endif
-}
-
-
-/* thread_print_info ***********************************************************
-
-   Print information of the passed thread.
-
-   ARGUMENTS:
-       t ... thread data-structure.
-
-*******************************************************************************/
-
-void thread_print_info(threadobject *t)
-{
-       java_lang_Thread *to;
-       int               state;
-
-       /* If the thread is currently in initalization, don't print it. */
-
-       to = (java_lang_Thread *) thread_get_object(t);
-
-       /* Print as much as we can when we are in state NEW. */
-
-       if (to != NULL) {
-               /* Print thread name. */
-
-               printf("\"");
-               thread_fprint_name(t, stdout);
-               printf("\"");
-       }
-       else {
-       }
-
-       if (thread_is_daemon(t))
-               printf(" daemon");
-
-       if (to != NULL) {
-               printf(" prio=%d", LLNI_field_direct(to, priority));
-       }
-
-#if SIZEOF_VOID_P == 8
-       printf(" t=0x%016lx tid=0x%016lx (%ld)",
-                  (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
-#else
-       printf(" t=0x%08x tid=0x%08x (%d)",
-                  (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
-#endif
-
-       printf(" index=%d", t->index);
-
-       /* Print thread state. */
-
-       state = cacaothread_get_state(t);
-
-       switch (state) {
-       case THREAD_STATE_NEW:
-               printf(" new");
-               break;
-       case THREAD_STATE_RUNNABLE:
-               printf(" runnable");
-               break;
-       case THREAD_STATE_BLOCKED:
-               printf(" blocked");
-               break;
-       case THREAD_STATE_WAITING:
-               printf(" waiting");
-               break;
-       case THREAD_STATE_TIMED_WAITING:
-               printf(" waiting on condition");
-               break;
-       case THREAD_STATE_TERMINATED:
-               printf(" terminated");
-               break;
-       default:
-               vm_abort("thread_print_info: unknown thread state %d", state);
-       }
-}
-
-
-/* threads_get_current_tid *****************************************************
-
-   Return the tid of the current thread.
-   
-   RETURN VALUE:
-       the current tid
-
-*******************************************************************************/
-
-intptr_t threads_get_current_tid(void)
-{
-       threadobject *thread;
-
-       thread = THREADOBJECT;
-
-       /* this may happen during bootstrap */
-
-       if (thread == NULL)
-               return 0;
-
-       return (intptr_t) thread->tid;
-}
-
-
-/* thread_set_state_runnable ***************************************************
-
-   Set the current state of the given thread to THREAD_STATE_RUNNABLE.
-
-   NOTE: If the thread has already terminated, don't set the state.
-         This is important for threads_detach_thread.
-
-*******************************************************************************/
-
-void thread_set_state_runnable(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threadlist_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_RUNNABLE;
-
-               DEBUGTHREADS("is RUNNABLE", t);
-       }
-
-       threadlist_unlock();
-}
-
-
-/* thread_set_state_waiting ****************************************************
-
-   Set the current state of the given thread to THREAD_STATE_WAITING.
-
-   NOTE: If the thread has already terminated, don't set the state.
-         This is important for threads_detach_thread.
-
-*******************************************************************************/
-
-void thread_set_state_waiting(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threadlist_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_WAITING;
-
-               DEBUGTHREADS("is WAITING", t);
-       }
-
-       threadlist_unlock();
-}
-
-
-/* thread_set_state_timed_waiting **********************************************
-
-   Set the current state of the given thread to
-   THREAD_STATE_TIMED_WAITING.
-
-   NOTE: If the thread has already terminated, don't set the state.
-         This is important for threads_detach_thread.
-
-*******************************************************************************/
-
-void thread_set_state_timed_waiting(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threadlist_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_TIMED_WAITING;
-
-               DEBUGTHREADS("is TIMED_WAITING", t);
-       }
-
-       threadlist_unlock();
-}
-
-
-/* thread_set_state_terminated *************************************************
-
-   Set the current state of the given thread to
-   THREAD_STATE_TERMINATED.
-
-*******************************************************************************/
-
-void thread_set_state_terminated(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threadlist_lock();
-
-       t->state = THREAD_STATE_TERMINATED;
-
-       DEBUGTHREADS("is TERMINATED", t);
-
-       threadlist_unlock();
-}
-
-
-/* thread_get_thread **********************************************************
-
-   Return the thread data structure of the given Java thread object.
-
-   ARGUMENTS:
-       h ... java.lang.{VM}Thread object
-
-   RETURN VALUE:
-       the thread object
-
-*******************************************************************************/
-
-threadobject *thread_get_thread(java_handle_t *h)
-{
-       threadobject       *t;
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_VMThread *vmto;
-       java_lang_Object   *to;
-#endif
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       bool                equal;
-#endif
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       vmto = (java_lang_VMThread *) h;
-
-       LLNI_field_get_val(vmto, vmdata, to);
-
-       t = (threadobject *) to;
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       /* XXX This is just a quick hack. */
-
-       threadlist_lock();
-
-       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
-               LLNI_equals(t->object, h, equal);
-
-               if (equal == true)
-                       break;
-       }
-
-       threadlist_unlock();
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       log_println("threads_get_thread: IMPLEMENT ME!");
-
-#else
-# error unknown classpath configuration
-#endif
-
-       return t;
-}
-
-
-/* threads_thread_is_alive *****************************************************
-
-   Returns if the give thread is alive.
-
-*******************************************************************************/
-
-bool threads_thread_is_alive(threadobject *t)
-{
-       int state;
-
-       state = cacaothread_get_state(t);
-
-       switch (state) {
-       case THREAD_STATE_NEW:
-       case THREAD_STATE_TERMINATED:
-               return false;
-
-       case THREAD_STATE_RUNNABLE:
-       case THREAD_STATE_BLOCKED:
-       case THREAD_STATE_WAITING:
-       case THREAD_STATE_TIMED_WAITING:
-               return true;
-
-       default:
-               vm_abort("threads_thread_is_alive: unknown thread state %d", state);
-       }
-
-       /* keep compiler happy */
-
-       return false;
-}
-
-
-/* threads_dump ****************************************************************
-
-   Dumps info for all threads running in the JVM.  This function is
-   called when SIGQUIT (<ctrl>-\) is sent to CACAO.
-
-*******************************************************************************/
-
-void threads_dump(void)
-{
-       threadobject *t;
-
-       /* XXX we should stop the world here */
-
-       /* Lock the thread lists. */
-
-       threadlist_lock();
-
-       printf("Full thread dump CACAO "VERSION":\n");
-
-       /* iterate over all started threads */
-
-       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
-               /* ignore threads which are in state NEW */
-               if (t->state == THREAD_STATE_NEW)
-                       continue;
-
-#if defined(ENABLE_GC_CACAO)
-               /* Suspend the thread. */
-               /* XXX Is the suspend reason correct? */
-
-               if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
-                       vm_abort("threads_dump: threads_suspend_thread failed");
-#endif
-
-               /* Print thread info. */
-
-               printf("\n");
-               thread_print_info(t);
-               printf("\n");
-
-               /* Print trace of thread. */
-
-               stacktrace_print_of_thread(t);
-
-#if defined(ENABLE_GC_CACAO)
-               /* Resume the thread. */
-
-               if (threads_resume_thread(t) == false)
-                       vm_abort("threads_dump: threads_resume_thread failed");
-#endif
-       }
-
-       /* Unlock the thread lists. */
-
-       threadlist_unlock();
-}
-
-
-/*
- * 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/threads/thread.cpp b/src/threads/thread.cpp
new file mode 100644 (file)
index 0000000..4d4d4c6
--- /dev/null
@@ -0,0 +1,1247 @@
+/* src/threads/thread.cpp - machine independent thread functions
+
+   Copyright (C) 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 <unistd.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#if defined(ENABLE_GC_BOEHM)
+/* We need to include Boehm's gc.h here for GC_register_my_thread and
+   friends. */
+# include "mm/boehm-gc/include/gc.h"
+#endif
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#include "threads/lock-common.h"
+#include "threads/threadlist.h"
+#include "threads/thread.hpp"
+
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/jit/stacktrace.hpp"
+
+
+// FIXME
+extern "C" {
+
+/* global variables ***********************************************************/
+
+static methodinfo    *thread_method_init;
+static java_handle_t *threadgroup_system;
+static java_handle_t *threadgroup_main;
+
+#if defined(__LINUX__)
+/* XXX Remove for exact-GC. */
+bool threads_pthreads_implementation_nptl;
+#endif
+
+
+/* static functions ***********************************************************/
+
+static void          thread_create_initial_threadgroups(void);
+static void          thread_create_initial_thread(void);
+static threadobject *thread_new(void);
+
+
+/* threads_preinit *************************************************************
+
+   Do some early initialization of stuff required.
+
+*******************************************************************************/
+
+void threads_preinit(void)
+{
+       threadobject *mainthread;
+#if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
+       char         *pathbuf;
+       size_t        len;
+#endif
+
+       TRACESUBSYSTEMINITIALIZATION("threads_preinit");
+
+#if defined(__LINUX__)
+       /* XXX Remove for exact-GC. */
+
+       /* On Linux we need to check the pthread implementation. */
+
+       /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
+       /* If the glibc is a pre-2.3.2 version, we fall back to
+          linuxthreads. */
+
+# if defined(_CS_GNU_LIBPTHREAD_VERSION)
+       len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
+
+       /* Some systems return as length 0 (maybe cross-compilation
+          related).  In this case we also fall back to linuxthreads. */
+
+       if (len > 0) {
+               pathbuf = MNEW(char, len);
+
+               (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
+
+               if (strstr(pathbuf, "NPTL") != NULL)
+                       threads_pthreads_implementation_nptl = true;
+               else
+                       threads_pthreads_implementation_nptl = false;
+       }
+       else
+               threads_pthreads_implementation_nptl = false;
+# else
+       threads_pthreads_implementation_nptl = false;
+# endif
+#endif
+
+       /* Initialize the threads implementation (sets the thinlock on the
+          main thread). */
+
+       threads_impl_preinit();
+
+       /* Create internal thread data-structure for the main thread. */
+
+       mainthread = thread_new();
+
+       /* The main thread should always have index 1. */
+
+       if (mainthread->index != 1)
+               vm_abort("threads_preinit: main thread index not 1: %d != 1",
+                                mainthread->index);
+
+       /* thread is a Java thread and running */
+
+       mainthread->flags |= THREAD_FLAG_JAVA;
+       mainthread->state = THREAD_STATE_RUNNABLE;
+
+       /* Store the internal thread data-structure in the TSD. */
+
+       thread_set_current(mainthread);
+}
+
+
+/* threads_init ****************************************************************
+
+   Initialize the main thread.
+
+*******************************************************************************/
+
+void threads_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("threads_init");
+
+       /* Create the system and main thread groups. */
+
+       thread_create_initial_threadgroups();
+
+       /* Cache the java.lang.Thread initialization method. */
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
+                                                                class_java_lang_Thread,
+                                                                true);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
+                                                                class_java_lang_Thread,
+                                                                true);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_java_lang_String__void,
+                                                                class_java_lang_Thread,
+                                                                true);
+
+#else
+# error unknown classpath configuration
+#endif
+
+       if (thread_method_init == NULL)
+               vm_abort("threads_init: failed to resolve thread init method");
+
+       thread_create_initial_thread();
+}
+
+
+/* thread_create_object ********************************************************
+
+   Create a Java thread object for the given thread data-structure,
+   initializes it and adds the thread to the threadgroup.
+
+   ARGUMENTS:
+
+       t ....... thread
+       name .... thread name
+       group ... threadgroup
+
+   RETURN:
+
+*******************************************************************************/
+
+static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
+{
+       /* Create a java.lang.Thread Java object. */
+
+       java_handle_t* h = builtin_new(class_java_lang_Thread);
+
+       if (h == NULL)
+               return false;
+
+       java_lang_Thread jlt(h);
+
+       // Set the Java object in the thread data-structure.  This
+       // indicates that the thread is attached to the VM.
+       thread_set_object(t, jlt.get_handle());
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       h = builtin_new(class_java_lang_VMThread);
+
+       if (h == NULL)
+               return false;
+
+       // Create and initialize a java.lang.VMThread object.
+       java_lang_VMThread jlvmt(h, jlt.get_handle(), t);
+
+       /* Call:
+          java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
+
+       bool isdaemon = thread_is_daemon(t);
+
+       (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(),
+                                                 name, NORM_PRIORITY, isdaemon);
+
+       if (exceptions_get_exception())
+               return false;
+
+       // Set the ThreadGroup in the Java thread object.
+       jlt.set_group(group);
+
+       /* Add thread to the threadgroup. */
+
+       classinfo* c;
+       LLNI_class_get(group, c);
+
+       methodinfo* m = class_resolveclassmethod(c,
+                                                                                        utf_addThread,
+                                                                                        utf_java_lang_Thread__V,
+                                                                                        class_java_lang_ThreadGroup,
+                                                                                        true);
+
+       if (m == NULL)
+               return false;
+
+       (void) vm_call_method(m, group, jlt.get_handle());
+
+       if (exceptions_get_exception())
+               return false;
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       /* Set the priority.  java.lang.Thread.<init> requires it because
+          it sets the priority of the current thread to the parent's one
+          (which is the current thread in this case). */
+       jlt.set_priority(NORM_PRIORITY);
+
+       // Call: java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V
+
+       (void) vm_call_method(thread_method_init, jlt.get_handle(), group, name);
+
+       if (exceptions_get_exception())
+               return false;
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       // Set the thread data-structure in the Java thread object.
+       jlt.set_vm_thread(t);
+
+       // Call: public Thread(Ljava/lang/String;)V
+       (void) vm_call_method(thread_method_init, jlt.get_handle(), name);
+
+       if (exceptions_get_exception())
+               return false;
+
+#else
+# error unknown classpath configuration
+#endif
+
+       return true;
+}
+
+
+/* thread_create_initial_threadgroups ******************************************
+
+   Create the initial threadgroups.
+
+   GNU Classpath:
+       Create the main threadgroup only and set the system
+       threadgroup to the main threadgroup.
+
+   SUN:
+       Create the system and main threadgroup.
+
+   CLDC:
+       This function is a no-op.
+
+*******************************************************************************/
+
+static void thread_create_initial_threadgroups(void)
+{
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       /* Allocate and initialize the main thread group. */
+
+       threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
+
+       if (threadgroup_main == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
+
+       /* Use the same threadgroup for system as for main. */
+
+       threadgroup_system = threadgroup_main;
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       java_handle_t *name;
+       methodinfo    *m;
+
+       /* Allocate and initialize the system thread group. */
+
+       threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
+
+       if (threadgroup_system == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
+
+       /* Allocate and initialize the main thread group. */
+
+       threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
+
+       if (threadgroup_main == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
+
+       name = javastring_new(utf_main);
+
+       m = class_resolveclassmethod(class_java_lang_ThreadGroup,
+                                                                utf_init,
+                                                                utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
+                                                                class_java_lang_ThreadGroup,
+                                                                true);
+
+       if (m == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
+
+       (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
+
+       if (exceptions_get_exception())
+               vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
+
+# else
+#  error unknown classpath configuration
+# endif
+#endif
+}
+
+
+/* thread_create_initial_thread ***********************************************
+
+   Create the initial thread: main
+
+*******************************************************************************/
+
+static void thread_create_initial_thread(void)
+{
+       threadobject  *t;
+       java_handle_t *name;
+
+       /* Get the main-thread (NOTE: The main thread is always the first
+          thread in the list). */
+
+       t = threadlist_first();
+
+       /* The thread name. */
+
+       name = javastring_new(utf_main);
+
+#if defined(ENABLE_INTRP)
+       /* create interpreter stack */
+
+       if (opt_intrp) {
+               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+               mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
+       }
+#endif
+
+       /* Create the Java thread object. */
+
+       if (!thread_create_object(t, name, threadgroup_main))
+               vm_abort("thread_create_initial_thread: failed to create Java object");
+
+       /* Initialize the implementation specific bits. */
+
+       threads_impl_init();
+
+       DEBUGTHREADS("starting (main)", t);
+}
+
+
+/* thread_new ******************************************************************
+
+   Allocates and initializes an internal thread data-structure and
+   adds it to the threads list.
+
+*******************************************************************************/
+
+static threadobject *thread_new(void)
+{
+       int32_t       index;
+       threadobject *t;
+       
+       /* Lock the thread lists */
+
+       threadlist_lock();
+
+       index = threadlist_get_free_index();
+
+       /* Allocate a thread data structure. */
+
+       /* First, try to get one from the free-list. */
+
+       t = threadlist_free_first();
+
+       if (t != NULL) {
+               /* Remove from free list. */
+
+               threadlist_free_remove(t);
+
+               /* Equivalent of MZERO on the else path */
+
+               threads_impl_thread_clear(t);
+       }
+       else {
+#if defined(ENABLE_GC_BOEHM)
+               t = GCNEW_UNCOLLECTABLE(threadobject, 1);
+#else
+               t = NEW(threadobject);
+#endif
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       size_threadobject += sizeof(threadobject);
+#endif
+
+               /* Clear memory. */
+
+               MZERO(t, threadobject, 1);
+
+#if defined(ENABLE_GC_CACAO)
+               /* Register reference to java.lang.Thread with the GC. */
+               /* FIXME is it ok to do this only once? */
+
+               gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
+               gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
+#endif
+
+               /* Initialize the implementation-specific bits. */
+
+               threads_impl_thread_init(t);
+       }
+
+       /* Pre-compute the thinlock-word. */
+
+       assert(index != 0);
+
+       t->index     = index;
+       t->thinlock  = lock_pre_compute_thinlock(t->index);
+       t->flags     = 0;
+       t->state     = THREAD_STATE_NEW;
+
+#if defined(ENABLE_GC_CACAO)
+       t->flags    |= THREAD_FLAG_IN_NATIVE; 
+#endif
+
+       /* Initialize the implementation-specific bits. */
+
+       threads_impl_thread_reuse(t);
+
+       /* Add the thread to the thread list. */
+
+       threadlist_add(t);
+
+       /* Unlock the thread lists. */
+
+       threadlist_unlock();
+
+       return t;
+}
+
+
+/* thread_free *****************************************************************
+
+   Remove the thread from the threads-list and free the internal
+   thread data structure.  The thread index is added to the
+   thread-index free-list.
+
+   IN:
+       t ... thread data structure
+
+*******************************************************************************/
+
+void thread_free(threadobject *t)
+{
+       /* Lock the thread lists. */
+
+       threadlist_lock();
+
+       /* Remove the thread from the thread-list. */
+
+       threadlist_remove(t);
+
+       /* Add the thread index to the free list. */
+
+       threadlist_index_add(t->index);
+
+       /* Set the reference to the Java object to NULL. */
+
+       thread_set_object(t, NULL);
+
+       /* Add the thread data structure to the free list. */
+
+       threadlist_free_add(t);
+
+       /* Unlock the thread lists. */
+
+       threadlist_unlock();
+}
+
+
+/* threads_thread_start_internal ***********************************************
+
+   Start an internal thread in the JVM.  No Java thread objects exists
+   so far.
+
+   IN:
+      name.......UTF-8 name of the thread
+      f..........function pointer to C function to start
+
+*******************************************************************************/
+
+bool threads_thread_start_internal(utf *name, functionptr f)
+{
+       threadobject *t;
+
+       /* Enter the join-mutex, so if the main-thread is currently
+          waiting to join all threads, the number of non-daemon threads
+          is correct. */
+
+       threads_mutex_join_lock();
+
+       /* Create internal thread data-structure. */
+
+       t = thread_new();
+
+       t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
+
+       /* The thread is flagged as (non-)daemon thread, we can leave the
+          mutex. */
+
+       threads_mutex_join_unlock();
+
+       /* Create the Java thread object. */
+
+       if (!thread_create_object(t, javastring_new(name), threadgroup_system))
+               return false;
+
+       /* Start the thread. */
+
+       threads_impl_thread_start(t, f);
+
+       /* everything's ok */
+
+       return true;
+}
+
+
+/* threads_thread_start ********************************************************
+
+   Start a Java thread in the JVM.  Only the java thread object exists
+   so far.
+
+   IN:
+      object.....the java thread object java.lang.Thread
+
+*******************************************************************************/
+
+void threads_thread_start(java_handle_t *object)
+{
+       java_lang_Thread jlt(object);
+
+       /* Enter the join-mutex, so if the main-thread is currently
+          waiting to join all threads, the number of non-daemon threads
+          is correct. */
+
+       threads_mutex_join_lock();
+
+       /* Create internal thread data-structure. */
+
+       threadobject* t = thread_new();
+
+       /* this is a normal Java thread */
+
+       t->flags |= THREAD_FLAG_JAVA;
+
+#if defined(ENABLE_JAVASE)
+       /* Is this a daemon thread? */
+
+       if (jlt.get_daemon() == true)
+               t->flags |= THREAD_FLAG_DAEMON;
+#endif
+
+       /* The thread is flagged and (non-)daemon thread, we can leave the
+          mutex. */
+
+       threads_mutex_join_unlock();
+
+       /* Link the two objects together. */
+
+       thread_set_object(t, object);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       /* Get the java.lang.VMThread object and do some sanity checks. */
+       java_lang_VMThread jlvmt(jlt.get_vmThread());
+
+       assert(jlvmt.get_handle() != NULL);
+       assert(jlvmt.get_vmdata() == NULL);
+
+       jlvmt.set_vmdata(t);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       // Nothing to do.
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       jlt.set_vm_thread(t);
+
+#else
+# error unknown classpath configuration
+#endif
+
+       /* Start the thread.  Don't pass a function pointer (NULL) since
+          we want Thread.run()V here. */
+
+       threads_impl_thread_start(t, NULL);
+}
+
+
+/**
+ * Attaches the current thread to the VM.
+ *
+ * @param vm_aargs Attach arguments.
+ * @param isdaemon true if the attached thread should be a daemon
+ *                 thread.
+ *
+ * @return true on success, false otherwise.
+ */
+bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
+{
+       bool           result;
+       threadobject  *t;
+       utf           *u;
+       java_handle_t *name;
+       java_handle_t *group;
+
+    /* If the current thread has already been attached, this operation
+          is a no-op. */
+
+       result = thread_current_is_attached();
+
+       if (result == true)
+               return true;
+
+       /* Enter the join-mutex, so if the main-thread is currently
+          waiting to join all threads, the number of non-daemon threads
+          is correct. */
+
+       threads_mutex_join_lock();
+
+       /* Create internal thread data structure. */
+
+       t = thread_new();
+
+       /* Thread is a Java thread and running. */
+
+       t->flags = THREAD_FLAG_JAVA;
+
+       if (isdaemon)
+               t->flags |= THREAD_FLAG_DAEMON;
+
+       /* Store the internal thread data-structure in the TSD. */
+
+       thread_set_current(t);
+
+       /* The thread is flagged and (non-)daemon thread, we can leave the
+          mutex. */
+
+       threads_mutex_join_unlock();
+
+       DEBUGTHREADS("attaching", t);
+
+       /* Get the thread name. */
+
+       if (vm_aargs != NULL) {
+               u = utf_new_char(vm_aargs->name);
+       }
+       else {
+               u = utf_null;
+       }
+
+       name = javastring_new(u);
+
+#if defined(ENABLE_JAVASE)
+       /* Get the threadgroup. */
+
+       if (vm_aargs != NULL)
+               group = (java_handle_t *) vm_aargs->group;
+       else
+               group = NULL;
+
+       /* If no threadgroup was given, use the main threadgroup. */
+
+       if (group == NULL)
+               group = threadgroup_main;
+#endif
+
+#if defined(ENABLE_INTRP)
+       /* create interpreter stack */
+
+       if (opt_intrp) {
+               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+               thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
+       }
+#endif
+
+       /* Create the Java thread object. */
+
+       if (!thread_create_object(t, name, group))
+               return false;
+
+       /* The thread is completely initialized. */
+
+       thread_set_state_runnable(t);
+
+       return true;
+}
+
+
+/**
+ * Attaches the current external thread to the VM.  This function is
+ * called by JNI's AttachCurrentThread.
+ *
+ * @param vm_aargs Attach arguments.
+ * @param isdaemon true if the attached thread should be a daemon
+ *                 thread.
+ *
+ * @return true on success, false otherwise.
+ */
+bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
+{
+       int result;
+
+#if defined(ENABLE_GC_BOEHM)
+       struct GC_stack_base sb;
+#endif
+
+#if defined(ENABLE_GC_BOEHM)
+       /* Register the thread with Boehm-GC.  This must happen before the
+          thread allocates any memory from the GC heap.*/
+
+       result = GC_get_stack_base(&sb);
+
+       if (result != GC_SUCCESS)
+               vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
+
+       GC_register_my_thread(&sb);
+#endif
+
+       result = thread_attach_current_thread(vm_aargs, isdaemon);
+
+       if (result == false) {
+#if defined(ENABLE_GC_BOEHM)
+               /* Unregister the thread. */
+
+               GC_unregister_my_thread();
+#endif
+
+               return false;
+       }
+
+       return true;
+}
+
+
+/**
+ * Detaches the current external thread from the VM.  This function is
+ * called by JNI's DetachCurrentThread.
+ *
+ * @return true on success, false otherwise.
+ */
+bool thread_detach_current_external_thread(void)
+{
+       int result;
+
+       result = thread_detach_current_thread();
+
+       if (result == false)
+               return false;
+
+#if defined(ENABLE_GC_BOEHM)
+       /* Unregister the thread with Boehm-GC.  This must happen after
+          the thread allocates any memory from the GC heap. */
+
+       /* Don't detach the main thread.  This is a workaround for
+          OpenJDK's java binary. */
+       if (thread_get_current()->index != 1)
+               GC_unregister_my_thread();
+#endif
+
+       return true;
+}
+
+
+/* thread_fprint_name **********************************************************
+
+   Print the name of the given thread to the given stream.
+
+   ARGUMENTS:
+       t ........ thread data-structure
+       stream ... stream to print to
+
+*******************************************************************************/
+
+void thread_fprint_name(threadobject *t, FILE *stream)
+{
+       if (thread_get_object(t) == NULL)
+               vm_abort("");
+
+       java_lang_Thread jlt(thread_get_object(t));
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       java_handle_t* name = jlt.get_name();
+       javastring_fprint(name, stream);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       /* FIXME: In OpenJDK and CLDC the name is a char[]. */
+       java_chararray_t *name;
+
+       /* FIXME This prints to stdout. */
+       utf_display_printable_ascii(utf_null);
+
+#else
+# error unknown classpath configuration
+#endif
+}
+
+
+/* thread_print_info ***********************************************************
+
+   Print information of the passed thread.
+
+   ARGUMENTS:
+       t ... thread data-structure.
+
+*******************************************************************************/
+
+void thread_print_info(threadobject *t)
+{
+       java_lang_Thread jlt(thread_get_object(t));
+
+       /* Print as much as we can when we are in state NEW. */
+
+       if (jlt.get_handle() != NULL) {
+               /* Print thread name. */
+
+               printf("\"");
+               thread_fprint_name(t, stdout);
+               printf("\"");
+       }
+       else {
+       }
+
+       if (thread_is_daemon(t))
+               printf(" daemon");
+
+       if (jlt.get_handle() != NULL) {
+               printf(" prio=%d", jlt.get_priority());
+       }
+
+#if SIZEOF_VOID_P == 8
+       printf(" t=0x%016lx tid=0x%016lx (%ld)",
+                  (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
+#else
+       printf(" t=0x%08x tid=0x%08x (%d)",
+                  (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
+#endif
+
+       printf(" index=%d", t->index);
+
+       /* Print thread state. */
+
+       int state = cacaothread_get_state(t);
+
+       switch (state) {
+       case THREAD_STATE_NEW:
+               printf(" new");
+               break;
+       case THREAD_STATE_RUNNABLE:
+               printf(" runnable");
+               break;
+       case THREAD_STATE_BLOCKED:
+               printf(" blocked");
+               break;
+       case THREAD_STATE_WAITING:
+               printf(" waiting");
+               break;
+       case THREAD_STATE_TIMED_WAITING:
+               printf(" waiting on condition");
+               break;
+       case THREAD_STATE_TERMINATED:
+               printf(" terminated");
+               break;
+       default:
+               vm_abort("thread_print_info: unknown thread state %d", state);
+       }
+}
+
+
+/* threads_get_current_tid *****************************************************
+
+   Return the tid of the current thread.
+   
+   RETURN VALUE:
+       the current tid
+
+*******************************************************************************/
+
+intptr_t threads_get_current_tid(void)
+{
+       threadobject *thread;
+
+       thread = THREADOBJECT;
+
+       /* this may happen during bootstrap */
+
+       if (thread == NULL)
+               return 0;
+
+       return (intptr_t) thread->tid;
+}
+
+
+/* thread_set_state_runnable ***************************************************
+
+   Set the current state of the given thread to THREAD_STATE_RUNNABLE.
+
+   NOTE: If the thread has already terminated, don't set the state.
+         This is important for threads_detach_thread.
+
+*******************************************************************************/
+
+void thread_set_state_runnable(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       threadlist_lock();
+
+       if (t->state != THREAD_STATE_TERMINATED) {
+               t->state = THREAD_STATE_RUNNABLE;
+
+               DEBUGTHREADS("is RUNNABLE", t);
+       }
+
+       threadlist_unlock();
+}
+
+
+/* thread_set_state_waiting ****************************************************
+
+   Set the current state of the given thread to THREAD_STATE_WAITING.
+
+   NOTE: If the thread has already terminated, don't set the state.
+         This is important for threads_detach_thread.
+
+*******************************************************************************/
+
+void thread_set_state_waiting(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       threadlist_lock();
+
+       if (t->state != THREAD_STATE_TERMINATED) {
+               t->state = THREAD_STATE_WAITING;
+
+               DEBUGTHREADS("is WAITING", t);
+       }
+
+       threadlist_unlock();
+}
+
+
+/* thread_set_state_timed_waiting **********************************************
+
+   Set the current state of the given thread to
+   THREAD_STATE_TIMED_WAITING.
+
+   NOTE: If the thread has already terminated, don't set the state.
+         This is important for threads_detach_thread.
+
+*******************************************************************************/
+
+void thread_set_state_timed_waiting(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       threadlist_lock();
+
+       if (t->state != THREAD_STATE_TERMINATED) {
+               t->state = THREAD_STATE_TIMED_WAITING;
+
+               DEBUGTHREADS("is TIMED_WAITING", t);
+       }
+
+       threadlist_unlock();
+}
+
+
+/* thread_set_state_terminated *************************************************
+
+   Set the current state of the given thread to
+   THREAD_STATE_TERMINATED.
+
+*******************************************************************************/
+
+void thread_set_state_terminated(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       threadlist_lock();
+
+       t->state = THREAD_STATE_TERMINATED;
+
+       DEBUGTHREADS("is TERMINATED", t);
+
+       threadlist_unlock();
+}
+
+
+/* thread_get_thread **********************************************************
+
+   Return the thread data structure of the given Java thread object.
+
+   ARGUMENTS:
+       h ... java.lang.{VM}Thread object
+
+   RETURN VALUE:
+       the thread object
+
+*******************************************************************************/
+
+threadobject *thread_get_thread(java_handle_t *h)
+{
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       java_lang_VMThread jlvmt(h);
+       threadobject* t = jlvmt.get_vmdata();
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       /* XXX This is just a quick hack. */
+       threadobject* t;
+       bool          equal;
+
+       threadlist_lock();
+
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               LLNI_equals(t->object, h, equal);
+
+               if (equal == true)
+                       break;
+       }
+
+       threadlist_unlock();
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       log_println("threads_get_thread: IMPLEMENT ME!");
+       threadobject* t = NULL;
+
+#else
+# error unknown classpath configuration
+#endif
+
+       return t;
+}
+
+
+/* threads_thread_is_alive *****************************************************
+
+   Returns if the give thread is alive.
+
+*******************************************************************************/
+
+bool threads_thread_is_alive(threadobject *t)
+{
+       int state;
+
+       state = cacaothread_get_state(t);
+
+       switch (state) {
+       case THREAD_STATE_NEW:
+       case THREAD_STATE_TERMINATED:
+               return false;
+
+       case THREAD_STATE_RUNNABLE:
+       case THREAD_STATE_BLOCKED:
+       case THREAD_STATE_WAITING:
+       case THREAD_STATE_TIMED_WAITING:
+               return true;
+
+       default:
+               vm_abort("threads_thread_is_alive: unknown thread state %d", state);
+       }
+
+       /* keep compiler happy */
+
+       return false;
+}
+
+
+/* threads_dump ****************************************************************
+
+   Dumps info for all threads running in the JVM.  This function is
+   called when SIGQUIT (<ctrl>-\) is sent to CACAO.
+
+*******************************************************************************/
+
+void threads_dump(void)
+{
+       threadobject *t;
+
+       /* XXX we should stop the world here */
+
+       /* Lock the thread lists. */
+
+       threadlist_lock();
+
+       printf("Full thread dump CACAO "VERSION":\n");
+
+       /* iterate over all started threads */
+
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               /* ignore threads which are in state NEW */
+               if (t->state == THREAD_STATE_NEW)
+                       continue;
+
+#if defined(ENABLE_GC_CACAO)
+               /* Suspend the thread. */
+               /* XXX Is the suspend reason correct? */
+
+               if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
+                       vm_abort("threads_dump: threads_suspend_thread failed");
+#endif
+
+               /* Print thread info. */
+
+               printf("\n");
+               thread_print_info(t);
+               printf("\n");
+
+               /* Print trace of thread. */
+
+               stacktrace_print_of_thread(t);
+
+#if defined(ENABLE_GC_CACAO)
+               /* Resume the thread. */
+
+               if (threads_resume_thread(t) == false)
+                       vm_abort("threads_dump: threads_resume_thread failed");
+#endif
+       }
+
+       /* Unlock the thread lists. */
+
+       threadlist_unlock();
+}
+
+} // extern "C"
+
+
+/*
+ * 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/threads/thread.h b/src/threads/thread.h
deleted file mode 100644 (file)
index 309de1a..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/* src/threads/thread.h - machine independent thread functions
-
-   Copyright (C) 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 _THREAD_H
-#define _THREAD_H
-
-#include "config.h"
-
-#include "vmcore/system.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/posix/thread-posix.h"
-#else
-# include "threads/none/thread-none.h"
-#endif
-
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-
-#include "vmcore/utf8.h"
-
-
-/* only define the following stuff with thread enabled ************************/
-
-#if defined(ENABLE_THREADS)
-
-/* thread states **************************************************************/
-
-#define THREAD_STATE_NEW              0
-#define THREAD_STATE_RUNNABLE         1
-#define THREAD_STATE_BLOCKED          2
-#define THREAD_STATE_WAITING          3
-#define THREAD_STATE_TIMED_WAITING    4
-#define THREAD_STATE_TERMINATED       5
-
-
-/* thread priorities **********************************************************/
-
-#define MIN_PRIORITY     1
-#define NORM_PRIORITY    5
-#define MAX_PRIORITY     10
-
-
-/* debug **********************************************************************/
-
-#if !defined(NDEBUG)
-# define DEBUGTHREADS(message, thread) \
-       do { \
-               if (opt_DebugThreads) { \
-                       printf("[Thread %-16s: ", message); \
-                       thread_print_info(thread); \
-                       printf("]\n"); \
-               } \
-       } while (0)
-#else
-# define DEBUGTHREADS(message, thread)
-#endif
-
-
-/* global variables ***********************************************************/
-
-#if defined(__LINUX__)
-/* XXX Remove for exact-GC. */
-extern bool threads_pthreads_implementation_nptl;
-#endif
-
-
-/* inline functions ***********************************************************/
-
-/* thread_get_object ***********************************************************
-
-   Return the Java for the given thread.
-
-   ARGUMENTS:
-       t ... thread
-
-   RETURN:
-       the Java object
-
-*******************************************************************************/
-
-inline static java_handle_t *thread_get_object(threadobject *t)
-{
-       return LLNI_WRAP(t->object);
-}
-
-
-/* threads_thread_set_object ***************************************************
-
-   Set the Java object for the given thread.
-
-   ARGUMENTS:
-       t ... thread
-          o ... Java object
-
-*******************************************************************************/
-
-inline static void thread_set_object(threadobject *t, java_handle_t *o)
-{
-       t->object = LLNI_DIRECT(o);
-}
-
-
-/* thread_get_current_object **************************************************
-
-   Return the Java object of the current thread.
-   
-   RETURN VALUE:
-       the Java object
-
-*******************************************************************************/
-
-inline static java_handle_t *thread_get_current_object(void)
-{
-       threadobject  *t;
-       java_handle_t *o;
-
-       t = THREADOBJECT;
-       o = thread_get_object(t);
-
-       return o;
-}
-
-
-/* cacaothread_get_state *******************************************************
-
-   Returns the current state of the given thread.
-
-   ARGUMENTS:
-       t ... the thread to check
-
-   RETURN:
-       thread state
-
-*******************************************************************************/
-
-inline static int cacaothread_get_state(threadobject *t)
-{
-       return t->state;
-}
-
-
-/* thread_is_attached **********************************************************
-
-   Returns if the given thread is attached to the VM.
-
-   ARGUMENTS:
-       t ... the thread to check
-
-   RETURN:
-       true .... the thread is attached to the VM
-       false ... the thread is not
-
-*******************************************************************************/
-
-inline static bool thread_is_attached(threadobject *t)
-{
-       java_handle_t *o;
-
-       o = thread_get_object(t);
-
-       if (o != NULL)
-               return true;
-       else
-               return false;
-}
-
-
-/* thread_is_interrupted *******************************************************
-
-   Check if the given thread has been interrupted.
-
-   ARGUMENTS:
-       t ... the thread to check
-
-   RETURN VALUE:
-      true, if the given thread had been interrupted
-
-*******************************************************************************/
-
-inline static bool thread_is_interrupted(threadobject *t)
-{
-       bool interrupted;
-
-       /* We need the mutex because classpath will call this function when
-          a blocking system call is interrupted. The mutex ensures that it will
-          see the correct value for the interrupted flag. */
-
-       mutex_lock(&t->waitmutex);
-       interrupted = t->interrupted;
-       mutex_unlock(&t->waitmutex);
-
-       return interrupted;
-}
-
-
-/* thread_set_interrupted ******************************************************
-
-   Set the interrupted flag to the given value.
-
-   ARGUMENTS:
-       interrupted ... value to set
-
-*******************************************************************************/
-
-inline static void thread_set_interrupted(threadobject *t, bool interrupted)
-{
-       mutex_lock(&t->waitmutex);
-
-       /* Set interrupted flag. */
-
-       t->interrupted = interrupted;
-
-       mutex_unlock(&t->waitmutex);
-}
-
-
-/* thread_is_daemon ************************************************************
-
-   Returns if the given thread is a daemon thread.
-
-   ARGUMENTS:
-       t ... the thread to check
-
-   RETURN:
-       true .... the thread is a daemon thread
-       false ... the thread is not
-
-*******************************************************************************/
-
-inline static bool thread_is_daemon(threadobject *t)
-{
-       if (t->flags & THREAD_FLAG_DAEMON)
-               return true;
-       else
-               return false;
-}
-
-
-/* thread_current_is_attached **************************************************
-
-   Returns if the current thread is attached to the VM.
-
-   RETURN:
-       true .... the thread is attached to the VM
-       false ... the thread is not
-
-*******************************************************************************/
-
-inline static bool thread_current_is_attached(void)
-{
-       threadobject  *t;
-       bool           result;
-
-       t = thread_get_current();
-
-       if (t == NULL)
-               return false;
-
-       result = thread_is_attached(t);
-
-       return result;
-}
-
-
-/* function prototypes ********************************************************/
-
-void          threads_preinit(void);
-void          threads_init(void);
-
-void          thread_free(threadobject *t);
-
-bool          threads_thread_start_internal(utf *name, functionptr f);
-void          threads_thread_start(java_handle_t *object);
-
-bool          thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
-bool          thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
-bool          thread_detach_current_thread(void);
-
-bool          thread_detach_current_external_thread(void);
-
-void          thread_fprint_name(threadobject *t, FILE *stream);
-void          thread_print_info(threadobject *t);
-
-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_terminated(threadobject *t);
-
-threadobject *thread_get_thread(java_handle_t *h);
-
-bool          threads_thread_is_alive(threadobject *t);
-
-void          threads_dump(void);
-
-
-/* implementation specific functions */
-
-void          threads_impl_preinit(void);
-void          threads_impl_init(void);
-
-#if defined(ENABLE_GC_CACAO)
-void          threads_mutex_gc_lock(void);
-void          threads_mutex_gc_unlock(void);
-#endif
-
-void          threads_mutex_join_lock(void);
-void          threads_mutex_join_unlock(void);
-
-void          threads_impl_thread_init(threadobject *t);
-void          threads_impl_thread_clear(threadobject *t);
-void          threads_impl_thread_reuse(threadobject *t);
-void          threads_impl_thread_free(threadobject *t);
-void          threads_impl_thread_start(threadobject *thread, functionptr f);
-
-void          threads_yield(void);
-
-#endif /* ENABLE_THREADS */
-
-#endif /* _THREAD_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/threads/thread.hpp b/src/threads/thread.hpp
new file mode 100644 (file)
index 0000000..c6336c8
--- /dev/null
@@ -0,0 +1,381 @@
+/* src/threads/thread.hpp - machine independent thread functions
+
+   Copyright (C) 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 _THREAD_HPP
+#define _THREAD_HPP
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vm/types.h"
+
+// Include early to get threadobject.
+#if defined(ENABLE_THREADS)
+# include "threads/posix/thread-posix.hpp"
+#else
+# include "threads/none/thread-none.h"
+#endif
+
+#include "vm/os.hpp"
+
+#include "native/jni.h"
+#include "native/llni.h"
+
+#include "threads/mutex.hpp"
+
+#include "vm/global.h"
+#include "vm/utf8.h"
+
+
+/* only define the following stuff with thread enabled ************************/
+
+#if defined(ENABLE_THREADS)
+
+/* thread states **************************************************************/
+
+#define THREAD_STATE_NEW              0
+#define THREAD_STATE_RUNNABLE         1
+#define THREAD_STATE_BLOCKED          2
+#define THREAD_STATE_WAITING          3
+#define THREAD_STATE_TIMED_WAITING    4
+#define THREAD_STATE_TERMINATED       5
+
+
+/* thread priorities **********************************************************/
+
+#define MIN_PRIORITY     1
+#define NORM_PRIORITY    5
+#define MAX_PRIORITY     10
+
+
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+# define DEBUGTHREADS(message, thread) \
+       do { \
+               if (opt_DebugThreads) { \
+                       printf("[Thread %-16s: ", message); \
+                       thread_print_info(thread); \
+                       printf("]\n"); \
+               } \
+       } while (0)
+#else
+# define DEBUGTHREADS(message, thread)
+#endif
+
+
+/* global variables ***********************************************************/
+
+#if defined(__LINUX__)
+/* XXX Remove for exact-GC. */
+extern bool threads_pthreads_implementation_nptl;
+#endif
+
+
+/* inline functions ***********************************************************/
+
+/* thread_get_object ***********************************************************
+
+   Return the Java for the given thread.
+
+   ARGUMENTS:
+       t ... thread
+
+   RETURN:
+       the Java object
+
+*******************************************************************************/
+
+inline static java_handle_t *thread_get_object(threadobject *t)
+{
+       return LLNI_WRAP(t->object);
+}
+
+
+/* threads_thread_set_object ***************************************************
+
+   Set the Java object for the given thread.
+
+   ARGUMENTS:
+       t ... thread
+          o ... Java object
+
+*******************************************************************************/
+
+inline static void thread_set_object(threadobject *t, java_handle_t *o)
+{
+       t->object = LLNI_DIRECT(o);
+}
+
+
+/* thread_get_current_object **************************************************
+
+   Return the Java object of the current thread.
+   
+   RETURN VALUE:
+       the Java object
+
+*******************************************************************************/
+
+inline static java_handle_t *thread_get_current_object(void)
+{
+       threadobject  *t;
+       java_handle_t *o;
+
+       t = THREADOBJECT;
+       o = thread_get_object(t);
+
+       return o;
+}
+
+
+/* cacaothread_get_state *******************************************************
+
+   Returns the current state of the given thread.
+
+   ARGUMENTS:
+       t ... the thread to check
+
+   RETURN:
+       thread state
+
+*******************************************************************************/
+
+inline static int cacaothread_get_state(threadobject *t)
+{
+       return t->state;
+}
+
+
+/* thread_is_attached **********************************************************
+
+   Returns if the given thread is attached to the VM.
+
+   ARGUMENTS:
+       t ... the thread to check
+
+   RETURN:
+       true .... the thread is attached to the VM
+       false ... the thread is not
+
+*******************************************************************************/
+
+inline static bool thread_is_attached(threadobject *t)
+{
+       java_handle_t *o;
+
+       o = thread_get_object(t);
+
+       if (o != NULL)
+               return true;
+       else
+               return false;
+}
+
+
+/* thread_is_interrupted *******************************************************
+
+   Check if the given thread has been interrupted.
+
+   ARGUMENTS:
+       t ... the thread to check
+
+   RETURN VALUE:
+      true, if the given thread had been interrupted
+
+*******************************************************************************/
+
+inline static bool thread_is_interrupted(threadobject *t)
+{
+       bool interrupted;
+
+       /* We need the mutex because classpath will call this function when
+          a blocking system call is interrupted. The mutex ensures that it will
+          see the correct value for the interrupted flag. */
+
+#ifdef __cplusplus
+       t->waitmutex->lock();
+       interrupted = t->interrupted;
+       t->waitmutex->unlock();
+#else
+       Mutex_lock(t->waitmutex);
+       interrupted = t->interrupted;
+       Mutex_unlock(t->waitmutex);
+#endif
+
+       return interrupted;
+}
+
+
+/* thread_set_interrupted ******************************************************
+
+   Set the interrupted flag to the given value.
+
+   ARGUMENTS:
+       interrupted ... value to set
+
+*******************************************************************************/
+
+inline static void thread_set_interrupted(threadobject *t, bool interrupted)
+{
+#ifdef __cplusplus
+       t->waitmutex->lock();
+       t->interrupted = interrupted;
+       t->waitmutex->unlock();
+#else
+       Mutex_lock(t->waitmutex);
+       t->interrupted = interrupted;
+       Mutex_unlock(t->waitmutex);
+#endif
+}
+
+
+/* thread_is_daemon ************************************************************
+
+   Returns if the given thread is a daemon thread.
+
+   ARGUMENTS:
+       t ... the thread to check
+
+   RETURN:
+       true .... the thread is a daemon thread
+       false ... the thread is not
+
+*******************************************************************************/
+
+inline static bool thread_is_daemon(threadobject *t)
+{
+       if (t->flags & THREAD_FLAG_DAEMON)
+               return true;
+       else
+               return false;
+}
+
+
+/* thread_current_is_attached **************************************************
+
+   Returns if the current thread is attached to the VM.
+
+   RETURN:
+       true .... the thread is attached to the VM
+       false ... the thread is not
+
+*******************************************************************************/
+
+inline static bool thread_current_is_attached(void)
+{
+       threadobject  *t;
+       bool           result;
+
+       t = thread_get_current();
+
+       if (t == NULL)
+               return false;
+
+       result = thread_is_attached(t);
+
+       return result;
+}
+
+
+/* function prototypes ********************************************************/
+
+void          threads_preinit(void);
+void          threads_init(void);
+
+void          thread_free(threadobject *t);
+
+bool          threads_thread_start_internal(utf *name, functionptr f);
+void          threads_thread_start(java_handle_t *object);
+
+bool          thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+bool          thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+bool          thread_detach_current_thread(void);
+
+bool          thread_detach_current_external_thread(void);
+
+void          thread_fprint_name(threadobject *t, FILE *stream);
+void          thread_print_info(threadobject *t);
+
+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_terminated(threadobject *t);
+
+threadobject *thread_get_thread(java_handle_t *h);
+
+bool          threads_thread_is_alive(threadobject *t);
+
+void          threads_dump(void);
+
+
+/* implementation specific functions */
+
+void          threads_impl_preinit(void);
+void          threads_impl_init(void);
+
+#if defined(ENABLE_GC_CACAO)
+void          threads_mutex_gc_lock(void);
+void          threads_mutex_gc_unlock(void);
+#endif
+
+void          threads_mutex_join_lock(void);
+void          threads_mutex_join_unlock(void);
+
+void          threads_impl_thread_init(threadobject *t);
+void          threads_impl_thread_clear(threadobject *t);
+void          threads_impl_thread_reuse(threadobject *t);
+void          threads_impl_thread_free(threadobject *t);
+void          threads_impl_thread_start(threadobject *thread, functionptr f);
+
+void          threads_yield(void);
+
+#endif /* ENABLE_THREADS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _THREAD_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 8b7d92e3e84764a2c33581a44d87139beeccad09..b585f22c54f2c6177241f086c72fcb610cfd18f0 100644 (file)
 
 #include "mm/memory.h"
 
-#include "threads/mutex.h"
+#include "threads/mutex.hpp"
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/list.h"
 
-#include "vmcore/options.h"
+#include "vm/options.h"
 
 
 /* global variables ***********************************************************/
 
-static mutex_t threadlist_mutex;          /* global mutex for the thread list */
+static Mutex* threadlist_mutex;           /* global mutex for the thread list */
 
 static list_t *list_thread;                            /* global threads list */
 static list_t *list_thread_free;                  /* global free threads list */
@@ -65,7 +65,7 @@ void threadlist_init(void)
 
        /* Initialize the thread list mutex. */
 
-       mutex_init(&threadlist_mutex);
+       threadlist_mutex = Mutex_new();
 
        /* Initialize the thread lists. */
 
@@ -88,7 +88,7 @@ void threadlist_init(void)
 
 void threadlist_lock(void)
 {
-       mutex_lock(&threadlist_mutex);
+       Mutex_lock(threadlist_mutex);
 }
 
 
@@ -100,7 +100,7 @@ void threadlist_lock(void)
 
 void threadlist_unlock(void)
 {
-       mutex_unlock(&threadlist_mutex);
+       Mutex_unlock(threadlist_mutex);
 }
 
 
index b3dd2cbf3d33f4f9ff84ad9d74ebd983bb465ba5..6f2ae0adefa29d277fc7fbc64829fa3a82df3dc1 100644 (file)
 
 #include <stdint.h>
 
-#include "threads/thread.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "threads/thread.hpp"
 
 
 /* function prototypes ********************************************************/
@@ -58,6 +62,10 @@ void          threadlist_impl_init(void);
 void          threadlist_lock(void);
 void          threadlist_unlock(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _THREADLIST_H */
 
 
index 4fe67c5c992af864f4d44c727f00df683831af79..404328c05dba516049198abc7f42db81b3fa7332 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/avl.c - AVL tree implementation
 
-   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.
 
 
 #include "mm/memory.h"
 
-#include "threads/lock-common.h"
+#include "threads/mutex.hpp"
 
 #include "toolbox/avl.h"
 #include "toolbox/logging.h"
 
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 
 /* avl_create ******************************************************************
@@ -54,18 +52,11 @@ avl_tree_t *avl_create(avl_comparator *comparator)
 
        t = NEW(avl_tree_t);
 
+       t->mutex      = Mutex_new();
        t->root       = NULL;
        t->comparator = comparator;
        t->entries    = 0;
 
-#if defined(ENABLE_THREADS)
-       /* create lock object for this tree */
-
-       t->lock       = NEW(java_object_t);
-
-       LOCK_INIT_OBJECT_LOCK(t->lock);
-#endif
-
        return t;
 }
 
@@ -312,7 +303,7 @@ bool avl_insert(avl_tree_t *tree, void *data)
        assert(tree);
        assert(data);
 
-       LOCK_MONITOR_ENTER(tree->lock);
+       Mutex_lock(tree->mutex);
 
        /* if we don't have a root node, create one */
 
@@ -325,7 +316,7 @@ bool avl_insert(avl_tree_t *tree, void *data)
 
        tree->entries++;
 
-       LOCK_MONITOR_EXIT(tree->lock);
+       Mutex_unlock(tree->mutex);
 
        /* insertion was ok */
 
@@ -348,7 +339,7 @@ void *avl_find(avl_tree_t *tree, void *data)
        assert(tree);
        assert(data);
 
-       LOCK_MONITOR_ENTER(tree->lock);
+       Mutex_lock(tree->mutex);
 
        /* search the tree for the given node */
 
@@ -360,7 +351,7 @@ void *avl_find(avl_tree_t *tree, void *data)
                /* was the entry found? return it */
 
                if (res == 0) {
-                       LOCK_MONITOR_EXIT(tree->lock);
+                       Mutex_unlock(tree->mutex);
 
                        return node->data;
                }
@@ -370,7 +361,7 @@ void *avl_find(avl_tree_t *tree, void *data)
                node = node->childs[(res < 0) ? AVL_LEFT : AVL_RIGHT];
        }
 
-       LOCK_MONITOR_EXIT(tree->lock);
+       Mutex_unlock(tree->mutex);
 
        /* entry was not found, returning NULL */
 
index a8dcaba588949a370324a4f0adb0daecf23861ce..c968fa8a9e9d020800465b2044d998539f4beed4 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/avl.h - AVL tree implementation
 
-   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.
 
@@ -32,6 +30,8 @@
 
 #include "vm/types.h"
 
+#include "threads/mutex.hpp"
+
 #include "vm/global.h"
 
 
@@ -55,12 +55,10 @@ typedef struct avl_node_t avl_node_t;
 /* avl_tree_t *****************************************************************/
 
 struct avl_tree_t {
-#if defined(ENABLE_THREADS)
-       java_object_t     *lock;            /* threads lock object                */
-#endif
-       avl_node_t        *root;            /* pointer to root node               */
-       avl_comparator    *comparator;      /* pointer to comparison function     */
-       s4                 entries;         /* contains number of entries         */
+       Mutex*          mutex;              ///< Mutex to lock the tree.
+       avl_node_t     *root;               /* pointer to root node               */
+       avl_comparator *comparator;         /* pointer to comparison function     */
+       s4              entries;            /* contains number of entries         */
 };
 
 
index 1712ae99dd8cd1174fe641e5066e20a7edc8b2d2..51161b7832e64444ab72190a36bf8cabce0856d3 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/hashtable.h - functions for internal hashtables
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Christian Thalinger
-
 */
 
 
@@ -42,7 +35,7 @@ typedef struct hashtable hashtable;
 #include "vm/types.h"
 
 #include "vm/global.h"
-#include "vmcore/utf8.h"
+#include "vm/utf8.h"
 
 
 /* data structures for hashtables ********************************************
index c9fea656a0933c2942b683ff8ddd6640008f5f6d..7ff7f1b69fafe369178fa28fa28f77f1d6bb440a 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "mm/memory.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
@@ -41,7 +41,7 @@
 #include "vm/global.h"
 
 #if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
+# include "vm/statistics.h"
 #endif
 
 
index f6def38059908089d224f4f29446b0f8ac2e031e..a0604b702bcae0822f3dd522f5bbb538244c7b1b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/logging.h - contains logging functions
 
-   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.
 
@@ -33,9 +31,9 @@
 #include <stdio.h>
 #include <stdarg.h>
 
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/utf8.h"
+#include "vm/class.h"
+#include "vm/method.h"
+#include "vm/utf8.h"
 
 
 /*500 is to small for eclipse traces, (builtin_trace_args, perhaps the
index 82acc8ff7f517543a2999cb0fd9af244295f7f15..2e26c259b6c1be35205db5583e73d469480cd6f7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/util.c - contains some utility functions
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
 */
 
 
@@ -41,7 +33,7 @@
 #include "vm/types.h"
 
 #include "mm/memory.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 
 /* _Jv_getcwd ******************************************************************
index 866f410a800be978d805931c80230b242b45e8d3..4952cd26fd1e60d52d42ae702f7a5e3160f87efb 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/util.h - contains some utility functions
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
 */
 
 
 #ifndef _UTIL_H
 #define _UTIL_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "config.h"
 
 #include <stdarg.h>
 char *_Jv_getcwd(void);
 int   get_variable_message_length(const char *fmt, va_list ap);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _UTIL_H */
 
 
index cd56a115fff690fba2e7c554d365d0de759f02d9..4ec2f30d1ce894918f8d28ee266a03cdf1ab26ee 100644 (file)
@@ -39,6 +39,36 @@ CYCLES_STATS_SOURCES = \
        cycles-stats.h
 endif
 
+if ENABLE_JAVASE
+if ENABLE_ANNOTATIONS
+ANNOTATION_SOURCES = \
+       annotation.c \
+       annotation.h
+endif
+
+STACKMAP_SOURCES = \
+       stackmap.c \
+       stackmap.h
+endif
+
+if ENABLE_RT_TIMING
+RT_TIMING_SOURCES = \
+       rt-timing.c \
+       rt-timing.h
+endif
+
+if ENABLE_STATISTICS
+STATISTICS_SOURCES = \
+       statistics.c \
+       statistics.h
+endif
+
+if ENABLE_ZLIB
+ZLIB_SOURCES = \
+       zip.c \
+       zip.h
+endif
+
 noinst_HEADERS = \
        global.h \
        types.h
@@ -47,36 +77,69 @@ noinst_LTLIBRARIES = \
        libvm.la
 
 libvm_la_SOURCES = \
-       $(ASSERTION_SOURCES) \
        access.c \
        access.h \
+       $(ANNOTATION_SOURCES) \
        array.c \
        array.h \
+       $(ASSERTION_SOURCES) \
        builtin.c \
        builtin.h \
        builtintable.inc \
+       class.c \
+       class.h \
+       classcache.c \
+       classcache.h \
        $(CYCLES_STATS_SOURCES) \
-       exceptions.c \
-       exceptions.h \
+       descriptor.c \
+       descriptor.h \
+       exceptions.cpp \
+       exceptions.hpp \
+       field.c \
+       field.h \
        finalizer.c \
        finalizer.h \
+       globals.cpp \
+       globals.hpp \
        initialize.c \
        initialize.h \
+       javaobjects.cpp \
+       javaobjects.hpp \
        jit_interface.h \
+       linker.c \
+       linker.h \
+       loader.c \
+       loader.h \
+       method.c \
+       method.h \
+       options.c \
+       options.h \
+       os.cpp \
+       os.hpp \
        package.cpp \
        package.hpp \
-       primitive.c \
-       primitive.h \
+       primitive.cpp \
+       primitive.hpp \
+       primitivecore.c \
        properties.c \
        properties.h \
+       references.h \
        resolve.c \
        resolve.h \
+       $(RT_TIMING_SOURCES) \
        signal.c \
        signallocal.h \
-       string.c \
-       stringlocal.h \
-       vm.c \
-       vm.h
+       $(STACKMAP_SOURCES) \
+       $(STATISTICS_SOURCES) \
+       string.cpp \
+       string.hpp \
+       suck.c \
+       suck.h \
+       utf8.c \
+       utf8.h \
+       vm.cpp \
+       vm.hpp \
+       $(ZLIB_SOURCES)
 
 libvm_la_LIBADD = \
        jit/libjit.la
index 81ea76412329c8d74e8a2a52a876aa52d973e5b5..eb67440337ddd7acab9ddfd80ac403568f572172 100644 (file)
 
 #include "vm/access.h"
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/field.h"
+#include "vm/globals.hpp"
+#include "vm/method.h"
 
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/method.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* access_is_accessible_class **************************************************
index 2b8a10c173e93251be7fcfac22854e49a6c16f0a..1b90872201d610d90daf1300f56002c444b9829b 100644 (file)
 
 #include <stdint.h>
 
-#include "vm/global.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/method.h"
+#include "vm/class.h"
+#include "vm/field.h"
+#include "vm/global.h"
+#include "vm/method.h"
 
 
 /* macros *********************************************************************/
@@ -56,6 +59,10 @@ bool access_check_field(fieldinfo *f, int callerdepth);
 bool access_check_method(methodinfo *m, int callerdepth);
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _ACCESS_H */
 
 
diff --git a/src/vm/annotation.c b/src/vm/annotation.c
new file mode 100644 (file)
index 0000000..5b3c9ce
--- /dev/null
@@ -0,0 +1,614 @@
+/* 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.h"
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/loader.h"
+#include "vm/primitive.hpp"
+#include "vm/suck.h"
+#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
new file mode 100644 (file)
index 0000000..38f517c
--- /dev/null
@@ -0,0 +1,85 @@
+/* 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.h"
+#include "vm/field.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+
+
+/* function prototypes ********************************************************/
+
+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);
+
+#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:
+ */
index 30f231d3e720a8a60ae388a7dfb5abed406b3114..58fdff3c7e8b686c6008c4a99dd4b0c9b11104b7 100644 (file)
 #include "native/llni.h"
 
 #include "vm/array.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/primitive.h"
-#include "vm/vm.h"
+#include "vm/primitive.hpp"
+#include "vm/vm.hpp"
 
 
 /* array_element_get ***********************************************************
@@ -60,7 +60,7 @@ java_handle_t *array_element_get(java_handle_t *a, int32_t index)
 
        value = array_element_primitive_get(a, index);
 
-       o = primitive_box(type, value);
+       o = Primitive_box(type, value);
 
        return o;
 }
@@ -76,7 +76,7 @@ void array_element_set(java_handle_t *a, int32_t index, java_handle_t *o)
 {
        imm_union value;
 
-       value = primitive_unbox(o);
+       value = Primitive_unbox(o);
 
        array_element_primitive_set(a, index, value);
 }
index 3425d591226793d649017294c2a4e701668a935d..132855ce8fd75ebdfcd4aa3d91a97d66e5969676 100644 (file)
 
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/global.h"
-#include "vm/primitive.h"
+#include "vm/primitive.hpp"
 
 
 /* array types ****************************************************************/
@@ -81,6 +85,10 @@ void           array_objectarray_element_set(java_handle_objectarray_t *a, int32
 
 int32_t        array_length_get(java_handle_t *a);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _VM_ARRAY_H */
 
 
index 6a1f0f694f13a8132d7b82ab7010f03db88e423a..efe40b2776a09d785ebfec95cbcf46ac8ee1e6be 100644 (file)
@@ -34,9 +34,8 @@
 
 #include "vm/assertion.h"
 #include "vm/global.h"
-#include "vm/vm.h"
-
-#include "vmcore/system.h"
+#include "vm/os.hpp"
+#include "vm/vm.hpp"
 
 
 /* -ea/-da options ************************************************************/
@@ -68,13 +67,13 @@ void assertion_ea_da(const char *name, bool enabled)
        }
 
        package = false;
-       len     = system_strlen(name);
+       len     = os_strlen(name);
 
        if (name[len - 1] == '/') {
                return;
        }
 
-       buf = system_strdup(name);
+       buf = os_strdup(name);
 
        if (buf == NULL) {
                vm_abort("assertion_ea_da: strdup failed: %s", strerror(errno));
@@ -94,7 +93,7 @@ void assertion_ea_da(const char *name, bool enabled)
                assertion_class_count += 1;
        }
 
-       len = system_strlen(buf);
+       len = os_strlen(buf);
 
        for (i = 0; i < len; i++) {
 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
index 4175bec646502ee119598a75f10bd3641ec1a0ca..20add69ccf0700ed89c85f7855e277c6389155e2 100644 (file)
 #define _ASSERTION_H
 
 #include "config.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/global.h"
 #include "toolbox/list.h"
 
-#include <stdint.h>
 
 typedef struct assertion_name_t assertion_name_t;
 
@@ -53,6 +59,10 @@ extern bool     assertion_system_enabled;
 
 void assertion_ea_da(const char *name, bool enabled);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _ASSERTION_H */
 
 
index dab69a171795b276ccd7fce46e18907bed463f75..346417110d5d8535aee8984f332cd3119abe7f0c 100644 (file)
 # undef Bias
 #endif
 
-#include "mm/gc-common.h"
+#include "mm/gc.hpp"
 #include "mm/memory.h"
 
 #include "native/jni.h"
 #include "native/llni.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
 
 #include "vm/array.h"
 #include "vm/builtin.h"
+#include "vm/class.h"
 #include "vm/cycles-stats.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
+#include "vm/globals.hpp"
 #include "vm/initialize.h"
-#include "vm/primitive.h"
-#include "vm/stringlocal.h"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/rt-timing.h"
+#include "vm/string.hpp"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/trace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/rt-timing.h"
+#include "vm/jit/trace.hpp"
 
 #if defined(ENABLE_VMLOG)
 #include <vmlog_cacao.h>
@@ -979,6 +979,91 @@ java_handle_t *builtin_new(classinfo *c)
        return o;
 }
 
+#if defined(ENABLE_ESCAPE_REASON)
+java_handle_t *builtin_escape_reason_new(classinfo *c) {
+       print_escape_reasons();
+       return builtin_java_new(c);
+}
+#endif
+
+#if defined(ENABLE_TLH)
+java_handle_t *builtin_tlh_new(classinfo *c)
+{
+       java_handle_t *o;
+# if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+# endif
+# if defined(ENABLE_CYCLES_STATS)
+       u8 cycles_start, cycles_end;
+# endif
+
+       RT_TIMING_GET_TIME(time_start);
+       CYCLES_STATS_GET(cycles_start);
+
+       /* is the class loaded */
+
+       assert(c->state & CLASS_LOADED);
+
+       /* check if we can instantiate this class */
+
+       if (c->flags & ACC_ABSTRACT) {
+               exceptions_throw_instantiationerror(c);
+               return NULL;
+       }
+
+       /* is the class linked */
+
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+
+       if (!(c->state & CLASS_INITIALIZED)) {
+# if !defined(NDEBUG)
+               if (initverbose)
+                       log_message_class("Initialize class (from builtin_new): ", c);
+# endif
+
+               if (!initialize_class(c))
+                       return NULL;
+       }
+
+       /*
+       o = tlh_alloc(&(THREADOBJECT->tlh), c->instancesize);
+       */
+       o = NULL;
+
+       if (o == NULL) {
+               o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
+                                          c->finalizer, true);
+       }
+
+       if (!o)
+               return NULL;
+
+# if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+       /* XXX this is only a dirty hack to make Boehm work with handles */
+
+       o = LLNI_WRAP((java_object_t *) o);
+# endif
+
+       LLNI_vftbl_direct(o) = c->vftbl;
+
+# if defined(ENABLE_THREADS)
+       lock_init_object_lock(LLNI_DIRECT(o));
+# endif
+
+       CYCLES_STATS_GET(cycles_end);
+       RT_TIMING_GET_TIME(time_end);
+
+/*
+       CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
+       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
+*/
+
+       return o;
+}
+#endif
+
 
 /* builtin_java_new ************************************************************
 
index af6c51eb8bd855d49ebee528ddefafbc53839163..8856520a17b60a132f6a3ba62cd981a3342d8d34 100644 (file)
 #ifndef _BUILTIN_H
 #define _BUILTIN_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* forward typedefs ***********************************************************/
 
 typedef struct builtintable_entry builtintable_entry;
@@ -38,7 +42,8 @@ typedef struct builtintable_entry builtintable_entry;
 
 #include "toolbox/logging.h"
 
-#include "vmcore/utf8.h"
+#include "vm/descriptor.h"
+#include "vm/utf8.h"
 
 
 /* define infinity for floating point numbers */
@@ -147,6 +152,17 @@ java_handle_t *builtin_new(classinfo *c);
 /* NOT AN OP */
 java_handle_t *builtin_java_new(java_handle_t *c);
 #define BUILTIN_new (functionptr) builtin_java_new
+
+#if defined(ENABLE_TLH)
+#define BUILTIN_tlh_new (functionptr) builtin_tlh_new
+java_handle_t *builtin_tlh_new(classinfo *c);
+#endif
+
+#if defined(ENABLE_ESCAPE_REASON)
+#define BUILTIN_escape_reason_new (functionptr)builtin_escape_reason_new
+java_handle_t *builtin_escape_reason_new(classinfo *c);
+#endif
+
 java_object_t *builtin_fast_new(classinfo *c);
 #define BUILTIN_FAST_new (functionptr) builtin_fast_new
 
@@ -318,6 +334,10 @@ s8 builtin_currenttimemillis(void);
 void builtin_print_cycles_stats(FILE *file);
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _BUILTIN_H */
 
 
index 735c1de70776c296d1113670634222df52a2526e..3f5781fe261a27bff1c1cd70173e64ea41011157 100644 (file)
@@ -194,6 +194,39 @@ static builtintable_entry builtintable_internal[] = {
                NULL,
                NULL
        },
+
+#if defined(ENABLE_TLH)
+       {
+               ICMD_NEW,
+               BUILTINTABLE_FLAG_STUB,
+               BUILTIN_tlh_new,
+               NULL,
+               NULL,
+               "tlh_new",
+               "(Ljava/lang/Class;)Ljava/lang/Object;",
+               NULL,
+               NULL,
+               NULL,
+               NULL
+       },
+#endif
+
+#if defined(ENABLE_ESCAPE_REASON)
+       {
+               ICMD_NEW,
+               BUILTINTABLE_FLAG_STUB,
+               BUILTIN_escape_reason_new,
+               NULL,
+               NULL,
+               "escape_reason_new",
+               "(Ljava/lang/Class;)Ljava/lang/Object;",
+               NULL,
+               NULL,
+               NULL,
+               NULL
+       },
+#endif
+
        {
                ICMD_NEW,
                0,
diff --git a/src/vm/class.c b/src/vm/class.c
new file mode 100644 (file)
index 0000000..b851c65
--- /dev/null
@@ -0,0 +1,2481 @@
+/* src/vm/class.c - class related 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "arch.h"
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "threads/lock-common.h"
+
+#include "toolbox/logging.h"
+
+#include "vm/array.h"
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/jit/jitcache.h"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/suck.h"
+#include "vm/utf8.h"
+
+#include "vm/jit/asmpart.h"
+
+
+/* class_set_packagename *******************************************************
+
+   Derive the package name from the class name and store it in the
+   struct.
+
+   An internal package name consists of the package name plus the
+   trailing '/', e.g. "java/lang/".
+
+   For classes in the unnamed package, the package name is set to
+   NULL.
+
+*******************************************************************************/
+
+void class_set_packagename(classinfo *c)
+{
+       char *p;
+       char *start;
+
+       p     = UTF_END(c->name) - 1;
+       start = c->name->text;
+
+       if (c->name->text[0] == '[') {
+               /* Set packagename of arrays to the element's package. */
+
+               for (; *start == '['; start++);
+
+               /* Skip the 'L' in arrays of references. */
+
+               if (*start == 'L')
+                       start++;
+       }
+
+       /* Search for last '/'. */
+
+       for (; (p > start) && (*p != '/'); --p);
+
+       /* If we found a '/' we set the package name plus the trailing
+          '/'.  Otherwise we set the packagename to NULL. */
+
+       if (p > start)
+               c->packagename = utf_new(start, p - start + 1);
+       else
+               c->packagename = NULL;
+}
+
+
+/* class_create_classinfo ******************************************************
+
+   Create a new classinfo struct. The class name is set to the given utf *,
+   most other fields are initialized to zero.
+
+   Note: classname may be NULL. In this case a not-yet-named classinfo is
+         created. The name must be filled in later and class_set_packagename
+                must be called after that.
+
+*******************************************************************************/
+
+classinfo *class_create_classinfo(utf *classname)
+{
+       classinfo *c;
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_classinfo += sizeof(classinfo);
+#endif
+
+       /* we use a safe name for temporarily unnamed classes */
+
+       if (classname == NULL)
+               classname = utf_not_named_yet;
+
+#if !defined(NDEBUG)
+       if (initverbose)
+               log_message_utf("Creating class: ", classname);
+#endif
+
+#if !defined(ENABLE_GC_BOEHM)
+       c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
+       /*c = NEW(classinfo);
+       MZERO(c, classinfo, 1);*/
+#else
+       c = GCNEW_UNCOLLECTABLE(classinfo, 1);
+       /* GCNEW_UNCOLLECTABLE clears the allocated memory */
+#endif
+
+       c->name = classname;
+
+       /* Set the header.vftbl of all loaded classes to the one of
+       java.lang.Class, so Java code can use a class as object. */
+
+       if (class_java_lang_Class != NULL)
+               if (class_java_lang_Class->vftbl != NULL)
+                       c->object.header.vftbl = class_java_lang_Class->vftbl;
+
+#if defined(ENABLE_JAVASE)
+       /* check if the class is a reference class and flag it */
+
+       if (classname == utf_java_lang_ref_SoftReference) {
+               c->flags |= ACC_CLASS_REFERENCE_SOFT;
+       }
+       else if (classname == utf_java_lang_ref_WeakReference) {
+               c->flags |= ACC_CLASS_REFERENCE_WEAK;
+       }
+       else if (classname == utf_java_lang_ref_PhantomReference) {
+               c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
+       }
+#endif
+
+       if (classname != utf_not_named_yet)
+               class_set_packagename(c);
+#if defined (ENABLE_JITCACHE)
+    c->cache_file_fd = 0;
+#endif
+
+       LOCK_INIT_OBJECT_LOCK(&c->object.header);
+
+       return c;
+}
+
+
+/* class_postset_header_vftbl **************************************************
+
+   Set the header.vftbl of all classes created before java.lang.Class
+   was linked.  This is necessary that Java code can use a class as
+   object.
+
+*******************************************************************************/
+
+void class_postset_header_vftbl(void)
+{
+       classinfo *c;
+       u4 slot;
+       classcache_name_entry *nmen;
+       classcache_class_entry *clsen;
+
+       assert(class_java_lang_Class);
+
+       for (slot = 0; slot < hashtable_classcache.size; slot++) {
+               nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+
+               for (; nmen; nmen = nmen->hashlink) {
+                       /* iterate over all class entries */
+
+                       for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+                               c = clsen->classobj;
+
+                               /* now set the the vftbl */
+
+                               if (c->object.header.vftbl == NULL)
+                                       c->object.header.vftbl = class_java_lang_Class->vftbl;
+                       }
+               }
+       }
+}
+
+/* class_define ****************************************************************
+
+   Calls the loader and defines a class in the VM.
+
+*******************************************************************************/
+
+classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
+{
+       classinfo   *c;
+       classinfo   *r;
+       classbuffer *cb;
+
+       if (name != NULL) {
+               /* check if this class has already been defined */
+
+               c = classcache_lookup_defined_or_initiated(cl, name);
+
+               if (c != NULL) {
+                       exceptions_throw_linkageerror("duplicate class definition: ", c);
+                       return NULL;
+               }
+       } 
+
+       /* create a new classinfo struct */
+
+       c = class_create_classinfo(name);
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_start();
+#endif
+
+       /* build a classbuffer with the given data */
+
+       cb = NEW(classbuffer);
+
+       cb->clazz = c;
+       cb->size  = length;
+       cb->data  = data;
+       cb->pos   = cb->data;
+
+       /* preset the defining classloader */
+
+       c->classloader = cl;
+
+       /* load the class from this buffer */
+
+       r = load_class_from_classbuffer(cb);
+
+       /* free memory */
+
+       FREE(cb, classbuffer);
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_stop();
+#endif
+
+       if (r == NULL) {
+               /* If return value is NULL, we had a problem and the class is
+                  not loaded.  Now free the allocated memory, otherwise we
+                  could run into a DOS. */
+
+               class_free(c);
+
+               return NULL;
+       }
+
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       /* Store the protection domain. */
+
+       c->protectiondomain = pd;
+# endif
+#endif
+
+       /* Store the newly defined class in the class cache. This call
+          also checks whether a class of the same name has already been
+          defined by the same defining loader, and if so, replaces the
+          newly created class by the one defined earlier. */
+
+       /* Important: The classinfo given to classcache_store must be
+                     fully prepared because another thread may return
+                     this pointer after the lookup at to top of this
+                     function directly after the class cache lock has
+                     been released. */
+
+       c = classcache_store(cl, c, true);
+
+       return c;
+}
+
+
+/* class_load_attribute_sourcefile *********************************************
+
+   SourceFile_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+          u2 sourcefile_index;
+   }
+
+*******************************************************************************/
+
+static bool class_load_attribute_sourcefile(classbuffer *cb)
+{
+       classinfo *c;
+       u4         attribute_length;
+       u2         sourcefile_index;
+       utf       *sourcefile;
+
+       /* get classinfo */
+
+       c = cb->clazz;
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 2) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       /* there can be no more than one SourceFile attribute */
+
+       if (c->sourcefile != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
+               return false;
+       }
+
+       /* get sourcefile */
+
+       sourcefile_index = suck_u2(cb);
+       sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
+
+       if (sourcefile == NULL)
+               return false;
+
+       /* store sourcefile */
+
+       c->sourcefile = sourcefile;
+
+       return true;
+}
+
+
+/* class_load_attribute_enclosingmethod ****************************************
+
+   EnclosingMethod_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+          u2 class_index;
+          u2 method_index;
+   }
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+static bool class_load_attribute_enclosingmethod(classbuffer *cb)
+{
+       classinfo             *c;
+       u4                     attribute_length;
+       u2                     class_index;
+       u2                     method_index;
+       classref_or_classinfo  cr;
+       constant_nameandtype  *cn;
+
+       /* get classinfo */
+
+       c = cb->clazz;
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 4) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       /* there can be no more than one EnclosingMethod attribute */
+
+       if (c->enclosingmethod != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
+               return false;
+       }
+
+       /* get class index */
+
+       class_index = suck_u2(cb);
+       cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
+
+       /* get method index */
+
+       method_index = suck_u2(cb);
+       cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
+
+       /* store info in classinfo */
+
+       c->enclosingclass.any = cr.any;
+       c->enclosingmethod    = cn;
+
+       return true;
+}
+#endif /* defined(ENABLE_JAVASE) */
+
+
+/* class_load_attributes *******************************************************
+
+   Read attributes from ClassFile.
+
+   attribute_info {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 info[attribute_length];
+   }
+
+   InnerClasses_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+   }
+
+*******************************************************************************/
+
+bool class_load_attributes(classbuffer *cb)
+{
+       classinfo             *c;
+       uint16_t               attributes_count;
+       uint16_t               attribute_name_index;
+       utf                   *attribute_name;
+       innerclassinfo        *info;
+       classref_or_classinfo  inner;
+       classref_or_classinfo  outer;
+       utf                   *name;
+       uint16_t               flags;
+       int                    i, j;
+
+       c = cb->clazz;
+
+       /* get attributes count */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       attributes_count = suck_u2(cb);
+
+       for (i = 0; i < attributes_count; i++) {
+               /* get attribute name */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               attribute_name_index = suck_u2(cb);
+               attribute_name =
+                       class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
+
+               if (attribute_name == NULL)
+                       return false;
+
+               if (attribute_name == utf_InnerClasses) {
+                       /* InnerClasses */
+
+                       if (c->innerclass != NULL) {
+                               exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
+                               return false;
+                       }
+                               
+                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                               return false;
+
+                       /* skip attribute length */
+                       suck_u4(cb);
+
+                       /* number of records */
+                       c->innerclasscount = suck_u2(cb);
+
+                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
+                               return false;
+
+                       /* allocate memory for innerclass structure */
+                       c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
+
+                       for (j = 0; j < c->innerclasscount; j++) {
+                               /* The innerclass structure contains a class with an encoded
+                                  name, its defining scope, its simple name and a bitmask of
+                                  the access flags. */
+                                                               
+                               info = c->innerclass + j;
+
+                               inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+                               outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+                               name      = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
+                               flags     = suck_u2(cb);
+
+                               /* If the current inner-class is the currently loaded
+                                  class check for some special flags. */
+
+                               if (inner.ref->name == c->name) {
+                                       /* If an inner-class is not a member, its
+                                          outer-class is NULL. */
+
+                                       if (outer.ref != NULL) {
+                                               c->flags |= ACC_CLASS_MEMBER;
+
+                                               /* A member class doesn't have an
+                                                  EnclosingMethod attribute, so set the
+                                                  enclosing-class to be the same as the
+                                                  declaring-class. */
+
+                                               c->declaringclass = outer;
+                                               c->enclosingclass = outer;
+                                       }
+
+                                       /* If an inner-class is anonymous, its name is
+                                          NULL. */
+
+                                       if (name == NULL)
+                                               c->flags |= ACC_CLASS_ANONYMOUS;
+                               }
+
+                               info->inner_class = inner;
+                               info->outer_class = outer;
+                               info->name        = name;
+                               info->flags       = flags;
+                       }
+               }
+               else if (attribute_name == utf_SourceFile) {
+                       /* SourceFile */
+
+                       if (!class_load_attribute_sourcefile(cb))
+                               return false;
+               }
+#if defined(ENABLE_JAVASE)
+               else if (attribute_name == utf_EnclosingMethod) {
+                       /* EnclosingMethod */
+
+                       if (!class_load_attribute_enclosingmethod(cb))
+                               return false;
+               }
+               else if (attribute_name == utf_Signature) {
+                       /* Signature */
+
+                       if (!loader_load_attribute_signature(cb, &(c->signature)))
+                               return false;
+               }
+#endif
+
+#if defined(ENABLE_ANNOTATIONS)
+               else if (attribute_name == utf_RuntimeVisibleAnnotations) {
+                       /* RuntimeVisibleAnnotations */
+                       if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
+                               return false;
+               }
+               else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
+                       /* RuntimeInvisibleAnnotations */
+                       if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
+                               return false;
+               }
+#endif
+
+               else {
+                       /* unknown attribute */
+
+                       if (!loader_skip_attribute_body(cb))
+                               return false;
+               }
+       }
+
+       return true;
+}
+
+
+/* class_freepool **************************************************************
+
+       Frees all resources used by this classes Constant Pool.
+
+*******************************************************************************/
+
+static void class_freecpool(classinfo *c)
+{
+       u4 idx;
+       u4 tag;
+       void* info;
+       
+       if (c->cptags && c->cpinfos) {
+               for (idx = 0; idx < c->cpcount; idx++) {
+                       tag = c->cptags[idx];
+                       info = c->cpinfos[idx];
+               
+                       if (info != NULL) {
+                               switch (tag) {
+                               case CONSTANT_Fieldref:
+                               case CONSTANT_Methodref:
+                               case CONSTANT_InterfaceMethodref:
+                                       FREE(info, constant_FMIref);
+                                       break;
+                               case CONSTANT_Integer:
+                                       FREE(info, constant_integer);
+                                       break;
+                               case CONSTANT_Float:
+                                       FREE(info, constant_float);
+                                       break;
+                               case CONSTANT_Long:
+                                       FREE(info, constant_long);
+                                       break;
+                               case CONSTANT_Double:
+                                       FREE(info, constant_double);
+                                       break;
+                               case CONSTANT_NameAndType:
+                                       FREE(info, constant_nameandtype);
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       if (c->cptags)
+               MFREE(c->cptags, u1, c->cpcount);
+
+       if (c->cpinfos)
+               MFREE(c->cpinfos, void*, c->cpcount);
+}
+
+
+/* class_getconstant ***********************************************************
+
+   Retrieves the value at position 'pos' of the constantpool of a
+   class. If the type of the value is other than 'ctype', an error is
+   thrown.
+
+*******************************************************************************/
+
+void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
+{
+       /* check index and type of constantpool entry */
+       /* (pos == 0 is caught by type comparison) */
+
+       if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+
+       return c->cpinfos[pos];
+}
+
+
+/* innerclass_getconstant ******************************************************
+
+   Like class_getconstant, but if cptags is ZERO, null is returned.
+       
+*******************************************************************************/
+
+void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
+{
+       /* invalid position in constantpool */
+
+       if (pos >= c->cpcount) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+
+       /* constantpool entry of type 0 */      
+
+       if (c->cptags[pos] == 0)
+               return NULL;
+
+       /* check type of constantpool entry */
+
+       if (c->cptags[pos] != ctype) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+               
+       return c->cpinfos[pos];
+}
+
+
+/* class_free ******************************************************************
+
+   Frees all resources used by the class.
+
+*******************************************************************************/
+
+void class_free(classinfo *c)
+{
+       s4 i;
+       vftbl_t *v;
+
+#if defined(ENABLE_JITCACHE)
+/* TODO: Find a way around the linker problem */
+/*    jitcache_freeclass(c);*/
+#endif
+
+       class_freecpool(c);
+
+       if (c->interfaces != NULL)
+               MFREE(c->interfaces, classinfo*, c->interfacescount);
+
+       if (c->fields) {
+               for (i = 0; i < c->fieldscount; i++)
+                       field_free(&(c->fields[i]));
+               MFREE(c->fields, fieldinfo, c->fieldscount);
+       }
+       
+       if (c->methods) {
+               for (i = 0; i < c->methodscount; i++)
+                       method_free(&(c->methods[i]));
+               MFREE(c->methods, methodinfo, c->methodscount);
+       }
+
+       if ((v = c->vftbl) != NULL) {
+               if (v->arraydesc)
+                       mem_free(v->arraydesc,sizeof(arraydescriptor));
+               
+               for (i = 0; i < v->interfacetablelength; i++) {
+                       MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
+               }
+               MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
+
+               i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
+                   sizeof(methodptr*) * (v->interfacetablelength -
+                                        (v->interfacetablelength > 0));
+               v = (vftbl_t*) (((methodptr*) v) -
+                                               (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
+               mem_free(v, i);
+       }
+
+       if (c->innerclass)
+               MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
+
+       /*      if (c->classvftbl)
+               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
+       
+/*     GCFREE(c); */
+}
+
+
+/* get_array_class *************************************************************
+
+   Returns the array class with the given name for the given
+   classloader, or NULL if an exception occurred.
+
+   Note: This function does eager loading. 
+
+*******************************************************************************/
+
+static classinfo *get_array_class(utf *name,classloader_t *initloader,
+                                                                                       classloader_t *defloader,bool link)
+{
+       classinfo *c;
+       
+       /* lookup this class in the classcache */
+       c = classcache_lookup(initloader,name);
+       if (!c)
+               c = classcache_lookup_defined(defloader,name);
+
+       if (!c) {
+               /* we have to create it */
+               c = class_create_classinfo(name);
+               c = load_newly_created_array(c,initloader);
+               if (c == NULL)
+                       return NULL;
+       }
+
+       assert(c);
+       assert(c->state & CLASS_LOADED);
+       assert(c->classloader == defloader);
+
+       if (link && !(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+
+       assert(!link || (c->state & CLASS_LINKED));
+
+       return c;
+}
+
+
+/* class_array_of **************************************************************
+
+   Returns an array class with the given component class. The array
+   class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_array_of(classinfo *component, bool link)
+{
+       classloader_t     *cl;
+    s4                 namelen;
+    char              *namebuf;
+       utf               *u;
+       classinfo         *c;
+       int32_t            dumpmarker;
+
+       cl = component->classloader;
+
+       DMARKER;
+
+    /* Assemble the array class name */
+    namelen = component->name->blength;
+    
+    if (component->name->text[0] == '[') {
+        /* the component is itself an array */
+        namebuf = DMNEW(char, namelen + 1);
+        namebuf[0] = '[';
+        MCOPY(namebuf + 1, component->name->text, char, namelen);
+        namelen++;
+    }
+       else {
+        /* the component is a non-array class */
+        namebuf = DMNEW(char, namelen + 3);
+        namebuf[0] = '[';
+        namebuf[1] = 'L';
+        MCOPY(namebuf + 2, component->name->text, char, namelen);
+        namebuf[2 + namelen] = ';';
+        namelen += 3;
+    }
+
+       u = utf_new(namebuf, namelen);
+
+       c = get_array_class(u, cl, cl, link);
+
+       DRELEASE;
+
+       return c;
+}
+
+
+/* class_multiarray_of *********************************************************
+
+   Returns an array class with the given dimension and element class.
+   The array class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
+{
+    s4 namelen;
+    char *namebuf;
+       classinfo *c;
+       int32_t    dumpmarker;
+
+       DMARKER;
+
+       if (dim < 1) {
+               log_text("Invalid array dimension requested");
+               assert(0);
+       }
+
+    /* Assemble the array class name */
+    namelen = element->name->blength;
+    
+    if (element->name->text[0] == '[') {
+        /* the element is itself an array */
+        namebuf = DMNEW(char, namelen + dim);
+        memcpy(namebuf + dim, element->name->text, namelen);
+        namelen += dim;
+    }
+    else {
+        /* the element is a non-array class */
+        namebuf = DMNEW(char, namelen + 2 + dim);
+        namebuf[dim] = 'L';
+        memcpy(namebuf + dim + 1, element->name->text, namelen);
+        namelen += (2 + dim);
+        namebuf[namelen - 1] = ';';
+    }
+       memset(namebuf, '[', dim);
+
+       c = get_array_class(utf_new(namebuf, namelen),
+                                               element->classloader,
+                                               element->classloader,
+                                               link);
+
+       DRELEASE;
+
+       return c;
+}
+
+
+/* class_lookup_classref *******************************************************
+
+   Looks up the constant_classref for a given classname in the classref
+   tables of a class.
+
+   IN:
+       cls..............the class containing the reference
+          name.............the name of the class refered to
+
+    RETURN VALUE:
+          a pointer to a constant_classref, or 
+          NULL if the reference was not found
+   
+*******************************************************************************/
+
+constant_classref *class_lookup_classref(classinfo *cls, utf *name)
+{
+       constant_classref *ref;
+       extra_classref *xref;
+       int count;
+
+       assert(cls);
+       assert(name);
+       assert(!cls->classrefcount || cls->classrefs);
+       
+       /* first search the main classref table */
+       count = cls->classrefcount;
+       ref = cls->classrefs;
+       for (; count; --count, ++ref)
+               if (ref->name == name)
+                       return ref;
+
+       /* next try the list of extra classrefs */
+       for (xref = cls->extclassrefs; xref; xref = xref->next) {
+               if (xref->classref.name == name)
+                       return &(xref->classref);
+       }
+
+       /* not found */
+       return NULL;
+}
+
+
+/* class_get_classref **********************************************************
+
+   Returns the constant_classref for a given classname.
+
+   IN:
+       cls..............the class containing the reference
+          name.............the name of the class refered to
+
+   RETURN VALUE:
+       a pointer to a constant_classref (never NULL)
+
+   NOTE:
+       The given name is not checked for validity!
+   
+*******************************************************************************/
+
+constant_classref *class_get_classref(classinfo *cls, utf *name)
+{
+       constant_classref *ref;
+       extra_classref *xref;
+
+       assert(cls);
+       assert(name);
+
+       ref = class_lookup_classref(cls,name);
+       if (ref)
+               return ref;
+
+       xref = NEW(extra_classref);
+       CLASSREF_INIT(xref->classref,cls,name);
+
+       xref->next = cls->extclassrefs;
+       cls->extclassrefs = xref;
+
+       return &(xref->classref);
+}
+
+
+/* class_get_self_classref *****************************************************
+
+   Returns the constant_classref to the class itself.
+
+   IN:
+       cls..............the class containing the reference
+
+   RETURN VALUE:
+       a pointer to a constant_classref (never NULL)
+
+*******************************************************************************/
+
+constant_classref *class_get_self_classref(classinfo *cls)
+{
+       /* XXX this should be done in a faster way. Maybe always make */
+       /* the classref of index 0 a self reference.                  */
+       return class_get_classref(cls,cls->name);
+}
+
+/* class_get_classref_multiarray_of ********************************************
+
+   Returns an array type reference with the given dimension and element class
+   reference.
+
+   IN:
+       dim..............the requested dimension
+                           dim must be in [1;255]. This is NOT checked!
+          ref..............the component class reference
+
+   RETURN VALUE:
+       a pointer to the class reference for the array type
+
+   NOTE:
+       The referer of `ref` is used as the referer for the new classref.
+
+*******************************************************************************/
+
+constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
+{
+    s4 namelen;
+    char *namebuf;
+       constant_classref *cr;
+       int32_t            dumpmarker;
+
+       assert(ref);
+       assert(dim >= 1 && dim <= 255);
+
+       DMARKER;
+
+    /* Assemble the array class name */
+    namelen = ref->name->blength;
+    
+    if (ref->name->text[0] == '[') {
+        /* the element is itself an array */
+        namebuf = DMNEW(char, namelen + dim);
+        memcpy(namebuf + dim, ref->name->text, namelen);
+        namelen += dim;
+    }
+    else {
+        /* the element is a non-array class */
+        namebuf = DMNEW(char, namelen + 2 + dim);
+        namebuf[dim] = 'L';
+        memcpy(namebuf + dim + 1, ref->name->text, namelen);
+        namelen += (2 + dim);
+        namebuf[namelen - 1] = ';';
+    }
+       memset(namebuf, '[', dim);
+
+    cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
+
+       DRELEASE;
+
+       return cr;
+}
+
+
+/* class_get_classref_component_of *********************************************
+
+   Returns the component classref of a given array type reference
+
+   IN:
+       ref..............the array type reference
+
+   RETURN VALUE:
+       a reference to the component class, or
+          NULL if `ref` is not an object array type reference
+
+   NOTE:
+       The referer of `ref` is used as the referer for the new classref.
+
+*******************************************************************************/
+
+constant_classref *class_get_classref_component_of(constant_classref *ref)
+{
+       s4 namelen;
+       char *name;
+       
+       assert(ref);
+
+       name = ref->name->text;
+       if (*name++ != '[')
+               return NULL;
+       
+       namelen = ref->name->blength - 1;
+       if (*name == 'L') {
+               name++;
+               namelen -= 2;
+       }
+       else if (*name != '[') {
+               return NULL;
+       }
+
+    return class_get_classref(ref->referer, utf_new(name, namelen));
+}
+
+
+/* class_findmethod ************************************************************
+       
+   Searches a 'classinfo' structure for a method having the given name
+   and descriptor. If descriptor is NULL, it is ignored.
+
+*******************************************************************************/
+
+methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
+{
+       methodinfo *m;
+       s4          i;
+
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
+                       return m;
+       }
+
+       return NULL;
+}
+
+
+/* class_resolvemethod *********************************************************
+       
+   Searches a class and it's super classes for a method.
+
+   Superinterfaces are *not* searched.
+
+*******************************************************************************/
+
+methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
+{
+       methodinfo *m;
+
+       while (c) {
+               m = class_findmethod(c, name, desc);
+
+               if (m)
+                       return m;
+
+               /* JVM Specification bug: 
+
+                  It is important NOT to resolve special <init> and <clinit>
+                  methods to super classes or interfaces; yet, this is not
+                  explicited in the specification.  Section 5.4.3.3 should be
+                  updated appropriately.  */
+
+               if (name == utf_init || name == utf_clinit)
+                       return NULL;
+
+               c = c->super;
+       }
+
+       return NULL;
+}
+
+
+/* class_resolveinterfacemethod_intern *****************************************
+
+   Internally used helper function. Do not use this directly.
+
+*******************************************************************************/
+
+static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
+                                                                                                          utf *name, utf *desc)
+{
+       methodinfo *m;
+       s4          i;
+
+       /* try to find the method in the class */
+
+       m = class_findmethod(c, name, desc);
+
+       if (m != NULL)
+               return m;
+
+       /* No method found?  Try the super interfaces. */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
+
+               if (m != NULL)
+                       return m;
+       }
+
+       /* no method found */
+
+       return NULL;
+}
+
+
+/* class_resolveclassmethod ****************************************************
+       
+   Resolves a reference from REFERER to a method with NAME and DESC in
+   class C.
+
+   If the method cannot be resolved the return value is NULL. If
+   EXCEPT is true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
+                                                                        classinfo *referer, bool throwexception)
+{
+       classinfo  *cls;
+       methodinfo *m;
+       s4          i;
+
+/*     if (c->flags & ACC_INTERFACE) { */
+/*             if (throwexception) */
+/*                     *exceptionptr = */
+/*                             new_exception(string_java_lang_IncompatibleClassChangeError); */
+/*             return NULL; */
+/*     } */
+
+       /* try class c and its superclasses */
+
+       cls = c;
+
+       m = class_resolvemethod(cls, name, desc);
+
+       if (m != NULL)
+               goto found;
+
+       /* Try the super interfaces. */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
+
+               if (m != NULL)
+                       goto found;
+       }
+       
+       if (throwexception)
+               exceptions_throw_nosuchmethoderror(c, name, desc);
+
+       return NULL;
+
+ found:
+       if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
+               if (throwexception)
+                       exceptions_throw_abstractmethoderror();
+
+               return NULL;
+       }
+
+       /* XXX check access rights */
+
+       return m;
+}
+
+
+/* class_resolveinterfacemethod ************************************************
+
+   Resolves a reference from REFERER to a method with NAME and DESC in
+   interface C.
+
+   If the method cannot be resolved the return value is NULL. If
+   EXCEPT is true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
+                                                                                classinfo *referer, bool throwexception)
+{
+       methodinfo *mi;
+
+       if (!(c->flags & ACC_INTERFACE)) {
+               if (throwexception)
+                       exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
+
+               return NULL;
+       }
+
+       mi = class_resolveinterfacemethod_intern(c, name, desc);
+
+       if (mi != NULL)
+               return mi;
+
+       /* try class java.lang.Object */
+
+       mi = class_findmethod(class_java_lang_Object, name, desc);
+
+       if (mi != NULL)
+               return mi;
+
+       if (throwexception)
+               exceptions_throw_nosuchmethoderror(c, name, desc);
+
+       return NULL;
+}
+
+
+/* class_findfield *************************************************************
+       
+   Searches for field with specified name and type in a classinfo
+   structure. If no such field is found NULL is returned.
+
+*******************************************************************************/
+
+fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
+{
+       s4 i;
+
+       for (i = 0; i < c->fieldscount; i++)
+               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
+                       return &(c->fields[i]);
+
+       if (c->super != NULL)
+               return class_findfield(c->super, name, desc);
+
+       return NULL;
+}
+
+
+/* class_findfield_approx ******************************************************
+       
+   Searches in 'classinfo'-structure for a field with the specified
+   name.
+
+*******************************************************************************/
+fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
+{
+       for (int32_t i = 0; i < c->fieldscount; i++) {
+               fieldinfo* f = &(c->fields[i]);
+
+               if (f->name == name)
+                       return f;
+       }
+
+       // Field not found.
+       exceptions_throw_nosuchfielderror(c, name);
+       return NULL;
+}
+
+
+/****************** Function: class_resolvefield_int ***************************
+
+    This is an internally used helper function. Do not use this directly.
+
+       Tries to resolve a field having the given name and type.
+    If the field cannot be resolved, NULL is returned.
+
+*******************************************************************************/
+
+static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
+{
+       fieldinfo *fi;
+       s4         i;
+
+       /* search for field in class c */
+
+       for (i = 0; i < c->fieldscount; i++) { 
+               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
+                       return &(c->fields[i]);
+               }
+    }
+
+       /* Try super interfaces recursively. */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               fi = class_resolvefield_int(c->interfaces[i], name, desc);
+
+               if (fi != NULL)
+                       return fi;
+       }
+
+       /* Try super class. */
+
+       if (c->super != NULL)
+               return class_resolvefield_int(c->super, name, desc);
+
+       /* not found */
+
+       return NULL;
+}
+
+
+/********************* Function: class_resolvefield ***************************
+       
+       Resolves a reference from REFERER to a field with NAME and DESC in class C.
+
+    If the field cannot be resolved, an exception is thrown and the
+    return value is NULL.
+
+*******************************************************************************/
+
+fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
+{
+       fieldinfo *fi;
+
+       fi = class_resolvefield_int(c, name, desc);
+
+       if (!fi) {
+               exceptions_throw_nosuchfielderror(c, name);
+               return NULL;
+       }
+
+       /* XXX check access rights */
+
+       return fi;
+}
+
+
+/* class_issubclass ************************************************************
+
+   Checks if sub is a descendant of super.
+       
+*******************************************************************************/
+
+bool class_issubclass(classinfo *sub, classinfo *super)
+{
+       classinfo *c;
+
+       c = sub;
+
+       for (;;) {
+               /* We reached java/lang/Object and did not find the requested
+                  super class. */
+
+               if (c == NULL)
+                       return false;
+
+               /* We found the requested super class. */
+
+               if (c == super)
+                       return true;
+
+               c = c->super;
+       }
+}
+
+
+/* class_isanysubclass *********************************************************
+
+   Checks a subclass relation between two classes. Implemented
+   interfaces are interpreted as super classes.
+
+   Return value: 1 ... sub is subclass of super
+                 0 ... otherwise
+
+*******************************************************************************/
+
+bool class_isanysubclass(classinfo *sub, classinfo *super)
+{
+       uint32_t diffval;
+       bool     result;
+
+       /* This is the trivial case. */
+
+       if (sub == super)
+               return true;
+
+       /* Primitive classes are only subclasses of themselves. */
+
+       if (class_is_primitive(sub) || class_is_primitive(super))
+               return false;
+
+       /* Check for interfaces. */
+
+       if (super->flags & ACC_INTERFACE) {
+               result = (sub->vftbl->interfacetablelength > super->index) &&
+                       (sub->vftbl->interfacetable[-super->index] != NULL);
+       }
+       else {
+               /* java.lang.Object is the only super class of any
+                  interface. */
+
+               if (sub->flags & ACC_INTERFACE)
+                       return (super == class_java_lang_Object);
+
+               LOCK_MONITOR_ENTER(linker_classrenumber_lock);
+
+               diffval = sub->vftbl->baseval - super->vftbl->baseval;
+               result  = diffval <= (uint32_t) super->vftbl->diffval;
+
+               LOCK_MONITOR_EXIT(linker_classrenumber_lock);
+       }
+
+       return result;
+}
+
+
+/* class_is_assignable_from ****************************************************
+
+   Return whether an instance of the "from" class parameter would be
+   an instance of this class "to" as well.
+
+   ARGUMENTS:
+       to ..... class
+          from ... class
+
+   RETURN:
+       true .... is assignable
+          false ... is not assignable
+
+*******************************************************************************/
+
+bool class_is_assignable_from(classinfo *to, classinfo *from)
+{
+       if (!(to->state & CLASS_LINKED))
+               if (!link_class(to))
+                       return false;
+
+       if (!(from->state & CLASS_LINKED))
+               if (!link_class(from))
+                       return false;
+
+       return class_isanysubclass(from, to);
+}
+
+
+/* class_is_instance ***********************************************************
+
+   Return if the given Java object is an instance of the given class.
+
+   ARGUMENTS:
+       c ... class
+          h ... Java object
+
+   RETURN:
+       true .... is instance
+          false ... is not instance
+
+*******************************************************************************/
+
+bool class_is_instance(classinfo *c, java_handle_t *h)
+{
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return false;
+
+       return builtin_instanceof(h, c);
+}
+
+
+/* class_get_componenttype *****************************************************
+
+   Return the component class of the given class.  If the given class
+   is not an array, return NULL.
+
+*******************************************************************************/
+
+classinfo *class_get_componenttype(classinfo *c)
+{
+       classinfo       *component;
+       arraydescriptor *ad;
+       
+       /* XXX maybe we could find a way to do this without linking. */
+       /* This way should be safe and easy, however.                */
+
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+
+       ad = c->vftbl->arraydesc;
+       
+       if (ad == NULL)
+               return NULL;
+       
+       if (ad->arraytype == ARRAYTYPE_OBJECT)
+               component = ad->componentvftbl->clazz;
+       else
+               component = Primitive_get_class_by_type(ad->arraytype);
+               
+       return component;
+}
+
+
+/* class_get_declaredclasses ***************************************************
+
+   Return an array of declared classes of the given class.
+
+*******************************************************************************/
+
+java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
+{
+       classref_or_classinfo  inner;
+       classref_or_classinfo  outer;
+       utf                   *outername;
+       int                    declaredclasscount;  /* number of declared classes */
+       int                    pos;                     /* current declared class */
+       java_handle_objectarray_t *oa;               /* array of declared classes */
+       int                    i;
+       classinfo             *ic;
+
+       declaredclasscount = 0;
+
+       if (!class_is_primitive(c) && !class_is_array(c)) {
+               /* Determine number of declared classes. */
+
+               for (i = 0; i < c->innerclasscount; i++) {
+                       /* Get outer-class.  If the inner-class is not a member
+                          class, the outer-class is NULL. */
+
+                       outer = c->innerclass[i].outer_class;
+
+                       if (outer.any == NULL)
+                               continue;
+
+                       /* Check if outer-class is a classref or a real class and
+               get the class name from the structure. */
+
+                       outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
+
+                       /* Outer class is this class. */
+
+                       if ((outername == c->name) &&
+                               ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
+                               declaredclasscount++;
+               }
+       }
+
+       /* Allocate Class[] and check for OOM. */
+
+       oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
+
+       if (oa == NULL)
+               return NULL;
+
+       for (i = 0, pos = 0; i < c->innerclasscount; i++) {
+               inner = c->innerclass[i].inner_class;
+               outer = c->innerclass[i].outer_class;
+
+               /* Get outer-class.  If the inner-class is not a member class,
+                  the outer-class is NULL. */
+
+               if (outer.any == NULL)
+                       continue;
+
+               /* Check if outer_class is a classref or a real class and get
+                  the class name from the structure. */
+
+               outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
+
+               /* Outer class is this class. */
+
+               if ((outername == c->name) &&
+                       ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
+
+                       ic = resolve_classref_or_classinfo_eager(inner, false);
+
+                       if (ic == NULL)
+                               return NULL;
+
+                       if (!(ic->state & CLASS_LINKED))
+                               if (!link_class(ic))
+                                       return NULL;
+
+                       LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
+               }
+       }
+
+       return oa;
+}
+
+
+/**
+ * Return an array of declared constructors of the given class.
+ *
+ * @param c          class to get the constructors of
+ * @param publicOnly show only public fields
+ *
+ * @return array of java.lang.reflect.Constructor
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
+{
+       methodinfo*                m;
+       java_handle_objectarray_t* oa;
+       java_handle_t*             rc;
+       int                        count;
+       int                        index;
+       int                        i;
+
+       /* Determine number of constructors. */
+
+       count = 0;
+
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+                       (m->name == utf_init))
+                       count++;
+       }
+
+       /* Create array of constructors. */
+
+       oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
+
+       if (oa == NULL)
+               return NULL;
+
+       /* Get the constructors and store them in the array. */
+
+       for (i = 0, index = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+                       (m->name == utf_init)) {
+                       // Create a java.lang.reflect.Constructor object.
+
+                       rc = java_lang_reflect_Constructor_create(m);
+
+                       /* Store object into array. */
+
+                       array_objectarray_element_set(oa, index, rc);
+                       index++;
+               }
+       }
+
+       return oa;
+}
+#endif
+
+
+/* class_get_declaredfields ****************************************************
+
+   Return an array of declared fields of the given class.
+
+   ARGUMENTS:
+       c ............ class to get the fields of
+          publicOnly ... show only public fields
+
+   RETURN:
+       array of java.lang.reflect.Field
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
+{
+       java_handle_objectarray_t *oa;
+       fieldinfo                 *f;
+       java_handle_t             *h;
+       int                        count;
+       int                        index;
+       int                        i;
+
+       /* Determine number of fields. */
+
+       count = 0;
+
+       for (i = 0; i < c->fieldscount; i++)
+               if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
+                       count++;
+
+       /* Create array of fields. */
+
+       oa = builtin_anewarray(count, class_java_lang_reflect_Field);
+
+       if (oa == NULL)
+               return NULL;
+
+       /* Get the fields and store them in the array. */
+
+       for (i = 0, index = 0; i < c->fieldscount; i++) {
+               f = &(c->fields[i]);
+
+               if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
+                       // Create a java.lang.reflect.Field object.
+
+                       h = java_lang_reflect_Field_create(f);
+
+                       /* Store object into array. */
+
+                       array_objectarray_element_set(oa, index, h);
+                       index++;
+               }
+       }
+
+       return oa;
+}
+#endif
+
+
+/* class_get_declaredmethods ***************************************************
+
+   Return an array of declared methods of the given class.
+
+   ARGUMENTS:
+       c ............ class to get the methods of
+          publicOnly ... show only public methods
+
+   RETURN:
+       array of java.lang.reflect.Method
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
+{
+       java_handle_objectarray_t *oa;         /* result: array of Method-objects */
+       methodinfo                *m;     /* the current method to be represented */
+       java_handle_t             *h;
+       int                        count;
+       int                        index;
+       int                        i;
+
+       /* JOWENN: array classes do not declare methods according to mauve
+          test.  It should be considered, if we should return to my old
+          clone method overriding instead of declaring it as a member
+          function. */
+
+       if (class_is_array(c))
+               return builtin_anewarray(0, class_java_lang_reflect_Method);
+
+       /* Determine number of methods. */
+
+       count = 0;
+
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+                       ((m->name != utf_init) && (m->name != utf_clinit)) &&
+                       !(m->flags & ACC_MIRANDA))
+                       count++;
+       }
+
+       /* Create array of methods. */
+
+       oa = builtin_anewarray(count, class_java_lang_reflect_Method);
+
+       if (oa == NULL)
+               return NULL;
+
+       /* Get the methods and store them in the array. */
+
+       for (i = 0, index = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
+                       ((m->name != utf_init) && (m->name != utf_clinit)) &&
+                       !(m->flags & ACC_MIRANDA)) {
+                       // Create java.lang.reflect.Method object.
+
+                       h = java_lang_reflect_Method_create(m);
+
+                       /* Store object into array. */
+
+                       array_objectarray_element_set(oa, index, h);
+                       index++;
+               }
+       }
+
+       return oa;
+}
+#endif
+
+
+/* class_get_declaringclass ****************************************************
+
+   If the class or interface given is a member of another class,
+   return the declaring class.  For array and primitive classes return
+   NULL.
+
+*******************************************************************************/
+
+classinfo *class_get_declaringclass(classinfo *c)
+{
+       classref_or_classinfo  cr;
+       classinfo             *dc;
+
+       /* Get declaring class. */
+
+       cr = c->declaringclass;
+
+       if (cr.any == NULL)
+               return NULL;
+
+       /* Resolve the class if necessary. */
+
+       if (IS_CLASSREF(cr)) {
+/*             dc = resolve_classref_eager(cr.ref); */
+               dc = resolve_classref_or_classinfo_eager(cr, true);
+
+               if (dc == NULL)
+                       return NULL;
+
+               /* Store the resolved class in the class structure. */
+
+               cr.cls = dc;
+       }
+
+       dc = cr.cls;
+
+       return dc;
+}
+
+
+/* class_get_enclosingclass ****************************************************
+
+   Return the enclosing class for the given class.
+
+*******************************************************************************/
+
+classinfo *class_get_enclosingclass(classinfo *c)
+{
+       classref_or_classinfo  cr;
+       classinfo             *ec;
+
+       /* Get enclosing class. */
+
+       cr = c->enclosingclass;
+
+       if (cr.any == NULL)
+               return NULL;
+
+       /* Resolve the class if necessary. */
+
+       if (IS_CLASSREF(cr)) {
+/*             ec = resolve_classref_eager(cr.ref); */
+               ec = resolve_classref_or_classinfo_eager(cr, true);
+
+               if (ec == NULL)
+                       return NULL;
+
+               /* Store the resolved class in the class structure. */
+
+               cr.cls = ec;
+       }
+
+       ec = cr.cls;
+
+       return ec;
+}
+
+
+/**
+ * Return the enclosing constructor as java.lang.reflect.Constructor
+ * object for the given class.
+ *
+ * @param c class to return the enclosing constructor for
+ *
+ * @return java.lang.reflect.Constructor object of the enclosing
+ * constructor
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_t* class_get_enclosingconstructor(classinfo *c)
+{
+       methodinfo*    m;
+       java_handle_t* rc;
+
+       m = class_get_enclosingmethod_raw(c);
+
+       if (m == NULL)
+               return NULL;
+
+       /* Check for <init>. */
+
+       if (m->name != utf_init)
+               return NULL;
+
+       // Create a java.lang.reflect.Constructor object.
+
+       rc = java_lang_reflect_Constructor_create(m);
+
+       return rc;
+}
+#endif
+
+
+/* class_get_enclosingmethod ***************************************************
+
+   Return the enclosing method for the given class.
+
+   IN:
+       c ... class to return the enclosing method for
+
+   RETURN:
+       methodinfo of the enclosing method
+
+*******************************************************************************/
+
+methodinfo *class_get_enclosingmethod_raw(classinfo *c)
+{
+       constant_nameandtype *cn;
+       classinfo            *ec;
+       methodinfo           *m;
+
+       /* get enclosing class and method */
+
+       ec = class_get_enclosingclass(c);
+       cn = c->enclosingmethod;
+
+       /* check for enclosing class and method */
+
+       if (ec == NULL)
+               return NULL;
+
+       if (cn == NULL)
+               return NULL;
+
+       /* find method in enclosing class */
+
+       m = class_findmethod(ec, cn->name, cn->descriptor);
+
+       if (m == NULL) {
+               exceptions_throw_internalerror("Enclosing method doesn't exist");
+               return NULL;
+       }
+
+       return m;
+}
+
+
+/**
+ * Return the enclosing method as java.lang.reflect.Method object for
+ * the given class.
+ *
+ * @param c class to return the enclosing method for
+ *
+ * @return java.lang.reflect.Method object of the enclosing method
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_t* class_get_enclosingmethod(classinfo *c)
+{
+       methodinfo*    m;
+       java_handle_t* rm;
+
+       m = class_get_enclosingmethod_raw(c);
+
+       if (m == NULL)
+               return NULL;
+
+       /* check for <init> */
+
+       if (m->name == utf_init)
+               return NULL;
+
+       // Create a java.lang.reflect.Method object.
+
+       rm = java_lang_reflect_Method_create(m);
+
+       return rm;
+}
+#endif
+
+
+/* class_get_interfaces ********************************************************
+
+   Return an array of interfaces of the given class.
+
+*******************************************************************************/
+
+java_handle_objectarray_t *class_get_interfaces(classinfo *c)
+{
+       classinfo                 *ic;
+       java_handle_objectarray_t *oa;
+       u4                         i;
+
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+
+       oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
+
+       if (oa == NULL)
+               return NULL;
+
+       for (i = 0; i < c->interfacescount; i++) {
+               ic = c->interfaces[i];
+
+               LLNI_array_direct(oa, i) = (java_object_t *) ic;
+       }
+
+       return oa;
+}
+
+
+/* class_get_annotations *******************************************************
+
+   Get the unparsed declared annotations in a byte array
+   of the given class.
+
+   IN:
+       c........the class of which the annotations should be returned
+
+   RETURN VALUE:
+       The unparsed declared annotations in a byte array
+       (or NULL if there aren't any).
+
+*******************************************************************************/
+
+java_handle_bytearray_t *class_get_annotations(classinfo *c)
+{
+#if defined(ENABLE_ANNOTATIONS)
+       java_handle_t *annotations; /* unparsed annotations */
+
+       LLNI_classinfo_field_get(c, annotations, annotations);
+
+       return (java_handle_bytearray_t*)annotations;
+#else
+       return NULL;
+#endif
+}
+
+
+/* class_get_modifiers *********************************************************
+
+   Get the modifier flags of the given class.
+
+   IN:
+       c....the class of which the modifier flags should be returned
+          ignoreInnerClassesAttrib
+   RETURN VALUE:
+       modifier flags
+
+*******************************************************************************/
+
+int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
+{
+       classref_or_classinfo  inner;
+       classref_or_classinfo  outer;
+       utf                   *innername;
+       int                    i;
+
+       if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
+               /* search for passed class as inner class */
+
+               for (i = 0; i < c->innerclasscount; i++) {
+                       inner = c->innerclass[i].inner_class;
+                       outer = c->innerclass[i].outer_class;
+
+                       /* Check if inner is a classref or a real class and get
+               the name of the structure */
+
+                       innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
+
+                       /* innerclass is this class */
+
+                       if (innername == c->name) {
+                               /* has the class actually an outer class? */
+
+                               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;
+                       }
+               }
+       }
+
+       /* passed class is no inner class or it was not requested */
+
+       return c->flags & ACC_CLASS_REFLECT_MASK;
+}
+
+
+/* class_get_signature *********************************************************
+
+   Return the signature of the given class.  For array and primitive
+   classes return NULL.
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+utf *class_get_signature(classinfo *c)
+{
+       /* For array and primitive classes return NULL. */
+
+       if (class_is_array(c) || class_is_primitive(c))
+               return NULL;
+
+       return c->signature;
+}
+#endif
+
+
+/* class_printflags ************************************************************
+
+   Prints flags of a class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_printflags(classinfo *c)
+{
+       if (c == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
+       if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
+       if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
+       if (c->flags & ACC_STATIC)       printf(" STATIC");
+       if (c->flags & ACC_FINAL)        printf(" FINAL");
+       if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
+       if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
+       if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
+       if (c->flags & ACC_NATIVE)       printf(" NATIVE");
+       if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
+       if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
+}
+#endif
+
+
+/* class_print *****************************************************************
+
+   Prints classname plus flags.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_print(classinfo *c)
+{
+       if (c == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       utf_display_printable_ascii(c->name);
+       class_printflags(c);
+}
+#endif
+
+
+/* class_classref_print ********************************************************
+
+   Prints classname plus referer class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_print(constant_classref *cr)
+{
+       if (cr == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       utf_display_printable_ascii(cr->name);
+       printf("(ref.by ");
+       if (cr->referer)
+               class_print(cr->referer);
+       else
+               printf("NULL");
+       printf(")");
+}
+#endif
+
+
+/* class_println ***************************************************************
+
+   Prints classname plus flags and new line.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_println(classinfo *c)
+{
+       class_print(c);
+       printf("\n");
+}
+#endif
+
+
+/* class_classref_println ******************************************************
+
+   Prints classname plus referer class and new line.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_println(constant_classref *cr)
+{
+       class_classref_print(cr);
+       printf("\n");
+}
+#endif
+
+
+/* class_classref_or_classinfo_print *******************************************
+
+   Prints classname plus referer class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_or_classinfo_print(classref_or_classinfo c)
+{
+       if (c.any == NULL) {
+               printf("(classref_or_classinfo) NULL");
+               return;
+       }
+       if (IS_CLASSREF(c))
+               class_classref_print(c.ref);
+       else
+               class_print(c.cls);
+}
+#endif
+
+
+/* class_classref_or_classinfo_println *****************************************
+
+   Prints classname plus referer class and a newline.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_or_classinfo_println(classref_or_classinfo c)
+{
+       class_classref_or_classinfo_print(c);
+       printf("\n");
+}
+#endif
+
+
+/* class_showconstantpool ******************************************************
+
+   Dump the constant pool of the given class to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_showconstantpool (classinfo *c) 
+{
+       u4 i;
+       void* e;
+
+       printf ("---- dump of constant pool ----\n");
+
+       for (i=0; i<c->cpcount; i++) {
+               printf ("#%d:  ", (int) i);
+               
+               e = c -> cpinfos [i];
+               if (e) {
+                       
+                       switch (c -> cptags [i]) {
+                       case CONSTANT_Class:
+                               printf ("Classreference -> ");
+                               utf_display_printable_ascii ( ((constant_classref*)e) -> name );
+                               break;
+                       case CONSTANT_Fieldref:
+                               printf ("Fieldref -> ");
+                               field_fieldref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_Methodref:
+                               printf ("Methodref -> ");
+                               method_methodref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_InterfaceMethodref:
+                               printf ("InterfaceMethod -> ");
+                               method_methodref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_String:
+                               printf ("String -> ");
+                               utf_display_printable_ascii (e);
+                               break;
+                       case CONSTANT_Integer:
+                               printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
+                               break;
+                       case CONSTANT_Float:
+                               printf ("Float -> %f", ((constant_float*)e) -> value);
+                               break;
+                       case CONSTANT_Double:
+                               printf ("Double -> %f", ((constant_double*)e) -> value);
+                               break;
+                       case CONSTANT_Long:
+                               {
+                                       u8 v = ((constant_long*)e) -> value;
+#if U8_AVAILABLE
+                                       printf ("Long -> %ld", (long int) v);
+#else
+                                       printf ("Long -> HI: %ld, LO: %ld\n", 
+                                                       (long int) v.high, (long int) v.low);
+#endif 
+                               }
+                               break;
+                       case CONSTANT_NameAndType:
+                               {
+                                       constant_nameandtype *cnt = e;
+                                       printf ("NameAndType: ");
+                                       utf_display_printable_ascii (cnt->name);
+                                       printf (" ");
+                                       utf_display_printable_ascii (cnt->descriptor);
+                               }
+                               break;
+                       case CONSTANT_Utf8:
+                               printf ("Utf8 -> ");
+                               utf_display_printable_ascii (e);
+                               break;
+                       default: 
+                               log_text("Invalid type of ConstantPool-Entry");
+                               assert(0);
+                       }
+               }
+
+               printf ("\n");
+       }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* class_showmethods ***********************************************************
+
+   Dump info about the fields and methods of the given class to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_showmethods (classinfo *c)
+{
+       s4 i;
+       
+       printf("--------- Fields and Methods ----------------\n");
+       printf("Flags: ");
+       class_printflags(c);
+       printf("\n");
+
+       printf("This: ");
+       utf_display_printable_ascii(c->name);
+       printf("\n");
+
+       if (c->super) {
+               printf("Super: ");
+               utf_display_printable_ascii(c->super->name);
+               printf ("\n");
+       }
+
+       printf("Index: %d\n", c->index);
+       
+       printf("Interfaces:\n");        
+       for (i = 0; i < c->interfacescount; i++) {
+               printf("   ");
+               utf_display_printable_ascii(c->interfaces[i]->name);
+               printf (" (%d)\n", c->interfaces[i]->index);
+       }
+
+       printf("Fields:\n");
+       for (i = 0; i < c->fieldscount; i++)
+               field_println(&(c->fields[i]));
+
+       printf("Methods:\n");
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+
+               if (!(m->flags & ACC_STATIC))
+                       printf("vftblindex: %d   ", m->vftblindex);
+
+               method_println(m);
+       }
+
+       printf ("Virtual function table:\n");
+       for (i = 0; i < c->vftbl->vftbllength; i++)
+               printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
+}
+#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/class.h b/src/vm/class.h
new file mode 100644 (file)
index 0000000..a1434be
--- /dev/null
@@ -0,0 +1,464 @@
+/* src/vm/class.h - class related functions header
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _CLASS_H
+#define _CLASS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* forward typedefs ***********************************************************/
+
+typedef struct classinfo      classinfo; 
+typedef struct innerclassinfo innerclassinfo;
+typedef struct extra_classref extra_classref;
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "toolbox/list.h"
+
+#if defined(ENABLE_JAVASE)
+# include "vm/annotation.h"
+#endif
+
+#include "vm/field.h"
+#include "vm/global.h"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+#include "vm/references.h"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+
+/* class state defines ********************************************************/
+
+#define CLASS_LOADING         0x0001
+#define CLASS_LOADED          0x0002
+#define CLASS_LINKING         0x0004
+#define CLASS_LINKED          0x0008
+#define CLASS_INITIALIZING    0x0010
+#define CLASS_INITIALIZED     0x0020
+#define CLASS_ERROR           0x0040
+
+
+/* some macros ****************************************************************/
+
+#define CLASS_IS_OR_ALMOST_INITIALIZED(c) \
+    (((c)->state & CLASS_INITIALIZING) || ((c)->state & CLASS_INITIALIZED))
+
+
+/* classinfo ******************************************************************/
+
+/* We define this dummy structure of java_lang_Class so we can
+   bootstrap cacaoh without needing a java_lang_Class.h file.  Whether
+   the size of the dummy structure is big enough is checked during
+   runtime in vm_create. */
+
+typedef struct {
+       java_object_t      header;
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       intptr_t           padding[4];
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       intptr_t           padding[19];
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+       intptr_t           padding[3];
+#else
+# error unknown classpath configuration
+#endif
+} dummy_java_lang_Class;
+
+struct classinfo {                /* class structure                          */
+       dummy_java_lang_Class object;
+
+       s4          flags;            /* ACC flags                                */
+       utf        *name;             /* class name                               */
+
+       s4          cpcount;          /* number of entries in constant pool       */
+       u1         *cptags;           /* constant pool tags                       */
+       void*      *cpinfos;          /* pointer to constant pool info structures */
+
+       s4          classrefcount;    /* number of symbolic class references      */
+       constant_classref *classrefs; /* table of symbolic class references       */
+       extra_classref *extclassrefs; /* additional classrefs                     */
+       s4          parseddescsize;   /* size of the parsed descriptors block     */
+       u1         *parseddescs;      /* parsed descriptors                       */
+
+       classinfo  *super;            /* super class                              */
+       classinfo  *sub;              /* sub class pointer                        */
+       classinfo  *nextsub;          /* pointer to next class in sub class list  */
+
+       int32_t     interfacescount;  /* number of interfaces                     */
+       classinfo **interfaces;       /* super interfaces                         */
+
+       int32_t     fieldscount;      /* number of fields                         */
+       fieldinfo  *fields;           /* field table                              */
+
+       int32_t     methodscount;     /* number of methods                        */
+       methodinfo *methods;          /* method table                             */
+
+       s4          state;            /* current class state                      */
+       s4          index;            /* hierarchy depth (classes) or index       */
+                                     /* (interfaces)                             */
+       s4          instancesize;     /* size of an instance of this class        */
+
+       vftbl_t    *vftbl;            /* pointer to virtual function table        */
+
+       methodinfo *finalizer;        /* finalizer method                         */
+
+       u2          innerclasscount;  /* number of inner classes                  */
+       innerclassinfo *innerclass;
+
+       classref_or_classinfo  declaringclass;
+       classref_or_classinfo  enclosingclass;  /* enclosing class                */
+       constant_nameandtype  *enclosingmethod; /* enclosing method               */
+
+       utf        *packagename;      /* full name of the package                 */
+       utf        *sourcefile;       /* SourceFile attribute                     */
+#if defined(ENABLE_JAVASE)
+       utf        *signature;        /* Signature attribute                      */
+#if defined(ENABLE_ANNOTATIONS)
+       /* All the annotation attributes are NULL (and not a zero length array)   */
+       /* if there is nothing.                                                   */
+       java_object_t *annotations;   /* annotations of this class                */
+       
+       java_object_t *method_annotations; /* array of annotations of the methods */
+       java_object_t *method_parameterannotations; /* array of parameter         */
+                                     /* annotations of the methods               */
+       java_object_t *method_annotationdefaults; /* array of annotation default  */
+                                     /* values of the methods                    */
+
+       java_object_t *field_annotations; /* array of annotations of the fields   */
+
+#endif
+#endif
+       classloader_t *classloader;       /* NULL for bootstrap classloader         */
+
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       java_object_t      *protectiondomain;
+       java_objectarray_t *signers;
+# endif
+#endif
+#if defined(ENABLE_JITCACHE)
+       int         cache_file_fd;
+#endif
+};
+
+
+/* innerclassinfo *************************************************************/
+
+struct innerclassinfo {
+       classref_or_classinfo inner_class; /* inner class pointer                 */
+       classref_or_classinfo outer_class; /* outer class pointer                 */
+       utf                  *name;        /* innerclass name                     */
+       s4                    flags;       /* ACC flags                           */
+};
+
+
+/* extra_classref **************************************************************
+
+   for classrefs not occurring within descriptors
+
+*******************************************************************************/
+
+struct extra_classref {
+       extra_classref    *next;
+       constant_classref  classref;
+};
+
+
+/* inline functions ***********************************************************/
+
+/**
+ * Returns the classname of the class, where slashes ('/') are
+ * replaced by dots ('.').
+ *
+ * @param c class to get name of
+ * @return classname
+ */
+inline static java_handle_t* class_get_classname(classinfo* c)
+{
+       java_handle_t *s;
+
+       /* Create a java string. */
+
+       s = javastring_new_slash_to_dot(c->name);
+
+       return s;
+}
+
+
+/* class_is_primitive **********************************************************
+
+   Checks if the given class is a primitive class.
+
+*******************************************************************************/
+
+static inline bool class_is_primitive(classinfo *c)
+{
+       if (c->flags & ACC_CLASS_PRIMITIVE)
+               return true;
+
+       return false;
+}
+
+
+/* class_is_anonymousclass *****************************************************
+
+   Checks if the given class is an anonymous class.
+
+*******************************************************************************/
+
+static inline bool class_is_anonymousclass(classinfo *c)
+{
+       if (c->flags & ACC_CLASS_ANONYMOUS)
+               return true;
+
+       return false;
+}
+
+
+/* class_is_array **************************************************************
+
+   Checks if the given class is an array class.
+
+*******************************************************************************/
+
+static inline bool class_is_array(classinfo *c)
+{
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return false;
+
+       return (c->vftbl->arraydesc != NULL);
+}
+
+
+/* class_is_interface **********************************************************
+
+   Checks if the given class is an interface.
+
+*******************************************************************************/
+
+static inline bool class_is_interface(classinfo *c)
+{
+       if (c->flags & ACC_INTERFACE)
+               return true;
+
+       return false;
+}
+
+
+/* class_is_localclass *********************************************************
+
+   Checks if the given class is a local class.
+
+*******************************************************************************/
+
+static inline bool class_is_localclass(classinfo *c)
+{
+       if ((c->enclosingmethod != NULL) && !class_is_anonymousclass(c))
+               return true;
+
+       return false;
+}
+
+
+/* class_is_memberclass ********************************************************
+
+   Checks if the given class is a member class.
+
+*******************************************************************************/
+
+static inline bool class_is_memberclass(classinfo *c)
+{
+       if (c->flags & ACC_CLASS_MEMBER)
+               return true;
+
+       return false;
+}
+
+
+/* class_get_classloader *******************************************************
+
+   Return the classloader of the given class.
+
+*******************************************************************************/
+
+static inline classloader_t *class_get_classloader(classinfo *c)
+{
+       classloader_t *cl;
+
+       cl = c->classloader;
+
+       /* The classloader may be NULL. */
+
+       return cl;
+}
+
+
+/* class_get_superclass ********************************************************
+
+   Return the super class of the given class.
+
+*******************************************************************************/
+
+static inline classinfo *class_get_superclass(classinfo *c)
+{
+       /* For interfaces we return NULL. */
+
+       if (c->flags & ACC_INTERFACE)
+               return NULL;
+
+       /* For java/lang/Object, primitive-type and Void classes c->super
+          is NULL and we return NULL. */
+
+       return c->super;
+}
+
+
+/* function prototypes ********************************************************/
+
+classinfo *class_create_classinfo(utf *u);
+void       class_postset_header_vftbl(void);
+classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd);
+void       class_set_packagename(classinfo *c);
+
+bool       class_load_attributes(classbuffer *cb);
+
+/* retrieve constantpool element */
+void* class_getconstant(classinfo *c, u4 pos, u4 ctype);
+void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype);
+
+/* frees all resources used by the class */
+void class_free(classinfo *);
+
+/* return an array class with the given component class */
+classinfo *class_array_of(classinfo *component,bool link);
+
+/* return an array class with the given dimension and element class */
+classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link);
+
+/* return a classref for the given class name */
+/* (does a linear search!)                    */
+constant_classref *class_lookup_classref(classinfo *cls,utf *name);
+
+/* return a classref for the given class name */
+/* (does a linear search!)                    */
+constant_classref *class_get_classref(classinfo *cls,utf *name);
+
+/* return a classref to the class itself */
+/* (does a linear search!)                    */
+constant_classref *class_get_self_classref(classinfo *cls);
+
+/* return a classref for an array with the given dimension of with the */
+/* given component type */
+constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref);
+
+/* return a classref for the component type of the given array type */
+constant_classref *class_get_classref_component_of(constant_classref *ref);
+
+/* get a class' field by name and descriptor */
+fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc);
+
+/* search 'classinfo'-structure for a field with the specified name */
+fieldinfo *class_findfield_by_name(classinfo *c, utf *name);
+
+/* search class for a field */
+fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer);
+
+/* search for a method with a specified name and descriptor */
+methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc);
+methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *dest);
+methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
+methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
+
+bool                       class_issubclass(classinfo *sub, classinfo *super);
+bool                       class_isanysubclass(classinfo *sub, classinfo *super);
+bool                       class_is_assignable_from(classinfo *to, classinfo *from);
+bool                       class_is_instance(classinfo *c, java_handle_t *h);
+
+classloader_t             *class_get_classloader(classinfo *c);
+classinfo                 *class_get_superclass(classinfo *c);
+classinfo                 *class_get_componenttype(classinfo *c);
+java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly);
+java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly);
+java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly);
+java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly);
+classinfo                 *class_get_declaringclass(classinfo *c);
+classinfo                 *class_get_enclosingclass(classinfo *c);
+java_handle_t*             class_get_enclosingconstructor(classinfo *c);
+methodinfo*                class_get_enclosingmethod_raw(classinfo *c);
+java_handle_t*             class_get_enclosingmethod(classinfo *c);
+java_handle_objectarray_t *class_get_interfaces(classinfo *c);
+java_handle_bytearray_t   *class_get_annotations(classinfo *c);
+int32_t                    class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib);
+java_handle_t             *class_get_name(classinfo *c);
+
+#if defined(ENABLE_JAVASE)
+utf                       *class_get_signature(classinfo *c);
+#endif
+
+/* some debugging functions */
+
+#if !defined(NDEBUG)
+void class_printflags(classinfo *c);
+void class_print(classinfo *c);
+void class_println(classinfo *c);
+void class_classref_print(constant_classref *cr);
+void class_classref_println(constant_classref *cr);
+void class_classref_or_classinfo_print(classref_or_classinfo c);
+void class_classref_or_classinfo_println(classref_or_classinfo c);
+#endif
+
+/* debug purposes */
+void class_showmethods(classinfo *c);
+void class_showconstantpool(classinfo *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CLASS_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/classcache.c b/src/vm/classcache.c
new file mode 100644 (file)
index 0000000..3de9665
--- /dev/null
@@ -0,0 +1,1587 @@
+/* src/vm/classcache.c - loaded class cache and loading constraints
+
+   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 "mm/memory.h"
+
+#include "threads/lock-common.h"
+
+#include "toolbox/hashtable.h"
+#include "toolbox/logging.h"
+
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/options.h"
+#include "vm/utf8.h"
+
+
+/*************************************************************************
+
+  Class Cache
+
+  The classcache has two functions:
+  
+       1) caching the resolution of class references
+       2) storing and checking loading constraints
+
+  We will use the following terms in this description:
+
+       N          a class name: a utf string
+       (N,L)      a class reference with initiating loader L and class name N
+       C          a class (object): the result of resolving a reference (N,L)
+               We will write resultion as
+                               C = *(N,L)
+       (N,L1,L2)  a loading constraint indicating that (N,L1) and (N,L2) must
+                  resolve to the same class C. So (N,L1,L2) means
+                               *(N,L1) = *(N,L2)
+
+  The functions of the classcache require:
+
+    1) a mapping (N,L) |--> C for looking up prior resolution results.
+       2) storing the current set of loading constraints { (N,L1,L2) }
+
+  These functions can be rearranged like that:
+
+    a mapping N |--> (a mapping L |--> C or NULL, 
+                         a set of constraints {(L1,L2)})
+
+  Thus we can treat the mapping and constraints for each name N
+  separately. The implementation does this by keeping a hash table
+  mapping a name N to a `classcache_name_entry` which contains all
+  info with respect to N.
+
+  For a class name N we can define an equivalence relation ~N~ on
+  class loaders:
+
+       L1 ~N~ L2  <==>  *(N,L1) = *(N,L2)
+
+  A loading constraint (N,L1,L2) implies L1 ~N~ L2.
+
+  Also, if two references (N,L1) and (N,L2) resolve to the same class C
+  we have L1 ~N~ L2 because class loaders are required to return
+  consistent resolutions for a name N [XXX].
+
+  A `classcache_name_entry` keeps a set of tuples { (Cx,IL,CL) },
+  where
+               Cx...is a class C or NULL
+               IL...is the set of initiating loaders
+               CL...is the set of constrained loaders
+               
+  Such a tuple is called `classcache_class_entry` in the source code.
+
+  The following holds for each tuple (Cx,IL,CL):
+
+    .  (Cx is NULL) implies IL = {}.
+          
+       .  If Cx is a class, IL is the set of loaders that have been
+          recorded as initiating loaders for Cx. IL may be the
+          empty set {} in case Cx has already been defined but no
+          initiating loader has been recorded, yet.
+  
+    .  (IL u CL) is a subset of an equivalence class of ~N~.
+
+                (This means that all loaders in IL and CL must resolve
+                the name N to the same class.)
+
+  The following holds for the set of tuples { (Cx,IL,CL) }:
+
+    .  For a given class C there is at most one tuple with Cx = C
+          in the set. (There may be an arbitrary number of tuples
+          with Cx = NULL, however.)
+
+       .  For a given loader L there is at most one tuple with
+          L in (IL u CL).
+
+  The implementation stores sets of loaders as linked lists of
+  `classcache_loader_entry`s.
+
+  Comments about manipulating the classcache can be found in the
+  individual functions below.
+*************************************************************************/
+
+
+/* initial number of slots in the classcache hash table */
+#define CLASSCACHE_INIT_SIZE  2048
+
+/*============================================================================*/
+/* DEBUG HELPERS                                                              */
+/*============================================================================*/
+
+/* #define CLASSCACHE_VERBOSE */
+
+/*============================================================================*/
+/* STATISTICS                                                                 */
+/*============================================================================*/
+
+/*#define CLASSCACHE_STATS*/
+
+#ifdef CLASSCACHE_STATS
+static int stat_classnames_stored = 0;
+static int stat_classes_stored = 0;
+static int stat_trivial_constraints = 0;
+static int stat_nontriv_constraints = 0;
+static int stat_nontriv_constraints_both = 0;
+static int stat_nontriv_constraints_merged = 0;
+static int stat_nontriv_constraints_one = 0;
+static int stat_nontriv_constraints_none = 0;
+static int stat_new_loader_entry = 0;
+static int stat_merge_class_entries = 0;
+static int stat_merge_loader_entries = 0;
+static int stat_lookup = 0;
+static int stat_lookup_class_entry_checked = 0;
+static int stat_lookup_loader_checked = 0;
+static int stat_lookup_name = 0;
+static int stat_lookup_name_entry = 0;
+static int stat_lookup_name_notfound = 0;
+static int stat_lookup_new_name = 0;
+static int stat_lookup_new_name_entry = 0;
+static int stat_lookup_new_name_collisions = 0;
+static int stat_rehash_names = 0;
+static int stat_rehash_names_collisions = 0;
+
+#define CLASSCACHE_COUNT(cnt)  (cnt)++
+#define CLASSCACHE_COUNTIF(cond,cnt)  do{if(cond) (cnt)++;} while(0)
+
+void classcache_print_statistics(FILE *file) {
+       fprintf(file,"classnames stored   : %8d\n",stat_classnames_stored);
+       fprintf(file,"classes stored      : %8d\n",stat_classes_stored);
+       fprintf(file,"trivial constraints : %8d\n",stat_trivial_constraints);
+       fprintf(file,"non-triv constraints: %8d\n",stat_nontriv_constraints);
+       fprintf(file,"   both loaders rec.: %8d\n",stat_nontriv_constraints_both);
+       fprintf(file,"       merged       : %8d\n",stat_nontriv_constraints_merged);
+       fprintf(file,"   one loader rec.  : %8d\n",stat_nontriv_constraints_one);
+       fprintf(file,"   no loaders rec.  : %8d\n",stat_nontriv_constraints_none);
+       fprintf(file,"new loader entries  : %8d\n",stat_new_loader_entry);
+       fprintf(file,"merge class entries : %8d\n",stat_merge_class_entries);
+       fprintf(file,"merge loader entries: %8d\n",stat_merge_loader_entries);
+       fprintf(file,"lookups             : %8d\n",stat_lookup);
+       fprintf(file,"   class entries ckd: %8d\n",stat_lookup_class_entry_checked);
+       fprintf(file,"   loader checked   : %8d\n",stat_lookup_loader_checked);
+       fprintf(file,"lookup name         : %8d\n",stat_lookup_name);
+       fprintf(file,"   entries checked  : %8d\n",stat_lookup_name_entry);
+       fprintf(file,"   not found        : %8d\n",stat_lookup_name_notfound);
+       fprintf(file,"lookup (new) name   : %8d\n",stat_lookup_new_name);
+       fprintf(file,"   entries checked  : %8d\n",stat_lookup_new_name_entry);
+       fprintf(file,"   new collisions   : %8d\n",stat_lookup_new_name_collisions);
+       fprintf(file,"names rehashed      : %8d times\n",stat_rehash_names);
+       fprintf(file,"    collisions      : %8d\n",stat_rehash_names_collisions);
+}
+#else
+#define CLASSCACHE_COUNT(cnt)
+#define CLASSCACHE_COUNTIF(cond,cnt)
+#endif
+
+/*============================================================================*/
+/* THREAD-SAFE LOCKING                                                        */
+/*============================================================================*/
+
+       /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+       /* CAUTION: The static functions below are */
+       /*          NOT synchronized!              */
+       /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+#if defined(ENABLE_THREADS)
+# define CLASSCACHE_LOCK()      LOCK_MONITOR_ENTER(lock_hashtable_classcache)
+# define CLASSCACHE_UNLOCK()    LOCK_MONITOR_EXIT(lock_hashtable_classcache)
+#else
+# define CLASSCACHE_LOCK()
+# define CLASSCACHE_UNLOCK()
+#endif
+
+/*============================================================================*/
+/* GLOBAL VARIABLES                                                           */
+/*============================================================================*/
+
+hashtable hashtable_classcache;
+
+#if defined(ENABLE_THREADS)
+static java_object_t *lock_hashtable_classcache;
+#endif
+
+
+/*============================================================================*/
+/*                                                                            */
+/*============================================================================*/
+
+/* prototypes */
+
+static void classcache_free_class_entry(classcache_class_entry *clsen);
+static void classcache_remove_class_entry(classcache_name_entry *en,
+                                                                                 classcache_class_entry *clsen);
+
+/* hash function to use */
+
+#define CLASSCACHE_HASH utf_full_hashkey
+
+/* classcache_init *************************************************************
+   Initialize the class cache
+
+   Note: NOT synchronized!
+  
+*******************************************************************************/
+
+bool classcache_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("classcache_init");
+
+       /* create the hashtable */
+
+       hashtable_create(&hashtable_classcache, CLASSCACHE_INIT_SIZE);
+
+#if defined(ENABLE_THREADS)
+       /* create utf hashtable lock object */
+
+       lock_hashtable_classcache = NEW(java_object_t);
+
+       LOCK_INIT_OBJECT_LOCK(lock_hashtable_classcache);
+#endif
+
+       /* everything's ok */
+
+       return true;
+}
+
+/* classcache_new_loader_entry *************************************************
+   Create a new classcache_loader_entry struct
+   (internally used helper function)
+  
+   IN:
+       loader...........the ClassLoader object
+          next.............the next classcache_loader_entry
+
+   RETURN VALUE:
+       the new classcache_loader_entry
+  
+*******************************************************************************/
+
+static classcache_loader_entry * classcache_new_loader_entry(
+                                                                       classloader_t * loader,
+                                                                       classcache_loader_entry * next)
+{
+       classcache_loader_entry *lden;
+
+       lden = NEW(classcache_loader_entry);
+       lden->loader = loader;
+       lden->next = next;
+       CLASSCACHE_COUNT(stat_new_loader_entry);
+
+       return lden;
+}
+
+/* classcache_merge_loaders ****************************************************
+   Merge two lists of loaders into one
+   (internally used helper function)
+  
+   IN:
+       lista............first list (may be NULL)
+          listb............second list (may be NULL)
+
+   RETURN VALUE:
+       the merged list (may be NULL)
+
+   NOTE:
+       The lists given as arguments are destroyed!
+  
+*******************************************************************************/
+
+static classcache_loader_entry * classcache_merge_loaders(
+                                                                       classcache_loader_entry * lista,
+                                                                       classcache_loader_entry * listb)
+{
+       classcache_loader_entry *result;
+       classcache_loader_entry *ldenA;
+       classcache_loader_entry *ldenB;
+       classcache_loader_entry **chain;
+
+       CLASSCACHE_COUNT(stat_merge_loader_entries);
+
+       /* XXX This is a quadratic algorithm. If this ever
+        * becomes a problem, the loader lists should be
+        * stored as sorted lists and merged in linear time. */
+
+       result = NULL;
+       chain = &result;
+
+       for (ldenA = lista; ldenA; ldenA = ldenA->next) {
+
+               for (ldenB = listb; ldenB; ldenB = ldenB->next) {
+                       if (ldenB->loader == ldenA->loader)
+                               goto common_element;
+               }
+
+               /* this loader is only in lista */
+               *chain = ldenA;
+               chain = &(ldenA->next);
+
+         common_element:
+               /* XXX free the duplicated element */
+               ;
+       }
+
+       /* concat listb to the result */
+       *chain = listb;
+
+       return result;
+}
+
+/* classcache_merge_class_entries **********************************************
+   Merge two `classcache_class_entry`s into one.
+   (internally used helper function)
+  
+   IN:
+       en...............the classcache_name_entry containing both class entries
+       clsenA...........first class entry, will receive the result
+          clsenB...........second class entry
+
+   PRE-CONDITION:
+       Either both entries must have the same classobj, or one of them has
+          classobj == NULL.
+
+   NOTE:
+       clsenB is freed by this function!
+  
+*******************************************************************************/
+
+static void classcache_merge_class_entries(classcache_name_entry *en,
+                                                                                  classcache_class_entry *clsenA,
+                                                                                  classcache_class_entry *clsenB)
+{
+#ifdef CLASSCACHE_VERBOSE
+       char logbuffer[1024];
+#endif
+       
+       assert(en);
+       assert(clsenA);
+       assert(clsenB);
+       assert(!clsenA->classobj || !clsenB->classobj || clsenA->classobj == clsenB->classobj);
+
+#ifdef CLASSCACHE_VERBOSE
+       sprintf(logbuffer,"classcache_merge_class_entries(%p,%p->%p,%p->%p) ", 
+                       (void*)en,(void*)clsenA,(void*)clsenA->classobj,(void*)clsenB,(void*)clsenB->classobj);
+       if (clsenA->classobj)
+               utf_cat_classname(logbuffer, clsenA->classobj->name);
+       if (clsenB->classobj)
+               utf_cat_classname(logbuffer, clsenB->classobj->name);
+       log_println(logbuffer);
+#endif
+
+       CLASSCACHE_COUNT(stat_merge_class_entries);
+
+       /* clsenB will be merged into clsenA */
+       clsenA->loaders = classcache_merge_loaders(clsenA->loaders, clsenB->loaders);
+       clsenB->loaders = NULL; /* these have been freed or reused */
+
+       clsenA->constraints = classcache_merge_loaders(clsenA->constraints,
+                                                                                                  clsenB->constraints);
+       clsenB->constraints = NULL; /* these have been freed or reused */
+
+       if (!clsenA->classobj)
+               clsenA->classobj = clsenB->classobj;
+
+       /* remove clsenB from the list of class entries */
+       classcache_remove_class_entry(en, clsenB);
+}
+
+
+/* classcache_lookup_name ******************************************************
+   Lookup a name in the first level of the cache
+   (internally used helper function)
+   
+   IN:
+       name.............the name to look up
+  
+   RETURN VALUE:
+       a pointer to the classcache_name_entry for this name, or
+       null if no entry was found.
+          
+*******************************************************************************/
+
+static classcache_name_entry *classcache_lookup_name(utf *name)
+{
+       classcache_name_entry *c;           /* hash table element                 */
+       u4 key;                             /* hashkey computed from classname    */
+       u4 slot;                            /* slot in hashtable                  */
+
+       CLASSCACHE_COUNT(stat_lookup_name);
+
+       key  = CLASSCACHE_HASH(name->text, (u4) name->blength);
+       slot = key & (hashtable_classcache.size - 1);
+       c    = hashtable_classcache.ptr[slot];
+
+       /* search external hash chain for the entry */
+
+       while (c) {
+               /* entry found in hashtable */
+               CLASSCACHE_COUNT(stat_lookup_name_entry);
+
+               if (c->name == name)
+                       return c;
+
+               c = c->hashlink;                    /* next element in external chain */
+       }
+
+       /* not found */
+
+       CLASSCACHE_COUNT(stat_lookup_name_notfound);
+       return NULL;
+}
+
+
+/* classcache_new_name *********************************************************
+   Return a classcache_name_entry for the given name. The entry is created
+   if it is not already in the cache.
+   (internally used helper function)
+   
+   IN:
+       name.............the name to look up / create an entry for
+  
+   RETURN VALUE:
+       a pointer to the classcache_name_entry for this name
+          
+*******************************************************************************/
+
+static classcache_name_entry *classcache_new_name(utf *name)
+{
+       classcache_name_entry *c;       /* hash table element */
+       u4 key;                                         /* hashkey computed from classname */
+       u4 slot;                                        /* slot in hashtable               */
+       u4 i;
+
+       CLASSCACHE_COUNT(stat_lookup_new_name);
+
+       key  = CLASSCACHE_HASH(name->text, (u4) name->blength);
+       slot = key & (hashtable_classcache.size - 1);
+       c    = hashtable_classcache.ptr[slot];
+
+       /* search external hash chain for the entry */
+
+       while (c) {
+               /* entry found in hashtable */
+               CLASSCACHE_COUNT(stat_lookup_new_name_entry);
+
+               if (c->name == name)
+                       return c;
+
+               c = c->hashlink;                    /* next element in external chain */
+       }
+
+       /* location in hashtable found, create new entry */
+
+       c = NEW(classcache_name_entry);
+
+       c->name = name;
+       c->classes = NULL;
+
+       /* insert entry into hashtable */
+       c->hashlink = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+       CLASSCACHE_COUNTIF(c->hashlink,stat_lookup_new_name_collisions);
+       hashtable_classcache.ptr[slot] = c;
+
+       /* update number of hashtable-entries */
+       hashtable_classcache.entries++;
+       CLASSCACHE_COUNT(stat_classnames_stored);
+
+       if ((hashtable_classcache.entries*2) > hashtable_classcache.size) {
+               /* reorganization of hashtable */ 
+
+               classcache_name_entry *c2;
+               hashtable newhash;              /* the new hashtable */
+
+               CLASSCACHE_COUNT(stat_rehash_names);
+
+               /* create new hashtable, double the size */
+
+               hashtable_create(&newhash, hashtable_classcache.size * 2);
+               newhash.entries = hashtable_classcache.entries;
+
+               /* transfer elements to new hashtable */
+
+               for (i = 0; i < hashtable_classcache.size; i++) {
+                       c2 = (classcache_name_entry *) hashtable_classcache.ptr[i];
+                       while (c2) {
+                               classcache_name_entry *nextc = c2->hashlink;
+                               u4 newslot =
+                                       (CLASSCACHE_HASH(c2->name->text, (u4) c2->name->blength)) & (newhash.size - 1);
+
+                               c2->hashlink = (classcache_name_entry *) newhash.ptr[newslot];
+                               CLASSCACHE_COUNTIF(c2->hashlink,stat_rehash_names_collisions);
+                               newhash.ptr[newslot] = c2;
+
+                               c2 = nextc;
+                       }
+               }
+
+               /* dispose old table */
+
+               MFREE(hashtable_classcache.ptr, void *, hashtable_classcache.size);
+               hashtable_classcache = newhash;
+       }
+
+       return c;
+}
+
+
+/* classcache_lookup ***********************************************************
+   Lookup a possibly loaded class
+  
+   IN:
+       initloader.......initiating loader for resolving the class name
+       classname........class name to look up
+  
+   RETURN VALUE:
+       The return value is a pointer to the cached class object,
+       or NULL, if the class is not in the cache.
+
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+classinfo *classcache_lookup(classloader_t *initloader, utf *classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+       classinfo *cls = NULL;
+
+       CLASSCACHE_LOCK();
+
+       CLASSCACHE_COUNT(stat_lookup);
+       en = classcache_lookup_name(classname);
+
+       if (en) {
+               /* iterate over all class entries */
+
+               for (clsen = en->classes; clsen; clsen = clsen->next) {
+                       CLASSCACHE_COUNT(stat_lookup_class_entry_checked);
+                       /* check if this entry has been loaded by initloader */
+
+                       for (lden = clsen->loaders; lden; lden = lden->next) {
+                               CLASSCACHE_COUNT(stat_lookup_loader_checked);
+                               if (lden->loader == initloader) {
+                                       /* found the loaded class entry */
+
+                                       assert(clsen->classobj);
+                                       cls = clsen->classobj;
+                                       goto found;
+                               }
+                       }
+               }
+       }
+
+  found:
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
+
+/* classcache_lookup_defined ***************************************************
+   Lookup a class with the given name and defining loader
+  
+   IN:
+       defloader........defining loader
+       classname........class name
+  
+   RETURN VALUE:
+       The return value is a pointer to the cached class object,
+       or NULL, if the class is not in the cache.
+   
+*******************************************************************************/
+
+classinfo *classcache_lookup_defined(classloader_t *defloader, utf *classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classinfo *cls = NULL;
+
+       CLASSCACHE_LOCK();
+
+       en = classcache_lookup_name(classname);
+
+       if (en) {
+               /* iterate over all class entries */
+               for (clsen = en->classes; clsen; clsen = clsen->next) {
+                       if (!clsen->classobj)
+                               continue;
+
+                       /* check if this entry has been defined by defloader */
+                       if (clsen->classobj->classloader == defloader) {
+                               cls = clsen->classobj;
+                               goto found;
+                       }
+               }
+       }
+
+  found:
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
+
+/* classcache_lookup_defined_or_initiated **************************************
+   Lookup a class that has been defined or initiated by the given loader
+  
+   IN:
+       loader...........defining or initiating loader
+       classname........class name to look up
+  
+   RETURN VALUE:
+       The return value is a pointer to the cached class object,
+       or NULL, if the class is not in the cache.
+
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+classinfo *classcache_lookup_defined_or_initiated(classloader_t *loader, 
+                                                                                                 utf *classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+       classinfo *cls = NULL;
+
+       CLASSCACHE_LOCK();
+
+       en = classcache_lookup_name(classname);
+
+       if (en) {
+               /* iterate over all class entries */
+
+               for (clsen = en->classes; clsen; clsen = clsen->next) {
+
+                       /* check if this entry has been defined by loader */
+                       if (clsen->classobj && clsen->classobj->classloader == loader) {
+                               cls = clsen->classobj;
+                               goto found;
+                       }
+                       
+                       /* check if this entry has been initiated by loader */
+                       for (lden = clsen->loaders; lden; lden = lden->next) {
+                               if (lden->loader == loader) {
+                                       /* found the loaded class entry */
+
+                                       assert(clsen->classobj);
+                                       cls = clsen->classobj;
+                                       goto found;
+                               }
+                       }
+               }
+       }
+
+  found:
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
+
+/* classcache_store ************************************************************
+   
+   Store a loaded class. If a class of the same name has already been stored
+   with the same initiating loader, then the given class CLS is freed (if
+   possible) and the previously stored class is returned.
+  
+   IN:
+       initloader.......initiating loader used to load the class
+                           (may be NULL indicating the bootstrap loader)
+       cls..............class object to cache
+          mayfree..........true if CLS may be freed in case another class is
+                           returned
+  
+   RETURN VALUE:
+       cls..............everything ok, the class was stored in the cache,
+          other classinfo..another class with the same (initloader,name) has been
+                           stored earlier. CLS has been freed[1] and the earlier
+                                               stored class is returned.
+       NULL.............an exception has been thrown.
+   
+   Note: synchronized with global tablelock
+
+   [1]...in case MAYFREE is true
+   
+*******************************************************************************/
+
+classinfo *classcache_store(classloader_t *initloader, classinfo *cls,
+                                                       bool mayfree)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classcache_class_entry *clsenB;
+       classcache_loader_entry *lden;
+#ifdef CLASSCACHE_VERBOSE
+       char logbuffer[1024];
+#endif
+       
+       assert(cls);
+       assert(cls->state & CLASS_LOADED);
+
+       CLASSCACHE_LOCK();
+
+#ifdef CLASSCACHE_VERBOSE
+       sprintf(logbuffer,"classcache_store (%p,%d,%p=", (void*)initloader,mayfree,(void*)cls);
+       utf_cat_classname(logbuffer, cls->name);
+       strcat(logbuffer,")");
+       log_println(logbuffer);
+#endif
+
+       en = classcache_new_name(cls->name);
+
+       assert(en);
+
+       /* iterate over all class entries */
+       for (clsen = en->classes; clsen; clsen = clsen->next) {
+
+               /* check if this entry has already been loaded by initloader */
+               for (lden = clsen->loaders; lden; lden = lden->next) {
+                       if (lden->loader == initloader) {
+                          if (clsen->classobj != cls) {
+                                       /* A class with the same (initloader,name) pair has been stored already. */
+                                       /* We free the given class and return the earlier one.                   */
+#ifdef CLASSCACHE_VERBOSE
+                                       log_println("replacing %p with earlier loaded class %p",cls,clsen->classobj);
+#endif
+                                       assert(clsen->classobj);
+                                       if (mayfree)
+                                               class_free(cls);
+                                       cls = clsen->classobj;
+                          }
+                          goto return_success;
+                       }
+               }
+
+               /* {This entry has not been resolved with initloader} */
+
+               /* check if initloader is constrained to this entry */
+               for (lden = clsen->constraints; lden; lden = lden->next) {
+                       if (lden->loader == initloader) {
+                               /* we have to use this entry. check if it has been resolved */
+                               if (clsen->classobj) {
+                                       /* check if is has already been resolved to another class */
+                                       if (clsen->classobj != cls) {
+                                               /* a loading constraint is violated */
+                                               exceptions_throw_linkageerror("loading constraint violated: ", cls);
+                                               goto return_exception;
+                                       }
+
+                                       /* record initloader as initiating loader */
+                                       clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
+                                       goto return_success;
+                               }
+
+                               /* {this is the first resolution for this entry} */
+                               /* record initloader as initiating loader */
+                               clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
+
+                               /* maybe we can merge this entry with another one */
+                               for (clsenB = en->classes; clsenB; clsenB = clsenB->next) {
+                                       /* we dont want the entry that we have already */
+                                       if (clsenB->classobj == cls) {
+                                               /* this entry has the same classobj. let's merge them */
+                                               classcache_merge_class_entries(en,clsen,clsenB);
+                                               goto return_success;
+                                       }
+                               }
+
+                               /* record the loaded class object */
+                               clsen->classobj = cls;
+                               CLASSCACHE_COUNT(stat_classes_stored);
+
+                               /* done */
+                               goto return_success;
+                       }
+               }
+
+       }
+
+       /* {There is no class entry containing initloader as initiating 
+        *  or constrained loader.} */
+
+       /* we look for a class entry with the same classobj we want to store */
+       for (clsen = en->classes; clsen; clsen = clsen->next) {
+               if (clsen->classobj == cls) {
+                       /* this entry is about the same classobj. let's use it */
+                       /* check if this entry has already been loaded by initloader */
+                       for (lden = clsen->loaders; lden; lden = lden->next) {
+                               if (lden->loader == initloader)
+                                       goto return_success;
+                       }
+                       clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
+                       goto return_success;
+               }
+       }
+
+       /* create a new class entry for this class object with */
+       /* initiating loader initloader                        */
+
+       clsen = NEW(classcache_class_entry);
+       clsen->classobj = cls;
+       clsen->loaders = classcache_new_loader_entry(initloader, NULL);
+       clsen->constraints = NULL;
+
+       clsen->next = en->classes;
+       en->classes = clsen;
+       CLASSCACHE_COUNT(stat_classes_stored);
+
+  return_success:
+#ifdef CLASSCACHE_VERBOSE
+       classcache_debug_dump(stdout,cls->name);
+#endif
+       CLASSCACHE_UNLOCK();
+       return cls;
+
+  return_exception:
+       CLASSCACHE_UNLOCK();
+       return NULL;                            /* exception */
+}
+
+/* classcache_store_unique *****************************************************
+   
+   Store a loaded class as loaded by the bootstrap loader. This is a wrapper 
+   aroung classcache_store that throws an exception if a class with the same 
+   name has already been loaded by the bootstrap loader.
+
+   This function is used to register a few special classes during startup.
+   It should not be used otherwise.
+  
+   IN:
+       cls..............class object to cache
+  
+   RETURN VALUE:
+       true.............everything ok, the class was stored.
+       false............an exception has been thrown.
+   
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+bool classcache_store_unique(classinfo *cls)
+{
+       classinfo *result;
+
+       result = classcache_store(NULL,cls,false);
+       if (result == NULL)
+               return false;
+
+       if (result != cls) {
+               exceptions_throw_internalerror("class already stored in the class cache");
+               return false;
+       }
+
+       return true;
+}
+
+/* classcache_store_defined ****************************************************
+   
+   Store a loaded class after it has been defined. If the class has already
+   been defined by the same defining loader in another thread, free the given
+   class and returned the one which has been defined earlier.
+  
+   IN:
+       cls..............class object to store. classloader must be set
+                           (classloader may be NULL, for bootloader)
+  
+   RETURN VALUE:
+       cls..............everything ok, the class was stored the cache,
+          other classinfo..the class had already been defined, CLS was freed, the
+                           class which was defined earlier is returned,
+       NULL.............an exception has been thrown.
+   
+*******************************************************************************/
+
+classinfo *classcache_store_defined(classinfo *cls)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+#ifdef CLASSCACHE_VERBOSE
+       char logbuffer[1024];
+#endif
+
+       assert(cls);
+       assert(cls->state & CLASS_LOADED);
+
+       CLASSCACHE_LOCK();
+
+#ifdef CLASSCACHE_VERBOSE
+       sprintf(logbuffer,"classcache_store_defined (%p,", (void*)cls->classloader);
+       utf_cat_classname(logbuffer, cls->name);
+       strcat(logbuffer,")");
+       log_println(logbuffer);
+#endif
+
+       en = classcache_new_name(cls->name);
+
+       assert(en);
+
+       /* iterate over all class entries */
+       for (clsen = en->classes; clsen; clsen = clsen->next) {
+               
+               /* check if this class has been defined by the same classloader */
+               if (clsen->classobj && clsen->classobj->classloader == cls->classloader) {
+                       /* we found an earlier definition, delete the newer one */
+                       /* (if it is a different classinfo)                     */
+                       if (clsen->classobj != cls) {
+#ifdef CLASSCACHE_VERBOSE
+                               log_println("replacing %p with earlier defined class %p",cls,clsen->classobj);
+#endif
+                               class_free(cls);
+                               cls = clsen->classobj;
+                       }
+                       goto return_success;
+               }
+       }
+
+       /* create a new class entry for this class object */
+       /* the list of initiating loaders is empty at this point */
+
+       clsen = NEW(classcache_class_entry);
+       clsen->classobj = cls;
+       clsen->loaders = NULL;
+       clsen->constraints = NULL;
+
+       clsen->next = en->classes;
+       en->classes = clsen;
+       CLASSCACHE_COUNT(stat_classes_stored);
+
+return_success:
+#ifdef CLASSCACHE_VERBOSE
+       classcache_debug_dump(stdout,cls->name);
+#endif
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
+/* classcache_find_loader ******************************************************
+   Find the class entry loaded by or constrained to a given loader
+   (internally used helper function)
+  
+   IN:
+       entry............the classcache_name_entry
+       loader...........the loader to look for
+  
+   RETURN VALUE:
+       the classcache_class_entry for the given loader, or
+          NULL if no entry was found
+   
+*******************************************************************************/
+
+static classcache_class_entry * classcache_find_loader(
+                                                                       classcache_name_entry * entry,
+                                                                       classloader_t * loader)
+{
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+
+       assert(entry);
+
+       /* iterate over all class entries */
+       for (clsen = entry->classes; clsen; clsen = clsen->next) {
+
+               /* check if this entry has already been loaded by initloader */
+               for (lden = clsen->loaders; lden; lden = lden->next) {
+                       if (lden->loader == loader)
+                               return clsen;   /* found */
+               }
+
+               /* check if loader is constrained to this entry */
+               for (lden = clsen->constraints; lden; lden = lden->next) {
+                       if (lden->loader == loader)
+                               return clsen;   /* found */
+               }
+       }
+
+       /* not found */
+       return NULL;
+}
+
+/* classcache_free_class_entry *************************************************
+   Free the memory used by a class entry
+  
+   IN:
+       clsen............the classcache_class_entry to free  
+          
+*******************************************************************************/
+
+static void classcache_free_class_entry(classcache_class_entry * clsen)
+{
+       classcache_loader_entry *lden;
+       classcache_loader_entry *next;
+
+       assert(clsen);
+
+       for (lden = clsen->loaders; lden; lden = next) {
+               next = lden->next;
+               FREE(lden, classcache_loader_entry);
+       }
+       for (lden = clsen->constraints; lden; lden = next) {
+               next = lden->next;
+               FREE(lden, classcache_loader_entry);
+       }
+
+       FREE(clsen, classcache_class_entry);
+}
+
+/* classcache_remove_class_entry ***********************************************
+   Remove a classcache_class_entry from the list of possible resolution of
+   a name entry
+   (internally used helper function)
+  
+   IN:
+       entry............the classcache_name_entry
+       clsen............the classcache_class_entry to remove
+  
+*******************************************************************************/
+
+static void classcache_remove_class_entry(classcache_name_entry * entry,
+                                                                                 classcache_class_entry * clsen)
+{
+       classcache_class_entry **chain;
+
+       assert(entry);
+       assert(clsen);
+
+       chain = &(entry->classes);
+       while (*chain) {
+               if (*chain == clsen) {
+                       *chain = clsen->next;
+                       classcache_free_class_entry(clsen);
+                       return;
+               }
+               chain = &((*chain)->next);
+       }
+}
+
+/* classcache_free_name_entry **************************************************
+   Free the memory used by a name entry
+  
+   IN:
+       entry............the classcache_name_entry to free  
+          
+*******************************************************************************/
+
+static void classcache_free_name_entry(classcache_name_entry * entry)
+{
+       classcache_class_entry *clsen;
+       classcache_class_entry *next;
+
+       assert(entry);
+
+       for (clsen = entry->classes; clsen; clsen = next) {
+               next = clsen->next;
+               classcache_free_class_entry(clsen);
+       }
+
+       FREE(entry, classcache_name_entry);
+}
+
+/* classcache_free *************************************************************
+   Free the memory used by the class cache
+
+   NOTE:
+       The class cache may not be used any more after this call, except
+          when it is reinitialized with classcache_init.
+  
+   Note: NOT synchronized!
+  
+*******************************************************************************/
+
+void classcache_free(void)
+{
+       u4 slot;
+       classcache_name_entry *entry;
+       classcache_name_entry *next;
+
+       for (slot = 0; slot < hashtable_classcache.size; ++slot) {
+               for (entry = (classcache_name_entry *) hashtable_classcache.ptr[slot]; entry; entry = next) {
+                       next = entry->hashlink;
+                       classcache_free_name_entry(entry);
+               }
+       }
+
+       MFREE(hashtable_classcache.ptr, void*, hashtable_classcache.size);
+       hashtable_classcache.size = 0;
+       hashtable_classcache.entries = 0;
+       hashtable_classcache.ptr = NULL;
+}
+
+/* classcache_add_constraint ***************************************************
+   Add a loading constraint
+  
+   IN:
+       a................first initiating loader
+       b................second initiating loader
+       classname........class name
+  
+   RETURN VALUE:
+       true.............everything ok, the constraint has been added,
+       false............an exception has been thrown.
+   
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool classcache_add_constraint(classloader_t * a,
+                                                          classloader_t * b,
+                                                          utf * classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsenA;
+       classcache_class_entry *clsenB;
+
+       assert(classname);
+
+#ifdef CLASSCACHE_VERBOSE
+       log_start();
+       log_print("classcache_add_constraint(%p,%p,", (void *) a, (void *) b);
+       utf_fprint_printable_ascii_classname(stdout, classname);
+       log_print(")\n");
+       log_finish();
+#endif
+
+       /* a constraint with a == b is trivially satisfied */
+       if (a == b) {
+               CLASSCACHE_COUNT(stat_trivial_constraints);
+               return true;
+       }
+
+       CLASSCACHE_LOCK();
+
+       en = classcache_new_name(classname);
+
+       assert(en);
+       CLASSCACHE_COUNT(stat_nontriv_constraints);
+
+       /* find the entry loaded by / constrained to each loader */
+       clsenA = classcache_find_loader(en, a);
+       clsenB = classcache_find_loader(en, b);
+
+       if (clsenA && clsenB) {
+               /* { both loaders have corresponding entries } */
+               CLASSCACHE_COUNT(stat_nontriv_constraints_both);
+
+               /* if the entries are the same, the constraint is already recorded */
+               if (clsenA == clsenB)
+                       goto return_success;
+
+               /* check if the entries can be merged */
+               if (clsenA->classobj && clsenB->classobj
+                       && clsenA->classobj != clsenB->classobj) {
+                       /* no, the constraint is violated */
+                       exceptions_throw_linkageerror("loading constraint violated: ",
+                                                                                 clsenA->classobj);
+                       goto return_exception;
+               }
+
+               /* yes, merge the entries */
+               classcache_merge_class_entries(en,clsenA,clsenB);
+               CLASSCACHE_COUNT(stat_nontriv_constraints_merged);
+       }
+       else {
+               /* { at most one of the loaders has a corresponding entry } */
+
+               /* set clsenA to the single class entry we have */
+               if (!clsenA)
+                       clsenA = clsenB;
+
+               if (!clsenA) {
+                       /* { no loader has a corresponding entry } */
+                       CLASSCACHE_COUNT(stat_nontriv_constraints_none);
+
+                       /* create a new class entry with the constraint (a,b,en->name) */
+                       clsenA = NEW(classcache_class_entry);
+                       clsenA->classobj = NULL;
+                       clsenA->loaders = NULL;
+                       clsenA->constraints = classcache_new_loader_entry(b, NULL);
+                       clsenA->constraints = classcache_new_loader_entry(a, clsenA->constraints);
+
+                       clsenA->next = en->classes;
+                       en->classes = clsenA;
+               }
+               else {
+                       CLASSCACHE_COUNT(stat_nontriv_constraints_one);
+
+                       /* make b the loader that has no corresponding entry */
+                       if (clsenB)
+                               b = a;
+
+                       /* loader b must be added to entry clsenA */
+                       clsenA->constraints = classcache_new_loader_entry(b, clsenA->constraints);
+               }
+       }
+
+  return_success:
+       CLASSCACHE_UNLOCK();
+       return true;
+
+  return_exception:
+       CLASSCACHE_UNLOCK();
+       return false;                           /* exception */
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+/* classcache_add_constraints_for_params ***************************************
+   Add loading constraints for the parameters and return type of 
+   the given method.
+  
+   IN:
+       a................first initiating loader
+       b................second initiating loader
+       m................methodinfo 
+  
+   RETURN VALUE:
+       true.............everything ok, the constraints have been added,
+       false............an exception has been thrown.
+   
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool classcache_add_constraints_for_params(classloader_t * a,
+                                                                                  classloader_t * b,
+                                                                                  methodinfo *m)
+{
+       methoddesc *md;
+       typedesc *td;
+       s4 i;
+
+       /* a constraint with a == b is trivially satisfied */
+
+       if (a == b) {
+               return true;
+       }
+
+       /* get the parsed descriptor */
+
+       assert(m);
+       md = m->parseddesc;
+       assert(md);
+
+       /* constrain the return type */
+
+       if (md->returntype.type == TYPE_ADR) {
+               if (!classcache_add_constraint(a, b, md->returntype.classref->name))
+                       return false; /* exception */
+       }
+
+       /* constrain each reference type used in the parameters */
+
+       td = md->paramtypes;
+       i = md->paramcount;
+       for (; i--; td++) {
+               if (td->type != TYPE_ADR)
+                       continue;
+
+               if (!classcache_add_constraint(a, b, td->classref->name))
+                       return false; /* exception */
+       }
+
+       /* everything ok */
+       return true;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+
+/* classcache_number_of_loaded_classes *****************************************
+
+   Counts the number of loaded classes and returns it.
+
+   Note: This function assumes that the CLASSCACHE_LOCK is held by the
+   caller!
+
+*******************************************************************************/
+
+static s4 classcache_number_of_loaded_classes(void)
+{
+       classcache_name_entry  *en;
+       classcache_class_entry *clsen;
+       s4                      number;
+       s4                      i;
+
+       /* initialize class counter */
+
+       number = 0;
+
+       for (i = 0; i < hashtable_classcache.size; i++) {
+               /* iterate over hashlink */
+
+               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
+                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
+
+                       if (en->name->text[0] == '$')
+                               continue;
+
+                       /* iterate over classes with same name */
+
+                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
+                               /* get only loaded classes */
+
+                               if (clsen->classobj != NULL)
+                                       number++;
+                       }
+               }
+       }
+
+       return number;
+}
+
+
+/* classcache_get_loaded_class_count *******************************************
+
+   Counts the number of loaded classes and returns it.
+
+*******************************************************************************/
+
+s4 classcache_get_loaded_class_count(void)
+{
+       s4 count;
+
+       CLASSCACHE_LOCK();
+
+       count = classcache_number_of_loaded_classes();
+       
+       CLASSCACHE_UNLOCK();
+
+       return count;
+}
+
+
+/* classcache_get_loaded_classes ***********************************************
+
+   Returns an array of all loaded classes as array.  The array is
+   allocaed on the Java heap.
+
+*******************************************************************************/
+
+#if defined(ENABLE_JVMTI)
+void classcache_get_loaded_classes(s4 *class_count_ptr,
+                                                                  classinfo ***classes_ptr)
+{
+       classinfo              **classes;
+       s4                       class_count;
+       classcache_name_entry   *en;
+       classcache_class_entry  *clsen;
+       s4                       i;
+       s4                       j;
+
+       CLASSCACHE_LOCK();
+
+       /* get the number of loaded classes and allocate the array */
+
+       class_count = classcache_number_of_loaded_classes();
+
+       classes = GCMNEW(classinfo*, class_count);
+
+       /* look in every slot of the hashtable */
+
+       for (i = 0, j = 0; i < hashtable_classcache.size; i++) {
+               /* iterate over hashlink */
+
+               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
+                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
+
+                       if (en->name->text[0] == '$')
+                               continue;
+
+                       /* iterate over classes with same name */
+
+                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
+                               /* get only loaded classes */
+
+                               if (clsen->classobj != NULL) {
+                                       classes[j] = clsen->classobj;
+                                       j++;
+                               }
+                       }
+               }
+       }
+
+       /* pass the return values */
+
+       *class_count_ptr = class_count;
+       *classes_ptr     = classes;
+
+       CLASSCACHE_UNLOCK();
+}
+#endif /* defined(ENABLE_JVMTI) */
+
+
+/* classcache_foreach_loaded_class *********************************************
+
+   Calls the given function for each loaded class.
+
+*******************************************************************************/
+
+void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func,
+                                                                        void *data)
+{
+       classcache_name_entry   *en;
+       classcache_class_entry  *clsen;
+       s4                       i;
+
+       CLASSCACHE_LOCK();
+
+       /* look in every slot of the hashtable */
+
+       for (i = 0; i < hashtable_classcache.size; i++) {
+               /* iterate over hashlink */
+
+               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
+                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
+
+                       if (en->name->text[0] == '$')
+                               continue;
+
+                       /* iterate over classes with same name */
+
+                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
+                               /* get only loaded classes */
+
+                               if (clsen->classobj != NULL) {
+                                       (*func)(clsen->classobj, data);
+                               }
+                       }
+               }
+       }
+
+       CLASSCACHE_UNLOCK();
+}
+
+
+/*============================================================================*/
+/* DEBUG DUMPS                                                                */
+/*============================================================================*/
+
+/* classcache_debug_dump *******************************************************
+   Print the contents of the loaded class cache to a stream
+  
+   IN:
+       file.............output stream
+          only.............if != NULL, only print entries for this name
+                           (Currently we print also the rest of the hash chain to
+                                                get a feel for the average length of hash chains.)
+  
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+#ifndef NDEBUG
+void classcache_debug_dump(FILE * file,utf *only)
+{
+       classcache_name_entry *c;
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+       u4 slot;
+
+       CLASSCACHE_LOCK();
+
+       log_println("=== [loaded class cache] =====================================");
+       log_println("hash size   : %d", (int) hashtable_classcache.size);
+       log_println("hash entries: %d", (int) hashtable_classcache.entries);
+       log_println("");
+
+       if (only) {
+               c = classcache_lookup_name(only);
+               slot = 0; /* avoid compiler warning */
+               goto dump_it;
+       }
+
+       for (slot = 0; slot < hashtable_classcache.size; ++slot) {
+               c = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+
+dump_it:
+               for (; c; c = c->hashlink) {
+                       utf_fprint_printable_ascii_classname(file, c->name);
+                       fprintf(file, "\n");
+
+                       /* iterate over all class entries */
+                       for (clsen = c->classes; clsen; clsen = clsen->next) {
+                               if (clsen->classobj) {
+                                       log_println("    loaded %p", (void *) clsen->classobj);
+                               }
+                               else {
+                                       log_println("    unresolved");
+                               }
+
+                               log_start();
+                               log_print("        loaders: ");
+                               for (lden = clsen->loaders; lden; lden = lden->next) {
+                                       log_print("<%p> %p ", (void *) lden, (void *) lden->loader);
+                               }
+                               log_finish();
+
+                               log_start();
+                               log_print("        constraints: ");
+                               for (lden = clsen->constraints; lden; lden = lden->next) {
+                                       log_print("<%p> %p ", (void *) lden, (void *) lden->loader);
+                               }
+                               log_finish();
+                       }
+               }
+
+               if (only)
+                       break;
+       }
+       fprintf(file, "\n==============================================================\n\n");
+
+       CLASSCACHE_UNLOCK();
+}
+#endif /* 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/classcache.h b/src/vm/classcache.h
new file mode 100644 (file)
index 0000000..e8286e0
--- /dev/null
@@ -0,0 +1,181 @@
+/* src/vm/classcache.h - loaded class cache and loading constraints
+
+   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 _CLASSCACHE_H
+#define _CLASSCACHE_H
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vm/types.h"
+
+#include <stdio.h>  /* for FILE */
+
+#if defined(ENABLE_JVMTI)
+# include "native/jni.h"
+#endif
+
+#include "toolbox/hashtable.h"
+
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/references.h"
+
+
+/* forward declarations *******************************************************/
+
+typedef struct classcache_name_entry classcache_name_entry;
+typedef struct classcache_class_entry classcache_class_entry;
+typedef struct classcache_loader_entry classcache_loader_entry;
+
+/* global variables ***********************************************************/
+
+extern hashtable hashtable_classcache;
+
+
+/* structs ********************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* The Loaded Class Cache                                                     */
+/*                                                                            */
+/* The loaded class cache is implemented as a two-level data structure.       */
+/*                                                                            */
+/* The first level is a hash table indexed by class names. For each class     */
+/* name in the cache there is a classcache_name_entry, which collects all     */
+/* information about classes with this class name.                            */
+/*                                                                            */
+/* Second level: For each classcache_name_entry there is a list of            */
+/* classcache_class_entry:s representing the possible different resolutions   */
+/* of the class name.                                                         */
+/*                                                                            */
+/* A classcache_class_entry records the following:                            */
+/*                                                                            */
+/* - the loaded class object, if this entry has been resolved, otherwise NULL */
+/* - the list of initiating loaders which have resolved the class name to     */
+/*   this class object                                                        */
+/* - the list of initiating loaders which are constrained to resolve this     */
+/*   class name to this class object in the future                            */
+/*                                                                            */
+/* The classcache_class_entry:s approximate the equivalence classes created   */
+/* by the loading constraints and the equivalence of loaded classes.          */
+/*                                                                            */
+/* When a loading constraint (loaderA,loaderB,NAME) is added, then the        */
+/* classcache_class_entry:s for NAME containing loaderA and loaderB resp.     */
+/* must be merged into one entry. If this is impossible, because the entries  */
+/* have already been resolved to different class objects, then the constraint */
+/* is violated and an expception must be thrown.                              */
+/*----------------------------------------------------------------------------*/
+
+
+/* classcache_name_entry
+ *
+ * For each classname a classcache_name_entry struct is created.
+ */
+
+struct classcache_name_entry
+{
+       utf                     *name;        /* class name                       */
+       classcache_name_entry   *hashlink;    /* link for external chaining       */
+       classcache_class_entry  *classes;     /* equivalence classes for this name*/
+};
+
+struct classcache_class_entry
+{
+       classinfo               *classobj;    /* the loaded class object, or NULL */
+       classcache_loader_entry *loaders;
+       classcache_loader_entry *constraints;
+       classcache_class_entry  *next;        /* next class entry for same name   */
+};
+
+struct classcache_loader_entry
+{
+       classloader_t            *loader;     /* class loader object              */
+       classcache_loader_entry  *next;       /* next loader entry in the list    */
+};
+
+
+/* callback function type for  classcache_foreach_loaded_class */
+
+typedef void (*classcache_foreach_functionptr_t)(classinfo *, void *);
+
+
+/* function prototypes ********************************************************/
+
+/* initialize the loaded class cache */
+bool classcache_init(void);
+void classcache_free(void);
+
+classinfo * classcache_lookup(classloader_t *initloader,utf *classname);
+classinfo * classcache_lookup_defined(classloader_t *defloader,utf *classname);
+classinfo * classcache_lookup_defined_or_initiated(classloader_t *loader,utf *classname);
+
+bool classcache_store_unique(classinfo *cls);
+classinfo * classcache_store(classloader_t *initloader,classinfo *cls,bool mayfree);
+classinfo * classcache_store_defined(classinfo *cls);
+
+#if defined(ENABLE_VERIFIER)
+bool classcache_add_constraint(classloader_t *a,classloader_t *b,utf *classname);
+bool classcache_add_constraints_for_params(classloader_t *a,classloader_t *b,
+                                                                                  methodinfo *m);
+#endif
+
+s4 classcache_get_loaded_class_count(void);
+
+void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func,
+                                                                        void *data);
+
+#if defined(ENABLE_JVMTI)
+void classcache_get_loaded_classes(s4 *class_count_ptr,
+                                                                  classinfo ***classes_ptr);
+#endif
+
+#ifndef NDEBUG
+void classcache_debug_dump(FILE *file,utf *only);
+#endif
+       
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CLASSCACHE_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.c b/src/vm/descriptor.c
new file mode 100644 (file)
index 0000000..235154e
--- /dev/null
@@ -0,0 +1,1398 @@
+/* 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.h b/src/vm/descriptor.h
new file mode 100644 (file)
index 0000000..1f104a0
--- /dev/null
@@ -0,0 +1,200 @@
+/* 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.h"
+#include "vm/global.h"
+#include "vm/method.h"
+#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 ********************************************************/
+
+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) */
+
+#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/exceptions.c b/src/vm/exceptions.c
deleted file mode 100644 (file)
index d258329..0000000
+++ /dev/null
@@ -1,2105 +0,0 @@
-/* src/vm/exceptions.c - exception related 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 <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#include "vm/types.h"
-
-#include "md-abi.h"
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Thread.h"
-#include "native/include/java_lang_Throwable.h"
-
-#include "threads/lock-common.h"
-#include "threads/thread.h"
-
-#include "toolbox/util.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/methodheader.h"
-#include "vm/jit/patcher-common.h"
-#include "vm/jit/show.h"
-#include "vm/jit/stacktrace.h"
-#include "vm/jit/trace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/system.h"
-
-#if defined(ENABLE_VMLOG)
-#include <vmlog_cacao.h>
-#endif
-
-
-/* for raising exceptions from native methods *********************************/
-
-#if !defined(ENABLE_THREADS)
-java_object_t *_no_threads_exceptionptr = NULL;
-#endif
-
-
-/* exceptions_get_exception ****************************************************
-
-   Returns the current exception pointer of the current thread.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_get_exception(void)
-{
-       java_object_t *o;
-       java_handle_t *e;
-#if defined(ENABLE_THREADS)
-       threadobject  *t;
-
-       t = THREADOBJECT;
-#endif
-
-       /* Get the exception. */
-
-       LLNI_CRITICAL_START;
-
-#if defined(ENABLE_THREADS)
-       o = t->_exceptionptr;
-#else
-       o = _no_threads_exceptionptr;
-#endif
-
-       e = LLNI_WRAP(o);
-
-       LLNI_CRITICAL_END;
-
-       /* Return the exception. */
-
-       return e;
-}
-
-
-/* exceptions_set_exception ****************************************************
-
-   Sets the exception pointer of the current thread.
-
-*******************************************************************************/
-
-void exceptions_set_exception(java_handle_t *e)
-{
-       threadobject  *t;
-       java_object_t *o;
-
-#if defined(ENABLE_THREADS)
-       t = THREADOBJECT;
-#else
-       t = NULL;
-#endif
-
-       /* Set the exception. */
-
-       LLNI_CRITICAL_START;
-
-       o = LLNI_UNWRAP(e);
-
-#if !defined(NDEBUG)
-       if (opt_DebugExceptions) {
-               printf("[exceptions_set_exception  : t=%p, o=%p, class=",
-                          (void *) t, (void *) o);
-               class_print(o->vftbl->clazz);
-               printf("]\n");
-       }
-#endif
-
-#if defined(ENABLE_THREADS)
-       t->_exceptionptr = o;
-#else
-       _no_threads_exceptionptr = o;
-#endif
-
-       LLNI_CRITICAL_END;
-}
-
-
-/* exceptions_clear_exception **************************************************
-
-   Clears the current exception pointer of the current thread.
-
-*******************************************************************************/
-
-void exceptions_clear_exception(void)
-{
-       threadobject *t;
-
-#if defined(ENABLE_THREADS)
-       t = THREADOBJECT;
-#else
-       t = NULL;
-#endif
-
-       /* Set the exception. */
-
-#if !defined(NDEBUG)
-       if (opt_DebugExceptions) {
-               printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
-       }
-#endif
-
-#if defined(ENABLE_THREADS)
-       t->_exceptionptr = NULL;
-#else
-       _no_threads_exceptionptr = NULL;
-#endif
-}
-
-
-/* exceptions_get_and_clear_exception ******************************************
-
-   Gets the exception pointer of the current thread and clears it.
-   This function may return NULL.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_get_and_clear_exception(void)
-{
-       java_handle_t *o;
-
-       /* Get the exception... */
-
-       o = exceptions_get_exception();
-
-       /* ...and clear the exception if it is set. */
-
-       if (o != NULL)
-               exceptions_clear_exception();
-
-       /* return the exception */
-
-       return o;
-}
-
-
-/* exceptions_abort ************************************************************
-
-   Prints exception to be thrown and aborts.
-
-   IN:
-      classname....class name
-      message......exception message
-
-*******************************************************************************/
-
-static void exceptions_abort(utf *classname, utf *message)
-{
-       log_println("exception thrown while VM is initializing: ");
-
-       log_start();
-       utf_display_printable_ascii_classname(classname);
-
-       if (message != NULL) {
-               log_print(": ");
-               utf_display_printable_ascii_classname(message);
-       }
-
-       log_finish();
-
-       vm_abort("Aborting...");
-}
-
-
-/* exceptions_new_class_utf ****************************************************
-
-   Creates an exception object with the given class and initalizes it
-   with the given utf message.
-
-   IN:
-      c ......... exception class
-         message ... the message as an utf *
-
-   RETURN VALUE:
-     an exception pointer (in any case -- either it is the newly
-     created exception, or an exception thrown while trying to create
-     it).
-
-*******************************************************************************/
-
-static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
-{
-       java_handle_t *s;
-       java_handle_t *o;
-
-       if (vm_initializing) {
-               /* This can happen when global class variables are used which
-                  are not initialized yet. */
-
-               if (c == NULL)
-                       exceptions_abort(NULL, message);
-               else
-                       exceptions_abort(c->name, message);
-       }
-
-       s = javastring_new(message);
-
-       if (s == NULL)
-               return exceptions_get_exception();
-
-       o = native_new_and_init_string(c, s);
-
-       if (o == NULL)
-               return exceptions_get_exception();
-
-       return o;
-}
-
-
-/* exceptions_new_utf **********************************************************
-
-   Creates an exception object with the given name and initalizes it.
-
-   IN:
-      classname....class name in UTF-8
-
-*******************************************************************************/
-
-static java_handle_t *exceptions_new_utf(utf *classname)
-{
-       classinfo     *c;
-       java_handle_t *o;
-
-       if (vm_initializing)
-               exceptions_abort(classname, NULL);
-
-       c = load_class_bootstrap(classname);
-
-       if (c == NULL)
-               return exceptions_get_exception();
-
-       o = native_new_and_init(c);
-
-       if (o == NULL)
-               return exceptions_get_exception();
-
-       return o;
-}
-
-
-/* exceptions_new_utf_javastring ***********************************************
-
-   Creates an exception object with the given name and initalizes it
-   with the given java/lang/String message.
-
-   IN:
-      classname....class name in UTF-8
-         message......the message as a java.lang.String
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
-
-*******************************************************************************/
-
-static java_handle_t *exceptions_new_utf_javastring(utf *classname,
-                                                                                                       java_handle_t *message)
-{
-       java_handle_t *o;
-       classinfo     *c;
-   
-       if (vm_initializing)
-               exceptions_abort(classname, NULL);
-
-       c = load_class_bootstrap(classname);
-
-       if (c == NULL)
-               return exceptions_get_exception();
-
-       o = native_new_and_init_string(c, message);
-
-       if (o == NULL)
-               return exceptions_get_exception();
-
-       return o;
-}
-
-
-/* exceptions_new_utf_utf ******************************************************
-
-   Creates an exception object with the given name and initalizes it
-   with the given utf message.
-
-   IN:
-      classname....class name in UTF-8
-         message......the message as an utf *
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
-
-*******************************************************************************/
-
-static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
-{
-       classinfo     *c;
-       java_handle_t *o;
-
-       if (vm_initializing)
-               exceptions_abort(classname, message);
-
-       c = load_class_bootstrap(classname);
-
-       if (c == NULL)
-               return exceptions_get_exception();
-
-       o = exceptions_new_class_utf(c, message);
-
-       return o;
-}
-
-
-/* exceptions_throw_class_utf **************************************************
-
-   Creates an exception object with the given class, initalizes and
-   throws it with the given utf message.
-
-   IN:
-      c ......... exception class
-         message ... the message as an utf *
-
-*******************************************************************************/
-
-static void exceptions_throw_class_utf(classinfo *c, utf *message)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_class_utf(c, message);
-
-       exceptions_set_exception(o);
-}
-
-
-/* exceptions_throw_utf ********************************************************
-
-   Creates an exception object with the given name, initalizes and
-   throws it.
-
-   IN:
-      classname....class name in UTF-8
-
-*******************************************************************************/
-
-static void exceptions_throw_utf(utf *classname)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_utf(classname);
-
-       if (o == NULL)
-               return;
-
-       exceptions_set_exception(o);
-}
-
-
-/* exceptions_throw_utf_throwable **********************************************
-
-   Creates an exception object with the given name and initalizes it
-   with the given java/lang/Throwable exception.
-
-   IN:
-      classname....class name in UTF-8
-         cause........the given Throwable
-
-*******************************************************************************/
-
-static void exceptions_throw_utf_throwable(utf *classname,
-                                                                                  java_handle_t *cause)
-{
-       classinfo           *c;
-       java_handle_t       *o;
-       methodinfo          *m;
-       java_lang_Throwable *object;
-
-       if (vm_initializing)
-               exceptions_abort(classname, NULL);
-
-       object = (java_lang_Throwable *) cause;
-
-       c = load_class_bootstrap(classname);
-
-       if (c == NULL)
-               return;
-
-       /* create object */
-
-       o = builtin_new(c);
-       
-       if (o == NULL)
-               return;
-
-       /* call initializer */
-
-       m = class_resolveclassmethod(c,
-                                                                utf_init,
-                                                                utf_java_lang_Throwable__void,
-                                                                NULL,
-                                                                true);
-                                                     
-       if (m == NULL)
-               return;
-
-       (void) vm_call_method(m, o, cause);
-
-       exceptions_set_exception(o);
-}
-
-
-/* exceptions_throw_utf_exception **********************************************
-
-   Creates an exception object with the given name and initalizes it
-   with the given java/lang/Exception exception.
-
-   IN:
-      classname....class name in UTF-8
-         exception....the given Exception
-
-*******************************************************************************/
-
-static void exceptions_throw_utf_exception(utf *classname,
-                                                                                  java_handle_t *exception)
-{
-       classinfo     *c;
-       java_handle_t *o;
-       methodinfo    *m;
-
-       if (vm_initializing)
-               exceptions_abort(classname, NULL);
-
-       c = load_class_bootstrap(classname);
-
-       if (c == NULL)
-               return;
-
-       /* create object */
-
-       o = builtin_new(c);
-       
-       if (o == NULL)
-               return;
-
-       /* call initializer */
-
-       m = class_resolveclassmethod(c,
-                                                                utf_init,
-                                                                utf_java_lang_Exception__V,
-                                                                NULL,
-                                                                true);
-                                                     
-       if (m == NULL)
-               return;
-
-       (void) vm_call_method(m, o, exception);
-
-       exceptions_set_exception(o);
-}
-
-
-/* exceptions_throw_utf_cause **************************************************
-
-   Creates an exception object with the given name and initalizes it
-   with the given java/lang/Throwable exception with initCause.
-
-   IN:
-      classname....class name in UTF-8
-         cause........the given Throwable
-
-*******************************************************************************/
-
-static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
-{
-       classinfo           *c;
-       java_handle_t       *o;
-       methodinfo          *m;
-       java_lang_String    *s;
-       java_lang_Throwable *object;
-
-       if (vm_initializing)
-               exceptions_abort(classname, NULL);
-
-       object = (java_lang_Throwable *) cause;
-
-       c = load_class_bootstrap(classname);
-
-       if (c == NULL)
-               return;
-
-       /* create object */
-
-       o = builtin_new(c);
-       
-       if (o == NULL)
-               return;
-
-       /* call initializer */
-
-       m = class_resolveclassmethod(c,
-                                                                utf_init,
-                                                                utf_java_lang_String__void,
-                                                                NULL,
-                                                                true);
-                                                     
-       if (m == NULL)
-               return;
-
-       LLNI_field_get_ref(object, detailMessage, s);
-
-       (void) vm_call_method(m, o, s);
-
-       /* call initCause */
-
-       m = class_resolveclassmethod(c,
-                                                                utf_initCause,
-                                                                utf_java_lang_Throwable__java_lang_Throwable,
-                                                                NULL,
-                                                                true);
-
-       if (m == NULL)
-               return;
-
-       (void) vm_call_method(m, o, cause);
-
-       exceptions_set_exception(o);
-}
-
-
-/* exceptions_throw_utf_utf ****************************************************
-
-   Creates an exception object with the given name, initalizes and
-   throws it with the given utf message.
-
-   IN:
-      classname....class name in UTF-8
-         message......the message as an utf *
-
-*******************************************************************************/
-
-static void exceptions_throw_utf_utf(utf *classname, utf *message)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_utf_utf(classname, message);
-
-       exceptions_set_exception(o);
-}
-
-
-/* exceptions_new_abstractmethoderror ****************************************
-
-   Generates a java.lang.AbstractMethodError for the VM.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_new_abstractmethoderror(void)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
-
-       return o;
-}
-
-
-/* exceptions_new_error ********************************************************
-
-   Generates a java.lang.Error for the VM.
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVAME_CLDC1_1)
-static java_handle_t *exceptions_new_error(utf *message)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_utf_utf(utf_java_lang_Error, message);
-
-       return o;
-}
-#endif
-
-
-/* exceptions_asm_new_abstractmethoderror **************************************
-
-   Generates a java.lang.AbstractMethodError for
-   asm_abstractmethoderror.
-
-*******************************************************************************/
-
-java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
-{
-       stackframeinfo_t  sfi;
-       java_handle_t    *e;
-       java_object_t    *o;
-
-       /* Fill and add a stackframeinfo (XPC is equal to RA). */
-
-       stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
-
-       /* create the exception */
-
-#if defined(ENABLE_JAVASE)
-       e = exceptions_new_abstractmethoderror();
-#else
-       e = exceptions_new_error(utf_java_lang_AbstractMethodError);
-#endif
-
-       /* Remove the stackframeinfo. */
-
-       stacktrace_stackframeinfo_remove(&sfi);
-
-       /* unwrap the exception */
-       /* ATTENTION: do the this _after_ the stackframeinfo was removed */
-
-       o = LLNI_UNWRAP(e);
-
-       return o;
-}
-
-
-/* exceptions_new_arraystoreexception ******************************************
-
-   Generates a java.lang.ArrayStoreException for the VM.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_new_arraystoreexception(void)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
-
-       return o;
-}
-
-
-/* exceptions_throw_abstractmethoderror ****************************************
-
-   Generates and throws a java.lang.AbstractMethodError for the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_abstractmethoderror(void)
-{
-       exceptions_throw_utf(utf_java_lang_AbstractMethodError);
-}
-
-
-/* exceptions_throw_classcircularityerror **************************************
-
-   Generates and throws a java.lang.ClassCircularityError for the
-   classloader.
-
-   IN:
-      c....the class in which the error was found
-
-*******************************************************************************/
-
-void exceptions_throw_classcircularityerror(classinfo *c)
-{
-       exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
-}
-
-
-/* exceptions_throw_classformaterror *******************************************
-
-   Generates and throws a java.lang.ClassFormatError for the VM.
-
-   IN:
-      c............the class in which the error was found
-         message......UTF-8 format string
-
-*******************************************************************************/
-
-void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
-{
-       char    *msg;
-       s4       msglen;
-       va_list  ap;
-       utf     *u;
-
-       /* calculate message length */
-
-       msglen = 0;
-
-       if (c != NULL)
-               msglen += utf_bytes(c->name) + strlen(" (");
-
-       va_start(ap, message);
-       msglen += get_variable_message_length(message, ap);
-       va_end(ap);
-
-       if (c != NULL)
-               msglen += strlen(")");
-
-       msglen += strlen("0");
-
-       /* allocate a buffer */
-
-       msg = MNEW(char, msglen);
-
-       /* print message into allocated buffer */
-
-       if (c != NULL) {
-               utf_copy_classname(msg, c->name);
-               strcat(msg, " (");
-       }
-
-       va_start(ap, message);
-       vsprintf(msg + strlen(msg), message, ap);
-       va_end(ap);
-
-       if (c != NULL)
-               strcat(msg, ")");
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, msglen);
-
-       /* throw exception */
-
-       exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
-}
-
-
-/* exceptions_throw_classnotfoundexception *************************************
-
-   Generates and throws a java.lang.ClassNotFoundException for the
-   VM.
-
-   IN:
-      name.........name of the class not found as a utf *
-
-*******************************************************************************/
-
-void exceptions_throw_classnotfoundexception(utf *name)
-{      
-       exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
-}
-
-
-/* exceptions_throw_noclassdeffounderror ***************************************
-
-   Generates and throws a java.lang.NoClassDefFoundError.
-
-   IN:
-      name.........name of the class not found as a utf *
-
-*******************************************************************************/
-
-void exceptions_throw_noclassdeffounderror(utf *name)
-{
-       exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
-}
-
-
-/* exceptions_throw_noclassdeffounderror_cause *********************************
-
-   Generates and throws a java.lang.NoClassDefFoundError with the
-   given cause.
-
-*******************************************************************************/
-
-void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
-{
-       exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
-}
-
-
-/* exceptions_throw_noclassdeffounderror_wrong_name ****************************
-
-   Generates and throws a java.lang.NoClassDefFoundError with a
-   specific message:
-
-   IN:
-      name.........name of the class not found as a utf *
-
-*******************************************************************************/
-
-void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
-{
-       char *msg;
-       s4    msglen;
-       utf  *u;
-
-       msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
-               utf_bytes(name) + strlen(")") + strlen("0");
-
-       msg = MNEW(char, msglen);
-
-       utf_copy_classname(msg, c->name);
-       strcat(msg, " (wrong name: ");
-       utf_cat_classname(msg, name);
-       strcat(msg, ")");
-
-       u = utf_new_char(msg);
-
-       MFREE(msg, char, msglen);
-
-       exceptions_throw_noclassdeffounderror(u);
-}
-
-
-/* exceptions_throw_exceptionininitializererror ********************************
-
-   Generates and throws a java.lang.ExceptionInInitializerError for
-   the VM.
-
-   IN:
-      cause......cause exception object
-
-*******************************************************************************/
-
-void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
-{
-       exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
-                                                                  cause);
-}
-
-
-/* exceptions_throw_incompatibleclasschangeerror *******************************
-
-   Generates and throws a java.lang.IncompatibleClassChangeError for
-   the VM.
-
-   IN:
-      message......UTF-8 message format string
-
-*******************************************************************************/
-
-void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
-{
-       char *msg;
-       s4    msglen;
-       utf  *u;
-
-       /* calculate exception message length */
-
-       msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
-
-       /* allocate memory */
-
-       msg = MNEW(char, msglen);
-
-       utf_copy_classname(msg, c->name);
-       strcat(msg, message);
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, msglen);
-
-       /* throw exception */
-
-       exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
-}
-
-
-/* exceptions_throw_instantiationerror *****************************************
-
-   Generates and throws a java.lang.InstantiationError for the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_instantiationerror(classinfo *c)
-{
-       exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
-}
-
-
-/* exceptions_throw_internalerror **********************************************
-
-   Generates and throws a java.lang.InternalError for the VM.
-
-   IN:
-      message......UTF-8 message format string
-
-*******************************************************************************/
-
-void exceptions_throw_internalerror(const char *message, ...)
-{
-       va_list  ap;
-       char    *msg;
-       s4       msglen;
-       utf     *u;
-
-       /* calculate exception message length */
-
-       va_start(ap, message);
-       msglen = get_variable_message_length(message, ap);
-       va_end(ap);
-
-       /* allocate memory */
-
-       msg = MNEW(char, msglen);
-
-       /* generate message */
-
-       va_start(ap, message);
-       vsprintf(msg, message, ap);
-       va_end(ap);
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, msglen);
-
-       /* throw exception */
-
-       exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
-}
-
-
-/* exceptions_throw_linkageerror ***********************************************
-
-   Generates and throws java.lang.LinkageError with an error message.
-
-   IN:
-      message......UTF-8 message
-         c............class related to the error. If this is != NULL
-                      the name of c is appended to the error message.
-
-*******************************************************************************/
-
-void exceptions_throw_linkageerror(const char *message, classinfo *c)
-{
-       utf  *u;
-       char *msg;
-       int   len;
-
-       /* calculate exception message length */
-
-       len = strlen(message) + 1;
-
-       if (c != NULL)
-               len += utf_bytes(c->name);
-               
-       /* allocate memory */
-
-       msg = MNEW(char, len);
-
-       /* generate message */
-
-       strcpy(msg, message);
-
-       if (c != NULL)
-               utf_cat_classname(msg, c->name);
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, len);
-
-       exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
-}
-
-
-/* exceptions_throw_nosuchfielderror *******************************************
-
-   Generates and throws a java.lang.NoSuchFieldError with an error
-   message.
-
-   IN:
-      c............class in which the field was not found
-         name.........name of the field
-
-*******************************************************************************/
-
-void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
-{
-       char *msg;
-       s4    msglen;
-       utf  *u;
-
-       /* calculate exception message length */
-
-       msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
-
-       /* allocate memory */
-
-       msg = MNEW(char, msglen);
-
-       /* generate message */
-
-       utf_copy_classname(msg, c->name);
-       strcat(msg, ".");
-       utf_cat(msg, name);
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, msglen);
-
-       exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
-}
-
-
-/* exceptions_throw_nosuchmethoderror ******************************************
-
-   Generates and throws a java.lang.NoSuchMethodError with an error
-   message.
-
-   IN:
-      c............class in which the method was not found
-         name.........name of the method
-         desc.........descriptor of the method
-
-*******************************************************************************/
-
-void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
-{
-       char *msg;
-       s4    msglen;
-       utf  *u;
-
-       /* calculate exception message length */
-
-       msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
-               utf_bytes(desc) + strlen("0");
-
-       /* allocate memory */
-
-       msg = MNEW(char, msglen);
-
-       /* generate message */
-
-       utf_copy_classname(msg, c->name);
-       strcat(msg, ".");
-       utf_cat(msg, name);
-       utf_cat(msg, desc);
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, msglen);
-
-#if defined(ENABLE_JAVASE)
-       exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
-#else
-       exceptions_throw_utf_utf(utf_java_lang_Error, u);
-#endif
-}
-
-
-/* exceptions_throw_outofmemoryerror *******************************************
-
-   Generates and throws an java.lang.OutOfMemoryError for the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_outofmemoryerror(void)
-{
-       exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
-}
-
-
-/* exceptions_throw_unsatisfiedlinkerror ***************************************
-
-   Generates and throws a java.lang.UnsatisfiedLinkError for the
-   classloader.
-
-   IN:
-         name......UTF-8 name string
-
-*******************************************************************************/
-
-void exceptions_throw_unsatisfiedlinkerror(utf *name)
-{
-#if defined(ENABLE_JAVASE)
-       exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
-#else
-       exceptions_throw_utf_utf(utf_java_lang_Error, name);
-#endif
-}
-
-
-/* exceptions_throw_unsupportedclassversionerror *******************************
-
-   Generates and throws a java.lang.UnsupportedClassVersionError for
-   the classloader.
-
-   IN:
-      c............class in which the method was not found
-         message......UTF-8 format string
-
-*******************************************************************************/
-
-void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
-{
-       char *msg;
-    s4    msglen;
-       utf  *u;
-
-       /* calculate exception message length */
-
-       msglen =
-               utf_bytes(c->name) +
-               strlen(" (Unsupported major.minor version 00.0)") +
-               strlen("0");
-
-       /* allocate memory */
-
-       msg = MNEW(char, msglen);
-
-       /* generate message */
-
-       utf_copy_classname(msg, c->name);
-       sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
-                       ma, mi);
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, msglen);
-
-       /* throw exception */
-
-       exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
-}
-
-
-/* exceptions_throw_verifyerror ************************************************
-
-   Generates and throws a java.lang.VerifyError for the JIT compiler.
-
-   IN:
-      m............method in which the error was found
-         message......UTF-8 format string
-
-*******************************************************************************/
-
-void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
-{
-       va_list  ap;
-       char    *msg;
-       s4       msglen;
-       utf     *u;
-
-       /* calculate exception message length */
-
-       msglen = 0;
-
-       if (m != NULL)
-               msglen =
-                       strlen("(class: ") + utf_bytes(m->clazz->name) +
-                       strlen(", method: ") + utf_bytes(m->name) +
-                       strlen(" signature: ") + utf_bytes(m->descriptor) +
-                       strlen(") ") + strlen("0");
-
-       va_start(ap, message);
-       msglen += get_variable_message_length(message, ap);
-       va_end(ap);
-
-       /* allocate memory */
-
-       msg = MNEW(char, msglen);
-
-       /* generate message */
-
-       if (m != NULL) {
-               strcpy(msg, "(class: ");
-               utf_cat_classname(msg, m->clazz->name);
-               strcat(msg, ", method: ");
-               utf_cat(msg, m->name);
-               strcat(msg, " signature: ");
-               utf_cat(msg, m->descriptor);
-               strcat(msg, ") ");
-       }
-
-       va_start(ap, message);
-       vsprintf(msg + strlen(msg), message, ap);
-       va_end(ap);
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, msglen);
-
-       /* throw exception */
-
-       exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
-}
-
-
-/* exceptions_throw_verifyerror_for_stack **************************************
-
-   throws a java.lang.VerifyError for an invalid stack slot type
-
-   IN:
-      m............method in which the error was found
-         type.........the expected type
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
-
-*******************************************************************************/
-
-void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
-{
-       char *msg;
-       s4    msglen;
-       char *typename;
-       utf  *u;
-
-       /* calculate exception message length */
-
-       msglen = 0;
-
-       if (m != NULL)
-               msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
-                       strlen(", method: ") + utf_bytes(m->name) +
-                       strlen(" signature: ") + utf_bytes(m->descriptor) +
-                       strlen(") Expecting to find longest-------typename on stack") 
-                       + strlen("0");
-
-       /* allocate memory */
-
-       msg = MNEW(char, msglen);
-
-       /* generate message */
-
-       if (m != NULL) {
-               strcpy(msg, "(class: ");
-               utf_cat_classname(msg, m->clazz->name);
-               strcat(msg, ", method: ");
-               utf_cat(msg, m->name);
-               strcat(msg, " signature: ");
-               utf_cat(msg, m->descriptor);
-               strcat(msg, ") ");
-       }
-       else {
-               msg[0] = 0;
-       }
-
-       strcat(msg, "Expecting to find ");
-
-       switch (type) {
-               case TYPE_INT: typename = "integer"; break;
-               case TYPE_LNG: typename = "long"; break;
-               case TYPE_FLT: typename = "float"; break;
-               case TYPE_DBL: typename = "double"; break;
-               case TYPE_ADR: typename = "object/array"; break;
-               case TYPE_RET: typename = "returnAddress"; break;
-               default:       typename = "<INVALID>"; assert(0); break;
-       }
-
-       strcat(msg, typename);
-       strcat(msg, " on stack");
-
-       u = utf_new_char(msg);
-
-       /* free memory */
-
-       MFREE(msg, char, msglen);
-
-       /* throw exception */
-
-       exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
-}
-
-
-/* exceptions_new_arithmeticexception ******************************************
-
-   Generates a java.lang.ArithmeticException for the JIT compiler.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_new_arithmeticexception(void)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
-                                                          utf_division_by_zero);
-
-       return o;
-}
-
-
-/* exceptions_new_arrayindexoutofboundsexception *******************************
-
-   Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
-   system.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
-{
-       java_handle_t *o;
-       methodinfo    *m;
-       java_handle_t *s;
-
-       /* convert the index into a String, like Sun does */
-
-       m = class_resolveclassmethod(class_java_lang_String,
-                                                                utf_new_char("valueOf"),
-                                                                utf_new_char("(I)Ljava/lang/String;"),
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (m == NULL)
-               return exceptions_get_exception();
-
-       s = vm_call_method(m, NULL, index);
-
-       if (s == NULL)
-               return exceptions_get_exception();
-
-       o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
-                                                                         s);
-
-       if (o == NULL)
-               return exceptions_get_exception();
-
-       return o;
-}
-
-
-/* exceptions_throw_arrayindexoutofboundsexception *****************************
-
-   Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
-   the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_arrayindexoutofboundsexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
-}
-
-
-/* exceptions_throw_arraystoreexception ****************************************
-
-   Generates and throws a java.lang.ArrayStoreException for the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_arraystoreexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_ArrayStoreException);
-}
-
-
-/* exceptions_new_classcastexception *******************************************
-
-   Generates a java.lang.ClassCastException for the JIT compiler.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
-{
-       java_handle_t *e;
-       classinfo     *c;
-       utf           *classname;
-
-       LLNI_class_get(o, c);
-
-       classname = c->name;
-
-       e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
-
-       return e;
-}
-
-
-/* exceptions_throw_clonenotsupportedexception *********************************
-
-   Generates and throws a java.lang.CloneNotSupportedException for the
-   VM.
-
-*******************************************************************************/
-
-void exceptions_throw_clonenotsupportedexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
-}
-
-
-/* exceptions_throw_illegalaccessexception *************************************
-
-   Generates and throws a java.lang.IllegalAccessException for the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_illegalaccessexception(utf *message)
-{
-       exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
-}
-
-
-/* exceptions_throw_illegalargumentexception ***********************************
-
-   Generates and throws a java.lang.IllegalArgumentException for the
-   VM.
-
-*******************************************************************************/
-
-void exceptions_throw_illegalargumentexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
-}
-
-
-/* exceptions_throw_illegalmonitorstateexception *******************************
-
-   Generates and throws a java.lang.IllegalMonitorStateException for
-   the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_illegalmonitorstateexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
-}
-
-
-/* exceptions_throw_instantiationexception *************************************
-
-   Generates and throws a java.lang.InstantiationException for the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_instantiationexception(classinfo *c)
-{
-       exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
-}
-
-
-/* exceptions_throw_interruptedexception ***************************************
-
-   Generates and throws a java.lang.InterruptedException for the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_interruptedexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_InterruptedException);
-}
-
-
-/* exceptions_throw_invocationtargetexception **********************************
-
-   Generates and throws a java.lang.reflect.InvocationTargetException
-   for the VM.
-
-   IN:
-      cause......cause exception object
-
-*******************************************************************************/
-
-void exceptions_throw_invocationtargetexception(java_handle_t *cause)
-{
-       exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
-                                                                  cause);
-}
-
-
-/* exceptions_throw_negativearraysizeexception *********************************
-
-   Generates and throws a java.lang.NegativeArraySizeException for the
-   VM.
-
-*******************************************************************************/
-
-void exceptions_throw_negativearraysizeexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
-}
-
-
-/* exceptions_new_nullpointerexception *****************************************
-
-   Generates a java.lang.NullPointerException for the VM system.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_new_nullpointerexception(void)
-{
-       java_handle_t *o;
-
-       o = exceptions_new_utf(utf_java_lang_NullPointerException);
-
-       return o;
-}
-
-
-/* exceptions_throw_nullpointerexception ***************************************
-
-   Generates a java.lang.NullPointerException for the VM system and
-   throw it in the VM system.
-
-*******************************************************************************/
-
-void exceptions_throw_nullpointerexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_NullPointerException);
-}
-
-
-/* exceptions_throw_privilegedactionexception **********************************
-
-   Generates and throws a java.security.PrivilegedActionException.
-
-*******************************************************************************/
-
-void exceptions_throw_privilegedactionexception(java_handle_t *exception)
-{
-       exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
-                                                                  exception);
-}
-
-
-/* exceptions_throw_stringindexoutofboundsexception ****************************
-
-   Generates and throws a java.lang.StringIndexOutOfBoundsException
-   for the VM.
-
-*******************************************************************************/
-
-void exceptions_throw_stringindexoutofboundsexception(void)
-{
-       exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
-}
-
-
-/* exceptions_fillinstacktrace *************************************************
-
-   Calls the fillInStackTrace-method of the currently thrown
-   exception.
-
-*******************************************************************************/
-
-java_handle_t *exceptions_fillinstacktrace(void)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-
-       /* get exception */
-
-       o = exceptions_get_and_clear_exception();
-
-       assert(o);
-
-       /* resolve methodinfo pointer from exception object */
-
-       LLNI_class_get(o, c);
-
-#if defined(ENABLE_JAVASE)
-       m = class_resolvemethod(c,
-                                                       utf_fillInStackTrace,
-                                                       utf_void__java_lang_Throwable);
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-       m = class_resolvemethod(c,
-                                                       utf_fillInStackTrace,
-                                                       utf_void__void);
-#else
-#error IMPLEMENT ME!
-#endif
-
-       /* call function */
-
-       (void) vm_call_method(m, o);
-
-       /* return exception object */
-
-       return o;
-}
-
-
-/* exceptions_handle_exception *************************************************
-
-   Try to find an exception handler for the given exception and return it.
-   If no handler is found, exit the monitor of the method (if any)
-   and return NULL.
-
-   IN:
-      xptr.........the exception object
-         xpc..........PC of where the exception was thrown
-         pv...........Procedure Value of the current method
-         sp...........current stack pointer
-
-   RETURN VALUE:
-      the address of the first matching exception handler, or
-         NULL if no handler was found
-
-*******************************************************************************/
-
-#if defined(ENABLE_JIT)
-void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
-{
-       stackframeinfo_t        sfi;
-       java_handle_t          *xptr;
-       methodinfo             *m;
-       codeinfo               *code;
-       exceptiontable_t       *et;
-       exceptiontable_entry_t *ete;
-       s4                      i;
-       classref_or_classinfo   cr;
-       classinfo              *c;
-#if defined(ENABLE_THREADS)
-       java_object_t          *o;
-#endif
-       void                   *result;
-
-#ifdef __S390__
-       /* Addresses are 31 bit integers */
-#      define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
-#else
-#      define ADDR_MASK(x) (x)
-#endif
-
-       xptr = LLNI_WRAP(xptro);
-       xpc  = ADDR_MASK(xpc);
-
-       /* Fill and add a stackframeinfo (XPC is equal to RA). */
-
-       stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
-
-       result = NULL;
-
-       /* Get the codeinfo for the current method. */
-
-       code = code_get_codeinfo_for_pv(pv);
-
-       /* Get the methodinfo pointer from the codeinfo pointer. For
-          asm_vm_call_method the codeinfo pointer is NULL and we simply
-          can return the proper exception handler. */
-
-       if (code == NULL) {
-               result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
-               goto exceptions_handle_exception_return;
-       }
-
-       m = code->m;
-
-#if !defined(NDEBUG)
-       /* print exception trace */
-
-       if (opt_TraceExceptions)
-               trace_exception(LLNI_DIRECT(xptr), m, xpc);
-
-# if defined(ENABLE_VMLOG)
-       vmlog_cacao_throw(xptr);
-# endif
-#endif
-
-       /* Get the exception table. */
-
-       et = code->exceptiontable;
-
-       if (et != NULL) {
-       /* Iterate over all exception table entries. */
-
-       ete = et->entries;
-
-       for (i = 0; i < et->length; i++, ete++) {
-               /* is the xpc is the current catch range */
-
-               if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
-                       cr = ete->catchtype;
-
-                       /* NULL catches everything */
-
-                       if (cr.any == NULL) {
-#if !defined(NDEBUG)
-                               /* Print stacktrace of exception when caught. */
-
-# if defined(ENABLE_VMLOG)
-                               vmlog_cacao_catch(xptr);
-# endif
-
-                               if (opt_TraceExceptions) {
-                                       exceptions_print_exception(xptr);
-                                       stacktrace_print_exception(xptr);
-                               }
-#endif
-
-                               result = ete->handlerpc;
-                               goto exceptions_handle_exception_return;
-                       }
-
-                       /* resolve or load/link the exception class */
-
-                       if (IS_CLASSREF(cr)) {
-                               /* The exception class reference is unresolved. */
-                               /* We have to do _eager_ resolving here. While the
-                                  class of the exception object is guaranteed to be
-                                  loaded, it may well have been loaded by a different
-                                  loader than the defining loader of m's class, which
-                                  is the one we must use to resolve the catch
-                                  class. Thus lazy resolving might fail, even if the
-                                  result of the resolution would be an already loaded
-                                  class. */
-
-                               c = resolve_classref_eager(cr.ref);
-
-                               if (c == NULL) {
-                                       /* Exception resolving the exception class, argh! */
-                                       goto exceptions_handle_exception_return;
-                               }
-
-                               /* Ok, we resolved it. Enter it in the table, so we
-                                  don't have to do this again. */
-                               /* XXX this write should be atomic. Is it? */
-
-                               ete->catchtype.cls = c;
-                       }
-                       else {
-                               c = cr.cls;
-
-                               /* XXX I don't think this case can ever happen. -Edwin */
-                               if (!(c->state & CLASS_LOADED))
-                                       /* use the methods' classloader */
-                                       if (!load_class_from_classloader(c->name,
-                                                                                                        m->clazz->classloader))
-                                               goto exceptions_handle_exception_return;
-
-                               /* XXX I think, if it is not linked, we can be sure
-                                  that the exception object is no (indirect) instance
-                                  of it, no?  -Edwin  */
-                               if (!(c->state & CLASS_LINKED))
-                                       if (!link_class(c))
-                                               goto exceptions_handle_exception_return;
-                       }
-
-                       /* is the thrown exception an instance of the catch class? */
-
-                       if (builtin_instanceof(xptr, c)) {
-#if !defined(NDEBUG)
-                               /* Print stacktrace of exception when caught. */
-
-# if defined(ENABLE_VMLOG)
-                               vmlog_cacao_catch(xptr);
-# endif
-
-                               if (opt_TraceExceptions) {
-                                       exceptions_print_exception(xptr);
-                                       stacktrace_print_exception(xptr);
-                               }
-#endif
-
-                               result = ete->handlerpc;
-                               goto exceptions_handle_exception_return;
-                       }
-               }
-       }
-       }
-
-#if defined(ENABLE_THREADS)
-       /* Is this method realization synchronized? */
-
-       if (code_is_synchronized(code)) {
-               /* Get synchronization object. */
-
-               o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
-
-               assert(o != NULL);
-
-               lock_monitor_exit(LLNI_QUICKWRAP(o));
-       }
-#endif
-
-       /* none of the exceptions catch this one */
-
-#if !defined(NDEBUG)
-# if defined(ENABLE_VMLOG)
-       vmlog_cacao_unwnd_method(m);
-# endif
-
-# if defined(ENABLE_DEBUG_FILTER)
-       if (show_filters_test_verbosecall_exit(m)) {
-# endif
-
-       /* outdent the log message */
-
-       if (opt_verbosecall) {
-               if (TRACEJAVACALLINDENT)
-                       TRACEJAVACALLINDENT--;
-               else
-                       log_text("exceptions_handle_exception: WARNING: unmatched unindent");
-       }
-
-# if defined(ENABLE_DEBUG_FILTER)
-       }
-# endif
-#endif /* !defined(NDEBUG) */
-
-       result = NULL;
-
-exceptions_handle_exception_return:
-
-       /* Remove the stackframeinfo. */
-
-       stacktrace_stackframeinfo_remove(&sfi);
-
-       return result;
-}
-#endif /* defined(ENABLE_JIT) */
-
-
-/* exceptions_print_exception **************************************************
-
-   Prints an exception, the detail message and the cause, if
-   available, with CACAO internal functions to stdout.
-
-*******************************************************************************/
-
-void exceptions_print_exception(java_handle_t *xptr)
-{
-       java_lang_Throwable   *t;
-#if defined(ENABLE_JAVASE)
-       java_lang_Throwable   *cause;
-#endif
-       java_lang_String      *s;
-       classinfo             *c;
-       utf                   *u;
-
-       t = (java_lang_Throwable *) xptr;
-
-       if (t == NULL) {
-               puts("NULL\n");
-               return;
-       }
-
-#if defined(ENABLE_JAVASE)
-       LLNI_field_get_ref(t, cause, cause);
-#endif
-
-       /* print the root exception */
-
-       LLNI_class_get(t, c);
-       utf_display_printable_ascii_classname(c->name);
-
-       LLNI_field_get_ref(t, detailMessage, s);
-
-       if (s != NULL) {
-               u = javastring_toutf((java_handle_t *) s, false);
-
-               printf(": ");
-               utf_display_printable_ascii(u);
-       }
-
-       putc('\n', stdout);
-
-#if defined(ENABLE_JAVASE)
-       /* print the cause if available */
-
-       if ((cause != NULL) && (cause != t)) {
-               printf("Caused by: ");
-               
-               LLNI_class_get(cause, c);
-               utf_display_printable_ascii_classname(c->name);
-
-               LLNI_field_get_ref(cause, detailMessage, s);
-
-               if (s != NULL) {
-                       u = javastring_toutf((java_handle_t *) s, false);
-
-                       printf(": ");
-                       utf_display_printable_ascii(u);
-               }
-
-               putc('\n', stdout);
-       }
-#endif
-}
-
-
-/* exceptions_print_current_exception ******************************************
-
-   Prints the current pending exception, the detail message and the
-   cause, if available, with CACAO internal functions to stdout.
-
-*******************************************************************************/
-
-void exceptions_print_current_exception(void)
-{
-       java_handle_t *o;
-
-       o = exceptions_get_exception();
-
-       exceptions_print_exception(o);
-}
-
-
-/* exceptions_print_stacktrace *************************************************
-
-   Prints a pending exception with Throwable.printStackTrace().  If
-   there happens an exception during printStackTrace(), we print the
-   thrown exception and the original one.
-
-   NOTE: This function calls Java code.
-
-*******************************************************************************/
-
-void exceptions_print_stacktrace(void)
-{
-       java_handle_t    *e;
-       java_handle_t    *ne;
-       classinfo        *c;
-       methodinfo       *m;
-
-#if defined(ENABLE_THREADS)
-       threadobject     *t;
-       java_lang_Thread *to;
-#endif
-
-       /* Get and clear exception because we are calling Java code
-          again. */
-
-       e = exceptions_get_and_clear_exception();
-
-       if (e == NULL)
-               return;
-
-#if 0
-       /* FIXME Enable me. */
-       if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
-               /* Don't print anything if we are being killed. */
-       }
-       else
-#endif
-       {
-               /* Get the exception class. */
-
-               LLNI_class_get(e, c);
-
-               /* Find the printStackTrace() method. */
-
-               m = class_resolveclassmethod(c,
-                                                                        utf_printStackTrace,
-                                                                        utf_void__void,
-                                                                        class_java_lang_Object,
-                                                                        false);
-
-               if (m == NULL)
-                       vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
-
-               /* Print message. */
-
-               fprintf(stderr, "Exception ");
-
-#if defined(ENABLE_THREADS)
-               /* Print thread name.  We get the thread here explicitly as we
-                  need it afterwards. */
-
-               t  = thread_get_current();
-               to = (java_lang_Thread *) thread_get_object(t);
-
-               if (to != NULL) {
-                       fprintf(stderr, "in thread \"");
-                       thread_fprint_name(t, stderr);
-                       fprintf(stderr, "\" ");
-               }
-#endif
-
-               /* Print the stacktrace. */
-
-               if (builtin_instanceof(e, class_java_lang_Throwable)) {
-                       (void) vm_call_method(m, e);
-
-                       /* If this happens we are EXTREMLY out of memory or have a
-                          serious problem while printStackTrace.  But may be
-                          another exception, so print it. */
-
-                       ne = exceptions_get_exception();
-
-                       if (ne != NULL) {
-                               fprintf(stderr, "Exception while printStackTrace(): ");
-
-                               /* Print the current exception. */
-
-                               exceptions_print_exception(ne);
-                               stacktrace_print_exception(ne);
-
-                               /* Now print the original exception. */
-
-                               fprintf(stderr, "Original exception was: ");
-                               exceptions_print_exception(e);
-                               stacktrace_print_exception(e);
-                       }
-               }
-               else {
-                       fprintf(stderr, ". Uncaught exception of type ");
-#if !defined(NDEBUG)
-                       /* FIXME This prints to stdout. */
-                       class_print(c);
-#else
-                       fprintf(stderr, "UNKNOWN");
-#endif
-                       fprintf(stderr, ".");
-               }
-
-               fflush(stderr);
-       }
-}
-
-
-/*
- * 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/exceptions.cpp b/src/vm/exceptions.cpp
new file mode 100644 (file)
index 0000000..e97c6e1
--- /dev/null
@@ -0,0 +1,2091 @@
+/* src/vm/exceptions.cpp - exception related 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 <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include "vm/types.h"
+
+#include "md-abi.h"
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/native.h"
+
+#include "threads/lock-common.h"
+#include "threads/thread.hpp"
+
+#include "toolbox/util.h"
+
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/loader.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/methodheader.h"
+#include "vm/jit/patcher-common.h"
+#include "vm/jit/show.h"
+#include "vm/jit/stacktrace.hpp"
+#include "vm/jit/trace.hpp"
+
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
+
+// FIXME
+extern "C" {
+
+/* for raising exceptions from native methods *********************************/
+
+#if !defined(ENABLE_THREADS)
+java_object_t *_no_threads_exceptionptr = NULL;
+#endif
+
+
+/* exceptions_get_exception ****************************************************
+
+   Returns the current exception pointer of the current thread.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_get_exception(void)
+{
+       java_object_t *o;
+       java_handle_t *e;
+#if defined(ENABLE_THREADS)
+       threadobject  *t;
+
+       t = THREADOBJECT;
+#endif
+
+       /* Get the exception. */
+
+       LLNI_CRITICAL_START;
+
+#if defined(ENABLE_THREADS)
+       o = t->_exceptionptr;
+#else
+       o = _no_threads_exceptionptr;
+#endif
+
+       e = LLNI_WRAP(o);
+
+       LLNI_CRITICAL_END;
+
+       /* Return the exception. */
+
+       return e;
+}
+
+
+/* exceptions_set_exception ****************************************************
+
+   Sets the exception pointer of the current thread.
+
+*******************************************************************************/
+
+void exceptions_set_exception(java_handle_t *e)
+{
+       threadobject  *t;
+       java_object_t *o;
+
+#if defined(ENABLE_THREADS)
+       t = THREADOBJECT;
+#else
+       t = NULL;
+#endif
+
+       /* Set the exception. */
+
+       LLNI_CRITICAL_START;
+
+       o = LLNI_UNWRAP(e);
+
+#if !defined(NDEBUG)
+       if (opt_DebugExceptions) {
+               printf("[exceptions_set_exception  : t=%p, o=%p, class=",
+                          (void *) t, (void *) o);
+               class_print(o->vftbl->clazz);
+               printf("]\n");
+       }
+#endif
+
+#if defined(ENABLE_THREADS)
+       t->_exceptionptr = o;
+#else
+       _no_threads_exceptionptr = o;
+#endif
+
+       LLNI_CRITICAL_END;
+}
+
+
+/* exceptions_clear_exception **************************************************
+
+   Clears the current exception pointer of the current thread.
+
+*******************************************************************************/
+
+void exceptions_clear_exception(void)
+{
+       threadobject *t;
+
+#if defined(ENABLE_THREADS)
+       t = THREADOBJECT;
+#else
+       t = NULL;
+#endif
+
+       /* Set the exception. */
+
+#if !defined(NDEBUG)
+       if (opt_DebugExceptions) {
+               printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
+       }
+#endif
+
+#if defined(ENABLE_THREADS)
+       t->_exceptionptr = NULL;
+#else
+       _no_threads_exceptionptr = NULL;
+#endif
+}
+
+
+/* exceptions_get_and_clear_exception ******************************************
+
+   Gets the exception pointer of the current thread and clears it.
+   This function may return NULL.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_get_and_clear_exception(void)
+{
+       java_handle_t *o;
+
+       /* Get the exception... */
+
+       o = exceptions_get_exception();
+
+       /* ...and clear the exception if it is set. */
+
+       if (o != NULL)
+               exceptions_clear_exception();
+
+       /* return the exception */
+
+       return o;
+}
+
+
+/* exceptions_abort ************************************************************
+
+   Prints exception to be thrown and aborts.
+
+   IN:
+      classname....class name
+      message......exception message
+
+*******************************************************************************/
+
+static void exceptions_abort(utf *classname, utf *message)
+{
+       log_println("exception thrown while VM is initializing: ");
+
+       log_start();
+       utf_display_printable_ascii_classname(classname);
+
+       if (message != NULL) {
+               log_print(": ");
+               utf_display_printable_ascii_classname(message);
+       }
+
+       log_finish();
+
+       vm_abort("Aborting...");
+}
+
+
+/* exceptions_new_class_utf ****************************************************
+
+   Creates an exception object with the given class and initalizes it
+   with the given utf message.
+
+   IN:
+      c ......... exception class
+         message ... the message as an utf *
+
+   RETURN VALUE:
+     an exception pointer (in any case -- either it is the newly
+     created exception, or an exception thrown while trying to create
+     it).
+
+*******************************************************************************/
+
+static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
+{
+       java_handle_t *s;
+       java_handle_t *o;
+
+       if (vm->is_initializing()) {
+               /* This can happen when global class variables are used which
+                  are not initialized yet. */
+
+               if (c == NULL)
+                       exceptions_abort(NULL, message);
+               else
+                       exceptions_abort(c->name, message);
+       }
+
+       s = javastring_new(message);
+
+       if (s == NULL)
+               return exceptions_get_exception();
+
+       o = native_new_and_init_string(c, s);
+
+       if (o == NULL)
+               return exceptions_get_exception();
+
+       return o;
+}
+
+
+/* exceptions_new_utf **********************************************************
+
+   Creates an exception object with the given name and initalizes it.
+
+   IN:
+      classname....class name in UTF-8
+
+*******************************************************************************/
+
+static java_handle_t *exceptions_new_utf(utf *classname)
+{
+       classinfo     *c;
+       java_handle_t *o;
+
+       if (vm->is_initializing())
+               exceptions_abort(classname, NULL);
+
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return exceptions_get_exception();
+
+       o = native_new_and_init(c);
+
+       if (o == NULL)
+               return exceptions_get_exception();
+
+       return o;
+}
+
+
+/* exceptions_new_utf_javastring ***********************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/String message.
+
+   IN:
+      classname....class name in UTF-8
+         message......the message as a java.lang.String
+
+   RETURN VALUE:
+      an exception pointer (in any case -- either it is the newly created
+         exception, or an exception thrown while trying to create it).
+
+*******************************************************************************/
+
+static java_handle_t *exceptions_new_utf_javastring(utf *classname,
+                                                                                                       java_handle_t *message)
+{
+       java_handle_t *o;
+       classinfo     *c;
+   
+       if (vm->is_initializing())
+               exceptions_abort(classname, NULL);
+
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return exceptions_get_exception();
+
+       o = native_new_and_init_string(c, message);
+
+       if (o == NULL)
+               return exceptions_get_exception();
+
+       return o;
+}
+
+
+/* exceptions_new_utf_utf ******************************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given utf message.
+
+   IN:
+      classname....class name in UTF-8
+         message......the message as an utf *
+
+   RETURN VALUE:
+      an exception pointer (in any case -- either it is the newly created
+         exception, or an exception thrown while trying to create it).
+
+*******************************************************************************/
+
+static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
+{
+       classinfo     *c;
+       java_handle_t *o;
+
+       if (vm->is_initializing())
+               exceptions_abort(classname, message);
+
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return exceptions_get_exception();
+
+       o = exceptions_new_class_utf(c, message);
+
+       return o;
+}
+
+
+/* exceptions_throw_class_utf **************************************************
+
+   Creates an exception object with the given class, initalizes and
+   throws it with the given utf message.
+
+   IN:
+      c ......... exception class
+         message ... the message as an utf *
+
+*******************************************************************************/
+
+static void exceptions_throw_class_utf(classinfo *c, utf *message)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_class_utf(c, message);
+
+       exceptions_set_exception(o);
+}
+
+
+/* exceptions_throw_utf ********************************************************
+
+   Creates an exception object with the given name, initalizes and
+   throws it.
+
+   IN:
+      classname....class name in UTF-8
+
+*******************************************************************************/
+
+static void exceptions_throw_utf(utf *classname)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_utf(classname);
+
+       if (o == NULL)
+               return;
+
+       exceptions_set_exception(o);
+}
+
+
+/* exceptions_throw_utf_throwable **********************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/Throwable exception.
+
+   IN:
+      classname....class name in UTF-8
+         cause........the given Throwable
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_throwable(utf *classname,
+                                                                                  java_handle_t *cause)
+{
+       classinfo           *c;
+       methodinfo          *m;
+
+       if (vm->is_initializing())
+               exceptions_abort(classname, NULL);
+
+       java_lang_Throwable jlt(cause);
+
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return;
+
+       /* create object */
+
+       java_handle_t* h = builtin_new(c);
+
+       if (h == NULL)
+               return;
+
+       /* call initializer */
+
+       m = class_resolveclassmethod(c,
+                                                                utf_init,
+                                                                utf_java_lang_Throwable__void,
+                                                                NULL,
+                                                                true);
+                                                     
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, h, jlt.get_handle());
+
+       exceptions_set_exception(h);
+}
+
+
+/* exceptions_throw_utf_exception **********************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/Exception exception.
+
+   IN:
+      classname....class name in UTF-8
+         exception....the given Exception
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_exception(utf *classname,
+                                                                                  java_handle_t *exception)
+{
+       classinfo     *c;
+       java_handle_t *o;
+       methodinfo    *m;
+
+       if (vm->is_initializing())
+               exceptions_abort(classname, NULL);
+
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return;
+
+       /* create object */
+
+       o = builtin_new(c);
+       
+       if (o == NULL)
+               return;
+
+       /* call initializer */
+
+       m = class_resolveclassmethod(c,
+                                                                utf_init,
+                                                                utf_java_lang_Exception__V,
+                                                                NULL,
+                                                                true);
+                                                     
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, o, exception);
+
+       exceptions_set_exception(o);
+}
+
+
+/* exceptions_throw_utf_cause **************************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/Throwable exception with initCause.
+
+   IN:
+      classname....class name in UTF-8
+         cause........the given Throwable
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
+{
+       if (vm->is_initializing())
+               exceptions_abort(classname, NULL);
+
+       java_lang_Throwable jltcause(cause);
+
+       classinfo* c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return;
+
+       /* create object */
+
+       java_handle_t* h = builtin_new(c);
+       
+       if (h == NULL)
+               return;
+
+       /* call initializer */
+
+       methodinfo* m = class_resolveclassmethod(c,
+                                                                                        utf_init,
+                                                                                        utf_java_lang_String__void,
+                                                                                        NULL,
+                                                                                        true);
+                                                     
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, h, jltcause.get_detailMessage());
+
+       /* call initCause */
+
+       m = class_resolveclassmethod(c,
+                                                                utf_initCause,
+                                                                utf_java_lang_Throwable__java_lang_Throwable,
+                                                                NULL,
+                                                                true);
+
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, h, jltcause.get_handle());
+
+       exceptions_set_exception(h);
+}
+
+
+/* exceptions_throw_utf_utf ****************************************************
+
+   Creates an exception object with the given name, initalizes and
+   throws it with the given utf message.
+
+   IN:
+      classname....class name in UTF-8
+         message......the message as an utf *
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_utf(utf *classname, utf *message)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_utf_utf(classname, message);
+
+       exceptions_set_exception(o);
+}
+
+
+/* exceptions_new_abstractmethoderror ****************************************
+
+   Generates a java.lang.AbstractMethodError for the VM.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_new_abstractmethoderror(void)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
+
+       return o;
+}
+
+
+/* exceptions_new_error ********************************************************
+
+   Generates a java.lang.Error for the VM.
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVAME_CLDC1_1)
+static java_handle_t *exceptions_new_error(utf *message)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_utf_utf(utf_java_lang_Error, message);
+
+       return o;
+}
+#endif
+
+
+/* exceptions_asm_new_abstractmethoderror **************************************
+
+   Generates a java.lang.AbstractMethodError for
+   asm_abstractmethoderror.
+
+*******************************************************************************/
+
+java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
+{
+       stackframeinfo_t  sfi;
+       java_handle_t    *e;
+       java_object_t    *o;
+
+       /* Fill and add a stackframeinfo (XPC is equal to RA). */
+
+       stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
+
+       /* create the exception */
+
+#if defined(ENABLE_JAVASE)
+       e = exceptions_new_abstractmethoderror();
+#else
+       e = exceptions_new_error(utf_java_lang_AbstractMethodError);
+#endif
+
+       /* Remove the stackframeinfo. */
+
+       stacktrace_stackframeinfo_remove(&sfi);
+
+       /* unwrap the exception */
+       /* ATTENTION: do the this _after_ the stackframeinfo was removed */
+
+       o = LLNI_UNWRAP(e);
+
+       return o;
+}
+
+
+/* exceptions_new_arraystoreexception ******************************************
+
+   Generates a java.lang.ArrayStoreException for the VM.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_new_arraystoreexception(void)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
+
+       return o;
+}
+
+
+/* exceptions_throw_abstractmethoderror ****************************************
+
+   Generates and throws a java.lang.AbstractMethodError for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_abstractmethoderror(void)
+{
+       exceptions_throw_utf(utf_java_lang_AbstractMethodError);
+}
+
+
+/* exceptions_throw_classcircularityerror **************************************
+
+   Generates and throws a java.lang.ClassCircularityError for the
+   classloader.
+
+   IN:
+      c....the class in which the error was found
+
+*******************************************************************************/
+
+void exceptions_throw_classcircularityerror(classinfo *c)
+{
+       exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
+}
+
+
+/* exceptions_throw_classformaterror *******************************************
+
+   Generates and throws a java.lang.ClassFormatError for the VM.
+
+   IN:
+      c............the class in which the error was found
+         message......UTF-8 format string
+
+*******************************************************************************/
+
+void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
+{
+       char    *msg;
+       s4       msglen;
+       va_list  ap;
+       utf     *u;
+
+       /* calculate message length */
+
+       msglen = 0;
+
+       if (c != NULL)
+               msglen += utf_bytes(c->name) + strlen(" (");
+
+       va_start(ap, message);
+       msglen += get_variable_message_length(message, ap);
+       va_end(ap);
+
+       if (c != NULL)
+               msglen += strlen(")");
+
+       msglen += strlen("0");
+
+       /* allocate a buffer */
+
+       msg = MNEW(char, msglen);
+
+       /* print message into allocated buffer */
+
+       if (c != NULL) {
+               utf_copy_classname(msg, c->name);
+               strcat(msg, " (");
+       }
+
+       va_start(ap, message);
+       vsprintf(msg + strlen(msg), message, ap);
+       va_end(ap);
+
+       if (c != NULL)
+               strcat(msg, ")");
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       /* throw exception */
+
+       exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
+}
+
+
+/* exceptions_throw_classnotfoundexception *************************************
+
+   Generates and throws a java.lang.ClassNotFoundException for the
+   VM.
+
+   IN:
+      name.........name of the class not found as a utf *
+
+*******************************************************************************/
+
+void exceptions_throw_classnotfoundexception(utf *name)
+{      
+       exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
+}
+
+
+/* exceptions_throw_noclassdeffounderror ***************************************
+
+   Generates and throws a java.lang.NoClassDefFoundError.
+
+   IN:
+      name.........name of the class not found as a utf *
+
+*******************************************************************************/
+
+void exceptions_throw_noclassdeffounderror(utf *name)
+{
+       exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
+}
+
+
+/* exceptions_throw_noclassdeffounderror_cause *********************************
+
+   Generates and throws a java.lang.NoClassDefFoundError with the
+   given cause.
+
+*******************************************************************************/
+
+void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
+{
+       exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
+}
+
+
+/* exceptions_throw_noclassdeffounderror_wrong_name ****************************
+
+   Generates and throws a java.lang.NoClassDefFoundError with a
+   specific message:
+
+   IN:
+      name.........name of the class not found as a utf *
+
+*******************************************************************************/
+
+void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
+{
+       char *msg;
+       s4    msglen;
+       utf  *u;
+
+       msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
+               utf_bytes(name) + strlen(")") + strlen("0");
+
+       msg = MNEW(char, msglen);
+
+       utf_copy_classname(msg, c->name);
+       strcat(msg, " (wrong name: ");
+       utf_cat_classname(msg, name);
+       strcat(msg, ")");
+
+       u = utf_new_char(msg);
+
+       MFREE(msg, char, msglen);
+
+       exceptions_throw_noclassdeffounderror(u);
+}
+
+
+/* exceptions_throw_exceptionininitializererror ********************************
+
+   Generates and throws a java.lang.ExceptionInInitializerError for
+   the VM.
+
+   IN:
+      cause......cause exception object
+
+*******************************************************************************/
+
+void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
+{
+       exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
+                                                                  cause);
+}
+
+
+/* exceptions_throw_incompatibleclasschangeerror *******************************
+
+   Generates and throws a java.lang.IncompatibleClassChangeError for
+   the VM.
+
+   IN:
+      message......UTF-8 message format string
+
+*******************************************************************************/
+
+void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
+{
+       char *msg;
+       s4    msglen;
+       utf  *u;
+
+       /* calculate exception message length */
+
+       msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       utf_copy_classname(msg, c->name);
+       strcat(msg, message);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       /* throw exception */
+
+       exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
+}
+
+
+/* exceptions_throw_instantiationerror *****************************************
+
+   Generates and throws a java.lang.InstantiationError for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_instantiationerror(classinfo *c)
+{
+       exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
+}
+
+
+/* exceptions_throw_internalerror **********************************************
+
+   Generates and throws a java.lang.InternalError for the VM.
+
+   IN:
+      message......UTF-8 message format string
+
+*******************************************************************************/
+
+void exceptions_throw_internalerror(const char *message, ...)
+{
+       va_list  ap;
+       char    *msg;
+       s4       msglen;
+       utf     *u;
+
+       /* calculate exception message length */
+
+       va_start(ap, message);
+       msglen = get_variable_message_length(message, ap);
+       va_end(ap);
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       va_start(ap, message);
+       vsprintf(msg, message, ap);
+       va_end(ap);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       /* throw exception */
+
+       exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
+}
+
+
+/* exceptions_throw_linkageerror ***********************************************
+
+   Generates and throws java.lang.LinkageError with an error message.
+
+   IN:
+      message......UTF-8 message
+         c............class related to the error. If this is != NULL
+                      the name of c is appended to the error message.
+
+*******************************************************************************/
+
+void exceptions_throw_linkageerror(const char *message, classinfo *c)
+{
+       utf  *u;
+       char *msg;
+       int   len;
+
+       /* calculate exception message length */
+
+       len = strlen(message) + 1;
+
+       if (c != NULL)
+               len += utf_bytes(c->name);
+               
+       /* allocate memory */
+
+       msg = MNEW(char, len);
+
+       /* generate message */
+
+       strcpy(msg, message);
+
+       if (c != NULL)
+               utf_cat_classname(msg, c->name);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, len);
+
+       exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
+}
+
+
+/* exceptions_throw_nosuchfielderror *******************************************
+
+   Generates and throws a java.lang.NoSuchFieldError with an error
+   message.
+
+   IN:
+      c............class in which the field was not found
+         name.........name of the field
+
+*******************************************************************************/
+
+void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
+{
+       char *msg;
+       s4    msglen;
+       utf  *u;
+
+       /* calculate exception message length */
+
+       msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       utf_copy_classname(msg, c->name);
+       strcat(msg, ".");
+       utf_cat(msg, name);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
+}
+
+
+/* exceptions_throw_nosuchmethoderror ******************************************
+
+   Generates and throws a java.lang.NoSuchMethodError with an error
+   message.
+
+   IN:
+      c............class in which the method was not found
+         name.........name of the method
+         desc.........descriptor of the method
+
+*******************************************************************************/
+
+void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
+{
+       char *msg;
+       s4    msglen;
+       utf  *u;
+
+       /* calculate exception message length */
+
+       msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
+               utf_bytes(desc) + strlen("0");
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       utf_copy_classname(msg, c->name);
+       strcat(msg, ".");
+       utf_cat(msg, name);
+       utf_cat(msg, desc);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+#if defined(ENABLE_JAVASE)
+       exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
+#else
+       exceptions_throw_utf_utf(utf_java_lang_Error, u);
+#endif
+}
+
+
+/* exceptions_throw_outofmemoryerror *******************************************
+
+   Generates and throws an java.lang.OutOfMemoryError for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_outofmemoryerror(void)
+{
+       exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
+}
+
+
+/* exceptions_throw_unsatisfiedlinkerror ***************************************
+
+   Generates and throws a java.lang.UnsatisfiedLinkError for the
+   classloader.
+
+   IN:
+         name......UTF-8 name string
+
+*******************************************************************************/
+
+void exceptions_throw_unsatisfiedlinkerror(utf *name)
+{
+#if defined(ENABLE_JAVASE)
+       exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
+#else
+       exceptions_throw_utf_utf(utf_java_lang_Error, name);
+#endif
+}
+
+
+/* exceptions_throw_unsupportedclassversionerror *******************************
+
+   Generates and throws a java.lang.UnsupportedClassVersionError for
+   the classloader.
+
+   IN:
+      c............class in which the method was not found
+         message......UTF-8 format string
+
+*******************************************************************************/
+
+void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
+{
+       char *msg;
+    s4    msglen;
+       utf  *u;
+
+       /* calculate exception message length */
+
+       msglen =
+               utf_bytes(c->name) +
+               strlen(" (Unsupported major.minor version 00.0)") +
+               strlen("0");
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       utf_copy_classname(msg, c->name);
+       sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
+                       ma, mi);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       /* throw exception */
+
+       exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
+}
+
+
+/* exceptions_throw_verifyerror ************************************************
+
+   Generates and throws a java.lang.VerifyError for the JIT compiler.
+
+   IN:
+      m............method in which the error was found
+         message......UTF-8 format string
+
+*******************************************************************************/
+
+void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
+{
+       va_list  ap;
+       char    *msg;
+       s4       msglen;
+       utf     *u;
+
+       /* calculate exception message length */
+
+       msglen = 0;
+
+       if (m != NULL)
+               msglen =
+                       strlen("(class: ") + utf_bytes(m->clazz->name) +
+                       strlen(", method: ") + utf_bytes(m->name) +
+                       strlen(" signature: ") + utf_bytes(m->descriptor) +
+                       strlen(") ") + strlen("0");
+
+       va_start(ap, message);
+       msglen += get_variable_message_length(message, ap);
+       va_end(ap);
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       if (m != NULL) {
+               strcpy(msg, "(class: ");
+               utf_cat_classname(msg, m->clazz->name);
+               strcat(msg, ", method: ");
+               utf_cat(msg, m->name);
+               strcat(msg, " signature: ");
+               utf_cat(msg, m->descriptor);
+               strcat(msg, ") ");
+       }
+
+       va_start(ap, message);
+       vsprintf(msg + strlen(msg), message, ap);
+       va_end(ap);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       /* throw exception */
+
+       exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
+}
+
+
+/* exceptions_throw_verifyerror_for_stack **************************************
+
+   throws a java.lang.VerifyError for an invalid stack slot type
+
+   IN:
+      m............method in which the error was found
+         type.........the expected type
+
+   RETURN VALUE:
+      an exception pointer (in any case -- either it is the newly created
+         exception, or an exception thrown while trying to create it).
+
+*******************************************************************************/
+
+void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
+{
+       char *msg;
+       s4    msglen;
+       utf  *u;
+
+       /* calculate exception message length */
+
+       msglen = 0;
+
+       if (m != NULL)
+               msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
+                       strlen(", method: ") + utf_bytes(m->name) +
+                       strlen(" signature: ") + utf_bytes(m->descriptor) +
+                       strlen(") Expecting to find longest-------typename on stack") 
+                       + strlen("0");
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       if (m != NULL) {
+               strcpy(msg, "(class: ");
+               utf_cat_classname(msg, m->clazz->name);
+               strcat(msg, ", method: ");
+               utf_cat(msg, m->name);
+               strcat(msg, " signature: ");
+               utf_cat(msg, m->descriptor);
+               strcat(msg, ") ");
+       }
+       else {
+               msg[0] = 0;
+       }
+
+       strcat(msg, "Expecting to find ");
+
+       const char *name;
+
+       switch (type) {
+       case TYPE_INT: name = "integer";       break;
+       case TYPE_LNG: name = "long";          break;
+       case TYPE_FLT: name = "float";         break;
+       case TYPE_DBL: name = "double";        break;
+       case TYPE_ADR: name = "object/array";  break;
+       case TYPE_RET: name = "returnAddress"; break;
+       default:       name = "<INVALID>"; assert(0); break;
+       }
+
+       strcat(msg, name);
+       strcat(msg, " on stack");
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       /* throw exception */
+
+       exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
+}
+
+
+/* exceptions_new_arithmeticexception ******************************************
+
+   Generates a java.lang.ArithmeticException for the JIT compiler.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_new_arithmeticexception(void)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
+                                                          utf_division_by_zero);
+
+       return o;
+}
+
+
+/* exceptions_new_arrayindexoutofboundsexception *******************************
+
+   Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
+   system.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
+{
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *s;
+
+       /* convert the index into a String, like Sun does */
+
+       m = class_resolveclassmethod(class_java_lang_String,
+                                                                utf_new_char("valueOf"),
+                                                                utf_new_char("(I)Ljava/lang/String;"),
+                                                                class_java_lang_Object,
+                                                                true);
+
+       if (m == NULL)
+               return exceptions_get_exception();
+
+       s = vm_call_method(m, NULL, index);
+
+       if (s == NULL)
+               return exceptions_get_exception();
+
+       o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
+                                                                         s);
+
+       if (o == NULL)
+               return exceptions_get_exception();
+
+       return o;
+}
+
+
+/* exceptions_throw_arrayindexoutofboundsexception *****************************
+
+   Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
+   the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_arrayindexoutofboundsexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
+}
+
+
+/* exceptions_throw_arraystoreexception ****************************************
+
+   Generates and throws a java.lang.ArrayStoreException for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_arraystoreexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_ArrayStoreException);
+}
+
+
+/* exceptions_new_classcastexception *******************************************
+
+   Generates a java.lang.ClassCastException for the JIT compiler.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
+{
+       java_handle_t *e;
+       classinfo     *c;
+       utf           *classname;
+
+       LLNI_class_get(o, c);
+
+       classname = c->name;
+
+       e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
+
+       return e;
+}
+
+
+/* exceptions_throw_clonenotsupportedexception *********************************
+
+   Generates and throws a java.lang.CloneNotSupportedException for the
+   VM.
+
+*******************************************************************************/
+
+void exceptions_throw_clonenotsupportedexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
+}
+
+
+/* exceptions_throw_illegalaccessexception *************************************
+
+   Generates and throws a java.lang.IllegalAccessException for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_illegalaccessexception(utf *message)
+{
+       exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
+}
+
+
+/* exceptions_throw_illegalargumentexception ***********************************
+
+   Generates and throws a java.lang.IllegalArgumentException for the
+   VM.
+
+*******************************************************************************/
+
+void exceptions_throw_illegalargumentexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
+}
+
+
+/* exceptions_throw_illegalmonitorstateexception *******************************
+
+   Generates and throws a java.lang.IllegalMonitorStateException for
+   the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_illegalmonitorstateexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
+}
+
+
+/* exceptions_throw_instantiationexception *************************************
+
+   Generates and throws a java.lang.InstantiationException for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_instantiationexception(classinfo *c)
+{
+       exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
+}
+
+
+/* exceptions_throw_interruptedexception ***************************************
+
+   Generates and throws a java.lang.InterruptedException for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_interruptedexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_InterruptedException);
+}
+
+
+/* exceptions_throw_invocationtargetexception **********************************
+
+   Generates and throws a java.lang.reflect.InvocationTargetException
+   for the VM.
+
+   IN:
+      cause......cause exception object
+
+*******************************************************************************/
+
+void exceptions_throw_invocationtargetexception(java_handle_t *cause)
+{
+       exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
+                                                                  cause);
+}
+
+
+/* exceptions_throw_negativearraysizeexception *********************************
+
+   Generates and throws a java.lang.NegativeArraySizeException for the
+   VM.
+
+*******************************************************************************/
+
+void exceptions_throw_negativearraysizeexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
+}
+
+
+/* exceptions_new_nullpointerexception *****************************************
+
+   Generates a java.lang.NullPointerException for the VM system.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_new_nullpointerexception(void)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_utf(utf_java_lang_NullPointerException);
+
+       return o;
+}
+
+
+/* exceptions_throw_nullpointerexception ***************************************
+
+   Generates a java.lang.NullPointerException for the VM system and
+   throw it in the VM system.
+
+*******************************************************************************/
+
+void exceptions_throw_nullpointerexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_NullPointerException);
+}
+
+
+/* exceptions_throw_privilegedactionexception **********************************
+
+   Generates and throws a java.security.PrivilegedActionException.
+
+*******************************************************************************/
+
+void exceptions_throw_privilegedactionexception(java_handle_t *exception)
+{
+       exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
+                                                                  exception);
+}
+
+
+/* exceptions_throw_stringindexoutofboundsexception ****************************
+
+   Generates and throws a java.lang.StringIndexOutOfBoundsException
+   for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_stringindexoutofboundsexception(void)
+{
+       exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
+}
+
+
+/* exceptions_fillinstacktrace *************************************************
+
+   Calls the fillInStackTrace-method of the currently thrown
+   exception.
+
+*******************************************************************************/
+
+java_handle_t *exceptions_fillinstacktrace(void)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+
+       /* get exception */
+
+       o = exceptions_get_and_clear_exception();
+
+       assert(o);
+
+       /* resolve methodinfo pointer from exception object */
+
+       LLNI_class_get(o, c);
+
+#if defined(ENABLE_JAVASE)
+       m = class_resolvemethod(c,
+                                                       utf_fillInStackTrace,
+                                                       utf_void__java_lang_Throwable);
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+       m = class_resolvemethod(c,
+                                                       utf_fillInStackTrace,
+                                                       utf_void__void);
+#else
+#error IMPLEMENT ME!
+#endif
+
+       /* call function */
+
+       (void) vm_call_method(m, o);
+
+       /* return exception object */
+
+       return o;
+}
+
+
+/* exceptions_handle_exception *************************************************
+
+   Try to find an exception handler for the given exception and return it.
+   If no handler is found, exit the monitor of the method (if any)
+   and return NULL.
+
+   IN:
+      xptr.........the exception object
+         xpc..........PC of where the exception was thrown
+         pv...........Procedure Value of the current method
+         sp...........current stack pointer
+
+   RETURN VALUE:
+      the address of the first matching exception handler, or
+         NULL if no handler was found
+
+*******************************************************************************/
+
+#if defined(ENABLE_JIT)
+void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
+{
+       stackframeinfo_t        sfi;
+       java_handle_t          *xptr;
+       methodinfo             *m;
+       codeinfo               *code;
+       exceptiontable_t       *et;
+       exceptiontable_entry_t *ete;
+       s4                      i;
+       classref_or_classinfo   cr;
+       classinfo              *c;
+#if defined(ENABLE_THREADS)
+       java_object_t          *o;
+#endif
+       void                   *result;
+
+#ifdef __S390__
+       /* Addresses are 31 bit integers */
+#      define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
+#else
+#      define ADDR_MASK(x) (x)
+#endif
+
+       xptr = LLNI_WRAP(xptro);
+       xpc  = ADDR_MASK(xpc);
+
+       /* Fill and add a stackframeinfo (XPC is equal to RA). */
+
+       stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
+
+       result = NULL;
+
+       /* Get the codeinfo for the current method. */
+
+       code = code_get_codeinfo_for_pv(pv);
+
+       /* Get the methodinfo pointer from the codeinfo pointer. For
+          asm_vm_call_method the codeinfo pointer is NULL and we simply
+          can return the proper exception handler. */
+
+       if (code == NULL) {
+               result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
+               goto exceptions_handle_exception_return;
+       }
+
+       m = code->m;
+
+#if !defined(NDEBUG)
+       /* print exception trace */
+
+       if (opt_TraceExceptions)
+               trace_exception(LLNI_DIRECT(xptr), m, xpc);
+
+# if defined(ENABLE_VMLOG)
+       vmlog_cacao_throw(xptr);
+# endif
+#endif
+
+       /* Get the exception table. */
+
+       et = code->exceptiontable;
+
+       if (et != NULL) {
+       /* Iterate over all exception table entries. */
+
+       ete = et->entries;
+
+       for (i = 0; i < et->length; i++, ete++) {
+               /* is the xpc is the current catch range */
+
+               if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
+                       cr = ete->catchtype;
+
+                       /* NULL catches everything */
+
+                       if (cr.any == NULL) {
+#if !defined(NDEBUG)
+                               /* Print stacktrace of exception when caught. */
+
+# if defined(ENABLE_VMLOG)
+                               vmlog_cacao_catch(xptr);
+# endif
+
+                               if (opt_TraceExceptions) {
+                                       exceptions_print_exception(xptr);
+                                       stacktrace_print_exception(xptr);
+                               }
+#endif
+
+                               result = ete->handlerpc;
+                               goto exceptions_handle_exception_return;
+                       }
+
+                       /* resolve or load/link the exception class */
+
+                       if (IS_CLASSREF(cr)) {
+                               /* The exception class reference is unresolved. */
+                               /* We have to do _eager_ resolving here. While the
+                                  class of the exception object is guaranteed to be
+                                  loaded, it may well have been loaded by a different
+                                  loader than the defining loader of m's class, which
+                                  is the one we must use to resolve the catch
+                                  class. Thus lazy resolving might fail, even if the
+                                  result of the resolution would be an already loaded
+                                  class. */
+
+                               c = resolve_classref_eager(cr.ref);
+
+                               if (c == NULL) {
+                                       /* Exception resolving the exception class, argh! */
+                                       goto exceptions_handle_exception_return;
+                               }
+
+                               /* Ok, we resolved it. Enter it in the table, so we
+                                  don't have to do this again. */
+                               /* XXX this write should be atomic. Is it? */
+
+                               ete->catchtype.cls = c;
+                       }
+                       else {
+                               c = cr.cls;
+
+                               /* XXX I don't think this case can ever happen. -Edwin */
+                               if (!(c->state & CLASS_LOADED))
+                                       /* use the methods' classloader */
+                                       if (!load_class_from_classloader(c->name,
+                                                                                                        m->clazz->classloader))
+                                               goto exceptions_handle_exception_return;
+
+                               /* XXX I think, if it is not linked, we can be sure
+                                  that the exception object is no (indirect) instance
+                                  of it, no?  -Edwin  */
+                               if (!(c->state & CLASS_LINKED))
+                                       if (!link_class(c))
+                                               goto exceptions_handle_exception_return;
+                       }
+
+                       /* is the thrown exception an instance of the catch class? */
+
+                       if (builtin_instanceof(xptr, c)) {
+#if !defined(NDEBUG)
+                               /* Print stacktrace of exception when caught. */
+
+# if defined(ENABLE_VMLOG)
+                               vmlog_cacao_catch(xptr);
+# endif
+
+                               if (opt_TraceExceptions) {
+                                       exceptions_print_exception(xptr);
+                                       stacktrace_print_exception(xptr);
+                               }
+#endif
+
+                               result = ete->handlerpc;
+                               goto exceptions_handle_exception_return;
+                       }
+               }
+       }
+       }
+
+#if defined(ENABLE_THREADS)
+       /* Is this method realization synchronized? */
+
+       if (code_is_synchronized(code)) {
+               /* Get synchronization object. */
+
+               o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
+
+               assert(o != NULL);
+
+               lock_monitor_exit(LLNI_QUICKWRAP(o));
+       }
+#endif
+
+       /* none of the exceptions catch this one */
+
+#if !defined(NDEBUG)
+# if defined(ENABLE_VMLOG)
+       vmlog_cacao_unwnd_method(m);
+# endif
+
+# if defined(ENABLE_DEBUG_FILTER)
+       if (show_filters_test_verbosecall_exit(m)) {
+# endif
+
+       /* outdent the log message */
+
+       if (opt_verbosecall) {
+               if (TRACEJAVACALLINDENT)
+                       TRACEJAVACALLINDENT--;
+               else
+                       log_text("exceptions_handle_exception: WARNING: unmatched unindent");
+       }
+
+# if defined(ENABLE_DEBUG_FILTER)
+       }
+# endif
+#endif /* !defined(NDEBUG) */
+
+       result = NULL;
+
+exceptions_handle_exception_return:
+
+       /* Remove the stackframeinfo. */
+
+       stacktrace_stackframeinfo_remove(&sfi);
+
+       return result;
+}
+#endif /* defined(ENABLE_JIT) */
+
+
+/* exceptions_print_exception **************************************************
+
+   Prints an exception, the detail message and the cause, if
+   available, with CACAO internal functions to stdout.
+
+*******************************************************************************/
+
+void exceptions_print_exception(java_handle_t *xptr)
+{
+       java_lang_Throwable jlt(xptr);
+
+       if (jlt.is_null()) {
+               puts("NULL\n");
+               return;
+       }
+
+#if defined(ENABLE_JAVASE)
+       java_lang_Throwable jltcause(jlt.get_cause());
+#endif
+
+       /* print the root exception */
+
+       classinfo* c = jlt.get_Class();
+       utf_display_printable_ascii_classname(c->name);
+
+       java_lang_String jls(jlt.get_detailMessage());
+
+       if (!jls.is_null()) {
+               utf* u = javastring_toutf(jls.get_handle(), false);
+
+               printf(": ");
+               utf_display_printable_ascii(u);
+       }
+
+       putc('\n', stdout);
+
+#if defined(ENABLE_JAVASE)
+       /* print the cause if available */
+
+       // FIXME cause != t compare with operator override.
+       if ((!jltcause.is_null()) && (jltcause.get_handle() != jlt.get_handle())) {
+               printf("Caused by: ");
+
+               c = jltcause.get_Class();
+               utf_display_printable_ascii_classname(c->name);
+
+               java_lang_String jlscause(jlt.get_detailMessage());
+
+               if (jlscause.get_handle() != NULL) {
+                       utf* u = javastring_toutf(jlscause.get_handle(), false);
+
+                       printf(": ");
+                       utf_display_printable_ascii(u);
+               }
+
+               putc('\n', stdout);
+       }
+#endif
+}
+
+
+/* exceptions_print_current_exception ******************************************
+
+   Prints the current pending exception, the detail message and the
+   cause, if available, with CACAO internal functions to stdout.
+
+*******************************************************************************/
+
+void exceptions_print_current_exception(void)
+{
+       java_handle_t *o;
+
+       o = exceptions_get_exception();
+
+       exceptions_print_exception(o);
+}
+
+
+/* exceptions_print_stacktrace *************************************************
+
+   Prints a pending exception with Throwable.printStackTrace().  If
+   there happens an exception during printStackTrace(), we print the
+   thrown exception and the original one.
+
+   NOTE: This function calls Java code.
+
+*******************************************************************************/
+
+void exceptions_print_stacktrace(void)
+{
+       java_handle_t    *e;
+       java_handle_t    *ne;
+       classinfo        *c;
+       methodinfo       *m;
+
+#if defined(ENABLE_THREADS)
+       threadobject     *t;
+       java_lang_Thread *to;
+#endif
+
+       /* Get and clear exception because we are calling Java code
+          again. */
+
+       e = exceptions_get_and_clear_exception();
+
+       if (e == NULL)
+               return;
+
+#if 0
+       /* FIXME Enable me. */
+       if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
+               /* Don't print anything if we are being killed. */
+       }
+       else
+#endif
+       {
+               /* Get the exception class. */
+
+               LLNI_class_get(e, c);
+
+               /* Find the printStackTrace() method. */
+
+               m = class_resolveclassmethod(c,
+                                                                        utf_printStackTrace,
+                                                                        utf_void__void,
+                                                                        class_java_lang_Object,
+                                                                        false);
+
+               if (m == NULL)
+                       vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
+
+               /* Print message. */
+
+               fprintf(stderr, "Exception ");
+
+#if defined(ENABLE_THREADS)
+               /* Print thread name.  We get the thread here explicitly as we
+                  need it afterwards. */
+
+               t  = thread_get_current();
+               to = (java_lang_Thread *) thread_get_object(t);
+
+               if (to != NULL) {
+                       fprintf(stderr, "in thread \"");
+                       thread_fprint_name(t, stderr);
+                       fprintf(stderr, "\" ");
+               }
+#endif
+
+               /* Print the stacktrace. */
+
+               if (builtin_instanceof(e, class_java_lang_Throwable)) {
+                       (void) vm_call_method(m, e);
+
+                       /* If this happens we are EXTREMLY out of memory or have a
+                          serious problem while printStackTrace.  But may be
+                          another exception, so print it. */
+
+                       ne = exceptions_get_exception();
+
+                       if (ne != NULL) {
+                               fprintf(stderr, "Exception while printStackTrace(): ");
+
+                               /* Print the current exception. */
+
+                               exceptions_print_exception(ne);
+                               stacktrace_print_exception(ne);
+
+                               /* Now print the original exception. */
+
+                               fprintf(stderr, "Original exception was: ");
+                               exceptions_print_exception(e);
+                               stacktrace_print_exception(e);
+                       }
+               }
+               else {
+                       fprintf(stderr, ". Uncaught exception of type ");
+#if !defined(NDEBUG)
+                       /* FIXME This prints to stdout. */
+                       class_print(c);
+#else
+                       fprintf(stderr, "UNKNOWN");
+#endif
+                       fprintf(stderr, ".");
+               }
+
+               fflush(stderr);
+       }
+}
+
+} // extern "C"
+
+
+/*
+ * 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/exceptions.h b/src/vm/exceptions.h
deleted file mode 100644 (file)
index 1aea660..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* src/vm/exceptions.h - exception related functions prototypes
-
-   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 _EXCEPTIONS_H
-#define _EXCEPTIONS_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "vmcore/references.h"
-#include "vmcore/method.h"
-
-
-/* function prototypes ********************************************************/
-
-java_handle_t *exceptions_get_exception(void);
-void           exceptions_set_exception(java_handle_t *o);
-void           exceptions_clear_exception(void);
-java_handle_t *exceptions_get_and_clear_exception(void);
-
-
-/* functions to generate compiler exceptions */
-
-java_handle_t *exceptions_new_abstractmethoderror(void);
-java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra);
-java_handle_t *exceptions_new_arraystoreexception(void);
-
-void exceptions_throw_abstractmethoderror(void);
-void exceptions_throw_classcircularityerror(classinfo *c);
-void exceptions_throw_classformaterror(classinfo *c, const char *message, ...);
-void exceptions_throw_classnotfoundexception(utf *name);
-void exceptions_throw_noclassdeffounderror(utf *name);
-void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause);
-void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name);
-void exceptions_throw_linkageerror(const char *message, classinfo *c);
-void exceptions_throw_nosuchfielderror(classinfo *c, utf *name);
-void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc);
-void exceptions_throw_exceptionininitializererror(java_handle_t *cause);
-void exceptions_throw_incompatibleclasschangeerror(classinfo *c,
-                                                                                                  const char *message);
-void exceptions_throw_instantiationerror(classinfo *c);
-void exceptions_throw_internalerror(const char *message, ...);
-void exceptions_throw_outofmemoryerror(void);
-void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...);
-void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type);
-void exceptions_throw_unsatisfiedlinkerror(utf *name);
-void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi);
-
-java_handle_t *exceptions_new_arithmeticexception(void);
-
-java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index);
-void exceptions_throw_arrayindexoutofboundsexception(void);
-void exceptions_throw_arraystoreexception(void);
-
-java_handle_t *exceptions_new_classcastexception(java_handle_t *o);
-
-void exceptions_throw_clonenotsupportedexception(void);
-void exceptions_throw_illegalaccessexception(utf *message);
-void exceptions_throw_illegalargumentexception(void);
-void exceptions_throw_illegalmonitorstateexception(void);
-void exceptions_throw_interruptedexception(void);
-void exceptions_throw_instantiationexception(classinfo *c);
-void exceptions_throw_invocationtargetexception(java_handle_t *cause);
-void exceptions_throw_negativearraysizeexception(void);
-
-java_handle_t *exceptions_new_nullpointerexception(void);
-void exceptions_throw_nullpointerexception(void);
-void exceptions_throw_privilegedactionexception(java_handle_t *cause);
-void exceptions_throw_stringindexoutofboundsexception(void);
-
-java_handle_t *exceptions_fillinstacktrace(void);
-
-void exceptions_print_exception(java_handle_t *xptr);
-void exceptions_print_current_exception(void);
-void exceptions_print_stacktrace(void);
-
-#endif /* _EXCEPTIONS_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/exceptions.hpp b/src/vm/exceptions.hpp
new file mode 100644 (file)
index 0000000..355c986
--- /dev/null
@@ -0,0 +1,123 @@
+/* src/vm/exceptions.hpp - exception related functions prototypes
+
+   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 _EXCEPTIONS_HPP
+#define _EXCEPTIONS_HPP
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+#include "vm/references.h"
+#include "vm/method.h"
+
+
+/* function prototypes ********************************************************/
+
+java_handle_t *exceptions_get_exception(void);
+void           exceptions_set_exception(java_handle_t *o);
+void           exceptions_clear_exception(void);
+java_handle_t *exceptions_get_and_clear_exception(void);
+
+
+/* functions to generate compiler exceptions */
+
+java_handle_t *exceptions_new_abstractmethoderror(void);
+java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra);
+java_handle_t *exceptions_new_arraystoreexception(void);
+
+void exceptions_throw_abstractmethoderror(void);
+void exceptions_throw_classcircularityerror(classinfo *c);
+void exceptions_throw_classformaterror(classinfo *c, const char *message, ...);
+void exceptions_throw_classnotfoundexception(utf *name);
+void exceptions_throw_noclassdeffounderror(utf *name);
+void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause);
+void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name);
+void exceptions_throw_linkageerror(const char *message, classinfo *c);
+void exceptions_throw_nosuchfielderror(classinfo *c, utf *name);
+void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc);
+void exceptions_throw_exceptionininitializererror(java_handle_t *cause);
+void exceptions_throw_incompatibleclasschangeerror(classinfo *c,
+                                                                                                  const char *message);
+void exceptions_throw_instantiationerror(classinfo *c);
+void exceptions_throw_internalerror(const char *message, ...);
+void exceptions_throw_outofmemoryerror(void);
+void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...);
+void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type);
+void exceptions_throw_unsatisfiedlinkerror(utf *name);
+void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi);
+
+java_handle_t *exceptions_new_arithmeticexception(void);
+
+java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index);
+void exceptions_throw_arrayindexoutofboundsexception(void);
+void exceptions_throw_arraystoreexception(void);
+
+java_handle_t *exceptions_new_classcastexception(java_handle_t *o);
+
+void exceptions_throw_clonenotsupportedexception(void);
+void exceptions_throw_illegalaccessexception(utf *message);
+void exceptions_throw_illegalargumentexception(void);
+void exceptions_throw_illegalmonitorstateexception(void);
+void exceptions_throw_interruptedexception(void);
+void exceptions_throw_instantiationexception(classinfo *c);
+void exceptions_throw_invocationtargetexception(java_handle_t *cause);
+void exceptions_throw_negativearraysizeexception(void);
+
+java_handle_t *exceptions_new_nullpointerexception(void);
+void exceptions_throw_nullpointerexception(void);
+void exceptions_throw_privilegedactionexception(java_handle_t *cause);
+void exceptions_throw_stringindexoutofboundsexception(void);
+
+java_handle_t *exceptions_fillinstacktrace(void);
+
+void exceptions_print_exception(java_handle_t *xptr);
+void exceptions_print_current_exception(void);
+void exceptions_print_stacktrace(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _EXCEPTIONS_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:
+ */
diff --git a/src/vm/field.c b/src/vm/field.c
new file mode 100644 (file)
index 0000000..a304f31
--- /dev/null
@@ -0,0 +1,561 @@
+/* src/vm/field.c - field functions
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "vm/types.h"
+
+#include "vm/annotation.h"
+#include "vm/array.h"
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/descriptor.h"
+#include "vm/exceptions.hpp"
+#include "vm/field.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/references.h"
+#include "vm/string.hpp"
+#include "vm/suck.h"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+/* field_load ******************************************************************
+
+   Load everything about a class field from the class file and fill a
+   fieldinfo structure.
+
+*******************************************************************************/
+
+#define field_load_NOVALUE  0xffffffff /* must be bigger than any u2 value! */
+
+bool field_load(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
+{
+       classinfo *c;
+       u4 attrnum, i;
+       u4 pindex = field_load_NOVALUE;     /* constantvalue_index */
+       utf *u;
+
+       /* Get class. */
+
+       c = cb->clazz;
+
+       f->clazz = c;
+
+       /* Get access flags. */
+
+       if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
+               return false;
+
+       f->flags = suck_u2(cb);
+
+       /* Get name. */
+
+       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+               return false;
+
+       f->name = u;
+
+       /* Get descriptor. */
+
+       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+               return false;
+
+       f->descriptor = u;
+       f->parseddesc = NULL;
+
+       if (!descriptor_pool_add(descpool, u, NULL))
+               return false;
+
+       /* descriptor_pool_add accepts method descriptors, so we have to
+          check against them here before the call of
+          descriptor_to_basic_type below. */
+
+       if (u->text[0] == '(') {
+               exceptions_throw_classformaterror(c, "Method descriptor used for field");
+               return false;
+       }
+
+#ifdef ENABLE_VERIFIER
+       if (opt_verify) {
+               /* check name */
+               if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal Field name \"%s\"",
+                                                                                         f->name->text);
+                       return false;
+               }
+
+               /* check flag consistency */
+               i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
+
+               if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
+                       ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal field modifiers: 0x%X",
+                                                                                         f->flags);
+                       return false;
+               }
+
+               if (c->flags & ACC_INTERFACE) {
+                       if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
+                               != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
+                               f->flags & ACC_TRANSIENT) {
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal field modifiers: 0x%X",
+                                                                                                 f->flags);
+                               return false;
+                       }
+               }
+       }
+#endif /* ENABLE_VERIFIER */
+
+       /* data type */
+
+       f->type = descriptor_to_basic_type(f->descriptor);
+
+       /* For static-fields allocate memory for the value and set the
+          value to 0. */
+
+       if (f->flags & ACC_STATIC) {
+               switch (f->type) {
+               case TYPE_INT:
+               case TYPE_LNG:
+               case TYPE_FLT:
+               case TYPE_DBL:
+                       f->value = NEW(imm_union);
+                       break;
+
+               case TYPE_ADR:
+#if !defined(ENABLE_GC_BOEHM)
+                       f->value = NEW(imm_union);
+#else
+                       f->value = GCNEW_UNCOLLECTABLE(imm_union, 1);
+#endif
+                       break;
+
+               default:
+                       vm_abort("field_load: invalid field type %d", f->type);
+               }
+
+               /* Set the field to zero, for float and double fields set the
+                  correct 0.0 value. */
+
+               switch (f->type) {
+               case TYPE_INT:
+               case TYPE_LNG:
+               case TYPE_ADR:
+                       f->value->l = 0;
+                       break;
+
+               case TYPE_FLT:
+                       f->value->f = 0.0;
+                       break;
+
+               case TYPE_DBL:
+                       f->value->d = 0.0;
+                       break;
+               }
+       }
+       else {
+               /* For instance-fields set the offset to 0. */
+
+               f->offset = 0;
+
+               /* For final fields, which are not static, we need a value
+                  structure. */
+
+               if (f->flags & ACC_FINAL) {
+                       f->value = NEW(imm_union);
+                       /* XXX hack */
+                       f->value->l = 0;
+               }
+
+               switch (f->type) {
+               case TYPE_ADR:
+                       c->flags |= ACC_CLASS_HAS_POINTERS;
+                       break;
+               }
+       }
+
+       /* read attributes */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       attrnum = suck_u2(cb);
+
+       for (i = 0; i < attrnum; i++) {
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+                       return false;
+
+               if (u == utf_ConstantValue) {
+                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                               return false;
+
+                       /* check attribute length */
+
+                       if (suck_u4(cb) != 2) {
+                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+                               return false;
+                       }
+                       
+                       /* constant value attribute */
+
+                       if (pindex != field_load_NOVALUE) {
+                               exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
+                               return false;
+                       }
+                       
+                       /* index of value in constantpool */
+
+                       pindex = suck_u2(cb);
+               
+                       /* initialize field with value from constantpool */             
+
+                       switch (f->type) {
+                       case TYPE_INT: {
+                               constant_integer *ci; 
+
+                               if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
+                                       return false;
+
+                               f->value->i = ci->value;
+                       }
+                       break;
+                                       
+                       case TYPE_LNG: {
+                               constant_long *cl; 
+
+                               if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
+                                       return false;
+
+                               f->value->l = cl->value;
+                       }
+                       break;
+
+                       case TYPE_FLT: {
+                               constant_float *cf;
+
+                               if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
+                                       return false;
+
+                               f->value->f = cf->value;
+                       }
+                       break;
+                                                                                       
+                       case TYPE_DBL: {
+                               constant_double *cd;
+
+                               if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
+                                       return false;
+
+                               f->value->d = cd->value;
+                       }
+                       break;
+                                               
+                       case TYPE_ADR:
+                               if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
+                                       return false;
+
+                               /* Create Java-string from compressed UTF8-string. */
+
+                               f->value->a = literalstring_new(u);
+                               break;
+       
+                       default: 
+                               vm_abort("field_load: invalid field type %d", f->type);
+                       }
+               }
+#if defined(ENABLE_JAVASE)
+               else if (u == utf_Signature) {
+                       /* Signature */
+
+                       if (!loader_load_attribute_signature(cb, &(f->signature)))
+                               return false;
+               }
+
+#if defined(ENABLE_ANNOTATIONS)
+               else if (u == utf_RuntimeVisibleAnnotations) {
+                       /* RuntimeVisibleAnnotations */
+                       if (!annotation_load_field_attribute_runtimevisibleannotations(cb, f))
+                               return false;
+               }
+               else if (u == utf_RuntimeInvisibleAnnotations) {
+                       /* RuntimeInvisibleAnnotations */
+                       if (!annotation_load_field_attribute_runtimeinvisibleannotations(cb, f))
+                               return false;
+               }
+#endif
+#endif
+               else {
+                       /* unknown attribute */
+
+                       if (!loader_skip_attribute_body(cb))
+                               return false;
+               }
+       }
+
+       /* everything was ok */
+
+       return true;
+}
+
+
+/* field_get_type **************************************************************
+
+   Returns the type of the field as class.
+
+*******************************************************************************/
+
+classinfo *field_get_type(fieldinfo *f)
+{
+       typedesc  *td;
+       utf       *u;
+       classinfo *c;
+
+       td = f->parseddesc;
+
+       if (td->type == TYPE_ADR) {
+               assert(td->classref);
+
+               u = td->classref->name;
+
+               /* load the class of the field-type with the field's
+                  classloader */
+
+               c = load_class_from_classloader(u, f->clazz->classloader);
+       }
+       else {
+               c = Primitive_get_class_by_type(td->primitivetype);
+       }
+
+       return c;
+}
+
+
+/* field_free ******************************************************************
+
+   Frees a fields' resources.
+
+*******************************************************************************/
+
+void field_free(fieldinfo *f)
+{
+       /* free memory for fields which have a value */
+
+       if (f->value)
+#if defined(ENABLE_GC_BOEHM)
+               if (f->type != TYPE_ADR)
+#endif
+                       FREE(f->value, imm_union);
+}
+
+
+/* field_get_annotations ******************************************************
+
+   Get a fields' unparsed annotations in a byte array.
+
+   IN:
+       f........the field of which the annotations should be returned
+
+   RETURN VALUE:
+       The unparsed annotations in a byte array (or NULL if there aren't any).
+
+*******************************************************************************/
+
+java_handle_bytearray_t *field_get_annotations(fieldinfo *f)
+{
+#if defined(ENABLE_ANNOTATIONS)
+       classinfo               *c;           /* declaring class           */
+       int                      slot;        /* slot of this field        */
+       java_handle_bytearray_t *annotations; /* unparsed annotations      */
+       java_handle_t           *field_annotations;  /* array of unparsed  */
+                      /* annotations of all fields of the declaring class */
+
+       c           = f->clazz;
+       slot        = f - c->fields;
+       annotations = NULL;
+
+       LLNI_classinfo_field_get(c, field_annotations, field_annotations);
+
+       /* the field_annotations array might be shorter then the field
+        * count if the fields above a certain index have no annotations.
+        */
+       if (field_annotations != NULL &&
+               array_length_get(field_annotations) > slot) {
+               annotations = (java_handle_bytearray_t*)array_objectarray_element_get(
+                               (java_handle_objectarray_t*)field_annotations, slot);
+       }
+       
+       return annotations;
+#else
+       return NULL;
+#endif
+}
+
+
+/* field_printflags ************************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_printflags(fieldinfo *f)
+{
+       if (f == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       if (f->flags & ACC_PUBLIC)       printf(" PUBLIC");
+       if (f->flags & ACC_PRIVATE)      printf(" PRIVATE");
+       if (f->flags & ACC_PROTECTED)    printf(" PROTECTED");
+       if (f->flags & ACC_STATIC)       printf(" STATIC");
+       if (f->flags & ACC_FINAL)        printf(" FINAL");
+       if (f->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
+       if (f->flags & ACC_VOLATILE)     printf(" VOLATILE");
+       if (f->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
+       if (f->flags & ACC_NATIVE)       printf(" NATIVE");
+       if (f->flags & ACC_INTERFACE)    printf(" INTERFACE");
+       if (f->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
+}
+#endif
+
+
+/* field_print *****************************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_print(fieldinfo *f)
+{
+       if (f == NULL) {
+               printf("(fieldinfo*)NULL");
+               return;
+       }
+
+       utf_display_printable_ascii_classname(f->clazz->name);
+       printf(".");
+       utf_display_printable_ascii(f->name);
+       printf(" ");
+       utf_display_printable_ascii(f->descriptor);     
+
+       field_printflags(f);
+
+       if (!(f->flags & ACC_STATIC)) {
+               printf(", offset: %d", f->offset);
+       }
+}
+#endif
+
+
+/* field_println ***************************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_println(fieldinfo *f)
+{
+       field_print(f);
+       printf("\n");
+}
+#endif
+
+/* field_fieldref_print ********************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_fieldref_print(constant_FMIref *fr)
+{
+       if (fr == NULL) {
+               printf("(constant_FMIref *)NULL");
+               return;
+       }
+
+       if (IS_FMIREF_RESOLVED(fr)) {
+               printf("<field> ");
+               field_print(fr->p.field);
+       }
+       else {
+               printf("<fieldref> ");
+               utf_display_printable_ascii_classname(fr->p.classref->name);
+               printf(".");
+               utf_display_printable_ascii(fr->name);
+               printf(" ");
+               utf_display_printable_ascii(fr->descriptor);
+       }
+}
+#endif
+
+/* field_fieldref_println ******************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_fieldref_println(constant_FMIref *fr)
+{
+       field_fieldref_print(fr);
+       printf("\n");
+}
+#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/field.h b/src/vm/field.h
new file mode 100644 (file)
index 0000000..a0960c0
--- /dev/null
@@ -0,0 +1,99 @@
+/* src/vm/field.h - field functions header
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _FIELD_H
+#define _FIELD_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct fieldinfo fieldinfo; 
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/descriptor.h"
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/references.h"
+#include "vm/utf8.h"
+
+
+/* fieldinfo ******************************************************************/
+
+struct fieldinfo {           /* field of a class                                 */
+
+       /* CAUTION: The first field must be a pointer that is never the same      */
+       /*          value as CLASSREF_PSEUDO_VFTBL! This is used to check whether */
+       /*          a constant_FMIref has been resolved.                          */
+
+       classinfo *clazz;     /* needed by typechecker. Could be optimized        */
+                             /* away by using constant_FMIref instead of         */
+                             /* fieldinfo throughout the compiler.               */
+
+       s4         flags;     /* ACC flags                                        */
+       s4         type;      /* basic data type                                  */
+       utf       *name;      /* name of field                                    */
+       utf       *descriptor;/* JavaVM descriptor string of field                */
+       utf       *signature; /* Signature attribute string                       */
+       typedesc  *parseddesc;/* parsed descriptor                                */
+
+       int32_t    offset;    /* offset from start of object (instance variables) */
+       imm_union *value;     /* storage for static values (class variables)      */
+};
+
+
+/* function prototypes ********************************************************/
+
+bool       field_load(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool);
+classinfo *field_get_type(fieldinfo *f);
+void       field_free(fieldinfo *f);
+
+java_handle_bytearray_t *field_get_annotations(fieldinfo *f);
+
+#if !defined(NDEBUG)
+void field_printflags(fieldinfo *f);
+void field_print(fieldinfo *f);
+void field_println(fieldinfo *f);
+void field_fieldref_print(constant_FMIref *fr);
+void field_fieldref_println(constant_FMIref *fr);
+#endif
+
+#endif /* _FIELD_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 833efbfb127d02449d36c7d5c342e06e867df1d5..270d7eb46fbc8120b0f14387f6bc047aa871abb4 100644 (file)
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 
-#include "vmcore/options.h"
-
 
 /* global variables ***********************************************************/
 
index ca3682735d684e789419f0e440d66c8c0a92c0a8..04abf9ed0e791dd6988de54f38a2462d14057320 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/finalizer.h - finalizer linked list and thread header
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
 */
 
 
 #define _FINALIZER_H
 
 #include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/types.h"
 
 #include "vm/global.h"
@@ -47,6 +44,10 @@ bool finalizer_start_thread(void);
 void finalizer_notify(void);
 void finalizer_run(void *o, void *p);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _FINALIZER_H */
 
 
index 5d1e65bf82de057e4202d673a9baa8d102717735..a9ec8c8f9735521260e13f68e49252f7054c9f8c 100644 (file)
@@ -36,7 +36,6 @@
 
 /* additional data types ******************************************************/
 
-typedef void *voidptr;                  /* generic pointer                    */
 typedef void (*functionptr) (void);     /* generic function pointer           */
 typedef u1* methodptr;
 
@@ -207,6 +206,10 @@ typedef struct java_objectarray_t java_objectarray_t;
 #define ACC_METHOD_IMPLEMENTED 0x00020000     /* there is an implementation   */
 #define ACC_METHOD_MONOMORPHIC 0x00040000     /* currently monomorphic method */
 #define ACC_METHOD_EA          0x00080000     /* method being escape analyzed */
+#define ACC_METHOD_MONOMORPHY_USED \
+                               0x00100000
+#define ACC_METHOD_PARENT_MONOMORPHY_USED \
+                               0x00200000
 
 
 /* data structures of the runtime system **************************************/
diff --git a/src/vm/globals.cpp b/src/vm/globals.cpp
new file mode 100644 (file)
index 0000000..cb72176
--- /dev/null
@@ -0,0 +1,124 @@
+/* src/vm/globals.cpp - global variables
+
+   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.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/class.h"
+
+
+// Classes.
+
+/* Important system classes. */
+
+classinfo *class_java_lang_Object;
+classinfo *class_java_lang_Class;
+classinfo *class_java_lang_ClassLoader;
+classinfo *class_java_lang_Cloneable;
+classinfo *class_java_lang_SecurityManager;
+classinfo *class_java_lang_String;
+classinfo *class_java_lang_System;
+classinfo *class_java_lang_Thread;
+classinfo *class_java_lang_ThreadGroup;
+classinfo *class_java_lang_Throwable;
+classinfo *class_java_io_Serializable;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+classinfo *class_java_lang_VMSystem;
+classinfo *class_java_lang_VMThread;
+classinfo *class_java_lang_VMThrowable;
+#endif
+
+/* Important system exceptions. */
+
+classinfo *class_java_lang_Exception;
+classinfo *class_java_lang_ClassNotFoundException;
+classinfo *class_java_lang_RuntimeException;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+classinfo *class_sun_misc_Signal;
+classinfo *class_sun_reflect_MagicAccessorImpl;
+#endif
+
+#if defined(ENABLE_JAVASE)
+classinfo *class_java_lang_Void;
+#endif
+classinfo *class_java_lang_Boolean;
+classinfo *class_java_lang_Byte;
+classinfo *class_java_lang_Character;
+classinfo *class_java_lang_Short;
+classinfo *class_java_lang_Integer;
+classinfo *class_java_lang_Long;
+classinfo *class_java_lang_Float;
+classinfo *class_java_lang_Double;
+
+/* some classes which may be used more often */
+
+#if defined(ENABLE_JAVASE)
+classinfo *class_java_lang_StackTraceElement;
+classinfo *class_java_lang_reflect_Constructor;
+classinfo *class_java_lang_reflect_Field;
+classinfo *class_java_lang_reflect_Method;
+classinfo *class_java_security_PrivilegedAction;
+classinfo *class_java_util_Vector;
+classinfo *class_java_util_HashMap;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+classinfo *class_java_lang_reflect_VMConstructor;
+classinfo *class_java_lang_reflect_VMField;
+classinfo *class_java_lang_reflect_VMMethod;
+# endif
+
+classinfo *arrayclass_java_lang_Object;
+
+# if defined(ENABLE_ANNOTATIONS)
+classinfo *class_sun_reflect_ConstantPool;
+#  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+classinfo *class_sun_reflect_annotation_AnnotationParser;
+#  endif
+# endif
+#endif
+
+/* pseudo classes for the typechecker */
+
+classinfo *pseudo_class_Arraystub;
+classinfo *pseudo_class_Null;
+classinfo *pseudo_class_New;
+
+
+/*
+ * 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/globals.hpp b/src/vm/globals.hpp
new file mode 100644 (file)
index 0000000..5ddf1cb
--- /dev/null
@@ -0,0 +1,160 @@
+/* src/vm/globals.hpp - global variables
+
+   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.
+
+*/
+
+
+#ifndef _GLOBALS_HPP
+#define _GLOBALS_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/class.h"
+
+
+// FIXME For now we export them a C symbols.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Classes.
+
+/* Important system classes. */
+
+extern classinfo *class_java_lang_Object;
+extern classinfo *class_java_lang_Class;
+extern classinfo *class_java_lang_ClassLoader;
+extern classinfo *class_java_lang_Cloneable;
+extern classinfo *class_java_lang_SecurityManager;
+extern classinfo *class_java_lang_String;
+extern classinfo *class_java_lang_System;
+extern classinfo *class_java_lang_Thread;
+extern classinfo *class_java_lang_ThreadGroup;
+extern classinfo *class_java_lang_Throwable;
+extern classinfo *class_java_io_Serializable;
+
+/* Important system exceptions. */
+
+extern classinfo *class_java_lang_Exception;
+extern classinfo *class_java_lang_ClassNotFoundException;
+extern classinfo *class_java_lang_RuntimeException;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+extern classinfo *class_java_lang_VMSystem;
+extern classinfo *class_java_lang_VMThread;
+extern classinfo *class_java_lang_VMThrowable;
+#endif
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+extern classinfo *class_sun_misc_Signal;
+extern classinfo *class_sun_reflect_MagicAccessorImpl;
+#endif
+
+#if defined(ENABLE_JAVASE)
+extern classinfo *class_java_lang_Void;
+#endif
+
+extern classinfo *class_java_lang_Boolean;
+extern classinfo *class_java_lang_Byte;
+extern classinfo *class_java_lang_Character;
+extern classinfo *class_java_lang_Short;
+extern classinfo *class_java_lang_Integer;
+extern classinfo *class_java_lang_Long;
+extern classinfo *class_java_lang_Float;
+extern classinfo *class_java_lang_Double;
+
+/* some classes which may be used more often */
+
+#if defined(ENABLE_JAVASE)
+extern classinfo *class_java_lang_StackTraceElement;
+extern classinfo *class_java_lang_reflect_Constructor;
+extern classinfo *class_java_lang_reflect_Field;
+extern classinfo *class_java_lang_reflect_Method;
+extern classinfo *class_java_security_PrivilegedAction;
+extern classinfo *class_java_util_Vector;
+extern classinfo *class_java_util_HashMap;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+extern classinfo *class_java_lang_reflect_VMConstructor;
+extern classinfo *class_java_lang_reflect_VMField;
+extern classinfo *class_java_lang_reflect_VMMethod;
+# endif
+
+extern classinfo *arrayclass_java_lang_Object;
+
+# if defined(ENABLE_ANNOTATIONS)
+extern classinfo *class_sun_reflect_ConstantPool;
+#  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+extern classinfo *class_sun_reflect_annotation_AnnotationParser;
+#  endif
+# endif
+#endif
+
+
+/* pseudo classes for the type checker ****************************************/
+
+/*
+ * pseudo_class_Arraystub
+ *     (extends Object implements Cloneable, java.io.Serializable)
+ *
+ *     If two arrays of incompatible component types are merged,
+ *     the resulting reference has no accessible components.
+ *     The result does, however, implement the interfaces Cloneable
+ *     and java.io.Serializable. This pseudo class is used internally
+ *     to represent such results. (They are *not* considered arrays!)
+ *
+ * pseudo_class_Null
+ *
+ *     This pseudo class is used internally to represent the
+ *     null type.
+ *
+ * pseudo_class_New
+ *
+ *     This pseudo class is used internally to represent the
+ *     the 'uninitialized object' type.
+ */
+
+extern classinfo *pseudo_class_Arraystub;
+extern classinfo *pseudo_class_Null;
+extern classinfo *pseudo_class_New;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CLASS_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:
+ */
index 6e0c10838155bac944f8427877302f4069f1a282..82d9a749e72b762cbb241cc90813a143793ec0ff 100644 (file)
 
 #include "threads/lock-common.h"
 
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
+#include "vm/globals.hpp"
 #include "vm/initialize.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/asmpart.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
+# include "vm/statistics.h"
 #endif
 
+#include "vm/jit/asmpart.h"
+
 
 /* private functions **********************************************************/
 
index 431c1c8d846eb3fb8d4c04733813aec3ce7441b5..88a7ff55428b948993965df3fb93e7b54e21b723 100644 (file)
 
 #include "config.h"
 
-#include "vm/global.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-#include "vmcore/class.h"
+#include "vm/class.h"
+#include "vm/global.h"
 
 
 /* function prototypes ********************************************************/
 void initialize_init(void);
 bool initialize_class(classinfo *c);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _INITIALIZE_H */
 
 
diff --git a/src/vm/javaobjects.cpp b/src/vm/javaobjects.cpp
new file mode 100644 (file)
index 0000000..904063f
--- /dev/null
@@ -0,0 +1,146 @@
+/* src/vm/javaobjects.cpp - functions to create and access Java objects
+
+   Copyright (C) 2008 Theobroma Systems Ltd.
+
+   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 <stdint.h>
+
+#include "native/vm/reflection.hpp"
+
+#include "vm/access.h"
+#include "vm/builtin.h"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/javaobjects.hpp"
+
+
+#if defined(ENABLE_JAVASE)
+
+/**
+ * Constructs a Java object with the given
+ * java.lang.reflect.Constructor.
+ *
+ * @param args     Constructor arguments.
+ *
+ * @return Handle to Java object.
+ */
+java_handle_t* java_lang_reflect_Constructor::new_instance(java_handle_objectarray_t* args)
+{
+       methodinfo* m = get_method();
+
+       // Should we bypass security the checks (AccessibleObject)?
+       if (get_override() == false) {
+               /* This method is always called like this:
+                      [0] java.lang.reflect.Constructor.constructNative (Native Method)
+                      [1] java.lang.reflect.Constructor.newInstance
+                      [2] <caller>
+               */
+
+               if (!access_check_method(m, 2))
+                       return NULL;
+       }
+
+       // Create a Java object.
+       java_handle_t* h = builtin_new(m->clazz);
+
+       if (h == NULL)
+               return NULL;
+        
+       // Call initializer.
+       (void) Reflection::invoke(m, h, args);
+
+       return h;
+}
+
+
+/**
+ * Invokes the given method.
+ *
+ * @param args Method arguments.
+ *
+ * @return return value of the method
+ */
+java_handle_t* java_lang_reflect_Method::invoke(java_handle_t* o, java_handle_objectarray_t* args)
+{
+       methodinfo* m = get_method();
+
+       // Should we bypass security the checks (AccessibleObject)?
+       if (get_override() == false) {
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+               /* This method is always called like this:
+                      [0] java.lang.reflect.Method.invokeNative (Native Method)
+                      [1] java.lang.reflect.Method.invoke (Method.java:329)
+                      [2] <caller>
+               */
+
+               if (!access_check_method(m, 2))
+                       return NULL;
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+               /* We only pass 1 here as stacktrace_get_caller_class, which
+                  is called from access_check_method, skips
+                  java.lang.reflect.Method.invoke(). */
+
+               if (!access_check_method(m, 1))
+                       return NULL;
+#else
+# error unknown classpath configuration
+#endif
+       }
+
+       // Check if method class is initialized.
+       if (!(m->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(m->clazz))
+                       return NULL;
+
+       // Call the Java method.
+       java_handle_t* result = Reflection::invoke(m, o, args);
+
+       return result;
+}
+
+
+// Legacy C interface.
+
+extern "C" {
+       java_handle_t* java_lang_reflect_Constructor_create(methodinfo* m) { return java_lang_reflect_Constructor(m).get_handle(); }
+       java_handle_t* java_lang_reflect_Field_create(fieldinfo* f) { return java_lang_reflect_Field(f).get_handle(); }
+       java_handle_t* java_lang_reflect_Method_create(methodinfo* m) { return java_lang_reflect_Method(m).get_handle(); }
+}
+
+#endif // ENABLE_JAVASE
+
+
+/*
+ * 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/javaobjects.hpp b/src/vm/javaobjects.hpp
new file mode 100644 (file)
index 0000000..7253e44
--- /dev/null
@@ -0,0 +1,2939 @@
+/* src/vm/javaobjects.hpp - functions to create and access Java objects
+
+   Copyright (C) 2008 Theobroma Systems Ltd.
+
+   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 _JAVAOBJECTS_HPP
+#define _JAVAOBJECTS_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "vm/class.h"
+#include "vm/field.h"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/method.h"
+
+
+#ifdef __cplusplus
+
+/**
+ * This class provides low-level functions to access Java object
+ * instance fields.
+ *
+ * These functions do NOT take care about the GC critical section!
+ * Please use FieldAccess wherever possible.
+ */
+class RawFieldAccess {
+protected:
+       template<class T> static inline T    raw_get(void* address, const off_t offset);
+       template<class T> static inline void raw_set(void* address, const off_t offset, T value);
+};
+
+
+template<class T> inline T RawFieldAccess::raw_get(void* address, const off_t offset)
+{
+       T* p = (T*) (((uintptr_t) address) + offset);
+       return *p;
+}
+
+
+template<class T> inline void RawFieldAccess::raw_set(void* address, const off_t offset, T value)
+{
+       T* p = (T*) (((uintptr_t) address) + offset);
+       *p = value;
+}
+
+
+/**
+ * This classes provides functions to access Java object instance
+ * fields.  These functions enter a critical GC section before
+ * accessing the Java object throught the handle and leave it
+ * afterwards.
+ */
+class FieldAccess : private RawFieldAccess {
+protected:
+       template<class T> static inline T    get(java_handle_t* h, const off_t offset);
+       template<class T> static inline void set(java_handle_t* h, const off_t offset, T value);
+};
+
+template<class T> inline T FieldAccess::get(java_handle_t* h, const off_t offset)
+{
+       java_object_t* o;
+       T result;
+               
+       // XXX Move this to a GC inline function, e.g.
+       // gc->enter_critical();
+       LLNI_CRITICAL_START;
+
+       // XXX This should be _handle->get_object();
+       o = LLNI_UNWRAP(h);
+
+       result = raw_get<T>(o, offset);
+
+       // XXX Move this to a GC inline function.
+       // gc->leave_critical();
+       LLNI_CRITICAL_END;
+
+       return result;
+}      
+
+template<> inline java_handle_t* FieldAccess::get(java_handle_t* h, const off_t offset)
+{
+       java_object_t* o;
+       java_object_t* result;
+       java_handle_t* hresult;
+               
+       // XXX Move this to a GC inline function, e.g.
+       // gc->enter_critical();
+       LLNI_CRITICAL_START;
+
+       // XXX This should be _handle->get_object();
+       o = LLNI_UNWRAP(h);
+
+       result = raw_get<java_object_t*>(o, offset);
+
+       hresult = LLNI_WRAP(result);
+
+       // XXX Move this to a GC inline function.
+       // gc->leave_critical();
+       LLNI_CRITICAL_END;
+
+       return result;
+}      
+
+
+template<class T> inline void FieldAccess::set(java_handle_t* h, const off_t offset, T value)
+{
+       java_object_t* o;
+
+       // XXX Move this to a GC inline function, e.g.
+       // gc->enter_critical();
+       LLNI_CRITICAL_START;
+
+       // XXX This should be h->get_object();
+       o = LLNI_UNWRAP(h);
+
+       raw_set(o, offset, value);
+
+       // XXX Move this to a GC inline function.
+       // gc->leave_critical();
+       LLNI_CRITICAL_END;
+}
+
+template<> inline void FieldAccess::set<java_handle_t*>(java_handle_t* h, const off_t offset, java_handle_t* value)
+{
+       java_object_t* o;
+       java_object_t* ovalue;
+
+       // XXX Move this to a GC inline function, e.g.
+       // gc->enter_critical();
+       LLNI_CRITICAL_START;
+
+       // XXX This should be h->get_object();
+       o      = LLNI_UNWRAP(h);
+       ovalue = LLNI_UNWRAP(value);
+
+       raw_set(o, offset, ovalue);
+
+       // XXX Move this to a GC inline function.
+       // gc->leave_critical();
+       LLNI_CRITICAL_END;
+}
+
+
+/**
+ * java/lang/Object
+ *
+ * Object layout:
+ *
+ * 0. object header
+ */
+class java_lang_Object {
+protected:
+       // Handle of Java object.
+       java_handle_t* _handle;
+
+protected:
+       java_lang_Object() : _handle(NULL) {}
+       java_lang_Object(java_handle_t* h) : _handle(h) {}
+       java_lang_Object(jobject h) : _handle((java_handle_t*) h) {}
+       virtual ~java_lang_Object() {}
+
+public:
+       // Getters.
+       virtual inline java_handle_t* get_handle() const { return _handle; }
+       inline vftbl_t*               get_vftbl () const;
+       inline classinfo*             get_Class () const;
+
+       inline bool is_null    () const;
+       inline bool is_non_null() const;
+};
+
+
+inline vftbl_t* java_lang_Object::get_vftbl() const
+{
+       // XXX Move this to a GC inline function, e.g.
+       // gc->enter_critical();
+       LLNI_CRITICAL_START;
+
+       // XXX This should be h->get_object();
+       java_object_t* o = LLNI_UNWRAP(_handle);
+       vftbl_t* vftbl = o->vftbl;
+
+       // XXX Move this to a GC inline function.
+       // gc->leave_critical();
+       LLNI_CRITICAL_END;
+
+       return vftbl;
+}
+
+inline classinfo* java_lang_Object::get_Class() const
+{
+       return get_vftbl()->clazz;
+}
+
+
+inline bool java_lang_Object::is_null() const
+{
+       return (_handle == NULL);
+}
+
+inline bool java_lang_Object::is_non_null() const
+{
+       return (_handle != NULL);
+}
+
+
+/**
+ * java/lang/Boolean
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. boolean value;
+ */
+class java_lang_Boolean : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value = MEMORY_ALIGN(sizeof(java_object_t), sizeof(int32_t));
+
+public:
+       java_lang_Boolean(java_handle_t* h) : java_lang_Object(h) {}
+
+       inline uint8_t get_value();
+       inline void    set_value(uint8_t value);
+};
+
+inline uint8_t java_lang_Boolean::get_value()
+{
+       return get<int32_t>(_handle, offset_value);
+}
+
+inline void java_lang_Boolean::set_value(uint8_t value)
+{
+       set(_handle, offset_value, (uint32_t) value);
+}
+
+
+/**
+ * java/lang/Byte
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. byte value;
+ */
+class java_lang_Byte : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value = MEMORY_ALIGN(sizeof(java_object_t), sizeof(int32_t));
+
+public:
+       java_lang_Byte(java_handle_t* h) : java_lang_Object(h) {}
+
+       inline int8_t get_value();
+       inline void   set_value(int8_t value);
+};
+
+inline int8_t java_lang_Byte::get_value()
+{
+       return get<int32_t>(_handle, offset_value);
+}
+
+inline void java_lang_Byte::set_value(int8_t value)
+{
+       set(_handle, offset_value, (int32_t) value);
+}
+
+
+/**
+ * java/lang/Character
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. char value;
+ */
+class java_lang_Character : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value = MEMORY_ALIGN(sizeof(java_object_t), sizeof(int32_t));
+
+public:
+       java_lang_Character(java_handle_t* h) : java_lang_Object(h) {}
+
+       inline uint16_t get_value();
+       inline void     set_value(uint16_t value);
+};
+
+inline uint16_t java_lang_Character::get_value()
+{
+       return get<int32_t>(_handle, offset_value);
+}
+
+inline void java_lang_Character::set_value(uint16_t value)
+{
+       set(_handle, offset_value, (uint32_t) value);
+}
+
+
+/**
+ * java/lang/Short
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. short value;
+ */
+class java_lang_Short : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value = MEMORY_ALIGN(sizeof(java_object_t), sizeof(int32_t));
+
+public:
+       java_lang_Short(java_handle_t* h) : java_lang_Object(h) {}
+
+       inline int16_t get_value();
+       inline void    set_value(int16_t value);
+};
+
+inline int16_t java_lang_Short::get_value()
+{
+       return get<int32_t>(_handle, offset_value);
+}
+
+inline void java_lang_Short::set_value(int16_t value)
+{
+       set(_handle, offset_value, (int32_t) value);
+}
+
+
+/**
+ * java/lang/Integer
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. int value;
+ */
+class java_lang_Integer : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value = MEMORY_ALIGN(sizeof(java_object_t), sizeof(int32_t));
+
+public:
+       java_lang_Integer(java_handle_t* h) : java_lang_Object(h) {}
+
+       inline int32_t get_value();
+       inline void    set_value(int32_t value);
+};
+
+inline int32_t java_lang_Integer::get_value()
+{
+       return get<int32_t>(_handle, offset_value);
+}
+
+inline void java_lang_Integer::set_value(int32_t value)
+{
+       set(_handle, offset_value, value);
+}
+
+
+/**
+ * java/lang/Long
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. long value;
+ */
+class java_lang_Long : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value = MEMORY_ALIGN(sizeof(java_object_t), sizeof(int64_t));
+
+public:
+       java_lang_Long(java_handle_t* h) : java_lang_Object(h) {}
+
+       inline int64_t get_value();
+       inline void    set_value(int64_t value);
+};
+
+inline int64_t java_lang_Long::get_value()
+{
+       return get<int64_t>(_handle, offset_value);
+}
+
+inline void java_lang_Long::set_value(int64_t value)
+{
+       set(_handle, offset_value, value);
+}
+
+
+/**
+ * java/lang/Float
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. float value;
+ */
+class java_lang_Float : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value = MEMORY_ALIGN(sizeof(java_object_t), sizeof(float));
+
+public:
+       java_lang_Float(java_handle_t* h) : java_lang_Object(h) {}
+
+       inline float get_value();
+       inline void  set_value(float value);
+};
+
+inline float java_lang_Float::get_value()
+{
+       return get<float>(_handle, offset_value);
+}
+
+inline void java_lang_Float::set_value(float value)
+{
+       set(_handle, offset_value, value);
+}
+
+
+/**
+ * java/lang/Double
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. double value;
+ */
+class java_lang_Double : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value = MEMORY_ALIGN(sizeof(java_object_t), sizeof(double));
+
+public:
+       java_lang_Double(java_handle_t* h) : java_lang_Object(h) {}
+
+       inline double get_value();
+       inline void   set_value(double value);
+};
+
+inline double java_lang_Double::get_value()
+{
+       return get<double>(_handle, offset_value);
+}
+
+inline void java_lang_Double::set_value(double value)
+{
+       set(_handle, offset_value, value);
+}
+
+
+#if defined(ENABLE_JAVASE)
+
+# if defined(ENABLE_ANNOTATIONS)
+/**
+ * OpenJDK sun/reflect/ConstantPool
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.Object constantPoolOop;
+ */
+class sun_reflect_ConstantPool : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_constantPoolOop = MEMORY_ALIGN(sizeof(java_object_t), SIZEOF_VOID_P);
+
+public:
+       sun_reflect_ConstantPool(java_handle_t* h) : java_lang_Object(h) {}
+       sun_reflect_ConstantPool(java_handle_t* h, jclass constantPoolOop);
+
+       // Setters.
+       inline void set_constantPoolOop(classinfo* value);
+       inline void set_constantPoolOop(jclass value);
+};
+
+
+inline sun_reflect_ConstantPool::sun_reflect_ConstantPool(java_handle_t* h, jclass constantPoolOop) : java_lang_Object(h)
+{
+       set_constantPoolOop(constantPoolOop);
+}
+
+
+inline void sun_reflect_ConstantPool::set_constantPoolOop(classinfo* value)
+{
+       set(_handle, offset_constantPoolOop, value);
+}
+
+inline void sun_reflect_ConstantPool::set_constantPoolOop(jclass value)
+{
+       // XXX jclass is a boxed object.
+       set_constantPoolOop(LLNI_classinfo_unwrap(value));
+}
+# endif // ENABLE_ANNOTATIONS
+
+#endif // ENABLE_JAVASE
+
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+/**
+ * GNU Classpath java/lang/Class
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.Object[]             signers;
+ * 2. java.security.ProtectionDomain pd;
+ * 3. java.lang.Object               vmdata;
+ * 4. java.lang.reflect.Constructor  constructor;
+ */
+class java_lang_Class : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_signers     = MEMORY_ALIGN(sizeof(java_object_t),          SIZEOF_VOID_P);
+       static const off_t offset_pd          = MEMORY_ALIGN(offset_signers + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_vmdata      = MEMORY_ALIGN(offset_pd      + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_constructor = MEMORY_ALIGN(offset_vmdata  + SIZEOF_VOID_P, SIZEOF_VOID_P);
+
+public:
+       java_lang_Class(java_handle_t* h) : java_lang_Object(h) {}
+
+       // Setters.
+       inline void set_pd(java_handle_t* value);
+       inline void set_pd(jobject value);
+};
+
+inline void java_lang_Class::set_pd(java_handle_t* value)
+{
+       set(_handle, offset_pd, value);
+}
+
+inline void java_lang_Class::set_pd(jobject value)
+{
+       set_pd((java_handle_t*) value);
+}
+
+
+/**
+ * GNU Classpath java/lang/StackTraceElement
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.String fileName;
+ * 2. int              lineNumber;
+ * 3. java.lang.String declaringClass;
+ * 4. java.lang.String methodName;
+ * 5. boolean          isNative;
+ */
+class java_lang_StackTraceElement : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_fileName       = MEMORY_ALIGN(sizeof(java_object_t),                   SIZEOF_VOID_P);
+       static const off_t offset_lineNumber     = MEMORY_ALIGN(offset_fileName       + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_declaringClass = MEMORY_ALIGN(offset_lineNumber     + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_methodName     = MEMORY_ALIGN(offset_declaringClass + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_isNative       = MEMORY_ALIGN(offset_methodName     + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_StackTraceElement(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_StackTraceElement(java_handle_t* h, java_handle_t* fileName, int32_t lineNumber, java_handle_t* declaringClass, java_handle_t* methodName, uint8_t isNative);
+};
+
+inline java_lang_StackTraceElement::java_lang_StackTraceElement(java_handle_t* h, java_handle_t* fileName, int32_t lineNumber, java_handle_t* declaringClass, java_handle_t* methodName, uint8_t isNative) : java_lang_Object(h)
+{
+       java_lang_StackTraceElement((java_handle_t*) h);
+
+       set(_handle, offset_fileName,       fileName);
+       set(_handle, offset_lineNumber,     lineNumber);
+       set(_handle, offset_declaringClass, declaringClass);
+       set(_handle, offset_methodName,     methodName);
+       set(_handle, offset_isNative,       isNative);
+}
+
+
+/**
+ * GNU Classpath java/lang/String
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. char[] value;
+ * 2. int    count;
+ * 3. int    cachedHashCode;
+ * 4. int    offset;
+ */
+class java_lang_String : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value          = MEMORY_ALIGN(sizeof(java_object_t),                   SIZEOF_VOID_P);
+       static const off_t offset_count          = MEMORY_ALIGN(offset_value          + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_cachedHashCode = MEMORY_ALIGN(offset_count          + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_offset         = MEMORY_ALIGN(offset_cachedHashCode + sizeof(int32_t), sizeof(int32_t));
+
+public:
+       java_lang_String(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_String(jstring h);
+       java_lang_String(java_handle_t* h, java_handle_chararray_t* value, int32_t count, int32_t offset = 0);
+
+       // Getters.
+       inline java_handle_chararray_t* get_value () const;
+       inline int32_t                  get_count () const;
+       inline int32_t                  get_offset() const;
+
+       // Setters.
+       inline void set_value (java_handle_chararray_t* value);
+       inline void set_count (int32_t value);
+       inline void set_offset(int32_t value);
+};
+
+inline java_lang_String::java_lang_String(jstring h) : java_lang_Object(h)
+{
+       java_lang_String((java_handle_t*) h);
+}
+
+inline java_lang_String::java_lang_String(java_handle_t* h, java_handle_chararray_t* value, int32_t count, int32_t offset) : java_lang_Object(h)
+{
+       set_value(value);
+       set_count(count);
+       set_offset(offset);
+}
+
+inline java_handle_chararray_t* java_lang_String::get_value() const
+{
+       return get<java_handle_chararray_t*>(_handle, offset_value);
+}
+
+inline int32_t java_lang_String::get_count() const
+{
+       return get<int32_t>(_handle, offset_count);
+}
+
+inline int32_t java_lang_String::get_offset() const
+{
+       return get<int32_t>(_handle, offset_offset);
+}
+
+inline void java_lang_String::set_value(java_handle_chararray_t* value)
+{
+       set(_handle, offset_value, value);
+}
+
+inline void java_lang_String::set_count(int32_t value)
+{
+       set(_handle, offset_count, value);
+}
+
+inline void java_lang_String::set_offset(int32_t value)
+{
+       set(_handle, offset_offset, value);
+}
+
+
+/**
+ * GNU Classpath java/lang/Thread
+ *
+ * Object layout:
+ *
+ *  0. object header
+ *  1. java.lang.VMThread                        vmThread;
+ *  2. java.lang.ThreadGroup                     group;
+ *  3. java.lang.Runnable                        runnable;
+ *  4. java.lang.String                          name;
+ *  5. boolean                                   daemon;
+ *  6. int                                       priority;
+ *  7. long                                      stacksize;
+ *  8. java.lang.Throwable                       stillborn;
+ *  9. java.lang.ClassLoader                     contextClassLoader;
+ * 10. boolean                                   contextClassLoaderIsSystemClassLoader;
+ * 11. long                                      threadId;
+ * 12. java.lang.Object                          parkBlocker;
+ * 13. gnu.java.util.WeakIdentityHashMap         locals;
+ * 14. java_lang_Thread_UncaughtExceptionHandler exceptionHandler;
+ */
+class java_lang_Thread : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_vmThread                              = MEMORY_ALIGN(sizeof(java_object_t),                                          SIZEOF_VOID_P);
+       static const off_t offset_group                                 = MEMORY_ALIGN(offset_vmThread                              + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_runnable                              = MEMORY_ALIGN(offset_group                                 + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_name                                  = MEMORY_ALIGN(offset_runnable                              + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_daemon                                = MEMORY_ALIGN(offset_name                                  + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_priority                              = MEMORY_ALIGN(offset_daemon                                + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_stacksize                             = MEMORY_ALIGN(offset_priority                              + sizeof(int32_t), sizeof(int64_t));
+       static const off_t offset_stillborn                             = MEMORY_ALIGN(offset_stacksize                             + sizeof(int64_t), SIZEOF_VOID_P);
+       static const off_t offset_contextClassLoader                    = MEMORY_ALIGN(offset_stillborn                             + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_contextClassLoaderIsSystemClassLoader = MEMORY_ALIGN(offset_contextClassLoader                    + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_threadId                              = MEMORY_ALIGN(offset_contextClassLoaderIsSystemClassLoader + sizeof(int32_t), sizeof(int64_t));
+       static const off_t offset_parkBlocker                           = MEMORY_ALIGN(offset_threadId                              + sizeof(int64_t), SIZEOF_VOID_P);
+       static const off_t offset_locals                                = MEMORY_ALIGN(offset_parkBlocker                           + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_exceptionHandler                      = MEMORY_ALIGN(offset_locals                                + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_Thread(java_handle_t* h) : java_lang_Object(h) {}
+//     java_lang_Thread(threadobject* t);
+
+       // Getters.
+       inline java_handle_t* get_vmThread        () const;
+       inline java_handle_t* get_group           () const;
+       inline java_handle_t* get_name            () const;
+       inline int32_t        get_daemon          () const;
+       inline int32_t        get_priority        () const;
+       inline java_handle_t* get_exceptionHandler() const;
+
+       // Setters.
+       inline void set_group(java_handle_t* value);
+};
+
+
+// inline java_lang_Thread::java_lang_Thread(threadobject* t) : java_lang_Object(h)
+// {
+//     java_lang_Thread(thread_get_object(t));
+// }
+
+
+inline java_handle_t* java_lang_Thread::get_vmThread() const
+{
+       return get<java_handle_t*>(_handle, offset_vmThread);
+}
+
+inline java_handle_t* java_lang_Thread::get_group() const
+{
+       return get<java_handle_t*>(_handle, offset_group);
+}
+
+inline java_handle_t* java_lang_Thread::get_name() const
+{
+       return get<java_handle_t*>(_handle, offset_name);
+}
+
+inline int32_t java_lang_Thread::get_daemon() const
+{
+       return get<int32_t>(_handle, offset_daemon);
+}
+
+inline int32_t java_lang_Thread::get_priority() const
+{
+       return get<int32_t>(_handle, offset_priority);
+}
+
+inline java_handle_t* java_lang_Thread::get_exceptionHandler() const
+{
+       return get<java_handle_t*>(_handle, offset_exceptionHandler);
+}
+
+
+inline void java_lang_Thread::set_group(java_handle_t* value)
+{
+       set(_handle, offset_group, value);
+}
+
+
+/**
+ * GNU Classpath java/lang/VMThread
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.Thread   thread;
+ * 2. boolean            running;
+ * 3. java.lang.VMThread vmdata;
+ */
+class java_lang_VMThread : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_thread  = MEMORY_ALIGN(sizeof(java_object_t),            SIZEOF_VOID_P);
+       static const off_t offset_running = MEMORY_ALIGN(offset_thread  + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_vmdata  = MEMORY_ALIGN(offset_running + sizeof(int32_t), SIZEOF_VOID_P);
+
+public:
+       java_lang_VMThread(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_VMThread(jobject h);
+       java_lang_VMThread(java_handle_t* h, java_handle_t* thread, threadobject* vmdata);
+
+       // Getters.
+       inline java_handle_t* get_thread() const;
+       inline threadobject*  get_vmdata() const;
+
+       // Setters.
+       inline void set_thread(java_handle_t* value);
+       inline void set_vmdata(threadobject* value);
+};
+
+
+inline java_lang_VMThread::java_lang_VMThread(jobject h) : java_lang_Object(h)
+{
+       java_lang_VMThread((java_handle_t*) h);
+}
+
+inline java_lang_VMThread::java_lang_VMThread(java_handle_t* h, java_handle_t* thread, threadobject* vmdata) : java_lang_Object(h)
+{
+       set_thread(thread);
+       set_vmdata(vmdata);
+}
+
+
+inline java_handle_t* java_lang_VMThread::get_thread() const
+{
+       return get<java_handle_t*>(_handle, offset_thread);
+}
+
+inline threadobject* java_lang_VMThread::get_vmdata() const
+{
+       return get<threadobject*>(_handle, offset_vmdata);
+}
+
+
+inline void java_lang_VMThread::set_thread(java_handle_t* value)
+{
+       set(_handle, offset_thread, value);
+}
+
+inline void java_lang_VMThread::set_vmdata(threadobject* value)
+{
+       set(_handle, offset_vmdata, value);
+}
+
+
+/**
+ * GNU Classpath java/lang/Throwable
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.String              detailMessage;
+ * 2. java.lang.Throwable           cause;
+ * 3. java.lang.StackTraceElement[] stackTrace;
+ * 4. java.lang.VMThrowable         vmState;
+ */
+class java_lang_Throwable : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_detailMessage = MEMORY_ALIGN(sizeof(java_object_t),                SIZEOF_VOID_P);
+       static const off_t offset_cause         = MEMORY_ALIGN(offset_detailMessage + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_stackTrace    = MEMORY_ALIGN(offset_cause         + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_vmState       = MEMORY_ALIGN(offset_stackTrace    + SIZEOF_VOID_P, SIZEOF_VOID_P);
+
+public:
+       java_lang_Throwable(java_handle_t* h) : java_lang_Object(h) {}
+
+       // Getters.
+       inline java_handle_t* get_detailMessage() const;
+       inline java_handle_t* get_cause        () const;
+       inline java_handle_t* get_vmState      () const;
+};
+
+
+inline java_handle_t* java_lang_Throwable::get_detailMessage() const
+{
+       return get<java_handle_t*>(_handle, offset_detailMessage);
+}
+
+inline java_handle_t* java_lang_Throwable::get_cause() const
+{
+       return get<java_handle_t*>(_handle, offset_cause);
+}
+
+inline java_handle_t* java_lang_Throwable::get_vmState() const
+{
+       return get<java_handle_t*>(_handle, offset_vmState);
+}
+
+
+/**
+ * GNU Classpath java/lang/VMThrowable
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.Object vmdata;
+ */
+class java_lang_VMThrowable : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_vmdata = MEMORY_ALIGN(sizeof(java_object_t), SIZEOF_VOID_P);
+
+public:
+       java_lang_VMThrowable(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_VMThrowable(jobject h);
+
+       inline java_handle_bytearray_t* get_vmdata() const;
+       inline void                     set_vmdata(java_handle_bytearray_t* value);
+};
+
+inline java_lang_VMThrowable::java_lang_VMThrowable(jobject h) : java_lang_Object(h)
+{
+       java_lang_VMThrowable((java_handle_t*) h);
+}
+
+inline java_handle_bytearray_t* java_lang_VMThrowable::get_vmdata() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_vmdata);
+}
+
+inline void java_lang_VMThrowable::set_vmdata(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_vmdata, value);
+}
+
+
+/**
+ * GNU Classpath java/lang/reflect/VMConstructor
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.Class               clazz;
+ * 2. int                           slot;
+ * 3. byte[]                        annotations;
+ * 4. byte[]                        parameterAnnotations;
+ * 5. java.util.Map                 declaredAnnotations;
+ * 6. java.lang.reflect.Constructor cons;
+ */
+class java_lang_reflect_VMConstructor : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_clazz                = MEMORY_ALIGN(sizeof(java_object_t),                         SIZEOF_VOID_P);
+       static const off_t offset_slot                 = MEMORY_ALIGN(offset_clazz                + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_annotations          = MEMORY_ALIGN(offset_slot                 + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_parameterAnnotations = MEMORY_ALIGN(offset_annotations          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_declaredAnnotations  = MEMORY_ALIGN(offset_parameterAnnotations + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_cons                 = MEMORY_ALIGN(offset_declaredAnnotations  + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_VMConstructor(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_VMConstructor(jobject h);
+       java_lang_reflect_VMConstructor(methodinfo* m);
+
+       // Getters.
+       inline classinfo*               get_clazz               () const;
+       inline int32_t                  get_slot                () const;
+       inline java_handle_bytearray_t* get_annotations         () const;
+       inline java_handle_bytearray_t* get_parameterAnnotations() const;
+       inline java_handle_t*           get_declaredAnnotations () const;
+       inline java_handle_t*           get_cons                () const;
+
+       // Setters.
+       inline void set_clazz               (classinfo* value);
+       inline void set_slot                (int32_t value);
+       inline void set_annotations         (java_handle_bytearray_t* value);
+       inline void set_parameterAnnotations(java_handle_bytearray_t* value);
+       inline void set_declaredAnnotations (java_handle_t* value);
+       inline void set_cons                (java_handle_t* value);
+
+       // Convenience functions.
+       inline methodinfo* get_method();
+};
+
+
+inline java_lang_reflect_VMConstructor::java_lang_reflect_VMConstructor(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_VMConstructor((java_handle_t*) h);
+}
+
+inline java_lang_reflect_VMConstructor::java_lang_reflect_VMConstructor(methodinfo* m)
+{
+       _handle = builtin_new(class_java_lang_reflect_VMConstructor);
+
+       if (is_null())
+               return;
+
+       int                      slot                 = m - m->clazz->methods;
+       java_handle_bytearray_t* annotations          = method_get_annotations(m);
+       java_handle_bytearray_t* parameterAnnotations = method_get_parameterannotations(m);
+
+       set_clazz(m->clazz);
+       set_slot(slot);
+       set_annotations(annotations);
+       set_parameterAnnotations(parameterAnnotations);
+}
+
+
+inline classinfo* java_lang_reflect_VMConstructor::get_clazz() const
+{
+       return get<classinfo*>(_handle, offset_clazz);
+}
+
+inline int32_t java_lang_reflect_VMConstructor::get_slot() const
+{
+       return get<int32_t>(_handle, offset_slot);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_VMConstructor::get_annotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_annotations);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_VMConstructor::get_parameterAnnotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_parameterAnnotations);
+}
+
+inline java_handle_t* java_lang_reflect_VMConstructor::get_declaredAnnotations() const
+{
+       return get<java_handle_t*>(_handle, offset_declaredAnnotations);
+}
+
+inline java_handle_t* java_lang_reflect_VMConstructor::get_cons() const
+{
+       return get<java_handle_t*>(_handle, offset_cons);
+}
+
+inline void java_lang_reflect_VMConstructor::set_clazz(classinfo* value)
+{
+       set(_handle, offset_clazz, value);
+}
+
+inline void java_lang_reflect_VMConstructor::set_slot(int32_t value)
+{
+       set(_handle, offset_slot, value);
+}
+
+inline void java_lang_reflect_VMConstructor::set_annotations(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_annotations, value);
+}
+
+inline void java_lang_reflect_VMConstructor::set_parameterAnnotations(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_parameterAnnotations, value);
+}
+
+inline void java_lang_reflect_VMConstructor::set_declaredAnnotations(java_handle_t* value)
+{
+       set(_handle, offset_declaredAnnotations, value);
+}
+
+inline void java_lang_reflect_VMConstructor::set_cons(java_handle_t* value)
+{
+       set(_handle, offset_cons, value);
+}
+
+inline methodinfo* java_lang_reflect_VMConstructor::get_method()
+{
+       classinfo*  c    = get_clazz();
+       int32_t     slot = get_slot();
+       methodinfo* m    = &(c->methods[slot]);
+       return m;
+}
+
+
+/**
+ * GNU Classpath java/lang/reflect/Constructor
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. boolean                                     flag;
+ * 2. gnu.java.lang.reflect.MethodSignatureParser p;
+ * 3. java.lang.reflect.VMConstructor             cons;
+ */
+class java_lang_reflect_Constructor : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_flag = MEMORY_ALIGN(sizeof(java_object_t),         sizeof(int32_t));
+       static const off_t offset_p    = MEMORY_ALIGN(offset_flag + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_cons = MEMORY_ALIGN(offset_p    + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_Constructor(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_Constructor(jobject h);
+       java_lang_reflect_Constructor(methodinfo* m);
+
+       java_handle_t* new_instance(java_handle_objectarray_t* args);
+
+       // Getters.
+       inline int32_t        get_flag() const;
+       inline java_handle_t* get_cons() const;
+
+       // Setters.
+       inline void set_cons(java_handle_t* value);
+
+       // Convenience functions.
+       inline methodinfo* get_method  () const;
+       inline int32_t     get_override() const;
+};
+
+
+inline java_lang_reflect_Constructor::java_lang_reflect_Constructor(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_Constructor((java_handle_t*) h);
+}
+
+inline java_lang_reflect_Constructor::java_lang_reflect_Constructor(methodinfo* m)
+{
+       java_lang_reflect_VMConstructor jlrvmc(m);
+
+       if (jlrvmc.is_null())
+               return;
+
+       _handle = builtin_new(class_java_lang_reflect_Constructor);
+
+       if (is_null())
+               return;
+
+       // Link the two Java objects.
+       set_cons(jlrvmc.get_handle());
+       jlrvmc.set_cons(get_handle());
+}
+
+
+inline int32_t java_lang_reflect_Constructor::get_flag() const
+{
+       return get<int32_t>(_handle, offset_flag);
+}
+
+inline java_handle_t* java_lang_reflect_Constructor::get_cons() const
+{
+       return get<java_handle_t*>(_handle, offset_cons);
+}
+
+
+inline void java_lang_reflect_Constructor::set_cons(java_handle_t* value)
+{
+       set(_handle, offset_cons, value);
+}
+
+
+inline methodinfo* java_lang_reflect_Constructor::get_method() const
+{
+       java_lang_reflect_VMConstructor jlrvmc(get_cons());
+       return jlrvmc.get_method();
+}
+
+inline int32_t java_lang_reflect_Constructor::get_override() const
+{
+       return get_flag();
+}
+
+
+/**
+ * GNU Classpath java/lang/reflect/VMField
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.Class         clazz;
+ * 2. java.lang.String        name;
+ * 3. int                     slot;
+ * 4. byte[]                  annotations;
+ * 5. java.lang.Map           declaredAnnotations;
+ * 6. java.lang.reflect.Field f;
+ */
+class java_lang_reflect_VMField : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_clazz               = MEMORY_ALIGN(sizeof(java_object_t),                        SIZEOF_VOID_P);
+       static const off_t offset_name                = MEMORY_ALIGN(offset_clazz               + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_slot                = MEMORY_ALIGN(offset_name                + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_annotations         = MEMORY_ALIGN(offset_slot                + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_declaredAnnotations = MEMORY_ALIGN(offset_annotations         + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_f                   = MEMORY_ALIGN(offset_declaredAnnotations + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_VMField(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_VMField(jobject h);
+       java_lang_reflect_VMField(fieldinfo* f);
+
+       // Getters.
+       inline classinfo*               get_clazz              () const;
+       inline int32_t                  get_slot               () const;
+       inline java_handle_bytearray_t* get_annotations        () const;
+       inline java_handle_t*           get_declaredAnnotations() const;
+       inline java_handle_t*           get_f                  () const;
+
+       // Setters.
+       inline void set_clazz              (classinfo* value);
+       inline void set_name               (java_handle_t* value);
+       inline void set_slot               (int32_t value);
+       inline void set_annotations        (java_handle_bytearray_t* value);
+       inline void set_declaredAnnotations(java_handle_t* value);
+       inline void set_f                  (java_handle_t* value);
+
+       // Convenience functions.
+       inline fieldinfo* get_field() const;
+};
+
+
+inline java_lang_reflect_VMField::java_lang_reflect_VMField(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_VMField((java_handle_t*) h);
+}
+
+inline java_lang_reflect_VMField::java_lang_reflect_VMField(fieldinfo* f)
+{
+       _handle = builtin_new(class_java_lang_reflect_VMField);
+
+       if (is_null())
+               return;
+
+       java_handle_t*           name        = javastring_intern(javastring_new(f->name));
+       int                      slot        = f - f->clazz->fields;
+       java_handle_bytearray_t* annotations = field_get_annotations(f);
+
+       set_clazz(f->clazz);
+       set_name(name);
+       set_slot(slot);
+       set_annotations(annotations);
+}
+
+
+inline classinfo* java_lang_reflect_VMField::get_clazz() const
+{
+       return get<classinfo*>(_handle, offset_clazz);
+}
+
+inline int32_t java_lang_reflect_VMField::get_slot() const
+{
+       return get<int32_t>(_handle, offset_slot);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_VMField::get_annotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_annotations);
+}
+
+inline java_handle_t* java_lang_reflect_VMField::get_declaredAnnotations() const
+{
+       return get<java_handle_t*>(_handle, offset_declaredAnnotations);
+}
+
+inline java_handle_t* java_lang_reflect_VMField::get_f() const
+{
+       return get<java_handle_t*>(_handle, offset_f);
+}
+
+
+inline void java_lang_reflect_VMField::set_clazz(classinfo* value)
+{
+       set(_handle, offset_clazz, value);
+}
+
+inline void java_lang_reflect_VMField::set_name(java_handle_t* value)
+{
+       set(_handle, offset_name, value);
+}
+
+inline void java_lang_reflect_VMField::set_slot(int32_t value)
+{
+       set(_handle, offset_slot, value);
+}
+
+inline void java_lang_reflect_VMField::set_annotations(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_annotations, value);
+}
+
+inline void java_lang_reflect_VMField::set_declaredAnnotations(java_handle_t* value)
+{
+       set(_handle, offset_declaredAnnotations, value);
+}
+
+inline void java_lang_reflect_VMField::set_f(java_handle_t* value)
+{
+       set(_handle, offset_f, value);
+}
+
+inline fieldinfo* java_lang_reflect_VMField::get_field() const
+{
+       classinfo* c    = get_clazz();
+       int32_t    slot = get_slot();
+       fieldinfo* f    = &(c->fields[slot]);
+       return f;
+}
+
+
+/**
+ * GNU Classpath java/lang/reflect/Field
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. boolean                                    flag;
+ * 2. gnu.java.lang.reflect.FieldSignatureParser p;
+ * 3. java.lang.reflect.VMField                  f;
+ */
+class java_lang_reflect_Field : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_flag = MEMORY_ALIGN(sizeof(java_object_t),         sizeof(int32_t));
+       static const off_t offset_p    = MEMORY_ALIGN(offset_flag + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_f    = MEMORY_ALIGN(offset_p    + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_Field(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_Field(jobject h);
+       java_lang_reflect_Field(fieldinfo* f);
+
+       // Getters.
+       inline int32_t        get_flag() const;
+       inline java_handle_t* get_f() const;
+
+       // Setters.
+       inline void set_f(java_handle_t* value);
+
+       // Convenience functions.
+       inline fieldinfo* get_field() const;
+};
+
+
+inline java_lang_reflect_Field::java_lang_reflect_Field(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_Field((java_handle_t*) h);
+}
+
+inline java_lang_reflect_Field::java_lang_reflect_Field(fieldinfo* f)
+{
+       java_lang_reflect_VMField jlrvmf(f);
+
+       if (jlrvmf.is_null())
+               return;
+
+       _handle = builtin_new(class_java_lang_reflect_Field);
+
+       if (is_null())
+               return;
+
+       // Link the two Java objects.
+       set_f(jlrvmf.get_handle());
+       jlrvmf.set_f(get_handle());
+}
+
+
+inline int32_t java_lang_reflect_Field::get_flag() const
+{
+       return get<int32_t>(_handle, offset_flag);
+}
+
+inline java_handle_t* java_lang_reflect_Field::get_f() const
+{
+       return get<java_handle_t*>(_handle, offset_f);
+}
+
+
+inline void java_lang_reflect_Field::set_f(java_handle_t* value)
+{
+       set(_handle, offset_f, value);
+}
+
+
+inline fieldinfo* java_lang_reflect_Field::get_field() const
+{
+       java_lang_reflect_VMField jlrvmf(get_f());
+       return jlrvmf.get_field();
+}
+
+
+/**
+ * GNU Classpath java/lang/reflect/VMMethod
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.Class          clazz;
+ * 2. java.lang.String         name;
+ * 3. int                      slot;
+ * 4. byte[]                   annotations;
+ * 5. byte[]                   parameterAnnotations;
+ * 6. byte[]                   annotationDefault;
+ * 7. java.lang.Map            declaredAnnotations;
+ * 8. java.lang.reflect.Method m;
+ */
+class java_lang_reflect_VMMethod : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_clazz                = MEMORY_ALIGN(sizeof(java_object_t),                         SIZEOF_VOID_P);
+       static const off_t offset_name                 = MEMORY_ALIGN(offset_clazz                + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_slot                 = MEMORY_ALIGN(offset_name                 + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_annotations          = MEMORY_ALIGN(offset_slot                 + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_parameterAnnotations = MEMORY_ALIGN(offset_annotations          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_annotationDefault    = MEMORY_ALIGN(offset_parameterAnnotations + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_declaredAnnotations  = MEMORY_ALIGN(offset_annotationDefault    + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_m                    = MEMORY_ALIGN(offset_declaredAnnotations  + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_VMMethod(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_VMMethod(jobject h);
+       java_lang_reflect_VMMethod(methodinfo* m);
+
+       // Getters.
+       inline classinfo*               get_clazz               () const;
+       inline int32_t                  get_slot                () const;
+       inline java_handle_bytearray_t* get_annotations         () const;
+       inline java_handle_bytearray_t* get_parameterAnnotations() const;
+       inline java_handle_bytearray_t* get_annotationDefault   () const;
+       inline java_handle_t*           get_declaredAnnotations () const;
+       inline java_handle_t*           get_m                   () const;
+
+       // Setters.
+       inline void set_clazz               (classinfo* value);
+       inline void set_name                (java_handle_t* value);
+       inline void set_slot                (int32_t value);
+       inline void set_annotations         (java_handle_bytearray_t* value);
+       inline void set_parameterAnnotations(java_handle_bytearray_t* value);
+       inline void set_annotationDefault   (java_handle_bytearray_t* value);
+       inline void set_declaredAnnotations (java_handle_t* value);
+       inline void set_m                   (java_handle_t* value);
+
+       // Convenience functions.
+       inline methodinfo* get_method() const;
+};
+
+inline java_lang_reflect_VMMethod::java_lang_reflect_VMMethod(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_VMMethod((java_handle_t*) h);
+}
+
+inline java_lang_reflect_VMMethod::java_lang_reflect_VMMethod(methodinfo* m)
+{
+       _handle = builtin_new(class_java_lang_reflect_VMMethod);
+
+       if (is_null())
+               return;
+
+       java_handle_t*           name                 = javastring_intern(javastring_new(m->name));
+       int                      slot                 = m - m->clazz->methods;
+       java_handle_bytearray_t* annotations          = method_get_annotations(m);
+       java_handle_bytearray_t* parameterAnnotations = method_get_parameterannotations(m);
+       java_handle_bytearray_t* annotationDefault    = method_get_annotationdefault(m);
+
+       set_clazz(m->clazz);
+       set_name(name);
+       set_slot(slot);
+       set_annotations(annotations);
+       set_parameterAnnotations(parameterAnnotations);
+       set_annotationDefault(annotationDefault);
+}
+
+inline classinfo* java_lang_reflect_VMMethod::get_clazz() const
+{
+       return get<classinfo*>(_handle, offset_clazz);
+}
+
+inline int32_t java_lang_reflect_VMMethod::get_slot() const
+{
+       return get<int32_t>(_handle, offset_slot);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_VMMethod::get_annotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_annotations);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_VMMethod::get_parameterAnnotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_parameterAnnotations);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_VMMethod::get_annotationDefault() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_annotationDefault);
+}
+
+inline java_handle_t* java_lang_reflect_VMMethod::get_declaredAnnotations() const
+{
+       return get<java_handle_t*>(_handle, offset_declaredAnnotations);
+}
+
+inline java_handle_t* java_lang_reflect_VMMethod::get_m() const
+{
+       return get<java_handle_t*>(_handle, offset_m);
+}
+
+inline void java_lang_reflect_VMMethod::set_clazz(classinfo* value)
+{
+       set(_handle, offset_clazz, value);
+}
+
+inline void java_lang_reflect_VMMethod::set_name(java_handle_t* value)
+{
+       set(_handle, offset_name, value);
+}
+
+inline void java_lang_reflect_VMMethod::set_slot(int32_t value)
+{
+       set(_handle, offset_slot, value);
+}
+
+inline void java_lang_reflect_VMMethod::set_annotations(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_annotations, value);
+}
+
+inline void java_lang_reflect_VMMethod::set_parameterAnnotations(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_parameterAnnotations, value);
+}
+
+inline void java_lang_reflect_VMMethod::set_annotationDefault(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_annotationDefault, value);
+}
+
+inline void java_lang_reflect_VMMethod::set_declaredAnnotations(java_handle_t* value)
+{
+       set(_handle, offset_declaredAnnotations, value);
+}
+
+inline void java_lang_reflect_VMMethod::set_m(java_handle_t* value)
+{
+       set(_handle, offset_m, value);
+}
+
+inline methodinfo* java_lang_reflect_VMMethod::get_method() const
+{
+       classinfo*  c    = get_clazz();
+       int32_t     slot = get_slot();
+       methodinfo* m    = &(c->methods[slot]);
+       return m;
+}
+
+
+/**
+ * GNU Classpath java/lang/reflect/Method
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. boolean                                     flag;
+ * 2. gnu.java.lang.reflect.MethodSignatureParser p;
+ * 3. java.lang.reflect.VMMethod                  m;
+ */
+class java_lang_reflect_Method : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_flag = MEMORY_ALIGN(sizeof(java_object_t),         sizeof(int32_t));
+       static const off_t offset_p    = MEMORY_ALIGN(offset_flag + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_m    = MEMORY_ALIGN(offset_p    + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_Method(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_Method(jobject h);
+       java_lang_reflect_Method(methodinfo* m);
+
+       java_handle_t* invoke(java_handle_t* o, java_handle_objectarray_t* args);
+
+       // Getters.
+       inline int32_t        get_flag() const;
+       inline java_handle_t* get_m() const;
+
+       // Setters.
+       inline void set_m(java_handle_t* value);
+
+       // Convenience functions.
+       inline methodinfo* get_method  () const;
+       inline int32_t     get_override() const;
+};
+
+
+inline java_lang_reflect_Method::java_lang_reflect_Method(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_Method((java_handle_t*) h);
+}
+
+inline java_lang_reflect_Method::java_lang_reflect_Method(methodinfo* m)
+{
+       java_lang_reflect_VMMethod jlrvmm(m);
+
+       if (jlrvmm.is_null())
+               return;
+
+       _handle = builtin_new(class_java_lang_reflect_Method);
+
+       if (is_null())
+               return;
+
+       // Link the two Java objects.
+       set_m(jlrvmm.get_handle());
+       jlrvmm.set_m(get_handle());
+}
+
+
+inline int32_t java_lang_reflect_Method::get_flag() const
+{
+       return get<int32_t>(_handle, offset_flag);
+}
+
+inline java_handle_t* java_lang_reflect_Method::get_m() const
+{
+       return get<java_handle_t*>(_handle, offset_m);
+}
+
+
+inline void java_lang_reflect_Method::set_m(java_handle_t* value)
+{
+       set(_handle, offset_m, value);
+}
+
+
+inline methodinfo* java_lang_reflect_Method::get_method() const
+{
+       java_lang_reflect_VMMethod jlrvmm(get_m());
+       return jlrvmm.get_method();
+}
+
+inline int32_t java_lang_reflect_Method::get_override() const
+{
+       return get_flag();
+}
+
+
+/**
+ * GNU Classpath java/nio/Buffer
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. int                   cap;
+ * 2. int                   limit;
+ * 3. int                   pos;
+ * 4. int                   mark;
+ * 5. gnu.classpath.Pointer address;
+ */
+class java_nio_Buffer : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_cap     = MEMORY_ALIGN(sizeof(java_object_t),          sizeof(int32_t));
+       static const off_t offset_limit   = MEMORY_ALIGN(offset_cap   + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_pos     = MEMORY_ALIGN(offset_limit + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_mark    = MEMORY_ALIGN(offset_pos   + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_address = MEMORY_ALIGN(offset_mark  + sizeof(int32_t), SIZEOF_VOID_P);
+
+public:
+       java_nio_Buffer(java_handle_t* h) : java_lang_Object(h) {}
+
+       // Getters.
+       inline int32_t get_cap() const;
+};
+
+inline int32_t java_nio_Buffer::get_cap() const
+{
+       return get<int32_t>(_handle, offset_cap);
+}
+
+
+/**
+ * GNU Classpath java/nio/DirectByteBufferImpl
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. int                   cap;
+ * 2. int                   limit;
+ * 3. int                   pos;
+ * 4. int                   mark;
+ * 5. gnu.classpath.Pointer address;
+ * 6. java.nio.ByteOrder    endian;
+ * 7. byte[]                backing_buffer;
+ * 8. int                   array_offset;
+ * 9. java.lang.Object      owner;
+ */
+class java_nio_DirectByteBufferImpl : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_cap            = MEMORY_ALIGN(sizeof(java_object_t),                   sizeof(int32_t));
+       static const off_t offset_limit          = MEMORY_ALIGN(offset_cap            + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_pos            = MEMORY_ALIGN(offset_limit          + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_mark           = MEMORY_ALIGN(offset_pos            + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_address        = MEMORY_ALIGN(offset_mark           + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_endian         = MEMORY_ALIGN(offset_address        + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_backing_buffer = MEMORY_ALIGN(offset_endian         + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_array_offset   = MEMORY_ALIGN(offset_backing_buffer + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_owner          = MEMORY_ALIGN(offset_array_offset   + sizeof(int32_t), SIZEOF_VOID_P);
+
+public:
+       java_nio_DirectByteBufferImpl(java_handle_t* h) : java_lang_Object(h) {}
+       java_nio_DirectByteBufferImpl(jobject h);
+
+       // Getters.
+       inline java_handle_t* get_address() const;
+};
+
+inline java_nio_DirectByteBufferImpl::java_nio_DirectByteBufferImpl(jobject h) : java_lang_Object(h)
+{
+       java_nio_DirectByteBufferImpl((java_handle_t*) h);
+}
+
+inline java_handle_t* java_nio_DirectByteBufferImpl::get_address() const
+{
+       return get<java_handle_t*>(_handle, offset_address);
+}
+
+
+/**
+ * GNU Classpath gnu/classpath/Pointer
+ *
+ * Actually there are two classes, gnu.classpath.Pointer32 and
+ * gnu.classpath.Pointer64, but we only define the abstract super
+ * class and use the int/long field as void* type.
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. int/long data;
+ */
+class gnu_classpath_Pointer : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_data = MEMORY_ALIGN(sizeof(java_object_t), SIZEOF_VOID_P);
+
+public:
+       gnu_classpath_Pointer(java_handle_t* h) : java_lang_Object(h) {}
+       gnu_classpath_Pointer(java_handle_t* h, void* data);
+
+       // Setters.
+       inline void* get_data() const;
+
+       // Setters.
+       inline void set_data(void* value);
+};
+
+inline gnu_classpath_Pointer::gnu_classpath_Pointer(java_handle_t* h, void* data) : java_lang_Object(h)
+{
+       set_data(data);
+}
+
+inline void* gnu_classpath_Pointer::get_data() const
+{
+       return get<void*>(_handle, offset_data);
+}
+
+inline void gnu_classpath_Pointer::set_data(void* value)
+{
+       set(_handle, offset_data, value);
+}
+
+#endif // WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH
+
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+/**
+ * OpenJDK java/lang/AssertionStatusDirectives
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.String[] classes;
+ * 2. boolean[]          classEnabled;
+ * 3. java.lang.String[] packages;
+ * 4. boolean[]          packageEnabled;
+ * 5. boolean            deflt;
+ */
+class java_lang_AssertionStatusDirectives : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_classes        = MEMORY_ALIGN(sizeof(java_object_t),                 SIZEOF_VOID_P);
+       static const off_t offset_classEnabled   = MEMORY_ALIGN(offset_classes        + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_packages       = MEMORY_ALIGN(offset_classEnabled   + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_packageEnabled = MEMORY_ALIGN(offset_packages       + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_deflt          = MEMORY_ALIGN(offset_packageEnabled + SIZEOF_VOID_P, sizeof(int32_t));
+
+public:
+       java_lang_AssertionStatusDirectives(java_handle_objectarray_t* classes, java_handle_booleanarray_t* classEnabled, java_handle_objectarray_t* packages, java_handle_booleanarray_t* packageEnabled);
+};
+
+inline java_lang_AssertionStatusDirectives::java_lang_AssertionStatusDirectives(java_handle_objectarray_t* classes, java_handle_booleanarray_t* classEnabled, java_handle_objectarray_t* packages, java_handle_booleanarray_t* packageEnabled)
+{
+       classinfo* c = load_class_bootstrap(utf_new_char("java/lang/AssertionStatusDirectives"));
+
+       // FIXME Load the class at VM startup.
+       if (c == NULL)
+               return;
+
+       _handle = builtin_new(c);
+
+       if (is_null())
+               return;
+
+       set(_handle, offset_classes,        classes);
+       set(_handle, offset_classEnabled,   classEnabled);
+       set(_handle, offset_packages,       packages);
+       set(_handle, offset_packageEnabled, packageEnabled);
+}
+
+
+/**
+ * OpenJDK java/lang/StackTraceElement
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.String declaringClass;
+ * 2. java.lang.String methodName;
+ * 3. java.lang.String fileName;
+ * 4. int              lineNumber;
+ */
+class java_lang_StackTraceElement : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_declaringClass = MEMORY_ALIGN(sizeof(java_object_t),                 SIZEOF_VOID_P);
+       static const off_t offset_methodName     = MEMORY_ALIGN(offset_declaringClass + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_fileName       = MEMORY_ALIGN(offset_methodName     + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_lineNumber     = MEMORY_ALIGN(offset_fileName       + SIZEOF_VOID_P, sizeof(int32_t));
+
+public:
+       java_lang_StackTraceElement(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_StackTraceElement(java_handle_t* declaringClass, java_handle_t* methodName, java_handle_t* fileName, int32_t lineNumber);
+};
+
+inline java_lang_StackTraceElement::java_lang_StackTraceElement(java_handle_t* declaringClass, java_handle_t* methodName, java_handle_t* fileName, int32_t lineNumber)
+{
+       _handle = builtin_new(class_java_lang_StackTraceElement);
+
+       if (is_null())
+               return;
+
+       set(_handle, offset_declaringClass, declaringClass);
+       set(_handle, offset_methodName,     methodName);
+       set(_handle, offset_fileName,       fileName);
+       set(_handle, offset_lineNumber,     lineNumber);
+}
+
+
+/**
+ * OpenJDK java/lang/String
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. char[] value;
+ * 2. int    offset;
+ * 3. int    count;
+ * 4. int    hash;
+ */
+class java_lang_String : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value  = MEMORY_ALIGN(sizeof(java_object_t),           SIZEOF_VOID_P);
+       static const off_t offset_offset = MEMORY_ALIGN(offset_value  + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_count  = MEMORY_ALIGN(offset_offset + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_hash   = MEMORY_ALIGN(offset_count  + sizeof(int32_t), sizeof(int32_t));
+
+public:
+       java_lang_String(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_String(jstring h);
+       java_lang_String(java_handle_t* h, java_handle_chararray_t* value, int32_t count, int32_t offset = 0);
+
+       // Getters.
+       inline java_handle_chararray_t* get_value () const;
+       inline int32_t                  get_offset() const;
+       inline int32_t                  get_count () const;
+
+       // Setters.
+       inline void set_value (java_handle_chararray_t* value);
+       inline void set_offset(int32_t value);
+       inline void set_count (int32_t value);
+};
+
+inline java_lang_String::java_lang_String(jstring h) : java_lang_Object(h)
+{
+       java_lang_String((java_handle_t*) h);
+}
+
+inline java_lang_String::java_lang_String(java_handle_t* h, java_handle_chararray_t* value, int32_t count, int32_t offset) : java_lang_Object(h)
+{
+       set_value(value);
+       set_offset(offset);
+       set_count(count);
+}
+
+inline java_handle_chararray_t* java_lang_String::get_value() const
+{
+       return get<java_handle_chararray_t*>(_handle, offset_value);
+}
+
+inline int32_t java_lang_String::get_offset() const
+{
+       return get<int32_t>(_handle, offset_offset);
+}
+
+inline int32_t java_lang_String::get_count() const
+{
+       return get<int32_t>(_handle, offset_count);
+}
+
+inline void java_lang_String::set_value(java_handle_chararray_t* value)
+{
+       set(_handle, offset_value, value);
+}
+
+inline void java_lang_String::set_offset(int32_t value)
+{
+       set(_handle, offset_offset, value);
+}
+
+inline void java_lang_String::set_count(int32_t value)
+{
+       set(_handle, offset_count, value);
+}
+
+
+/**
+ * OpenJDK java/lang/Thread
+ *
+ * Object layout:
+ *
+ * 0.  object header
+ * 1.  char[]                                    name;
+ * 2.  int                                       priority;
+ * 3.  java_lang_Thread                          threadQ;
+ * 4.  long                                      eetop;
+ * 5.  boolean                                   single_step;
+ * 6.  boolean                                   daemon;
+ * 7.  boolean                                   stillborn;
+ * 8.  java_lang_Runnable                        target;
+ * 9.  java_lang_ThreadGroup                     group;
+ * 10. java_lang_ClassLoader                     contextClassLoader;
+ * 11. java_security_AccessControlContext        inheritedAccessControlContext;
+ * 12. java_lang_ThreadLocal_ThreadLocalMap      threadLocals;
+ * 13. java_lang_ThreadLocal_ThreadLocalMap      inheritableThreadLocals;
+ * 14. long                                      stackSize;
+ * 15. long                                      nativeParkEventPointer;
+ * 16. long                                      tid;
+ * 17. int                                       threadStatus;
+ * 18. java_lang_Object                          parkBlocker;
+ * 19. sun_nio_ch_Interruptible                  blocker;
+ * 20. java_lang_Object                          blockerLock;
+ * 21. boolean                                   stopBeforeStart;
+ * 22. java_lang_Throwable                       throwableFromStop;
+ * 23. java.lang.Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
+ */
+class java_lang_Thread : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_name                          = MEMORY_ALIGN(sizeof(java_object_t),                                  SIZEOF_VOID_P);
+       static const off_t offset_priority                      = MEMORY_ALIGN(offset_name                          + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_threadQ                       = MEMORY_ALIGN(offset_priority                      + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_eetop                         = MEMORY_ALIGN(offset_threadQ                       + SIZEOF_VOID_P,   sizeof(int64_t));
+       static const off_t offset_single_step                   = MEMORY_ALIGN(offset_eetop                         + sizeof(int64_t), sizeof(int32_t));
+       static const off_t offset_daemon                        = MEMORY_ALIGN(offset_single_step                   + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_stillborn                     = MEMORY_ALIGN(offset_daemon                        + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_target                        = MEMORY_ALIGN(offset_stillborn                     + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_group                         = MEMORY_ALIGN(offset_target                        + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_contextClassLoader            = MEMORY_ALIGN(offset_group                         + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_inheritedAccessControlContext = MEMORY_ALIGN(offset_contextClassLoader            + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_threadLocals                  = MEMORY_ALIGN(offset_inheritedAccessControlContext + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_inheritableThreadLocals       = MEMORY_ALIGN(offset_threadLocals                  + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_stackSize                     = MEMORY_ALIGN(offset_inheritableThreadLocals       + SIZEOF_VOID_P,   sizeof(int64_t));
+       static const off_t offset_nativeParkEventPointer        = MEMORY_ALIGN(offset_stackSize                     + sizeof(int64_t), sizeof(int64_t));
+       static const off_t offset_tid                           = MEMORY_ALIGN(offset_nativeParkEventPointer        + sizeof(int64_t), sizeof(int64_t));
+       static const off_t offset_threadStatus                  = MEMORY_ALIGN(offset_tid                           + sizeof(int64_t), sizeof(int32_t));
+       static const off_t offset_parkBlocker                   = MEMORY_ALIGN(offset_threadStatus                  + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_blocker                       = MEMORY_ALIGN(offset_parkBlocker                   + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_blockerLock                   = MEMORY_ALIGN(offset_blocker                       + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_stopBeforeStart               = MEMORY_ALIGN(offset_blockerLock                   + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_throwableFromStop             = MEMORY_ALIGN(offset_stopBeforeStart               + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_uncaughtExceptionHandler      = MEMORY_ALIGN(offset_throwableFromStop             + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_Thread(java_handle_t* h) : java_lang_Object(h) {}
+//     java_lang_Thread(threadobject* t);
+
+       // Getters.
+       inline int32_t        get_priority                () const;
+       inline int32_t        get_daemon                  () const;
+       inline java_handle_t* get_group                   () const;
+       inline java_handle_t* get_uncaughtExceptionHandler() const;
+
+       // Setters.
+       inline void set_priority(int32_t value);
+       inline void set_group   (java_handle_t* value);
+};
+
+
+inline int32_t java_lang_Thread::get_priority() const
+{
+       return get<int32_t>(_handle, offset_priority);
+}
+
+inline int32_t java_lang_Thread::get_daemon() const
+{
+       return get<int32_t>(_handle, offset_daemon);
+}
+
+inline java_handle_t* java_lang_Thread::get_group() const
+{
+       return get<java_handle_t*>(_handle, offset_group);
+}
+
+inline java_handle_t* java_lang_Thread::get_uncaughtExceptionHandler() const
+{
+       return get<java_handle_t*>(_handle, offset_uncaughtExceptionHandler);
+}
+
+
+inline void java_lang_Thread::set_priority(int32_t value)
+{
+       set(_handle, offset_priority, value);
+}
+
+inline void java_lang_Thread::set_group(java_handle_t* value)
+{
+       set(_handle, offset_group, value);
+}
+
+
+
+/**
+ * OpenJDK java/lang/Throwable
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.Object              backtrace;
+ * 2. java.lang.String              detailMessage;
+ * 3. java.lang.Throwable           cause;
+ * 4. java.lang.StackTraceElement[] stackTrace;
+ */
+class java_lang_Throwable : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_backtrace     = MEMORY_ALIGN(sizeof(java_object_t),                SIZEOF_VOID_P);
+       static const off_t offset_detailMessage = MEMORY_ALIGN(offset_backtrace     + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_cause         = MEMORY_ALIGN(offset_detailMessage + SIZEOF_VOID_P, SIZEOF_VOID_P);
+       static const off_t offset_stackTrace    = MEMORY_ALIGN(offset_cause         + SIZEOF_VOID_P, SIZEOF_VOID_P);
+
+public:
+       java_lang_Throwable(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_Throwable(jobject h);
+       java_lang_Throwable(jobject h, java_handle_bytearray_t* backtrace);
+
+       // Getters.
+       inline java_handle_bytearray_t* get_backtrace    () const;
+       inline java_handle_t*           get_detailMessage() const;
+       inline java_handle_t*           get_cause        () const;
+
+       // Setters.
+       inline void set_backtrace(java_handle_bytearray_t* value);
+};
+
+
+inline java_lang_Throwable::java_lang_Throwable(jobject h) : java_lang_Object(h)
+{
+       java_lang_Throwable((java_handle_t*) h);
+}
+
+inline java_lang_Throwable::java_lang_Throwable(jobject h, java_handle_bytearray_t* backtrace) : java_lang_Object(h)
+{
+       java_lang_Throwable((java_handle_t*) h);
+       set_backtrace(backtrace);
+}
+
+
+inline java_handle_bytearray_t* java_lang_Throwable::get_backtrace() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_backtrace);
+}
+
+inline java_handle_t* java_lang_Throwable::get_detailMessage() const
+{
+       return get<java_handle_t*>(_handle, offset_detailMessage);
+}
+
+inline java_handle_t* java_lang_Throwable::get_cause() const
+{
+       return get<java_handle_t*>(_handle, offset_cause);
+}
+
+
+inline void java_lang_Throwable::set_backtrace(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_backtrace, value);
+}
+
+
+/**
+ * OpenJDK java/lang/reflect/Constructor
+ *
+ * Object layout:
+ *
+ * 0.  object header
+ * 1.  boolean                                               override;
+ * 2.  java.lang.Class                                       clazz;
+ * 3.  int                                                   slot;
+ * 4.  java.lang.Class[]                                     parameterTypes;
+ * 5.  java.lang.Class[]                                     exceptionTypes;
+ * 6.  int                                                   modifiers;
+ * 7.  java.lang.String                                      signature;
+ * 8.  sun.reflect.generics.repository.ConstructorRepository genericInfo;
+ * 9.  byte[]                                                annotations;
+ * 10. byte[]                                                parameterAnnotations;
+ * 11. java.lang.Class                                       securityCheckCache;
+ * 12. sun.reflect.ConstructorAccessor                       constructorAccessor;
+ * 13. java.lang.reflect.Constructor                         root;
+ * 14. java.util.Map                                         declaredAnnotations;
+ */
+class java_lang_reflect_Constructor : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_override             = MEMORY_ALIGN(sizeof(java_object_t),                         sizeof(int32_t));
+       static const off_t offset_clazz                = MEMORY_ALIGN(offset_override             + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_slot                 = MEMORY_ALIGN(offset_clazz                + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_parameterTypes       = MEMORY_ALIGN(offset_slot                 + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_exceptionTypes       = MEMORY_ALIGN(offset_parameterTypes       + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_modifiers            = MEMORY_ALIGN(offset_exceptionTypes       + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_signature            = MEMORY_ALIGN(offset_modifiers            + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_genericInfo          = MEMORY_ALIGN(offset_signature            + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_annotations          = MEMORY_ALIGN(offset_genericInfo          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_parameterAnnotations = MEMORY_ALIGN(offset_annotations          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_securityCheckCache   = MEMORY_ALIGN(offset_parameterAnnotations + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_constructorAccessor  = MEMORY_ALIGN(offset_securityCheckCache   + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_root                 = MEMORY_ALIGN(offset_constructorAccessor  + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_declaredAnnotations  = MEMORY_ALIGN(offset_root                 + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_Constructor(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_Constructor(jobject h);
+       java_lang_reflect_Constructor(methodinfo* m);
+
+       java_handle_t* new_instance(java_handle_objectarray_t* args);
+
+       // Getters.
+       inline int32_t                  get_override   () const;
+       inline classinfo*               get_clazz      () const;
+       inline int32_t                  get_slot       () const;
+       inline java_handle_bytearray_t* get_annotations() const;
+
+       // Setters.
+       inline void set_clazz               (classinfo* value);
+       inline void set_slot                (int32_t value);
+       inline void set_parameterTypes      (java_handle_objectarray_t* value);
+       inline void set_exceptionTypes      (java_handle_objectarray_t* value);
+       inline void set_modifiers           (int32_t value);
+       inline void set_signature           (java_handle_t* value);
+       inline void set_annotations         (java_handle_bytearray_t* value);
+       inline void set_parameterAnnotations(java_handle_bytearray_t* value);
+
+       // Convenience functions.
+       inline methodinfo* get_method();
+};
+
+
+inline java_lang_reflect_Constructor::java_lang_reflect_Constructor(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_Constructor((java_handle_t*) h);
+}
+
+inline java_lang_reflect_Constructor::java_lang_reflect_Constructor(methodinfo* m)
+{
+       _handle = builtin_new(class_java_lang_reflect_Constructor);
+
+       if (is_null())
+               return;
+
+       int                        slot                 = m - m->clazz->methods;
+       java_handle_objectarray_t* parameterTypes       = method_get_parametertypearray(m);
+       java_handle_objectarray_t* exceptionTypes       = method_get_exceptionarray(m);
+       java_handle_bytearray_t*   annotations          = method_get_annotations(m);
+       java_handle_bytearray_t*   parameterAnnotations = method_get_parameterannotations(m);
+
+       set_clazz(m->clazz);
+       set_slot(slot);
+       set_parameterTypes(parameterTypes);
+       set_exceptionTypes(exceptionTypes);
+       set_modifiers(m->flags & ACC_CLASS_REFLECT_MASK);
+       set_signature(m->signature ? javastring_new(m->signature) : NULL);
+       set_annotations(annotations);
+       set_parameterAnnotations(parameterAnnotations);
+}
+
+
+inline int32_t java_lang_reflect_Constructor::get_override() const
+{
+       return get<int32_t>(_handle, offset_override);
+}
+
+inline classinfo* java_lang_reflect_Constructor::get_clazz() const
+{
+       return get<classinfo*>(_handle, offset_clazz);
+}
+
+inline int32_t java_lang_reflect_Constructor::get_slot() const
+{
+       return get<int32_t>(_handle, offset_slot);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_Constructor::get_annotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_annotations);
+}
+
+
+inline void java_lang_reflect_Constructor::set_clazz(classinfo* value)
+{
+       set(_handle, offset_clazz, value);
+}
+
+inline void java_lang_reflect_Constructor::set_slot(int32_t value)
+{
+       set(_handle, offset_slot, value);
+}
+
+inline void java_lang_reflect_Constructor::set_parameterTypes(java_handle_objectarray_t* value)
+{
+       set(_handle, offset_parameterTypes, value);
+}
+
+inline void java_lang_reflect_Constructor::set_exceptionTypes(java_handle_objectarray_t* value)
+{
+       set(_handle, offset_exceptionTypes, value);
+}
+
+inline void java_lang_reflect_Constructor::set_modifiers(int32_t value)
+{
+       set(_handle, offset_modifiers, value);
+}
+
+inline void java_lang_reflect_Constructor::set_signature(java_handle_t* value)
+{
+       set(_handle, offset_signature, value);
+}
+
+inline void java_lang_reflect_Constructor::set_annotations(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_annotations, value);
+}
+
+inline void java_lang_reflect_Constructor::set_parameterAnnotations(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_parameterAnnotations, value);
+}
+
+
+inline methodinfo* java_lang_reflect_Constructor::get_method()
+{
+       classinfo*  c    = get_clazz();
+       int32_t     slot = get_slot();
+       methodinfo* m    = &(c->methods[slot]);
+       return m;
+}
+
+
+/**
+ * OpenJDK java/lang/reflect/Field
+ *
+ * Object layout:
+ *
+ * 0.  object header
+ * 1.  boolean                                         override;
+ * 2.  java.lang.Class                                 clazz;
+ * 3.  int                                             slot;
+ * 4.  java.lang.String                                name;
+ * 5.  java.lang.Class                                 type;
+ * 6.  int                                             modifiers;
+ * 7.  java.lang.String                                signature;
+ * 8.  sun.reflect.generics.repository.FieldRepository genericInfo;
+ * 9.  byte[]                                          annotations;
+ * 10. sun.reflect.FieldAccessor                       fieldAccessor;
+ * 11. sun.reflect.FieldAccessor                       overrideFieldAccessor;
+ * 12. java.lang.reflect.Field                         root;
+ * 13. java.lang.Class                                 securityCheckCache;
+ * 14. java.lang.Class                                 securityCheckTargetClassCache;
+ * 15. java.util.Map                                   declaredAnnotations;
+ */
+class java_lang_reflect_Field : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_override                      = MEMORY_ALIGN(sizeof(java_object_t),                                  sizeof(int32_t));
+       static const off_t offset_clazz                         = MEMORY_ALIGN(offset_override                      + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_slot                          = MEMORY_ALIGN(offset_clazz                         + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_name                          = MEMORY_ALIGN(offset_slot                          + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_type                          = MEMORY_ALIGN(offset_name                          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_modifiers                     = MEMORY_ALIGN(offset_type                          + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_signature                     = MEMORY_ALIGN(offset_modifiers                     + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_genericInfo                   = MEMORY_ALIGN(offset_signature                     + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_annotations                   = MEMORY_ALIGN(offset_genericInfo                   + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_fieldAccessor                 = MEMORY_ALIGN(offset_annotations                   + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_overrideFieldAccessor         = MEMORY_ALIGN(offset_fieldAccessor                 + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_root                          = MEMORY_ALIGN(offset_overrideFieldAccessor         + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_securityCheckCache            = MEMORY_ALIGN(offset_root                          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_securityCheckTargetClassCache = MEMORY_ALIGN(offset_securityCheckCache            + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_declaredAnnotations           = MEMORY_ALIGN(offset_securityCheckTargetClassCache + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_Field(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_Field(jobject h);
+       java_lang_reflect_Field(fieldinfo* f);
+
+       // Getters.
+       inline int32_t                  get_override   () const;
+       inline classinfo*               get_clazz      () const;
+       inline int32_t                  get_slot       () const;
+       inline java_handle_bytearray_t* get_annotations() const;
+
+       // Setters.
+       inline void set_clazz      (classinfo* value);
+       inline void set_slot       (int32_t value);
+       inline void set_name       (java_handle_t* value);
+       inline void set_type       (classinfo* value);
+       inline void set_modifiers  (int32_t value);
+       inline void set_signature  (java_handle_t* value);
+       inline void set_annotations(java_handle_bytearray_t* value);
+
+       // Convenience functions.
+       inline fieldinfo* get_field() const;
+};
+
+
+inline java_lang_reflect_Field::java_lang_reflect_Field(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_Field((java_handle_t*) h);
+}
+
+inline java_lang_reflect_Field::java_lang_reflect_Field(fieldinfo* f)
+{
+       _handle = builtin_new(class_java_lang_reflect_Field);
+
+       // OOME.
+       if (is_null())
+               return;
+
+       set_clazz(f->clazz);
+       set_slot(f - f->clazz->fields);
+       set_name(javastring_intern(javastring_new(f->name)));
+       set_type(field_get_type(f));
+       set_modifiers(f->flags);
+       set_signature(f->signature ? javastring_new(f->signature) : NULL);
+       set_annotations(field_get_annotations(f));
+}
+
+
+inline int32_t java_lang_reflect_Field::get_override() const
+{
+       return get<int32_t>(_handle, offset_override);
+}
+
+inline classinfo* java_lang_reflect_Field::get_clazz() const
+{
+       return get<classinfo*>(_handle, offset_clazz);
+}
+
+inline int32_t java_lang_reflect_Field::get_slot() const
+{
+       return get<int32_t>(_handle, offset_slot);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_Field::get_annotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_annotations);
+}
+
+
+inline void java_lang_reflect_Field::set_clazz(classinfo* value)
+{
+       set(_handle, offset_clazz, value);
+}
+
+inline void java_lang_reflect_Field::set_slot(int32_t value)
+{
+       set(_handle, offset_slot, value);
+}
+
+inline void java_lang_reflect_Field::set_name(java_handle_t* value)
+{
+       set(_handle, offset_name, value);
+}
+
+inline void java_lang_reflect_Field::set_type(classinfo* value)
+{
+       set(_handle, offset_type, value);
+}
+
+inline void java_lang_reflect_Field::set_modifiers(int32_t value)
+{
+       set(_handle, offset_modifiers, value);
+}
+
+inline void java_lang_reflect_Field::set_signature(java_handle_t* value)
+{
+       set(_handle, offset_signature, value);
+}
+
+inline void java_lang_reflect_Field::set_annotations(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_annotations, value);
+}
+
+
+inline fieldinfo* java_lang_reflect_Field::get_field() const
+{
+       classinfo* c    = get_clazz();
+       int32_t    slot = get_slot();
+       fieldinfo* f    = &(c->fields[slot]);
+       return f;
+}
+
+
+/**
+ * OpenJDK java/lang/reflect/Method
+ *
+ * Object layout:
+ *
+ * 0.  object header
+ * 1.  boolean                                               override;
+ * 2.  java.lang.Class                                       clazz;
+ * 3.  int                                                   slot;
+ * 4.  java.lang.String                                      name;
+ * 5.  java.lang.Class                                       returnType;
+ * 6.  java.lang.Class[]                                     parameterTypes;
+ * 7.  java.lang.Class[]                                     exceptionTypes;
+ * 8.  int                                                   modifiers;
+ * 9.  java.lang.String                                      signature;
+ * 10  sun.reflect.generics.repository.ConstructorRepository genericInfo;
+ * 11. byte[]                                                annotations;
+ * 12. byte[]                                                parameterAnnotations;
+ * 13. byte[]                                                annotationDefault;
+ * 14. sun.reflect.MethodAccessor                            methodAccessor;
+ * 15. java.lang.reflect.Method                              root;
+ * 16. java.lang.Class                                       securityCheckCache;
+ * 17. java.lang.Class                                       securityCheckTargetClassCache;
+ * 18. java.util.Map                                         declaredAnnotations;
+ */
+class java_lang_reflect_Method : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_override                      = MEMORY_ALIGN(sizeof(java_object_t),                                  sizeof(int32_t));
+       static const off_t offset_clazz                         = MEMORY_ALIGN(offset_override                      + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_slot                          = MEMORY_ALIGN(offset_clazz                         + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_name                          = MEMORY_ALIGN(offset_slot                          + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_returnType                    = MEMORY_ALIGN(offset_name                          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_parameterTypes                = MEMORY_ALIGN(offset_returnType                    + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_exceptionTypes                = MEMORY_ALIGN(offset_parameterTypes                + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_modifiers                     = MEMORY_ALIGN(offset_exceptionTypes                + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_signature                     = MEMORY_ALIGN(offset_modifiers                     + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_genericInfo                   = MEMORY_ALIGN(offset_signature                     + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_annotations                   = MEMORY_ALIGN(offset_genericInfo                   + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_parameterAnnotations          = MEMORY_ALIGN(offset_annotations                   + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_annotationDefault             = MEMORY_ALIGN(offset_parameterAnnotations          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_methodAccessor                = MEMORY_ALIGN(offset_annotationDefault             + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_root                          = MEMORY_ALIGN(offset_methodAccessor                + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_securityCheckCache            = MEMORY_ALIGN(offset_root                          + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_securityCheckTargetClassCache = MEMORY_ALIGN(offset_securityCheckCache            + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_declaredAnnotations           = MEMORY_ALIGN(offset_securityCheckTargetClassCache + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+
+public:
+       java_lang_reflect_Method(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_reflect_Method(jobject h);
+       java_lang_reflect_Method(methodinfo* m);
+
+       java_handle_t* invoke(java_handle_t* o, java_handle_objectarray_t* args);
+
+       // Getters.
+       inline int32_t                  get_override            () const;
+       inline classinfo*               get_clazz               () const;
+       inline int32_t                  get_slot                () const;
+       inline java_handle_bytearray_t* get_annotations         () const;
+       inline java_handle_bytearray_t* get_parameterAnnotations() const;
+       inline java_handle_bytearray_t* get_annotationDefault   () const;
+
+       // Setters.
+
+       // Convenience functions.
+       inline methodinfo* get_method() const;
+};
+
+
+inline java_lang_reflect_Method::java_lang_reflect_Method(jobject h) : java_lang_Object(h)
+{
+       java_lang_reflect_Method((java_handle_t*) h);
+}
+
+inline java_lang_reflect_Method::java_lang_reflect_Method(methodinfo* m)
+{
+       _handle = builtin_new(class_java_lang_reflect_Method);
+
+       if (is_null())
+               return;
+
+       set(_handle, offset_clazz, m->clazz);
+       set(_handle, offset_slot,  m - m->clazz->methods);
+       set(_handle, offset_name,  javastring_intern(javastring_new(m->name)));
+       set(_handle, offset_returnType,           method_returntype_get(m));
+       set(_handle, offset_parameterTypes,       method_get_parametertypearray(m));
+       set(_handle, offset_exceptionTypes,       method_get_exceptionarray(m));
+       set(_handle, offset_modifiers,            m->flags & ACC_CLASS_REFLECT_MASK);
+       set(_handle, offset_signature,            m->signature ? javastring_new(m->signature) : NULL);
+       set(_handle, offset_annotations,          method_get_annotations(m));
+       set(_handle, offset_parameterAnnotations, method_get_parameterannotations(m));
+       set(_handle, offset_annotationDefault,    method_get_annotationdefault(m));
+}
+
+
+inline int32_t java_lang_reflect_Method::get_override() const
+{
+       return get<int32_t>(_handle, offset_override);
+}
+
+inline classinfo* java_lang_reflect_Method::get_clazz() const
+{
+       return get<classinfo*>(_handle, offset_clazz);
+}
+
+inline int32_t java_lang_reflect_Method::get_slot() const
+{
+       return get<int32_t>(_handle, offset_slot);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_Method::get_annotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_annotations);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_Method::get_parameterAnnotations() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_parameterAnnotations);
+}
+
+inline java_handle_bytearray_t* java_lang_reflect_Method::get_annotationDefault() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_annotationDefault);
+}
+
+
+inline methodinfo* java_lang_reflect_Method::get_method() const
+{
+       classinfo*  c    = get_clazz();
+       int32_t     slot = get_slot();
+       methodinfo* m    = &(c->methods[slot]);
+       return m;
+}
+
+
+/**
+ * OpenJDK java/nio/Buffer
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. int  mark;
+ * 2. int  position;
+ * 3. int  limit;
+ * 4. int  capacity;
+ * 5. long address;
+ */
+class java_nio_Buffer : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_mark     = MEMORY_ALIGN(sizeof(java_object_t),          sizeof(int32_t));
+       static const off_t offset_position = MEMORY_ALIGN(offset_mark     + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_limit    = MEMORY_ALIGN(offset_position + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_capacity = MEMORY_ALIGN(offset_limit    + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_address  = MEMORY_ALIGN(offset_capacity + sizeof(int32_t), sizeof(int64_t));
+
+public:
+       java_nio_Buffer(java_handle_t* h) : java_lang_Object(h) {}
+       java_nio_Buffer(jobject h) : java_lang_Object(h) {}
+
+       // Getters.
+       inline void* get_address() const;
+};
+
+
+inline void* java_nio_Buffer::get_address() const
+{
+       return get<void*>(_handle, offset_address);
+}
+
+#endif // WITH_JAVA_RUNTIME_LIBRARY_OPENJDK
+
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+/**
+ * CLDC 1.1 com/sun/cldchi/jvm/FileDescriptor
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. long   pointer;
+ * 2. int    position;
+ * 3. int    length;
+ */
+class com_sun_cldchi_jvm_FileDescriptor : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_pointer  = MEMORY_ALIGN(sizeof(java_object_t),             sizeof(int64_t));
+       static const off_t offset_position = MEMORY_ALIGN(offset_pointer  + sizeof(int64_t), sizeof(int32_t));
+       static const off_t offset_length   = MEMORY_ALIGN(offset_position + sizeof(int32_t), sizeof(int32_t));
+
+public:
+       com_sun_cldchi_jvm_FileDescriptor(java_handle_t* h) : java_lang_Object(h) {}
+       com_sun_cldchi_jvm_FileDescriptor(jobject h);
+       com_sun_cldchi_jvm_FileDescriptor(java_handle_t* h, int64_t pointer, int32_t position, int32_t length);
+       com_sun_cldchi_jvm_FileDescriptor(java_handle_t* h, com_sun_cldchi_jvm_FileDescriptor& fd);
+
+       // Getters.
+       inline int64_t get_pointer () const;
+       inline int32_t get_position() const;
+       inline int32_t get_length  () const;
+
+       // Setters.
+       inline void set_pointer (int64_t value);
+       inline void set_position(int32_t value);
+       inline void set_length  (int32_t value);
+};
+
+
+inline com_sun_cldchi_jvm_FileDescriptor::com_sun_cldchi_jvm_FileDescriptor(jobject h) : java_lang_Object(h)
+{
+       com_sun_cldchi_jvm_FileDescriptor((java_handle_t*) h);
+}
+
+inline com_sun_cldchi_jvm_FileDescriptor::com_sun_cldchi_jvm_FileDescriptor(java_handle_t* h, int64_t pointer, int32_t position, int32_t length) : java_lang_Object(h)
+{
+       set_pointer(pointer);
+       set_position(position);
+       set_length(length);
+}
+
+inline com_sun_cldchi_jvm_FileDescriptor::com_sun_cldchi_jvm_FileDescriptor(java_handle_t* h, com_sun_cldchi_jvm_FileDescriptor& fd) : java_lang_Object(h)
+{
+       com_sun_cldchi_jvm_FileDescriptor(h, fd.get_pointer(), fd.get_position(), fd.get_length());
+}
+
+
+inline int64_t com_sun_cldchi_jvm_FileDescriptor::get_pointer() const
+{
+       return get<int64_t>(_handle, offset_pointer);
+}
+
+inline int32_t com_sun_cldchi_jvm_FileDescriptor::get_position() const
+{
+       return get<int32_t>(_handle, offset_position);
+}
+
+inline int32_t com_sun_cldchi_jvm_FileDescriptor::get_length() const
+{
+       return get<int32_t>(_handle, offset_length);
+}
+
+
+inline void com_sun_cldchi_jvm_FileDescriptor::set_pointer(int64_t value)
+{
+       set(_handle, offset_pointer, value);
+}
+
+inline void com_sun_cldchi_jvm_FileDescriptor::set_position(int32_t value)
+{
+       set(_handle, offset_position, value);
+}
+
+inline void com_sun_cldchi_jvm_FileDescriptor::set_length(int32_t value)
+{
+       set(_handle, offset_length, value);
+}
+
+
+/**
+ * CLDC 1.1 java/lang/String
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. char[] value;
+ * 2. int    offset;
+ * 3. int    count;
+ */
+class java_lang_String : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_value  = MEMORY_ALIGN(sizeof(java_object_t),           SIZEOF_VOID_P);
+       static const off_t offset_offset = MEMORY_ALIGN(offset_value  + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_count  = MEMORY_ALIGN(offset_offset + sizeof(int32_t), sizeof(int32_t));
+
+public:
+       java_lang_String(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_String(jstring h);
+       java_lang_String(java_handle_t* h, java_handle_chararray_t* value, int32_t count, int32_t offset = 0);
+
+       // Getters.
+       inline java_handle_chararray_t* get_value () const;
+       inline int32_t                  get_offset() const;
+       inline int32_t                  get_count () const;
+
+       // Setters.
+       inline void set_value (java_handle_chararray_t* value);
+       inline void set_offset(int32_t value);
+       inline void set_count (int32_t value);
+};
+
+inline java_lang_String::java_lang_String(jstring h) : java_lang_Object(h)
+{
+       java_lang_String((java_handle_t*) h);
+}
+
+inline java_lang_String::java_lang_String(java_handle_t* h, java_handle_chararray_t* value, int32_t count, int32_t offset) : java_lang_Object(h)
+{
+       set_value(value);
+       set_offset(offset);
+       set_count(count);
+}
+
+inline java_handle_chararray_t* java_lang_String::get_value() const
+{
+       return get<java_handle_chararray_t*>(_handle, offset_value);
+}
+
+inline int32_t java_lang_String::get_offset() const
+{
+       return get<int32_t>(_handle, offset_offset);
+}
+
+inline int32_t java_lang_String::get_count() const
+{
+       return get<int32_t>(_handle, offset_count);
+}
+
+inline void java_lang_String::set_value(java_handle_chararray_t* value)
+{
+       set(_handle, offset_value, value);
+}
+
+inline void java_lang_String::set_offset(int32_t value)
+{
+       set(_handle, offset_offset, value);
+}
+
+inline void java_lang_String::set_count(int32_t value)
+{
+       set(_handle, offset_count, value);
+}
+
+
+/**
+ * CLDC 1.1 java/lang/Thread
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. int                priority;
+ * 2. java.lang.Runnable runnable;
+ * 3. java.lang.Object   vm_thread;
+ * 4. int                is_terminated;
+ * 5. int                is_stillborn;
+ * 6. char[]             name;
+ */
+class java_lang_Thread : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_priority      = MEMORY_ALIGN(sizeof(java_object_t),              sizeof(int32_t));
+       static const off_t offset_runnable      = MEMORY_ALIGN(offset_priority      + sizeof(int32_t), SIZEOF_VOID_P);
+       static const off_t offset_vm_thread     = MEMORY_ALIGN(offset_runnable      + SIZEOF_VOID_P,   SIZEOF_VOID_P);
+       static const off_t offset_is_terminated = MEMORY_ALIGN(offset_vm_thread     + SIZEOF_VOID_P,   sizeof(int32_t));
+       static const off_t offset_is_stillborn  = MEMORY_ALIGN(offset_is_terminated + sizeof(int32_t), sizeof(int32_t));
+       static const off_t offset_name          = MEMORY_ALIGN(offset_is_stillborn  + sizeof(int32_t), SIZEOF_VOID_P);
+
+public:
+       java_lang_Thread(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_Thread(jobject h);
+//     java_lang_Thread(threadobject* t);
+
+       // Getters.
+       inline int32_t                  get_priority () const;
+       inline threadobject*            get_vm_thread() const;
+       inline java_handle_chararray_t* get_name     () const;
+
+       // Setters.
+       inline void set_vm_thread(threadobject* value);
+};
+
+
+inline java_lang_Thread::java_lang_Thread(jobject h) : java_lang_Object(h)
+{
+       java_lang_Thread((java_handle_t*) h);
+}
+
+// inline java_lang_Thread::java_lang_Thread(threadobject* t) : java_lang_Object(h)
+// {
+//     java_lang_Thread(thread_get_object(t));
+// }
+
+
+inline int32_t java_lang_Thread::get_priority() const
+{
+       return get<int32_t>(_handle, offset_priority);
+}
+
+inline threadobject* java_lang_Thread::get_vm_thread() const
+{
+       return get<threadobject*>(_handle, offset_vm_thread);
+}
+
+inline java_handle_chararray_t* java_lang_Thread::get_name() const
+{
+       return get<java_handle_chararray_t*>(_handle, offset_name);
+}
+
+
+inline void java_lang_Thread::set_vm_thread(threadobject* value)
+{
+       set(_handle, offset_vm_thread, value);
+}
+
+
+/**
+ * CLDC 1.1 java/lang/Throwable
+ *
+ * Object layout:
+ *
+ * 0. object header
+ * 1. java.lang.String detailMessage;
+ * 2. java.lang.Object backtrace;
+ */
+class java_lang_Throwable : public java_lang_Object, private FieldAccess {
+private:
+       // Static offsets of the object's instance fields.
+       // TODO These offsets need to be checked on VM startup.
+       static const off_t offset_detailMessage = MEMORY_ALIGN(sizeof(java_object_t),                SIZEOF_VOID_P);
+       static const off_t offset_backtrace     = MEMORY_ALIGN(offset_detailMessage + SIZEOF_VOID_P, SIZEOF_VOID_P);
+
+public:
+       java_lang_Throwable(java_handle_t* h) : java_lang_Object(h) {}
+       java_lang_Throwable(jobject h);
+
+       // Getters.
+       inline java_handle_t*           get_detailMessage() const;
+       inline java_handle_bytearray_t* get_backtrace    () const;
+
+       // Setters.
+       inline void set_backtrace(java_handle_bytearray_t* value);
+};
+
+
+inline java_lang_Throwable::java_lang_Throwable(jobject h) : java_lang_Object(h)
+{
+       java_lang_Throwable((java_handle_t*) h);
+}
+
+
+inline java_handle_t* java_lang_Throwable::get_detailMessage() const
+{
+       return get<java_handle_t*>(_handle, offset_detailMessage);
+}
+
+inline java_handle_bytearray_t* java_lang_Throwable::get_backtrace() const
+{
+       return get<java_handle_bytearray_t*>(_handle, offset_backtrace);
+}
+
+
+inline void java_lang_Throwable::set_backtrace(java_handle_bytearray_t* value)
+{
+       set(_handle, offset_backtrace, value);
+}
+
+#endif // WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1
+
+#else
+
+// Legacy C interface.
+java_handle_t* java_lang_reflect_Constructor_create(methodinfo* m);
+java_handle_t* java_lang_reflect_Field_create(fieldinfo* f);
+java_handle_t* java_lang_reflect_Method_create(methodinfo* m);
+
+#endif
+
+#endif // _JAVAOBJECTS_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:
+ */
index 5c2aada1d2d70c77921b87dd4b2d6102fb562626..cd7d5852b1f134b7fb9e7cdf235db10be2e4c537 100644 (file)
@@ -135,6 +135,13 @@ VERIFIER_LIB = \
        verify/libverify.la
 endif
 
+if ENABLE_OPAGENT
+OPAGENT_SOURCES = \
+       oprofile-agent.cpp \
+       oprofile-agent.hpp
+
+endif
+
 if WITH_BINUTILS_DISASSEMBLER
 DISASS_SOURCES = disass-common.c
 endif
@@ -183,11 +190,12 @@ libjit_la_SOURCES = \
        show.c \
        show.h \
        $(STACK_SOURCES) \
-       stacktrace.c \
-       stacktrace.h \
-       trace.c \
-       trace.h \
-       $(TRAP_SOURCES)
+       stacktrace.cpp \
+       stacktrace.hpp \
+       trace.cpp \
+       trace.hpp \
+       $(TRAP_SOURCES) \
+       $(OPAGENT_SOURCES)
 
 libjit_la_SOURCES += \
        cfg.c \
index 5a0e1da95539354da4a5c092039ee7364de06f62..d6d6acc1002aef18fa983f49d241ab026391d7c2 100644 (file)
@@ -36,7 +36,7 @@
 #include "toolbox/worklist.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/method.h"
 #include "vm/resolve.h"
index 0ac20d24b929c59ad6b17e4b16b540b0bde8529f..d8b122157b698e4ea4b458186e51342ca0c10e14 100644 (file)
 #include "vm/types.h"
 
 #include "mm/memory.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/resolve.h"
 #include "vm/options.h"
 #include "vm/statistics.h"
-#include "vm/stringlocal.h"
+
 #include "vm/jit/abi.h"
 #include "vm/jit/reg.h"
+
 #include "vm/jit/allocator/liveness.h"
 #include "vm/jit/allocator/lsra.h"
 
index f8cbcab9dcb7ecbfe8b2922ac58528c0b57e5d1f..d8ccdfa092731464d45867a3a78bc38760371f51 100644 (file)
 #include "mm/memory.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
+#include "vm/method.h"
+#include "vm/options.h"
 #include "vm/resolve.h"
-#include "vm/stringlocal.h"
+#include "vm/string.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/show.h"
 #include "vm/jit/allocator/simplereg.h"
 
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-
 
 #if 0
 #    define LOG(args) printf args
index cd4e0f470162efcf4cae8b40bd4f9d8d9f8e978f..d9ba3e434584689c3695ec832249380eed2b51aa 100644 (file)
@@ -34,9 +34,9 @@ LIBS =
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h \
        \
-       md-asm.h
+       md-asm.h \
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = libarch.la
 
index b05a8afcd100b2cbd5781f1c4baa6cd30d359e35..11fa64576c3f8564ce10b2caaa65a2fe9b977a0c 100644 (file)
@@ -54,9 +54,6 @@
 
        .globl asm_abstractmethoderror
 
-       .globl asm_compare_and_swap
-       .globl asm_memory_barrier
-
        .globl asm_md_init
        .globl asm_cacheflush
 
@@ -339,52 +336,6 @@ asm_abstractmethoderror:
        .end    asm_abstractmethoderror
 
 
-/* asm_compare_and_swap ********************************************************
-
-   Does an atomic compare and swap.  Required for the lock
-   implementation.
-
-   Atomically do the following: Check if the location still contains
-   `oldval`. If so, replace it by `newval` and return `oldval`.
-
-   RETURN VALUE:
-       the old value at *p
-
-   long compare_and_swap(volatile long *p, long oldval, long newval);
-
-*******************************************************************************/
-
-       .ent    asm_compare_and_swap
-
-asm_compare_and_swap:
-1:
-       ldq_l   v0,0(a0)
-       cmpeq   v0,a1,t0
-       beq     t0,2f
-       mov     a2,t0
-       stq_c   t0,0(a0)
-       beq     t0,1b
-2:
-       jmp     zero,(ra)
-
-       .end    asm_compare_and_swap
-
-
-/* asm_memory_barrier **********************************************************
-
-   A memory barrier for the Java Memory Model.
-
-*******************************************************************************/
-
-       .ent    asm_memory_barrier
-
-asm_memory_barrier:
-       mb
-       jmp     zero,(ra)
-
-       .end    asm_memory_barrier
-
-
 /* asm_md_init *****************************************************************
 
    Initialize machine dependent stuff.
index e30d7d601b5702a0ebdfc0c2eb1ca79ce97a1331..8457be0feb9170065c39ac792281e44cbeea7426 100644 (file)
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
@@ -60,7 +62,7 @@
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 #if defined(ENABLE_SSA)
@@ -70,9 +72,6 @@
 # include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 
 /* codegen_emit ****************************************************************
 
@@ -2709,9 +2708,6 @@ gen_method:
                                        superindex = super->index;
                                }
 
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -2783,8 +2779,6 @@ gen_method:
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ALD(REG_ITMP3, REG_PV, disp);
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                        /*                              if (s1 != REG_ITMP1) { */
                                        /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
@@ -2800,8 +2794,6 @@ gen_method:
                                        M_ALD(REG_ITMP3, REG_PV, disp);
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
 
-                                       CODEGEN_CRITICAL_SECTION_END;
-
                                        /*                              } */
                                        M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
                                        emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
@@ -2869,9 +2861,6 @@ gen_method:
                                supervftbl = super->vftbl;
                        }
 
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
 
@@ -2954,14 +2943,10 @@ gen_method:
                                M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_ITMP2, REG_PV, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
                                M_CMPULE(REG_ITMP1, REG_ITMP2, d);
 
@@ -3236,7 +3221,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument register */
 
-               disp = dseg_add_address(cd, _Jv_env);
+               disp = dseg_add_address(cd, VM_get_jnienv());
                M_ALD(REG_A0, REG_PV, disp);
        }
 
index f0d1b7c8967e54335b258afce0b2c0e1d0265fc5..4f2f540d8304bf783c1a443d0e09eec7455399b6 100644 (file)
@@ -37,6 +37,8 @@
 
 #include "threads/lock-common.h"
 
+#include "vm/options.h"
+
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
-#include "vmcore/options.h"
-
 
 /* emit_load *******************************************************************
 
index 10deba916971329c656e275b2405e1054bcedd78..e60626f3fabaff75554193c6a5b7560da4c5a62b 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/alpha/freebsd/md.c - machine dependent Alpha FreeBSD functions
+/* src/vm/jit/alpha/freebsd/md-os.c - machine dependent Alpha FreeBSD functions
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
 */
 
 
 
 #include "vm/jit/alpha/md-abi.h"
 
-#include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
 #include "vm/jit/asmpart.h"
 
 
@@ -95,22 +85,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
-#if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       void       *critical;
-
-       _mc = &_uc->uc_mcontext;
-
-       critical = critical_find_restart_point((void *) _mc->mc_regs[R_PC]);
-
-       if (critical)
-               _mc->mc_regs[R_PC] = (ptrint) critical;
-}
-#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
index afe391d11b2b86b0abc946d0a0ff509ff7ff80e1..d752d57fccde5d6ebd348be135b1db39918ef00e 100644 (file)
 #include "vm/jit/alpha/md.h"
 #include "vm/jit/alpha/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/signallocal.h"
+#include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
-#include "vm/jit/stacktrace.h"
 #include "vm/jit/trap.h"
 
-#include "vmcore/system.h"
-
 
 /* md_signal_handler_sigsegv ***************************************************
 
@@ -237,7 +235,7 @@ void md_executionstate_read(executionstate_t *es, void *context)
         * the _mc->sc_fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs));
-       system_memcpy(&es->fltregs, &_mc->sc_fpregs, sizeof(_mc->sc_fpregs));
+       os_memcpy(&es->fltregs, &_mc->sc_fpregs, sizeof(_mc->sc_fpregs));
 }
 
 
@@ -265,7 +263,7 @@ void md_executionstate_write(executionstate_t *es, void *context)
         * the _mc->sc_fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs));
-       system_memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs));
+       os_memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs));
 
        /* write special registers */
        _mc->sc_pc           = (ptrint) es->pc;
@@ -275,32 +273,6 @@ void md_executionstate_write(executionstate_t *es, void *context)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       u1         *pc;
-       u1         *npc;
-
-       _mc = &_uc->uc_mcontext;
-
-       pc = (u1 *) _mc->sc_pc;
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL)
-               _mc->sc_pc = (ptrint) npc;
-}
-#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
diff --git a/src/vm/jit/alpha/machine-instr.h b/src/vm/jit/alpha/machine-instr.h
deleted file mode 100644 (file)
index 3d054e1..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-static inline long
-__attribute__ ((unused))
-compare_and_swap (volatile long *p, long oldval, long newval)
-{
-  long ret, temp;
-
-  __asm__ __volatile__ (
-    "1:\t"
-    "ldq_l  %0,%5\n\t"
-    "cmpeq  %0,%3,%2\n\t"
-    "beq    %2,2f\n\t"
-    "mov    %4,%2\n\t"
-    "stq_c  %2,%1\n\t"
-    "beq    %2,1b\n\t"
-    "2:\t"
-    : "=&r"(ret), "=m"(*p), "=&r"(temp)
-    : "r"(oldval), "r"(newval), "m"(*p));
-
-  return ret;
-}
-
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("wmb" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
-#define MEMORY_BARRIER() __asm__ __volatile__ ( \
-               "mb" : : : "memory" );
-
-#endif
index 90189e17ae6d47338e9eedd43eb6fa902785ab18..496834761c646923fdd60750d8c98553d8ae80fd 100644 (file)
 
 #include "vm/jit/alpha/md-abi.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 
-#include "vmcore/descriptor.h"
-
 
 /* register descripton array **************************************************/
 
diff --git a/src/vm/jit/alpha/md-atomic.hpp b/src/vm/jit/alpha/md-atomic.hpp
new file mode 100644 (file)
index 0000000..962852a
--- /dev/null
@@ -0,0 +1,152 @@
+/* src/vm/jit/alpha/atomic.hpp - Alpha atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       uint32_t temp;
+       uint32_t result;
+
+       __asm__ __volatile__ (
+               "1:                   \n"
+               "    ldl_l  %0,%5     \n"
+               "    cmpeq  %0,%3,%2  \n"
+               "    beq    %2,2f     \n"
+               "    mov    %4,%2     \n"
+               "    stl_c  %2,%1     \n"
+               "    beq    %2,1b     \n"
+               "2:                   \n"
+               : "=&r" (result), "=m" (*p), "=&r" (temp)
+               : "r" (oldval), "r" (newval), "m" (*p));
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       uint64_t temp;
+       uint64_t result;
+
+       __asm__ __volatile__ (
+               "1:                   \n"
+               "    ldq_l  %0,%5     \n"
+               "    cmpeq  %0,%3,%2  \n"
+               "    beq    %2,2f     \n"
+               "    mov    %4,%2     \n"
+               "    stq_c  %2,%1     \n"
+               "    beq    %2,1b     \n"
+               "2:                   \n"
+               : "=&r" (result), "=m" (*p), "=&r" (temp)
+               : "r" (oldval), "r" (newval), "m" (*p));
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return (void*) compare_and_swap((volatile uint64_t*) p, (uint64_t) oldval, (uint64_t) newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("mb" : : : "memory");
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("wmb" : : : "memory");
+}
+
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       __asm__ __volatile__ ("mb" : : : "memory");
+}
+
+#endif // _MD_ATOMIC_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 c932579dc7bc09ef7ca91bae707d391ab2622ca5..e6947d80eee0c47a352524fd3bf6fda6757ab60a 100644 (file)
@@ -58,6 +58,7 @@ enum {
        /* Don't use 8 (could be a normal load offset). */
 
        TRAP_COMPILER                       = 9,
+       TRAP_COUNTDOWN                      = 10,
        TRAP_END
 };
 
index 4899d8f9ffd15d347773cd52eb5a4575ff4f8d57..da186e3c0560a7efcf4c197104056e0f82ed8573 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/alpha/md.h - machine dependent Alpha functions
 
-   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.
 
@@ -36,7 +34,7 @@
 #include "vm/jit/alpha/codegen.h"
 
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
index f990bbe99fdcac16251520844b4b0d69f25646fd..0e981a090e92ecbe28245a668f74441cac933023 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/methodheader.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
-#include "vm/resolve.h"
 
 
 #define PATCH_BACK_ORIGINAL_MCODE \
index 8705e6be13cedcb8e1a9c0302df135e706b62d19..dbee5fa9597a373d64eef0c045cb3a5bca87294c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/argument.c - argument passing from and to JIT methods
 
-   Copyright (C) 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) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 #include "native/llni.h"
 
 #include "vm/array.h"
+#include "vm/descriptor.h"
 #include "vm/global.h"
-#include "vm/primitive.h"
+#include "vm/method.h"
+#include "vm/primitive.hpp"
 #include "vm/resolve.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi-asm.h"
 
-#include "vmcore/descriptor.h"
-#include "vmcore/method.h"
-
 
 /* argument_jitarray_load ******************************************************
  
@@ -500,7 +497,7 @@ uint64_t *argument_vmarray_from_jvalue(methodinfo *m, java_handle_t *o,
        } 
 
        for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
-               switch (td->decltype) {
+               switch (td->primitivetype) {
                case TYPE_INT:
                        argument_vmarray_store_int(array, pd, args[j].i);
                        break;
@@ -599,9 +596,9 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                        /* convert the value according to its declared type */
 
                        LLNI_class_get(param, c);
-                       type = primitive_type_get_by_wrapperclass(c);
+                       type = Primitive_get_type_by_wrapperclass(c);
 
-                       switch (td->decltype) {
+                       switch (td->primitivetype) {
                        case PRIMITIVETYPE_BOOLEAN:
                                switch (type) {
                                case PRIMITIVETYPE_BOOLEAN:
@@ -657,10 +654,10 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
 
                        default:
                                vm_abort("argument_vmarray_from_objectarray: invalid type %d",
-                                                td->decltype);
+                                                td->primitivetype);
                        }
 
-                       value = primitive_unbox(param);
+                       value = Primitive_unbox(param);
                        argument_vmarray_store_int(array, pd, value.i);
                        break;
 
@@ -669,9 +666,9 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                                return NULL;
 
                        LLNI_class_get(param, c);
-                       type = primitive_type_get_by_wrapperclass(c);
+                       type = Primitive_get_type_by_wrapperclass(c);
 
-                       assert(td->decltype == PRIMITIVETYPE_LONG);
+                       assert(td->primitivetype == PRIMITIVETYPE_LONG);
 
                        switch (type) {
                        case PRIMITIVETYPE_BYTE:
@@ -684,7 +681,7 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                                return NULL;
                        }
 
-                       value = primitive_unbox(param);
+                       value = Primitive_unbox(param);
                        argument_vmarray_store_lng(array, pd, value.l);
                        break;
 
@@ -693,9 +690,9 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                                return NULL;
 
                        LLNI_class_get(param, c);
-                       type = primitive_type_get_by_wrapperclass(c);
+                       type = Primitive_get_type_by_wrapperclass(c);
 
-                       assert(td->decltype == PRIMITIVETYPE_FLOAT);
+                       assert(td->primitivetype == PRIMITIVETYPE_FLOAT);
 
                        switch (type) {
                        case PRIMITIVETYPE_FLOAT:
@@ -705,7 +702,7 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                                return NULL;
                        }
 
-                       value = primitive_unbox(param);
+                       value = Primitive_unbox(param);
                        argument_vmarray_store_flt(array, pd, value.l);
                        break;
 
@@ -714,9 +711,9 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                                return NULL;
 
                        LLNI_class_get(param, c);
-                       type = primitive_type_get_by_wrapperclass(c);
+                       type = Primitive_get_type_by_wrapperclass(c);
 
-                       assert(td->decltype == PRIMITIVETYPE_DOUBLE);
+                       assert(td->primitivetype == PRIMITIVETYPE_DOUBLE);
 
                        switch (type) {
                        case PRIMITIVETYPE_FLOAT:
@@ -727,7 +724,7 @@ uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                                return NULL;
                        }
 
-                       value = primitive_unbox(param);
+                       value = Primitive_unbox(param);
                        argument_vmarray_store_dbl(array, pd, value.l);
                        break;
                
index 3c1c53c271cdd99acb918fba2b9b82df6e8fcd77..fe6ef25fa50a18035ea916ddd325665e5daff7da 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/argument.h - argument passing from and to JIT methods
 
-   Copyright (C) 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) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/global.h"
 
 
@@ -54,6 +56,10 @@ uint64_t *argument_vmarray_from_jvalue(methodinfo *m, java_handle_t *o,
 uint64_t *argument_vmarray_from_objectarray(methodinfo *m, java_handle_t *o,
                                                                                        java_handle_objectarray_t *params);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _VM_JIT_ARGUMENT_H */
 
 
index 5955ff12e0797bfd625b540da05f9c45f97af159..de85844084064d535b394a210a82840bea7d23be 100644 (file)
@@ -31,8 +31,8 @@ AM_CCASFLAGS = $(AM_CPPFLAGS)
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h \
-       md-asm.h
+       md-asm.h \
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = libarch.la
 
index 88dfc8f74d3a3c2e503018aba1ae986ed98c4034..d3f4b93fdddcc5802cb94e47dfe1b484b5dd327c 100644 (file)
@@ -78,8 +78,8 @@
 asm_vm_call_method:
 asm_vm_call_method_int:
 asm_vm_call_method_long:
-/* asm_vm_call_method_float:
-asm_vm_call_method_double: */
+asm_vm_call_method_float:
+asm_vm_call_method_double:
        SAVE_SCRATCH_REGISTERS            /* save our personal scratch regs   */
        stmfd sp!, {v1}                   /* V1 is used to remember SP        */
        str   a0, [sp, #-4]!              /* store methods entrypoint         */
@@ -134,13 +134,6 @@ asm_vm_call_method_exception_handler:
        ldmfd sp!, {v1}
        RESTORE_SCRATCH_REGS_AND_RETURN   /* return to caller, restore regs   */
 
-asm_vm_call_method_float:
-       mov a0,#0x51
-       b asm_debug
-asm_vm_call_method_double:
-       mov a0,#0x52
-       b asm_debug
-
 asm_vm_call_method_end:
 
 
index 41bccef1bb0553be650dcb28762542b76b7e637a..0ba33473cc0c116f42714be81bf3c8303a287d07 100644 (file)
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
@@ -64,9 +66,6 @@
 #include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 
 /* codegen_emit ****************************************************************
 
@@ -2457,9 +2456,6 @@ bool codegen_emit(jitdata *jd)
                                superindex = super->index;
                        }
 
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                        /* if class is not resolved, check which code to call */
@@ -2566,16 +2562,12 @@ bool codegen_emit(jitdata *jd)
                                M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                M_DSEG_LOAD(REG_ITMP3, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
                                M_SUB(REG_ITMP2, REG_ITMP2, REG_ITMP3);
                                M_DSEG_LOAD(REG_ITMP3, disp);
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_CMP(REG_ITMP2, REG_ITMP3);
                                emit_classcast_check(cd, iptr, BRANCH_UGT, 0, s1);
 
@@ -2644,9 +2636,6 @@ bool codegen_emit(jitdata *jd)
                                superindex = super->index;
                        }
 
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
 
@@ -2773,14 +2762,10 @@ bool codegen_emit(jitdata *jd)
                                M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_DSEG_LOAD(REG_ITMP2, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_LDR_INTERN(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_SUB(REG_ITMP1, REG_ITMP1, REG_ITMP3);
                                M_CMP(REG_ITMP1, REG_ITMP2);
                                /* If d == REG_ITMP2, then it's destroyed */
@@ -3075,7 +3060,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument register */
 
-               disp = dseg_add_address(cd, _Jv_env);
+               disp = dseg_add_address(cd, VM_get_jnienv());
                M_DSEG_LOAD(REG_A0, disp);
        }
 
index 293731cfc473c70f509f46f2cbaf1f5fe3e475f9..f27c558dfc61e2bbbe2386c1570b50389054249f 100644 (file)
@@ -38,7 +38,6 @@
 
 #include "threads/lock-common.h"
 
-#include "vm/exceptions.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
@@ -47,7 +46,7 @@
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
 #include "toolbox/logging.h" /* XXX for debugging only */
index 37aaabcdc46f8a151b9b4a7624faf3e6873825fd..191605bb7bb79a3f34ba71e57bd8c48c7745a919 100644 (file)
@@ -49,16 +49,14 @@ typedef struct ucontext {
 
 #define scontext_t struct sigcontext
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
-#include "vm/exceptions.h"
+#include "vm/os.hpp"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
-#include "vm/jit/stacktrace.h"
 #include "vm/jit/trap.h"
 
 
@@ -266,7 +264,7 @@ void md_executionstate_read(executionstate_t *es, void *context)
         * the _mc->sc_fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs));
-       system_memcpy(&es->fltregs, &_mc->sc_fpregs, sizeof(_mc->sc_fpregs));
+       os_memcpy(&es->fltregs, &_mc->sc_fpregs, sizeof(_mc->sc_fpregs));
 #endif
 }
 
@@ -298,7 +296,7 @@ void md_executionstate_write(executionstate_t *es, void *context)
         * the _mc->sc_fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs));
-       system_memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs));
+       os_memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs));
 
        /* write special registers */
        _mc->sc_pc           = (ptrint) es->pc;
@@ -309,32 +307,6 @@ void md_executionstate_write(executionstate_t *es, void *context)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       scontext_t *_sc;
-       u1         *pc;
-       u1         *npc;
-
-       _sc = &_uc->uc_mcontext;
-
-       pc = (u1 *) _sc->arm_pc;
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL)
-               _sc->arm_pc = (ptrint) npc;
-}
-#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
diff --git a/src/vm/jit/arm/machine-instr.h b/src/vm/jit/arm/machine-instr.h
deleted file mode 100644 (file)
index 82fba29..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-static inline long compare_and_swap(long *p, long oldval, long newval)
-{
-       long ret, temp;
-       /*dolog("compare_and_swap(%p [%d], %d, %d)", p, *p, oldval, newval);*/
-
-       /* TODO: improve this one! */
-       __asm__ __volatile__ (
-               "1:\t"
-               "ldr   %0,[%2]\n\t"
-               "cmp   %0,%4\n\t"
-               "bne   2f\n\t"
-               "swp   %1,%3,[%2]\n\t"
-               "cmp   %1,%0\n\t"
-               "swpne %0,%1,[%2]\n\t"
-               "bne   1b\n\t"
-               "2:"
-               : "=&r" (ret), "=&r" (temp)
-               : "r" (p), "r" (newval), "r" (oldval)
-               : "cc", "memory"
-       );
-
-       /*dolog("compare_and_swap() return=%d mem=%d", ret, *p);*/
-       return ret;
-}
-
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER() __asm__ __volatile__ ("" : : : "memory" );
-
-#endif
index b10d45665a84181304360d564ac1b6afadb580eb..bdf6a14f918d2debb0234f7a15315cfef23a0531 100644 (file)
 
 #include "vm/jit/arm/md-abi.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 
-#include "vmcore/descriptor.h"
-
 
 /* register descripton array **************************************************/
 
diff --git a/src/vm/jit/arm/md-atomic.hpp b/src/vm/jit/arm/md-atomic.hpp
new file mode 100644 (file)
index 0000000..81f0a39
--- /dev/null
@@ -0,0 +1,141 @@
+/* src/vm/jit/arm/atomic.hpp - ARM atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       uint32_t result;
+       uint32_t temp;
+
+       /* TODO: improve this one! */
+       __asm__ __volatile__ (
+               "1:\t"
+               "ldr   %0,[%2]\n\t"
+               "cmp   %0,%4\n\t"
+               "bne   2f\n\t"
+               "swp   %1,%3,[%2]\n\t"
+               "cmp   %1,%0\n\t"
+               "swpne %0,%1,[%2]\n\t"
+               "bne   1b\n\t"
+               "2:"
+               : "=&r" (result), "=&r" (temp)
+               : "r" (p), "r" (newval), "r" (oldval)
+               : "cc", "memory"
+       );
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       return generic_compare_and_swap(p, oldval, newval);
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return (void*) compare_and_swap((volatile uint32_t*) p, (uint32_t) oldval, (uint32_t) newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+#endif // _MD_ATOMIC_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 7992441b2e9be6a00aa414c8279b6f13c212e267..c94a8f73c553e4a6a0826b429c13d6e9a6ba4113 100644 (file)
@@ -50,7 +50,8 @@ enum {
        TRAP_ClassCastException             = 5,
        TRAP_CHECK_EXCEPTION                = 6,
        TRAP_PATCHER                        = 7,
-       TRAP_COMPILER                       = 8
+       TRAP_COMPILER                       = 8,
+       TRAP_COUNTDOWN                      = 9
 };
 
 #endif /* _MD_TRAP_H */
index d37b3a710cee1487c052c05e0b45191d0932b519..b150f1a14831499f59267ff14222b67708e1627d 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/arm/md.c - machine dependent Arm functions
+/* src/vm/jit/arm/md.c - machine dependent ARM functions
 
-   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.
 
@@ -138,6 +136,17 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr)
 }
 
 
+/**
+ * Patch the given replacement point.
+ */
+#if defined(ENABLE_REPLACEMENT)
+void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert)
+{
+       vm_abort("md_patch_replacement_point: IMPLEMENT ME!");
+}
+#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
index 04774df4e7d4ee3a35702442474ba72d8ba59163..ba9c1f7ee7823667e7e7ec8fd5eb8f3f9970a186 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/md.h - machine dependent Arm functions
 
-   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.
 
@@ -66,31 +64,33 @@ inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframe
 
 *******************************************************************************/
 
-inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
+inline static void* md_codegen_get_pv_from_pc(void* ra)
 {
-       u1 *pv;
-       u4  mcode1, mcode2, mcode3;
+       uint32_t* pc;
+       uintptr_t pv;
+       uint32_t mcode1, mcode2, mcode3;
 
-       pv = ra;
+       pc = (uint32_t*) ra;
+       pv = (uintptr_t) ra;
 
        /* this can either be a RECOMPUTE_IP in JIT code or a fake in asm_calljavafunction */
-       mcode1 = *((u4*) ra);
+       mcode1 = pc[0];
        if ((mcode1 & 0xffffff00) == 0xe24fcf00 /*sub ip,pc,#__*/)
-               pv -= (s4) ((mcode1 & 0x000000ff) <<  2);
+               pv -= (uintptr_t) ((mcode1 & 0x000000ff) << 2);
        else if ((mcode1 & 0xffffff00) == 0xe24fc000 /*sub ip,pc,#__*/)
-               pv -= (s4) (mcode1 & 0x000000ff);
+               pv -= (uintptr_t) (mcode1 & 0x000000ff);
        else {
                /* if this happens, we got an unexpected instruction at (*ra) */
                vm_abort("Unable to find method: %p (instr=%x)", ra, mcode1);
        }
 
        /* if we have a RECOMPUTE_IP there can be more than one instruction */
-       mcode2 = *((u4*) (ra + 4));
-       mcode3 = *((u4*) (ra + 8));
+       mcode2 = pc[1];
+       mcode3 = pc[2];
        if ((mcode2 & 0xffffff00) == 0xe24ccb00 /*sub ip,ip,#__*/)
-               pv -= (s4) ((mcode2 & 0x000000ff) << 10);
+               pv -= (uintptr_t) ((mcode2 & 0x000000ff) << 10);
        if ((mcode3 & 0xffffff00) == 0xe24cc700 /*sub ip,ip,#__*/)
-               pv -= (s4) ((mcode3 & 0x000000ff) << 18);
+               pv -= (uintptr_t) ((mcode3 & 0x000000ff) << 18);
 
        /* we used PC-relative adressing; but now it is LR-relative */
        pv += 8;
@@ -99,7 +99,7 @@ inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
        /* we check this by looking up the IsLeaf field, which has to be boolean */
 /*     assert( *((s4*)pv-8) == (s4)true || *((s4*)pv-8) == (s4)false );  */
 
-       return pv;
+       return (void*) pv;
 }
 
 
index 4c3ad2805bcf1472709253dd17f5d51a5637579a..8e5540343cf71ca05ef2355be2f9d7951dc2ceb8 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.h"
 
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
-#include "vm/resolve.h"
-
 
 #define PATCH_BACK_ORIGINAL_MCODE \
     *((u4 *) pr->mpc) = (u4) pr->mcode; \
index 8dea3aacc2030445d82d8c60fa3ee7e9cf8b4ec9..ecb44b785fd2b965f31466e0e213fffaca2af1b3 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/asmpart.h - prototypes for machine specfic functions
 
-   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.
 
 
 #include <stdint.h>
 
-#include "vm/types.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/critical.h"
+#ifdef __cplusplus
+extern "C" {
 #endif
 
-#include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/types.h"
 
-#include "vmcore/linker.h"
+#include "vm/global.h"
+#include "vm/vm.hpp"
 
 
 /* function prototypes ********************************************************/
@@ -103,11 +99,8 @@ void intrp_asm_abstractmethoderror(void);
 /* wrapper for code patching functions */
 void asm_patcher_wrapper(void);
 
-long asm_compare_and_swap(volatile long *p, long oldval, long newval);
-void asm_memory_barrier(void);
-
 /* cache flush function */
-void asm_cacheflush(u1 *addr, s4 nbytes);
+void asm_cacheflush(void* addr, int nbytes);
 
 u8 asm_get_cycle_count(void);
 
@@ -117,6 +110,10 @@ void *md_asm_codegen_get_pv_from_pc(void *ra);
 void asm_escape_check(java_object_t *obj);
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _ASMPART_H */
 
 
index 652e200970461fc6d6531c460f30a62cd6935182..da46ee966b02b3beadb2ee23c3391c9a4e7f89dc 100644 (file)
@@ -501,6 +501,21 @@ void cfg_add_root(jitdata *jd) {
        }
 }
 
+void cfg_remove_root(jitdata *jd) {
+       basicblock *root, *zero, *it;
+
+       root = jd->basicblocks;
+       zero = root->next;
+
+       zero->predecessorcount -= 1;
+
+       jd->basicblocks = zero;
+
+       for (it = zero; it; it = it->next) {
+               it->nr -= 1;
+       }
+}
+
 #if defined(ENABLE_SSA)
 
 static void cfg_eliminate_edges_to_unreachable(jitdata *jd);
index 0a7e70cc589b0f975f1821a26f64c0762595d8a5..750de64137fc373abecddf8bc996c03c0640b0e5 100644 (file)
@@ -32,7 +32,8 @@
 
 #include "mm/memory.h"
 
-#include "vm/vm.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/code.h"
 #include "vm/jit/codegen-common.h"
@@ -40,8 +41,6 @@
 #include "vm/jit/methodtree.h"
 #include "vm/jit/patcher-common.h"
 
-#include "vmcore/options.h"
-
 
 /* code_init *******************************************************************
 
index b2f9fcdf505fae5f84388397fc668f92f43c0f25..af2849a012e42e49a6a7350a735ecf71c82f1de8 100644 (file)
 #include "toolbox/list.h"
 
 #include "vm/global.h"
+#include "vm/method.h"
 
 #include "vm/jit/exceptiontable.h"
 #include "vm/jit/linenumbertable.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/replace.h"
 
-#include "vmcore/method.h"
-
 
 /* constants ******************************************************************/
 
 #define CODE_FLAG_INVALID         0x0001
 #define CODE_FLAG_LEAFMETHOD      0x0002
 #define CODE_FLAG_SYNCHRONIZED    0x0004
+#define CODE_FLAG_TLH             0x0008
 
 
 /* codeinfo *******************************************************************
index 6f9cb4039fa26d680d27206ff9a5bc63b8f9a5a7..7adb13985a9b8b6b08438bcfc5db8e24a011265e 100644 (file)
 #include "native/localref.h"
 #include "native/native.h"
 
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-# include "native/include/java_lang_Object.h"
-# include "native/include/java_lang_String.h"           /* required by j.l.CL */
-# include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
-# include "native/include/java_lang_ClassLoader.h"
-#endif
+#include "threads/thread.hpp"
 
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-# include "native/include/java_lang_String.h"
-#endif
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/string.hpp"
 
-#include "native/include/java_lang_Class.h"
+# include "vm/statistics.h"
 
-#include "threads/thread.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 # include "vm/jit/optimizing/lsra.h"
 # include "vm/jit/optimizing/ssa.h"
 #endif
-#include "vm/jit/stacktrace.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/stacktrace.hpp"
+#include "vm/jit/trace.hpp"
 
 #if defined(ENABLE_INTRP)
 #include "vm/jit/intrp/intrp.h"
 #endif
 
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-
-# include "vmcore/statistics.h"
-
 #if defined(ENABLE_VMLOG)
 #include <vmlog_cacao.h>
 #endif
@@ -189,7 +176,6 @@ void codegen_setup(jitdata *jd)
 #endif
 
        cd->brancheslabel  = list_create_dump(OFFSET(branch_label_ref_t, linkage));
-       cd->listcritical   = list_create_dump(OFFSET(critical_section_ref_t, linkage));
        cd->linenumbers    = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
 }
 
@@ -231,7 +217,6 @@ static void codegen_reset(jitdata *jd)
 #endif
 
        cd->brancheslabel   = list_create_dump(OFFSET(branch_label_ref_t, linkage));
-       cd->listcritical    = list_create_dump(OFFSET(critical_section_ref_t, linkage));
        cd->linenumbers     = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
        
        /* We need to clear the mpc and the branch references from all
@@ -499,164 +484,6 @@ void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u
 }
 
 
-/* codegen_critical_section_new ************************************************
-
-   Allocates a new critical-section reference and adds it to the
-   critical-section list.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void codegen_critical_section_new(codegendata *cd)
-{
-       list_t                 *l;
-       critical_section_ref_t *csr;
-       s4                      mpc;
-
-       /* Get the critical section list. */
-
-       l = cd->listcritical;
-       
-       /* calculate the current mpc */
-
-       mpc = cd->mcodeptr - cd->mcodebase;
-
-       csr = DNEW(critical_section_ref_t);
-
-       /* We only can set restart right now, as start and end are set by
-          the following, corresponding functions. */
-
-       csr->start   = -1;
-       csr->end     = -1;
-       csr->restart = mpc;
-
-       /* Add the branch to the list. */
-
-       list_add_last(l, csr);
-}
-#endif
-
-
-/* codegen_critical_section_start **********************************************
-
-   Set the start-point of the current critical section (which is the
-   last element of the list).
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void codegen_critical_section_start(codegendata *cd)
-{
-       list_t                 *l;
-       critical_section_ref_t *csr;
-       s4                      mpc;
-
-       /* Get the critical section list. */
-
-       l = cd->listcritical;
-       
-       /* calculate the current mpc */
-
-       mpc = cd->mcodeptr - cd->mcodebase;
-
-       /* Get the current critical section. */
-
-       csr = list_last(l);
-
-       /* set the start point */
-
-       assert(csr->start == -1);
-
-       csr->start = mpc;
-}
-#endif
-
-
-/* codegen_critical_section_end ************************************************
-
-   Set the end-point of the current critical section (which is the
-   last element of the list).
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void codegen_critical_section_end(codegendata *cd)
-{
-       list_t                 *l;
-       critical_section_ref_t *csr;
-       s4                      mpc;
-
-       /* Get the critical section list. */
-
-       l = cd->listcritical;
-       
-       /* calculate the current mpc */
-
-       mpc = cd->mcodeptr - cd->mcodebase;
-
-       /* Get the current critical section. */
-
-       csr = list_last(l);
-
-       /* set the end point */
-
-       assert(csr->end == -1);
-
-       csr->end = mpc;
-}
-#endif
-
-
-/* codegen_critical_section_finish *********************************************
-
-   Finish the critical sections, create the critical section nodes for
-   the AVL tree and insert them into the tree.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-static void codegen_critical_section_finish(jitdata *jd)
-{
-       codeinfo    *code;
-       codegendata *cd;
-       list_t                  *l;
-       critical_section_ref_t  *csr;
-       critical_section_node_t *csn;
-
-       /* get required compiler data */
-
-       code = jd->code;
-       cd   = jd->cd;
-
-       /* Get the critical section list. */
-
-       l = cd->listcritical;
-
-       /* iterate over all critical sections */
-
-       for (csr = list_first(l); csr != NULL; csr = list_next(l, csr)) {
-               /* check if all points are set */
-
-               assert(csr->start   != -1);
-               assert(csr->end     != -1);
-               assert(csr->restart != -1);
-
-               /* allocate tree node */
-
-               csn = NEW(critical_section_node_t);
-
-               csn->start   = code->entrypoint + csr->start;
-               csn->end     = code->entrypoint + csr->end;
-               csn->restart = code->entrypoint + csr->restart;
-
-               /* insert into the tree */
-
-               critical_section_register(csn);
-       }
-}
-#endif
-
-
 /* codegen_set_replacement_point_notrap ****************************************
 
    Record the position of a non-trappable replacement point.
@@ -867,12 +694,6 @@ void codegen_finish(jitdata *jd)
        dseg_resolve_datareferences(jd);
 #endif
 
-#if defined(ENABLE_THREADS)
-       /* create cirtical sections */
-
-       codegen_critical_section_finish(jd);
-#endif
-
        /* flush the instruction and data caches */
 
        md_cacheflush(code->mcode, code->mcodelength);
index cf1ad7d771a3f807472fb32185c86a5223dc175d..4a4fea9e56f33b84db77005b89bb8931e06c0a16 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/codegen-common.h - architecture independent code generator stuff
 
-   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.
 
@@ -33,7 +31,6 @@
 typedef struct codegendata            codegendata;
 typedef struct branchref              branchref;
 typedef struct branch_label_ref_t     branch_label_ref_t;
-typedef struct critical_section_ref_t critical_section_ref_t;
 typedef struct jumpref                jumpref;
 typedef struct dataref                dataref;
 typedef struct exceptionref           exceptionref;
@@ -44,7 +41,10 @@ typedef struct linenumberref          linenumberref;
 #include "vm/types.h"
 
 #include "vm/builtin.h"
+#include "vm/descriptor.h"
 #include "vm/global.h"
+#include "vm/method.h"
+#include "vm/references.h"
 
 #include "vm/jit/dseg.h"
 #include "vm/jit/jit.h"
@@ -52,10 +52,6 @@ typedef struct linenumberref          linenumberref;
 #include "vm/jit/code.h"
 #include "vm/jit/replace.h"
 
-#include "vmcore/descriptor.h"
-#include "vmcore/method.h"
-#include "vmcore/references.h"
-
 
 #define MCODEINITSIZE (1<<15)       /* 32 Kbyte code area initialization size */
 #define DSEGINITSIZE  (1<<12)       /*  4 Kbyte data area initialization size */
@@ -133,7 +129,6 @@ struct codegendata {
 #endif
 
        list_t         *brancheslabel;
-       list_t         *listcritical;   /* list of critical sections              */
        list_t         *linenumbers;    /* list of line numbers                   */
 
        methodinfo     *method;
@@ -180,16 +175,6 @@ struct branch_label_ref_t {
 };
 
 
-/* critical_section_ref_t *****************************************************/
-
-struct critical_section_ref_t {
-       s4         start;           /* relative offset to method entry-point      */
-       s4         end;
-       s4         restart;
-       listnode_t linkage;
-};
-
-
 /* jumpref ********************************************************************/
 
 struct jumpref {
@@ -291,20 +276,6 @@ java_object_t *codegen_finish_native_call(u1 *currentsp, u1 *pv);
 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum);
 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum);
 
-#if defined(ENABLE_THREADS)
-void codegen_critical_section_new(codegendata *cd);
-void codegen_critical_section_start(codegendata *cd);
-void codegen_critical_section_end(codegendata *cd);
-
-# define CODEGEN_CRITICAL_SECTION_NEW      codegen_critical_section_new(cd)
-# define CODEGEN_CRITICAL_SECTION_START    codegen_critical_section_start(cd)
-# define CODEGEN_CRITICAL_SECTION_END      codegen_critical_section_end(cd)
-#else
-# define CODEGEN_CRITICAL_SECTION_NEW      /* no-op */
-# define CODEGEN_CRITICAL_SECTION_START    /* no-op */
-# define CODEGEN_CRITICAL_SECTION_END      /* no-op */
-#endif
-
 #if defined(ENABLE_SSA)
 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr);
 #endif
index 3b2280a9faf7e0a804e90579fb20446e40cb4538..8e2fdef105191fb46ae6562ce488e0d6adf6e8ef 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/disass.h - disassembler header
 
-   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.
 
 #ifndef _DISASS_H
 #define _DISASS_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "config.h"
 
 #if defined(WITH_BINUTILS_DISASSEMBLER)
@@ -119,7 +121,11 @@ void intrp_disassemble(u1 *start, u1 *end);
 
 #endif /* defined(ENABLE_DISASSEMBLER) */
 
-#endif /* _DISASS_H */
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DISASS_H
 
 
 /*
index 7d80a965f4c7550660bee4e085887a7f5cc075a3..5de1e5da21791e7df22439de2126405a80fa509c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/dseg.c - data segment handling stuff
 
-   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.
 
 
 #include "mm/memory.h"
 
+#include "vm/options.h"
+
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/methodheader.h"
 
-#include "vmcore/options.h"
-
 
 /* dseg_finish *****************************************************************
 
index 68c1564ae3c17a359bab30594b6a274eb9baf61a..c69406fc9d870a3841dda8854f039f95b440f3c0 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/dseg.c - data segment handling stuff
 
-   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.
 
@@ -38,11 +36,11 @@ typedef struct dsegentry dsegentry;
 
 #include "toolbox/list.h"
 
+#include "vm/references.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/codegen-common.h"
 
-#include "vmcore/references.h"
-
 
 /* convenience macros *********************************************************/
 
index 3a167808265e151f477303cf419a2c7c6c4be292..22422e22d381a7e8ce7e59b20c67586e40ba2756 100644 (file)
 #include "arch.h"
 #include "codegen.h"
 
+#include "vm/options.h"
+#include "vm/statistics.h"
+
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
 
 /* emit_load_s1 ****************************************************************
 
index 34fa5ada147f7abe820421a611c2390f2e544e8d..f0f854a03b92cac66d76eef33413c4257f5f9369 100644 (file)
@@ -178,6 +178,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg);
 void emit_exception_check(codegendata *cd, instruction *iptr);
 
 void emit_trap_compiler(codegendata *cd);
+void emit_trap_countdown(codegendata *cd, s4 *counter);
 uint32_t emit_trap(codegendata *cd);
 
 void emit_patcher_traps(jitdata *jd);
index 34153a63033c78b878c1b29c776b05d4971ef64c..722922ce4f839e62b46297b31c20e4bef2d2e666 100644 (file)
 
 #include "md-abi.h"
 
+#include "vm/descriptor.h"
+#include "vm/os.hpp"
+
 #include "vm/jit/abi.h"
 #include "vm/jit/executionstate.h"
 
-#include "vmcore/descriptor.h"
-#include "vmcore/system.h"
-
 
 /* executionstate_sanity_check *************************************************
 
@@ -66,13 +66,13 @@ void executionstate_sanity_check(void *context)
 
        /* keep a copy of (a prefix of) the context for reference */
 
-       system_memcpy(&reference, context, MINIMUM_CONTEXT_SIZE);
+       os_memcpy(&reference, context, MINIMUM_CONTEXT_SIZE);
 
        /* different poisons */
 
-       system_memset(&es1, 0xc9, sizeof(executionstate_t));
-       system_memset(&es2, 0xb5, sizeof(executionstate_t));
-       system_memset(&es3, 0x6f, sizeof(executionstate_t));
+       os_memset(&es1, 0xc9, sizeof(executionstate_t));
+       os_memset(&es2, 0xb5, sizeof(executionstate_t));
+       os_memset(&es3, 0x6f, sizeof(executionstate_t));
 
        md_executionstate_read(&es1, context);
 
index 0adf031286e8a9cf89c1a263b7b312ae905e2968..044e950af353558577d4847c93b032600bf28ed5 100644 (file)
@@ -25,7 +25,8 @@ DIST_SUBDIRS = \
        cygwin \
        darwin \
        freebsd \
-       linux
+       linux \
+       solaris
 
 SUBDIRS = $(OS_DIR)
 
@@ -36,7 +37,7 @@ LIBS =
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = \
        libarch.la
index 6c08b9cfb756126d328766c526eda5546a7468ee..12ebffd59ea0062709fefa5ed5698022948a1753 100644 (file)
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/primitive.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/jitcache.h"
 #include "vm/jit/linenumbertable.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vm/jit/jitcache.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 #if defined(ENABLE_SSA)
 # include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/utf8.h"
-
 
 /* codegen_emit ****************************************************************
 
@@ -419,9 +416,7 @@ bool codegen_emit(jitdata *jd)
                if (bptr->bitflags & BBFLAG_REPLACEMENT) {
                        if (cd->replacementpoint[-1].flags & RPLPOINT_FLAG_COUNTDOWN) {
                                MCODECHECK(32);
-                               disp = (s4) &(m->hitcountdown);
-                               M_ISUB_IMM_MEMABS(1, disp);
-                               M_BS(0);
+                               emit_trap_countdown(cd, &(m->hitcountdown));
                        }
                }
 #endif
@@ -2264,7 +2259,7 @@ bool codegen_emit(jitdata *jd)
                        break;
 
                case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
-
+                       
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
@@ -2939,6 +2934,21 @@ nowperformreturn:
 
                        bte = iptr->sx.s23.s3.bte;
                        md = bte->md;
+
+#if defined(ENABLE_ESCAPE_REASON)
+                       if (bte->fp == BUILTIN_escape_reason_new) {
+                               void set_escape_reasons(void *);
+                               M_ASUB_IMM(8, REG_SP);
+                               M_MOV_IMM(iptr->escape_reasons, REG_ITMP1);
+                               M_AST(EDX, REG_SP, 4);
+                               M_AST(REG_ITMP1, REG_SP, 0);
+                               M_MOV_IMM(set_escape_reasons, REG_ITMP1);
+                               M_CALL(REG_ITMP1);
+                               M_ALD(EDX, REG_SP, 4);
+                               M_AADD_IMM(8, REG_SP);
+                       }
+#endif
+
                        goto gen_method;
 
                case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
@@ -3157,10 +3167,6 @@ gen_method:
                                        superindex = super->index;
                                        supervftbl = super->vftbl;
                                }
-
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -3235,8 +3241,6 @@ gen_method:
                                        M_MOV_IMM(supervftbl, REG_ITMP3);
                                        JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super);
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
 
                                        /*                              if (s1 != REG_ITMP1) { */
@@ -3254,8 +3258,6 @@ gen_method:
                                        JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super);
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
 
-                                       CODEGEN_CRITICAL_SECTION_END;
-
                                        /*                              } */
 
                                        M_CMP(REG_ITMP3, REG_ITMP2);
@@ -3324,9 +3326,6 @@ gen_method:
                                supervftbl = super->vftbl;
                        }
                        
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
 
@@ -3414,14 +3413,10 @@ gen_method:
 
                                M_MOV_IMM(supervftbl, REG_ITMP2);
                                JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super);
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_ISUB(REG_ITMP2, REG_ITMP1);
                                M_CLR(d);                                 /* may be REG_ITMP2 */
                                M_CMP(REG_ITMP3, REG_ITMP1);
@@ -3695,7 +3690,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument */
 
-               M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
+               M_AST_IMM(VM_get_jnienv(), REG_SP, 0 * 4);
        }
 
        /* Call the native function. */
@@ -3711,7 +3706,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        switch (md->returntype.type) {
        case TYPE_INT:
        case TYPE_ADR:
-               switch (md->returntype.decltype) {
+               switch (md->returntype.primitivetype) {
                case PRIMITIVETYPE_BOOLEAN:
                        M_BZEXT(REG_RESULT, REG_RESULT);
                        break;
index bd96c8bdd83663a5a93a466901af407ef86cd8f1..e35e6f6a18ca1dca37200e53b182f85c3234923a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/cygwin/md-os.c - machine dependent i386 Windows functions
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Michael Starzinger
-
-   Changes:
-
 */
 
 
 
 #include "vm/types.h"
 
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
 #include "vm/jit/asmpart.h"
-#include "vm/jit/stacktrace.h"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -73,14 +62,6 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
-#if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *uc)
-{
-       assert(0);
-}
-#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
index 344c582052b0be3a0ab01598c742328453285632..3737b0144f1dcb3800e9338aa7a190e0e17026ab 100644 (file)
 #include "vm/jit/i386/codegen.h"
 #include "vm/jit/i386/md.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/global.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 #include "vm/jit/i386/codegen.h"
@@ -353,34 +352,6 @@ void md_executionstate_write(executionstate_t *es, void *context)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *_uc)
-{
-       mcontext_t           _mc;
-       i386_thread_state_t *_ss;
-       u1                  *pc;
-       void                *rpc;
-
-       _mc = _uc->uc_mcontext;
-       _ss = &_mc->__ss;
-
-       pc = (u1 *) _ss->__eip;
-
-       rpc = critical_find_restart_point(pc);
-
-       if (rpc != NULL)
-               _ss->__eip = (ptrint) rpc;
-}
-#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
index 74e7f493f4868c06c0bf437314c13f48d0dfca88..a23d4c0e60a1b3bd4a2f3fd702b7c5de982a8031 100644 (file)
@@ -37,7 +37,8 @@
 
 #include "threads/lock-common.h"
 
-#include "vm/exceptions.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
 
 /* emit_load ******************************************************************
 
@@ -517,6 +515,20 @@ void emit_trap_compiler(codegendata *cd)
        M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
 }
 
+/* emit_trap_countdown *********************************************************
+
+   Emit a countdown trap.
+
+   counter....absolute address of the counter variable
+
+*******************************************************************************/
+
+void emit_trap_countdown(codegendata *cd, s4 *counter)
+{
+       M_ISUB_IMM_MEMABS(1, (s4) counter);
+       M_BNS(6);
+       M_ALD_MEM(REG_METHODPTR, TRAP_COUNTDOWN);
+}
 
 /* emit_trap *******************************************************************
 
index 4eebf69877da4a0e589657b06a81982089c15989..b3ec691f21d64bc37a327cb9fbf3416a79f5361d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/freebsd/md-os.c - machine dependent i386 FreeBSD functions
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
 */
 
 
 
 #include "vm/jit/i386/md-abi.h"
 
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
 #include "vm/jit/asmpart.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -103,19 +94,6 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
-#if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *uc)
-{
-       void *critical;
-
-       critical = critical_find_restart_point((void *) uc->uc_mcontext.mc_eip);
-
-       if (critical)
-               uc->uc_mcontext.mc_eip = (ptrint) critical;
-}
-#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
index 17630b05143dd0f437031b94877eb7efdf9e2c9b..97c362f4e081e0b8c3cfe7b7384189958926bb95 100644 (file)
 #include "vm/jit/i386/codegen.h"
 #include "vm/jit/i386/md.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 
@@ -151,6 +150,11 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                        _mc->gregs[REG_EIP] = (uintptr_t) p;
                }
        }
+#if defined(ENABLE_REPLACEMENT)
+       else if (type == TRAP_COUNTDOWN) {
+               /* context has been written by md_replace_executionstate_write */
+       }
+#endif
        else {
                _mc->gregs[REG_EAX] = (uintptr_t) p;
                _mc->gregs[REG_ECX] = (uintptr_t) xpc;               /* REG_ITMP2_XPC */
@@ -354,32 +358,6 @@ void md_executionstate_write(executionstate_t *es, void *context)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       u1         *pc;
-       u1         *npc;
-
-       _mc = &_uc->uc_mcontext;
-
-       pc = (u1 *) _mc->gregs[REG_EIP];
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL)
-               _mc->gregs[REG_EIP] = (ptrint) npc;
-}
-#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
diff --git a/src/vm/jit/i386/machine-instr.h b/src/vm/jit/i386/machine-instr.h
deleted file mode 100644 (file)
index 1499e96..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-static inline long
-__attribute__ ((unused))
-compare_and_swap (volatile long *p, long oldval, long newval)
-{
-  long ret;
-
-  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
-                        : "=a" (ret), "=m" (*p)
-                        : "r" (newval), "m" (*p), "0" (oldval));
-  return ret;
-}
-
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() /* nothing */
-#define MEMORY_BARRIER() __asm__ __volatile__ ( \
-               "lock; add $0, 0(%%esp)" : : : "memory" );
-
-#endif
index f4d9f4c66cc2dafe337d057741f35c0ccff7ce12..dbaf089b81d80c4ba3f5b02f8ae5e0f0bcda1b70 100644 (file)
 
 #include "vm/jit/i386/md-abi.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 
-#include "vmcore/descriptor.h"
-
 
 /* register descripton - array ************************************************/
 
diff --git a/src/vm/jit/i386/md-atomic.hpp b/src/vm/jit/i386/md-atomic.hpp
new file mode 100644 (file)
index 0000000..d6ea3d7
--- /dev/null
@@ -0,0 +1,129 @@
+/* src/vm/jit/i386/atomic.hpp - i386 atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       uint32_t result;
+
+       __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+                                                 : "=a" (result), "=m" (*p)
+                                                 : "r" (newval), "m" (*p), "0" (oldval));
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+#warning Should we use cmpxchg8b or a generic version?
+       return generic_compare_and_swap(p, oldval, newval);
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return (void*) compare_and_swap((volatile uint32_t*) p, (uint32_t) oldval, (uint32_t) newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("lock; add $0, 0(%%esp)" : : : "memory" );
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       // Nothing.
+}
+
+#endif // _MD_ATOMIC_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 0c39650967eae2db07d0c9449b5e361b9cdae55f..52e6a0067ce0d74777e664f73cfc85da4c757e65 100644 (file)
@@ -1,4 +1,4 @@
-/* src/vm/jit/x86_64/md-trap.h - i386 hardware traps
+/* src/vm/jit/i386/md-trap.h - i386 hardware traps
 
    Copyright (C) 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
@@ -58,6 +58,7 @@ enum {
        /* Don't use 8 (could be a normal load offset). */
 
        TRAP_COMPILER                       = 9,
+       TRAP_COUNTDOWN                      = 10,
        TRAP_END
 };
 
index 48664ef1fddd22e7084106164fcab40f35011947..cc93cd855bcb5cbc64250d54f4c0b70144be520c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/md.c - machine dependent i386 functions
 
-   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.
 
@@ -33,7 +31,7 @@
 #include "vm/types.h"
 
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
index 4aa86f6e23afe739d0c23bc521f2a1cd807140ca..3befeff5d96855818fd3dd2588beff84ebaf9212 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vm/resolve.h"
-#include "vmcore/references.h"
 
 
 #define PATCH_BACK_ORIGINAL_MCODE *((u2 *) pr->mpc) = (u2) pr->mcode
diff --git a/src/vm/jit/i386/solaris/Makefile.am b/src/vm/jit/i386/solaris/Makefile.am
new file mode 100644 (file)
index 0000000..aa9595b
--- /dev/null
@@ -0,0 +1,44 @@
+## src/vm/jit/i386/solaris/Makefile.am
+##
+## 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.
+
+
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_builddir)/src
+
+LIBS =
+
+noinst_HEADERS = \
+       md-asm.h
+
+noinst_LTLIBRARIES = \
+       libmd.la
+
+libmd_la_SOURCES = \
+       md-os.c
+
+
+## Local variables:
+## mode: Makefile
+## indent-tabs-mode: t
+## c-basic-offset: 4
+## tab-width: 8
+## compile-command: "automake --add-missing"
+## End:
diff --git a/src/vm/jit/i386/solaris/md-asm.h b/src/vm/jit/i386/solaris/md-asm.h
new file mode 100644 (file)
index 0000000..8a2a5fe
--- /dev/null
@@ -0,0 +1,82 @@
+/* src/vm/jit/i386/solaris/md-asm.h - assembler defines for i386 ABI
+
+   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.
+
+*/
+
+
+#ifndef _MD_ASM_H
+#define _MD_ASM_H
+
+/* register defines ***********************************************************/
+
+#define v0       %eax
+#define itmp1    v0
+
+#define itmp2    %ecx
+#define itmp3    %edx
+
+#define t0       %ebx
+
+#define sp       %esp
+#define s0       %ebp
+#define s1       %esi
+#define s2       %edi
+
+#define bp       s0
+
+#define itmp1b   %al
+
+#define xptr     itmp1
+#define xpc      itmp2
+#define mptr     itmp2
+
+
+/* save and restore macros ****************************************************/
+
+#define SAVE_ARGUMENT_REGISTERS(off) \
+    /* no argument registers */
+
+#define SAVE_TEMPORARY_REGISTERS(off) \
+       mov     t0,(0+(off))*4(sp) ;
+
+
+#define RESTORE_ARGUMENT_REGISTERS(off) \
+    /* no argument registers */
+
+#define RESTORE_TEMPORARY_REGISTERS(off) \
+       mov     (0+(off))*4(sp),t0 ;
+
+#endif /* _MD_ASM_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/jit/i386/solaris/md-os.c b/src/vm/jit/i386/solaris/md-os.c
new file mode 100644 (file)
index 0000000..bc95947
--- /dev/null
@@ -0,0 +1,365 @@
+/* src/vm/jit/i386/solaris/md-os.c - machine dependent i386 Solaris functions
+
+   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.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+#include <ucontext.h>
+
+#include "vm/types.h"
+
+#include "vm/jit/i386/codegen.h"
+#include "vm/jit/i386/md.h"
+
+#include "threads/thread.hpp"
+
+#include "vm/builtin.h"
+#include "vm/signallocal.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
+#include "vm/jit/stacktrace.hpp"
+#include "vm/jit/trap.h"
+
+
+/* md_signal_handler_sigsegv ***************************************************
+
+   Signal handler for hardware exceptions.
+
+*******************************************************************************/
+
+void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
+{
+       ucontext_t     *_uc;
+       mcontext_t     *_mc;
+       u1             *pv;
+       u1             *sp;
+       u1             *ra;
+       u1             *xpc;
+       u1              opc;
+       u1              mod;
+       u1              rm;
+       s4              d;
+       s4              disp;
+       ptrint          val;
+       s4              type;
+       void           *p;
+       java_object_t  *o;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       pv  = NULL;                 /* is resolved during stackframeinfo creation */
+       sp  = (u1 *) _mc->gregs[ESP];
+       xpc = (u1 *) _mc->gregs[EIP];
+       ra  = xpc;                              /* return address is equal to XPC */
+
+       /* get exception-throwing instruction */
+
+       opc = M_ALD_MEM_GET_OPC(xpc);
+       mod = M_ALD_MEM_GET_MOD(xpc);
+       rm  = M_ALD_MEM_GET_RM(xpc);
+
+       /* for values see emit_mov_mem_reg and emit_mem */
+
+       if ((opc == 0x8b) && (mod == 0) && (rm == 5)) {
+               /* this was a hardware-exception */
+
+               d    = M_ALD_MEM_GET_REG(xpc);
+               disp = M_ALD_MEM_GET_DISP(xpc);
+
+               /* we use the exception type as load displacement */
+
+               type = disp;
+
+               /* ATTENTION: The _mc->gregs layout is completely crazy!  The
+                  registers are reversed starting with number 4 for REG_EDI
+                  (see /usr/include/sys/ucontext.h).  We have to convert that
+                  here. */
+
+               val = _mc->gregs[EAX - d];
+
+               if (type == TRAP_COMPILER) {
+                       /* The PV from the compiler stub is equal to the XPC. */
+
+                       pv = xpc;
+
+                       /* We use a framesize of zero here because the call pushed
+                          the return addres onto the stack. */
+
+                       ra = md_stacktrace_get_returnaddress(sp, 0);
+
+                       /* Skip the RA on the stack. */
+
+                       sp = sp + 1 * SIZEOF_VOID_P;
+
+                       /* The XPC is the RA minus 2, because the RA points to the
+                          instruction after the call. */
+
+                       xpc = ra - 2;
+               }
+       }
+       else {
+               /* this was a normal NPE */
+
+               type = TRAP_NullPointerException;
+               val  = 0;
+       }
+
+       /* Handle the trap. */
+
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
+
+       /* Set registers. */
+
+       if (type == TRAP_COMPILER) {
+               if (p == NULL) {
+                       o = builtin_retrieve_exception();
+
+                       _mc->gregs[ESP] = (uintptr_t) sp;    /* Remove RA from stack. */
+
+                       _mc->gregs[EAX] = (uintptr_t) o;
+                       _mc->gregs[ECX] = (uintptr_t) xpc;           /* REG_ITMP2_XPC */
+                       _mc->gregs[EIP] = (uintptr_t) asm_handle_exception;
+               }
+               else {
+                       _mc->gregs[EIP] = (uintptr_t) p;
+               }
+       }
+       else {
+               _mc->gregs[EAX] = (uintptr_t) p;
+               _mc->gregs[ECX] = (uintptr_t) xpc;               /* REG_ITMP2_XPC */
+               _mc->gregs[EIP] = (uintptr_t) asm_handle_exception;
+       }
+}
+
+
+/* md_signal_handler_sigfpe ****************************************************
+
+   ArithmeticException signal handler for hardware divide by zero
+   check.
+
+*******************************************************************************/
+
+void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
+{
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       u1         *pv;
+       u1         *sp;
+       u1         *ra;
+       u1         *xpc;
+       s4          type;
+       ptrint      val;
+       void       *p;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       pv  = NULL;                 /* is resolved during stackframeinfo creation */
+       sp  = (u1 *) _mc->gregs[ESP];
+       xpc = (u1 *) _mc->gregs[EIP];
+       ra  = xpc;                          /* return address is equal to xpc     */
+
+       /* This is an ArithmeticException. */
+
+       type = TRAP_ArithmeticException;
+       val  = 0;
+
+       /* Handle the trap. */
+
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
+
+       /* Set registers. */
+
+       _mc->gregs[EAX] = (uintptr_t) p;
+       _mc->gregs[ECX] = (uintptr_t) xpc;                   /* REG_ITMP2_XPC */
+       _mc->gregs[EIP] = (uintptr_t) asm_handle_exception;
+}
+
+
+/* md_signal_handler_sigill ****************************************************
+
+   Signal handler for hardware patcher traps (ud2).
+
+*******************************************************************************/
+
+void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
+{
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       u1         *pv;
+       u1         *sp;
+       u1         *ra;
+       u1         *xpc;
+       s4          type;
+       ptrint      val;
+       void       *p;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       pv  = NULL;                 /* is resolved during stackframeinfo creation */
+       sp  = (u1 *) _mc->gregs[ESP];
+       xpc = (u1 *) _mc->gregs[EIP];
+       ra  = xpc;                            /* return address is equal to xpc   */
+
+       type = TRAP_PATCHER;
+       val  = 0;
+
+       /* Handle the trap. */
+
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
+
+       /* Set registers. */
+
+       if (p != NULL) {
+               _mc->gregs[EAX] = (uintptr_t) p;
+               _mc->gregs[ECX] = (uintptr_t) xpc;               /* REG_ITMP2_XPC */
+               _mc->gregs[EIP] = (uintptr_t) asm_handle_exception;
+       }
+}
+
+
+/* md_signal_handler_sigusr1 ***************************************************
+
+   Signal handler for suspending threads.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+void md_signal_handler_sigusr1(int sig, siginfo_t *siginfo, void *_p)
+{
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       u1         *pc;
+       u1         *sp;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       /* get the PC and SP for this thread */
+       pc = (u1 *) _mc->gregs[EIP];
+       sp = (u1 *) _mc->gregs[ESP];
+
+       /* now suspend the current thread */
+       threads_suspend_ack(pc, sp);
+}
+#endif
+
+
+/* md_signal_handler_sigusr2 ***************************************************
+
+   Signal handler for profiling sampling.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS)
+void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
+{
+       threadobject *t;
+       ucontext_t   *_uc;
+       mcontext_t   *_mc;
+       u1           *pc;
+
+       t = THREADOBJECT;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       pc = (u1 *) _mc->gregs[EIP];
+
+       t->pc = pc;
+}
+#endif
+
+
+/* md_executionstate_read ******************************************************
+
+   Read the given context into an executionstate for Replacement.
+
+*******************************************************************************/
+
+void md_executionstate_read(executionstate_t *es, void *context)
+{
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       s4          i;
+
+       _uc = (ucontext_t *) context;
+       _mc = &_uc->uc_mcontext;
+
+       /* read special registers */
+       es->pc = (u1 *) _mc->gregs[EIP];
+       es->sp = (u1 *) _mc->gregs[ESP];
+       es->pv = NULL;                   /* pv must be looked up via AVL tree */
+
+       /* read integer registers */
+       for (i = 0; i < INT_REG_CNT; i++)
+               es->intregs[i] = _mc->gregs[EAX - i];
+
+       /* read float registers */
+       for (i = 0; i < FLT_REG_CNT; i++)
+               es->fltregs[i] = 0xdeadbeefdeadbeefULL;
+}
+
+
+/* md_executionstate_write *****************************************************
+
+   Write the given executionstate back to the context for Replacement.
+
+*******************************************************************************/
+
+void md_executionstate_write(executionstate_t *es, void *context)
+{
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       s4          i;
+
+       _uc = (ucontext_t *) context;
+       _mc = &_uc->uc_mcontext;
+
+       /* write integer registers */
+       for (i = 0; i < INT_REG_CNT; i++)
+               _mc->gregs[EAX - i] = es->intregs[i];
+
+       /* write special registers */
+       _mc->gregs[EIP] = (ptrint) es->pc;
+       _mc->gregs[ESP] = (ptrint) es->sp;
+}
+
+
+/*
+ * 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 210d9459903b1882db1b688cbb2ddf7b7a845ddb..d5108a6dfce3326d72003f8bdf0315e9aff50651 100644 (file)
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
 #include "vm/builtin.h"
+#include "vm/class.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 
 #include "vm/jit/verify/typecheck.h"
 
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
 
 /* algorithm tuning constants *************************************************/
 
index 6bba262c8a44dad463058bf077ab57534ee1ce34..35cec22935251ea7eb093af0d98f2c89cfc2ee9e 100644 (file)
 
 #include "arch.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/options.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodheader.h"
 
 #include "vm/jit/intrp/intrp.h"
 
-#include "vmcore/class.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 #if defined(ENABLE_VMLOG)
 #include <vmlog_cacao.h>
 #endif
index 6fe3cc7270a935a532f0651a0c7e09e188b727e7..ec35739dab3dc1bbe9d7130749748ed4789b5586 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/stack.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/options.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 #define gen_branch(_inst) { \
@@ -2085,7 +2083,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
                assert(false);
        }
 
-       av_ptr(alist, _Jv_JNIEnv *, _Jv_env);
+       av_ptr(alist, _Jv_JNIEnv *, VM_get_jnienv());
 
        if (m->flags & ACC_STATIC)
                av_ptr(alist, classinfo *, m->clazz);
@@ -2150,7 +2148,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
 
        /* pass env pointer */
 
-       penv = (_Jv_JNIEnv *) _Jv_env;
+       penv = (_Jv_JNIEnv *) VM_get_jnienv();
        *pvalues++ = &penv;
 
        /* for static methods, pass class pointer */
index d735aa3c6182b83f6df1d55190279981314856f1..dcf7d9e44cc7b3b73b62956c50f13359e9cd3158 100644 (file)
@@ -3,10 +3,8 @@
    Copyright (C) 1995,1996,1997,1998,2000,2003,2004 Free Software Foundation, Inc.
    Taken from Gforth.
 
-   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,6 +22,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
+
 */
 
 
 #include "toolbox/hashtable.h"
 #include "toolbox/logging.h"
 
+#include "vm/options.h"
+
 #include "vm/jit/disass.h"
 #include "vm/jit/intrp/intrp.h"
 
-#include "vmcore/options.h"
-
 
 s4 no_super=0;   /* option: just use replication, but no dynamic superinsts */
 
index 1e98d1e8bd821851d763ef412fe99f57145774a2..e3b2c4772b4f0f2428137d8664309fff5a5e7281 100644 (file)
 
 #include "mm/memory.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/loader.h"
+#include "vm/options.h"
 
 #include "vm/jit/methodheader.h"
 #include "vm/jit/patcher.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 #if defined(ENABLE_THREADS)
-# ifndef USE_FAKE_ATOMIC_INSTRUCTIONS
-#  include "machine-instr.h"
-# else
-#  include "threads/posix/generic-primitives.h"
-# endif
+# include "threads/atomic.hpp"
 #endif
 
 #if !defined(STORE_ORDER_BARRIER) && !defined(ENABLE_THREADS)
index c4e988201eab15b97ef0c81c2fc49db147684526..366f1d9cce9f6d9760e3ec0e596f6f0fd947213c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/intrp/intrp.h - definitions for Interpreter
 
-   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.
 
@@ -46,16 +44,15 @@ typedef s8 Cell;
 typedef s4 Cell;
 #endif
 
+#include "vm/class.h"
 #include "vm/global.h"
+#include "vm/linker.h"
+#include "vm/method.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/codegen-common.h"
 
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/references.h"
-#include "vm/resolve.h"
-#include "vmcore/linker.h"
-
 
 typedef void *Label;
 typedef void *Inst;
index a8f7107b24cc446510260953ff71047c1b45dac7..e51fb76c47a14ec356e05132cae19183ee5b438f 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
 
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vm/resolve.h"
-#include "vmcore/references.h"
-
 
 /* patcher_get_putstatic *******************************************************
 
index a190f35045711020722f19a7021215b1473651f2..a22bc3403add5cc3ce819c1feb3607f7010366d1 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "vm/jit/intrp/intrp.h"
 
-#include "vmcore/options.h"
+#include "vm/options.h"
 
 
 /* the numbers in this struct are primitive indices */
index 4225c66c66da01876cf354b5915ddb11b26d2dbb..cf2cf5b34d6dbeb587a26a6d539af04860df5494 100644 (file)
 
 #include "threads/lock-common.h"
 
+#include "vm/class.h"
 #include "vm/global.h"
+#include "vm/globals.hpp"
 #include "vm/initialize.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/rt-timing.h"
+#include "vm/statistics.h"
 
 #include "vm/jit/asmpart.h"
 
 # include "vm/jit/jitcache.h"
 #endif
 
+#if defined(ENABLE_OPAGENT)
+#include "vm/jit/oprofile-agent.hpp"
+#endif
+
 #include "vm/jit/allocator/simplereg.h"
 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
 # include "vm/jit/allocator/lsra.h"
 
 #include "vm/jit/verify/typecheck.h"
 
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/rt-timing.h"
-#include "vmcore/statistics.h"
-
 
 /* debug macros ***************************************************************/
 
@@ -213,6 +217,11 @@ void jit_init(void)
 #else
        intrp_md_init();
 #endif
+
+#if defined(ENABLE_OPAGENT)
+       if (opt_EnableOpagent)
+               OprofileAgent_initialize();
+#endif
 }
 
 
@@ -224,7 +233,10 @@ void jit_init(void)
 
 void jit_close(void)
 {
-       /* do nothing */
+#if defined(ENABLE_OPAGENT)
+       if (opt_EnableOpagent)
+               OprofileAgent_close();
+#endif
 }
 
 
@@ -405,8 +417,9 @@ u1 *jit_compile(methodinfo *m)
                jd->flags |= JITDATA_FLAG_VERBOSECALL;
 
 #if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
-       if (opt_Inline)
+       if (opt_Inline && (jd->m->hitcountdown > 0) && (jd->code->optlevel == 0)) {
                jd->flags |= JITDATA_FLAG_COUNTDOWN;
+       }
 #endif
 
 #if defined(ENABLE_JIT)
@@ -461,6 +474,11 @@ u1 *jit_compile(methodinfo *m)
                compilingtime_stop();
 #endif
 
+#if defined(ENABLE_OPAGENT)
+       if (opt_EnableOpagent)
+               OprofileAgent_newmethod(m);
+#endif
+
        /* leave the monitor */
 
        LOCK_MONITOR_EXIT(m);
@@ -573,6 +591,11 @@ u1 *jit_recompile(methodinfo *m)
                compilingtime_stop();
 #endif
 
+#if defined(ENABLE_OPAGENT)
+       if (opt_EnableOpagent)
+               OprofileAgent_newmethod(m);
+#endif
+
        DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
 
        /* return pointer to the methods entry point */
@@ -719,18 +742,6 @@ static u1 *jit_compile_intern(jitdata *jd)
 #endif
                RT_TIMING_GET_TIME(time_typecheck);
 
-#if defined(ENABLE_SSA)
-               if (opt_lsra) {
-                       fix_exception_handlers(jd);
-               }
-#endif
-
-               /* Build the CFG.  This has to be done after stack_analyse, as
-                  there happens the JSR elimination. */
-
-               if (!cfg_build(jd))
-                       return NULL;
-
 #if defined(ENABLE_LOOP)
                if (opt_loops) {
                        depthFirst(jd);
@@ -752,13 +763,25 @@ static u1 *jit_compile_intern(jitdata *jd)
 
                /* inlining */
 
-#if defined(ENABLE_INLINING)
+#if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
                if (JITDATA_HAS_FLAG_INLINE(jd)) {
                        if (!inline_inline(jd))
                                return NULL;
                }
 #endif
 
+#if defined(ENABLE_SSA)
+               if (opt_lsra) {
+                       fix_exception_handlers(jd);
+               }
+#endif
+
+               /* Build the CFG.  This has to be done after stack_analyse, as
+                  there happens the JSR elimination. */
+
+               if (!cfg_build(jd))
+                       return NULL;
+
 #if defined(ENABLE_PROFILING)
                /* Basic block reordering.  I think this should be done after
                   if-conversion, as we could lose the ability to do the
@@ -789,16 +812,17 @@ static u1 *jit_compile_intern(jitdata *jd)
 #if defined(ENABLE_SSA)
                /* allocate registers */
                if (
-                       (opt_lsra) 
-                       /*&& strncmp(jd->m->name->text, "banana", 6) == 0*/
+                       (opt_lsra &&
+                       jd->code->optlevel > 0) 
+                       /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
                        /*&& jd->exceptiontablelength == 0*/
                ) {
-                       /* printf("=== %s ===\n", jd->m->name->text); */
+                       /*printf("=== %s ===\n", jd->m->name->text);*/
                        jd->ls = DNEW(lsradata);
                        jd->ls = NULL;
                        ssa(jd);
                        /*lsra(jd);*/ regalloc(jd);
-                       eliminate_subbasicblocks(jd);
+                       /*eliminate_subbasicblocks(jd);*/
                        STATISTICS(count_methods_allocated_by_lsra++);
 
                } else
index 448f0cc539d6206c4c5493caef05f0586a6e3f32..6744106f4680ac7ab5906c93d42cb8e63ad8eba5 100644 (file)
@@ -41,13 +41,19 @@ typedef struct exception_entry exception_entry;
 #include "toolbox/chain.h"
 
 #include "vm/global.h"
+#include "vm/method.h"
+#include "vm/references.h"
 #include "vm/resolve.h"
 
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/stack.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 
 #if defined(ENABLE_INLINING)
 # include "vm/jit/inline/inline.h"
@@ -67,13 +73,6 @@ typedef struct exception_entry exception_entry;
 
 #include "vm/jit/verify/typeinfo.h"
 
-#include "vmcore/method.h"
-#include "vmcore/references.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
 
 /* common jit/codegen macros **************************************************/
 
@@ -383,6 +382,9 @@ struct instruction {
 #if SIZEOF_VOID_P == 4
     flags_operand_t         flags;  /* 4 bytes      */
 #endif
+#if defined(ENABLE_ESCAPE_REASON)
+       void *escape_reasons;
+#endif
 };
 
 
@@ -549,6 +551,9 @@ struct basicblock {
 #define FOR_EACH_INSTRUCTION(bptr, it) \
        for ((it) = (bptr)->iinstr; (it) != (bptr)->iinstr + (bptr)->icount; ++(it))
 
+#define FOR_EACH_INSTRUCTION_REV(bptr, it) \
+       for ((it) = (bptr)->iinstr + (bptr)->icount - 1; (it) != (bptr)->iinstr - 1; --(it))
+
 #if defined(ENABLE_SSA)
 
 #define FOR_EACH_EXHANDLER(bptr, it) \
index 835fea314f8d61f05eb41c73e9bff4828b439233..9568e3a4da6cf687496dc4723ed01d2f87e4d995 100644 (file)
 
 #include "mm/memory.h"
 
+#if defined(ENABLE_STATISTICS)
+# include "vm/options.h"
+# include "vm/statistics.h"
+#endif
+
 #include "vm/jit/code.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/linenumbertable.h"
 
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/options.h"
-# include "vmcore/statistics.h"
-#endif
 
 #if defined(__S390__)
 #  define ADDR_MASK(type, x) ((type)((uintptr_t)(x) & 0x7FFFFFFF))
index 925cf2405b51aaf03349f4a7c39149e1c305c9bc..ce915d367ef15a275e70047da726aac64e5b9003 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/linenumbertable.h - linenumber table
 
-   Copyright (C) 2007
+   Copyright (C) 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 #ifndef _LINENUMBERTABLE_H
 #define _LINENUMBERTABLE_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* forward typedefs ***********************************************************/
 
 typedef struct linenumbertable_t            linenumbertable_t;
@@ -39,12 +43,12 @@ typedef struct linenumbertable_list_entry_t linenumbertable_list_entry_t;
 
 #include "toolbox/list.h"
 
+#include "vm/method.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/code.h"
 #include "vm/jit/codegen-common.h"
 
-#include "vmcore/method.h"
-
 
 /* linenumbertable_t **********************************************************/
 
@@ -94,6 +98,10 @@ void    linenumbertable_list_entry_add_inline_end(codegendata *cd, instruction *
 
 int32_t linenumbertable_linenumber_for_pc(methodinfo **pm, codeinfo *code, void *pc);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _LINENUMBERTABLE_H */
 
 
index ff3beb1f530d3cbae3725bccfe5b9b1d67ecd43c..2f597848506c9908b2cdf6417987b5ae6cb45cc7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/loop/graph.h - control flow graph header
 
    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
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -31,9 +29,9 @@
 #include "config.h"
 #include "vm/types.h"
 
-#include "vm/jit/loop/loop.h"
+#include "vm/method.h"
 
-#include "vmcore/method.h"
+#include "vm/jit/loop/loop.h"
 
 
 /* function prototypes ********************************************************/
index 881fc746a7ae8b13050a9785a5b20737dc468288..586c729a3ee04d41f3966e1f4036a4bb12953029 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/loop/loop.h - array bound removal header
 
-   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.
 
 #include "vm/types.h"
 
 #include "vm/global.h"
+#include "vm/method.h"
 
 #include "vm/jit/jit.h"
 
-#include "vmcore/method.h"
-
 
 /*     Different types for struct Trace                                                                                */
 #define TRACE_UNKNOWN 0                        /* unknown                                                                      */
index eb3c1f4aca3e7e711a278df17f2b0d655600ab87..5799e1a78fe589732647e7916bcb4100b4de6c56 100644 (file)
@@ -33,7 +33,7 @@ LIBS =
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = \
        libarch.la
index 41bd7c7f7f83e459c527546e81fe368a01bbdf8b..22e9ea93e5615366bda3f43feefe0729fb667740 100644 (file)
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/utf8.h"
-
 
 bool codegen_emit(jitdata *jd) 
 {      
@@ -1994,9 +1992,6 @@ nowperformreturn:
                                superindex = super->index;
                        }
                        
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ATMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
 
@@ -2060,14 +2055,10 @@ nowperformreturn:
 
                                M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_ISUB(REG_ITMP3, REG_ITMP1);
                                M_ICMP(REG_ITMP2, REG_ITMP1);
                                M_BHI(4);
@@ -2119,9 +2110,6 @@ nowperformreturn:
                                        superindex = super->index;
                                }
 
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                                s1 = emit_load_s1(jd, iptr, REG_ATMP1);
                                assert(VAROP(iptr->s1)->type == TYPE_ADR);
 
@@ -2181,14 +2169,10 @@ nowperformreturn:
 
                                        M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));  /* REG_ITMP3 == sub->vftbl->baseval */
                                        M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
                                        M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
 
-                                       CODEGEN_CRITICAL_SECTION_END;
-
                                        M_ISUB(REG_ITMP1, REG_ITMP3);
                                        M_ICMP(REG_ITMP2, REG_ITMP3);   /* XXX was CMPU */
 
@@ -2455,7 +2439,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
                        M_AST(REG_ATMP3, REG_SP, 1 * 4);
 
                /* env ist first argument */
-               M_AMOV_IMM(_Jv_env, REG_ATMP1);
+               M_AMOV_IMM(VM_get_jnienv(), REG_ATMP1);
                M_AST(REG_ATMP1, REG_SP, 0 * 4);
        }
 
index 0b48ac636c1af9d0872cc588e17954fd0e7466a9..c6002a36b500379f8f6f4617fb5c2b59a1fd0f06 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/m68k/emit.c
 
-   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.
 
 #include "mm/memory.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/emit-common.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
 
index 778c700bf71c06c59f987ffe4adb6b61e990adf7..20fa2ea8e119c5235fcfc445aa62f72caf545643 100644 (file)
@@ -30,7 +30,7 @@
 #include "config.h"
 
 #include "vm/types.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 #include "vm/jit/codegen-common.h"
 
 void emit_mov_imm_reg (codegendata *cd, s4 imm, s4 dreg);
index 444f55c97edbeecc184ff9100fc27ebce2e86f60..21c54f56df80fc82f908b20d5cde9446d842ff3f 100644 (file)
@@ -28,9 +28,8 @@
 #include "vm/jit/m68k/md.h"
 #include "vm/jit/m68k/linux/md-abi.h"
 
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/trap.h"
diff --git a/src/vm/jit/m68k/machine-instr.h b/src/vm/jit/m68k/machine-instr.h
deleted file mode 100644 (file)
index 021e723..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* src/vm/jit/m68k/machine-instr.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
-
-   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 _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-static inline long compare_and_swap(long *p, long oldval, long newval)
-{
-       /* XXX, coldifre has no atomic compare and swap instrcution */
-       #warning "compare_and_swap is not atmically"
-       if (*p == oldval)       {
-               *p = newval;
-               return oldval;
-       } 
-       return *p;
-}
-
-
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER() __asm__ __volatile__ ( "" : : : "memory" );
-
-#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/jit/m68k/md-atomic.hpp b/src/vm/jit/m68k/md-atomic.hpp
new file mode 100644 (file)
index 0000000..ad5d4d2
--- /dev/null
@@ -0,0 +1,122 @@
+/* src/vm/jit/m68k/md-atomic.hpp - m68k atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       return generic_compare_and_swap(p, oldval, newval);
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       return generic_compare_and_swap(p, oldval, newval);
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return generic_compare_and_swap(p, oldval, newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       generic_memory_barrier();
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+#endif // _MD_ATOMIC_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 69a15a3158c8ddbdc3a9464b02d6f8c5cd224c35..0e5fcca3c25b1338292dbc4af522d360a1460579 100644 (file)
@@ -48,7 +48,8 @@ enum {
        TRAP_ClassCastException             = 5,
        TRAP_CHECK_EXCEPTION                = 6,
        TRAP_PATCHER                        = 7,
-       TRAP_COMPILER                       = 8
+       TRAP_COMPILER                       = 8,
+       TRAP_COUNTDOWN                      = 9
 };
 
 #endif /* _MD_TRAP_H */
index 9fb12da0c144ba32773430e615448de7fc377bd5..071a195303ee1705de9dd1295bd30c7e4c8de5d8 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "vm/types.h"
 
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 
 /*
index 71607c7f42010a38a489cde522f59c4533c31759..a5e03b50357b9bf29f53481b2ff0641085e39c8b 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
 #include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
 
 #include "codegen.h"
 
index 262804ecb52002501a11a405510061e29fd867c4..0cb513794b8f5998e0979b414544f812b6356bea 100644 (file)
 
 #include "mm/memory.h"
 
-#include "threads/thread.h"
-
 #include "toolbox/avl.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodtree.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* methodtree_element *********************************************************/
index e2be2204399c89bf16504d76319aae2944a89888..eef8d3fcaa17ea514528c31c3b8a74b0e19d0921 100644 (file)
 
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "toolbox/avl.h"
 
 
@@ -40,6 +44,10 @@ void  methodtree_insert(void *startpc, void *endpc);
 void *methodtree_find(void *pc);
 void *methodtree_find_nocheck(void *pc);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _METHODTREE_H */
 
 
index ce07cde79a90340b974fd6520b4ca34534e201ea..86ef145db86d6c49e85230466cfab5bfcd2b07bb 100644 (file)
@@ -35,9 +35,9 @@ LIBS =
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h \
        \
-       md-asm.h
+       md-asm.h \
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = \
        libarch.la
index 2a3b5fc0c8120b8de35efcec2397af1855400cc3..73732e6c633c1132f565994df8c1401b9620cb53 100644 (file)
@@ -51,8 +51,6 @@
 
        .globl asm_abstractmethoderror
 
-       .globl compare_and_swap
-
 
 /* asm_vm_call_method **********************************************************
 *                                                                              *
@@ -423,16 +421,16 @@ ex_int2:
        l.d     fs1,-3*8(t1)
        l.d     fs2,-2*8(t1)
        l.d     fs3,-1*8(t1)
-#else /* SIZEOF_VOID_P == 8 */
+#else
 # if !defined(ENABLE_SOFT_FLOAT)
-       l.d     fs0,-4*8(t1)
-       l.d     fs1,-3*8(t1)
-       l.d     fs2,-2*8(t1)
-       l.d     fs3,-1*8(t1)
-       l.d     fs4,-1*8(t1)
+       l.d     fs0,-6*8(t1)
+       l.d     fs1,-5*8(t1)
+       l.d     fs2,-4*8(t1)
+       l.d     fs3,-3*8(t1)
+       l.d     fs4,-2*8(t1)
        l.d     fs5,-1*8(t1)
-# endif /* !defined(ENABLE_SOFT_FLOAT) */
-#endif /* SIZEOF_VOID_P == 8 */
+# endif
+#endif
 
 ex_flt2:
        lw      t1,FrameSize(pv)            /* get frame size                     */
@@ -466,40 +464,6 @@ asm_abstractmethoderror:
        .end    asm_abstractmethoderror
 
 
-       .ent    compare_and_swap
-
-compare_and_swap:
-1:
-#if defined(__GNUC__)
-       .set mips2
-#endif
-       all     v0,0(a0)
-#if defined(__GNUC__)
-       .set mips0
-#endif
-       bne     v0,a1,2f
-       move    t0,a2
-#if defined(__GNUC__)
-       .set mips2
-#endif
-       asc     t0,0(a0)
-#if defined(__GNUC__)
-       .set mips0
-#endif
-       beqz    t0,1b
-2:
-#if defined(__GNUC__)
-       .set mips2
-#endif
-       sync
-#if defined(__GNUC__)
-       .set mips0
-#endif
-       j       ra
-
-       .end    compare_and_swap
-
-
 /* disable exec-stacks ********************************************************/
 
 #if defined(__linux__) && defined(__ELF__)
index cbb334513e2a6c18c17280cd72c742d045bc5a9b..eb73de9b99e70b7a36385ec5c781a552158f10f4 100644 (file)
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/vm.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
@@ -62,9 +64,6 @@
 # include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/class.h"
-#include "vmcore/options.h"
-
 
 /* codegen_emit ****************************************************************
 
@@ -3236,9 +3235,6 @@ gen_method:
                                        superindex = super->index;
                                }
                        
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -3309,8 +3305,6 @@ gen_method:
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ALD(REG_ITMP3, REG_PV, disp);
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                        /*                              if (s1 != REG_ITMP1) { */
                                        /*                                      M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
@@ -3325,8 +3319,6 @@ gen_method:
                                        M_ALD(REG_ITMP3, REG_PV, disp);
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
 
-                                       CODEGEN_CRITICAL_SECTION_END;
-
                                        /*                              } */
                                        M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
                                        emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
@@ -3391,9 +3383,6 @@ gen_method:
                                superindex = super->index;
                        }
                        
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
 
@@ -3471,14 +3460,10 @@ gen_method:
                                M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_ITMP2, REG_PV, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); 
                                M_CMPULT(REG_ITMP2, REG_ITMP1, d);
                                M_XOR_IMM(d, 1, d);
@@ -3885,7 +3870,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument register */
 
-               disp = dseg_add_address(cd, _Jv_env);
+               disp = dseg_add_address(cd, VM_get_jnienv());
                M_ALD(REG_A0, REG_PV, disp);
        }
 
index a8a7e225f0e1d6cf83a67cf46e0dab43c5cc00db..ef30af384eced91c0d588da6b9c1de8aee28aa83 100644 (file)
@@ -37,8 +37,7 @@
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h" /* XXX for gen_resolvebranch */
+#include "vm/options.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
@@ -50,8 +49,6 @@
 #include "vm/jit/replace.h"
 #include "vm/jit/trap.h"
 
-#include "vmcore/options.h"
-
 
 /* emit_load *******************************************************************
 
index d14fb611e8f98bcd8f8dfd66b2b7c1327cf1f2f3..8b54c15e80fce91954669a7666b5aa18baf97f67 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/irix/md-os.c - machine dependent MIPS IRIX functions
 
-   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.
 
 #include "vm/jit/mips/codegen.h"
 #include "vm/jit/mips/md-abi.h"
 
-#include "mm/gc-common.h"
+#include "mm/gc.hpp"
 
 #include "vm/global.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
-#include "vm/jit/stacktrace.h"
 
 
 /* md_init *********************************************************************
@@ -145,34 +141,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       u1         *pc;
-       u1         *npc;
-
-       _mc = &_uc->uc_mcontext;
-
-       pc = (u1 *) _mc->gregs[CTX_EPC];
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL) {
-               log_println("md_critical_section_restart: pc=%p, npc=%p", pc, npc);
-               _mc->gregs[CTX_EPC] = (ptrint) npc;
-       }
-}
-#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
index aebc1666aba9a0d16f8d1db30cecc62d0b8d3feb..e94b20d76faa8d962f9b7d5b6f4f726d1e780d6b 100644 (file)
 #include "vm/jit/mips/md.h"
 #include "vm/jit/mips/md-abi.h"
 
-#include "mm/gc-common.h"
+#include "mm/gc.hpp"
 #include "mm/memory.h"
 
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
+#include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
-#include "vm/jit/stacktrace.h"
 #include "vm/jit/trap.h"
 
 
@@ -305,7 +304,7 @@ void md_executionstate_read(executionstate_t* es, void* context)
           _mc->fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->fpregs.fp_r) == sizeof(es->fltregs));
-       system_memcpy(&es->fltregs, &_mc->fpregs.fp_r, sizeof(_mc->fpregs.fp_r));
+       os_memcpy(&es->fltregs, &_mc->fpregs.fp_r, sizeof(_mc->fpregs.fp_r));
 }
 
 
@@ -338,7 +337,7 @@ void md_executionstate_write(executionstate_t* es, void* context)
           _mc->fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->fpregs.fp_r) == sizeof(es->fltregs));
-       system_memcpy(&_mc->fpregs.fp_r, &es->fltregs, sizeof(_mc->fpregs.fp_r));
+       os_memcpy(&_mc->fpregs.fp_r, &es->fltregs, sizeof(_mc->fpregs.fp_r));
 
        /* Write special registers. */
 
@@ -354,41 +353,6 @@ void md_executionstate_write(executionstate_t* es, void* context)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       u1         *pc;
-       u1         *npc;
-
-       _mc = &_uc->uc_mcontext;
-
-#if defined(__UCLIBC__)
-       pc = (u1 *) (ptrint) _mc->gpregs[CTX_EPC];
-#else
-       pc = (u1 *) (ptrint) _mc->pc;
-#endif
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL) {
-#if defined(__UCLIBC__)
-               _mc->gpregs[CTX_EPC] = (ptrint) npc;
-#else
-               _mc->pc              = (ptrint) npc;
-#endif
-       }
-}
-#endif
-
-
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
diff --git a/src/vm/jit/mips/machine-instr.h b/src/vm/jit/mips/machine-instr.h
deleted file mode 100644 (file)
index 848a164..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-#if 0
-
-/* If anyone wants to compile with gcc, use this section.
- * It is not usable with the MIPSPro compiler.
- *
- * It is outdated, too.
- */ 
-
-static inline int
-__attribute__ ((unused))
-compare_and_swap (volatile long *p, long oldval, long newval)
-{
-  long ret, temp;
-
-  __asm__ __volatile__
-    ("1:\n\t"
-     ".set  push\n\t"
-     ".set  mips2\n\t"
-     "lld   %1,%5\n\t"
-     "move  %0,$0\n\t"
-     "bne   %1,%3,2f\n\t"
-     "move  %0,%4\n\t"
-     "scd   %0,%2\n\t"
-     ".set  pop\n\t"
-     "beqz  %0,1b\n"
-     "2:\n\t"
-     : "=&r" (ret), "=&r" (temp), "=m" (*p)
-     : "r" (oldval), "r" (newval), "m" (*p)
-     : "memory");
-
-  return ret;
-}
-
-#else
-
-long compare_and_swap (long *p, long oldval, long newval);
-
-#define STORE_ORDER_BARRIER()
-#define MEMORY_BARRIER_AFTER_ATOMIC()
-#define MEMORY_BARRIER()
-
-#endif
-#endif
index 256fa4717a8fe25180125c2e63ffe8ec469dd426..a2d9157c6868bdba6fde3e4423fd73ed9bdc46b9 100644 (file)
 
 #include "mm/memory.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
+#include "vm/method.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/stack.h"
 
-#include "vmcore/descriptor.h"
-#include "vmcore/method.h"
-
 
 /* register descripton array **************************************************/
 
diff --git a/src/vm/jit/mips/md-atomic.hpp b/src/vm/jit/mips/md-atomic.hpp
new file mode 100644 (file)
index 0000000..5cf0a3e
--- /dev/null
@@ -0,0 +1,166 @@
+/* src/vm/jit/mips/atomic.hpp - MIPS atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       uint32_t result;
+       uint32_t temp;
+
+       __asm__ __volatile__ (
+               "    .set  push      \n"
+               "    .set  mips2     \n"
+               "1:                  \n"
+               "    ll    %0,%5     \n"
+               "    bne   %0,%3,2f  \n"
+               "    move  %1,%4     \n"
+               "    sc    %1,%2     \n"
+               "    .set  pop       \n"
+               "    beqz  %1,1b     \n"
+               "2:                  \n"
+               : "=&r" (result), "=&r" (temp), "=m" (*p)
+               : "r" (oldval), "r" (newval), "m" (*p)
+               : "memory");
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+#if SIZEOF_VOID_P == 8
+       uint64_t result;
+       uint64_t temp;
+
+       __asm__ __volatile__ (
+               "    .set  push      \n"
+               "    .set  mips2     \n"
+               "1:                  \n"
+               "    lld   %0,%5     \n"
+               "    bne   %0,%3,2f  \n"
+               "    move  %1,%4     \n"
+               "    scd   %1,%2     \n"
+               "    .set  pop       \n"
+               "    beqz  %1,1b     \n"
+               "2:                  \n"
+               : "=&r" (result), "=&r" (temp), "=m" (*p)
+               : "r" (oldval), "r" (newval), "m" (*p)
+               : "memory");
+
+       return result;
+#else
+       return generic_compare_and_swap(p, oldval, newval);
+#endif
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+#if SIZEOF_VOID_P == 8
+       return (void*) compare_and_swap((volatile uint64_t*) p, (uint64_t) oldval, (uint64_t) newval);
+#else
+       return (void*) compare_and_swap((volatile uint32_t*) p, (uint32_t) oldval, (uint32_t) newval);
+#endif
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+#endif // _MD_ATOMIC_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 9fca702ef11d8d14dcdb5171c9eb62a23a62fa14..dbbee3249abe6a67ee770a66b72ee0bea901ca65 100644 (file)
@@ -58,6 +58,7 @@ enum {
        /* Don't use 8 (could be a normal load offset). */
 
        TRAP_COMPILER                       = 9,
+       TRAP_COUNTDOWN                      = 10,
        TRAP_END
 };
 
index 61e5113ee000d5382eff5ba3e8a61d9b59413556..af5f92fc1ab74d57fd369f933311801ca4ef17bf 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/mips/md.h"
 
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/jit.h"
 
index fc70b19bddbcbc9b229c9bdd1780f37f1a648207..100be5e306f3b2fa006624ca76270654f7d09028 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/md.h - machine dependent MIPS functions
 
-   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.
 
@@ -37,7 +35,7 @@
 
 #include "vm/types.h"
 
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 
 /* md_stacktrace_get_returnaddress *********************************************
@@ -70,28 +68,28 @@ inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframe
 
 *******************************************************************************/
 
-inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
+inline static void* md_codegen_get_pv_from_pc(void* ra)
 {
-       u1 *pv;
-       u4  mcode;
-       s4  offset;
+       int32_t offset;
+
+       uint32_t* pc = (uint32_t*) ra;
 
        /* get the offset of the instructions */
 
        /* get first instruction word after jump */
 
-       mcode = *((u4 *) ra);
+       uint32_t mcode = pc[0];
 
        /* check if we have 2 instructions (lui, daddiu) */
 
        if ((mcode >> 16) == 0x3c19) {
                /* get displacement of first instruction (lui) */
 
-               offset = (s4) (mcode << 16);
+               offset = (int32_t) (mcode << 16);
 
                /* get displacement of second instruction (daddiu) */
 
-               mcode = *((u4 *) (ra + 1 * 4));
+               mcode = pc[1];
 
 #if SIZEOF_VOID_P == 8
                assert((mcode >> 16) == 0x6739);
@@ -99,25 +97,23 @@ inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
                assert((mcode >> 16) == 0x2739);
 #endif
 
-               offset += (s2) (mcode & 0x0000ffff);
+               offset += (int16_t) (mcode & 0x0000ffff);
        }
        else {
                /* get offset of first instruction (daddiu) */
 
-               mcode = *((u4 *) ra);
-
 #if SIZEOF_VOID_P == 8
                assert((mcode >> 16) == 0x67fe);
 #else
                assert((mcode >> 16) == 0x27fe);
 #endif
 
-               offset = (s2) (mcode & 0x0000ffff);
+               offset = (int16_t) (mcode & 0x0000ffff);
        }
 
        /* calculate PV via RA + offset */
 
-       pv = ra + offset;
+       void* pv = (void*) (((uintptr_t) ra) + offset);
 
        return pv;
 }
index ef4f476b778cfda22773a1b01e5323a007735af3..2a0a9dd9adabfc755f81247768a2f58c8e910d73 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.h"
 
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vm/resolve.h"
-#include "vmcore/references.h"
-
 
 #define PATCH_BACK_ORIGINAL_MCODE \
        *((u4 *) pr->mpc) = (u4) pr->mcode; \
index a28d2d1bcd6ef71f644f8e0020b63d177c461240..fa352116becda5c4287eda97f5986fdd76f89833 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/uclinux/md-os.c - machine dependent MIPS uClinux functions
 
-   Copyright (C) 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) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -32,7 +30,7 @@
 
 #include "vm/types.h"
 
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 
 /* md_init *********************************************************************
@@ -71,21 +69,6 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       vm_abort("md_critical_section_restart: IMPLEMENT ME!");
-}
-#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
diff --git a/src/vm/jit/oprofile-agent.cpp b/src/vm/jit/oprofile-agent.cpp
new file mode 100644 (file)
index 0000000..ddf3d93
--- /dev/null
@@ -0,0 +1,118 @@
+/* src/vm/jit/oprofile-agent.cpp - oprofile agent implementation
+
+   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.
+
+*/
+
+
+#include "config.h"
+
+#include "mm/memory.h"
+
+#include "vm/jit/code.h"
+#include "vm/jit/oprofile-agent.hpp"
+
+#include <string.h>
+
+/* static fields **************************************************************/
+op_agent_t OprofileAgent::_handle = 0;
+
+/**
+ * Initializes the OprofileAgent system.
+ *
+ */
+/* void OprofileAgent_initialize() */
+void OprofileAgent::initialize(void)
+{
+       _handle = op_open_agent();
+       if (!_handle)
+               vm_abort_errno("unable to open opagent handle:");
+}
+
+/**
+ * Reports the given method to oprofile.
+ *
+ * This has to be done once per JIT compilation step for a specific method.
+ *
+ * @param m Method to register.
+ */
+/* void OprofileAgent_newmethod(methodinfo *m) */
+void OprofileAgent::newmethod(methodinfo *m)
+{
+       unsigned int real_length = (unsigned int) m->code->mcodelength -
+               (unsigned int) (m->code->entrypoint - m->code->mcode);
+
+       char *buf;
+       s4    len;
+
+       len = utf_bytes(m->clazz->name) + strlen(".") +
+                utf_bytes(m->name) + utf_bytes(m->descriptor) + strlen("0");
+
+       buf = MNEW(char, len);
+
+       utf_copy_classname(buf, m->clazz->name);
+       strcat(buf, ".");
+       utf_cat(buf, m->name);
+       utf_cat(buf, m->descriptor);
+
+       if (_handle)
+               op_write_native_code(_handle, buf,
+                       (uint64_t) (ptrint) m->code->entrypoint,
+                       (const void *) m->code->entrypoint,
+                       real_length);
+
+       MFREE(buf, char, len);
+}
+
+/**
+ * Shuts down the OprofileAgent system.
+ *
+ */
+/* void OprofileAgent_close() */
+void OprofileAgent::close()
+{
+       if (_handle)
+               op_close_agent(_handle);
+
+       _handle = 0;
+}
+/* Legacy C interface *********************************************************/
+
+extern "C" {
+
+void OprofileAgent_initialize() { OprofileAgent::initialize(); }
+void OprofileAgent_newmethod(methodinfo *m) { OprofileAgent::newmethod(m); }
+void OprofileAgent_close() { OprofileAgent::close(); }
+
+}
+
+/*
+ * 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/jit/oprofile-agent.hpp b/src/vm/jit/oprofile-agent.hpp
new file mode 100644 (file)
index 0000000..9b8cbdb
--- /dev/null
@@ -0,0 +1,84 @@
+/* src/vm/jit/oprofile-agent.hpp - oprofile agent implementation
+
+   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.
+
+*/
+
+
+#ifndef _OPROFILE_AGENT_HPP
+#define _OPROFILE_AGENT_HPP
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vm/method.h"
+
+#include <opagent.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+
+class OprofileAgent
+{
+       static op_agent_t _handle;
+
+public:
+       static void initialize();
+
+       static void newmethod(methodinfo *);
+
+       static void close();
+};
+
+#else
+
+/* Legacy C interface *********************************************************/
+
+typedef struct OprofileAgent OprofileAgent;
+
+void  OprofileAgent_initialize(void);
+void  OprofileAgent_newmethod(methodinfo *);
+void  OprofileAgent_close();
+
+#endif
+
+#endif /* _OPROFILE_AGENT_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 22fb1f2810f7ec0d9abbef087a5d153d69564849..70b942431c92042f32d43a5d841527f78361dc87 100644 (file)
    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 "mm/dumpmemory.h"
 #include "mm/memory.h"
 
 #include "toolbox/bitvector.h"
 
+#include "vm/class.h"
+#include "vm/descriptor.h"
 #include "vm/global.h"
-#include "vm/jit/ir/bytecode.h"
-#include "vm/jit/optimizing/escape.h"
+#include "vm/references.h"
 #include "vm/resolve.h"
 
-#include "vmcore/class.h"
-#include "vmcore/descriptor.h"
-#include "vmcore/references.h"
+#include "vm/jit/ir/bytecode.h"
+#include "vm/jit/optimizing/escape.h"
 
 #include <assert.h>
 #include <stdarg.h>
@@ -118,15 +122,10 @@ typedef struct {
        op_stack_slot_t *ptr;
        op_stack_slot_t *bottom;
        unsigned max;
+       bool *perror_flag;
 } op_stack_t;
 
-#define stack_assert_position(stack, pos) \
-       do { \
-               assert((stack)->elements <= (pos)); \
-               assert((pos) < (stack)->end); \
-       } while (0)
-
-static void op_stack_init(op_stack_t *stack, unsigned max) {
+static void op_stack_init(op_stack_t *stack, unsigned max, bool *perror_flag) {
        op_stack_slot_t *it;
 
        stack->elements = DMNEW(op_stack_slot_t, max * 2);
@@ -140,6 +139,27 @@ static void op_stack_init(op_stack_t *stack, unsigned max) {
 
        stack->ptr = stack->start;
        stack->bottom = stack->start;
+
+       stack->perror_flag = perror_flag;
+}
+
+static void op_stack_set_error(op_stack_t *stack) {
+       *(stack->perror_flag) = true;
+#if BC_ESCAPE_VERBOSE
+       printf("%s: error.\n", __FUNCTION__);
+#endif
+}
+
+static bool op_stack_test_position(op_stack_t *stack, op_stack_slot_t *pos) {
+       if (!(stack->elements <= pos)) {
+               op_stack_set_error(stack);
+               return false;
+       } else if (!(pos < stack->end)) {
+               op_stack_set_error(stack);
+               return false;
+       } else {
+               return true;
+       }
 }
 
 static void op_stack_reset(op_stack_t *stack) {
@@ -160,7 +180,9 @@ static void op_stack_reset(op_stack_t *stack) {
 static op_stack_slot_t op_stack_pop(op_stack_t *stack) {
        op_stack_slot_t ret;
        stack->ptr -= 1;
-       stack_assert_position(stack, stack->ptr);
+       if (! op_stack_test_position(stack, stack->ptr)) {
+               return OP_STACK_SLOT_UNKNOWN;
+       }
        ret = *(stack->ptr);
        if (stack->ptr < stack->bottom) {
                stack->bottom = stack->ptr;
@@ -169,19 +191,24 @@ static op_stack_slot_t op_stack_pop(op_stack_t *stack) {
 }
 
 static void op_stack_push(op_stack_t *stack, op_stack_slot_t element) {
-       stack_assert_position(stack, stack->ptr);
-       *(stack->ptr) = element;
-       stack->ptr += 1;
+       if (op_stack_test_position(stack, stack->ptr)) {
+               *(stack->ptr) = element;
+               stack->ptr += 1;
+       }
 }
 
 static op_stack_slot_t op_stack_get(const op_stack_t *stack, int offset) {
-       stack_assert_position(stack, stack->ptr - offset);
-       return *(stack->ptr - offset);
+       if (op_stack_test_position(stack, stack->ptr - offset)) {
+               return *(stack->ptr - offset);
+       } else {
+               return OP_STACK_SLOT_UNKNOWN;
+       }
 }
 
 static void op_stack_set(op_stack_t *stack, int offset, op_stack_slot_t value) {
-       stack_assert_position(stack, stack->ptr - offset);
-       *(stack->ptr - offset) = value;
+       if (op_stack_test_position(stack, stack->ptr - offset)) {
+               *(stack->ptr - offset) = value;
+       }
 }
 
 static inline void op_stack_push_unknown(op_stack_t *stack) {
@@ -301,13 +328,22 @@ typedef struct {
        u1 *pos;
        u1 *instruction_start;
        s4 offset;
+       bool *perror_flag;
 } jcode_t;
 
-static void jcode_init(jcode_t *jc, u1 *start, s4 length, s4 offset) {
+static void jcode_init(jcode_t *jc, u1 *start, s4 length, s4 offset, bool *perror_flag) {
        jc->start = start;
        jc->end = jc->start + length;
        jc->pos = jc->start;
        jc->offset = offset;
+       jc->perror_flag = perror_flag;
+}
+
+static void jcode_set_error(jcode_t *jc) {
+       *(jc->perror_flag) = true;
+#if BC_ESCAPE_VERBOSE
+       printf("%s: error.\n", __FUNCTION__);
+#endif
 }
 
 static void jcode_move_to_index(jcode_t *jc, s4 index) {
@@ -347,38 +383,56 @@ static s4 jcode_get_index(const jcode_t *jc) {
        return jc->offset + (jc->pos - jc->start);
 }
 
-#define jcode_assert_has_bytes(jc, n) \
-       assert((jc->pos + n) <= jc->end)
+bool jcode_test_has_bytes(jcode_t *jc, s4 n) {
+       if ((jc->pos + n) <= jc->end) {
+               return true;
+       } else {
+               jcode_set_error(jc);
+               return false;
+       }
+}
 
 static u1 jcode_get_u1(jcode_t *jc) {
        u1 ret;
-       jcode_assert_has_bytes(jc, 1);
-       ret = jc->pos[0];
-       jc->pos += 1;
+       if (jcode_test_has_bytes(jc, 1)) {
+               ret = jc->pos[0];
+               jc->pos += 1;
+       } else {
+               ret = 0;
+       }
        return ret;
 }
 
 static s2 jcode_get_s2(jcode_t *jc) {
        s2 ret;
-       jcode_assert_has_bytes(jc, 2);
-       ret = (jc->pos[0] << 8) | (jc->pos[1]);
-       jc->pos += 2;
+       if (jcode_test_has_bytes(jc, 2)) {
+               ret = (jc->pos[0] << 8) | (jc->pos[1]);
+               jc->pos += 2;
+       } else {
+               ret = 0;
+       }
        return ret;
 }
 
 static u2 jcode_get_u2(jcode_t *jc) {
        u2 ret;
-       jcode_assert_has_bytes(jc, 2);
-       ret = (jc->pos[0] << 8) | (jc->pos[1]);
-       jc->pos += 2;
+       if (jcode_test_has_bytes(jc, 2)) {
+               ret = (jc->pos[0] << 8) | (jc->pos[1]);
+               jc->pos += 2;
+       } else {
+               ret = 0;
+       }
        return ret;
 }
 
 static s4 jcode_get_s4(jcode_t *jc) {
        s4 ret;
-       jcode_assert_has_bytes(jc, 4);
-       ret = (jc->pos[0] << 24) | (jc->pos[1] << 16) | (jc->pos[2] << 8) | (jc->pos[3]);
-       jc->pos += 4;
+       if (jcode_test_has_bytes(jc, 4)) {
+               ret = (jc->pos[0] << 24) | (jc->pos[1] << 16) | (jc->pos[2] << 8) | (jc->pos[3]);
+               jc->pos += 4;
+       } else {
+               ret = 0;
+       }
        return ret;
 }
 
@@ -394,7 +448,9 @@ static s4 jcode_get_branch_target_wide(jcode_t *jc) {
 
 static s4 jcode_get_fall_through_target(jcode_t *jc) {
        int length = bytecode[*jc->instruction_start].length;
-       assert(length > 0);
+       if (length <= 0) {
+               jcode_set_error(jc);
+       }
        return jc->offset + (jc->instruction_start - jc->start) + length;
 }
 
@@ -420,6 +476,8 @@ typedef struct {
        bool verbose;
 #endif
        int depth;
+
+       bool fatal_error;
 } bc_escape_analysis_t;
 
 static void bc_escape_analysis_perform_intern(methodinfo *m, int depth);
@@ -430,13 +488,13 @@ static void bc_escape_analysis_init(bc_escape_analysis_t *be, methodinfo *m, boo
        int a;
        u1 *ite;
        u1 t;
-       int ret_adr;
        unsigned n;
+       int ret_val_is_adr;
 
        be->method = m;
 
        be->stack = DNEW(op_stack_t);
-       op_stack_init(be->stack, m->maxstack);
+       op_stack_init(be->stack, m->maxstack, &(be->fatal_error));
 
        be->basicblocks = DNEW(basicblock_work_list_t);
        basicblock_work_list_init(be->basicblocks);
@@ -464,27 +522,28 @@ static void bc_escape_analysis_init(bc_escape_analysis_t *be, methodinfo *m, boo
 
        assert(l == be->local_to_adr_param_size);
 
-       /* Determine whether return type is address */
-
-       ret_adr = m->parseddesc->returntype.type == TYPE_ADR ? 1 : 0;
+       ret_val_is_adr = m->parseddesc->returntype.type == TYPE_ADR ? 1 : 0;
 
        /* Allocate param_escape on heap. */
 
        be->param_escape_size = a;
-       n = a + ret_adr;
+       n = a + ret_val_is_adr;
 
        if (n == 0) {
                /* Use some non-NULL value. */
                be->param_escape = (u1 *)1;
        } else {
                be->param_escape = MNEW(u1, n);
+               be->param_escape += ret_val_is_adr;
        }
 
        for (ite = be->param_escape; ite != be->param_escape + n; ++ite) {
-               *ite = (u1)ESCAPE_NONE;
+               *ite = escape_state_to_u1(ESCAPE_NONE);
        }
 
-       be->param_escape += ret_adr;
+       if (ret_val_is_adr) {
+               be->param_escape[-1] = escape_state_to_u1(ESCAPE_NONE);
+       }
 
        be->adr_param_dirty = DNEW(bit_vector_t);
        bit_vector_init(be->adr_param_dirty, a);
@@ -499,6 +558,8 @@ static void bc_escape_analysis_init(bc_escape_analysis_t *be, methodinfo *m, boo
 #endif
 
        be->depth = depth;
+
+       be->fatal_error = false;
 }
 
 static void bc_escape_analysis_branch_target(bc_escape_analysis_t *be, s4 branch_target) {
@@ -524,8 +585,8 @@ static void bc_escape_analysis_adjust_state(
                                   parameters. */
 
                                if (
-                                       old < ESCAPE_GLOBAL_THROUGH_METHOD && 
-                                       escape_state >= ESCAPE_GLOBAL_THROUGH_METHOD
+                                       old < ESCAPE_GLOBAL && 
+                                       escape_state >= ESCAPE_GLOBAL
                                ) {
                                        be->non_escaping_adr_params -= 1;
                                }
@@ -550,16 +611,17 @@ static void bc_escape_analysis_dirty_2(bc_escape_analysis_t *be, s4 local) {
        bc_escape_analysis_dirty(be, local + 1);
 }
 
-static void bc_escape_analyisis_returned(bc_escape_analysis_t *be, op_stack_slot_t value) {
+static void bc_escape_analysis_returned(bc_escape_analysis_t *be, op_stack_slot_t value) {
        if (op_stack_slot_is_param(value)) {
                /* A parameter is returned, mark it as being returned. */
                bit_vector_set(be->adr_param_returned, value.index);
-       } else if (op_stack_slot_is_unknown(value)) {
-               /* An untracked value is returned.
-                  Conservatively asume a globally escaping value is returned. */
+               /* The escape state of the return value will be adjusted later. */
+       } else {
+               /* Adjust escape state of return value. */
                if (be->method->parseddesc->returntype.type == TYPE_ADR) {
-                       be->param_escape[-1] = (u1)ESCAPE_GLOBAL;
+                       be->param_escape[-1] = escape_state_to_u1(ESCAPE_GLOBAL);
                }
+               bc_escape_analysis_adjust_state(be, value, ESCAPE_GLOBAL);
        }
 }
 
@@ -589,6 +651,25 @@ value_category_t bc_escape_analysis_value_category(bc_escape_analysis_t *be, s4
        }
 }
 
+static void bc_escape_analysis_push_return_value(
+       bc_escape_analysis_t *be,
+       methoddesc *md
+) {
+       switch (md->returntype.type) {
+               case TYPE_LNG:
+               case TYPE_DBL:
+                       op_stack_push_unknown(be->stack);
+                       op_stack_push_unknown(be->stack);
+                       break;
+               case TYPE_VOID:
+                       /* Do nothing */
+                       break;
+               default:
+                       op_stack_push_unknown(be->stack);
+                       break;
+       }
+}
+
 static void bc_escape_analysis_adjust_invoke_parameters(
        bc_escape_analysis_t *be,
        methodinfo *mi
@@ -597,6 +678,8 @@ static void bc_escape_analysis_adjust_invoke_parameters(
        methoddesc *md = mi->parseddesc;
        u1 *paramescape = mi->paramescape;
        s4 stack_depth = md->paramslots;
+       unsigned num_params_returned = 0;
+       op_stack_slot_t param_returned;
 
        /* Process parameters. 
         * The first parameter is at the highest depth on the stack.
@@ -605,10 +688,14 @@ static void bc_escape_analysis_adjust_invoke_parameters(
        for (i = 0; i < md->paramcount; ++i) {
                switch (md->paramtypes[i].type) {
                        case TYPE_ADR:
+                               if (*paramescape & 0x80) {
+                                       num_params_returned += 1;
+                                       param_returned = op_stack_get(be->stack, stack_depth);
+                               }
                                bc_escape_analysis_adjust_state(
                                        be,
                                        op_stack_get(be->stack, stack_depth),
-                                       (escape_state_t)*(paramescape++)
+                                       escape_state_from_u1(*paramescape++)
                                );
                                stack_depth -= 1;
                                break;
@@ -627,7 +714,20 @@ static void bc_escape_analysis_adjust_invoke_parameters(
        for (i = 0; i < md->paramslots; ++i) {
                op_stack_pop(be->stack);
        }
+       
+       /* Push return value. */
 
+       if (md->returntype.type == TYPE_ADR) {
+               if ((num_params_returned == 1) && (mi->paramescape[-1] < ESCAPE_GLOBAL)) {
+                       /* Only a single argument can be returned by the method,
+                          and the retun value does not escape otherwise. */
+                       op_stack_push(be->stack, param_returned);
+               } else {
+                       op_stack_push_unknown(be->stack);
+               }
+       } else {
+               bc_escape_analysis_push_return_value(be, md);
+       }
 }
 
 static void bc_escape_analysis_escape_invoke_parameters(
@@ -638,6 +738,8 @@ static void bc_escape_analysis_escape_invoke_parameters(
        for (i = 0; i < md->paramslots; ++i) {
                bc_escape_analysis_adjust_state(be, op_stack_pop(be->stack), ESCAPE_GLOBAL);
        }
+
+       bc_escape_analysis_push_return_value(be, md);
 }
 
 static void bc_escape_analysis_parse_invoke(bc_escape_analysis_t *be, jcode_t *jc) {
@@ -713,7 +815,7 @@ static void bc_escape_analysis_parse_invoke(bc_escape_analysis_t *be, jcode_t *j
           or recurse into callee. 
           Otherwise we must assume, that all parameters escape. */
 
-       if (mi != NULL) {
+       if (mi != NULL && escape_is_monomorphic(be->method, mi)) {
 
                if (mi->paramescape == NULL) {
                        bc_escape_analysis_perform_intern(mi, be->depth + 1);
@@ -730,20 +832,6 @@ static void bc_escape_analysis_parse_invoke(bc_escape_analysis_t *be, jcode_t *j
        } else {
                bc_escape_analysis_escape_invoke_parameters(be, md);
        }
-
-       switch (md->returntype.type) {
-               case TYPE_LNG:
-               case TYPE_DBL:
-                       op_stack_push_unknown(be->stack);
-                       op_stack_push_unknown(be->stack);
-                       break;
-               case TYPE_VOID:
-                       /* Do nothing */
-                       break;
-               default:
-                       op_stack_push_unknown(be->stack);
-                       break;
-       }
 }
 
 static void bc_escape_analysis_parse_tableswitch(
@@ -825,7 +913,7 @@ static void bc_escape_analysis_process_basicblock(bc_escape_analysis_t *be, jcod
        /* TODO end if all parameters escape */
        /* TODO move code into process_instruction or the like */
 
-       while ((! jcode_end(jc)) && (! bb_end)) {
+       while ((! jcode_end(jc)) && (! bb_end) && (! be->fatal_error)) {
 
                jcode_record_instruction_start(jc);
 
@@ -1390,7 +1478,7 @@ static void bc_escape_analysis_process_basicblock(bc_escape_analysis_t *be, jcod
 
                        case BC_areturn:
                                /* FIXME */
-                               bc_escape_analyisis_returned(be, op_stack_pop(be->stack));
+                               bc_escape_analysis_returned(be, op_stack_pop(be->stack));
                                bb_end = true;
                                break;
 
@@ -1593,7 +1681,7 @@ static void bc_escape_analysis_process_basicblock(bc_escape_analysis_t *be, jcod
        }
 #endif
 
-       while (! op_stack_is_empty(be->stack)) {
+       while ((! op_stack_is_empty(be->stack)) && (! be->fatal_error)) {
 #if BC_ESCAPE_VERBOSE
                if (be->verbose) {
                        dprintf(be->depth, "Stack element: ");
@@ -1609,10 +1697,19 @@ static void bc_escape_analysis_process_basicblock(bc_escape_analysis_t *be, jcod
                }
 #endif
        }
+
+       if (be->fatal_error) {
+#if BC_ESCAPE_VERBOSE
+               if (be->verbose) {
+                       printf("Fatal error while processing basic block. Aborting.\n");
+               }
+#endif
+               assert(0);
+       }
 }
 
 static void    bc_escape_analysis_adjust_return_value(bc_escape_analysis_t *be) {
-       escape_state_t e, pe;
+       escape_state_t re, pe;
        int i;
 
        /* Only calculate, if return value is of type address. */
@@ -1621,22 +1718,20 @@ static void     bc_escape_analysis_adjust_return_value(bc_escape_analysis_t *be) {
                return ;
        }
 
-       /* Get current escape state of return value. */
-
-       e = (escape_state_t)be->param_escape[-1];
-
        /* If a parameter can be returned, adjust to its escape state. */
 
        for (i = 0; i < be->param_escape_size; ++i) {
                if (bit_vector_get(be->adr_param_returned, i)) {
-                       pe = (escape_state_t)be->param_escape[i];
-                       if (pe > e) {
-                               e = pe;
+                       be->param_escape[i] |= 0x80;
+
+                       pe = escape_state_from_u1(be->param_escape[i]);
+                       re = escape_state_from_u1(be->param_escape[-1]);
+                       
+                       if (pe > re) {
+                               be->param_escape[-1] = escape_state_to_u1(pe);
                        }
                }
        }
-
-       be->param_escape[-1] = (u1)e;
 }
 
 static void bc_escape_analysis_analyze(bc_escape_analysis_t *be) {
@@ -1664,7 +1759,8 @@ static void bc_escape_analysis_analyze(bc_escape_analysis_t *be) {
                &jc,
                be->method->jcode,
                be->method->jcodelength,
-               0
+               0,
+               &(be->fatal_error)
        );
 
        /* Process basicblock by basicblock. */
@@ -1702,6 +1798,10 @@ static void bc_escape_analysis_perform_intern(methodinfo *m, int depth) {
        }
 #endif
 
+       if (depth >= 3) {
+               return;
+       }
+
        if (m->paramescape != NULL) {
 #if BC_ESCAPE_VERBOSE
                if (verbose) {  
@@ -1729,7 +1829,14 @@ static void bc_escape_analysis_perform_intern(methodinfo *m, int depth) {
                return;
        }
 
-       /* TODO threshold */
+       if (m->jcodelength > 250) {
+#if BC_ESCAPE_VERBOSE
+               if (verbose) {
+                       dprintf(depth, "Bytecode too long: %d.\n", m->jcodelength);
+               }
+#endif
+               return;
+       }
 
        be = DNEW(bc_escape_analysis_t);
        bc_escape_analysis_init(be, m, verbose, depth);
index b1c0679d584720036e7d81704fc7d160c5d62cfd..cca121315a344b1328a5d83dbce6e3abf5f2522c 100644 (file)
@@ -1,4 +1,4 @@
-/* src/vm/optimizing/escape.c
+/* src/vm/jit/optimizing/escape.c
 
    Copyright (C) 2008
    CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
    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 "vm/class.h"
+#include "vm/classcache.h"
+
 #include "vm/jit/jit.h"
-#include "vmcore/class.h"
 #include "vm/jit/optimizing/escape.h"
 
+#include <stdarg.h>
+
+#if defined(ENABLE_ESCAPE_REASON)
+#define ENABLE_REASON
+#endif
+
+#if defined(ENABLE_REASON)
+#define I2(why, tov, es) escape_analysis_record_reason(e, why, iptr, tov, es);
+#else
+#define I2(why, tov, es)
+#endif
+#define I(why, to, from) I2(why, instruction_ ## to (iptr), escape_analysis_get_state(e, instruction_ ## from (iptr)))
+#define E2(why, var) I2(why, var, ESCAPE_GLOBAL)
+#define E(why, which) E2(why, instruction_ ## which (iptr))
+
+typedef enum {
+       RED = 31,
+       GREEN,
+       YELLOW,
+       BLUE,
+       MAGENTA,
+       CYAN,
+       WHITE,
+       COLOR_END
+} color_t;
+
+#define ENABLE_COLOR
+
+static void color_start(color_t color) {
+#if defined(ENABLE_COLOR)
+       if (RED <= color && color < COLOR_END) {
+               printf("\033[%dm", color);
+       }
+#endif
+}
+
+static void color_end() {
+#if defined(ENABLE_COLOR)
+       printf("\033[m");
+       fflush(stdout);
+#endif
+}
+
+static void color_printf(color_t color, const char *fmt, ...) {
+       va_list ap;
+       color_start(color);
+       va_start(ap, fmt);
+       vprintf(fmt, ap);
+       va_end(ap);
+       color_end();
+}
+
+
 /*** escape_state *************************************************************/
 
 const char *escape_state_to_string(escape_state_t escape_state) {
@@ -33,7 +92,7 @@ const char *escape_state_to_string(escape_state_t escape_state) {
                str(ESCAPE_UNKNOWN)
                str(ESCAPE_NONE)
                str(ESCAPE_METHOD)
-               str(ESCAPE_GLOBAL_THROUGH_METHOD)
+               str(ESCAPE_METHOD_RETURN)
                str(ESCAPE_GLOBAL)
                default: return "???";
        }
@@ -150,6 +209,8 @@ typedef struct {
 
        instruction_list_t *allocations;
        instruction_list_t *getfields;
+       instruction_list_t *monitors;
+       instruction_list_t *returns;
 
        struct var_extra **var;
 
@@ -274,12 +335,25 @@ void dependenCy_list_import(dependency_list_t *dl, dependency_list_t *other) {
 
 /*** var_extra ***************************************************************/
 
+#if defined(ENABLE_REASON)
+typedef struct reason {
+       const char *why;
+       instruction *iptr;
+       struct reason *next;
+} reason_t;
+#endif
+
 typedef struct var_extra {
        instruction *allocation;
        escape_state_t escape_state;
        s4 representant;
        dependency_list_t *dependency_list;
-       bool is_arg; /* TODO optimize */
+       unsigned contains_arg:1;
+       unsigned contains_only_args:1;
+       /*signed adr_arg_num:30;*/
+#if defined(ENABLE_REASON)
+       reason_t *reasons;
+#endif
 } var_extra_t;
 
 static void var_extra_init(var_extra_t *ve) {
@@ -287,7 +361,12 @@ static void var_extra_init(var_extra_t *ve) {
        ve->escape_state = ESCAPE_NONE;
        ve->representant = -1;
        ve->dependency_list = NULL;
-       ve->is_arg = false;
+       ve->contains_arg = false;
+       ve->contains_only_args = false;
+       /*ve->adr_arg_num = -1;*/
+#if defined(ENABLE_REASON)
+       ve->reasons = NULL;
+#endif
 }
 
 static inline var_extra_t *var_extra_get_no_alloc(const escape_analysis_t *e, s4 var) {
@@ -371,18 +450,41 @@ static void escape_analysis_init(escape_analysis_t *e, jitdata *jd) {
        e->getfields = DNEW(instruction_list_t);
        instruction_list_init(e->getfields);
 
+       e->monitors = DNEW(instruction_list_t);
+       instruction_list_init(e->monitors);
+
+       e->returns = DNEW(instruction_list_t);
+       instruction_list_init(e->returns);
+
        e->var = DMNEW(var_extra_t *, jd->vartop);
        MZERO(e->var, var_extra_t *, jd->vartop);
 
        e->adr_args_count = 0;
 
-       e->verbose = (
-               strcmp(e->jd->m->clazz->name->text, "gnu/java/util/regex/RESyntax") == 0 
-               && strcmp(e->jd->m->name->text, "<clinit>") == 0
-       );
        e->verbose = 1;
+       e->verbose = strcmp(jd->m->name->text, "<init>") == 0;
+       e->verbose = getenv("EV") != NULL;
 }
 
+#if defined(ENABLE_REASON)
+static void escape_analysis_record_reason(escape_analysis_t *e, const char *why, instruction *iptr, s4 var, escape_state_t es) {
+       var_extra_t *ve;
+       reason_t *re;
+       if (es == ESCAPE_GLOBAL || es == ESCAPE_METHOD_RETURN) {
+               var = var_extra_get_representant(e, var);
+               ve = var_extra_get(e, var);
+               re = NEW(reason_t);
+               re->why = why;
+               re->iptr= iptr;
+               re->next = ve->reasons;
+               ve->reasons = re;
+               if (e->verbose) {
+                       printf("%d escapes because %s\n", var, why);
+               }
+       }
+}
+#endif
+
 static void escape_analysis_set_allocation(escape_analysis_t *e, s4 var, instruction *iptr) {
        var_extra_get(e, var)->allocation = iptr;
 }
@@ -396,12 +498,38 @@ static instruction *escape_analysis_get_allocation(const escape_analysis_t *e, s
        return ve->allocation;
 }
 
-static void escape_analysis_set_is_argument(escape_analysis_t *e, s4 var) {
-       var_extra_get(e, var)->is_arg = true;
+static void escape_analysis_set_contains_argument(escape_analysis_t *e, s4 var) {
+       var = var_extra_get_representant(e, var);
+       var_extra_get(e, var)->contains_arg = true;
+}
+
+static bool escape_analysis_get_contains_argument(escape_analysis_t *e, s4 var) {
+       var = var_extra_get_representant(e, var);
+       return var_extra_get(e, var)->contains_arg;
+}
+
+static void escape_analysis_set_contains_only_arguments(escape_analysis_t *e, s4 var) {
+       var = var_extra_get_representant(e, var);
+       var_extra_get(e, var)->contains_only_args = true;
+}
+
+static bool escape_analysis_get_contains_only_arguments(escape_analysis_t *e, s4 var) {
+       var = var_extra_get_representant(e, var);
+       return var_extra_get(e, var)->contains_only_args;
+}
+
+/*
+static void escape_analysis_set_adr_arg_num(escape_analysis_t *e, s4 var, s4 num) {
+       var_extra_get(e, var)->adr_arg_num = num;
+}
+
+static s4 escape_analysis_get_adr_arg_num(escape_analysis_t *e, s4 var) {
+       return var_extra_get(e, var)->adr_arg_num;
 }
+*/
 
-static bool escape_analysis_get_is_argument(escape_analysis_t *e, s4 var) {
-       return var_extra_get(e, var)->is_arg;
+static bool escape_analysis_in_same_set(escape_analysis_t *e, s4 var1, s4 var2) {
+       return var_extra_get_representant(e, var1) == var_extra_get_representant(e, var2);
 }
 
 static void escape_analysis_ensure_state(escape_analysis_t *e, s4 var, escape_state_t escape_state) {
@@ -432,6 +560,10 @@ static void escape_analysis_ensure_state(escape_analysis_t *e, s4 var, escape_st
                                        dependency_list_item_get_dependency(it),
                                        escape_state
                                );
+                               {
+                               instruction *iptr = NULL;
+                               I2("propagated by dependency", dependency_list_item_get_dependency(it), escape_state);
+                               }
                        }
                }
        }
@@ -441,12 +573,6 @@ static escape_state_t escape_analysis_get_state(escape_analysis_t *e, s4 var) {
        return var_extra_get_escape_state(e, var);
 }
 
-#define escape_analysis_assert_has_escape(e, var) \
-       assert( \
-               var_extra_get_no_alloc(e, var) && \
-               (var_extra_get_no_alloc(e, var)->escape_state > ESCAPE_UNKNOWN) \
-       )
-
 static classinfo *escape_analysis_classinfo_in_var(escape_analysis_t *e, s4 var) {
        instruction *iptr = escape_analysis_get_allocation(e, var);
 
@@ -484,6 +610,8 @@ static void escape_analysis_merge(escape_analysis_t *e, s4 var1, s4 var2) {
                return;
        }
 
+       if (e->verbose) printf("Merging (%d,%d)\n", var1, var2);
+
        ve1 = var_extra_get(e, var1);
        ve2 = var_extra_get(e, var2);
 
@@ -496,10 +624,10 @@ static void escape_analysis_merge(escape_analysis_t *e, s4 var1, s4 var2) {
 
        ve2->representant = var1;
 
-       /* Adjust is_argument to logical or. */
+       /* Adjust is_arg to logical or. */
        
-       has_become_arg = ve1->is_arg != ve2->is_arg;
-       ve1->is_arg = ve1->is_arg || ve2->is_arg;
+       has_become_arg = ve1->contains_arg != ve2->contains_arg;
+       ve1->contains_arg = ve1->contains_arg || ve2->contains_arg;
 
        if (e->verbose && has_become_arg) printf("(%d,%d) has become arg.\n", var1, var2);
 
@@ -521,8 +649,35 @@ static void escape_analysis_merge(escape_analysis_t *e, s4 var1, s4 var2) {
                                dependency_list_item_get_dependency(itd),
                                ESCAPE_GLOBAL
                        );
+                       {
+                       instruction *iptr = NULL;
+                       E2("has become arg", dependency_list_item_get_dependency(itd));
+                       }
+               }
+       }
+
+       /* Adjust contains_only_args to logical and. */
+
+       ve1->contains_only_args = ve1->contains_only_args && ve2->contains_only_args;
+
+       /* Adjust address argument number contained in this var. */
+
+       /*
+       if (ve1->adr_arg_num != ve2->adr_arg_num) {
+               ve1->adr_arg_num = -1;
+       }
+       */
+#if defined(ENABLE_REASON)
+       if (ve1->reasons) {
+               reason_t *re = ve1->reasons;
+               while (re->next != NULL) {
+                       re = re->next;
                }
+               re->next = ve2->reasons;
+       } else {
+               ve1->reasons = ve2->reasons;
        }
+#endif
 }
 
 static void escape_analysis_add_dependency(escape_analysis_t *e, instruction *store) {
@@ -534,7 +689,9 @@ static void escape_analysis_add_dependency(escape_analysis_t *e, instruction *st
        dependency_list_add(dl, store);
 
        if (e->verbose) {
-               printf("dependency_list_add\n");
+               printf("dependency_list_add: %d.dependency_list.add( { ", obj);
+               show_icmd(e->jd, store, 0, 3);
+               printf(" } )\n"); 
        }
 }
 
@@ -545,12 +702,16 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
        u1 *paramescape;
        unsigned i;
        instruction **iarg;
-       constant_FMIref *fmi;
        methodinfo *mi;
-       resolve_result_t result;
+       escape_state_t es;
+       const char *why;
 
        if (e->verbose) {
-               printf("processing %s@%d\n", icmd_table[iptr->opc].name, iptr->line);
+               color_start(CYAN);
+               printf("%d: ", iptr->line);
+               show_icmd(e->jd, iptr, 0, 3);
+               color_end();
+               printf("\n");
        }
 
        switch (instruction_get_opcode(iptr)) {
@@ -568,46 +729,51 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
 
                        if (c == NULL) {
                                escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
-                               if (e->verbose) printf("1\n");
+                               E("unresolved class", dst)
                        } else if (c->finalizer != NULL) {
                                escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
-                               if (e->verbose) printf("3\n");
+                               E("finalizer", dst)
                        } else {
                                escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
-                               if (e->verbose) printf("2\n");
                        }
 
                        instruction_list_add(e->allocations, iptr);
 
                        break;
 
+               case ICMD_MONITORENTER:
+               case ICMD_MONITOREXIT:
+               
+                       instruction_list_add(e->monitors, iptr);
+
+                       break;
+
                case ICMD_NEWARRAY:
                case ICMD_ANEWARRAY:
                        
                        escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
                        escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
                        instruction_list_add(e->allocations, iptr);
-
+                       E("untracked array", dst)
                        break;
 
                case ICMD_PUTSTATIC:
                        if (instruction_field_type(iptr) == TYPE_ADR) {
-                               /*
-                               escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                               */
                                escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_GLOBAL);
+                               E("putstatic", s1)
                        }
                        break;
 
                case ICMD_PUTFIELD:
                        if (instruction_field_type(iptr) == TYPE_ADR) {
-                               /*
-                               escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                               escape_analysis_assert_has_escape(e, instruction_s2(iptr));
-                               */
-                               if (escape_analysis_get_is_argument(e, instruction_s1(iptr))) {
+                               if (escape_analysis_get_contains_argument(e, instruction_s1(iptr))) {
                                        escape_analysis_ensure_state(e, instruction_s2(iptr), ESCAPE_GLOBAL);
+                                       /* If s1 is currently not an argument, but can contain one later because
+                                          of a phi function, the merge function takes care to make all
+                                          dependencies escape globally. */
+                                       E("putfield into argument", s2)
                                } else {
+                                       I("putfield inherit", s2, s1);
                                        escape_analysis_ensure_state(e, instruction_s2(iptr), escape_analysis_get_state(e, instruction_s1(iptr)));
                                        escape_analysis_add_dependency(e, iptr);
                                }
@@ -615,13 +781,13 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
                        break;
 
                case ICMD_AASTORE:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       escape_analysis_assert_has_escape(e, instruction_s3(iptr));
-                       */
-                       if (escape_analysis_get_is_argument(e, instruction_s1(iptr))) {
+                       if (escape_analysis_get_contains_argument(e, instruction_s1(iptr))) {
+                               if (e->verbose) printf("Contains argument.\n");
                                escape_analysis_ensure_state(e, instruction_s3(iptr), ESCAPE_GLOBAL);
+                               E("aastore into argument", s3)
                        } else {
+                               if (e->verbose) printf("Contains no argument.\n");
+                               I("aastore", s3, s1)
                                escape_analysis_ensure_state(e, instruction_s3(iptr), escape_analysis_get_state(e, instruction_s1(iptr)));
                                escape_analysis_add_dependency(e, iptr);
                        }
@@ -630,22 +796,21 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
                case ICMD_GETSTATIC:
                        if (instruction_field_type(iptr) == TYPE_ADR) {
                                escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
+                               E("loaded from static var", dst)
                                escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
                        }
                        break;
 
                case ICMD_GETFIELD:
                        if (instruction_field_type(iptr) == TYPE_ADR) {
-                               /*
-                               escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                               */
 
-                               if (escape_analysis_get_is_argument(e, instruction_s1(iptr))) {
+                               if (escape_analysis_get_contains_argument(e, instruction_s1(iptr))) {
                                        /* Fields loaded from arguments escape globally.
                                           x = arg.foo;
                                           x.bar = y;
                                           => y escapes globally. */
                                        escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
+                                       E("loaded from arg", dst)
                                } else {
                                        escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
                                }
@@ -657,19 +822,15 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
                        break;
 
                case ICMD_ARRAYLENGTH:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       */
+                       escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
                        break;
 
                case ICMD_AALOAD:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       */
 
-                       if (escape_analysis_get_is_argument(e, instruction_s1(iptr))) {
+                       if (escape_analysis_get_contains_argument(e, instruction_s1(iptr))) {
                                /* If store into argument, escapes globally. See ICMD_GETFIELD. */
                                escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
+                               E("aaload from argument", dst)
                        } else {
                                escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
                        }
@@ -681,36 +842,27 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
 
                case ICMD_IF_ACMPEQ:
                case ICMD_IF_ACMPNE:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       escape_analysis_assert_has_escape(e, instruction_s2(iptr));
-                       */
                        escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
                        escape_analysis_ensure_state(e, instruction_s2(iptr), ESCAPE_METHOD);
                        break;
 
                case ICMD_IFNULL:
                case ICMD_IFNONNULL:
+                       escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
+                       break;
+
                case ICMD_CHECKNULL:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       */
                        escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
+                       escape_analysis_merge(e, instruction_s1(iptr), instruction_dst(iptr));
                        break;
 
                case ICMD_CHECKCAST:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       */
                        escape_analysis_merge(e, instruction_s1(iptr), instruction_dst(iptr));
                        escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
                        escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
                        break;
 
                case ICMD_INSTANCEOF:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       */
                        escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD);
                        break;
 
@@ -721,15 +873,25 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
                        count = instruction_arg_count(iptr);
                        mi = instruction_local_methodinfo(iptr);
                        paramescape = NULL;
+                       why = "???";
 
                        if (mi != NULL) {
                                /* If the method could be resolved, it already is. */
                                paramescape = mi->paramescape;
 
+                               if (e->verbose) {
+                                       if (paramescape) {
+                                               printf("Paramescape for callee available.\n");
+                                       }
+                               }
+
+                               if (paramescape) why = "Available param escape";
+
                                if (paramescape == NULL) {
                                        if (e->verbose) {
                                                printf("BC escape analyzing callee.\n");
                                        }
+                                       why = "BC param escape";
                                        bc_escape_analysis_perform(mi);
                                        paramescape = mi->paramescape;
                                }
@@ -737,26 +899,66 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
                                if (e->verbose) {
                                        printf("Unresolved callee.\n");
                                }
+                               why = "Unresolved callee";
+                       }
+
+                       if (iptr->opc == ICMD_INVOKEVIRTUAL || iptr->opc == ICMD_INVOKEINTERFACE) {
+                               if (mi != NULL && !escape_is_monomorphic(e->jd->m, mi)) {
+                                       if (e->verbose) {
+                                               printf("Not monomorphic.\n");
+                                       }
+                                       why = "Polymorphic";
+                                       paramescape = NULL;
+                               }
                        }
 
+                       /* Set the escape state of the return value.
+                          This is: global if we down have information of the callee, or the callee
+                          supplied escape state. */
+
+                       if (instruction_return_type(iptr) == TYPE_ADR) {
+                               if (paramescape == NULL) {
+                                       escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_GLOBAL);
+                                       E(why, dst);
+                               } else {
+                                       es = escape_state_from_u1(paramescape[-1]);
+                                       I2(why, instruction_dst(iptr), es)
+                                       escape_analysis_ensure_state(e, instruction_dst(iptr), es);
+                               }
+                               escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
+                       }
+                       
                        for (i = 0; i < count; ++i) {
                                if (instruction_arg_type(iptr, i) == TYPE_ADR) {
 
-                                       /*
-                                       escape_analysis_assert_has_escape(e, instruction_arg(iptr, i));
-                                       */
                                        if (paramescape == NULL) {
                                                escape_analysis_ensure_state(
                                                        e, 
                                                        instruction_arg(iptr, i), 
-                                                       instruction_local_methodinfo(iptr) && instruction_local_methodinfo(iptr)->jcode ?
-                                                               ESCAPE_GLOBAL_THROUGH_METHOD :
-                                                               ESCAPE_GLOBAL
+                                                       ESCAPE_GLOBAL
                                                );
-                                       } else if ((escape_state_t)*paramescape < ESCAPE_METHOD) {
-                                               escape_analysis_ensure_state(e, instruction_arg(iptr, i), ESCAPE_METHOD);
+                                               E2(why, instruction_arg(iptr, i));
+                                       } else if (escape_state_from_u1(*paramescape) <= ESCAPE_METHOD) {
+                                               es = escape_state_from_u1(*paramescape);
+
+                                               if (es < ESCAPE_METHOD) {
+                                                       es = ESCAPE_METHOD;
+                                               }
+
+                                               I2(why, instruction_arg(iptr, i), es);
+                                               escape_analysis_ensure_state(e, instruction_arg(iptr, i), es);
+
+                                               if (*paramescape & 0x80) {
+                                                       /* Parameter can be returned from method.
+                                                          This creates an alias to the retur value.
+                                                          If the return value escapes, the ES of the parameter needs 
+                                                          to be adjusted. */
+                                                       escape_analysis_merge(e, instruction_arg(iptr, i), instruction_dst(iptr));
+                                                       I2("return alias", instruction_arg(iptr, i), instruction_dst(iptr));
+                                               }
                                        } else {
-                                               escape_analysis_ensure_state(e, instruction_arg(iptr, i), (escape_state_t)*paramescape);
+                                               escape_analysis_ensure_state(e, instruction_arg(iptr, i), ESCAPE_GLOBAL);
+                                               E2(why, instruction_arg(iptr, i));
                                        }
 
                                        if (paramescape != NULL) {
@@ -765,25 +967,20 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
                                }
                        }
 
-                       if (instruction_return_type(iptr) == TYPE_ADR) {
-                               escape_analysis_ensure_state(e, instruction_dst(iptr), ESCAPE_NONE);
-                               escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
-                       }
-
                        break;
 
                case ICMD_ATHROW:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       */
                        escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_GLOBAL);
+                       E("throw", s1)
                        break;
 
                case ICMD_ARETURN:
-                       /*
-                       escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                       */
-                       escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_GLOBAL);
+                       /* If we return only arguments, the return value escapes only the method.
+                          ESCAPE_METHOD for now, and check later, if a different value than an
+                          argument is possibly returned. */
+                       escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_METHOD_RETURN);
+                       E("return", s1)
+                       instruction_list_add(e->returns, iptr);
                        break;
 
                case ICMD_ALOAD:
@@ -791,9 +988,6 @@ static void escape_analysis_process_instruction(escape_analysis_t *e, instructio
                case ICMD_MOVE:
                case ICMD_COPY:
                        if (instruction_dst_type(iptr, jd) == TYPE_ADR) {
-                               /*
-                               escape_analysis_assert_has_escape(e, instruction_s1(iptr));
-                               */
                                escape_analysis_merge(e, instruction_s1(iptr), instruction_dst(iptr));
                                escape_analysis_set_allocation(e, instruction_dst(iptr), iptr);
                        }
@@ -821,6 +1015,10 @@ static void escape_analysis_process_instructions(escape_analysis_t *e) {
 
        FOR_EACH_BASICBLOCK(e->jd, bptr) {
 
+               if (e->verbose) {
+                       color_printf(CYAN, "=== BB %d ===\n", bptr->nr);        
+               }
+
                for (iptr = bptr->phis; iptr != bptr->phis + bptr->phicount; ++iptr) {
                        escape_analysis_process_instruction(e, iptr);
                }
@@ -832,12 +1030,30 @@ static void escape_analysis_process_instructions(escape_analysis_t *e) {
        }
 }
 
+static void escape_analysis_post_process_returns(escape_analysis_t *e) {
+       instruction_list_item_t *iti;
+       instruction *iptr;
+
+       if (e->verbose) printf("Post processing returns:\n");
+
+       FOR_EACH_INSTRUCTION_LIST(e->getfields, iti) {
+               iptr = iti->instr;
+
+               if (! escape_analysis_get_contains_only_arguments(e, instruction_s1(iptr))) {
+                       escape_analysis_ensure_state(e, instruction_s1(iptr), ESCAPE_GLOBAL);
+                       E("return of not argument", s1)
+               }
+       }
+}
+
 static void escape_analysis_post_process_getfields(escape_analysis_t *e) {
        instruction_list_item_t *iti;
        dependency_list_item_t *itd;
        instruction *iptr;
        dependency_list_t *dl;
 
+       if (e->verbose) printf("Post processing getfields:\n");
+
        FOR_EACH_INSTRUCTION_LIST(e->getfields, iti) {
 
                iptr = iti->instr;
@@ -860,6 +1076,7 @@ static void escape_analysis_post_process_getfields(escape_analysis_t *e) {
                                                dependency_list_item_get_dependency(itd),
                                                escape_analysis_get_state(e, instruction_dst(iptr))
                                        );
+                                       I2("post process getfield", dependency_list_item_get_dependency(itd), escape_analysis_get_state(e, instruction_dst(iptr)));
                                }
                        }
                }
@@ -867,44 +1084,59 @@ static void escape_analysis_post_process_getfields(escape_analysis_t *e) {
        }
 }
 
-static void display_allocation(escape_analysis_t *e, const char *prefix, const instruction *iptr, escape_state_t es) {
-       const char *cl = "WTF";
-       classinfo *c;
+static void escape_analysis_mark_monitors(escape_analysis_t *e) {
+       instruction_list_item_t *iti;
+       instruction *iptr;
+
+       FOR_EACH_INSTRUCTION_LIST(e->monitors, iti) {
+               iptr = iti->instr;
 
-       if (instruction_get_opcode(iptr) == ICMD_NEW) {
-               c = escape_analysis_classinfo_in_var(e, instruction_arg(iptr, 0));
-               if (c) {
-                       cl = c->name->text;
+               /* TODO if argument does not escape, mark. */
+               if (escape_analysis_get_state(e, instruction_arg(iptr, 0)) != ESCAPE_GLOBAL) {
+                       if (e->verbose) {
+                               printf("Monitor on thread local object!\n");
+                       }
                }
        }
-       
-
-       printf(
-               " %s %s %s: %s %s @%d %s\n", 
-               prefix,
-               e->jd->m->clazz->name->text,
-               e->jd->m->name->text,
-               icmd_table[iptr->opc].name,
-               cl,
-               iptr->line,
-               escape_state_to_string(es)
-       );
 }
 
 static void escape_analysis_mark_allocations(escape_analysis_t *e) {
        instruction_list_item_t *iti;
+       instruction *iptr;
        escape_state_t es;
-/*
        FOR_EACH_INSTRUCTION_LIST(e->allocations, iti) {
-               es = escape_analysis_get_state(e, instruction_dst(iti->instr));
-               if (es < ESCAPE_GLOBAL_THROUGH_METHOD) {
-                       display_allocation(e, "****", iti->instr, es);
+               iptr = iti->instr;
+               es = escape_analysis_get_state(e, instruction_dst(iptr));
+
+#if defined(ENABLE_REASON)
+               if (instruction_get_opcode(iptr) == ICMD_NEW) {
+                       var_extra_t *ve;
+                       iptr->sx.s23.s3.bte = builtintable_get_internal(BUILTIN_escape_reason_new);
+                       ve = var_extra_get(e, var_extra_get_representant(e, instruction_dst(iptr)));
+                       iptr->escape_reasons = ve->reasons;
+                       if (es < ESCAPE_METHOD_RETURN) {
+                               assert(!ve->reasons);
+                               reason_t *r = NEW(reason_t);
+                               r->why = "No escape\n";
+                               r->iptr = NULL;
+                               r->next = NULL;
+                               iptr->escape_reasons = r;
+                       } else {
+                               assert(iptr->escape_reasons);
+                       }
                }
-               if (es == ESCAPE_GLOBAL_THROUGH_METHOD) {
-                       display_allocation(e, "!!!!", iti->instr, es);
+#endif
+
+/*
+               if (instruction_get_opcode(iptr) == ICMD_NEW) {
+                       es = escape_analysis_get_state(e, instruction_dst(iptr));
+                       if (es < ESCAPE_METHOD_RETURN) {
+                               iptr->sx.s23.s3.bte = builtintable_get_internal(BUILTIN_tlh_new);
+                               e->jd->code->flags |= CODE_FLAG_TLH;
+                       }
                }
-       }
 */
+       }
 }
 
 static void escape_analysis_process_arguments(escape_analysis_t *e) {
@@ -922,7 +1154,9 @@ static void escape_analysis_process_arguments(escape_analysis_t *e) {
                if (t == TYPE_ADR) {
                        if (varindex != UNUSED) {
                                escape_analysis_ensure_state(e, varindex, ESCAPE_NONE);
-                               escape_analysis_set_is_argument(e, varindex);
+                               escape_analysis_set_contains_argument(e, varindex);
+                               escape_analysis_set_contains_only_arguments(e, varindex);
+                               /*escape_analysis_set_adr_arg_num(e, varindex, e->adr_args_count);*/
                        }
                        e->adr_args_count += 1;
                }
@@ -937,11 +1171,18 @@ static void escape_analysis_export_arguments(escape_analysis_t *e) {
        s4 varindex;
        methoddesc *md;
        u1 *paramescape;
+       instruction_list_item_t *iti;
+       instruction *iptr;
+       escape_state_t es, re;
+       int ret_val_is_adr;
        
        md = e->jd->m->parseddesc;
 
-       paramescape = MNEW(u1, e->adr_args_count);
-       e->jd->m->paramescape = paramescape;
+       ret_val_is_adr = (md->returntype.type == TYPE_ADR) ? 1 : 0;
+
+       paramescape = MNEW(u1, e->adr_args_count + ret_val_is_adr);
+
+       e->jd->m->paramescape = paramescape + ret_val_is_adr;
 
        for (p = 0, l = 0; p < md->paramcount; ++p) {
                t = md->paramtypes[p].type;
@@ -950,16 +1191,59 @@ static void escape_analysis_export_arguments(escape_analysis_t *e) {
                        if (varindex == UNUSED) {
                                *paramescape = (u1)ESCAPE_NONE;
                        } else {
-                               *paramescape = (u1)escape_analysis_get_state(e, varindex);
-                       }
-                       if (e->verbose) {
-                               printf("adr parameter %d: %s\n", p, escape_state_to_string((escape_state_t)*paramescape));
+                               es = escape_analysis_get_state(e, varindex);
+
+                               if (es == ESCAPE_METHOD_RETURN) {
+                                       *paramescape = escape_state_to_u1(ESCAPE_METHOD) | 0x80;
+                                       if (e->verbose) {
+                                               printf("non-escaping adr parameter returned: %d\n", p);
+                                       }
+                               } else {
+                                       *paramescape = escape_state_to_u1(es);
+                               }
+
                        }
                        paramescape += 1;
                }
                l += IS_2_WORD_TYPE(t) ? 2 : 1;
        }
+
+       if (ret_val_is_adr) {
+               /* Calculate escape state of return value as maximum escape state of all
+                  values returned. */
+
+               re = ESCAPE_NONE;
+
+               FOR_EACH_INSTRUCTION_LIST(e->returns, iti) {
+                       iptr = iti->instr;
+                       es = escape_analysis_get_state(e, instruction_s1(iptr));
+
+                       if (es > re) {
+                               re = es;
+                       }
+               }
+
+               e->jd->m->paramescape[-1] = escape_state_to_u1(re);
+       }
+}
+
+#if defined(ENABLE_REASON)
+void print_escape_reasons() {
+       reason_t *re = THREADOBJECT->escape_reasons;
+
+       fprintf(stderr, "DYN_REASON");
+       
+       for (; re; re = re->next) {
+               fprintf(stderr,":%s", re->why);
+       }
+
+       fprintf(stderr, "\n");
+}
+
+void set_escape_reasons(void *vp) {
+       THREADOBJECT->escape_reasons = vp;
 }
+#endif
 
 static void escape_analysis_display(escape_analysis_t *e) {
        instruction_list_item_t *iti;
@@ -968,13 +1252,26 @@ static void escape_analysis_display(escape_analysis_t *e) {
 
        FOR_EACH_INSTRUCTION_LIST(e->allocations, iti) {
                iptr = iti->instr;
-               ve = var_extra_get(e, instruction_dst(iptr));
+               ve = var_extra_get(e, var_extra_get_representant(e, instruction_dst(iptr)));
+               show_icmd(e->jd, iptr-1, 0, 3);
+               printf("\n");
+               show_icmd(e->jd, iptr, 0, 3);
+               printf("\n");
                printf(
-                       "%s@%d: %s\n", 
+                       "%s@%d: --%s-- %d\n\n", 
                        icmd_table[iptr->opc].name, 
                        iptr->line, 
-                       escape_state_to_string(ve->escape_state)
+                       escape_state_to_string(ve->escape_state),
+                       ve->representant
                );
+#if defined(ENABLE_REASON)
+               {
+                       reason_t *re;
+                       for (re = ve->reasons; re; re = re->next) {
+                               printf("ESCAPE_REASON: %s\n", re->why);
+                       }
+               }
+#endif
        }
 }
 
@@ -983,25 +1280,72 @@ void escape_analysis_perform(jitdata *jd) {
 
        jd->m->flags |= ACC_METHOD_EA;
 
-       /*bc_escape_analysis_perform(jd->m);*/
-
        e = DNEW(escape_analysis_t);
        escape_analysis_init(e, jd);
 
        if (e->verbose) 
-               printf("==== %s/%s ====\n", e->jd->m->clazz->name->text, e->jd->m->name->text);
+               color_printf(RED, "\n\n==== %s/%s ====\n\n", e->jd->m->clazz->name->text, e->jd->m->name->text);
                
-       /*fprintf(stderr, ".");*/
-
        escape_analysis_process_arguments(e);
        escape_analysis_process_instructions(e);
        escape_analysis_post_process_getfields(e);
+       escape_analysis_post_process_returns(e);
+
        escape_analysis_export_arguments(e);
        if (e->verbose) escape_analysis_display(e);
+
+       if (e->verbose) {
+               int i, j, r;
+               for (i = 0; i < jd->vartop; ++i) {
+                       r = var_extra_get_representant(e, i);
+                       if (i == r) {
+                               printf("EES of %d: ", i);
+                               for (j = 0; j < jd->vartop; ++j) {
+                                       if (var_extra_get_representant(e, j) == r) {
+                                               printf("%d, ", j);
+                                       }
+                               }
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+
        escape_analysis_mark_allocations(e);
+       escape_analysis_mark_monitors(e);
 
        jd->m->flags &= ~ACC_METHOD_EA;
 }
 
 void escape_analysis_escape_check(void *vp) {
 }
+
+/*** monomorphic *************************************************************/
+
+bool escape_is_monomorphic(methodinfo *caller, methodinfo *callee) {
+
+       /* Non-speculative case */
+
+       if (callee->flags & (ACC_STATIC | ACC_FINAL | ACC_PRIVATE)) {
+               return true;
+       }
+
+       if (
+               (callee->flags & (ACC_METHOD_MONOMORPHIC | ACC_METHOD_IMPLEMENTED| ACC_ABSTRACT))
+               == (ACC_METHOD_MONOMORPHIC | ACC_METHOD_IMPLEMENTED)
+       ) {
+
+               /* Mark that we have used the information about monomorphy. */
+
+               callee->flags |= ACC_METHOD_MONOMORPHY_USED;
+
+               /* We assume the callee is monomorphic. */
+
+               method_add_assumption_monomorphic(caller, callee);
+
+               return true;
+       }
+
+       return false;
+}
+
index 2f427fa31b6c2faf245a3748704b98485e62e234..bb7cf7bb34081930a20d5a18b10c35dc9be4bf95 100644 (file)
 #define _VM_JIT_OPTIMIZING_ESCAPE_H
 
 #include "vm/jit/jit.h"
-#include "vmcore/method.h"
+#include "vm/method.h"
 
 typedef enum {
        ESCAPE_UNKNOWN,
        ESCAPE_NONE,
        ESCAPE_METHOD,
-       ESCAPE_GLOBAL_THROUGH_METHOD,
+       ESCAPE_METHOD_RETURN,
        ESCAPE_GLOBAL
 } escape_state_t;
 
+static inline escape_state_t escape_state_from_u1(u1 x) {
+       return (escape_state_t)(x & ~0x80);
+}
+
+static inline u1 escape_state_to_u1(escape_state_t x) {
+       return (u1)x;
+}
+
 void escape_analysis_perform(jitdata *jd);
 
 void escape_analysis_escape_check(void *vp);
 
 void bc_escape_analysis_perform(methodinfo *m);
 
+bool escape_is_monomorphic(methodinfo *caller, methodinfo *callee);
+
 #endif
index 9ffe18468e47f1721b733c4f75e9b2ead3d8af2b..99af008421ebd61726cc3b3622e014f402269289 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/graph.c - CFG
 
-   Copyright (C) 2005, 2006 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) 2005, 2006, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Christian Ullrich
-
-   $Id: graph.c$
-
 */
 
 #include <stdlib.h>
@@ -45,7 +37,7 @@
 #include "vm/jit/optimizing/graph.h"
 
 #ifdef GRAPH_DEBUG_VERBOSE
-#include "vmcore/options.h"
+#include "vm/options.h"
 #endif
 
 /* Helpers for graph_make_cfg */
index bfaef14a792812d1e8d9c44f17ce89b2e0deb34e..2decc95532b2ca74cef8801230a06ef1b1480083 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/ifconv/ifconv.c - if-conversion
+/* src/vm/jit/optimizing/ifconv.c - if-conversion
 
-   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.
 
 
 #include "vm/types.h"
 
-#include "vm/vm.h"
+#include "vm/method.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/show.h"
 
-#include "vmcore/method.h"
-
 
 /* patterns for a total number of 3 instructions ******************************/
 
index 3fe01878dc4677519a6cbfdf29b3f998b9968330..f10ced797fbf7b59ad0531288a18b9ef4702a5fa 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/ifconv.h - if-conversion
 
-   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.
 
@@ -35,8 +33,6 @@
 #include "vm/jit/jit.h"
 #include "vm/jit/reg.h"
 
-#include "vmcore/method.h"
-
 
 /* function prototypes ********************************************************/
 
index 54b9732d47b8afed16047b3d453a36a32089a6a5..c7fdb8d4d7495561b8f62364c2bf5e9f90b89d08 100644 (file)
@@ -1,4 +1,4 @@
-/* src/vm/jit/lsra.inc - lifetime anaylsis
+/* src/vm/jit/optimizing/lifetimes.c - lifetime anaylsis
 
    Copyright (C) 2005, 2006, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
@@ -23,6 +23,8 @@
 */
 
 
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -33,8 +35,8 @@
 
 #include "vm/builtin.h"
 #include "vm/resolve.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
+#include "vm/exceptions.hpp"
+#include "vm/string.hpp"
 
 #include "vm/jit/jit.h"
 
@@ -44,7 +46,7 @@
 #include "vm/jit/optimizing/lifetimes.h"
 
 #ifdef LT_DEBUG_VERBOSE
-#include "vmcore/options.h"
+#include "vm/options.h"
 #endif
 
 #include <time.h>
index 3b2006772c6721b117d8feddd03204237f1f91c2..b5a1b62bae86d153dc6c837191b81e1dea7a22ea 100644 (file)
@@ -35,9 +35,9 @@
 
 #include "toolbox/bitvector.h"
 
-#include "vmcore/statistics.h"
-#include "vmcore/options.h"
-#include "vmcore/method.h"
+#include "vm/statistics.h"
+#include "vm/options.h"
+#include "vm/method.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/reg.h"
index 319b2289a7fe41f03d8b9a561b1e641c10740c58..35ad152d909a28132a53ec65df1765c4acf330f0 100644 (file)
 #include "mm/memory.h"
 
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
-#include "vm/stringlocal.h"
+#include "vm/class.h"
+#include "vm/classcache.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/string.hpp"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/methodheader.h"
 
 #include "vm/jit/optimizing/recompile.h"
 
-#include "vmcore/class.h"
-#include "vmcore/classcache.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-
 
 /* profile_init ****************************************************************
 
index a88c1b611a24fcb91cd389e845a7c182416de86d..a235afacd4cab06e0c2df9114bb93255b3575fc5 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/profile.h - runtime profiling
+/* src/vm/jit/optimizing/profile.h - runtime profiling
 
-   Copyright (C) 1996-2005, 2006 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, J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
 */
 
 
 #define _PROFILE_H
 
 #include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/types.h"
 
 #include "vm/global.h"
@@ -49,6 +46,10 @@ bool profile_start_thread(void);
 void profile_printstats(void);
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _PROFILE_H */
 
 
index aa61989136de157bb5bf04a944fa5e4389a78fff..3b302d809d16681c1feeb04ce21bcc93d651ab5b 100644 (file)
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/list.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/options.h"
+#include "vm/string.hpp"
 
 #include "vm/jit/code.h"
 #include "vm/jit/jit.h"
 
 #include "vm/jit/optimizing/recompile.h"
 
-#include "vmcore/classcache.h"
-#include "vmcore/options.h"
-
 
 /* global variables ***********************************************************/
 
index ca71ac98c09b6d53d91942096f873ab27181ec9e..42e53a6ad9679f70b6810957582d3770f61e4423 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/recompile.h - recompilation system
 
-   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, 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.
 
 #define _RECOMPILE_H
 
 #include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "vm/types.h"
 
 #include "vm/global.h"
@@ -51,7 +54,11 @@ bool recompile_start_thread(void);
 
 void recompile_queue_method(methodinfo *m);
 
-#endif /* _PROFILE_H */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RECOMPILE_H */
 
 
 /*
index 721323e4bb0df7409dca7d2981c95c6da8c458c1..258fbf9f401a084d3deb0f64023a34c1378603aa 100644 (file)
@@ -51,7 +51,7 @@
 #include "vm/jit/python.h"
 
 #if defined(SSA_DEBUG_VERBOSE)
-#include "vmcore/options.h"   /* compileverbose */
+#include "vm/options.h"   /* compileverbose */
 #endif
 
 /* function prototypes */
@@ -133,6 +133,7 @@ void ssa(jitdata *jd) {
                yssa(jd);
        }
        /*pythonpass_run(jd, "foo", "after");*/
+       cfg_remove_root(jd);
        return;
 
        ls = jd->ls;
index 0f8c1306dcb754a625a7291c8dda1c008fb1b983..6dd7441ca78a4c0bf5379c4bc357fc22e8b350a1 100644 (file)
@@ -1,4 +1,4 @@
-/* src/vm/optimizing/ssa3.c
+/* src/vm/jit/optimizing/ssa3.c
 
    Copyright (C) 2008
    CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
 #include <limits.h>
 #include <stdio.h>
 
-#define ELIMINATE_NOP_LOAD_STORE
+/*#define ELIMINATE_NOP_LOAD_STORE*/
 #define FIXME(x) x
 #define SSA_VERIFY
-/* #define SSA_VERBOSE */
+/*#define SSA_VERBOSE */
 
 /*
 __attribute__((always_inline))
@@ -345,8 +345,8 @@ static inline void instruction_set_uses(instruction *iptr, s4 *buf, s4 *uses, un
 
 /*** vars *******************************************************************/
 
-#define VARS_CATEGORY_SHIFT 29
-#define VARS_INDEX_MASK 0x1FFFFFFF
+#define VARS_CATEGORY_SHIFT 28
+#define VARS_INDEX_MASK 0x0FFFFFFF
 
 #define VARS_CATEGORY_LOCAL 0
 #define VARS_CATEGORY_STACK 1
@@ -354,8 +354,15 @@ static inline void instruction_set_uses(instruction *iptr, s4 *buf, s4 *uses, un
 
 #define VAR_TYPE_SUBSTITUED 666
 
+#define OLD_INDEX_UNUSED -2
+
+typedef struct {
+       varinfo v;
+       s4 old_index;
+} vars_item_t;
+
 typedef struct {
-       varinfo items[9000]; /* XXX hardcoded max */
+       vars_item_t items[9000]; /* XXX hardcoded max */
        unsigned max;
        unsigned count;
        unsigned category;
@@ -365,7 +372,8 @@ static inline unsigned vars_add_item(vars_t *vs, const varinfo *item) {
        unsigned i = vs->count;
        assert(i < vs->max);
        vs->count += 1;
-       vs->items[i] = *item;
+       vs->items[i].v = *item;
+       vs->items[i].old_index = OLD_INDEX_UNUSED;
        return (vs->category << VARS_CATEGORY_SHIFT) | i;
 }
 
@@ -378,7 +386,7 @@ static inline unsigned vars_add(vars_t *vs) {
 
 static inline varinfo *vars_back(vars_t *vs) {
        assert(vs->count > 0);
-       return vs->items + (vs->count - 1);
+       return &(vs->items[vs->count - 1].v);
 }
 
 static inline void vars_init(vars_t *vs, unsigned category) {
@@ -400,8 +408,8 @@ static void vars_subst(vars_t *vs, unsigned varindex, unsigned replacementindex)
        varindex = vars_get_index(varindex);
        replacementindex = vars_get_index(replacementindex);
 
-       vs->items[varindex].type = VAR_TYPE_SUBSTITUED;
-       vs->items[varindex].vv.regoff = replacementindex;
+       vs->items[varindex].v.type = VAR_TYPE_SUBSTITUED;
+       vs->items[varindex].v.vv.ii[1] = replacementindex;
 }
 
 static unsigned vars_resolve_subst(const vars_t *vs, unsigned varindex) {
@@ -410,36 +418,80 @@ static unsigned vars_resolve_subst(const vars_t *vs, unsigned varindex) {
 #endif
        varindex = vars_get_index(varindex);
 
-       if (vs->items[varindex].type == VAR_TYPE_SUBSTITUED) /*fprintf(stderr, "*")*/;
+       if (vs->items[varindex].v.type == VAR_TYPE_SUBSTITUED) /*fprintf(stderr, "*")*/;
 
-       while (vs->items[varindex].type == VAR_TYPE_SUBSTITUED) {
+       while (vs->items[varindex].v.type == VAR_TYPE_SUBSTITUED) {
                assert(loop_ctr++ != vs->count);
-               varindex = vs->items[varindex].vv.regoff;
+               varindex = vs->items[varindex].v.vv.ii[1];
        }
 
        return (vs->category << VARS_CATEGORY_SHIFT) | varindex ;
 }
 
 static void vars_copy_to_final(vars_t *vs, varinfo *dst) {
-       const varinfo *it;
+       const vars_item_t *it;
        unsigned subst;
 
        for (it = vs->items; it != vs->items + vs->count; ++it, ++dst) {
 
                /* Copy variable. */
 
-               *dst = *it;
+               *dst = it->v;
 
                /* Eliminate VAR_TYPE_SUBSTITUED as it leads to problems. */
 
                if (dst->type == VAR_TYPE_SUBSTITUED) {
                        subst = vars_get_index(vars_resolve_subst(vs, it - vs->items));
-                       dst->type = vs->items[subst].type;
+                       dst->type = vs->items[subst].v.type;
 
                }
        }
 }
 
+static void vars_import(vars_t *vs, varinfo *v, unsigned count, s4 old_index) {
+       vars_item_t *it;
+
+       assert((vs->count + count) <= vs->max);
+
+       it = vs->items + vs->count;
+       vs->count += count;
+
+       while (count-- > 0) {
+               it->v = *v;
+               it->old_index = old_index;
+               it += 1;
+               v += 1;
+               old_index += 1;
+       }
+}
+
+static inline void vars_record_old_index(vars_t *vs, unsigned varindex, s4 old_index) {
+       vars_item_t *item;
+       varindex = vars_get_index(varindex);
+
+       assert(varindex < vs->count);
+
+       item = vs->items + varindex;
+
+       assert(
+               item->old_index == OLD_INDEX_UNUSED || 
+               item->old_index == old_index
+       );
+
+       item->old_index = old_index;
+}
+
+static inline s4 vars_get_old_index(vars_t *vs, unsigned varindex) {
+       s4 old;
+
+       varindex = vars_get_index(varindex);
+
+       assert(varindex < vs->count);
+       old = vs->items[varindex].old_index;
+       assert(old != OLD_INDEX_UNUSED);
+
+       return old;
+}
 
 /*** phis *******************************************************************/
 
@@ -486,13 +538,15 @@ FIXME() inline void phis_print(const phis_t *ps) {
 }
 #endif
 
-static inline void phis_copy_to(const phis_t *ps, instruction *dst) {
-       MCOPY(
-               dst,
-               ps->items,
-               instruction,
-               ps->count
-       );
+static inline unsigned phis_copy_to(const phis_t *ps, instruction *dst) {
+       instruction *it;
+       instruction *out = dst;
+
+       FOR_EACH_PHI_FUNCTION(ps, it) {
+               *(out++) = *it;
+       }
+
+       return (out - dst);
 }
 
 /*** state_array ************************************************************/
@@ -680,31 +734,41 @@ instruction *traversal_create_phi(traversal_t *t, vars_t *v, unsigned argcount,
 
        state_array_set(t->state_array, index, phi);
 
+       vars_record_old_index(v, phi->dst.varindex, index);
+
        return phi;
 }
 
 static void traversal_rename_def(traversal_t *t, vars_t *vars, instruction *iptr) {
        const varinfo *v;
        unsigned index;
+       s4 old;
 
        state_array_assert_items(t->state_array);
 
        v = t->ops->var_num_to_varinfo(t->ops_vp, iptr->dst.varindex);
        index = t->ops->var_num_to_index(t->ops_vp, iptr->dst.varindex);
 
+       old = iptr->dst.varindex;
        iptr->dst.varindex = vars_add_item(vars, v);
        state_array_set(t->state_array, index, iptr);
+
+       vars_record_old_index(vars, iptr->dst.varindex, index);
 }
 
-static void traversal_rename_use(traversal_t *t, s4 *puse) {
+static void traversal_rename_use(traversal_t *t, vars_t *vars, s4 *puse) {
        unsigned index;
+       s4 old;
 
        state_array_assert_items(t->state_array);
 
        index = t->ops->var_num_to_index(t->ops_vp, *puse);
 
        assert(state_array_get(t->state_array, index));
+       old = *puse;
        *puse = state_array_get_var(t->state_array, index);
+
+       vars_record_old_index(vars, *puse, index);
 }
 
 static inline unsigned traversal_variables_count(traversal_t *t) {
@@ -862,6 +926,18 @@ typedef struct ssa_info {
 
        basicblock_chain_t *new_blocks;
 
+       struct {
+               s4 maxlocals;
+               s4 maxinterfaces;
+               s4 *local_map;
+               varinfo *var;
+               s4 vartop;
+               s4 varcount;
+               s4 localcount;
+       } original;
+
+       unsigned keep_in_out:1;
+
 } ssa_info, ssa_info_t;
 
 void ssa_info_init(ssa_info_t *ssa, jitdata *jd) {
@@ -871,8 +947,7 @@ void ssa_info_init(ssa_info_t *ssa, jitdata *jd) {
        vars_init(ssa->locals, VARS_CATEGORY_LOCAL);
 
        /* Initialize first version of locals, that is always available. */
-       MCOPY(ssa->locals->items, jd->var, varinfo, jd->localcount);
-       ssa->locals->count = jd->localcount;
+       vars_import(ssa->locals, jd->var, jd->localcount, 0);
 
        ssa->stack = DNEW(vars_t);
        vars_init(ssa->stack, VARS_CATEGORY_STACK);
@@ -882,16 +957,26 @@ void ssa_info_init(ssa_info_t *ssa, jitdata *jd) {
 
        ssa->new_blocks = DNEW(basicblock_chain_t);
        basicblock_chain_init(ssa->new_blocks);
+
+       ssa->original.maxlocals = jd->maxlocals;
+       ssa->original.maxinterfaces = jd->maxinterfaces;
+       ssa->original.local_map = jd->local_map;
+       ssa->original.var = jd->var;
+       ssa->original.vartop = jd->vartop;
+       ssa->original.varcount = jd->varcount;
+       ssa->original.localcount = jd->localcount;
+
+       ssa->keep_in_out = false;
 }
 
 /*** others_mapping *********************************************************/
 
 static inline void others_mapping_set(ssa_info *ssa, s4 var, s4 new_var) {
-       ssa->jd->var[var].vv.regoff = new_var;
+       ssa->jd->var[var].vv.ii[1] = new_var;
 }
 
 static inline s4 others_mapping_get(const ssa_info *ssa, s4 var) {
-       return ssa->jd->var[var].vv.regoff;
+       return ssa->jd->var[var].vv.ii[1];
 }
 
 /*** code *******************************************************************/
@@ -907,6 +992,8 @@ void fix_exception_handlers(jitdata *jd) {
        basicblock_chain_t chain;
        basicblock *last = NULL;
        basicblock *marker = NULL;
+       s4 vartop;
+       unsigned i;
 
        if (jd->exceptiontablelength == 0) {
                return;
@@ -914,22 +1001,38 @@ void fix_exception_handlers(jitdata *jd) {
 
        basicblock_chain_init(&chain);
 
-       /* We need to allocate new iovars */
+       /* Remember, where we started adding IO variables. */
 
-       avail_vars = (jd->varcount - jd->vartop);
-       add_vars = jd->exceptiontablelength;
-
-       if (add_vars > avail_vars) {
-               add_vars -= avail_vars;
-               jd->var = DMREALLOC(jd->var, varinfo, jd->varcount, jd->varcount + add_vars);
-               jd->varcount += add_vars;
-       }
+       vartop = jd->vartop;
 
        /* For each exception handler block, create one block with a prologue block */
 
        FOR_EACH_BASICBLOCK(jd, bptr) {
                if (bptr->type == BBTYPE_EXH) {
 
+                       /*
+             
+            +---- EXH (exh)-------+
+            |  in0 in1 in2 exc    |
+                       |  .....              |
+            +---------------------+
+
+            === TRANSFORMED TO ===>
+
+            +---- PROL (exh) -------+
+            |  in0 in1 in2          |
+            |  GETEXECEPTION => OU3 |
+            |  GOTO REAL_EXH        |
+            |  in0 in1 in2 OU3      |
+            +-----------------------+
+
+            +---- REAL_EXH (std) -+
+            |  in0 in1 in2 exc    |
+                       |  ......             |
+            +---------------------+
+
+                       */
+
                        bptr->type = BBTYPE_STD;
                        bptr->predecessorcount = 0; /* legacy */
 
@@ -940,7 +1043,24 @@ void fix_exception_handlers(jitdata *jd) {
 
                        iptr = DMNEW(instruction, 2);
                        MZERO(iptr, instruction, 2);
+                       
+                       /* Create outvars */
+
+                       exh->outdepth = bptr->indepth;
+
+                       if (exh->outdepth > 0) {
+                               exh->outvars = DMNEW(s4, exh->outdepth);
+                               for (i = 0; i < exh->outdepth; ++i) {
+                                       exh->outvars[i] = vartop++;
+                               }
+                       }
+
+                       /* Create invars */
 
+                       exh->indepth = exh->outdepth - 1;
+                       exh->invars = exh->outvars;
+
+#if 0
                        /* Create new outvar */
 
                        assert(jd->vartop < jd->varcount);
@@ -948,6 +1068,7 @@ void fix_exception_handlers(jitdata *jd) {
                        jd->vartop += 1;
                        jd->var[v].type = TYPE_ADR;
                        jd->var[v].flags = INOUT;
+#endif
 
                        exh->nr = jd->basicblockcount;
                        jd->basicblockcount += 1;
@@ -955,9 +1076,11 @@ void fix_exception_handlers(jitdata *jd) {
                        exh->type = BBTYPE_EXH;
                        exh->icount = 2;
                        exh->iinstr = iptr;
+/*
                        exh->outdepth = 1;
                        exh->outvars = DNEW(s4);
                        exh->outvars[0] = v;
+*/
                        exh->predecessorcount = -1; /* legacy */
                        exh->flags = BBFINISHED;
                        exh->method = jd->m;
@@ -967,7 +1090,7 @@ void fix_exception_handlers(jitdata *jd) {
                        /* Get exception */
 
                        iptr->opc = ICMD_GETEXCEPTION;
-                       iptr->dst.varindex = v;
+                       iptr->dst.varindex = exh->outvars[exh->outdepth - 1];
                        iptr += 1;
 
                        /* Goto real exception handler */
@@ -986,6 +1109,19 @@ void fix_exception_handlers(jitdata *jd) {
                }
        }
 
+       /* We need to allocate the new iovars in the var array */
+
+       avail_vars = (jd->varcount - jd->vartop);
+       add_vars = (vartop - jd->vartop);
+
+       if (add_vars > avail_vars) {
+               add_vars -= avail_vars;
+               jd->var = DMREALLOC(jd->var, varinfo, jd->varcount, jd->varcount + add_vars);
+               jd->varcount += add_vars;
+       }
+
+       jd->vartop = vartop;
+
        /* Put the chain of exception handlers between just before the last
           basic block (end marker). */
 
@@ -1003,9 +1139,68 @@ void fix_exception_handlers(jitdata *jd) {
 
        for (ee = jd->exceptiontable; ee; ee = ee->down) {
                assert(ee->handler->vp);
-               ee->handler = ee->handler->vp;
+
+               bptr = ee->handler;
+               exh = (basicblock *)ee->handler->vp;
+
+               ee->handler = exh;
+
+               /* Set up IO variables in newly craeted exception handlers. */
+
+               for (i = 0; i < exh->outdepth; ++i) {
+                       v = exh->outvars[i];
+
+                       jd->var[v].flags = INOUT;
+                       jd->var[v].type = jd->var[ bptr->invars[i] ].type;
+               }
+       }
+
+}
+
+void unfix_exception_handlers(jitdata *jd) {
+       basicblock *bptr, *exh;
+       unsigned i;
+       exception_entry *ee;
+#if !defined(NDEBUG)
+       bool found = false;
+#endif
+
+       FOR_EACH_BASICBLOCK(jd, bptr) {
+               if (bptr->type == BBTYPE_EXH) {
+                       assert(bptr->iinstr[1].opc == ICMD_GOTO);
+                       exh = bptr->iinstr[1].dst.block;
+
+                       bptr->type = BBDELETED;
+                       bptr->icount = 0;
+                       bptr->indepth = 0;
+                       bptr->outdepth = 0;
+                       exh->type = BBTYPE_EXH;
+                       bptr->vp = exh;
+               
+                       /* bptr is no more a predecessor of exh */
+
+                       for (i = 0; i < exh->predecessorcount; ++i) {
+                               if (exh->predecessors[i] == bptr) {
+                                       exh->predecessors[i] = exh->predecessors[exh->predecessorcount - 1];
+                                       exh->predecessorcount -= 1;
+#if !defined(NDEBUG)
+                                       found = true;
+#endif
+                                       break;
+                               }
+                       }
+
+                       assert(found);
+
+               } else {
+                       bptr->vp = NULL;
+               }
        }
 
+       for (ee = jd->exceptiontable; ee; ee = ee->down) {
+               assert(ee->handler->vp);
+               ee->handler = ee->handler->vp;
+       }
 }
 
 /*** ssa_enter ***************************************************************/
@@ -1119,6 +1314,10 @@ static void ssa_enter_verify_no_redundant_phis(ssa_info_t *ssa) {
        basicblock *bptr;
        basicblock_info_t *bbi;
        instruction *itph;
+
+       /* XXX */
+       return;
+
        FOR_EACH_BASICBLOCK(ssa->jd, bptr) {
                if (basicblock_reached(bptr)) {
                        bbi = bb_info(bptr);
@@ -1241,6 +1440,14 @@ static void ssa_enter_process_pei(ssa_info *ssa, basicblock *bb, unsigned pei) {
                        basicblock_get_ex_predecessor_index(bb, pei, *itsucc),
                        ssa->locals
                );
+
+               ssa_enter_merge(
+                       bbi->stack,
+                       succi->stack,
+                       *itsucc,
+                       basicblock_get_ex_predecessor_index(bb, pei, *itsucc),
+                       ssa->stack
+               );
        }
 }
 
@@ -1249,6 +1456,9 @@ static FIXME(bool) ssa_enter_eliminate_redundant_phis(traversal_t *t, vars_t *vs
        instruction *itph;
        bool ret = false;
 
+       /* XXX */
+       return;
+
        FOR_EACH_PHI_FUNCTION(t->phis, itph) {
 
                phi_calculate_redundancy(itph);
@@ -1346,23 +1556,33 @@ static void ssa_enter_process_block(ssa_info *ssa, basicblock *bb) {
                state_array_allocate_items(bbi->stack->state_array);
        }
 
+#if 0
        /* Exception handlers have a clean stack. */
 
+       /* Not true with inlining. */
+
        if (bb->type == BBTYPE_EXH) {
                state_array_assert_no_items(bbi->stack->state_array);
                state_array_allocate_items(bbi->stack->state_array);
        }
+#endif
 
        /* Some in/out vars get marked as INOUT in simplereg,
           and are not marked at this point. 
           Mark them manually. */
 
        for (ituse = bb->invars; ituse != bb->invars + bb->indepth; ++ituse) {
+               if (ssa->keep_in_out && ssa->jd->var[*ituse].type == TYPE_RET) {
+                       continue;
+               }
                ssa->jd->var[*ituse].flags |= INOUT;
                ssa->jd->var[*ituse].flags &= ~PREALLOC;
        }
 
        for (ituse = bb->outvars; ituse != bb->outvars + bb->outdepth; ++ituse) {
+               if (ssa->keep_in_out && ssa->jd->var[*ituse].type == TYPE_RET) {
+                       continue;
+               }
                ssa->jd->var[*ituse].flags |= INOUT;
                ssa->jd->var[*ituse].flags &= ~PREALLOC;
        }
@@ -1404,11 +1624,13 @@ static void ssa_enter_process_block(ssa_info *ssa, basicblock *bb) {
                        if (var_is_local(ssa->jd, *ituse)) {
                                traversal_rename_use(
                                        bbi->locals, 
+                                       ssa->locals,
                                        ituse
                                );
                        } else if (var_is_inout(ssa->jd, *ituse)) {
                                traversal_rename_use(
                                        bbi->stack,
+                                       ssa->stack,
                                        ituse
                                );
                        } else {
@@ -1437,6 +1659,7 @@ static void ssa_enter_process_block(ssa_info *ssa, basicblock *bb) {
                                        ssa->others,
                                        ssa->jd->var + iptr->dst.varindex
                                );
+                               vars_record_old_index(ssa->others, iptr->dst.varindex, old);
                                others_mapping_set(ssa, old, iptr->dst.varindex);
                        }
                }
@@ -1456,6 +1679,7 @@ static void ssa_enter_export_variables(ssa_info *ssa) {
        s4 *it;
        unsigned i, j;
        jitdata *jd = ssa->jd;
+       s4 *local_map;
 
        vartop = ssa->locals->count + ssa->stack->count + ssa->others->count;
        vars = DMNEW(varinfo, vartop);
@@ -1470,13 +1694,15 @@ static void ssa_enter_export_variables(ssa_info *ssa) {
        /* Grow local map to accomodate all new locals and iovars.
           But keep the local map for version 1 of locals, that contains the holes. */
        
-       jd->local_map = DMREALLOC(
-               jd->local_map, 
-               s4, 
-               5 * jd->maxlocals, 
+       local_map = DMNEW(
+               s4,
                5 * (jd->maxlocals + ssa->locals->count + ssa->stack->count - jd->localcount)
        );
 
+       MCOPY(local_map, jd->local_map, s4, 5 * jd->maxlocals);
+
+       jd->local_map = local_map;
+
        it = jd->local_map + (jd->maxlocals * 5); /* start adding entries here */
 
        /* Add version > 1 of all locals */
@@ -1524,19 +1750,15 @@ static void ssa_enter_export_phis(ssa_info_t *ssa) {
        FOR_EACH_BASICBLOCK(ssa->jd, bptr) {
                bbi = bb_info(bptr);
                if (bbi != NULL) {
-                       bptr->phicount = 
-                               bbi->locals->phis->count + 
-                               bbi->stack->phis->count;
-
-                       bptr->phis = DMNEW(instruction, bptr->phicount);
+                       bptr->phis = DMNEW(instruction, bbi->locals->phis->count + bbi->stack->phis->count);
 
                        dst = bptr->phis;
 
-                       phis_copy_to(bbi->locals->phis, dst);
+                       dst += phis_copy_to(bbi->locals->phis, dst);
 
-                       dst += bbi->locals->phis->count;
+                       dst += phis_copy_to(bbi->stack->phis, dst);
 
-                       phis_copy_to(bbi->stack->phis, dst);
+                       bptr->phicount = dst - bptr->phis;
                }
        }
 }
@@ -1569,8 +1791,10 @@ void ssa_enter_eliminate_categories(ssa_info_t *ssa) {
 
                bbi = bb_info(bb);
 
-               bb->indepth = 0;
-               bb->outdepth = 0;
+               if (! ssa->keep_in_out) {
+                       bb->indepth = 0;
+                       bb->outdepth = 0;
+               }
 
                if (bbi != NULL) {
                        FOR_EACH_PHI_FUNCTION(bbi->locals->phis, itph) {
@@ -2055,20 +2279,115 @@ static void ssa_leave_create_exceptional_phi_moves(ssa_info *ssa) {
        }
 }
 
+void ssa_simple_leave_restore(ssa_info_t *ssa, basicblock *bptr, s4 *pvar) {
+       s4 var = *pvar;
+       s4 index;
+       basicblock_info_t *bbi;
+
+       if (var < ssa->locals->count) {
+               *pvar = vars_get_old_index(ssa->locals, var);
+       } else if (var < ssa->locals->count + ssa->stack->count) {
+
+               index = vars_get_old_index(
+                       ssa->stack,
+                       var - ssa->locals->count
+               );
+
+               bbi = bb_info(bptr);
+
+               /* We have to determine whether to take an invar or an outvar for
+                  the stack depth ``index''.
+                  The state array contains the last definition of the stack element
+                  at the given depth.
+               */
+
+               if (state_array_get_var(bbi->stack->state_array, index) == var) {
+                       /* The last definition of a stack depth inside the basicblock.
+                          This is the outvar at the given depth.
+                          If there is no outvar at the given depth, it must be an invar.
+                       */
+                       if (index < bptr->outdepth) {
+                               *pvar = bptr->outvars[index];
+                       } else if (index < bptr->indepth) {
+                               *pvar = bptr->invars[index];
+                       } else {
+                               assert(0);
+                       }
+               } else {
+                       /* A different than the last definition of a stack depth.
+                          This must be an invar.
+                       */
+                       assert(index < bptr->indepth);
+                       *pvar = bptr->invars[index];
+               }
+       } else {
+               *pvar = vars_get_old_index(
+                       ssa->others,
+                       var - ssa->locals->count - ssa->stack->count
+               );
+       }
+}
+
+void ssa_simple_leave(ssa_info_t *ssa) {
+       basicblock *bptr;
+       instruction *iptr;
+       s4 *ituse, *uses;
+       unsigned uses_count;
+
+       FOR_EACH_BASICBLOCK(ssa->jd, bptr) {
+               if (bptr->type == BBTYPE_EXH) {
+                       /* (Aritifical) exception handler blocks will be eliminated. */
+                       continue;
+               }
+               /* In reverse order. We need to rename the definition after any use! */
+               FOR_EACH_INSTRUCTION_REV(bptr, iptr) {
+                       if (instruction_has_dst(iptr)) {
+                               ssa_simple_leave_restore(ssa, bptr, &(iptr->dst.varindex));
+                       }
+                       instruction_get_uses(iptr, ssa->s_buf, &uses, &uses_count);
+                       for (ituse = uses; ituse != uses + uses_count; ++ituse) {
+                               ssa_simple_leave_restore(ssa, bptr, ituse);
+                       }
+                       instruction_set_uses(iptr, ssa->s_buf, uses, uses_count);
+               }
+               bptr->phicount = 0;
+       }
+
+       unfix_exception_handlers(ssa->jd);
+
+       ssa->jd->maxlocals = ssa->original.maxlocals;
+       ssa->jd->maxinterfaces = ssa->original.maxinterfaces;
+       ssa->jd->local_map =ssa->original.local_map;
+       ssa->jd->var = ssa->original.var;
+       ssa->jd->vartop = ssa->original.vartop;
+       ssa->jd->varcount = ssa->original.varcount;
+       ssa->jd->localcount = ssa->original.localcount;
+}
+
+#include "vm/rt-timing.h"
+
 void yssa(jitdata *jd) {
        basicblock *it;
        basicblock_info_t *iti;
        ssa_info *ssa;
 
+       struct timespec bs, es, be, ee;
+
+       RT_TIMING_GET_TIME(bs);
+
 #ifdef SSA_VERBOSE
-       printf("=============== [ before %s ] =========================\n", jd->m->name->text);
-       show_method(jd, 3);
-       printf("=============== [ /before ] =========================\n");
+       bool verb = true;
+       if (verb) {
+               printf("=============== [ before %s ] =========================\n", jd->m->name->text);
+               show_method(jd, 3);
+               printf("=============== [ /before ] =========================\n");
+       }
 #endif
 
        ssa = DNEW(ssa_info);
 
        ssa_info_init(ssa, jd);
+       ssa->keep_in_out = true;
 
        FOR_EACH_BASICBLOCK(jd, it) {
                if (basicblock_reached(it)) {
@@ -2094,18 +2413,38 @@ void yssa(jitdata *jd) {
 
        /*ssa_enter_create_phi_graph(ssa);*/
 
+       RT_TIMING_GET_TIME(be);
        escape_analysis_perform(ssa->jd);
+       RT_TIMING_GET_TIME(ee);
 
+       /*
        ssa_leave_create_phi_moves(ssa);
 
        ssa_leave_create_exceptional_phi_moves(ssa);
+       */
+       
+#ifdef SSA_VERBOSE
+       if (verb) {
+               printf("=============== [ mid ] =========================\n");
+               show_method(jd, 3);
+               printf("=============== [ /mid ] =========================\n");
+       }
+#endif
+
+       ssa_simple_leave(ssa);
 
 #ifdef SSA_VERBOSE
-       printf("=============== [ after ] =========================\n");
-       show_method(jd, 3);
-       printf("=============== [ /after ] =========================\n");
+       if (verb) {
+               printf("=============== [ after ] =========================\n");
+               show_method(jd, 3);
+               printf("=============== [ /after ] =========================\n");
+       }
 #endif
 
+       RT_TIMING_GET_TIME(es);
+
+       RT_TIMING_TIME_DIFF(bs, es, RT_TIMING_1);
+       RT_TIMING_TIME_DIFF(be, ee, RT_TIMING_2);
 }
 
 void eliminate_subbasicblocks(jitdata *jd) {
index 9ab4f6c29a34f2f1ccfc96f58a3765f1cc0b3722..40e04fd6681241d1083c3ef437b11986f6339783 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/ssa.c - static single-assignment form
 
-   Copyright (C) 2005 - 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) 2005-2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Christian Ullrich
+*/
 
-   $Id: $
 
-*/
+#include "config.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -50,7 +45,7 @@
 #include "vm/jit/optimizing/ssa_phi.h"
 
 #if defined(SSA_DEBUG_VERBOSE)
-#include "vmcore/options.h"   /* compileverbose */
+#include "vm/options.h"   /* compileverbose */
 #endif
 
 /* ssa_place_phi_functions *****************************************************
index 474419c1235240a7171260a217e5dab27a18f23d..b299fab262847d29ba1d6f19464af0803e2d95c2 100644 (file)
@@ -45,7 +45,7 @@
 #include "vm/jit/optimizing/ssa_rename.h"
 
 #if defined(SSA_DEBUG_VERBOSE)
-#include "vmcore/options.h"   /* compileverbose */
+#include "vm/options.h"   /* compileverbose */
 #endif
 
 /* function prototypes */
index 6b99040fbb0b3c880db694b9dedbd9b56d62cb78..c693d6ec58a50143b89cbaec325ce3ea75fae24c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/parisc/arch.h - architecture defines for PA-RISC
 
-   Copyright (C) 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) 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -95,8 +93,6 @@
 #endif
 
 
-#define USE_FAKE_ATOMIC_INSTRUCTIONS     1
-
 /* replacement ****************************************************************/
 
 #define REPLACEMENT_PATCH_SIZE           4  /* bytes */
index db707e71421de82ebc346a81d4d77ef221a5fad6..f85b999d2b1f11c2705ba4f7dc91c697608a3e6d 100644 (file)
 #include "toolbox/logging.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/stringlocal.h"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/string.hpp"
+#include "vm/suck.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 
 #include "vm/jit/ir/bytecode.h"
 
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vm/resolve.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#include "vmcore/suck.h"
 
 #define INSTRUCTIONS_INCREMENT  5  /* number of additional instructions to    */
                                    /* allocate if space runs out              */
index dee3d3de592714dc863fe3a2d66db4a9dde01a56..4128205c4036be8a3f7cdb14293172523f303d8b 100644 (file)
 #include "toolbox/list.h"
 #include "toolbox/logging.h"           /* XXX remove me! */
 
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/initialize.h"
+#include "vm/options.h"
 #include "vm/resolve.h"
-#include "vm/vm.h"                     /* for vm_abort */
+#include "vm/vm.hpp"                     /* for vm_abort */
 
 #include "vm/jit/code.h"
 #include "vm/jit/disass.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 
-#include "vmcore/options.h"
-
 
 /* patcher_function_list *******************************************************
 
@@ -175,8 +174,7 @@ static patchref_t *patcher_list_find(codeinfo *code, u1 *pc)
 
 *******************************************************************************/
 
-void patcher_add_patch_ref(jitdata *jd, functionptr patcher, voidptr ref,
-                           s4 disp)
+void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
 {
        codegendata *cd;
        codeinfo    *code;
index f4cf9a50745fa90ea1fba843596488f836d1ee15..994599a7826706d082cb6d168170350b4492492f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/patcher-common.h - architecture independent code patching stuff
 
-   Copyright (C) 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) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -55,7 +53,7 @@ typedef struct patchref_t {
        ptrint       datap;         /* absolute position in data segment          */
        s4           disp;          /* displacement of ref in the data segment    */
        functionptr  patcher;       /* patcher function to call                   */
-       voidptr      ref;           /* reference passed                           */
+       void*        ref;           /* reference passed                           */
        u8           mcode;         /* machine code to be patched back in         */
        bool         done;          /* XXX preliminary: patch already applied?    */
 #if defined (ENABLE_JITCACHE)
@@ -76,8 +74,7 @@ void patcher_list_create(codeinfo *code);
 void patcher_list_reset(codeinfo *code);
 void patcher_list_free(codeinfo *code);
 
-void patcher_add_patch_ref(jitdata *jd, functionptr patcher, voidptr ref,
-                           s4 disp);
+void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp);
 
 void patcher_resolve(jitdata* jd);
 
index d8e59bfa4957cc271a752439dc3524ccbcbc22a1..448fdde343784cb376dd1b4d2ff457bae82b7679 100644 (file)
@@ -35,7 +35,7 @@ LIBS =
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = \
        libarch.la
index 3413a354f16384a5bb3df4b84558db4a4aa7543d..cae9439fa6471ab1170a558a1c176a946e9f57bc 100644 (file)
@@ -57,9 +57,6 @@
 
        .globl asm_cacheflush
 
-       .globl asm_compare_and_swap
-       .globl asm_memory_barrier
-
 
 /* asm_vm_call_method **********************************************************
 *                                                                              *
@@ -463,36 +460,6 @@ asm_cacheflush:
        blr
 
 
-/* asm_compare_and_swap ********************************************************
-
-   XXX
-
-*******************************************************************************/
-
-asm_compare_and_swap:
-1:
-       lwarx   a6,0,a0 
-       subf.   r0,a6,a1 
-       bne-    2f 
-       or      r0,a2,a2 
-       stwcx.  r0,0,a0 
-       bne-    1b 
-2: 
-       mr      a0,a6
-       blr
-
-
-/* asm_memory_barrier **********************************************************
-
-   XXX
-
-*******************************************************************************/
-
-asm_memory_barrier:
-       sync
-       blr
-
-
 #if defined(__DARWIN__)
 
 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
index 378a7279e180dbdd2ebf1dcc2dcb4894680a22dc..f8d36f10cd03a0181785ebd35e650a6dd9c62bf7 100644 (file)
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 
 /* codegen *********************************************************************
 
@@ -2439,9 +2437,6 @@ gen_method:
                                        superindex = super->index;
                                }
 
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -2514,16 +2509,12 @@ gen_method:
 
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                        M_ALD(REG_ITMP2, REG_PV, disp);
                                        if (s1 != REG_ITMP1) {
                                                M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                                               CODEGEN_CRITICAL_SECTION_END;
-
                                                M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
                                        }
                                        else {
@@ -2531,8 +2522,6 @@ gen_method:
                                                M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
                                                M_ALD(REG_ITMP2, REG_PV, disp);
                                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
-
-                                               CODEGEN_CRITICAL_SECTION_END;
                                        }
                                        M_CMPU(REG_ITMP3, REG_ITMP2);
                                        emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1);
@@ -2594,9 +2583,6 @@ gen_method:
                                superindex = super->index;
                        }
                        
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
@@ -2675,14 +2661,10 @@ gen_method:
                                M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_ITMP2, REG_PV, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
                                M_CMPU(REG_ITMP1, REG_ITMP2);
                                M_CLR(d);
@@ -2985,7 +2967,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument register */
 
-               disp = dseg_add_address(cd, _Jv_env);
+               disp = dseg_add_address(cd, VM_get_jnienv());
                M_ALD(REG_A0, REG_PV, disp);
        }
 
index 783991af9aab3f00461445f2daca116524c2abe7..68899b4eed91f0bd048674cd78691b49a7cbb961 100644 (file)
 
 #include "vm/jit/powerpc/darwin/md-abi.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/stack.h"
 
-#include "vmcore/descriptor.h"
-
 
 /* register descripton arrays *************************************************/
 
index 44b0f73d81afcd986dd97a9e6ec9ba96ae051287..1f026257b055ac7161263a768bb9dd0f4039b6ca 100644 (file)
 #include "vm/jit/powerpc/codegen.h"
 #include "vm/jit/powerpc/darwin/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/stacktrace.h"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -251,34 +248,6 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       mcontext_t          _mc;
-       ppc_thread_state_t *_ss;
-       u1                 *pc;
-       u1                 *npc;
-
-       _mc = _uc->uc_mcontext;
-       _ss = &_mc->ss;
-
-       pc = (u1 *) _ss->srr0;
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL)
-               _ss->srr0 = (ptrint) npc;
-}
-#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
index 65927bb8a8260ff856c2d51345e403f4cda7d747..17cb85c1ae77355ad7e1d6743c8dd8bbf73b04ca 100644 (file)
@@ -38,7 +38,7 @@
 
 #include "threads/lock-common.h"
 
-#include "vm/exceptions.h"
+#include "vm/options.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
-#include "vmcore/options.h"
-
 
 /* emit_load *******************************************************************
 
index af175d4cac72d7a5fe22a199779de0200101537b..df5af31dbfbdf1d354915418c61458a22a099666 100644 (file)
 
 #include "vm/jit/powerpc/linux/md-abi.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/stack.h"
 
-#include "vmcore/descriptor.h"
-
 
 /* register descripton arrays *************************************************/
 
index beab97d872476f00447b035adfc4ce09943965b7..cfa9704080fe6fd00a7d7f4c709e8a7d92ef5ef9 100644 (file)
 #include "vm/jit/powerpc/md.h"
 #include "vm/jit/powerpc/linux/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
+#include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
 # include "vm/jit/optimizing/profile.h"
 #endif
 
-#include "vm/jit/stacktrace.h"
 #include "vm/jit/trap.h"
 
-#include "vmcore/system.h"
-
 
 /* md_signal_handler_sigsegv ***************************************************
 
@@ -335,7 +331,7 @@ void md_executionstate_read(executionstate_t *es, void *context)
         * the _mc->fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs));
-       system_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs));
+       os_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs));
 }
 
 
@@ -370,7 +366,7 @@ void md_executionstate_write(executionstate_t *es, void *context)
         * the _mc->fpregs[i] can cause invalid conversions. */
 
        assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs));
-       system_memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs));
+       os_memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs));
 
        /* write special registers */
        _gregs[PT_NIP] = (ptrint) es->pc;
@@ -380,39 +376,6 @@ void md_executionstate_write(executionstate_t *es, void *context)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       mcontext_t    *_mc;
-       unsigned long *_gregs;
-       u1            *pc;
-       u1            *npc;
-
-#if defined(__UCLIBC__)
-       _mc    = &(_uc->uc_mcontext);
-       _gregs = _mc->regs->gpr;
-#else
-       _mc    = _uc->uc_mcontext.uc_regs;
-       _gregs = _mc->gregs;
-#endif
-
-       pc = (u1 *) _gregs[PT_NIP];
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL)
-               _gregs[PT_NIP] = (ptrint) npc;
-}
-#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
diff --git a/src/vm/jit/powerpc/machine-instr.h b/src/vm/jit/powerpc/machine-instr.h
deleted file mode 100644 (file)
index 8c7ba6e..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-static inline long compare_and_swap(long *p, long oldval, long newval)
-{
-  long ret, temp;
-
-  __asm__ __volatile__ ("\n\
-1:  lwarx  %0,0,%4 \n\
-    subf.  %1,%0,%2 \n\
-    bne-   2f \n\
-    or     %1,%3,%3 \n\
-    stwcx. %1,0,%4 \n\
-    bne-   1b \n\
-2: \n\
-"   : "=&r"(ret), "=&r"(temp)
-    : "r"(oldval), "r"(newval), "r"(p) : "cr0", "memory");
-
-  return ret;
-}
-
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("isync" : : : "memory");
-#define MEMORY_BARRIER() __asm__ __volatile__ ( "sync" : : : "memory" );
-
-#endif
diff --git a/src/vm/jit/powerpc/md-atomic.hpp b/src/vm/jit/powerpc/md-atomic.hpp
new file mode 100644 (file)
index 0000000..09a3533
--- /dev/null
@@ -0,0 +1,137 @@
+/* src/vm/jit/powerpc/md-atomic.hpp - PowerPC atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       uint32_t temp;
+       uint32_t result;
+
+       __asm__ __volatile__ (
+               "1:                   \n"
+               "    lwarx  %0,0,%4   \n"
+               "    subf.  %1,%0,%2  \n"
+               "    bne-   2f        \n"
+               "    or     %1,%3,%3  \n"
+               "    stwcx. %1,0,%4   \n"
+               "    bne-   1b        \n"
+               "2:                   \n"
+               : "=&r" (result), "=&r" (temp)
+               : "r" (oldval), "r" (newval), "r" (p)
+               : "cr0", "memory");
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       return Atomic::generic_compare_and_swap(p, oldval, newval);
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return (void*) compare_and_swap((volatile uint32_t*) p, (uint32_t) oldval, (uint32_t) newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("sync" : : : "memory");
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       __asm__ __volatile__ ("isync" : : : "memory");
+}
+
+#endif // _MD_ATOMIC_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 3e552352653de800010fc569fc75843638fe2f90..fc9807d081ee0e4e60e4495c940ca469694082dd 100644 (file)
@@ -58,6 +58,7 @@ enum {
        /* Don't use 8 (could be a normal load offset). */
 
        TRAP_COMPILER                       = 9,
+       TRAP_COUNTDOWN                      = 10,
        TRAP_END
 };
 
index b85321c9d7f4ab89d4efe3a6802d00dcf1bd99c9..80257ab60cc5e958d33c29123feec1cf6c70ad0d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/md.c - machine dependent PowerPC functions
 
-   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.
 
@@ -37,7 +35,7 @@
 #include "vm/jit/powerpc/md.h"
 
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/jit.h"
 
index 6572885984ce9f7d9a51ef888f802d76e63150dd..dbf367765b12b5bab33d59c36610af40d070f948 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/md.h - machine dependent PowerPC functions
 
-   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.
 
@@ -36,7 +34,7 @@
 #include "vm/jit/powerpc/codegen.h"
 
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
@@ -77,46 +75,46 @@ inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframe
 
 *******************************************************************************/
 
-inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
+inline static void* md_codegen_get_pv_from_pc(void* ra)
 {
-       u1 *pv;
-       u4  mcode;
-       s4  offset;
+       int32_t offset;
+
+       uint32_t* pc = (uint32_t*) ra;
 
        /* get first instruction word after jump */
 
-       mcode = *((u4 *) (ra + 1 * 4));
+       uint32_t mcode = pc[1];
 
        /* check if we have 2 instructions (addis, addi) */
 
        if ((mcode >> 16) == 0x3dab) {
                /* get displacement of first instruction (addis) */
 
-               offset = (s4) (mcode << 16);
+               offset = (int32_t) (mcode << 16);
 
                /* get displacement of second instruction (addi) */
 
-               mcode = *((u4 *) (ra + 2 * 4));
+               mcode = pc[2];
 
                /* check for addi instruction */
 
                assert((mcode >> 16) == 0x39ad);
 
-               offset += (s2) (mcode & 0x0000ffff);
-
-       else {
+               offset += (int16_t) (mcode & 0x0000ffff);
+       }
+       else {
                /* check for addi instruction */
 
                assert((mcode >> 16) == 0x39ab);
 
                /* get offset of first instruction (addi) */
 
-               offset = (s2) (mcode & 0x0000ffff);
+               offset = (int16_t) (mcode & 0x0000ffff);
        }
 
        /* calculate PV via RA + offset */
 
-       pv = ra + offset;
+       void* pv = (void*) (((uintptr_t) ra) + offset);
 
        return pv;
 }
index 6955088303b909764671e2cf0d4c18881b7d6c73..a18683ef72475c94e1b79cf88d0e784706acd892 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/netbsd/md-os.c - machine dependent PowerPC NetBSD functions
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
 */
 
 
 
 #include "vm/jit/powerpc/netbsd/md-abi.h"
 
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* md_signal_handle_sigsegv ****************************************************
@@ -92,14 +83,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
-#if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *uc)
-{
-       /* XXX set pc to restart address */
-}
-#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
index f87a1a99dc0a9b8c89fe739fffae0948071c1bb7..13b50d814ca6df25c48ce7438fc3fbb07404fc59 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vm/resolve.h"
-#include "vmcore/references.h"
 
 
 #define PATCH_BACK_ORIGINAL_MCODE \
index 4ec4826ae012a0be82dd536a09cc7311a3b4d282..a450512ac5942dca5904ad4c3be681234213b500 100644 (file)
@@ -33,7 +33,7 @@ LIBS =
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = libarch.la
 
index f9cd0fbe63068332dbdb078ed0be244ac6659532..aac1b5707e2d75fc69f6171c4842734ca4691896 100644 (file)
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
@@ -2204,10 +2202,6 @@ gen_method:
                                        superindex = super->index;
                                }
                
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-                               }
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -2276,16 +2270,12 @@ gen_method:
 
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                        M_ALD(REG_ITMP2, REG_PV, disp);
                                        if (s1 != REG_ITMP1) {
                                                M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                                               CODEGEN_CRITICAL_SECTION_END;
-
                                                M_SUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
                                                M_EXTSW(REG_ITMP3, REG_ITMP3);
                                        } else {
@@ -2294,9 +2284,6 @@ gen_method:
                                                M_EXTSW(REG_ITMP3, REG_ITMP3);
                                                M_ALD(REG_ITMP2, REG_PV, disp);
                                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
-
-                                               CODEGEN_CRITICAL_SECTION_END;
-
                                        }
                                        M_CMPU(REG_ITMP3, REG_ITMP2);
                                        emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1);
@@ -2373,10 +2360,6 @@ gen_method:
                                superindex = super->index;
                        }
                        
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
-                               CODEGEN_CRITICAL_SECTION_NEW;
-                       }
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (s1 == d) {
@@ -2453,14 +2436,10 @@ gen_method:
                                M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_ITMP2, REG_PV, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
                                M_EXTSW(REG_ITMP1, REG_ITMP1);
                                M_CMPU(REG_ITMP1, REG_ITMP2);
@@ -2727,7 +2706,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument register */
 
-               disp = dseg_add_unique_address(cd, _Jv_env);
+               disp = dseg_add_unique_address(cd, VM_get_jnienv());
                M_ALD(REG_A0, REG_PV, disp);
        }
 
index b2a5119ee15daed98a51cba959f36ab118e0b736..26f2147600a0ede5786f1cada4d0c23c45be3a3f 100644 (file)
 
 #include "threads/lock-common.h"
 
-#include "vm/exceptions.h"
-#include "vm/vm.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
-#include "vmcore/options.h"
-
 
 /* emit_load *******************************************************************
 
index f1a054e122c6130ca8c6d3ae8516475b89e76714..68f1ae5e768a8f47acb1eed3089f9ed0d2909d39 100644 (file)
 
 #include "vm/jit/powerpc64/linux/md-abi.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/stack.h"
 
-#include "vmcore/descriptor.h"
-
-
-#define CACAO_ALIGN(a)    do { if ((a) & 1) (a)++; } while (0)
-
 
 /* register descripton array **************************************************/
 
index 8b292f1adb037876f59c8f3757c23618a66f88c6..e3821b7d01af5400daec2c7680d78373f9d52000 100644 (file)
 #include "vm/jit/powerpc64/md.h"
 #include "vm/jit/powerpc64/linux/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
+#include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
 
 #if defined(ENABLE_PROFILING)
 # include "vm/jit/optimizing/profile.h"
 #endif
 
-#include "vm/jit/stacktrace.h"
 #include "vm/jit/trap.h"
 
 
@@ -179,31 +179,87 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-/* md_critical_section_restart *************************************************
+/* md_executionstate_read ******************************************************
 
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
+   Read the given context into an executionstate.
 
 *******************************************************************************/
 
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
-       mcontext_t *_mc;
-       u1         *pc;
-       u1         *npc;
+#if 0
+       ucontext_t    *_uc;
+       mcontext_t    *_mc;
+       unsigned long *_gregs;
+       s4              i;
 
-       _mc = &(_uc->uc_mcontext);
+       _uc = (ucontext_t *) context;
 
-       pc = (u1 *) _mc->gp_regs[PT_NIP];
+       _mc    = _uc->uc_mcontext.uc_regs;
+       _gregs = _mc->gregs;
+
+       /* read special registers */
+       es->pc = (u1 *) _gregs[PT_NIP];
+       es->sp = (u1 *) _gregs[REG_SP];
+       es->pv = (u1 *) _gregs[REG_PV];
+       es->ra = (u1 *) _gregs[PT_LNK];
 
-       npc = critical_find_restart_point(pc);
+       /* read integer registers */
+       for (i = 0; i < INT_REG_CNT; i++)
+               es->intregs[i] = _gregs[i];
+
+       /* read float registers */
+       /* Do not use the assignment operator '=', as the type of
+        * the _mc->fpregs[i] can cause invalid conversions. */
+
+       assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs));
+       os_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs));
+#endif
 
-       if (npc != NULL)
-               _mc->gp_regs[PT_NIP] = (ptrint) npc;
+       vm_abort("md_executionstate_read: IMPLEMENT ME!");
 }
+
+
+/* md_executionstate_write *****************************************************
+
+   Write the given executionstate back to the context.
+
+*******************************************************************************/
+
+void md_executionstate_write(executionstate_t *es, void *context)
+{
+#if 0
+       ucontext_t    *_uc;
+       mcontext_t    *_mc;
+       unsigned long *_gregs;
+       s4              i;
+
+       _uc = (ucontext_t *) context;
+
+       _mc    = _uc->uc_mcontext.uc_regs;
+       _gregs = _mc->gregs;
+
+       /* write integer registers */
+       for (i = 0; i < INT_REG_CNT; i++)
+               _gregs[i] = es->intregs[i];
+
+       /* write float registers */
+       /* Do not use the assignment operator '=', as the type of
+        * the _mc->fpregs[i] can cause invalid conversions. */
+
+       assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs));
+       os_memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs));
+
+       /* write special registers */
+       _gregs[PT_NIP] = (ptrint) es->pc;
+       _gregs[REG_SP] = (ptrint) es->sp;
+       _gregs[REG_PV] = (ptrint) es->pv;
+       _gregs[PT_LNK] = (ptrint) es->ra;
 #endif
 
+       vm_abort("md_executionstate_write: IMPLEMENT ME!");
+}
+
 
 /*
  * These are local overrides for various environment variables in Emacs.
diff --git a/src/vm/jit/powerpc64/machine-instr.h b/src/vm/jit/powerpc64/machine-instr.h
deleted file mode 100644 (file)
index 5e3390c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-static inline long compare_and_swap(long *p, long oldval, long newval)
-{
-  long ret, temp;
-
-  __asm__ __volatile__ ("\n\
-1:  ldarx  %0,0,%4 \n\
-    subf.  %1,%0,%2 \n\
-    bne-   2f \n\
-    or     %1,%3,%3 \n\
-    stdcx. %1,0,%4 \n\
-    bne-   1b \n\
-2: \n\
-"   : "=&r"(ret), "=&r"(temp)
-    : "r"(oldval), "r"(newval), "r"(p) : "cr0", "memory");
-
-  return ret;
-}
-
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("isync" : : : "memory");
-#define MEMORY_BARRIER() __asm__ __volatile__ ( "sync" : : : "memory" );
-
-#endif
diff --git a/src/vm/jit/powerpc64/md-atomic.hpp b/src/vm/jit/powerpc64/md-atomic.hpp
new file mode 100644 (file)
index 0000000..f469e75
--- /dev/null
@@ -0,0 +1,154 @@
+/* src/vm/jit/powerpc64/atomic.hpp - PowerPC64 atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       uint32_t temp;
+       uint32_t result;
+
+       __asm__ __volatile__ (
+               "1:                   \n"
+               "    lwarx  %0,0,%4   \n"
+               "    subf.  %1,%0,%2  \n"
+               "    bne-   2f        \n"
+               "    or     %1,%3,%3  \n"
+               "    stwcx. %1,0,%4   \n"
+               "    bne-   1b        \n"
+               "2:                   \n"
+               : "=&r" (result), "=&r" (temp)
+               : "r" (oldval), "r" (newval), "r" (p)
+               : "cr0", "memory");
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       uint64_t temp;
+       uint64_t result;
+
+       __asm__ __volatile__ (
+               "1:                   \n"
+               "    ldarx  %0,0,%4   \n"
+               "    subf.  %1,%0,%2  \n"
+               "    bne-   2f        \n"
+               "    or     %1,%3,%3  \n"
+               "    stdcx. %1,0,%4   \n"
+               "    bne-   1b        \n"
+               "2:                   \n"
+               : "=&r" (result), "=&r" (temp)
+               : "r" (oldval), "r" (newval), "r" (p)
+               : "cr0", "memory");
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return (void*) compare_and_swap((volatile uint64_t*) p, (uint64_t) oldval, (uint64_t) newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("sync" : : : "memory");
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+
+/**
+ * An instruction memory barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       __asm__ __volatile__ ("isync" : : : "memory");
+}
+
+#endif // _MD_ATOMIC_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 7e8c5b6fdc830e60c792585bfe4bd5cc8dfed3bf..dad8d1f7dfcab9b9cfc2d0b56e136edee12b4e1f 100644 (file)
@@ -58,6 +58,7 @@ enum {
        /* Don't use 8 (could be a normal load offset). */
 
        TRAP_COMPILER                       = 9,
+       TRAP_COUNTDOWN                      = 10,
        TRAP_END
 };
 
index 3e8bc5c15edbb3c26b2375a9f17dfc4231f15129..842937ca3291b323200efc483da1aa2c45198f70 100644 (file)
@@ -37,7 +37,6 @@
 #include "vm/jit/powerpc64/codegen.h"
 #include "vm/jit/powerpc64/md.h"
 
-#include "vm/exceptions.h"
 #include "vm/global.h"
 
 #include "vm/jit/jit.h"
index 4a4d165e94777bb75a612bca55b73f98892f4ea7..992f8439d5c53627c591c37475ee8ff0fb19f3e8 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc64/md.h - machine dependent PowerPC functions
 
-   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.
 
@@ -36,7 +34,7 @@
 #include "vm/jit/powerpc64/codegen.h"
 
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
@@ -77,37 +75,37 @@ inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframe
 
 *******************************************************************************/
 
-inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
+inline static void* md_codegen_get_pv_from_pc(void* ra)
 {
-       u1 *pv;
-       u4  mcode;
-       s4  offset;
+       int32_t offset;
+
+       uint32_t* pc = (uint32_t*) ra;
 
        /* get first instruction word after jump */
 
-       mcode = *((u4 *) (ra + 1 * 4));
+       uint32_t mcode = pc[1];
 
        /* check if we have 2 instructions (addis, addi) */
 
        if ((mcode >> 16) == 0x3dcb) {
                /* get displacement of first instruction (addis) */
 
-               offset = (s4) (mcode << 16);
+               offset = (int32_t) (mcode << 16);
 
                /* get displacement of second instruction (addi) */
 
-               mcode = *((u4 *) (ra + 2 * 4));
+               mcode = pc[2];
 
                /* check for addi instruction */
 
                assert((mcode >> 16) == 0x39ce);
 
-               offset += (s2) (mcode & 0x0000ffff);
+               offset += (int16_t) (mcode & 0x0000ffff);
        }
        else if ((mcode >> 16) == 0x39cb) {
                /* get offset of first instruction (addi) */
 
-               offset = (s2) (mcode & 0x0000ffff);
+               offset = (int16_t) (mcode & 0x0000ffff);
        }
        else {
                vm_abort("md_codegen_get_pv_from_pc: unknown instruction %x", mcode);
@@ -119,7 +117,7 @@ inline static u1 *md_codegen_get_pv_from_pc(u1 *ra)
 
        /* calculate PV via RA + offset */
 
-       pv = ra + offset;
+       void* pv = (void*) (((uintptr_t) ra) + offset);
 
        return pv;
 }
index 8f6f160ad37bf1e942993e94e7206f5df6121fd4..c7c1eae6cafc932fc94f39b1c8777b6dc9ec8626 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
-#include "vm/resolve.h"
 
 
 /* patcher_patch_code **********************************************************
index 66e989f006371a76bb23070191d9531136cbc7cf..b4196b1f4477200aa59f08b2af57e931875f0a3a 100644 (file)
@@ -53,6 +53,7 @@ struct varinfo {
                float f;
                double d;
                basicblock *retaddr;
+               s4 ii[2];
        } vv;
 #if defined(ENABLE_VERIFIER)
        typeinfo_t typeinfo;       /* type info for reference types              */
index 5895bec0688a9368f4e8491e57c582ef0bf5be16..dea13b1ed821ff41bddc65c387ed80f5c7dfbfeb 100644 (file)
 
 #include "mm/memory.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
-#include "vm/stringlocal.h"
+#include "vm/classcache.h"
+#include "vm/globals.hpp"
+#include "vm/options.h"
+#include "vm/string.hpp"
+
+#if defined(ENABLE_RT_TIMING)
+# include "vm/rt-timing.h"
+#endif
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
@@ -54,9 +61,6 @@
 #include "vm/jit/show.h"
 #include "vm/jit/stack.h"
 
-#include "vmcore/options.h"
-#include "vmcore/classcache.h"
-
 
 #define REPLACE_PATCH_DYNAMIC_CALL
 /*#define REPLACE_PATCH_ALL*/
@@ -72,7 +76,6 @@
 #undef REPLACE_RA_TOP_OF_FRAME
 #undef REPLACE_RA_LINKAGE_AREA
 #undef REPLACE_LEAFMETHODS_RA_REGISTER
-#undef REPLACE_REG_RA
 
 /* i386, x86_64 and m68k */
 #if defined(__I386__) || defined(__X86_64__) || defined(__M68K__)
 #elif defined(__ALPHA__)
 #define REPLACE_RA_TOP_OF_FRAME
 #define REPLACE_LEAFMETHODS_RA_REGISTER
-#define REPLACE_REG_RA REG_RA
 /* powerpc */
 #elif defined(__POWERPC__)
 #define REPLACE_RA_LINKAGE_AREA
 #define REPLACE_LEAFMETHODS_RA_REGISTER
-#define REPLACE_REG_RA REG_ITMP3 /* the execution state has the LR in itmp3 */
 /* s390 */
 #elif defined(__S390__)
 #define REPLACE_RA_TOP_OF_FRAME
-#define REPLACE_REG_RA REG_ITMP3
 #endif
 
 
@@ -1232,6 +1232,12 @@ static void replace_read_executionstate(rplpoint *rp,
                replace_read_value(es, &instra, &(frame->instance));
 #endif
        }
+#if defined(__I386__)
+       else if (!(rp->method->flags & ACC_STATIC)) {
+               /* On i386 we always pass the first argument on stack. */
+               frame->instance.a = *(java_object_t **)(basesp + 1);
+       } 
+#endif
 #endif /* defined(REPLACE_PATCH_DYNAMIC_CALL) */
 
        /* read stack slots */
@@ -1463,6 +1469,12 @@ static void replace_write_executionstate(rplpoint *rp,
 
                if (!topframe && ra->index == RPLALLOC_PARAM) {
                        /* skip it */
+                       /*
+                       ra->index = RPLALLOC_PARAM;
+                       replace_val_t v;
+                       v.l = 0;
+                       replace_write_value(es,ra,&v);
+                       */
                }
                else {
                        assert(i < frame->javastackdepth);
@@ -1483,81 +1495,72 @@ static void replace_write_executionstate(rplpoint *rp,
 }
 
 
-/* replace_pop_activation_record ***********************************************
+/* md_pop_stackframe ***********************************************************
+
+   Restore callee-saved registers (including the RA register),
+   set the stack pointer to the next stackframe,
+   set the PC to the return address of the popped frame.
 
-   Peel a stack frame from the execution state.
-   
    *** This function imitates the effects of the method epilog ***
    *** and returning from the method call.                     ***
 
    IN:
-          es...............execution state
-          frame............source frame, receives synchronization slots
+       es...............execution state
 
    OUT:
        *es..............the execution state after popping the stack frame
-  
+                        NOTE: es->code and es->pv are NOT updated.
+
 *******************************************************************************/
 
-u1* replace_pop_activation_record(executionstate_t *es,
-                                                                 sourceframe_t *frame)
+void md_pop_stackframe(executionstate_t *es)
 {
        u1 *ra;
-       u1 *pv;
+       s4 ra_align_off;
        s4 reg;
        s4 i;
-       s4 count;
-       codeinfo *code;
        stackslot_t *basesp;
        stackslot_t *sp;
 
        assert(es->code);
-       assert(frame);
+
+       /* alignment offset of RA */
+
+       ra_align_off = 0;
+#if defined(REPLACE_RA_BETWEEN_FRAMES)
+    if (es->code->stackframesize)
+               ra_align_off = SIZE_OF_STACKSLOT - SIZEOF_VOID_P;
+#endif
 
        /* read the return address */
 
 #if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
        if (code_is_leafmethod(es->code))
-               ra = (u1*) (ptrint) es->intregs[REPLACE_REG_RA];
+               ra = es->ra;
        else
 #endif
                ra = md_stacktrace_get_returnaddress(es->sp,
-                               SIZE_OF_STACKSLOT * es->code->stackframesize);
-
-       DOLOG( printf("RA = %p\n", (void*)ra); );
-
-       assert(ra);
+                          SIZE_OF_STACKSLOT * es->code->stackframesize + ra_align_off);
 
        /* calculate the base of the stack frame */
 
        sp = (stackslot_t *) es->sp;
        basesp = sp + es->code->stackframesize;
 
-       /* read slots used for synchronization */
-
-       assert(frame->syncslotcount == 0);
-       assert(frame->syncslots == NULL);
-       count = code_get_sync_slot_count(es->code);
-       frame->syncslotcount = count;
-       frame->syncslots = DMNEW(replace_val_t, count);
-       for (i=0; i<count; ++i) {
-               frame->syncslots[i].p = sp[es->code->memuse + i]; /* XXX */
-       }
-
        /* restore return address, if part of frame */
 
 #if defined(REPLACE_RA_TOP_OF_FRAME)
 #if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
        if (!code_is_leafmethod(es->code))
 #endif
-               es->intregs[REPLACE_REG_RA] = *--basesp;
+               es->ra = (u1*) (ptrint) *--basesp;
 #endif /* REPLACE_RA_TOP_OF_FRAME */
 
 #if defined(REPLACE_RA_LINKAGE_AREA)
 #if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
        if (!code_is_leafmethod(es->code))
 #endif
-               es->intregs[REPLACE_REG_RA] = basesp[LA_LR_OFFSET / sizeof(stackslot_t)];
+               es->ra = (u1*) (ptrint) basesp[LA_LR_OFFSET / sizeof(stackslot_t)];
 #endif /* REPLACE_RA_LINKAGE_AREA */
 
        /* restore saved int registers */
@@ -1596,37 +1599,19 @@ u1* replace_pop_activation_record(executionstate_t *es,
        es->sp += SIZE_OF_STACKSLOT * es->code->stackframesize;
 
 #if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp += SIZE_OF_STACKSLOT; /* skip return address */
+       es->sp += ra_align_off + SIZEOF_VOID_P; /* skip return address */
 #endif
 
-       /* Set the new pc. Subtract one so we do not hit the replacement point */
-       /* of the instruction following the call, if there is one.             */
-
-       es->pc = ra - 1;
-
-       /* find the new codeinfo */
-
-       pv = md_codegen_get_pv_from_pc(ra);
-       DOLOG( printf("PV = %p\n", (void*) pv); );
-
-       code = code_get_codeinfo_for_pv(pv);
-       DOLOG( printf("CODE = %p\n", (void*) code); );
-
-       /* return NULL if we reached native code */
+       /* set the program counter to the return address */
 
-       es->pv = pv;
-       es->code = code;
+       es->pc = ra;
 
        /* in debugging mode clobber non-saved registers */
 
 #if !defined(NDEBUG)
        /* for debugging */
        for (i=0; i<INT_REG_CNT; ++i)
-               if ((nregdescint[i] != REG_SAV)
-#if defined(REG_RA)
-                               && (i != REPLACE_REG_RA)
-#endif
-                       )
+               if (nregdescint[i] != REG_SAV)
                        es->intregs[i] = (ptrint) 0x33dead3333dead33ULL;
        for (i=0; i<FLT_REG_CNT; ++i)
                if (nregdescfloat[i] != REG_SAV)
@@ -1637,6 +1622,211 @@ u1* replace_pop_activation_record(executionstate_t *es,
                        es->adrregs[i] = (ptrint) 0x33dead3333dead33ULL;
 # endif
 #endif /* !defined(NDEBUG) */
+}
+
+
+/* md_push_stackframe **********************************************************
+
+   Save the given return address, build the new stackframe,
+   and store callee-saved registers.
+
+   *** This function imitates the effects of a call and the ***
+   *** method prolog of the callee.                         ***
+
+   IN:
+       es...............execution state
+       calleecode.......the code we are "calling"
+       ra...............the return address to save
+
+   OUT:
+       *es..............the execution state after pushing the stack frame
+                        NOTE: es->pc, es->code, and es->pv are NOT updated.
+
+*******************************************************************************/
+
+void md_push_stackframe(executionstate_t *es, codeinfo *calleecode, u1 *ra)
+{
+       s4           reg;
+       s4           i;
+       stackslot_t *basesp;
+       stackslot_t *sp;
+
+       assert(es);
+       assert(calleecode);
+
+       /* write the return address */
+
+#if defined(REPLACE_RA_BETWEEN_FRAMES)
+       es->sp -= SIZEOF_VOID_P;
+       *((void **)es->sp) = (void *) ra;
+       if (calleecode->stackframesize)
+               es->sp -= (SIZE_OF_STACKSLOT - SIZEOF_VOID_P);
+#endif /* REPLACE_RA_BETWEEN_FRAMES */
+
+       es->ra = (u1*) (ptrint) ra;
+
+       /* build the stackframe */
+
+       DOLOG( printf("building stackframe of %d words at %p\n",
+                                 calleecode->stackframesize, (void*)es->sp); );
+
+       sp = (stackslot_t *) es->sp;
+       basesp = sp;
+
+       sp -= calleecode->stackframesize;
+       es->sp = (u1*) sp;
+
+       /* in debug mode, invalidate stack frame first */
+
+       /* XXX may not invalidate linkage area used by native code! */
+
+#if !defined(NDEBUG) && 0
+       for (i=0; i< (basesp - sp) && i < 1; ++i) {
+               sp[i] = 0xdeaddeadU;
+       }
+#endif
+
+#if defined(__I386__)
+       /* Stackslot 0 may contain the object instance for vftbl patching.
+          Destroy it, so there's no undefined value used. */
+       if ((basesp - sp) > 0) {
+               sp[0] = 0;
+       }
+#endif
+
+       /* save the return address register */
+
+#if defined(REPLACE_RA_TOP_OF_FRAME)
+#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+       if (!code_is_leafmethod(calleecode))
+#endif
+               *--basesp = (ptrint) ra;
+#endif /* REPLACE_RA_TOP_OF_FRAME */
+
+#if defined(REPLACE_RA_LINKAGE_AREA)
+#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+       if (!code_is_leafmethod(calleecode))
+#endif
+               basesp[LA_LR_OFFSET / sizeof(stackslot_t)] = (ptrint) ra;
+#endif /* REPLACE_RA_LINKAGE_AREA */
+
+       /* save int registers */
+
+       reg = INT_REG_CNT;
+       for (i=0; i<calleecode->savedintcount; ++i) {
+               while (nregdescint[--reg] != REG_SAV)
+                       ;
+               *--basesp = es->intregs[reg];
+
+               /* XXX may not clobber saved regs used by native code! */
+#if !defined(NDEBUG) && 0
+               es->intregs[reg] = (ptrint) 0x44dead4444dead44ULL;
+#endif
+       }
+
+       /* save flt registers */
+
+       /* XXX align? */
+       reg = FLT_REG_CNT;
+       for (i=0; i<calleecode->savedfltcount; ++i) {
+               while (nregdescfloat[--reg] != REG_SAV)
+                       ;
+               basesp -= STACK_SLOTS_PER_FLOAT;
+               *(double*)basesp = es->fltregs[reg];
+
+               /* XXX may not clobber saved regs used by native code! */
+#if !defined(NDEBUG) && 0
+               *(u8*)&(es->fltregs[reg]) = 0x44dead4444dead44ULL;
+#endif
+       }
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       /* save adr registers */
+
+       reg = ADR_REG_CNT;
+       for (i=0; i<calleecode->savedadrcount; ++i) {
+               while (nregdescadr[--reg] != REG_SAV)
+                       ;
+               *--basesp = es->adrregs[reg];
+
+               /* XXX may not clobber saved regs used by native code! */
+#if !defined(NDEBUG) && 0
+               es->adrregs[reg] = (ptrint) 0x44dead4444dead44ULL;
+#endif
+       }
+#endif
+}
+
+
+/* replace_pop_activation_record ***********************************************
+
+   Peel a stack frame from the execution state.
+
+   *** This function imitates the effects of the method epilog ***
+   *** and returning from the method call.                     ***
+
+   IN:
+       es...............execution state
+       frame............source frame, receives synchronization slots
+
+   OUT:
+       *es..............the execution state after popping the stack frame
+
+   RETURN VALUE:
+       the return address of the poped activation record
+
+*******************************************************************************/
+
+u1* replace_pop_activation_record(executionstate_t *es,
+                                                                 sourceframe_t *frame)
+{
+       u1 *ra;
+       u1 *pv;
+       s4 i;
+       s4 count;
+       codeinfo *code;
+       stackslot_t *sp;
+
+       assert(es->code);
+       assert(frame);
+
+       /* calculate the base of the stack frame */
+
+       sp = (stackslot_t *) es->sp;
+       assert(frame->syncslotcount == 0);
+       assert(frame->syncslots == NULL);
+       count = code_get_sync_slot_count(es->code);
+       frame->syncslotcount = count;
+       frame->syncslots = DMNEW(replace_val_t, count);
+       for (i=0; i<count; ++i) {
+               frame->syncslots[i].p = sp[es->code->memuse + i]; /* XXX md_ function */
+       }
+
+       /* pop the stackframe */
+
+       md_pop_stackframe(es);
+
+       ra = es->pc;
+
+       DOLOG( printf("RA = %p\n", (void*)ra); );
+
+       /* Subtract one from the PC so we do not hit the replacement point */
+       /* of the instruction following the call, if there is one.         */
+
+       es->pc--;
+
+       /* find the new codeinfo */
+
+       pv = md_codegen_get_pv_from_pc(ra);
+       DOLOG( printf("PV = %p\n", (void*) pv); );
+
+       code = code_get_codeinfo_for_pv(pv);
+       DOLOG( printf("CODE = %p\n", (void*) code); );
+
+       /* return NULL if we reached native code */
+
+       es->pv = pv;
+       es->code = code;
 
        return (code) ? ra : NULL;
 }
@@ -1830,8 +2020,11 @@ void replace_patch_future_calls(u1 *ra,
 
                /* we can only patch such calls if we are at the entry point */
 
+#if !defined(__I386__)
+               /* On i386 we always know the instance argument. */
                if (!atentry)
                        return;
+#endif
 
                assert((calleem->flags & ACC_STATIC) == 0);
 
@@ -1859,6 +2052,11 @@ void replace_patch_future_calls(u1 *ra,
        else {
                /* the call was statically bound */
 
+#if defined(__I386__)
+               /* It happens that there is a patcher trap. (pm) */
+               if (*(u2 *)(patchpos - 1) == 0x0b0f) {
+               } else
+#endif
                replace_patch_method_pointer((methodptr *) patchpos, entrypoint, "static   ");
        }
 }
@@ -1888,10 +2086,8 @@ void replace_push_activation_record(executionstate_t *es,
                                                                        sourceframe_t *callerframe,
                                                                        sourceframe_t *calleeframe)
 {
-       s4           reg;
        s4           i;
        s4           count;
-       stackslot_t *basesp;
        stackslot_t *sp;
        u1          *ra;
        codeinfo    *calleecode;
@@ -1915,120 +2111,25 @@ void replace_push_activation_record(executionstate_t *es,
        else
                ra = es->pc + 1 /* XXX this is ugly */;
 
-       /* write the return address */
-
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp -= SIZE_OF_STACKSLOT;
-
-       *((stackslot_t *)es->sp) = (stackslot_t) ra;
-#endif /* REPLACE_RA_BETWEEN_FRAMES */
+       /* push the stackframe */
 
-#if defined(REPLACE_REG_RA)
-       es->intregs[REPLACE_REG_RA] = (ptrint) ra;
-#endif
+       md_push_stackframe(es, calleecode, ra);
 
-       /* we move into a new code unit */
+       /* we move into a new code unit, set code, PC, PV */
 
        es->code = calleecode;
-
-       /* set the new pc XXX not needed? */
-
-       es->pc = calleecode->entrypoint;
-
-       /* build the stackframe */
-
-       DOLOG( printf("building stackframe of %d words at %p\n",
-                                 calleecode->stackframesize, (void*)es->sp); );
-
-       sp = (stackslot_t *) es->sp;
-       basesp = sp;
-
-       sp -= calleecode->stackframesize;
-       es->sp = (u1*) sp;
-
-       /* in debug mode, invalidate stack frame first */
-
-       /* XXX may not invalidate linkage area used by native code! */
-#if !defined(NDEBUG) && 0
-       for (i=0; i<(basesp - sp); ++i) {
-               sp[i] = 0xdeaddeadU;
-       }
-#endif
-
-       /* save the return address register */
-
-#if defined(REPLACE_RA_TOP_OF_FRAME)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
-       if (!code_is_leafmethod(calleecode))
-#endif
-               *--basesp = (ptrint) ra;
-#endif /* REPLACE_RA_TOP_OF_FRAME */
-
-#if defined(REPLACE_RA_LINKAGE_AREA)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
-       if (!code_is_leafmethod(calleecode))
-#endif
-               basesp[LA_LR_OFFSET / sizeof(stackslot_t)] = (ptrint) ra;
-#endif /* REPLACE_RA_LINKAGE_AREA */
-
-       /* save int registers */
-
-       reg = INT_REG_CNT;
-       for (i=0; i<calleecode->savedintcount; ++i) {
-               while (nregdescint[--reg] != REG_SAV)
-                       ;
-               *--basesp = es->intregs[reg];
-
-               /* XXX may not clobber saved regs used by native code! */
-#if !defined(NDEBUG) && 0
-               es->intregs[reg] = (ptrint) 0x44dead4444dead44ULL;
-#endif
-       }
-
-       /* save flt registers */
-
-       /* XXX align? */
-       reg = FLT_REG_CNT;
-       for (i=0; i<calleecode->savedfltcount; ++i) {
-               while (nregdescfloat[--reg] != REG_SAV)
-                       ;
-               basesp -= STACK_SLOTS_PER_FLOAT;
-               *(double*)basesp = es->fltregs[reg];
-
-               /* XXX may not clobber saved regs used by native code! */
-#if !defined(NDEBUG) && 0
-               *(u8*)&(es->fltregs[reg]) = 0x44dead4444dead44ULL;
-#endif
-       }
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       /* save adr registers */
-
-       reg = ADR_REG_CNT;
-       for (i=0; i<calleecode->savedadrcount; ++i) {
-               while (nregdescadr[--reg] != REG_SAV)
-                       ;
-               *--basesp = es->adrregs[reg];
-
-               /* XXX may not clobber saved regs used by native code! */
-#if !defined(NDEBUG) && 0
-               es->adrregs[reg] = (ptrint) 0x44dead4444dead44ULL;
-#endif
-       }
-#endif
+       es->pc = calleecode->entrypoint; /* XXX not needed? */
+       es->pv = calleecode->entrypoint;
 
        /* write slots used for synchronization */
 
+       sp = (stackslot_t *) es->sp;
        count = code_get_sync_slot_count(calleecode);
        assert(count == calleeframe->syncslotcount);
        for (i=0; i<count; ++i) {
                sp[calleecode->memuse + i] = calleeframe->syncslots[i].p;
        }
 
-       /* set the PV */
-
-       es->pv = calleecode->entrypoint;
-
        /* redirect future invocations */
 
        if (callerframe && rpcall) {
@@ -2144,7 +2245,7 @@ no_match:
 
 *******************************************************************************/
 
-rplpoint *replace_find_replacement_point_for_pc(codeinfo *code, u1 *pc)
+rplpoint *replace_find_replacement_point_for_pc(codeinfo *code, u1 *pc, unsigned desired_flags)
 {
        rplpoint *found;
        rplpoint *rp;
@@ -2158,14 +2259,20 @@ rplpoint *replace_find_replacement_point_for_pc(codeinfo *code, u1 *pc)
        rp = code->rplpoints;
        for (i=0; i<code->rplpointcount; ++i, ++rp) {
                DOLOG( replace_replacement_point_println(rp, 2); );
-               if (rp->pc <= pc && rp->pc + rp->callsize >= pc)
-                       found = rp;
+               if (rp->pc <= pc && rp->pc + rp->callsize >= pc) {
+                       if (desired_flags) {
+                               if (rp->flags & desired_flags) {
+                                       found = rp;
+                               }
+                       } else {
+                               found = rp;
+                       }
+               }
        }
 
        return found;
 }
 
-
 /* replace_pop_native_frame ****************************************************
 
    Unroll a native frame in the execution state and create a source frame
@@ -2199,7 +2306,7 @@ static void replace_pop_native_frame(executionstate_t *es,
        /* remember pc and size of native frame */
 
        frame->nativepc = es->pc;
-       frame->nativeframesize = (es->sp != 0) ? (sfi->sp - es->sp) : 0;
+       frame->nativeframesize = (es->sp != 0) ? (((uintptr_t) sfi->sp) - ((uintptr_t) es->sp)) : 0;
        assert(frame->nativeframesize >= 0);
 
        /* remember values of saved registers */
@@ -2271,12 +2378,12 @@ static void replace_pop_native_frame(executionstate_t *es,
 
        /* XXX michi: use this instead:
        es->sp = sfi->sp + code->stackframesize; */
-       es->sp   = sfi->sp + (*(s4 *) (sfi->pv + FrameSize));
+       es->sp   = (void*) (((uintptr_t) sfi->sp) + (*(s4 *) (((uintptr_t) sfi->pv) + FrameSize)));
 #if defined(REPLACE_RA_BETWEEN_FRAMES)
        es->sp  += SIZE_OF_STACKSLOT; /* skip return address */
 #endif
        es->pv   = md_codegen_get_pv_from_pc(sfi->ra);
-       es->pc   = ((sfi->xpc) ? sfi->xpc : sfi->ra) - 1;
+       es->pc   = (void*) (((uintptr_t) ((sfi->xpc) ? sfi->xpc : sfi->ra)) - 1);
        es->code = code_get_codeinfo_for_pv(es->pv);
 }
 
@@ -2320,7 +2427,7 @@ static void replace_push_native_frame(executionstate_t *es, sourcestate_t *ss)
 
        /* skip sp for the native stub */
 
-       es->sp -= (*(s4 *) (frame->sfi->pv + FrameSize));
+       es->sp -= (*(s4 *) (((uintptr_t) frame->sfi->pv) + FrameSize));
 #if defined(REPLACE_RA_BETWEEN_FRAMES)
        es->sp -= SIZE_OF_STACKSLOT; /* skip return address */
 #endif
@@ -2492,7 +2599,7 @@ sourcestate_t *replace_recover_source_state(rplpoint *rp,
                        /* find the replacement point at the call site */
 
 after_machine_frame:
-                       rp = replace_find_replacement_point_for_pc(es->code, es->pc);
+                       rp = replace_find_replacement_point_for_pc(es->code, es->pc, 0);
 
                        if (rp == NULL)
                                vm_abort("could not find replacement point while unrolling call");
@@ -2763,6 +2870,12 @@ static void replace_me(rplpoint *rp, executionstate_t *es)
        origcode = es->code;
        origrp   = rp;
 
+#if defined(ENABLE_TLH)
+       /*printf("Replacing in %s/%s\n", rp->method->clazz->name->text, rp->method->name->text);*/
+#endif
+
+       /*if (strcmp(rp->method->clazz->name->text, "antlr/AlternativeElement") == 0 && strcmp(rp->method->name->text, "getAutoGenType") ==0) opt_TraceReplacement = 2; else opt_TraceReplacement = 0;*/
+
        DOLOG_SHORT( printf("REPLACING(%d %p): (id %d %p) ",
                                 stat_replacements, (void*)THREADOBJECT,
                                 rp->id, (void*)rp);
@@ -2888,6 +3001,9 @@ bool replace_me_wrapper(u1 *pc, void *context)
        codeinfo         *code;
        rplpoint         *rp;
        executionstate_t  es;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
 
        /* search the codeinfo for the given PC */
 
@@ -2896,11 +3012,14 @@ bool replace_me_wrapper(u1 *pc, void *context)
 
        /* search for a replacement point at the given PC */
 
-       rp = replace_find_replacement_point_for_pc(code, pc);
+       rp = replace_find_replacement_point_for_pc(code, pc, (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN));
 
        /* check if the replacement point belongs to given PC and is active */
 
-       if ((rp != NULL) && (rp->pc == pc) && (rp->flags & RPLPOINT_FLAG_ACTIVE)) {
+       if ((rp != NULL) && (rp->pc == pc)
+           && (rp->flags & (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN))) {
+
+               DOLOG( printf("valid replacement point\n"); );
 
 #if !defined(NDEBUG)
                executionstate_sanity_check(context);
@@ -2919,8 +3038,17 @@ bool replace_me_wrapper(u1 *pc, void *context)
 
                /* do the actual replacement */
 
+#if defined(ENABLE_RT_TIMING)
+               RT_TIMING_GET_TIME(time_start);
+#endif
+
                replace_me(rp, &es);
 
+#if defined(ENABLE_RT_TIMING)
+               RT_TIMING_GET_TIME(time_end);
+               RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_REPLACE);
+#endif
+
                /* write execution state to current context */
 
                md_executionstate_write(&es, context);
index 752cd385f4c8f8a633638c33688272101c781511..76cf0819be547cc793571be0b11b254e1946eeb1 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/replace.h - on-stack replacement of methods
 
-   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.
 
@@ -59,10 +57,10 @@ typedef union  replace_val_t replace_val_t;
 #include "arch.h"
 #include "md-abi.h"
 
-#include "vm/jit/reg.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/method.h"
 
-#include "vmcore/method.h"
+#include "vm/jit/reg.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /*** structs *********************************************************/
@@ -140,7 +138,6 @@ union replace_val_t {
 };
 
 
-       u1           *ra;                /* return address / link register */
 struct sourceframe_t {
        sourceframe_t *down;           /* source frame down the call chain */
 
index a9c16bd31a3ac1ae7e4da4f34928cd5eb28a5330..7e17c12f7efcedac2527c2c647fa199653a298c6 100644 (file)
@@ -28,9 +28,9 @@ LIBS =
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h \
        \
-       md-asm.h
+       md-asm.h \
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = \
        libarch.la
index 37de069008202e107531539eb15bcc3f068cf0a7..72e5bc3c3d47ad62791ae7d5dd91a08f0f8da244 100644 (file)
 
 #include "threads/lock-common.h"
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
 #include "vm/types.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #if defined(ENABLE_LSRA)
@@ -68,7 +66,7 @@
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 
@@ -3003,9 +3001,6 @@ gen_method:
                                        supervftbl = super->vftbl;
                                }
 
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -3083,8 +3078,6 @@ gen_method:
                                        }
 
 #if 1
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        /* REG_ITMP3 := baseval(s1) */
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
@@ -3100,8 +3093,6 @@ gen_method:
                                        M_ALD_DSEG(REG_ITMP2, disp);
                                        M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                                       CODEGEN_CRITICAL_SECTION_END;
-
                                        M_CMPU(REG_ITMP3, REG_ITMP2); /* Unsigned compare */
 
                                        /* M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3); itmp3 = (itmp2 <= itmp3) */
@@ -3111,16 +3102,12 @@ gen_method:
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ALD_DSEG(REG_ITMP3, disp);
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
                                        M_ISUB(REG_ITMP3, REG_ITMP2);
                                        M_ALD_DSEG(REG_ITMP3, disp);
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
 
-                                       CODEGEN_CRITICAL_SECTION_END;
-                                       
                                        M_CMPU(REG_ITMP2, REG_ITMP3); /* Unsigned compare */
                                        /* M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3); itmp3 = (itmp2 <= itmp3) */
                                        /* M_BEQZ(REG_ITMP3, 0); branch if (! itmp) -> branch if > */
@@ -3223,9 +3210,6 @@ gen_method:
 #                      define LABEL_EXIT_INTERFACE_DONE BRANCH_LABEL_5
 #                      define LABEL_EXIT_CLASS_NULL BRANCH_LABEL_6
 
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (s1 == d) {
@@ -3327,14 +3311,10 @@ gen_method:
                                M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD_DSEG(REG_ITMP2, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_ISUB(REG_ITMP3, REG_ITMP1); /* itmp1 :=  itmp1 (sub.baseval) - itmp3 (super.baseval) */
 
                                M_CMPU(REG_ITMP1, REG_ITMP2); /* d := (uint)REG_ITMP1 <= (uint)REG_ITMP2 */
@@ -3665,7 +3645,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument register */
 
-               disp = dseg_add_address(cd, _Jv_env);
+               disp = dseg_add_address(cd, VM_get_jnienv());
                M_ALD_DSEG(REG_A0, disp);
        }
 
index 9ac259c71ff7dc7482dd32e287c9999803ea023e..00467f338d486b82f1af6986c5b03f39cbd472e6 100644 (file)
@@ -36,9 +36,9 @@
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/types.h"
+#include "vm/options.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
-#include "vmcore/options.h"
-
 
 /* emit_load *******************************************************************
 
diff --git a/src/vm/jit/s390/machine-instr.h b/src/vm/jit/s390/machine-instr.h
deleted file mode 100644 (file)
index b470961..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-/*  Taken from linux kernel source 
- *  include/asm-s390/atomic.h
- *
- *  S390 version
- *    Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Denis Joseph Barrow,
- *              Arnd Bergmann (arndb@de.ibm.com)
- *
- *  Derived from "include/asm-i386/bitops.h"
- *    Copyright (C) 1992, Linus Torvalds
- */
-
-static inline long
-compare_and_swap (volatile long *p, long oldval, long newval)
-{
-       __asm__ __volatile__("  cs   %0,%3,0(%2)\n"
-                            : "+d" (oldval), "=m" (*p)
-                            : "a" (p), "d" (newval), "m" (*p)
-                            : "cc", "memory" );
-       return oldval;
-}
-
-/*
- *  Taken from linux kerenl source
- *  include/asm-s390/system.h
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *
- *  Derived from "include/asm-i386/system.h"
- */
-
-/*
- * Force strict CPU ordering.
- * And yes, this is required on UP too when we're talking
- * to devices.
- *
- * This is very similar to the ppc eieio/sync instruction in that is
- * does a checkpoint syncronisation & makes sure that 
- * all memory ops have completed wrt other CPU's ( see 7-15 POP  DJB ).
- */
-
-#define eieio()  __asm__ __volatile__ ( "bcr 15,0" : : : "memory" ) 
-
-#define STORE_ORDER_BARRIER() eieio()
-#define MEMORY_BARRIER() eieio()
-
-/* TODO not sure if the following two can't be just empty. */
-
-#define MEMORY_BARRIER_AFTER_ATOMIC() eieio()
-
-#endif
index 99715c6e1a2f272d03597ea5750e42a426042755..7f9017ca4fab272b70e198f8e2143e78eb2021ec 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 #include "vm/types.h"
 
@@ -33,8 +34,6 @@
 
 #include "vm/jit/s390/md-abi.h"
 
-#include "vmcore/descriptor.h"
-
 #include <assert.h>
 
 
diff --git a/src/vm/jit/s390/md-atomic.hpp b/src/vm/jit/s390/md-atomic.hpp
new file mode 100644 (file)
index 0000000..fafb642
--- /dev/null
@@ -0,0 +1,127 @@
+/* src/vm/jit/s390/md-atomic.hpp - s390 atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       __asm__ __volatile__ (
+               "cs %0,%3,0(%2)\n"
+               : "+d" (oldval), "=m" (*p)
+               : "a" (p), "d" (newval), "m" (*p)
+               : "cc", "memory" );
+
+       return oldval;
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       return generic_compare_and_swap(p, oldval, newval);
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return (void*) compare_and_swap((volatile uint32_t*) p, (uint32_t) oldval, (uint32_t) newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("bcr 15,0" : : : "memory" );
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       memory_barrier();
+}
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       memory_barrier();
+}
+
+#endif // _MD_ATOMIC_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 ac0fe0816edf26b4d1eaad1c47a6c8f7fddc9166..a5e05a0716e82606a380dc0f3637eff78fd315e9 100644 (file)
@@ -46,7 +46,8 @@ enum {
        TRAP_ClassCastException             = 4,
        TRAP_CHECK_EXCEPTION                = 5,
        TRAP_PATCHER                        = 6,
-       TRAP_COMPILER                       = 7
+       TRAP_COMPILER                       = 7,
+       TRAP_COUNTDOWN                      = 8
 };
 
 #endif /* _MD_TRAP_H */
index 3959f0a91b87a2398462fc32b7da77c4c8187516..917e17a3c93ee2ab4f7edd0e69363f2216329685 100644 (file)
@@ -34,9 +34,9 @@
 
 #include "vm/jit/s390/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/signallocal.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/methodtree.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
-#include "vmcore/options.h" /* XXX debug */
+#include "vm/options.h" /* XXX debug */
 #include "vm/jit/disass.h" /* XXX debug */
 #endif
 
@@ -412,27 +412,6 @@ void md_executionstate_write(executionstate_t* es, void* context)
 }
 
 
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       u1         *pc;
-       void       *npc;
-
-       _mc = &_uc->uc_mcontext;
-
-       pc = (u1 *)_mc->psw.addr;
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL) {
-               log_println("%s: pc=%p, npc=%p", __FUNCTION__, pc, npc);
-               _mc->psw.addr = (ptrint) npc;
-       }
-}
-#endif
-
-
 /* md_jit_method_patch_address *************************************************
 
    Gets the patch address of the currently compiled method. The offset
index 667aa07587c0f05db22fb65ce0ee78b20727c4c3..94e40a9ff82b2f19dde32b86d7ba44c3ab6e69cc 100644 (file)
 
 #include "mm/memory.h"
 #include "native/native.h"
+
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
+#include "vm/types.h"
+
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/s390/codegen.h"
 #include "vm/jit/s390/md-abi.h"
-#include "vm/jit/stacktrace.h"
-#include "vm/resolve.h"
-#include "vm/types.h"
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
+
 
 #define PATCH_BACK_ORIGINAL_MCODE \
        *((u2 *) pr->mpc) = (u2) pr->mcode;
index 0b429ccadba6ef1cc03c43d1298c5e5c24aedfc8..55e3592c1f13d68bd2ecec751725f6ca36124184 100644 (file)
@@ -36,8 +36,9 @@
 
 #include "vm/global.h"
 #include "vm/builtin.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/options.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/stack.h"
 #include "vm/jit/parse.h"
 
-#include "vmcore/options.h"
-
 #if defined(ENABLE_DEBUG_FILTER)
 # include <sys/types.h>
 # include <regex.h>
-# include "threads/thread.h"
+# include "threads/thread.hpp"
 #endif
 
 
 /* global variables ***********************************************************/
 
-#if defined(ENABLE_THREADS) && !defined(NDEBUG)
-static java_object_t *show_global_lock;
+#if !defined(NDEBUG)
+static Mutex* mutex;
 #endif
 
 
@@ -81,9 +80,7 @@ bool show_init(void)
 #if defined(ENABLE_THREADS)
        /* initialize the show lock */
 
-       show_global_lock = NEW(java_object_t);
-
-       LOCK_INIT_OBJECT_LOCK(show_global_lock);
+       mutex = Mutex_new();
 #endif
 
 #if defined(ENABLE_DEBUG_FILTER)
@@ -158,7 +155,7 @@ void show_method(jitdata *jd, int stage)
           is not reentrant-able and we could not read functions printed
           at the same time. */
 
-       LOCK_MONITOR_ENTER(show_global_lock);
+       Mutex_lock(mutex);
 
 #if defined(ENABLE_INTRP)
        if (opt_intrp)
@@ -389,7 +386,7 @@ void show_method(jitdata *jd, int stage)
        }
 #endif
 
-       LOCK_MONITOR_EXIT(show_global_lock);
+       Mutex_unlock(mutex);
 
        /* finally flush the output */
 
@@ -549,6 +546,18 @@ void show_basicblock(jitdata *jd, basicblock *bptr, int stage)
                }
 #endif /* defined(ENABLE_INLINING) */
 
+#if defined(ENABLE_SSA)
+       
+               iptr = bptr->phis;
+
+               for (i = 0; i < bptr->phicount; i++, iptr++) {
+                       printf("%4d:%4d:  ", iptr->line, iptr->flags.bits >> INS_FLAG_ID_SHIFT);
+
+                       show_icmd(jd, iptr, deadcode, irstage);
+                       printf("\n");
+               }
+#endif
+
                iptr = bptr->iinstr;
 
                for (i = 0; i < bptr->icount; i++, iptr++) {
@@ -1425,6 +1434,19 @@ void show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
        case ICMD_GETEXCEPTION:
                SHOW_DST(iptr);
                break;
+#if defined(ENABLE_SSA)        
+       case ICMD_PHI:
+               printf("[ ");
+               for (i = 0; i < iptr->s1.argcount; ++i) {
+                       SHOW_VARIABLE(iptr->sx.s23.s2.iargs[i]->dst.varindex);
+               }
+               printf("] ");
+               SHOW_DST(iptr);
+               if (iptr->flags.bits & (1 << 0)) printf("used ");
+               if (iptr->flags.bits & (1 << 1)) printf("redundantAll ");
+               if (iptr->flags.bits & (1 << 2)) printf("redundantOne ");
+               break;
+#endif
        }
        fflush(stdout);
 }
index 573932273bfd0669fd6d4269d595aebf38230c87..024d2233e1d064f120c4140412ac75fab79784bf 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/show.h - showing the intermediate representation
 
-   Copyright (C) 1996-2005, 2006 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, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-
-   Changes: Edwin Steiner
-            Christian Thalinger
-            Christian Ullrich
-
-
 */
 
 
 #ifndef _SHOW_H
 #define _SHOW_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "config.h"
 #include "vm/types.h"
 
@@ -82,9 +75,13 @@ int show_filters_test_verbosecall_enter(methodinfo *m);
 int show_filters_test_verbosecall_exit(methodinfo *m);
 #endif
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _SHOW_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
index 38535c3a897ada405cecc2aae28f20f2a25f013a..b45fe94c47364f004396caf63322ce29902a5a36 100644 (file)
@@ -34,9 +34,9 @@ LIBS =
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h \
        \
-       md-asm.h
+       md-asm.h \
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = libarch.la
 
index d13339a8a8dc63c5d024de7e0d27b71d2f0ffc24..6364dbd51fd31266ccee09f31729f5f49620901f 100644 (file)
 #include "native/jni.h"
 #include "native/localref.h"
 #include "native/native.h"
+
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
+#include "vm/jit/stacktrace.hpp"
 
 #include "vm/jit/sparc64/solaris/macro_rename.h"
 
@@ -2671,9 +2671,6 @@ gen_method:
                                        superindex = super->index;
                                }
 
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -2744,16 +2741,12 @@ gen_method:
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ALD(REG_ITMP3, REG_PV, disp);
                                        
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
                                        M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
                                        M_ALD(REG_ITMP3, REG_PV, disp);
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
 
-                                       CODEGEN_CRITICAL_SECTION_END;
-
                                        /*                              } */
                                        M_CMP(REG_ITMP3, REG_ITMP2);
                                        emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
@@ -2836,9 +2829,6 @@ gen_method:
                                supervftbl = super->vftbl;
                        }
 
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (s1 == d) {
@@ -2914,14 +2904,10 @@ gen_method:
                                M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_ITMP2, REG_PV, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
                                M_CMP(REG_ITMP1, REG_ITMP2);
                                M_XCMOVULE_IMM(1, d);
@@ -3434,7 +3420,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* put env into first argument register */
 
-       disp = dseg_add_address(cd, _Jv_env);
+       disp = dseg_add_address(cd, VM_get_jnienv());
        M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
 
        /* do the native function call */
index def530822aeb785a3f430854e37586925df4014a..db4b4ba05f5bb99796fb2ca354f4896f8b909a3d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/sparc64/emit.c - SPARC code emitter functions
 
-   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.
 
 
 #include "mm/memory.h"
 
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h" /* XXX for gen_resolvebranch */
+#include "vm/builtin.h"
+#include "vm/options.h"
+
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
-#include "vm/builtin.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/replace.h"
 
-#include "vmcore/options.h"
-
 #include "vm/jit/sparc64/solaris/macro_rename.h"
 
 /* how to leaf optimization in the emitted stubs?? */
index 1144594771951d8f44736215ff77135dd490bdd8..e1cdfdb9f08de767d5931942ad77fa128b0711a5 100644 (file)
 #include "vm/jit/sparc64/md-abi.h"
 
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 
@@ -176,40 +175,6 @@ void md_icacheflush(u1 *addr, s4 nbytes)
        }
 }
 
-#if defined(ENABLE_THREADS)
-/* md_critical_section_restart ************************************************
-   Search the critical sections tree for a matching section and set
-   the NPC to the restart point, if necessary.
-
-   Reads PC and modifies NPC.
-
-******************************************************************************/
-
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       /* mcontext_t *_mc; */
-       sigcontext *ctx;
-       u1         *pc;
-       u1         *npc;
-
-       printf("ignoring md_critical_section_restart\n");
-       return;
-
-       /* again, we are getting sigcontext instead of ucontext */
-       ctx = (sigcontext *) _uc;
-       
-       pc = (u1 *) ctx->sigc_regs.tpc;
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL) {
-               log_println("md_critical_section_restart: pc=%p, npc=%p", pc, npc);
-               ctx->sigc_regs.tnpc = (ptrint) npc;
-       }
-
-}
-#endif
        
 /*
  * These are local overrides for various environment variables in Emacs.
diff --git a/src/vm/jit/sparc64/machine-instr.h b/src/vm/jit/sparc64/machine-instr.h
deleted file mode 100644 (file)
index cc07238..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-#include "toolbox/logging.h"
-
-static inline long
-__attribute__ ((unused))
-compare_and_swap (volatile long *p, long oldval, long newval)
-{
-  long ret;
-  /*dolog("compare_and_swap(%p [%d], %d, %d)", p, *p, oldval, newval);*/
-
-  __asm__ __volatile__ (
-    "mov %3,%0\n\t"
-    "casx [%4],%2,%0\n\t"
-    : "=&r"(ret), "=m"(*p) 
-    : "r"(oldval), "r"(newval), "r"(p));
-
-  /*dolog("compare_and_swap() return=%d mem=%d", ret, *p);*/
-  return ret;
-}
-
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("wmb" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
-#define MEMORY_BARRIER() __asm__ __volatile__ ( \
-               "membar 0x0F" : : : "memory" );
-
-#endif
index 4afd70d7c8e8b337cafb4412071629ef70e26c0a..cc12be598716a5abb965949cc178b629d7e566ff 100644 (file)
 
 #include "vm/jit/sparc64/md-abi.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/stack.h"
 
-#include "vmcore/descriptor.h"
-
 /* temp */
 #include "mm/memory.h"
 #include <assert.h>
diff --git a/src/vm/jit/sparc64/md-atomic.hpp b/src/vm/jit/sparc64/md-atomic.hpp
new file mode 100644 (file)
index 0000000..5539c38
--- /dev/null
@@ -0,0 +1,143 @@
+/* src/vm/jit/sparc64/atomic.hpp - SPARC64 atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+#if 0
+       // This one should be correct.
+       uint32_t result;
+
+       __asm__ __volatile__ (
+               "    mov %3,%0       \n"
+               "    cas [%4],%2,%0  \n"
+               : "=&r" (result), "=m" (*p) 
+               : "r" (oldval), "r" (newval), "r" (p));
+
+       return result;
+#else
+       return generic_compare_and_swap(p, oldval, newval);
+#endif
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       uint64_t result;
+
+       __asm__ __volatile__ (
+               "    mov %3,%0        \n"
+               "    casx [%4],%2,%0  \n"
+               : "=&r" (result), "=m" (*p) 
+               : "r" (oldval), "r" (newval), "r" (p));
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return (void*) compare_and_swap((volatile uint64_t*) p, (uint64_t) oldval, (uint64_t) newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("membar 0x0F" : : : "memory" );
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("wmb" : : : "memory");
+}
+
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       __asm__ __volatile__ ("mb" : : : "memory");
+}
+
+#endif // _MD_ATOMIC_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 e06903192b68bd7a65d8480bd3e93fe5f0e8b8bc..9cfaaeaeec73b7a0096d64ba44ba8af83e459996 100644 (file)
@@ -58,6 +58,7 @@ enum {
        /* Don't use 8 (could be a normal load offset). */
 
        TRAP_COMPILER                       = 9,
+       TRAP_COUNTDOWN                      = 10,
        TRAP_END
 };
 
index caf2d003deb8f4591850efb02b7be285e9dfcafd..ab2b30708acd7ec9b540e205b177e61767d82f33 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/sparc64/md.c - machine dependent SPARC64 functions
 
-   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.
 
@@ -34,9 +32,6 @@
 
 #include "vm/jit/sparc64/md-abi.h"
 
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/jit.h"
index 576e710c918b8b8bf324722167953d0121066f21..ff6e996af6b717558ec14b853ba312fd9532cb95 100644 (file)
 #include "vm/jit/sparc64/md-abi.h"
 
 #include "native/native.h"
+
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/methodheader.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
-#include "vm/resolve.h"
+#include "vm/jit/stacktrace.hpp"
 
 #include "vm/jit/sparc64/solaris/macro_rename.h"
 
index 81f191896fcc537fab491f57d8dae8609c441f93..7c4c802a84d1c7bc3a27784cdc854854300ba231 100644 (file)
 #include "vm/jit/sparc64/codegen.h"
 #include "vm/jit/sparc64/md-abi.h"
 
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
-#include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 
@@ -151,22 +149,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-void thread_restartcriticalsection(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       void       *critical;
-
-       _mc = &_uc->uc_mcontext;
-
-       critical = thread_checkcritical((void *) _mc->sc_pc);
-
-       if (critical)
-               _mc->sc_pc = (ptrint) critical;
-}
-#endif
-
-
 /* md_icacheflush **************************************************************
 
    Calls the system's function to flush the instruction cache.
index e692269d25bf2c6846b3dac13efe6597a0c8a94c..4ecac4876426e7fe74d17cd2ae4e1f63edb3ee48 100644 (file)
 
 #include "toolbox/logging.h"
 
-#include "vm/global.h"
 #include "vm/builtin.h"
-#include "vm/stringlocal.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/options.h"
+#include "vm/resolve.h"
+#include "vm/string.hpp"
 #include "vm/types.h"
 
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
 #include "vm/jit/abi.h"
 #include "vm/jit/cfg.h"
 #include "vm/jit/codegen-common.h"
 #endif
 #endif
 
-#include "vmcore/options.h"
-#include "vm/resolve.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
 /*#define STACK_VERBOSE*/
 
 
index eceb2db2204fd84ca3b6256b58a5a471c9d559a9..4663cc034c585a40ca81119cee09e9bc7e44f372 100644 (file)
@@ -37,7 +37,6 @@ typedef struct stackelement_t stackelement_t;
 
 #include "vm/types.h"
 
-#include "vm/exceptions.h"
 #include "vm/global.h"
 
 #include "vm/jit/jit.h"
diff --git a/src/vm/jit/stacktrace.c b/src/vm/jit/stacktrace.c
deleted file mode 100644 (file)
index 4f4765a..0000000
+++ /dev/null
@@ -1,1328 +0,0 @@
-/* src/vm/jit/stacktrace.c - machine independent stacktrace system
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "md.h"
-
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#include "vm/jit/stacktrace.h"
-
-#include "vm/global.h"                   /* required here for native includes */
-#include "native/jni.h"
-#include "native/llni.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Throwable.h"
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# include "native/include/gnu_classpath_Pointer.h"
-# include "native/include/java_lang_VMThrowable.h"
-#endif
-
-#include "threads/thread.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/array.h"
-#include "vm/builtin.h"
-#include "vm/cycles-stats.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
-#include "vm/jit/linenumbertable.h"
-#include "vm/jit/methodheader.h"
-#include "vm/jit/methodtree.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-
-
-/* global variables ***********************************************************/
-
-CYCLES_STATS_DECLARE(stacktrace_overhead        , 100, 1)
-CYCLES_STATS_DECLARE(stacktrace_fillInStackTrace, 40,  5000)
-CYCLES_STATS_DECLARE(stacktrace_get,              40,  5000)
-CYCLES_STATS_DECLARE(stacktrace_getClassContext , 40,  5000)
-CYCLES_STATS_DECLARE(stacktrace_getCurrentClass , 40,  5000)
-CYCLES_STATS_DECLARE(stacktrace_get_stack       , 40,  10000)
-
-
-/* stacktrace_stackframeinfo_add ***********************************************
-
-   Fills a stackframe info structure with the given or calculated
-   values and adds it to the chain.
-
-*******************************************************************************/
-
-void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra, u1 *xpc)
-{
-       stackframeinfo_t *currentsfi;
-       codeinfo         *code;
-#if defined(ENABLE_JIT)
-       s4                 framesize;
-#endif
-
-       /* Get current stackframe info. */
-
-       currentsfi = threads_get_current_stackframeinfo();
-
-       /* sometimes we don't have pv handy (e.g. in asmpart.S:
-       L_asm_call_jit_compiler_exception or in the interpreter). */
-
-       if (pv == NULL) {
-#if defined(ENABLE_INTRP)
-               if (opt_intrp)
-                       pv = methodtree_find(ra);
-               else
-#endif
-                       {
-#if defined(ENABLE_JIT)
-# if defined(__SPARC_64__)
-                               pv = md_get_pv_from_stackframe(sp);
-# else
-                               pv = md_codegen_get_pv_from_pc(ra);
-# endif
-#endif
-                       }
-       }
-
-       /* Get codeinfo pointer for the parent Java method. */
-
-       code = code_get_codeinfo_for_pv(pv);
-
-       /* XXX */
-       /*      assert(m != NULL); */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-       /* When using the interpreter, we pass RA to the function. */
-
-       if (!opt_intrp) {
-# endif
-# if defined(__I386__) || defined(__X86_64__) || defined(__S390__) || defined(__M68K__)
-               /* On i386 and x86_64 we always have to get the return address
-                  from the stack. */
-               /* m68k has return address on stack always */
-               /* On S390 we use REG_RA as REG_ITMP3, so we have always to get
-                  the RA from stack. */
-
-               framesize = *((u4 *) (pv + FrameSize));
-
-               ra = md_stacktrace_get_returnaddress(sp, framesize);
-# else
-               /* If the method is a non-leaf function, we need to get the
-                  return address from the stack.  For leaf functions the
-                  return address is set correctly.  This makes the assembler
-                  and the signal handler code simpler.  The code is NULL is
-                  the asm_vm_call_method special case. */
-
-               if ((code == NULL) || !code_is_leafmethod(code)) {
-                       framesize = *((u4 *) (pv + FrameSize));
-
-                       ra = md_stacktrace_get_returnaddress(sp, framesize);
-               }
-# endif
-# if defined(ENABLE_INTRP)
-       }
-# endif
-#endif
-
-       /* Calculate XPC when not given.  The XPC is then the return
-          address of the current method minus 1 because the RA points to
-          the instruction after the call instruction.  This is required
-          e.g. for method stubs. */
-
-       if (xpc == NULL) {
-               xpc = (void *) (((intptr_t) ra) - 1);
-       }
-
-       /* Fill new stackframeinfo structure. */
-
-       sfi->prev = currentsfi;
-       sfi->code = code;
-       sfi->pv   = pv;
-       sfi->sp   = sp;
-       sfi->ra   = ra;
-       sfi->xpc  = xpc;
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackFrameInfo) {
-               log_start();
-               log_print("[stackframeinfo add   : sfi=%p, method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=",
-                                 sfi, sfi->code->m, sfi->pv, sfi->sp, sfi->ra, sfi->xpc);
-               method_print(sfi->code->m);
-               log_print("]");
-               log_finish();
-       }
-#endif
-
-       /* Store new stackframeinfo pointer. */
-
-       threads_set_current_stackframeinfo(sfi);
-
-       /* set the native world flag for the current thread */
-       /* ATTENTION: This flag tells the GC how to treat this thread in case of
-          a collection. Set this flag _after_ a valid stackframe info was set. */
-
-       THREAD_NATIVEWORLD_ENTER;
-}
-
-
-/* stacktrace_stackframeinfo_remove ********************************************
-
-   Remove the given stackframeinfo from the chain in the current
-   thread.
-
-*******************************************************************************/
-
-void stacktrace_stackframeinfo_remove(stackframeinfo_t *sfi)
-{
-       /* Clear the native world flag for the current thread. */
-       /* ATTENTION: Clear this flag _before_ removing the stackframe info. */
-
-       THREAD_NATIVEWORLD_EXIT;
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackFrameInfo) {
-               log_start();
-               log_print("[stackframeinfo remove: sfi=%p, method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=",
-                                 sfi, sfi->code->m, sfi->pv, sfi->sp, sfi->ra, sfi->xpc);
-               method_print(sfi->code->m);
-               log_print("]");
-               log_finish();
-       }
-#endif
-
-       /* Set previous stackframe info. */
-
-       threads_set_current_stackframeinfo(sfi->prev);
-}
-
-
-/* stacktrace_stackframeinfo_fill **********************************************
-
-   Fill the temporary stackframeinfo structure with the values given
-   in sfi.
-
-   IN:
-       tmpsfi ... temporary stackframeinfo
-       sfi ...... stackframeinfo to be used in the next iteration
-
-*******************************************************************************/
-
-static inline void stacktrace_stackframeinfo_fill(stackframeinfo_t *tmpsfi, stackframeinfo_t *sfi)
-{
-       /* Sanity checks. */
-
-       assert(tmpsfi != NULL);
-       assert(sfi != NULL);
-
-       /* Fill the temporary stackframeinfo. */
-
-       tmpsfi->code = sfi->code;
-       tmpsfi->pv   = sfi->pv;
-       tmpsfi->sp   = sfi->sp;
-       tmpsfi->ra   = sfi->ra;
-       tmpsfi->xpc  = sfi->xpc;
-
-       /* Set the previous stackframe info of the temporary one to the
-          next in the chain. */
-
-       tmpsfi->prev = sfi->prev;
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackTrace)
-               log_println("[stacktrace fill]");
-#endif
-}
-
-
-/* stacktrace_stackframeinfo_next **********************************************
-
-   Walk the stack (or the stackframeinfo-chain) to the next method and
-   return the new stackframe values in the temporary stackframeinfo
-   passed.
-
-   ATTENTION: This function does NOT skip builtin methods!
-
-   IN:
-       tmpsfi ... temporary stackframeinfo of current method
-
-*******************************************************************************/
-
-static inline void stacktrace_stackframeinfo_next(stackframeinfo_t *tmpsfi)
-{
-       codeinfo         *code;
-       void             *pv;
-       void             *sp;
-       void             *ra;
-       void             *xpc;
-       uint32_t          framesize;
-       stackframeinfo_t *prevsfi;
-
-       /* Sanity check. */
-
-       assert(tmpsfi != NULL);
-
-       /* Get values from the stackframeinfo. */
-
-       code = tmpsfi->code;
-       pv   = tmpsfi->pv;
-       sp   = tmpsfi->sp;
-       ra   = tmpsfi->ra;
-       xpc  = tmpsfi->xpc;
-       /* Get the current stack frame size. */
-
-       framesize = *((uint32_t *) (((intptr_t) pv) + FrameSize));
-
-       /* Get the RA of the current stack frame (RA to the parent Java
-          method) if the current method is a non-leaf method.  Otherwise
-          the value in the stackframeinfo is correct (from the signal
-          handler). */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-       if (opt_intrp)
-               ra = intrp_md_stacktrace_get_returnaddress(sp, framesize);
-       else
-# endif
-               {
-                       if (!code_is_leafmethod(code))
-                               ra = md_stacktrace_get_returnaddress(sp, framesize);
-               }
-#else
-       ra = intrp_md_stacktrace_get_returnaddress(sp, framesize);
-#endif
-
-       /* Get the PV for the parent Java method. */
-
-#if defined(ENABLE_INTRP)
-       if (opt_intrp)
-               pv = methodtree_find(ra);
-       else
-#endif
-               {
-#if defined(ENABLE_JIT)
-# if defined(__SPARC_64__)
-                       sp = md_get_framepointer(sp);
-                       pv = md_get_pv_from_stackframe(sp);
-# else
-                       pv = md_codegen_get_pv_from_pc(ra);
-# endif
-#endif
-               }
-
-       /* Get the codeinfo pointer for the parent Java method. */
-
-       code = code_get_codeinfo_for_pv(pv);
-
-       /* Calculate the SP for the parent Java method. */
-
-#if defined(ENABLE_INTRP)
-       if (opt_intrp)
-               sp = *(u1 **) (sp - framesize);
-       else
-#endif
-               {
-#if defined(__I386__) || defined (__X86_64__) || defined (__M68K__)
-                       sp = (void *) (((intptr_t) sp) + framesize + SIZEOF_VOID_P);
-#elif defined(__SPARC_64__)
-                       /* already has the new sp */
-#else
-                       sp = (void *) (((intptr_t) sp) + framesize);
-#endif
-               }
-
-       /* If the new codeinfo pointer is NULL we reached a
-          asm_vm_call_method function.  In this case we get the next
-          values from the previous stackframeinfo in the chain.
-          Otherwise the new values have been calculated before. */
-
-       if (code == NULL) {
-               prevsfi = tmpsfi->prev;
-
-               /* If the previous stackframeinfo in the chain is NULL we
-                  reached the top of the stacktrace.  We set code and prev to
-                  NULL to mark the end, which is checked in
-                  stacktrace_stackframeinfo_end_check. */
-
-               if (prevsfi == NULL) {
-                       tmpsfi->code = NULL;
-                       tmpsfi->prev = NULL;
-                       return;
-               }
-
-               /* Fill the temporary stackframeinfo with the new values. */
-
-               stacktrace_stackframeinfo_fill(tmpsfi, prevsfi);
-       }
-       else {
-               /* Store the new values in the stackframeinfo.  NOTE: We
-                  subtract 1 from the RA to get the XPC, because the RA
-                  points to the instruction after the call instruction. */
-
-               tmpsfi->code = code;
-               tmpsfi->pv   = pv;
-               tmpsfi->sp   = sp;
-               tmpsfi->ra   = ra;
-               tmpsfi->xpc  = (void *) (((intptr_t) ra) - 1);
-       }
-
-#if !defined(NDEBUG)
-       /* Print current method information. */
-
-       if (opt_DebugStackTrace) {
-               log_start();
-               log_print("[stacktrace: method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=",
-                                 tmpsfi->code->m, tmpsfi->pv, tmpsfi->sp, tmpsfi->ra,
-                                 tmpsfi->xpc);
-               method_print(tmpsfi->code->m);
-               log_print("]");
-               log_finish();
-       }
-#endif
-}
-
-
-/* stacktrace_stackframeinfo_end_check *****************************************
-
-   Check if we reached the end of the stacktrace.
-
-   IN:
-       tmpsfi ... temporary stackframeinfo of current method
-
-   RETURN:
-       true .... the end is reached
-          false ... the end is not reached
-
-*******************************************************************************/
-
-static inline bool stacktrace_stackframeinfo_end_check(stackframeinfo_t *tmpsfi)
-{
-       /* Sanity check. */
-
-       assert(tmpsfi != NULL);
-
-       if ((tmpsfi->code == NULL) && (tmpsfi->prev == NULL)) {
-#if !defined(NDEBUG)
-               if (opt_DebugStackTrace)
-                       log_println("[stacktrace stop]");
-#endif
-
-               return true;
-       }
-
-       return false;
-}
-
-
-/* stacktrace_depth ************************************************************
-
-   Calculates and returns the depth of the current stacktrace.
-
-   IN:
-       sfi ... stackframeinfo where to start the stacktrace
-
-   RETURN:
-       depth of the stacktrace
-
-*******************************************************************************/
-
-static int stacktrace_depth(stackframeinfo_t *sfi)
-{
-       stackframeinfo_t  tmpsfi;
-       int               depth;
-       methodinfo       *m;
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackTrace)
-               log_println("[stacktrace_depth]");
-#endif
-
-       /* XXX This is not correct, but a workaround for threads-dump for
-          now. */
-/*     assert(sfi != NULL); */
-       if (sfi == NULL)
-               return 0;
-
-       /* Iterate over all stackframes. */
-
-       depth = 0;
-
-       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-               /* Get methodinfo. */
-
-               m = tmpsfi.code->m;
-
-               /* Skip builtin methods. */
-
-               if (m->flags & ACC_METHOD_BUILTIN)
-                       continue;
-
-               depth++;
-       }
-
-       return depth;
-}
-
-
-/* stacktrace_get **************************************************************
-
-   Builds and returns a stacktrace starting from the given stackframe
-   info and returns the stacktrace structure wrapped in a Java
-   byte-array to not confuse the GC.
-
-   IN:
-       sfi ... stackframe info to start stacktrace from
-
-   RETURN:
-       stacktrace as Java byte-array
-
-*******************************************************************************/
-
-java_handle_bytearray_t *stacktrace_get(stackframeinfo_t *sfi)
-{
-       stackframeinfo_t         tmpsfi;
-       int                      depth;
-       java_handle_bytearray_t *ba;
-       int32_t                  ba_size;
-       stacktrace_t            *st;
-       stacktrace_entry_t      *ste;
-       methodinfo              *m;
-       bool                     skip_fillInStackTrace;
-       bool                     skip_init;
-
-       CYCLES_STATS_DECLARE_AND_START_WITH_OVERHEAD
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackTrace)
-               log_println("[stacktrace_get]");
-#endif
-
-       skip_fillInStackTrace = true;
-       skip_init             = true;
-
-       depth = stacktrace_depth(sfi);
-
-       if (depth == 0)
-               return NULL;
-
-       /* Allocate memory from the GC heap and copy the stacktrace
-          buffer. */
-       /* ATTENTION: Use a Java byte-array for this to not confuse the
-          GC. */
-       /* FIXME: We waste some memory here as we skip some entries
-          later. */
-
-       ba_size = sizeof(stacktrace_t) + sizeof(stacktrace_entry_t) * depth;
-
-       ba = builtin_newarray_byte(ba_size);
-
-       if (ba == NULL)
-               goto return_NULL;
-
-       /* Get a stacktrace entry pointer. */
-       /* ATTENTION: We need a critical section here because we use the
-          byte-array data pointer directly. */
-
-       LLNI_CRITICAL_START;
-
-       st = (stacktrace_t *) LLNI_array_data(ba);
-
-       ste = st->entries;
-
-       /* Iterate over the whole stack. */
-
-       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-               /* Get the methodinfo. */
-
-               m = tmpsfi.code->m;
-
-               /* Skip builtin methods. */
-
-               if (m->flags & ACC_METHOD_BUILTIN)
-                       continue;
-
-               /* This logic is taken from
-                  hotspot/src/share/vm/classfile/javaClasses.cpp
-                  (java_lang_Throwable::fill_in_stack_trace). */
-
-               if (skip_fillInStackTrace == true) {
-                       /* Check "fillInStackTrace" only once, so we negate the
-                          flag after the first time check. */
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-                       /* For GNU Classpath we also need to skip
-                          VMThrowable.fillInStackTrace(). */
-
-                       if ((m->clazz == class_java_lang_VMThrowable) &&
-                               (m->name  == utf_fillInStackTrace))
-                               continue;
-#endif
-
-                       skip_fillInStackTrace = false;
-
-                       if (m->name == utf_fillInStackTrace)
-                               continue;
-               }
-
-               /* Skip <init> methods of the exceptions klass.  If there is
-                  <init> methods that belongs to a superclass of the
-                  exception we are going to skipping them in stack trace. */
-
-               if (skip_init == true) {
-                       if ((m->name == utf_init) &&
-                               (class_issubclass(m->clazz, class_java_lang_Throwable))) {
-                               continue;
-                       }
-                       else {
-                               /* If no "Throwable.init()" method found, we stop
-                                  checking it next time. */
-
-                               skip_init = false;
-                       }
-               }
-
-               /* Store the stacktrace entry and increment the pointer. */
-
-               ste->code = tmpsfi.code;
-               ste->pc   = tmpsfi.xpc;
-
-               ste++;
-       }
-
-       /* Store the number of entries in the stacktrace structure. */
-
-       st->length = ste - st->entries;
-
-       LLNI_CRITICAL_END;
-
-       /* release dump memory */
-
-/*     dump_release(dumpsize); */
-
-       CYCLES_STATS_END_WITH_OVERHEAD(stacktrace_fillInStackTrace,
-                                                                  stacktrace_overhead)
-       return ba;
-
-return_NULL:
-/*     dump_release(dumpsize); */
-
-       CYCLES_STATS_END_WITH_OVERHEAD(stacktrace_fillInStackTrace,
-                                                                  stacktrace_overhead)
-
-       return NULL;
-}
-
-
-/* stacktrace_get_current ******************************************************
-
-   Builds and returns a stacktrace from the current thread and returns
-   the stacktrace structure wrapped in a Java byte-array to not
-   confuse the GC.
-
-   RETURN:
-       stacktrace as Java byte-array
-
-*******************************************************************************/
-
-java_handle_bytearray_t *stacktrace_get_current(void)
-{
-       stackframeinfo_t        *sfi;
-       java_handle_bytearray_t *ba;
-
-       sfi = threads_get_current_stackframeinfo();
-       ba  = stacktrace_get(sfi);
-
-       return ba;
-}
-
-
-/* stacktrace_get_caller_class *************************************************
-
-   Get the class on the stack at the given depth.  This function skips
-   various special classes or methods.
-
-   ARGUMENTS:
-       depth ... depth to get caller class of
-
-   RETURN:
-       caller class
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-classinfo *stacktrace_get_caller_class(int depth)
-{
-       stackframeinfo_t *sfi;
-       stackframeinfo_t  tmpsfi;
-       methodinfo       *m;
-       classinfo        *c;
-       int               i;
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackTrace)
-               log_println("[stacktrace_get_caller_class]");
-#endif
-
-       /* Get the stackframeinfo of the current thread. */
-
-       sfi = threads_get_current_stackframeinfo();
-
-       /* Iterate over the whole stack until we reached the requested
-          depth. */
-
-       i = 0;
-
-       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-
-               m = tmpsfi.code->m;
-               c = m->clazz;
-
-               /* Skip builtin methods. */
-
-               if (m->flags & ACC_METHOD_BUILTIN)
-                       continue;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-               /* NOTE: See hotspot/src/share/vm/runtime/vframe.cpp
-                  (vframeStreamCommon::security_get_caller_frame). */
-
-               /* This is java.lang.reflect.Method.invoke(), skip it. */
-
-               if (m == method_java_lang_reflect_Method_invoke)
-                       continue;
-
-               /* This is an auxiliary frame, skip it. */
-
-               if (class_issubclass(c, class_sun_reflect_MagicAccessorImpl))
-                       continue;
-#endif
-
-               /* We reached the requested depth. */
-
-               if (i >= depth)
-                       return c;
-
-               i++;
-       }
-
-       return NULL;
-}
-#endif
-
-
-/* stacktrace_first_nonnull_classloader ****************************************
-
-   Returns the first non-null (user-defined) classloader on the stack.
-   If none is found NULL is returned.
-
-   RETURN:
-       classloader
-
-*******************************************************************************/
-
-classloader_t *stacktrace_first_nonnull_classloader(void)
-{
-       stackframeinfo_t *sfi;
-       stackframeinfo_t  tmpsfi;
-       methodinfo       *m;
-       classloader_t    *cl;
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackTrace)
-               log_println("[stacktrace_first_nonnull_classloader]");
-#endif
-
-       /* Get the stackframeinfo of the current thread. */
-
-       sfi = threads_get_current_stackframeinfo();
-
-       /* Iterate over the whole stack. */
-
-       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-
-               m  = tmpsfi.code->m;
-               cl = class_get_classloader(m->clazz);
-
-               if (cl != NULL)
-                       return cl;
-       }
-
-       return NULL;
-}
-
-
-/* stacktrace_getClassContext **************************************************
-
-   Creates a Class context array.
-
-   RETURN VALUE:
-      the array of java.lang.Class objects, or
-         NULL if an exception has been thrown
-
-*******************************************************************************/
-
-java_handle_objectarray_t *stacktrace_getClassContext(void)
-{
-       stackframeinfo_t           *sfi;
-       stackframeinfo_t            tmpsfi;
-       int                         depth;
-       java_handle_objectarray_t  *oa;
-       java_object_t             **data;
-       int                         i;
-       methodinfo                 *m;
-
-       CYCLES_STATS_DECLARE_AND_START
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackTrace)
-               log_println("[stacktrace_getClassContext]");
-#endif
-
-       sfi = threads_get_current_stackframeinfo();
-
-       /* Get the depth of the current stack. */
-
-       depth = stacktrace_depth(sfi);
-
-       /* The first stackframe corresponds to the method whose
-          implementation calls this native function.  We remove that
-          entry. */
-
-       depth--;
-       stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-       stacktrace_stackframeinfo_next(&tmpsfi);
-
-       /* Allocate the Class array. */
-
-       oa = builtin_anewarray(depth, class_java_lang_Class);
-
-       if (oa == NULL) {
-               CYCLES_STATS_END(stacktrace_getClassContext);
-
-               return NULL;
-       }
-
-       /* Fill the Class array from the stacktrace list. */
-
-       LLNI_CRITICAL_START;
-
-       data = LLNI_array_data(oa);
-
-       /* Iterate over the whole stack. */
-
-       i = 0;
-
-       for (;
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-               /* Get methodinfo. */
-
-               m = tmpsfi.code->m;
-
-               /* Skip builtin methods. */
-
-               if (m->flags & ACC_METHOD_BUILTIN)
-                       continue;
-
-               /* Store the class in the array. */
-
-               data[i] = (java_object_t *) m->clazz;
-
-               i++;
-       }
-
-       LLNI_CRITICAL_END;
-
-       CYCLES_STATS_END(stacktrace_getClassContext)
-
-       return oa;
-}
-
-
-/* stacktrace_getCurrentClass **************************************************
-
-   Find the current class by walking the stack trace.
-
-   Quote from the JNI documentation:
-        
-   In the Java 2 Platform, FindClass locates the class loader
-   associated with the current native method.  If the native code
-   belongs to a system class, no class loader will be
-   involved. Otherwise, the proper class loader will be invoked to
-   load and link the named class. When FindClass is called through the
-   Invocation Interface, there is no current native method or its
-   associated class loader. In that case, the result of
-   ClassLoader.getBaseClassLoader is used."
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-classinfo *stacktrace_get_current_class(void)
-{
-       stackframeinfo_t *sfi;
-       stackframeinfo_t  tmpsfi;
-       methodinfo       *m;
-
-       CYCLES_STATS_DECLARE_AND_START;
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackTrace)
-               log_println("[stacktrace_get_current_class]");
-#endif
-
-       /* Get the stackframeinfo of the current thread. */
-
-       sfi = threads_get_current_stackframeinfo();
-
-       /* If the stackframeinfo is NULL then FindClass is called through
-          the Invocation Interface and we return NULL */
-
-       if (sfi == NULL) {
-               CYCLES_STATS_END(stacktrace_getCurrentClass);
-
-               return NULL;
-       }
-
-       /* Iterate over the whole stack. */
-
-       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-               /* Get the methodinfo. */
-
-               m = tmpsfi.code->m;
-
-               if (m->clazz == class_java_security_PrivilegedAction) {
-                       CYCLES_STATS_END(stacktrace_getCurrentClass);
-
-                       return NULL;
-               }
-
-               if (m->clazz != NULL) {
-                       CYCLES_STATS_END(stacktrace_getCurrentClass);
-
-                       return m->clazz;
-               }
-       }
-
-       /* No Java method found on the stack. */
-
-       CYCLES_STATS_END(stacktrace_getCurrentClass);
-
-       return NULL;
-}
-#endif /* ENABLE_JAVASE */
-
-
-/* stacktrace_get_stack ********************************************************
-
-   Create a 2-dimensional array for java.security.VMAccessControler.
-
-   RETURN VALUE:
-      the arrary, or
-         NULL if an exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-java_handle_objectarray_t *stacktrace_get_stack(void)
-{
-       stackframeinfo_t          *sfi;
-       stackframeinfo_t           tmpsfi;
-       int                        depth;
-       java_handle_objectarray_t *oa;
-       java_handle_objectarray_t *classes;
-       java_handle_objectarray_t *methodnames;
-       methodinfo                *m;
-       java_handle_t             *string;
-       int                        i;
-
-       CYCLES_STATS_DECLARE_AND_START
-
-#if !defined(NDEBUG)
-       if (opt_DebugStackTrace)
-               log_println("[stacktrace_get_stack]");
-#endif
-
-       /* Get the stackframeinfo of the current thread. */
-
-       sfi = threads_get_current_stackframeinfo();
-
-       /* Get the depth of the current stack. */
-
-       depth = stacktrace_depth(sfi);
-
-       if (depth == 0)
-               return NULL;
-
-       /* Allocate the required arrays. */
-
-       oa = builtin_anewarray(2, arrayclass_java_lang_Object);
-
-       if (oa == NULL)
-               goto return_NULL;
-
-       classes = builtin_anewarray(depth, class_java_lang_Class);
-
-       if (classes == NULL)
-               goto return_NULL;
-
-       methodnames = builtin_anewarray(depth, class_java_lang_String);
-
-       if (methodnames == NULL)
-               goto return_NULL;
-
-       /* Set up the 2-dimensional array. */
-
-       array_objectarray_element_set(oa, 0, (java_handle_t *) classes);
-       array_objectarray_element_set(oa, 1, (java_handle_t *) methodnames);
-
-       /* Iterate over the whole stack. */
-       /* TODO We should use a critical section here to speed things
-          up. */
-
-       i = 0;
-
-       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-               /* Get the methodinfo. */
-
-               m = tmpsfi.code->m;
-
-               /* Skip builtin methods. */
-
-               if (m->flags & ACC_METHOD_BUILTIN)
-                       continue;
-
-               /* Store the class in the array. */
-               /* NOTE: We use a LLNI-macro here, because a classinfo is not
-                  a handle. */
-
-               LLNI_array_direct(classes, i) = (java_object_t *) m->clazz;
-
-               /* Store the name in the array. */
-
-               string = javastring_new(m->name);
-
-               if (string == NULL)
-                       goto return_NULL;
-
-               array_objectarray_element_set(methodnames, i, string);
-
-               i++;
-       }
-
-       CYCLES_STATS_END(stacktrace_get_stack)
-
-       return oa;
-
-return_NULL:
-       CYCLES_STATS_END(stacktrace_get_stack)
-
-       return NULL;
-}
-#endif
-
-
-/* stacktrace_print_entry ****************************************************
-
-   Print line for a stacktrace entry.
-
-   ARGUMENTS:
-       m ............ methodinfo of the entry
-       linenumber ... linenumber of the entry
-
-*******************************************************************************/
-
-static void stacktrace_print_entry(methodinfo *m, int32_t linenumber)
-{
-       /* Sanity check. */
-
-       assert(m != NULL);
-
-       printf("\tat ");
-
-       if (m->flags & ACC_METHOD_BUILTIN)
-               printf("NULL");
-       else
-               utf_display_printable_ascii_classname(m->clazz->name);
-
-       printf(".");
-       utf_display_printable_ascii(m->name);
-       utf_display_printable_ascii(m->descriptor);
-
-       if (m->flags & ACC_NATIVE) {
-               puts("(Native Method)");
-       }
-       else {
-               if (m->flags & ACC_METHOD_BUILTIN) {
-                       puts("(builtin)");
-               }
-               else {
-                       printf("(");
-                       utf_display_printable_ascii(m->clazz->sourcefile);
-                       printf(":%d)\n", linenumber);
-               }
-       }
-
-       fflush(stdout);
-}
-
-
-/* stacktrace_print ************************************************************
-
-   Print the given stacktrace with CACAO intern methods only (no Java
-   code required).
-
-   This method is used by stacktrace_dump_trace and
-   builtin_trace_exception.
-
-   IN:
-       st ... stacktrace to print
-
-*******************************************************************************/
-
-void stacktrace_print(stacktrace_t *st)
-{
-       stacktrace_entry_t *ste;
-       methodinfo         *m;
-       int32_t             linenumber;
-       int                 i;
-
-       ste = &(st->entries[0]);
-
-       for (i = 0; i < st->length; i++, ste++) {
-               m = ste->code->m;
-
-               /* Get the line number. */
-
-               linenumber = linenumbertable_linenumber_for_pc(&m, ste->code, ste->pc);
-
-               stacktrace_print_entry(m, linenumber);
-       }
-}
-
-
-/* stacktrace_print_current ****************************************************
-
-   Print the current stacktrace of the current thread.
-
-   NOTE: This function prints all frames of the stacktrace and does
-   not skip frames like stacktrace_get.
-
-*******************************************************************************/
-
-void stacktrace_print_current(void)
-{
-       stackframeinfo_t *sfi;
-       stackframeinfo_t  tmpsfi;
-       codeinfo         *code;
-       methodinfo       *m;
-       int32_t           linenumber;
-
-       sfi = threads_get_current_stackframeinfo();
-
-       if (sfi == NULL) {
-               puts("\t<<No stacktrace available>>");
-               fflush(stdout);
-               return;
-       }
-
-       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-               /* Get the methodinfo. */
-
-               code = tmpsfi.code;
-               m    = code->m;
-
-               /* Get the line number. */
-
-               linenumber = linenumbertable_linenumber_for_pc(&m, code, tmpsfi.xpc);
-
-               stacktrace_print_entry(m, linenumber);
-       }
-}
-
-
-/* stacktrace_print_of_thread **************************************************
-
-   Print the current stacktrace of the given thread.
-
-   ARGUMENTS:
-       t ... thread
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void stacktrace_print_of_thread(threadobject *t)
-{
-       stackframeinfo_t *sfi;
-       stackframeinfo_t  tmpsfi;
-       codeinfo         *code;
-       methodinfo       *m;
-       int32_t           linenumber;
-
-       /* Build a stacktrace for the passed thread. */
-
-       sfi = t->_stackframeinfo;
-       
-       if (sfi == NULL) {
-               puts("\t<<No stacktrace available>>");
-               fflush(stdout);
-               return;
-       }
-
-       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
-                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
-                stacktrace_stackframeinfo_next(&tmpsfi)) {
-               /* Get the methodinfo. */
-
-               code = tmpsfi.code;
-               m    = code->m;
-
-               /* Get the line number. */
-
-               linenumber = linenumbertable_linenumber_for_pc(&m, code, tmpsfi.xpc);
-
-               stacktrace_print_entry(m, linenumber);
-       }
-}
-#endif
-
-
-/* stacktrace_print_exception **************************************************
-
-   Print the stacktrace of a given exception (more or less a wrapper
-   to stacktrace_print).
-
-   IN:
-       h ... handle of exception to print
-
-*******************************************************************************/
-
-void stacktrace_print_exception(java_handle_t *h)
-{
-       java_lang_Throwable     *o;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_VMThrowable   *vmt;
-#endif
-
-       java_lang_Object        *backtrace;
-       java_handle_bytearray_t *ba;
-       stacktrace_t            *st;
-
-       o = (java_lang_Throwable *) h;
-
-       if (o == NULL)
-               return;
-
-       /* now print the stacktrace */
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       LLNI_field_get_ref(o,   vmState, vmt);
-       LLNI_field_get_ref(vmt, vmdata,  backtrace);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       LLNI_field_get_ref(o, backtrace, backtrace);
-
-#else
-# error unknown classpath configuration
-#endif
-
-       ba = (java_handle_bytearray_t *) backtrace;
-
-       /* Sanity check. */
-
-       assert(ba != NULL);
-
-       /* We need a critical section here as we use the byte-array data
-          pointer directly. */
-
-       LLNI_CRITICAL_START;
-       
-       st = (stacktrace_t *) LLNI_array_data(ba);
-
-       stacktrace_print(st);
-
-       LLNI_CRITICAL_END;
-}
-
-
-#if defined(ENABLE_CYCLES_STATS)
-void stacktrace_print_cycles_stats(FILE *file)
-{
-       CYCLES_STATS_PRINT_OVERHEAD(stacktrace_overhead, file);
-       CYCLES_STATS_PRINT(stacktrace_get,               file);
-       CYCLES_STATS_PRINT(stacktrace_getClassContext ,  file);
-       CYCLES_STATS_PRINT(stacktrace_getCurrentClass ,  file);
-       CYCLES_STATS_PRINT(stacktrace_get_stack,         file);
-}
-#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/jit/stacktrace.cpp b/src/vm/jit/stacktrace.cpp
new file mode 100644 (file)
index 0000000..d58427a
--- /dev/null
@@ -0,0 +1,1314 @@
+/* src/vm/jit/stacktrace.cpp - machine independent stacktrace system
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "md.h"
+
+#include "mm/gc.hpp"
+#include "mm/memory.h"
+
+#include "vm/jit/stacktrace.hpp"
+
+#include "vm/global.h"                   /* required here for native includes */
+#include "native/jni.h"
+#include "native/llni.h"
+
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/array.h"
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/cycles-stats.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/loader.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/codegen-common.h"
+#include "vm/jit/linenumbertable.h"
+#include "vm/jit/methodheader.h"
+#include "vm/jit/methodtree.h"
+
+
+// FIXME Use C-linkage for now.
+extern "C" {
+
+/* global variables ***********************************************************/
+
+CYCLES_STATS_DECLARE(stacktrace_overhead        , 100, 1)
+CYCLES_STATS_DECLARE(stacktrace_fillInStackTrace, 40,  5000)
+CYCLES_STATS_DECLARE(stacktrace_get,              40,  5000)
+CYCLES_STATS_DECLARE(stacktrace_getClassContext , 40,  5000)
+CYCLES_STATS_DECLARE(stacktrace_getCurrentClass , 40,  5000)
+CYCLES_STATS_DECLARE(stacktrace_get_stack       , 40,  10000)
+
+
+/* stacktrace_stackframeinfo_add ***********************************************
+
+   Fills a stackframe info structure with the given or calculated
+   values and adds it to the chain.
+
+*******************************************************************************/
+
+void stacktrace_stackframeinfo_add(stackframeinfo_t* sfi, void* pv, void* sp, void* ra, void* xpc)
+{
+       stackframeinfo_t *currentsfi;
+       codeinfo         *code;
+#if defined(ENABLE_JIT)
+       s4                 framesize;
+#endif
+
+       /* Get current stackframe info. */
+
+       currentsfi = threads_get_current_stackframeinfo();
+
+       /* sometimes we don't have pv handy (e.g. in asmpart.S:
+       L_asm_call_jit_compiler_exception or in the interpreter). */
+
+       if (pv == NULL) {
+#if defined(ENABLE_INTRP)
+               if (opt_intrp)
+                       pv = methodtree_find(ra);
+               else
+#endif
+                       {
+#if defined(ENABLE_JIT)
+# if defined(__SPARC_64__)
+                               pv = md_get_pv_from_stackframe(sp);
+# else
+                               pv = md_codegen_get_pv_from_pc(ra);
+# endif
+#endif
+                       }
+       }
+
+       /* Get codeinfo pointer for the parent Java method. */
+
+       code = code_get_codeinfo_for_pv(pv);
+
+       /* XXX */
+       /*      assert(m != NULL); */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       /* When using the interpreter, we pass RA to the function. */
+
+       if (!opt_intrp) {
+# endif
+# if defined(__I386__) || defined(__X86_64__) || defined(__S390__) || defined(__M68K__)
+               /* On i386 and x86_64 we always have to get the return address
+                  from the stack. */
+               /* m68k has return address on stack always */
+               /* On S390 we use REG_RA as REG_ITMP3, so we have always to get
+                  the RA from stack. */
+
+               framesize = *((u4 *) (((uintptr_t) pv) + FrameSize));
+
+               ra = md_stacktrace_get_returnaddress(sp, framesize);
+# else
+               /* If the method is a non-leaf function, we need to get the
+                  return address from the stack.  For leaf functions the
+                  return address is set correctly.  This makes the assembler
+                  and the signal handler code simpler.  The code is NULL is
+                  the asm_vm_call_method special case. */
+
+               if ((code == NULL) || !code_is_leafmethod(code)) {
+                       framesize = *((u4 *) (((uintptr_t) pv) + FrameSize));
+
+                       ra = md_stacktrace_get_returnaddress(sp, framesize);
+               }
+# endif
+# if defined(ENABLE_INTRP)
+       }
+# endif
+#endif
+
+       /* Calculate XPC when not given.  The XPC is then the return
+          address of the current method minus 1 because the RA points to
+          the instruction after the call instruction.  This is required
+          e.g. for method stubs. */
+
+       if (xpc == NULL) {
+               xpc = (void *) (((intptr_t) ra) - 1);
+       }
+
+       /* Fill new stackframeinfo structure. */
+
+       sfi->prev = currentsfi;
+       sfi->code = code;
+       sfi->pv   = pv;
+       sfi->sp   = sp;
+       sfi->ra   = ra;
+       sfi->xpc  = xpc;
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackFrameInfo) {
+               log_start();
+               log_print("[stackframeinfo add   : sfi=%p, method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=",
+                                 sfi, sfi->code->m, sfi->pv, sfi->sp, sfi->ra, sfi->xpc);
+               method_print(sfi->code->m);
+               log_print("]");
+               log_finish();
+       }
+#endif
+
+       /* Store new stackframeinfo pointer. */
+
+       threads_set_current_stackframeinfo(sfi);
+
+       /* set the native world flag for the current thread */
+       /* ATTENTION: This flag tells the GC how to treat this thread in case of
+          a collection. Set this flag _after_ a valid stackframe info was set. */
+
+       THREAD_NATIVEWORLD_ENTER;
+}
+
+
+/* stacktrace_stackframeinfo_remove ********************************************
+
+   Remove the given stackframeinfo from the chain in the current
+   thread.
+
+*******************************************************************************/
+
+void stacktrace_stackframeinfo_remove(stackframeinfo_t *sfi)
+{
+       /* Clear the native world flag for the current thread. */
+       /* ATTENTION: Clear this flag _before_ removing the stackframe info. */
+
+       THREAD_NATIVEWORLD_EXIT;
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackFrameInfo) {
+               log_start();
+               log_print("[stackframeinfo remove: sfi=%p, method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=",
+                                 sfi, sfi->code->m, sfi->pv, sfi->sp, sfi->ra, sfi->xpc);
+               method_print(sfi->code->m);
+               log_print("]");
+               log_finish();
+       }
+#endif
+
+       /* Set previous stackframe info. */
+
+       threads_set_current_stackframeinfo(sfi->prev);
+}
+
+
+/* stacktrace_stackframeinfo_fill **********************************************
+
+   Fill the temporary stackframeinfo structure with the values given
+   in sfi.
+
+   IN:
+       tmpsfi ... temporary stackframeinfo
+       sfi ...... stackframeinfo to be used in the next iteration
+
+*******************************************************************************/
+
+static inline void stacktrace_stackframeinfo_fill(stackframeinfo_t *tmpsfi, stackframeinfo_t *sfi)
+{
+       /* Sanity checks. */
+
+       assert(tmpsfi != NULL);
+       assert(sfi != NULL);
+
+       /* Fill the temporary stackframeinfo. */
+
+       tmpsfi->code = sfi->code;
+       tmpsfi->pv   = sfi->pv;
+       tmpsfi->sp   = sfi->sp;
+       tmpsfi->ra   = sfi->ra;
+       tmpsfi->xpc  = sfi->xpc;
+
+       /* Set the previous stackframe info of the temporary one to the
+          next in the chain. */
+
+       tmpsfi->prev = sfi->prev;
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace fill]");
+#endif
+}
+
+
+/* stacktrace_stackframeinfo_next **********************************************
+
+   Walk the stack (or the stackframeinfo-chain) to the next method and
+   return the new stackframe values in the temporary stackframeinfo
+   passed.
+
+   ATTENTION: This function does NOT skip builtin methods!
+
+   IN:
+       tmpsfi ... temporary stackframeinfo of current method
+
+*******************************************************************************/
+
+static inline void stacktrace_stackframeinfo_next(stackframeinfo_t *tmpsfi)
+{
+       codeinfo         *code;
+       void             *pv;
+       void             *sp;
+       void             *ra;
+       void             *xpc;
+       uint32_t          framesize;
+       stackframeinfo_t *prevsfi;
+
+       /* Sanity check. */
+
+       assert(tmpsfi != NULL);
+
+       /* Get values from the stackframeinfo. */
+
+       code = tmpsfi->code;
+       pv   = tmpsfi->pv;
+       sp   = tmpsfi->sp;
+       ra   = tmpsfi->ra;
+       xpc  = tmpsfi->xpc;
+       /* Get the current stack frame size. */
+
+       framesize = *((uint32_t *) (((intptr_t) pv) + FrameSize));
+
+       /* Get the RA of the current stack frame (RA to the parent Java
+          method) if the current method is a non-leaf method.  Otherwise
+          the value in the stackframeinfo is correct (from the signal
+          handler). */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               ra = intrp_md_stacktrace_get_returnaddress(sp, framesize);
+       else
+# endif
+               {
+                       if (!code_is_leafmethod(code))
+                               ra = md_stacktrace_get_returnaddress(sp, framesize);
+               }
+#else
+       ra = intrp_md_stacktrace_get_returnaddress(sp, framesize);
+#endif
+
+       /* Get the PV for the parent Java method. */
+
+#if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               pv = methodtree_find(ra);
+       else
+#endif
+               {
+#if defined(ENABLE_JIT)
+# if defined(__SPARC_64__)
+                       sp = md_get_framepointer(sp);
+                       pv = md_get_pv_from_stackframe(sp);
+# else
+                       pv = md_codegen_get_pv_from_pc(ra);
+# endif
+#endif
+               }
+
+       /* Get the codeinfo pointer for the parent Java method. */
+
+       code = code_get_codeinfo_for_pv(pv);
+
+       /* Calculate the SP for the parent Java method. */
+
+#if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               sp = *(u1 **) (sp - framesize);
+       else
+#endif
+               {
+#if defined(__I386__) || defined (__X86_64__) || defined (__M68K__)
+                       sp = (void *) (((intptr_t) sp) + framesize + SIZEOF_VOID_P);
+#elif defined(__SPARC_64__)
+                       /* already has the new sp */
+#else
+                       sp = (void *) (((intptr_t) sp) + framesize);
+#endif
+               }
+
+       /* If the new codeinfo pointer is NULL we reached a
+          asm_vm_call_method function.  In this case we get the next
+          values from the previous stackframeinfo in the chain.
+          Otherwise the new values have been calculated before. */
+
+       if (code == NULL) {
+               prevsfi = tmpsfi->prev;
+
+               /* If the previous stackframeinfo in the chain is NULL we
+                  reached the top of the stacktrace.  We set code and prev to
+                  NULL to mark the end, which is checked in
+                  stacktrace_stackframeinfo_end_check. */
+
+               if (prevsfi == NULL) {
+                       tmpsfi->code = NULL;
+                       tmpsfi->prev = NULL;
+                       return;
+               }
+
+               /* Fill the temporary stackframeinfo with the new values. */
+
+               stacktrace_stackframeinfo_fill(tmpsfi, prevsfi);
+       }
+       else {
+               /* Store the new values in the stackframeinfo.  NOTE: We
+                  subtract 1 from the RA to get the XPC, because the RA
+                  points to the instruction after the call instruction. */
+
+               tmpsfi->code = code;
+               tmpsfi->pv   = pv;
+               tmpsfi->sp   = sp;
+               tmpsfi->ra   = ra;
+               tmpsfi->xpc  = (void *) (((intptr_t) ra) - 1);
+       }
+
+#if !defined(NDEBUG)
+       /* Print current method information. */
+
+       if (opt_DebugStackTrace) {
+               log_start();
+               log_print("[stacktrace: method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=",
+                                 tmpsfi->code->m, tmpsfi->pv, tmpsfi->sp, tmpsfi->ra,
+                                 tmpsfi->xpc);
+               method_print(tmpsfi->code->m);
+               log_print("]");
+               log_finish();
+       }
+#endif
+}
+
+
+/* stacktrace_stackframeinfo_end_check *****************************************
+
+   Check if we reached the end of the stacktrace.
+
+   IN:
+       tmpsfi ... temporary stackframeinfo of current method
+
+   RETURN:
+       true .... the end is reached
+          false ... the end is not reached
+
+*******************************************************************************/
+
+static inline bool stacktrace_stackframeinfo_end_check(stackframeinfo_t *tmpsfi)
+{
+       /* Sanity check. */
+
+       assert(tmpsfi != NULL);
+
+       if ((tmpsfi->code == NULL) && (tmpsfi->prev == NULL)) {
+#if !defined(NDEBUG)
+               if (opt_DebugStackTrace)
+                       log_println("[stacktrace stop]");
+#endif
+
+               return true;
+       }
+
+       return false;
+}
+
+
+/* stacktrace_depth ************************************************************
+
+   Calculates and returns the depth of the current stacktrace.
+
+   IN:
+       sfi ... stackframeinfo where to start the stacktrace
+
+   RETURN:
+       depth of the stacktrace
+
+*******************************************************************************/
+
+static int stacktrace_depth(stackframeinfo_t *sfi)
+{
+       stackframeinfo_t  tmpsfi;
+       int               depth;
+       methodinfo       *m;
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace_depth]");
+#endif
+
+       /* XXX This is not correct, but a workaround for threads-dump for
+          now. */
+/*     assert(sfi != NULL); */
+       if (sfi == NULL)
+               return 0;
+
+       /* Iterate over all stackframes. */
+
+       depth = 0;
+
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+               /* Get methodinfo. */
+
+               m = tmpsfi.code->m;
+
+               /* Skip builtin methods. */
+
+               if (m->flags & ACC_METHOD_BUILTIN)
+                       continue;
+
+               depth++;
+       }
+
+       return depth;
+}
+
+
+/* stacktrace_get **************************************************************
+
+   Builds and returns a stacktrace starting from the given stackframe
+   info and returns the stacktrace structure wrapped in a Java
+   byte-array to not confuse the GC.
+
+   IN:
+       sfi ... stackframe info to start stacktrace from
+
+   RETURN:
+       stacktrace as Java byte-array
+
+*******************************************************************************/
+
+java_handle_bytearray_t *stacktrace_get(stackframeinfo_t *sfi)
+{
+       stackframeinfo_t         tmpsfi;
+       int                      depth;
+       java_handle_bytearray_t *ba;
+       int32_t                  ba_size;
+       stacktrace_t            *st;
+       stacktrace_entry_t      *ste;
+       methodinfo              *m;
+       bool                     skip_fillInStackTrace;
+       bool                     skip_init;
+
+       CYCLES_STATS_DECLARE_AND_START_WITH_OVERHEAD
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace_get]");
+#endif
+
+       skip_fillInStackTrace = true;
+       skip_init             = true;
+
+       depth = stacktrace_depth(sfi);
+
+       if (depth == 0)
+               return NULL;
+
+       /* Allocate memory from the GC heap and copy the stacktrace
+          buffer. */
+       /* ATTENTION: Use a Java byte-array for this to not confuse the
+          GC. */
+       /* FIXME: We waste some memory here as we skip some entries
+          later. */
+
+       ba_size = sizeof(stacktrace_t) + sizeof(stacktrace_entry_t) * depth;
+
+       ba = builtin_newarray_byte(ba_size);
+
+       if (ba == NULL)
+               goto return_NULL;
+
+       /* Get a stacktrace entry pointer. */
+       /* ATTENTION: We need a critical section here because we use the
+          byte-array data pointer directly. */
+
+       LLNI_CRITICAL_START;
+
+       st = (stacktrace_t *) LLNI_array_data(ba);
+
+       ste = st->entries;
+
+       /* Iterate over the whole stack. */
+
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+               /* Get the methodinfo. */
+
+               m = tmpsfi.code->m;
+
+               /* Skip builtin methods. */
+
+               if (m->flags & ACC_METHOD_BUILTIN)
+                       continue;
+
+               /* This logic is taken from
+                  hotspot/src/share/vm/classfile/javaClasses.cpp
+                  (java_lang_Throwable::fill_in_stack_trace). */
+
+               if (skip_fillInStackTrace == true) {
+                       /* Check "fillInStackTrace" only once, so we negate the
+                          flag after the first time check. */
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+                       /* For GNU Classpath we also need to skip
+                          VMThrowable.fillInStackTrace(). */
+
+                       if ((m->clazz == class_java_lang_VMThrowable) &&
+                               (m->name  == utf_fillInStackTrace))
+                               continue;
+#endif
+
+                       skip_fillInStackTrace = false;
+
+                       if (m->name == utf_fillInStackTrace)
+                               continue;
+               }
+
+               /* Skip <init> methods of the exceptions klass.  If there is
+                  <init> methods that belongs to a superclass of the
+                  exception we are going to skipping them in stack trace. */
+
+               if (skip_init == true) {
+                       if ((m->name == utf_init) &&
+                               (class_issubclass(m->clazz, class_java_lang_Throwable))) {
+                               continue;
+                       }
+                       else {
+                               /* If no "Throwable.init()" method found, we stop
+                                  checking it next time. */
+
+                               skip_init = false;
+                       }
+               }
+
+               /* Store the stacktrace entry and increment the pointer. */
+
+               ste->code = tmpsfi.code;
+               ste->pc   = tmpsfi.xpc;
+
+               ste++;
+       }
+
+       /* Store the number of entries in the stacktrace structure. */
+
+       st->length = ste - st->entries;
+
+       LLNI_CRITICAL_END;
+
+       /* release dump memory */
+
+/*     dump_release(dumpsize); */
+
+       CYCLES_STATS_END_WITH_OVERHEAD(stacktrace_fillInStackTrace,
+                                                                  stacktrace_overhead)
+       return ba;
+
+return_NULL:
+/*     dump_release(dumpsize); */
+
+       CYCLES_STATS_END_WITH_OVERHEAD(stacktrace_fillInStackTrace,
+                                                                  stacktrace_overhead)
+
+       return NULL;
+}
+
+
+/* stacktrace_get_current ******************************************************
+
+   Builds and returns a stacktrace from the current thread and returns
+   the stacktrace structure wrapped in a Java byte-array to not
+   confuse the GC.
+
+   RETURN:
+       stacktrace as Java byte-array
+
+*******************************************************************************/
+
+java_handle_bytearray_t *stacktrace_get_current(void)
+{
+       stackframeinfo_t        *sfi;
+       java_handle_bytearray_t *ba;
+
+       sfi = threads_get_current_stackframeinfo();
+       ba  = stacktrace_get(sfi);
+
+       return ba;
+}
+
+
+/* stacktrace_get_caller_class *************************************************
+
+   Get the class on the stack at the given depth.  This function skips
+   various special classes or methods.
+
+   ARGUMENTS:
+       depth ... depth to get caller class of
+
+   RETURN:
+       caller class
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+classinfo *stacktrace_get_caller_class(int depth)
+{
+       stackframeinfo_t *sfi;
+       stackframeinfo_t  tmpsfi;
+       methodinfo       *m;
+       classinfo        *c;
+       int               i;
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace_get_caller_class]");
+#endif
+
+       /* Get the stackframeinfo of the current thread. */
+
+       sfi = threads_get_current_stackframeinfo();
+
+       /* Iterate over the whole stack until we reached the requested
+          depth. */
+
+       i = 0;
+
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+
+               m = tmpsfi.code->m;
+               c = m->clazz;
+
+               /* Skip builtin methods. */
+
+               if (m->flags & ACC_METHOD_BUILTIN)
+                       continue;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+               /* NOTE: See hotspot/src/share/vm/runtime/vframe.cpp
+                  (vframeStreamCommon::security_get_caller_frame). */
+
+               /* This is java.lang.reflect.Method.invoke(), skip it. */
+
+               if (m == method_java_lang_reflect_Method_invoke)
+                       continue;
+
+               /* This is an auxiliary frame, skip it. */
+
+               if (class_issubclass(c, class_sun_reflect_MagicAccessorImpl))
+                       continue;
+#endif
+
+               /* We reached the requested depth. */
+
+               if (i >= depth)
+                       return c;
+
+               i++;
+       }
+
+       return NULL;
+}
+#endif
+
+
+/* stacktrace_first_nonnull_classloader ****************************************
+
+   Returns the first non-null (user-defined) classloader on the stack.
+   If none is found NULL is returned.
+
+   RETURN:
+       classloader
+
+*******************************************************************************/
+
+classloader_t *stacktrace_first_nonnull_classloader(void)
+{
+       stackframeinfo_t *sfi;
+       stackframeinfo_t  tmpsfi;
+       methodinfo       *m;
+       classloader_t    *cl;
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace_first_nonnull_classloader]");
+#endif
+
+       /* Get the stackframeinfo of the current thread. */
+
+       sfi = threads_get_current_stackframeinfo();
+
+       /* Iterate over the whole stack. */
+
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+
+               m  = tmpsfi.code->m;
+               cl = class_get_classloader(m->clazz);
+
+               if (cl != NULL)
+                       return cl;
+       }
+
+       return NULL;
+}
+
+
+/* stacktrace_getClassContext **************************************************
+
+   Creates a Class context array.
+
+   RETURN VALUE:
+      the array of java.lang.Class objects, or
+         NULL if an exception has been thrown
+
+*******************************************************************************/
+
+java_handle_objectarray_t *stacktrace_getClassContext(void)
+{
+       stackframeinfo_t           *sfi;
+       stackframeinfo_t            tmpsfi;
+       int                         depth;
+       java_handle_objectarray_t  *oa;
+       java_object_t             **data;
+       int                         i;
+       methodinfo                 *m;
+
+       CYCLES_STATS_DECLARE_AND_START
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace_getClassContext]");
+#endif
+
+       sfi = threads_get_current_stackframeinfo();
+
+       /* Get the depth of the current stack. */
+
+       depth = stacktrace_depth(sfi);
+
+       /* The first stackframe corresponds to the method whose
+          implementation calls this native function.  We remove that
+          entry. */
+
+       depth--;
+       stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+       stacktrace_stackframeinfo_next(&tmpsfi);
+
+       /* Allocate the Class array. */
+
+       oa = builtin_anewarray(depth, class_java_lang_Class);
+
+       if (oa == NULL) {
+               CYCLES_STATS_END(stacktrace_getClassContext);
+
+               return NULL;
+       }
+
+       /* Fill the Class array from the stacktrace list. */
+
+       LLNI_CRITICAL_START;
+
+       data = LLNI_array_data(oa);
+
+       /* Iterate over the whole stack. */
+
+       i = 0;
+
+       for (;
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+               /* Get methodinfo. */
+
+               m = tmpsfi.code->m;
+
+               /* Skip builtin methods. */
+
+               if (m->flags & ACC_METHOD_BUILTIN)
+                       continue;
+
+               /* Store the class in the array. */
+
+               data[i] = (java_object_t *) m->clazz;
+
+               i++;
+       }
+
+       LLNI_CRITICAL_END;
+
+       CYCLES_STATS_END(stacktrace_getClassContext)
+
+       return oa;
+}
+
+
+/* stacktrace_getCurrentClass **************************************************
+
+   Find the current class by walking the stack trace.
+
+   Quote from the JNI documentation:
+        
+   In the Java 2 Platform, FindClass locates the class loader
+   associated with the current native method.  If the native code
+   belongs to a system class, no class loader will be
+   involved. Otherwise, the proper class loader will be invoked to
+   load and link the named class. When FindClass is called through the
+   Invocation Interface, there is no current native method or its
+   associated class loader. In that case, the result of
+   ClassLoader.getBaseClassLoader is used."
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+classinfo *stacktrace_get_current_class(void)
+{
+       stackframeinfo_t *sfi;
+       stackframeinfo_t  tmpsfi;
+       methodinfo       *m;
+
+       CYCLES_STATS_DECLARE_AND_START;
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace_get_current_class]");
+#endif
+
+       /* Get the stackframeinfo of the current thread. */
+
+       sfi = threads_get_current_stackframeinfo();
+
+       /* If the stackframeinfo is NULL then FindClass is called through
+          the Invocation Interface and we return NULL */
+
+       if (sfi == NULL) {
+               CYCLES_STATS_END(stacktrace_getCurrentClass);
+
+               return NULL;
+       }
+
+       /* Iterate over the whole stack. */
+
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+               /* Get the methodinfo. */
+
+               m = tmpsfi.code->m;
+
+               if (m->clazz == class_java_security_PrivilegedAction) {
+                       CYCLES_STATS_END(stacktrace_getCurrentClass);
+
+                       return NULL;
+               }
+
+               if (m->clazz != NULL) {
+                       CYCLES_STATS_END(stacktrace_getCurrentClass);
+
+                       return m->clazz;
+               }
+       }
+
+       /* No Java method found on the stack. */
+
+       CYCLES_STATS_END(stacktrace_getCurrentClass);
+
+       return NULL;
+}
+#endif /* ENABLE_JAVASE */
+
+
+/* stacktrace_get_stack ********************************************************
+
+   Create a 2-dimensional array for java.security.VMAccessControler.
+
+   RETURN VALUE:
+      the arrary, or
+         NULL if an exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+java_handle_objectarray_t *stacktrace_get_stack(void)
+{
+       stackframeinfo_t          *sfi;
+       stackframeinfo_t           tmpsfi;
+       int                        depth;
+       java_handle_objectarray_t *oa;
+       java_handle_objectarray_t *classes;
+       java_handle_objectarray_t *methodnames;
+       methodinfo                *m;
+       java_handle_t             *string;
+       int                        i;
+
+       CYCLES_STATS_DECLARE_AND_START
+
+#if !defined(NDEBUG)
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace_get_stack]");
+#endif
+
+       /* Get the stackframeinfo of the current thread. */
+
+       sfi = threads_get_current_stackframeinfo();
+
+       /* Get the depth of the current stack. */
+
+       depth = stacktrace_depth(sfi);
+
+       if (depth == 0)
+               return NULL;
+
+       /* Allocate the required arrays. */
+
+       oa = builtin_anewarray(2, arrayclass_java_lang_Object);
+
+       if (oa == NULL)
+               goto return_NULL;
+
+       classes = builtin_anewarray(depth, class_java_lang_Class);
+
+       if (classes == NULL)
+               goto return_NULL;
+
+       methodnames = builtin_anewarray(depth, class_java_lang_String);
+
+       if (methodnames == NULL)
+               goto return_NULL;
+
+       /* Set up the 2-dimensional array. */
+
+       array_objectarray_element_set(oa, 0, (java_handle_t *) classes);
+       array_objectarray_element_set(oa, 1, (java_handle_t *) methodnames);
+
+       /* Iterate over the whole stack. */
+       /* TODO We should use a critical section here to speed things
+          up. */
+
+       i = 0;
+
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+               /* Get the methodinfo. */
+
+               m = tmpsfi.code->m;
+
+               /* Skip builtin methods. */
+
+               if (m->flags & ACC_METHOD_BUILTIN)
+                       continue;
+
+               /* Store the class in the array. */
+               /* NOTE: We use a LLNI-macro here, because a classinfo is not
+                  a handle. */
+
+               LLNI_array_direct(classes, i) = (java_object_t *) m->clazz;
+
+               /* Store the name in the array. */
+
+               string = javastring_new(m->name);
+
+               if (string == NULL)
+                       goto return_NULL;
+
+               array_objectarray_element_set(methodnames, i, string);
+
+               i++;
+       }
+
+       CYCLES_STATS_END(stacktrace_get_stack)
+
+       return oa;
+
+return_NULL:
+       CYCLES_STATS_END(stacktrace_get_stack)
+
+       return NULL;
+}
+#endif
+
+
+/* stacktrace_print_entry ****************************************************
+
+   Print line for a stacktrace entry.
+
+   ARGUMENTS:
+       m ............ methodinfo of the entry
+       linenumber ... linenumber of the entry
+
+*******************************************************************************/
+
+static void stacktrace_print_entry(methodinfo *m, int32_t linenumber)
+{
+       /* Sanity check. */
+
+       assert(m != NULL);
+
+       printf("\tat ");
+
+       if (m->flags & ACC_METHOD_BUILTIN)
+               printf("NULL");
+       else
+               utf_display_printable_ascii_classname(m->clazz->name);
+
+       printf(".");
+       utf_display_printable_ascii(m->name);
+       utf_display_printable_ascii(m->descriptor);
+
+       if (m->flags & ACC_NATIVE) {
+               puts("(Native Method)");
+       }
+       else {
+               if (m->flags & ACC_METHOD_BUILTIN) {
+                       puts("(builtin)");
+               }
+               else {
+                       printf("(");
+                       utf_display_printable_ascii(m->clazz->sourcefile);
+                       printf(":%d)\n", linenumber);
+               }
+       }
+
+       fflush(stdout);
+}
+
+
+/* stacktrace_print ************************************************************
+
+   Print the given stacktrace with CACAO intern methods only (no Java
+   code required).
+
+   This method is used by stacktrace_dump_trace and
+   builtin_trace_exception.
+
+   IN:
+       st ... stacktrace to print
+
+*******************************************************************************/
+
+void stacktrace_print(stacktrace_t *st)
+{
+       stacktrace_entry_t *ste;
+       methodinfo         *m;
+       int32_t             linenumber;
+       int                 i;
+
+       ste = &(st->entries[0]);
+
+       for (i = 0; i < st->length; i++, ste++) {
+               m = ste->code->m;
+
+               /* Get the line number. */
+
+               linenumber = linenumbertable_linenumber_for_pc(&m, ste->code, ste->pc);
+
+               stacktrace_print_entry(m, linenumber);
+       }
+}
+
+
+/* stacktrace_print_current ****************************************************
+
+   Print the current stacktrace of the current thread.
+
+   NOTE: This function prints all frames of the stacktrace and does
+   not skip frames like stacktrace_get.
+
+*******************************************************************************/
+
+void stacktrace_print_current(void)
+{
+       stackframeinfo_t *sfi;
+       stackframeinfo_t  tmpsfi;
+       codeinfo         *code;
+       methodinfo       *m;
+       int32_t           linenumber;
+
+       sfi = threads_get_current_stackframeinfo();
+
+       if (sfi == NULL) {
+               puts("\t<<No stacktrace available>>");
+               fflush(stdout);
+               return;
+       }
+
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+               /* Get the methodinfo. */
+
+               code = tmpsfi.code;
+               m    = code->m;
+
+               /* Get the line number. */
+
+               linenumber = linenumbertable_linenumber_for_pc(&m, code, tmpsfi.xpc);
+
+               stacktrace_print_entry(m, linenumber);
+       }
+}
+
+
+/* stacktrace_print_of_thread **************************************************
+
+   Print the current stacktrace of the given thread.
+
+   ARGUMENTS:
+       t ... thread
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS)
+void stacktrace_print_of_thread(threadobject *t)
+{
+       stackframeinfo_t *sfi;
+       stackframeinfo_t  tmpsfi;
+       codeinfo         *code;
+       methodinfo       *m;
+       int32_t           linenumber;
+
+       /* Build a stacktrace for the passed thread. */
+
+       sfi = t->_stackframeinfo;
+       
+       if (sfi == NULL) {
+               puts("\t<<No stacktrace available>>");
+               fflush(stdout);
+               return;
+       }
+
+       for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+                stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+                stacktrace_stackframeinfo_next(&tmpsfi)) {
+               /* Get the methodinfo. */
+
+               code = tmpsfi.code;
+               m    = code->m;
+
+               /* Get the line number. */
+
+               linenumber = linenumbertable_linenumber_for_pc(&m, code, tmpsfi.xpc);
+
+               stacktrace_print_entry(m, linenumber);
+       }
+}
+#endif
+
+
+/* stacktrace_print_exception **************************************************
+
+   Print the stacktrace of a given exception (more or less a wrapper
+   to stacktrace_print).
+
+   IN:
+       h ... handle of exception to print
+
+*******************************************************************************/
+
+void stacktrace_print_exception(java_handle_t *h)
+{
+       if (h == NULL)
+               return;
+
+       java_lang_Throwable t(h);
+
+       /* now print the stacktrace */
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       java_lang_VMThrowable vmt(t.get_vmState());
+       java_handle_bytearray_t* backtrace = vmt.get_vmdata();
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       java_handle_bytearray_t* backtrace = t.get_backtrace();
+
+#else
+# error unknown classpath configuration
+#endif
+
+       // Sanity check.
+
+       assert(backtrace != NULL);
+
+       /* We need a critical section here as we use the byte-array data
+          pointer directly. */
+
+       LLNI_CRITICAL_START;
+       
+       stacktrace_t* st = (stacktrace_t*) LLNI_array_data(backtrace);
+
+       stacktrace_print(st);
+
+       LLNI_CRITICAL_END;
+}
+
+
+#if defined(ENABLE_CYCLES_STATS)
+void stacktrace_print_cycles_stats(FILE *file)
+{
+       CYCLES_STATS_PRINT_OVERHEAD(stacktrace_overhead, file);
+       CYCLES_STATS_PRINT(stacktrace_get,               file);
+       CYCLES_STATS_PRINT(stacktrace_getClassContext ,  file);
+       CYCLES_STATS_PRINT(stacktrace_getCurrentClass ,  file);
+       CYCLES_STATS_PRINT(stacktrace_get_stack,         file);
+}
+#endif
+
+} // extern "C"
+
+
+/*
+ * 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/jit/stacktrace.h b/src/vm/jit/stacktrace.h
deleted file mode 100644 (file)
index e21c348..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* src/vm/jit/stacktrace.h - header file for stacktrace generation
-
-   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 _STACKTRACE_H
-#define _STACKTRACE_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct stackframeinfo_t   stackframeinfo_t;
-typedef struct stacktrace_entry_t stacktrace_entry_t;
-typedef struct stacktrace_t       stacktrace_t;
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "md-abi.h"
-
-#include "threads/thread.h"
-
-#include "vm/global.h"
-
-#include "vm/jit/code.h"
-
-#include "vmcore/class.h"
-
-
-/* stackframeinfo **************************************************************
-
-   ATTENTION: Keep the number of elements of this structure even, to
-   make sure that the stack keeps aligned (e.g. 16-bytes for x86_64).
-
-*******************************************************************************/
-
-struct stackframeinfo_t {
-       stackframeinfo_t *prev;             /* pointer to prev stackframeinfo     */
-       codeinfo         *code;             /* codeinfo of current method         */
-       u1               *pv;               /* PV of current function             */
-       u1               *sp;               /* SP of parent Java function         */
-       u1               *ra;               /* RA to parent Java function         */
-       u1               *xpc;              /* XPC (for inline stubs)             */
-#if defined(ENABLE_GC_CACAO)
-       /* 
-        * The exact GC needs to be able to recover saved registers, so the
-        * native-stub saves these registers here
-        */
-# if defined(HAS_ADDRESS_REGISTER_FILE)
-       uintptr_t         adrregs[ADR_SAV_CNT];
-# else
-       uintptr_t         intregs[INT_SAV_CNT];
-# endif
-#endif
-};
-
-
-/* stacktrace_entry_t *********************************************************/
-
-struct stacktrace_entry_t {
-       codeinfo *code;                     /* codeinfo pointer of this method    */
-       void     *pc;                       /* PC in this method                  */
-};
-
-
-/* stacktrace_t ***************************************************************/
-
-struct stacktrace_t {
-       int32_t            length;          /* length of the entries array        */
-       stacktrace_entry_t entries[1];      /* stacktrace entries                 */
-};
-
-
-/* function prototypes ********************************************************/
-
-void                       stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra, u1 *xpc);
-void                       stacktrace_stackframeinfo_remove(stackframeinfo_t *sfi);
-
-java_handle_bytearray_t   *stacktrace_get(stackframeinfo_t *sfi);
-java_handle_bytearray_t   *stacktrace_get_current(void);
-
-#if defined(ENABLE_JAVASE)
-classinfo                 *stacktrace_get_caller_class(int depth);
-classloader_t             *stacktrace_first_nonnull_classloader(void);
-java_handle_objectarray_t *stacktrace_getClassContext(void);
-classinfo                 *stacktrace_get_current_class(void);
-java_handle_objectarray_t *stacktrace_get_stack(void);
-#endif
-
-void                       stacktrace_print(stacktrace_t *st);
-void                       stacktrace_print_current(void);
-
-#if defined(ENABLE_THREADS)
-void                       stacktrace_print_of_thread(threadobject *t);
-#endif
-
-void                       stacktrace_print_exception(java_handle_t *h);
-
-/* machine dependent functions (code in ARCH_DIR/md.c) */
-
-#if defined(ENABLE_JIT)
-# if defined(__SPARC_64__)
-u1 *md_get_framepointer(u1 *sp);
-u1 *md_get_pv_from_stackframe(u1 *sp);
-# endif
-#endif
-
-#if defined(ENABLE_INTRP)
-u1 *intrp_md_stacktrace_get_returnaddress(u1 *sp, u4 framesize);
-#endif
-
-#if defined(ENABLE_CYCLES_STATS)
-void stacktrace_print_cycles_stats(FILE *file);
-#endif
-
-#endif /* _STACKTRACE_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/jit/stacktrace.hpp b/src/vm/jit/stacktrace.hpp
new file mode 100644 (file)
index 0000000..376b597
--- /dev/null
@@ -0,0 +1,161 @@
+/* src/vm/jit/stacktrace.hpp - header file for stacktrace generation
+
+   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 _STACKTRACE_HPP
+#define _STACKTRACE_HPP
+
+// FIXME Use C-linkage for now.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* forward typedefs ***********************************************************/
+
+typedef struct stackframeinfo_t   stackframeinfo_t;
+typedef struct stacktrace_entry_t stacktrace_entry_t;
+typedef struct stacktrace_t       stacktrace_t;
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "md-abi.h"
+
+#include "threads/thread.hpp"
+
+#include "vm/class.h"
+#include "vm/global.h"
+
+#include "vm/jit/code.h"
+
+
+/* stackframeinfo **************************************************************
+
+   ATTENTION: Keep the number of elements of this structure even, to
+   make sure that the stack keeps aligned (e.g. 16-bytes for x86_64).
+
+*******************************************************************************/
+
+struct stackframeinfo_t {
+       stackframeinfo_t *prev;             /* pointer to prev stackframeinfo     */
+       codeinfo         *code;             /* codeinfo of current method         */
+       void             *pv;               /* PV of current function             */
+       void             *sp;               /* SP of parent Java function         */
+       void             *ra;               /* RA to parent Java function         */
+       void             *xpc;              /* XPC (for inline stubs)             */
+#if defined(ENABLE_GC_CACAO)
+       /* 
+        * The exact GC needs to be able to recover saved registers, so the
+        * native-stub saves these registers here
+        */
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+       uintptr_t         adrregs[ADR_SAV_CNT];
+# else
+       uintptr_t         intregs[INT_SAV_CNT];
+# endif
+#endif
+};
+
+
+/* stacktrace_entry_t *********************************************************/
+
+struct stacktrace_entry_t {
+       codeinfo *code;                     /* codeinfo pointer of this method    */
+       void     *pc;                       /* PC in this method                  */
+};
+
+
+/* stacktrace_t ***************************************************************/
+
+struct stacktrace_t {
+       int32_t            length;          /* length of the entries array        */
+       stacktrace_entry_t entries[1];      /* stacktrace entries                 */
+};
+
+
+/* function prototypes ********************************************************/
+
+void                       stacktrace_stackframeinfo_add(stackframeinfo_t* sfi, void* pv, void* sp, void* ra, void* xpc);
+void                       stacktrace_stackframeinfo_remove(stackframeinfo_t *sfi);
+
+java_handle_bytearray_t   *stacktrace_get(stackframeinfo_t *sfi);
+java_handle_bytearray_t   *stacktrace_get_current(void);
+
+#if defined(ENABLE_JAVASE)
+classinfo                 *stacktrace_get_caller_class(int depth);
+classloader_t             *stacktrace_first_nonnull_classloader(void);
+java_handle_objectarray_t *stacktrace_getClassContext(void);
+classinfo                 *stacktrace_get_current_class(void);
+java_handle_objectarray_t *stacktrace_get_stack(void);
+#endif
+
+void                       stacktrace_print(stacktrace_t *st);
+void                       stacktrace_print_current(void);
+
+#if defined(ENABLE_THREADS)
+void                       stacktrace_print_of_thread(threadobject *t);
+#endif
+
+void                       stacktrace_print_exception(java_handle_t *h);
+
+/* machine dependent functions (code in ARCH_DIR/md.c) */
+
+#if defined(ENABLE_JIT)
+# if defined(__SPARC_64__)
+u1 *md_get_framepointer(u1 *sp);
+u1 *md_get_pv_from_stackframe(u1 *sp);
+# endif
+#endif
+
+#if defined(ENABLE_INTRP)
+u1 *intrp_md_stacktrace_get_returnaddress(u1 *sp, u4 framesize);
+#endif
+
+#if defined(ENABLE_CYCLES_STATS)
+void stacktrace_print_cycles_stats(FILE *file);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _STACKTRACE_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:
+ */
diff --git a/src/vm/jit/trace.c b/src/vm/jit/trace.c
deleted file mode 100644 (file)
index ba75999..0000000
+++ /dev/null
@@ -1,643 +0,0 @@
-/* src/vm/jit/trace.c - Functions for tracing from java code.
-
-   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 "arch.h"
-#include "md-abi.h"
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
-
-#include "threads/thread.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/global.h"
-#include "vm/stringlocal.h"
-#include "vm/jit/argument.h"
-#include "vm/jit/codegen-common.h"
-#include "vm/jit/trace.h"
-#include "vm/jit/show.h"
-
-#include "vmcore/options.h"
-#include "vmcore/utf8.h"
-
-
-#if !defined(NDEBUG)
-
-
-/* global variables ***********************************************************/
-
-#if !defined(ENABLE_THREADS)
-s4 _no_threads_tracejavacallindent = 0;
-u4 _no_threads_tracejavacallcount= 0;
-#endif
-
-
-/* trace_java_call_print_argument **********************************************
-
-   XXX: Document me!
-
-*******************************************************************************/
-
-static char *trace_java_call_print_argument(methodinfo *m, char *logtext, s4 *logtextlen, typedesc *paramtype, imm_union imu)
-{
-       java_object_t *o;
-       classinfo     *c;
-       utf           *u;
-       u4             len;
-
-       switch (paramtype->type) {
-       case TYPE_INT:
-               sprintf(logtext + strlen(logtext), "%d (0x%08x)", (int32_t)imu.l, (int32_t)imu.l);
-               break;
-
-       case TYPE_LNG:
-#if SIZEOF_VOID_P == 4
-               sprintf(logtext + strlen(logtext), "%lld (0x%016llx)", imu.l, imu.l);
-#else
-               sprintf(logtext + strlen(logtext), "%ld (0x%016lx)", imu.l, imu.l);
-#endif
-               break;
-
-       case TYPE_FLT:
-               sprintf(logtext + strlen(logtext), "%g (0x%08x)", imu.f, imu.i);
-               break;
-
-       case TYPE_DBL:
-#if SIZEOF_VOID_P == 4
-               sprintf(logtext + strlen(logtext), "%g (0x%016llx)", imu.d, imu.l);
-#else
-               sprintf(logtext + strlen(logtext), "%g (0x%016lx)", imu.d, imu.l);
-#endif
-               break;
-
-       case TYPE_ADR:
-#if SIZEOF_VOID_P == 4
-               sprintf(logtext + strlen(logtext), "0x%08x", (ptrint) imu.l);
-#else
-               sprintf(logtext + strlen(logtext), "0x%016lx", (ptrint) imu.l);
-#endif
-
-               /* Workaround for sun.misc.Unsafe methods.  In the future
-                  (exact GC) we should check if the address is on the GC
-                  heap. */
-
-               if ((m->clazz       != NULL) &&
-                       (m->clazz->name == utf_new_char("sun/misc/Unsafe")))
-                       break;
-
-               /* Cast to java.lang.Object. */
-
-               o = (java_object_t *) (ptrint) imu.l;
-
-               /* Check return argument for java.lang.Class or
-                  java.lang.String. */
-
-               if (o != NULL) {
-                       if (o->vftbl->clazz == class_java_lang_String) {
-                               /* get java.lang.String object and the length of the
-                                  string */
-
-                               u = javastring_toutf(o, false);
-
-                               len = strlen(" (String = \"") + utf_bytes(u) + strlen("\")");
-
-                               /* realloc memory for string length */
-
-                               logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len);
-                               *logtextlen += len;
-
-                               /* convert to utf8 string and strcat it to the logtext */
-
-                               strcat(logtext, " (String = \"");
-                               utf_cat(logtext, u);
-                               strcat(logtext, "\")");
-                       }
-                       else {
-                               if (o->vftbl->clazz == class_java_lang_Class) {
-                                       /* if the object returned is a java.lang.Class
-                                          cast it to classinfo structure and get the name
-                                          of the class */
-
-                                       c = (classinfo *) o;
-
-                                       u = c->name;
-                               }
-                               else {
-                                       /* if the object returned is not a java.lang.String or
-                                          a java.lang.Class just print the name of the class */
-
-                                       u = o->vftbl->clazz->name;
-                               }
-
-                               len = strlen(" (Class = \"") + utf_bytes(u) + strlen("\")");
-
-                               /* realloc memory for string length */
-
-                               logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len);
-                               *logtextlen += len;
-
-                               /* strcat to the logtext */
-
-                               strcat(logtext, " (Class = \"");
-                               utf_cat_classname(logtext, u);
-                               strcat(logtext, "\")");
-                       }
-               }
-       }
-
-       return logtext;
-}
-
-/* trace_java_call_enter ******************************************************
-   Traces an entry into a java method.
-
-   arg_regs: Array containing all argument registers as int64_t values in
-   the same order as listed in m->methoddesc. The array is usually allocated
-   on the stack and used for restoring the argument registers later.
-
-   stack: Pointer to first on stack argument in the same format passed to 
-   asm_vm_call_method.
-
-*******************************************************************************/
-
-void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
-{
-       methoddesc *md;
-       imm_union   arg;
-       char       *logtext;
-       s4          logtextlen;
-       s4          i;
-       s4          pos;
-       int32_t     dumpmarker;
-
-       /* We don't trace builtin functions here because the argument
-          passing happens via the native ABI and does not fit these
-          functions. */
-
-       if (method_is_builtin(m))
-               return;
-
-#if defined(ENABLE_DEBUG_FILTER)
-       if (!show_filters_test_verbosecall_enter(m))
-               return;
-#endif
-
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_enter_method(m);
-       return;
-#endif
-
-       md = m->parseddesc;
-
-       /* calculate message length */
-
-       logtextlen =
-               strlen("4294967295 ") +
-               strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
-               TRACEJAVACALLINDENT +
-               strlen("called: ") +
-               ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
-               strlen(".") +
-               utf_bytes(m->name) +
-               utf_bytes(m->descriptor);
-
-       /* Actually it's not possible to have all flags printed, but:
-          safety first! */
-
-       logtextlen +=
-               strlen(" PUBLIC") +
-               strlen(" PRIVATE") +
-               strlen(" PROTECTED") +
-               strlen(" STATIC") +
-               strlen(" FINAL") +
-               strlen(" SYNCHRONIZED") +
-               strlen(" VOLATILE") +
-               strlen(" TRANSIENT") +
-               strlen(" NATIVE") +
-               strlen(" INTERFACE") +
-               strlen(" ABSTRACT") +
-               strlen(" METHOD_BUILTIN");
-
-       /* add maximal argument length */
-
-       logtextlen +=
-               strlen("(") +
-               strlen("-9223372036854775808 (0x123456789abcdef0), ") * md->paramcount +
-               strlen("...(255)") +
-               strlen(")");
-
-       /* allocate memory */
-
-       DMARKER;
-
-       logtext = DMNEW(char, logtextlen);
-
-       TRACEJAVACALLCOUNT++;
-
-       sprintf(logtext, "%10d ", TRACEJAVACALLCOUNT);
-       sprintf(logtext + strlen(logtext), "-%d-", TRACEJAVACALLINDENT);
-
-       pos = strlen(logtext);
-
-       for (i = 0; i < TRACEJAVACALLINDENT; i++)
-               logtext[pos++] = '\t';
-
-       strcpy(logtext + pos, "called: ");
-
-       if (m->clazz != NULL)
-               utf_cat_classname(logtext, m->clazz->name);
-       else
-               strcat(logtext, "NULL");
-       strcat(logtext, ".");
-       utf_cat(logtext, m->name);
-       utf_cat(logtext, m->descriptor);
-
-       if (m->flags & ACC_PUBLIC)         strcat(logtext, " PUBLIC");
-       if (m->flags & ACC_PRIVATE)        strcat(logtext, " PRIVATE");
-       if (m->flags & ACC_PROTECTED)      strcat(logtext, " PROTECTED");
-       if (m->flags & ACC_STATIC)         strcat(logtext, " STATIC");
-       if (m->flags & ACC_FINAL)          strcat(logtext, " FINAL");
-       if (m->flags & ACC_SYNCHRONIZED)   strcat(logtext, " SYNCHRONIZED");
-       if (m->flags & ACC_VOLATILE)       strcat(logtext, " VOLATILE");
-       if (m->flags & ACC_TRANSIENT)      strcat(logtext, " TRANSIENT");
-       if (m->flags & ACC_NATIVE)         strcat(logtext, " NATIVE");
-       if (m->flags & ACC_INTERFACE)      strcat(logtext, " INTERFACE");
-       if (m->flags & ACC_ABSTRACT)       strcat(logtext, " ABSTRACT");
-
-       strcat(logtext, "(");
-
-       for (i = 0; i < md->paramcount; ++i) {
-               arg = argument_jitarray_load(md, i, arg_regs, stack);
-               logtext = trace_java_call_print_argument(m, logtext, &logtextlen,
-                                                                                                &md->paramtypes[i], arg);
-               if (i != (md->paramcount - 1)) {
-                       strcat(logtext, ", ");
-               }
-       }
-
-       strcat(logtext, ")");
-
-       log_text(logtext);
-
-       /* release memory */
-
-       DRELEASE;
-
-       TRACEJAVACALLINDENT++;
-
-}
-
-/* trace_java_call_exit ********************************************************
-
-   Traces an exit form a java method.
-
-   return_regs: Array of size 1 containing return register.
-   The array is usually allocated on the stack and used for restoring the
-   registers later.
-
-*******************************************************************************/
-
-void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
-{
-       methoddesc *md;
-       char       *logtext;
-       s4          logtextlen;
-       s4          i;
-       s4          pos;
-       imm_union   val;
-       int32_t     dumpmarker;
-
-       /* We don't trace builtin functions here because the argument
-          passing happens via the native ABI and does not fit these
-          functions. */
-
-       if (method_is_builtin(m))
-               return;
-
-#if defined(ENABLE_DEBUG_FILTER)
-       if (!show_filters_test_verbosecall_exit(m))
-               return;
-#endif
-
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_leave_method(m);
-       return;
-#endif
-
-       md = m->parseddesc;
-
-       /* outdent the log message */
-
-       if (TRACEJAVACALLINDENT)
-               TRACEJAVACALLINDENT--;
-       else
-               log_text("trace_java_call_exit: WARNING: unmatched unindent");
-
-       /* calculate message length */
-
-       logtextlen =
-               strlen("4294967295 ") +
-               strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
-               TRACEJAVACALLINDENT +
-               strlen("finished: ") +
-               ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
-               strlen(".") +
-               utf_bytes(m->name) +
-               utf_bytes(m->descriptor) +
-               strlen(" SYNCHRONIZED") + strlen("(") + strlen(")");
-
-       /* add maximal argument length */
-
-       logtextlen += strlen("->0.4872328470301428 (0x0123456789abcdef)");
-
-       /* allocate memory */
-
-       DMARKER;
-
-       logtext = DMNEW(char, logtextlen);
-
-       /* generate the message */
-
-       sprintf(logtext, "           ");
-       sprintf(logtext + strlen(logtext), "-%d-", TRACEJAVACALLINDENT);
-
-       pos = strlen(logtext);
-
-       for (i = 0; i < TRACEJAVACALLINDENT; i++)
-               logtext[pos++] = '\t';
-
-       strcpy(logtext + pos, "finished: ");
-       if (m->clazz != NULL)
-               utf_cat_classname(logtext, m->clazz->name);
-       else
-               strcat(logtext, "NULL");
-       strcat(logtext, ".");
-       utf_cat(logtext, m->name);
-       utf_cat(logtext, m->descriptor);
-
-       if (!IS_VOID_TYPE(md->returntype.type)) {
-               strcat(logtext, "->");
-               val = argument_jitreturn_load(md, return_regs);
-
-               logtext =
-                       trace_java_call_print_argument(m, logtext, &logtextlen,
-                                                                                  &md->returntype, val);
-       }
-
-       log_text(logtext);
-
-       /* release memory */
-
-       DRELEASE;
-}
-
-
-/* trace_exception *************************************************************
-
-   Traces an exception which is handled by exceptions_handle_exception.
-
-*******************************************************************************/
-
-void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
-{
-       char *logtext;
-       s4    logtextlen;
-       codeinfo *code;
-       int32_t   dumpmarker;
-
-       /* calculate message length */
-
-       if (xptr) {
-               logtextlen =
-                       strlen("Exception ") + utf_bytes(xptr->vftbl->clazz->name);
-       } 
-       else {
-               logtextlen = strlen("Some Throwable");
-       }
-
-       logtextlen += strlen(" thrown in ");
-
-       if (m) {
-               logtextlen +=
-                       utf_bytes(m->clazz->name) +
-                       strlen(".") +
-                       utf_bytes(m->name) +
-                       utf_bytes(m->descriptor) +
-                       strlen("(NOSYNC,NATIVE");
-
-#if SIZEOF_VOID_P == 8
-               logtextlen +=
-                       strlen(")(0x123456789abcdef0) at position 0x123456789abcdef0 (");
-#else
-               logtextlen += strlen(")(0x12345678) at position 0x12345678 (");
-#endif
-
-               if (m->clazz->sourcefile == NULL)
-                       logtextlen += strlen("<NO CLASSFILE INFORMATION>");
-               else
-                       logtextlen += utf_bytes(m->clazz->sourcefile);
-
-               logtextlen += strlen(":65536)");
-
-       } 
-       else {
-               logtextlen += strlen("call_java_method");
-       }
-
-       logtextlen += strlen("0");
-
-       /* allocate memory */
-
-       DMARKER;
-
-       logtext = DMNEW(char, logtextlen);
-
-       if (xptr) {
-               strcpy(logtext, "Exception ");
-               utf_cat_classname(logtext, xptr->vftbl->clazz->name);
-
-       } else {
-               strcpy(logtext, "Some Throwable");
-       }
-
-       strcat(logtext, " thrown in ");
-
-       if (m) {
-               utf_cat_classname(logtext, m->clazz->name);
-               strcat(logtext, ".");
-               utf_cat(logtext, m->name);
-               utf_cat(logtext, m->descriptor);
-
-               if (m->flags & ACC_SYNCHRONIZED)
-                       strcat(logtext, "(SYNC");
-               else
-                       strcat(logtext, "(NOSYNC");
-
-               if (m->flags & ACC_NATIVE) {
-                       strcat(logtext, ",NATIVE");
-
-                       code = m->code;
-
-#if SIZEOF_VOID_P == 8
-                       sprintf(logtext + strlen(logtext),
-                                       ")(0x%016lx) at position 0x%016lx",
-                                       (ptrint) code->entrypoint, (ptrint) pos);
-#else
-                       sprintf(logtext + strlen(logtext),
-                                       ")(0x%08x) at position 0x%08x",
-                                       (ptrint) code->entrypoint, (ptrint) pos);
-#endif
-
-               } else {
-
-                       /* XXX preliminary: This should get the actual codeinfo */
-                       /* in which the exception happened.                     */
-                       code = m->code;
-                       
-#if SIZEOF_VOID_P == 8
-                       sprintf(logtext + strlen(logtext),
-                                       ")(0x%016lx) at position 0x%016lx (",
-                                       (ptrint) code->entrypoint, (ptrint) pos);
-#else
-                       sprintf(logtext + strlen(logtext),
-                                       ")(0x%08x) at position 0x%08x (",
-                                       (ptrint) code->entrypoint, (ptrint) pos);
-#endif
-
-                       if (m->clazz->sourcefile == NULL)
-                               strcat(logtext, "<NO CLASSFILE INFORMATION>");
-                       else
-                               utf_cat(logtext, m->clazz->sourcefile);
-
-                       sprintf(logtext + strlen(logtext), ":%d)", 0);
-               }
-
-       } else
-               strcat(logtext, "call_java_method");
-
-       log_text(logtext);
-
-       /* release memory */
-
-       DRELEASE;
-}
-
-
-/* trace_exception_builtin *****************************************************
-
-   Traces an exception which is thrown by builtin_throw_exception.
-
-*******************************************************************************/
-
-void trace_exception_builtin(java_object_t *xptr)
-{
-       java_lang_Throwable *t;
-       java_lang_String    *s;
-       char                *logtext;
-       s4                   logtextlen;
-       int32_t              dumpmarker;
-
-       t = (java_lang_Throwable *) xptr;
-
-       /* get detail message */
-       if (t)
-               LLNI_field_get_ref(t, detailMessage, s);
-
-       /* calculate message length */
-
-       logtextlen = strlen("Builtin exception thrown: ") + strlen("0");
-
-       if (t) {
-               logtextlen +=
-                       utf_bytes(xptr->vftbl->clazz->name);
-               if (s) {
-                       logtextlen += strlen(": ") +
-                               u2_utflength(LLNI_field_direct(s, value)->data 
-                                                               + LLNI_field_direct(s, offset),
-                                                        LLNI_field_direct(s,count));
-               }
-       } 
-       else {
-               logtextlen += strlen("(nil)");
-       }
-
-       /* allocate memory */
-
-       DMARKER;
-
-       logtext = DMNEW(char, logtextlen);
-
-       strcpy(logtext, "Builtin exception thrown: ");
-
-       if (t) {
-               utf_cat_classname(logtext, xptr->vftbl->clazz->name);
-
-               if (s) {
-                       char *buf;
-
-                       buf = javastring_tochar((java_handle_t *) s);
-                       strcat(logtext, ": ");
-                       strcat(logtext, buf);
-                       MFREE(buf, char, strlen(buf) + 1);
-               }
-
-       } else {
-               strcat(logtext, "(nil)");
-       }
-
-       log_text(logtext);
-
-       /* release memory */
-
-       DRELEASE;
-}
-
-
-#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/jit/trace.cpp b/src/vm/jit/trace.cpp
new file mode 100644 (file)
index 0000000..3a138e5
--- /dev/null
@@ -0,0 +1,647 @@
+/* src/vm/jit/trace.cpp - Functions for tracing from java code.
+
+   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 "arch.h"
+#include "md-abi.h"
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/options.h"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+
+#include "vm/jit/argument.h"
+#include "vm/jit/codegen-common.h"
+#include "vm/jit/trace.hpp"
+#include "vm/jit/show.h"
+
+
+#if !defined(NDEBUG)
+
+// FIXME For now we export everything as C functions.
+extern "C" {
+
+/* global variables ***********************************************************/
+
+#if !defined(ENABLE_THREADS)
+s4 _no_threads_tracejavacallindent = 0;
+u4 _no_threads_tracejavacallcount= 0;
+#endif
+
+
+/* trace_java_call_print_argument **********************************************
+
+   XXX: Document me!
+
+*******************************************************************************/
+
+static char *trace_java_call_print_argument(methodinfo *m, char *logtext, s4 *logtextlen, typedesc *paramtype, imm_union imu)
+{
+       java_object_t *o;
+       classinfo     *c;
+       utf           *u;
+       u4             len;
+
+       switch (paramtype->type) {
+       case TYPE_INT:
+               sprintf(logtext + strlen(logtext), "%d (0x%08x)", (int32_t)imu.l, (int32_t)imu.l);
+               break;
+
+       case TYPE_LNG:
+#if SIZEOF_VOID_P == 4
+               sprintf(logtext + strlen(logtext), "%lld (0x%016llx)", imu.l, imu.l);
+#else
+               sprintf(logtext + strlen(logtext), "%ld (0x%016lx)", imu.l, imu.l);
+#endif
+               break;
+
+       case TYPE_FLT:
+               sprintf(logtext + strlen(logtext), "%g (0x%08x)", imu.f, imu.i);
+               break;
+
+       case TYPE_DBL:
+#if SIZEOF_VOID_P == 4
+               sprintf(logtext + strlen(logtext), "%g (0x%016llx)", imu.d, imu.l);
+#else
+               sprintf(logtext + strlen(logtext), "%g (0x%016lx)", imu.d, imu.l);
+#endif
+               break;
+
+       case TYPE_ADR:
+#if SIZEOF_VOID_P == 4
+               sprintf(logtext + strlen(logtext), "0x%08x", (ptrint) imu.l);
+#else
+               sprintf(logtext + strlen(logtext), "0x%016lx", (ptrint) imu.l);
+#endif
+
+               /* Workaround for sun.misc.Unsafe methods.  In the future
+                  (exact GC) we should check if the address is on the GC
+                  heap. */
+
+               if ((m->clazz       != NULL) &&
+                       (m->clazz->name == utf_new_char("sun/misc/Unsafe")))
+                       break;
+
+               /* Cast to java.lang.Object. */
+
+               o = (java_object_t *) (ptrint) imu.l;
+
+               /* Check return argument for java.lang.Class or
+                  java.lang.String. */
+
+               if (o != NULL) {
+                       if (o->vftbl->clazz == class_java_lang_String) {
+                               /* get java.lang.String object and the length of the
+                                  string */
+
+                               u = javastring_toutf(o, false);
+
+                               len = strlen(" (String = \"") + utf_bytes(u) + strlen("\")");
+
+                               /* realloc memory for string length */
+
+                               logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len);
+                               *logtextlen += len;
+
+                               /* convert to utf8 string and strcat it to the logtext */
+
+                               strcat(logtext, " (String = \"");
+                               utf_cat(logtext, u);
+                               strcat(logtext, "\")");
+                       }
+                       else {
+                               if (o->vftbl->clazz == class_java_lang_Class) {
+                                       /* if the object returned is a java.lang.Class
+                                          cast it to classinfo structure and get the name
+                                          of the class */
+
+                                       c = (classinfo *) o;
+
+                                       u = c->name;
+                               }
+                               else {
+                                       /* if the object returned is not a java.lang.String or
+                                          a java.lang.Class just print the name of the class */
+
+                                       u = o->vftbl->clazz->name;
+                               }
+
+                               len = strlen(" (Class = \"") + utf_bytes(u) + strlen("\")");
+
+                               /* realloc memory for string length */
+
+                               logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len);
+                               *logtextlen += len;
+
+                               /* strcat to the logtext */
+
+                               strcat(logtext, " (Class = \"");
+                               utf_cat_classname(logtext, u);
+                               strcat(logtext, "\")");
+                       }
+               }
+       }
+
+       return logtext;
+}
+
+/* trace_java_call_enter ******************************************************
+   Traces an entry into a java method.
+
+   arg_regs: Array containing all argument registers as int64_t values in
+   the same order as listed in m->methoddesc. The array is usually allocated
+   on the stack and used for restoring the argument registers later.
+
+   stack: Pointer to first on stack argument in the same format passed to 
+   asm_vm_call_method.
+
+*******************************************************************************/
+
+void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
+{
+       methoddesc *md;
+       imm_union   arg;
+       char       *logtext;
+       s4          logtextlen;
+       s4          i;
+       s4          pos;
+       int32_t     dumpmarker;
+
+       /* We don't trace builtin functions here because the argument
+          passing happens via the native ABI and does not fit these
+          functions. */
+
+       if (method_is_builtin(m))
+               return;
+
+#if defined(ENABLE_DEBUG_FILTER)
+       if (!show_filters_test_verbosecall_enter(m))
+               return;
+#endif
+
+#if defined(ENABLE_VMLOG)
+       vmlog_cacao_enter_method(m);
+       return;
+#endif
+
+       md = m->parseddesc;
+
+       /* calculate message length */
+
+       logtextlen =
+               strlen("4294967295 ") +
+               strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
+               TRACEJAVACALLINDENT +
+               strlen("called: ") +
+               ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
+               strlen(".") +
+               utf_bytes(m->name) +
+               utf_bytes(m->descriptor);
+
+       /* Actually it's not possible to have all flags printed, but:
+          safety first! */
+
+       logtextlen +=
+               strlen(" PUBLIC") +
+               strlen(" PRIVATE") +
+               strlen(" PROTECTED") +
+               strlen(" STATIC") +
+               strlen(" FINAL") +
+               strlen(" SYNCHRONIZED") +
+               strlen(" VOLATILE") +
+               strlen(" TRANSIENT") +
+               strlen(" NATIVE") +
+               strlen(" INTERFACE") +
+               strlen(" ABSTRACT") +
+               strlen(" METHOD_BUILTIN");
+
+       /* add maximal argument length */
+
+       logtextlen +=
+               strlen("(") +
+               strlen("-9223372036854775808 (0x123456789abcdef0), ") * md->paramcount +
+               strlen("...(255)") +
+               strlen(")");
+
+       /* allocate memory */
+
+       DMARKER;
+
+       logtext = DMNEW(char, logtextlen);
+
+       TRACEJAVACALLCOUNT++;
+
+       sprintf(logtext, "%10d ", TRACEJAVACALLCOUNT);
+       sprintf(logtext + strlen(logtext), "-%d-", TRACEJAVACALLINDENT);
+
+       pos = strlen(logtext);
+
+       for (i = 0; i < TRACEJAVACALLINDENT; i++)
+               logtext[pos++] = '\t';
+
+       strcpy(logtext + pos, "called: ");
+
+       if (m->clazz != NULL)
+               utf_cat_classname(logtext, m->clazz->name);
+       else
+               strcat(logtext, "NULL");
+       strcat(logtext, ".");
+       utf_cat(logtext, m->name);
+       utf_cat(logtext, m->descriptor);
+
+       if (m->flags & ACC_PUBLIC)         strcat(logtext, " PUBLIC");
+       if (m->flags & ACC_PRIVATE)        strcat(logtext, " PRIVATE");
+       if (m->flags & ACC_PROTECTED)      strcat(logtext, " PROTECTED");
+       if (m->flags & ACC_STATIC)         strcat(logtext, " STATIC");
+       if (m->flags & ACC_FINAL)          strcat(logtext, " FINAL");
+       if (m->flags & ACC_SYNCHRONIZED)   strcat(logtext, " SYNCHRONIZED");
+       if (m->flags & ACC_VOLATILE)       strcat(logtext, " VOLATILE");
+       if (m->flags & ACC_TRANSIENT)      strcat(logtext, " TRANSIENT");
+       if (m->flags & ACC_NATIVE)         strcat(logtext, " NATIVE");
+       if (m->flags & ACC_INTERFACE)      strcat(logtext, " INTERFACE");
+       if (m->flags & ACC_ABSTRACT)       strcat(logtext, " ABSTRACT");
+
+       strcat(logtext, "(");
+
+       for (i = 0; i < md->paramcount; ++i) {
+               arg = argument_jitarray_load(md, i, arg_regs, stack);
+               logtext = trace_java_call_print_argument(m, logtext, &logtextlen,
+                                                                                                &md->paramtypes[i], arg);
+               if (i != (md->paramcount - 1)) {
+                       strcat(logtext, ", ");
+               }
+       }
+
+       strcat(logtext, ")");
+
+       log_text(logtext);
+
+       /* release memory */
+
+       DRELEASE;
+
+       TRACEJAVACALLINDENT++;
+
+}
+
+/* trace_java_call_exit ********************************************************
+
+   Traces an exit form a java method.
+
+   return_regs: Array of size 1 containing return register.
+   The array is usually allocated on the stack and used for restoring the
+   registers later.
+
+*******************************************************************************/
+
+void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
+{
+       methoddesc *md;
+       char       *logtext;
+       s4          logtextlen;
+       s4          i;
+       s4          pos;
+       imm_union   val;
+       int32_t     dumpmarker;
+
+       /* We don't trace builtin functions here because the argument
+          passing happens via the native ABI and does not fit these
+          functions. */
+
+       if (method_is_builtin(m))
+               return;
+
+#if defined(ENABLE_DEBUG_FILTER)
+       if (!show_filters_test_verbosecall_exit(m))
+               return;
+#endif
+
+#if defined(ENABLE_VMLOG)
+       vmlog_cacao_leave_method(m);
+       return;
+#endif
+
+       md = m->parseddesc;
+
+       /* outdent the log message */
+
+       if (TRACEJAVACALLINDENT)
+               TRACEJAVACALLINDENT--;
+       else
+               log_text("trace_java_call_exit: WARNING: unmatched unindent");
+
+       /* calculate message length */
+
+       logtextlen =
+               strlen("4294967295 ") +
+               strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
+               TRACEJAVACALLINDENT +
+               strlen("finished: ") +
+               ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
+               strlen(".") +
+               utf_bytes(m->name) +
+               utf_bytes(m->descriptor) +
+               strlen(" SYNCHRONIZED") + strlen("(") + strlen(")");
+
+       /* add maximal argument length */
+
+       logtextlen += strlen("->0.4872328470301428 (0x0123456789abcdef)");
+
+       /* allocate memory */
+
+       DMARKER;
+
+       logtext = DMNEW(char, logtextlen);
+
+       /* generate the message */
+
+       sprintf(logtext, "           ");
+       sprintf(logtext + strlen(logtext), "-%d-", TRACEJAVACALLINDENT);
+
+       pos = strlen(logtext);
+
+       for (i = 0; i < TRACEJAVACALLINDENT; i++)
+               logtext[pos++] = '\t';
+
+       strcpy(logtext + pos, "finished: ");
+       if (m->clazz != NULL)
+               utf_cat_classname(logtext, m->clazz->name);
+       else
+               strcat(logtext, "NULL");
+       strcat(logtext, ".");
+       utf_cat(logtext, m->name);
+       utf_cat(logtext, m->descriptor);
+
+       if (!IS_VOID_TYPE(md->returntype.type)) {
+               strcat(logtext, "->");
+               val = argument_jitreturn_load(md, return_regs);
+
+               logtext =
+                       trace_java_call_print_argument(m, logtext, &logtextlen,
+                                                                                  &md->returntype, val);
+       }
+
+       log_text(logtext);
+
+       /* release memory */
+
+       DRELEASE;
+}
+
+
+/* trace_exception *************************************************************
+
+   Traces an exception which is handled by exceptions_handle_exception.
+
+*******************************************************************************/
+
+void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
+{
+       char *logtext;
+       s4    logtextlen;
+       codeinfo *code;
+       int32_t   dumpmarker;
+
+       /* calculate message length */
+
+       if (xptr) {
+               logtextlen =
+                       strlen("Exception ") + utf_bytes(xptr->vftbl->clazz->name);
+       } 
+       else {
+               logtextlen = strlen("Some Throwable");
+       }
+
+       logtextlen += strlen(" thrown in ");
+
+       if (m) {
+               logtextlen +=
+                       utf_bytes(m->clazz->name) +
+                       strlen(".") +
+                       utf_bytes(m->name) +
+                       utf_bytes(m->descriptor) +
+                       strlen("(NOSYNC,NATIVE");
+
+#if SIZEOF_VOID_P == 8
+               logtextlen +=
+                       strlen(")(0x123456789abcdef0) at position 0x123456789abcdef0 (");
+#else
+               logtextlen += strlen(")(0x12345678) at position 0x12345678 (");
+#endif
+
+               if (m->clazz->sourcefile == NULL)
+                       logtextlen += strlen("<NO CLASSFILE INFORMATION>");
+               else
+                       logtextlen += utf_bytes(m->clazz->sourcefile);
+
+               logtextlen += strlen(":65536)");
+
+       } 
+       else {
+               logtextlen += strlen("call_java_method");
+       }
+
+       logtextlen += strlen("0");
+
+       /* allocate memory */
+
+       DMARKER;
+
+       logtext = DMNEW(char, logtextlen);
+
+       if (xptr) {
+               strcpy(logtext, "Exception ");
+               utf_cat_classname(logtext, xptr->vftbl->clazz->name);
+
+       } else {
+               strcpy(logtext, "Some Throwable");
+       }
+
+       strcat(logtext, " thrown in ");
+
+       if (m) {
+               utf_cat_classname(logtext, m->clazz->name);
+               strcat(logtext, ".");
+               utf_cat(logtext, m->name);
+               utf_cat(logtext, m->descriptor);
+
+               if (m->flags & ACC_SYNCHRONIZED)
+                       strcat(logtext, "(SYNC");
+               else
+                       strcat(logtext, "(NOSYNC");
+
+               if (m->flags & ACC_NATIVE) {
+                       strcat(logtext, ",NATIVE");
+
+                       code = m->code;
+
+#if SIZEOF_VOID_P == 8
+                       sprintf(logtext + strlen(logtext),
+                                       ")(0x%016lx) at position 0x%016lx",
+                                       (ptrint) code->entrypoint, (ptrint) pos);
+#else
+                       sprintf(logtext + strlen(logtext),
+                                       ")(0x%08x) at position 0x%08x",
+                                       (ptrint) code->entrypoint, (ptrint) pos);
+#endif
+
+               } else {
+
+                       /* XXX preliminary: This should get the actual codeinfo */
+                       /* in which the exception happened.                     */
+                       code = m->code;
+                       
+#if SIZEOF_VOID_P == 8
+                       sprintf(logtext + strlen(logtext),
+                                       ")(0x%016lx) at position 0x%016lx (",
+                                       (ptrint) code->entrypoint, (ptrint) pos);
+#else
+                       sprintf(logtext + strlen(logtext),
+                                       ")(0x%08x) at position 0x%08x (",
+                                       (ptrint) code->entrypoint, (ptrint) pos);
+#endif
+
+                       if (m->clazz->sourcefile == NULL)
+                               strcat(logtext, "<NO CLASSFILE INFORMATION>");
+                       else
+                               utf_cat(logtext, m->clazz->sourcefile);
+
+                       sprintf(logtext + strlen(logtext), ":%d)", 0);
+               }
+
+       } else
+               strcat(logtext, "call_java_method");
+
+       log_text(logtext);
+
+       /* release memory */
+
+       DRELEASE;
+}
+
+
+/* trace_exception_builtin *****************************************************
+
+   Traces an exception which is thrown by builtin_throw_exception.
+
+*******************************************************************************/
+
+void trace_exception_builtin(java_handle_t* h)
+{
+       char                *logtext;
+       s4                   logtextlen;
+       int32_t              dumpmarker;
+
+       java_lang_Throwable jlt(h);
+
+       // Get detail message.
+       java_handle_t* s = NULL;
+
+       if (jlt.get_handle() != NULL)
+               s = jlt.get_detailMessage();
+
+       java_lang_String jls(s);
+
+       /* calculate message length */
+
+       logtextlen = strlen("Builtin exception thrown: ") + strlen("0");
+
+       if (jlt.get_handle() != NULL) {
+               logtextlen += utf_bytes(jlt.get_vftbl()->clazz->name);
+
+               if (jls.get_handle()) {
+                       // FIXME This is not handle capable!
+                       logtextlen += strlen(": ") +
+                               u2_utflength(jls.get_value()->data + jls.get_offset(), jls.get_count());
+               }
+       } 
+       else {
+               logtextlen += strlen("(nil)");
+       }
+
+       /* allocate memory */
+
+       DMARKER;
+
+       logtext = DMNEW(char, logtextlen);
+
+       strcpy(logtext, "Builtin exception thrown: ");
+
+       if (jlt.get_handle()) {
+               utf_cat_classname(logtext, jlt.get_vftbl()->clazz->name);
+
+               if (s) {
+                       char *buf;
+
+                       buf = javastring_tochar(jls.get_handle());
+                       strcat(logtext, ": ");
+                       strcat(logtext, buf);
+                       MFREE(buf, char, strlen(buf) + 1);
+               }
+
+       } else {
+               strcat(logtext, "(nil)");
+       }
+
+       log_text(logtext);
+
+       /* release memory */
+
+       DRELEASE;
+}
+
+} // extern "C"
+
+#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/jit/trace.h b/src/vm/jit/trace.h
deleted file mode 100644 (file)
index db41359..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* src/vm/jit/trace.h - Functions for tracing from java code.
-
-   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
-
-   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 _VM_JIT_TRACE_H
-#define _VM_JIT_TRACE_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vmcore/method.h"
-
-#if !defined(NDEBUG)
-
-void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack);
-void trace_java_call_exit(methodinfo *m, uint64_t *return_regs);
-
-void trace_exception(java_object_t *xptr, methodinfo *m, void *pos);
-void trace_exception_builtin(java_object_t *xptr);
-
-#endif /* !defined(NDEBUG) */
-
-#endif /* _VM_JIT_TRACE_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/jit/trace.hpp b/src/vm/jit/trace.hpp
new file mode 100644 (file)
index 0000000..06d808d
--- /dev/null
@@ -0,0 +1,70 @@
+/* src/vm/jit/trace.hpp - Functions for tracing from java code.
+
+   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 _VM_JIT_TRACE_HPP
+#define _VM_JIT_TRACE_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/method.h"
+
+#if !defined(NDEBUG)
+
+// FIXME For now we export everything as C functions.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack);
+void trace_java_call_exit(methodinfo *m, uint64_t *return_regs);
+
+void trace_exception(java_object_t *xptr, methodinfo *m, void *pos);
+void trace_exception_builtin(java_object_t *xptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(NDEBUG) */
+
+#endif // _VM_JIT_TRACE_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 d06295235c72847e3bc7dbd4c442d845f3dfdf5e..c6f441d5cc5d4b3debaab66b366ce8106486fbbf 100644 (file)
 
 #include "md-trap.h"
 
+#include "mm/memory.h"
+
 #include "native/llni.h"
 
 #include "toolbox/logging.h"
 
-#include "vm/exceptions.h"
-#include "vm/vm.h"
+#include "vm/exceptions.hpp"
+#include "vm/options.h"
+#include "vm/os.hpp"
+#include "vm/vm.hpp"
 
 #include "vm/jit/code.h"
 #include "vm/jit/disass.h"
 #include "vm/jit/methodtree.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/options.h"
-#include "vmcore/system.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /**
@@ -66,9 +67,9 @@ void trap_init(void)
        /* mmap a memory page at address 0x0, so our hardware-exceptions
           work. */
 
-       pagesize = system_getpagesize();
+       pagesize = os_getpagesize();
 
-       (void) system_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
+       (void) os_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
 #endif
 
        TRACESUBSYSTEMINITIALIZATION("trap_init");
@@ -182,6 +183,15 @@ void* trap_handle(int type, intptr_t val, void *pv, void *sp, void *ra, void *xp
                p = jit_compile_handle(m, sfi.pv, ra, (void *) val);
                break;
 
+#if defined(ENABLE_REPLACEMENT)
+       case TRAP_COUNTDOWN:
+#if defined(__I386__)
+               replace_me_wrapper((char*)xpc - 13, context);
+#endif
+               p = NULL;
+               break;
+#endif
+
        default:
                /* Let's try to get a backtrace. */
 
index 8eb295bd58ed20372165298264b7064e42ca8db7..6a18c35dc696da41776fd8f4841ed72f5c0340a1 100644 (file)
 
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Include machine dependent trap stuff. */
 
 #include "md-trap.h"
 void  trap_init(void);
 void* trap_handle(int type, intptr_t val, void *pv, void *sp, void *ra, void *xpc, void *context);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _TRAP_H */
 
 
index d308d8b790817685de1712d188a6bb5c53787eb2..65adf817db6f44f51b129b69d84b782cf84ad2a6 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/icmds.c - ICMD-specific type checking code
 
-   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.
 
index 5b559438aea9a19fee8fe5e551a133224e407a21..f574a4c07f4a7ad310a015a1d7279bb6c1e811b2 100644 (file)
 
 #include <assert.h>
 
-#include <vm/exceptions.h>
-#include <vm/jit/show.h>
-#include <typecheck-common.h>
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+
+#include "vm/jit/show.h"
+
+#include "typecheck-common.h"
+
 
 /****************************************************************************/
 /* DEBUG HELPERS                                                            */
index 5141dd871d709db94a8f30996905284adc30e718..90c693094bb84e235e8c1a259ccefc921ecb7a16 100644 (file)
 #include "mm/memory.h"
 
 #include "vm/array.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/primitive.h"
+#include "vm/globals.hpp"
+#include "vm/primitive.hpp"
 
 #include "vm/jit/parse.h"
 #include "vm/jit/show.h"
index 35005828ce73aaa81c534a8828c75a1a08097071..1cfeba69da3483b2484e7b0e57817c183671a10c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck-typeinferer.c - type inference pass
 
-   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.
 
 
 #include "toolbox/logging.h"
 
-#include "vm/array.h"
 #include "vm/access.h"
+#include "vm/array.h"
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/primitive.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
 #include "vm/resolve.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/show.h"
@@ -51,9 +52,6 @@
 
 #include "vm/jit/verify/typecheck-typeinferer.h"
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 #define TYPECHECK_NO_STATISTICS
 #include <typecheck-common.h>
 
index e679e952645e0c5ca947763a544f71c797179272..afe2fb62108170213373322bb9e052f0a99189ad 100644 (file)
@@ -150,18 +150,18 @@ error reporting.
 #include "vm/access.h"
 #include "vm/array.h"
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/primitive.h"
+#include "vm/globals.hpp"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
 #include "vm/resolve.h"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/show.h"
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 #include <typecheck-common.h>
 
 
index f31c4c958b982eb569f296cd29ec59b05dff3e94..b39ca9a61716592f1f56c168bb61d9c57eccc151 100644 (file)
 #include "toolbox/logging.h"
 
 #include "vm/array.h"
-#include "vm/exceptions.h"
-#include "vm/primitive.h"
+#include "vm/class.h"
+#include "vm/descriptor.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/loader.h"
+#include "vm/primitive.hpp"
 #include "vm/resolve.h"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/verify/typeinfo.h"
 
-#include "vmcore/class.h"
-#include "vmcore/descriptor.h"
-#include "vmcore/loader.h"
-
 
 /* check if a linked class is an array class. Only use for linked classes! */
 #define CLASSINFO_IS_ARRAY(clsinfo)  ((clsinfo)->vftbl->arraydesc != NULL)
index e35214928f421996efb3fd6f0d1e835c6bca2288..70bfcc11fe1110d6b15630a9723dab72b019b11b 100644 (file)
@@ -35,8 +35,7 @@ typedef struct typedescriptor      typedescriptor_t;
 #include "vm/types.h"
 
 #include "vm/global.h"
-
-#include "vmcore/references.h"
+#include "vm/references.h"
 
 
 /* configuration **************************************************************/
index 839f39c7bcef3faf045f13b81974c4071f50968f..338afc1829057be135aa6146e8f525e7043f1f88 100644 (file)
@@ -28,15 +28,16 @@ LIBS =
 
 DIST_SUBDIRS = \
        freebsd \
-       linux
+       linux \
+       solaris
 
 SUBDIRS = $(OS_DIR)
 
 noinst_HEADERS = \
        arch.h \
-       machine-instr.h \
        \
-       md-asm.h
+       md-asm.h \
+       md-atomic.hpp
 
 noinst_LTLIBRARIES = libarch.la
 
index 4f7a69f9fa074b5c22ccfaed0c05c59ea077b545..5807491ecbac01e65242b9c65be0c10615d4faaa 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008 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.
 
@@ -58,9 +56,6 @@
        .globl asm_builtin_d2i
        .globl asm_builtin_d2l
 
-       .globl asm_compare_and_swap
-       .globl asm_memory_barrier
-
        .globl asm_get_cycle_count
 
 
@@ -394,30 +389,6 @@ asm_builtin_d2l:
        ret
 
 
-/* asm_compare_and_swap ********************************************************
-
-   Does an atomic compare and swap.  Required for the lock
-   implementation.
-
-*******************************************************************************/
-
-asm_compare_and_swap:
-       mov     a1,v0                       /* v0 is %rax                         */
-       lock cmpxchg a2,(a0)
-       ret
-
-
-/* asm_memory_barrier **********************************************************
-
-   A memory barrier for the Java Memory Model.
-
-*******************************************************************************/
-
-asm_memory_barrier:
-       mfence
-       ret
-
-
 /* asm_get_cycle_count *********************************************************
 
    Get the current time-stamp counter from the CPU.
index 88e55caa6759c33c5826b707e482e52eda9a17df..680c82650f30e4b871a31c5c9d07386519230558 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
 
-   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.
 
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/primitive.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/statistics.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
 
 /* codegen_emit ****************************************************************
 
@@ -2499,9 +2496,6 @@ gen_method:
                                        superindex = super->index;
                                }
 
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -2574,8 +2568,6 @@ gen_method:
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ALD(REG_ITMP3, RIP, disp);
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
 
                                        /*                                      if (s1 != REG_ITMP1) { */
@@ -2598,8 +2590,6 @@ gen_method:
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
                                        /*                                      } */
 
-                                       CODEGEN_CRITICAL_SECTION_END;
-
                                        M_ICMP(REG_ITMP3, REG_ITMP2);
                                        emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
 
@@ -2663,9 +2653,6 @@ gen_method:
                                superindex = super->index;
                        }
 
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
 
@@ -2747,14 +2734,10 @@ gen_method:
                                M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_ITMP2, RIP, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_ISUB(REG_ITMP2, REG_ITMP1);
                                M_CLR(d); /* may be REG_ITMP2 */
                                M_ICMP(REG_ITMP3, REG_ITMP1);
@@ -3043,7 +3026,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument register */
 
-               M_MOV_IMM(_Jv_env, REG_A0);
+               M_MOV_IMM(VM_get_jnienv(), REG_A0);
        }
 
        /* Call the native function. */
@@ -3058,7 +3041,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        case TYPE_INT:
        case TYPE_LNG:
        case TYPE_ADR:
-               switch (md->returntype.decltype) {
+               switch (md->returntype.primitivetype) {
                case PRIMITIVETYPE_BOOLEAN:
                        M_BZEXT(REG_RESULT, REG_RESULT);
                        break;
index 163f840c26fb30a299827140c67dd09d93824d9e..92bf938ab92ce85e360fa6e46c0b711bf6d6f3f6 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/x86_64/emit.c - x86_64 code emitter functions
 
-   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.
 
@@ -39,6 +37,8 @@
 
 #include "threads/lock-common.h"
 
+#include "vm/options.h"
+
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
-#include "vmcore/options.h"
-
 
 /* emit_load *******************************************************************
 
index 6e4a2b227853841547c3ab343db497ff64399165..4b683342a409e8298af3c8e412e57cb0b6db21e5 100644 (file)
 #include <stdlib.h>
 #include <ucontext.h>
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/signallocal.h"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -129,25 +129,6 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-#if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       u1         *pc;
-       void       *critical;
-
-       _mc = &_uc->uc_mcontext;
-
-       pc = (u1 *) _mc->mc_rip;
-
-       critical = critical_find_restart_point(pc);
-
-       if (critical != NULL)
-               _mc->mc_rip = (ptrint) critical;
-}
-#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
index 8b8bf32d51f1a44dc0e920b70370ba58d2dd31b5..38d1306e6c953e700a2850379f96c728b9421cb2 100644 (file)
@@ -37,7 +37,7 @@
 #include "vm/jit/x86_64/codegen.h"
 #include "vm/jit/x86_64/md.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/signallocal.h"
@@ -45,7 +45,7 @@
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
 #include "vm/jit/trap.h"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -498,35 +498,6 @@ void md_executionstate_write(executionstate_t *es, void *context)
 }
 
 
-/* md_critical_section_restart *************************************************
-
-   Search the critical sections tree for a matching section and set
-   the PC to the restart point, if necessary.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void md_critical_section_restart(ucontext_t *_uc)
-{
-       mcontext_t *_mc;
-       u1         *pc;
-       u1         *npc;
-
-       _mc = &_uc->uc_mcontext;
-
-       /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
-          different to the ones in <ucontext.h>. */
-
-       pc = (u1 *) _mc->gregs[REG_RIP];
-
-       npc = critical_find_restart_point(pc);
-
-       if (npc != NULL)
-               _mc->gregs[REG_RIP] = (ptrint) npc;
-}
-#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
diff --git a/src/vm/jit/x86_64/machine-instr.h b/src/vm/jit/x86_64/machine-instr.h
deleted file mode 100644 (file)
index 3afe548..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _MACHINE_INSTR_H
-#define _MACHINE_INSTR_H
-
-static inline long
-__attribute__ ((unused))
-compare_and_swap (volatile long *p, long oldval, long newval)
-{
-  long ret;
-
-  __asm__ __volatile__ ("lock; cmpxchgq %2, %1"
-                        : "=a" (ret), "=m" (*p)
-                        : "r" (newval), "m" (*p), "0" (oldval));
-  return ret;
-}
-
-#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() /* nothing */
-#define MEMORY_BARRIER() __asm__ __volatile__ ( \
-               "mfence" : : : "memory" );
-
-#endif
index 9ae511b14cf585da2310a9ee858cabc74953fd4b..d0ef903056b2c0a7fdbfa0b999ea69f7f1390982 100644 (file)
 
 #include "vm/jit/x86_64/md-abi.h"
 
+#include "vm/descriptor.h"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/jit.h" /* for REG_* (maybe can be removed) */
 #include "vm/jit/stack.h"
 
-#include "vmcore/descriptor.h"
-
 
 /* register descripton array **************************************************/
 
diff --git a/src/vm/jit/x86_64/md-atomic.hpp b/src/vm/jit/x86_64/md-atomic.hpp
new file mode 100644 (file)
index 0000000..accef01
--- /dev/null
@@ -0,0 +1,134 @@
+/* src/vm/jit/x86_64/atomic.hpp - x86_64 atomic instructions
+
+   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.
+
+*/
+
+
+#ifndef _MD_ATOMIC_HPP
+#define _MD_ATOMIC_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/atomic.hpp"
+
+
+/**
+ * An atomic compare and swap for 32-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint32_t Atomic::compare_and_swap(volatile uint32_t *p, uint32_t oldval, uint32_t newval)
+{
+       uint32_t result;
+
+       __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+                                                 : "=a" (result), "=m" (*p)
+                                                 : "r" (newval), "m" (*p), "0" (oldval));
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for 64-bit integer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline uint64_t Atomic::compare_and_swap(volatile uint64_t *p, uint64_t oldval, uint64_t newval)
+{
+       uint64_t result;
+
+       __asm__ __volatile__ ("lock; cmpxchgq %2, %1"
+                                                 : "=a" (result), "=m" (*p)
+                                                 : "r" (newval), "m" (*p), "0" (oldval));
+
+       return result;
+}
+
+
+/**
+ * An atomic compare and swap for pointer values.
+ *
+ * @param p      Pointer to memory address.
+ * @param oldval Old value to be expected.
+ * @param newval New value to be stored.
+ *
+ * @return value of the memory location before the store
+ */
+inline void* Atomic::compare_and_swap(volatile void** p, void* oldval, void* newval)
+{
+       return (void*) compare_and_swap((volatile uint64_t*) p, (uint64_t) oldval, (uint64_t) newval);
+}
+
+
+/**
+ * A memory barrier.
+ */
+inline void Atomic::memory_barrier(void)
+{
+       __asm__ __volatile__ ("mfence" : : : "memory");
+}
+
+
+/**
+ * A write memory barrier.
+ */
+inline void Atomic::write_memory_barrier(void)
+{
+       __asm__ __volatile__ ("" : : : "memory");
+}
+
+
+/**
+ * An instruction barrier.
+ */
+inline void Atomic::instruction_barrier(void)
+{
+       // Nothing.
+}
+
+#endif // _MD_ATOMIC_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 6493e3559c089bf6333168e9bab0529a2b586943..c78e31b9540031ca1567b81d8b9a6803662dfc60 100644 (file)
@@ -58,6 +58,7 @@ enum {
        /* Don't use 8 (could be a normal load offset). */
 
        TRAP_COMPILER                       = 9,
+       TRAP_COUNTDOWN                      = 10,
        TRAP_END
 };
 
index dc4b3fab1820ca149ac1d34817c35a15200c9e92..75a61687a8a2e4126f4d47d1a4ea1c557f4f2341 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/x86_64/md.c - machine dependent x86_64 functions
 
-   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.
 
@@ -33,7 +31,7 @@
 
 #include "vm/jit/x86_64/md-abi.h"
 
-#include "vm/vm.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/jit.h"
index be30afa3759f0711b57cb8b7fbf489d81480707f..18e81ddc69e2c9677b44443dfbe1786e16eea900 100644 (file)
 #include "native/native.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
 
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
-#include "vm/resolve.h"
 
 
 #define PATCH_BACK_ORIGINAL_MCODE \
diff --git a/src/vm/jit/x86_64/solaris/Makefile.am b/src/vm/jit/x86_64/solaris/Makefile.am
new file mode 100644 (file)
index 0000000..aea86fd
--- /dev/null
@@ -0,0 +1,43 @@
+## src/vm/jit/x86_64/solaris/Makefile.am
+##
+## 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.
+
+
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_builddir)/src
+
+LIBS =
+
+noinst_HEADERS =
+
+noinst_LTLIBRARIES = \
+       libmd.la
+
+libmd_la_SOURCES = \
+       md-os.c
+
+
+## Local variables:
+## mode: Makefile
+## indent-tabs-mode: t
+## c-basic-offset: 4
+## tab-width: 8
+## compile-command: "automake --add-missing"
+## End:
diff --git a/src/vm/jit/x86_64/solaris/md-os.c b/src/vm/jit/x86_64/solaris/md-os.c
new file mode 100644 (file)
index 0000000..5619c9b
--- /dev/null
@@ -0,0 +1,525 @@
+/* src/vm/jit/x86_64/solaris/md-os.c - machine dependent x86_64 Solaris functions
+
+   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.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+#include "vm/types.h"
+
+#include "vm/jit/x86_64/codegen.h"
+#include "vm/jit/x86_64/md.h"
+
+#include "threads/thread.hpp"
+
+#include "vm/builtin.h"
+#include "vm/signallocal.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
+#include "vm/jit/trap.h"
+#include "vm/jit/stacktrace.hpp"
+
+
+/* md_signal_handler_sigsegv ***************************************************
+
+   Signal handler for hardware exception.
+
+*******************************************************************************/
+
+void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
+{
+       ucontext_t     *_uc;
+       mcontext_t     *_mc;
+       void           *pv;
+       u1             *sp;
+       u1             *ra;
+       u1             *xpc;
+       u1              opc;
+       u1              mod;
+       u1              rm;
+       s4              d;
+       s4              disp;
+       int             type;
+       intptr_t        val;
+       void           *p;
+       java_object_t  *o;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
+          different to the ones in <ucontext.h>. */
+
+       pv  = NULL;                 /* is resolved during stackframeinfo creation */
+       sp  = (u1 *) _mc->gregs[REG_RSP];
+       xpc = (u1 *) _mc->gregs[REG_RIP];
+       ra  = xpc;                              /* return address is equal to XPC */
+
+#if 0
+       /* check for StackOverflowException */
+
+       threads_check_stackoverflow(sp);
+#endif
+
+       /* get exception-throwing instruction */
+
+       opc = M_ALD_MEM_GET_OPC(xpc);
+       mod = M_ALD_MEM_GET_MOD(xpc);
+       rm  = M_ALD_MEM_GET_RM(xpc);
+
+       /* for values see emit_mov_mem_reg and emit_mem */
+
+       if ((opc == 0x8b) && (mod == 0) && (rm == 4)) {
+               /* this was a hardware-exception */
+
+               d    = M_ALD_MEM_GET_REG(xpc);
+               disp = M_ALD_MEM_GET_DISP(xpc);
+
+               /* we use the exception type as load displacement */
+
+               type = disp;
+
+               /* XXX FIX ME! */
+
+               /* ATTENTION: The _mc->gregs layout is even worse than on
+                  i386! See /usr/include/sys/ucontext.h.  We need a
+                  switch-case here... */
+
+               switch (d) {
+               case 0:  /* REG_RAX == 14 */
+                       d = REG_RAX;
+                       break;
+               case 1:  /* REG_RCX == 13 */
+                       d = REG_RCX;
+                       break;
+               case 2:  /* REG_RDX == 12 */
+                       d = REG_RDX;
+                       break;
+               case 3:  /* REG_RBX == 11 */
+                       d = REG_RBX;
+                       break;
+               case 4:  /* REG_RSP == 20 */
+                       d = REG_RSP;
+                       break;
+               case 5:  /* REG_RBP == 10 */
+                       d = REG_RBP;
+                       break;
+               case 6:  /* REG_RSI == 9  */
+                       d = REG_RSI;
+                       break;
+               case 7:  /* REG_RDI == 8  */
+                       d = REG_RDI;
+                       break;
+               case 8:  /* REG_R8  == 7  */
+                       d = REG_R8;
+                       break;
+               case 9:  /* REG_R9  == 6  */
+                       d = REG_R9;
+                       break;
+               case 10: /* REG_R10 == 5  */
+                       d = REG_R10;
+                       break;
+               case 11: /* REG_R11 == 4  */
+                       d = REG_R11;
+                       break;
+               case 12: /* REG_R12 == 3  */
+                       d = REG_R12;
+                       break;
+               case 13: /* REG_R13 == 2  */
+                       d = REG_R13;
+                       break;
+               case 14: /* REG_R14 == 1  */
+                       d = REG_R14;
+                       break;
+               case 15: /* REG_R15 == 0  */
+                       d = REG_R15;
+                       break;
+               }
+
+               val = _mc->gregs[d];
+
+               if (type == TRAP_COMPILER) {
+                       /* The PV from the compiler stub is equal to the XPC. */
+
+                       pv = xpc;
+
+                       /* We use a framesize of zero here because the call pushed
+                          the return addres onto the stack. */
+
+                       ra = md_stacktrace_get_returnaddress(sp, 0);
+
+                       /* Skip the RA on the stack. */
+
+                       sp = sp + 1 * SIZEOF_VOID_P;
+
+                       /* The XPC is the RA minus 1, because the RA points to the
+                          instruction after the call. */
+
+                       xpc = ra - 3;
+               }
+       }
+       else {
+               /* this was a normal NPE */
+
+               type = TRAP_NullPointerException;
+               val  = 0;
+       }
+
+       /* Handle the trap. */
+
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
+
+       /* Set registers. */
+
+       if (type == TRAP_COMPILER) {
+               if (p == NULL) {
+                       o = builtin_retrieve_exception();
+
+                       _mc->gregs[REG_RSP] = (uintptr_t) sp;    /* Remove RA from stack. */
+
+                       _mc->gregs[REG_RAX] = (uintptr_t) o;
+                       _mc->gregs[REG_R10] = (uintptr_t) xpc;           /* REG_ITMP2_XPC */
+                       _mc->gregs[REG_RIP] = (uintptr_t) asm_handle_exception;
+               }
+               else {
+                       _mc->gregs[REG_RIP] = (uintptr_t) p;
+               }
+       }
+       else {
+               _mc->gregs[REG_RAX] = (uintptr_t) p;
+               _mc->gregs[REG_R10] = (uintptr_t) xpc;               /* REG_ITMP2_XPC */
+               _mc->gregs[REG_RIP] = (uintptr_t) asm_handle_exception;
+       }
+}
+
+
+/* md_signal_handler_sigfpe ****************************************************
+
+   ArithmeticException signal handler for hardware divide by zero
+   check.
+
+*******************************************************************************/
+
+void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
+{
+       ucontext_t     *_uc;
+       mcontext_t     *_mc;
+       u1             *pv;
+       u1             *sp;
+       u1             *ra;
+       u1             *xpc;
+       int             type;
+       intptr_t        val;
+       void           *p;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
+          different to the ones in <ucontext.h>. */
+
+       pv  = NULL;
+       sp  = (u1 *) _mc->gregs[REG_RSP];
+       xpc = (u1 *) _mc->gregs[REG_RIP];
+       ra  = xpc;                          /* return address is equal to xpc     */
+
+       /* This is an ArithmeticException. */
+
+       type = TRAP_ArithmeticException;
+       val  = 0;
+
+       /* Handle the trap. */
+
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
+
+       /* set registers */
+
+       _mc->gregs[REG_RAX] = (intptr_t) p;
+       _mc->gregs[REG_R10] = (intptr_t) xpc;                    /* REG_ITMP2_XPC */
+       _mc->gregs[REG_RIP] = (intptr_t) asm_handle_exception;
+}
+
+
+/* md_signal_handler_sigill ****************************************************
+
+   Signal handler for patchers.
+
+*******************************************************************************/
+
+void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
+{
+       ucontext_t     *_uc;
+       mcontext_t     *_mc;
+       u1             *pv;
+       u1             *sp;
+       u1             *ra;
+       u1             *xpc;
+       int             type;
+       intptr_t        val;
+       void           *p;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
+          different to the ones in <ucontext.h>. */
+
+       pv  = NULL;
+       sp  = (u1 *) _mc->gregs[REG_RSP];
+       xpc = (u1 *) _mc->gregs[REG_RIP];
+       ra  = xpc;                          /* return address is equal to xpc     */
+
+       /* This is a patcher. */
+
+       type = TRAP_PATCHER;
+       val  = 0;
+
+       /* Handle the trap. */
+
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
+
+       /* set registers */
+
+       if (p != NULL) {
+               _mc->gregs[REG_RAX] = (intptr_t) p;
+               _mc->gregs[REG_R10] = (intptr_t) xpc;                /* REG_ITMP2_XPC */
+               _mc->gregs[REG_RIP] = (intptr_t) asm_handle_exception;
+       }
+}
+
+
+/* md_signal_handler_sigusr1 ***************************************************
+
+   Signal handler for suspending threads.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+void md_signal_handler_sigusr1(int sig, siginfo_t *siginfo, void *_p)
+{
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       u1         *pc;
+       u1         *sp;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
+          different to the ones in <ucontext.h>. */
+
+       /* get the PC and SP for this thread */
+       pc = (u1 *) _mc->gregs[REG_RIP];
+       sp = (u1 *) _mc->gregs[REG_RSP];
+
+       /* now suspend the current thread */
+       threads_suspend_ack(pc, sp);
+}
+#endif
+
+
+/* md_signal_handler_sigusr2 ***************************************************
+
+   Signal handler for profiling sampling.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS)
+void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
+{
+       threadobject *t;
+       ucontext_t   *_uc;
+       mcontext_t   *_mc;
+       u1           *pc;
+
+       t = THREADOBJECT;
+
+       _uc = (ucontext_t *) _p;
+       _mc = &_uc->uc_mcontext;
+
+       /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
+          different to the ones in <ucontext.h>. */
+
+       pc = (u1 *) _mc->gregs[REG_RIP];
+
+       t->pc = pc;
+}
+#endif
+
+
+/* md_executionstate_read ******************************************************
+
+   Read the given context into an executionstate.
+
+*******************************************************************************/
+
+void md_executionstate_read(executionstate_t *es, void *context)
+{
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       s4          i;
+       s4          d;
+
+       _uc = (ucontext_t *) context;
+       _mc = &_uc->uc_mcontext;
+
+       /* read special registers */
+       es->pc = (u1 *) _mc->gregs[REG_RIP];
+       es->sp = (u1 *) _mc->gregs[REG_RSP];
+       es->pv = NULL;
+
+       /* read integer registers */
+       for (i = 0; i < INT_REG_CNT; i++) {
+               /* XXX FIX ME! */
+
+               switch (i) {
+               case 0:  /* REG_RAX == 13 */
+                       d = REG_RAX;
+                       break;
+               case 1:  /* REG_RCX == 14 */
+                       d = REG_RCX;
+                       break;
+               case 2:  /* REG_RDX == 12 */
+                       d = REG_RDX;
+                       break;
+               case 3:  /* REG_RBX == 11 */
+                       d = REG_RBX;
+                       break;
+               case 4:  /* REG_RSP == 15 */
+                       d = REG_RSP;
+                       break;
+               case 5:  /* REG_RBP == 10 */
+                       d = REG_RBP;
+                       break;
+               case 6:  /* REG_RSI == 9  */
+                       d = REG_RSI;
+                       break;
+               case 7:  /* REG_RDI == 8  */
+                       d = REG_RDI;
+                       break;
+               case 8:  /* REG_R8  == 0  */
+               case 9:  /* REG_R9  == 1  */
+               case 10: /* REG_R10 == 2  */
+               case 11: /* REG_R11 == 3  */
+               case 12: /* REG_R12 == 4  */
+               case 13: /* REG_R13 == 5  */
+               case 14: /* REG_R14 == 6  */
+               case 15: /* REG_R15 == 7  */
+                       d = i - 8;
+                       break;
+               }
+
+               es->intregs[i] = _mc->gregs[d];
+       }
+
+       /* read float registers */
+       for (i = 0; i < FLT_REG_CNT; i++)
+               es->fltregs[i] = 0xdeadbeefdeadbeefL;
+}
+
+
+/* md_executionstate_write *****************************************************
+
+   Write the given executionstate back to the context.
+
+*******************************************************************************/
+
+void md_executionstate_write(executionstate_t *es, void *context)
+{
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       s4          i;
+       s4          d;
+
+       _uc = (ucontext_t *) context;
+       _mc = &_uc->uc_mcontext;
+
+       /* write integer registers */
+       for (i = 0; i < INT_REG_CNT; i++) {
+               /* XXX FIX ME! */
+
+               switch (i) {
+               case 0:  /* REG_RAX == 13 */
+                       d = REG_RAX;
+                       break;
+               case 1:  /* REG_RCX == 14 */
+                       d = REG_RCX;
+                       break;
+               case 2:  /* REG_RDX == 12 */
+                       d = REG_RDX;
+                       break;
+               case 3:  /* REG_RBX == 11 */
+                       d = REG_RBX;
+                       break;
+               case 4:  /* REG_RSP == 15 */
+                       d = REG_RSP;
+                       break;
+               case 5:  /* REG_RBP == 10 */
+                       d = REG_RBP;
+                       break;
+               case 6:  /* REG_RSI == 9  */
+                       d = REG_RSI;
+                       break;
+               case 7:  /* REG_RDI == 8  */
+                       d = REG_RDI;
+                       break;
+               case 8:  /* REG_R8  == 0  */
+               case 9:  /* REG_R9  == 1  */
+               case 10: /* REG_R10 == 2  */
+               case 11: /* REG_R11 == 3  */
+               case 12: /* REG_R12 == 4  */
+               case 13: /* REG_R13 == 5  */
+               case 14: /* REG_R14 == 6  */
+               case 15: /* REG_R15 == 7  */
+                       d = i - 8;
+                       break;
+               }
+
+               _mc->gregs[d] = es->intregs[i];
+       }
+
+       /* write special registers */
+       _mc->gregs[REG_RIP] = (ptrint) es->pc;
+       _mc->gregs[REG_RSP] = (ptrint) es->sp;
+}
+
+
+/*
+ * 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/jit_interface.h b/src/vm/jit_interface.h
deleted file mode 100644 (file)
index 89fbf61..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* src/vm/jit_interface.h - prototypes of jit functions used in vm/ code
-
-   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 _JIT_INTERFACE
-#define _JIT_INTERFACE
-
-#include "config.h"
-#include "vm/types.h"
-
-
-/* These functions are used from vm/ but defined in vm/jit/ */
-
-void code_free_code_of_method(methodinfo *m);
-
-u1       *codegen_generate_stub_compiler(methodinfo *m);
-codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f);
-
-#if defined(ENABLE_INTRP)
-u1 *intrp_createcompilerstub(methodinfo *m);
-#endif
-
-void removecompilerstub(u1 *stub);
-void removenativestub(u1 *stub);
-
-void jit_invalidate_code(methodinfo *m);
-
-void md_param_alloc(methoddesc *md);
-void md_param_alloc_native(methoddesc *md);
-
-/* stub for throwing AbstractMethodError's */
-#if defined(ENABLE_JIT)
-void asm_abstractmethoderror(void);
-#endif
-
-#if defined(ENABLE_INTRP)
-void intrp_asm_abstractmethoderror(void);
-#endif
-
-#endif /* _JIT_INTERFACE */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
diff --git a/src/vm/linker.c b/src/vm/linker.c
new file mode 100644 (file)
index 0000000..622935c
--- /dev/null
@@ -0,0 +1,1320 @@
+/* src/vm/linker.c - class linker functions
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/native.h"
+
+#include "threads/lock-common.h"
+
+#include "toolbox/logging.h"
+
+#include "vm/access.h"
+#include "vm/array.h"
+#include "vm/class.h"
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/rt-timing.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+#include "vm/jit/asmpart.h"
+
+
+/* debugging macros ***********************************************************/
+
+#if !defined(NDEBUG)
+# define TRACELINKCLASS(c) \
+    do { \
+        if (opt_TraceLinkClass) { \
+            log_start(); \
+            log_print("[Linking "); \
+            class_print((c)); \
+            log_print("]"); \
+            log_finish(); \
+        } \
+    } while (0)
+#else
+# define TRACELINKCLASS(c)
+#endif
+
+
+/* #include "vm/resolve.h" */
+/* copied prototype to avoid bootstrapping problem: */
+classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#if !defined(NDEBUG) && defined(ENABLE_INLINING)
+#define INLINELOG(code)  do { if (opt_TraceInlining) { code } } while (0)
+#else
+#define INLINELOG(code)
+#endif
+
+
+/* global variables ***********************************************************/
+
+static s4 interfaceindex;       /* sequential numbering of interfaces         */
+static s4 classvalue;
+
+java_object_t *linker_classrenumber_lock;
+
+
+/* private functions **********************************************************/
+
+static classinfo *link_class_intern(classinfo *c);
+static arraydescriptor *link_array(classinfo *c);
+static void linker_compute_class_values(classinfo *c);
+static void linker_compute_subclasses(classinfo *c);
+static bool linker_addinterface(classinfo *c, classinfo *ic);
+static s4 class_highestinterface(classinfo *c);
+
+
+/* linker_init *****************************************************************
+
+   Initializes the linker subsystem and links classes required for the
+   primitive table.
+
+*******************************************************************************/
+
+void linker_preinit(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("linker_preinit");
+
+       /* Reset interface index. */
+
+       interfaceindex = 0;
+
+#if defined(ENABLE_THREADS)
+       /* create the global lock object */
+
+       linker_classrenumber_lock = NEW(java_object_t);
+
+       LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
+#endif
+
+       /* Link the most basic classes. */
+
+       if (!link_class(class_java_lang_Object))
+               vm_abort("linker_preinit: linking java/lang/Object failed");
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_Cloneable))
+               vm_abort("linker_preinit: linking java/lang/Cloneable failed");
+
+       if (!link_class(class_java_io_Serializable))
+               vm_abort("linker_preinit: linking java/io/Serializable failed");
+#endif
+}
+
+
+/* linker_init *****************************************************************
+
+   Links all classes required in the VM.
+
+*******************************************************************************/
+
+void linker_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("linker_init");
+
+       /* Link java.lang.Class as first class of the system, because we
+       need it's vftbl for all other classes so we can use a class as
+       object. */
+
+       if (!link_class(class_java_lang_Class))
+               vm_abort("linker_init: linking java/lang/Class failed");
+
+       /* Now set the header.vftbl of all classes which were created
+       before java.lang.Class was linked. */
+
+       class_postset_header_vftbl();
+
+       /* Link primitive-type wrapping classes. */
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_Void))
+               vm_abort("linker_init: linking failed");
+#endif
+
+       if (!link_class(class_java_lang_Boolean))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Byte))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Character))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Short))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Integer))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Long))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Float))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Double))
+               vm_abort("linker_init: linking failed");
+
+       /* Link important system classes. */
+
+       if (!link_class(class_java_lang_String))
+               vm_abort("linker_init: linking java/lang/String failed");
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_ClassLoader))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_SecurityManager))
+               vm_abort("linker_init: linking failed");
+#endif
+
+       if (!link_class(class_java_lang_System))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Thread))
+               vm_abort("linker_init: linking failed");
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_ThreadGroup))
+               vm_abort("linker_init: linking failed");
+#endif
+
+       if (!link_class(class_java_lang_Throwable))
+               vm_abort("linker_init: linking failed");
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       if (!link_class(class_java_lang_VMSystem))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_VMThread))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_VMThrowable))
+               vm_abort("linker_init: linking failed");
+#endif
+
+       /* Important system exceptions. */
+
+       if (!link_class(class_java_lang_Exception))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_ClassNotFoundException))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_RuntimeException))
+               vm_abort("linker_init: linking failed");
+
+       /* some classes which may be used more often */
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_StackTraceElement))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_Constructor))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_Field))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_Method))
+               vm_abort("linker_init: linking failed");
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       if (!link_class(class_java_lang_reflect_VMConstructor))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_VMField))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_VMMethod))
+               vm_abort("linker_init: linking failed");
+# endif
+
+       if (!link_class(class_java_security_PrivilegedAction))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_util_Vector))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_util_HashMap))
+               vm_abort("linker_init: linking failed");
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       if (!link_class(class_sun_misc_Signal))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_sun_reflect_MagicAccessorImpl))
+               vm_abort("linker_init: linking failed");
+# endif
+
+       if (!link_class(arrayclass_java_lang_Object))
+               vm_abort("linker_init: linking failed");
+#endif
+
+
+       /* create pseudo classes used by the typechecker */
+
+    /* pseudo class for Arraystubs (extends java.lang.Object) */
+
+       pseudo_class_Arraystub                   =
+               class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
+       pseudo_class_Arraystub->state           |= CLASS_LOADED;
+       pseudo_class_Arraystub->super            = class_java_lang_Object;
+
+#if defined(ENABLE_JAVASE)
+
+       pseudo_class_Arraystub->interfacescount  = 2;
+       pseudo_class_Arraystub->interfaces       = MNEW(classinfo*, 2);
+       pseudo_class_Arraystub->interfaces[0]    = class_java_lang_Cloneable;
+       pseudo_class_Arraystub->interfaces[1]    = class_java_io_Serializable;
+
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+
+       pseudo_class_Arraystub->interfacescount    = 0;
+       pseudo_class_Arraystub->interfaces         = NULL;
+
+#else
+# error unknown Java configuration
+#endif
+
+       if (!classcache_store_unique(pseudo_class_Arraystub))
+               vm_abort("linker_init: could not cache pseudo_class_Arraystub");
+
+       if (!link_class(pseudo_class_Arraystub))
+               vm_abort("linker_init: linking pseudo_class_Arraystub failed");
+
+       /* pseudo class representing the null type */
+
+       pseudo_class_Null         = class_create_classinfo(utf_new_char("$NULL$"));
+       pseudo_class_Null->state |= CLASS_LOADED;
+       pseudo_class_Null->super  = class_java_lang_Object;
+
+       if (!classcache_store_unique(pseudo_class_Null))
+               vm_abort("linker_init: could not cache pseudo_class_Null");
+
+       if (!link_class(pseudo_class_Null))
+               vm_abort("linker_init: linking failed");
+
+       /* pseudo class representing new uninitialized objects */
+    
+       pseudo_class_New         = class_create_classinfo(utf_new_char("$NEW$"));
+       pseudo_class_New->state |= CLASS_LOADED;
+       pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
+       pseudo_class_New->super  = class_java_lang_Object;
+
+       if (!classcache_store_unique(pseudo_class_New))
+               vm_abort("linker_init: could not cache pseudo_class_New");
+
+       /* Correct vftbl-entries (retarded loading and linking of class
+          java/lang/String). */
+
+       stringtable_update();
+}
+
+
+/* link_class ******************************************************************
+
+   Wrapper function for link_class_intern to ease monitor enter/exit
+   and exception handling.
+
+*******************************************************************************/
+
+classinfo *link_class(classinfo *c)
+{
+       classinfo *r;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       if (c == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       LOCK_MONITOR_ENTER(c);
+
+       /* Maybe the class is currently linking or is already linked.*/
+
+       if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
+               LOCK_MONITOR_EXIT(c);
+
+               return c;
+       }
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getcompilingtime)
+               compilingtime_stop();
+
+       if (opt_getloadingtime)
+               loadingtime_start();
+#endif
+
+       /* call the internal function */
+
+       r = link_class_intern(c);
+
+       /* If return value is NULL, we had a problem and the class is not
+          linked. */
+
+       if (r == NULL)
+               c->state &= ~CLASS_LINKING;
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_stop();
+
+       if (opt_getcompilingtime)
+               compilingtime_start();
+#endif
+
+       LOCK_MONITOR_EXIT(c);
+
+       RT_TIMING_GET_TIME(time_end);
+
+       RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
+
+       return r;
+}
+
+
+/* linker_overwrite_method *****************************************************
+
+   Overwrite a method with another one, update method flags and check
+   assumptions.
+
+   IN:
+      mg................the general method being overwritten
+         ms................the overwriting (more specialized) method
+         wl................worklist where to add invalidated methods
+
+   RETURN VALUE:
+      true..............everything ok
+         false.............an exception has been thrown
+
+*******************************************************************************/
+
+static bool linker_overwrite_method(methodinfo *mg,
+                                                                       methodinfo *ms,
+                                                                       method_worklist **wl)
+{
+       classinfo *cg;
+       classinfo *cs;
+
+       cg = mg->clazz;
+       cs = ms->clazz;
+
+       /* overriding a final method is illegal */
+
+       if (mg->flags & ACC_FINAL) {
+               exceptions_throw_verifyerror(mg, "Overriding final method");
+               return false;
+       }
+
+       /* method ms overwrites method mg */
+
+#if defined(ENABLE_VERIFIER)
+       /* Add loading constraints (for the more general types of method mg). */
+       /* Not for <init>, as it is not invoked virtually.                    */
+
+       if ((ms->name != utf_init)
+                       && !classcache_add_constraints_for_params(
+                               cs->classloader, cg->classloader, mg))
+       {
+               return false;
+       }
+#endif
+
+       /* inherit the vftbl index, and record the overwriting */
+
+       ms->vftblindex = mg->vftblindex;
+       ms->overwrites = mg;
+
+       /* update flags and check assumptions */
+       /* <init> methods are a special case, as they are never dispatched dynamically */
+
+       if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
+               do {
+
+#if defined(ENABLE_TLH)
+                       if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
+                               printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
+                                       ms->clazz->name->text, ms->name->text);
+                               ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;                                 
+                       }
+#endif
+
+                       if (mg->flags & ACC_METHOD_IMPLEMENTED) {
+                               /* this adds another implementation */
+
+                               mg->flags &= ~ACC_METHOD_MONOMORPHIC;
+
+                               INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
+
+                               method_break_assumption_monomorphic(mg, wl);
+                       }
+                       else {
+                               /* this is the first implementation */
+
+                               mg->flags |= ACC_METHOD_IMPLEMENTED;
+
+                               INLINELOG( printf("becomes implemented: "); method_println(mg); );
+                       }
+
+                       ms = mg;
+                       mg = mg->overwrites;
+               } while (mg != NULL);
+       }
+
+       return true;
+}
+
+
+/* link_class_intern ***********************************************************
+
+   Tries to link a class. The function calculates the length in bytes
+   that an instance of this class requires as well as the VTBL for
+   methods and interface methods.
+       
+*******************************************************************************/
+
+static classinfo *link_class_intern(classinfo *c)
+{
+       classinfo *super;             /* super class                              */
+       classinfo *tc;                /* temporary class variable                 */
+       s4 supervftbllength;          /* vftbllegnth of super class               */
+       s4 vftbllength;               /* vftbllength of current class             */
+       s4 interfacetablelength;      /* interface table length                   */
+       vftbl_t *v;                   /* vftbl of current class                   */
+       s4 i;                         /* interface/method/field counter           */
+       arraydescriptor *arraydesc;   /* descriptor for array classes             */
+       method_worklist *worklist;    /* worklist for recompilation               */
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_resolving, time_compute_vftbl,
+                                       time_abstract, time_compute_iftbl, time_fill_vftbl,
+                                       time_offsets, time_fill_iftbl, time_finalizer,
+                                       time_subclasses;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       TRACELINKCLASS(c);
+
+       /* the class must be loaded */
+
+       /* XXX should this be a specific exception? */
+       assert(c->state & CLASS_LOADED);
+
+       /* This is check in link_class. */
+
+       assert(!(c->state & CLASS_LINKED));
+
+       /* cache the self-reference of this class                          */
+       /* we do this for cases where the defining loader of the class     */
+       /* has not yet been recorded as an initiating loader for the class */
+       /* this is needed so subsequent code can assume that self-refs     */
+       /* will always resolve lazily                                      */
+       /* No need to do it for the bootloader - it is always registered   */
+       /* as initiating loader for the classes it loads.                  */
+       if (c->classloader)
+               classcache_store(c->classloader,c,false);
+
+       /* this class is currently linking */
+
+       c->state |= CLASS_LINKING;
+
+       arraydesc = NULL;
+       worklist = NULL;
+
+       /* Link the super interfaces. */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               tc = c->interfaces[i];
+
+               if (!(tc->state & CLASS_LINKED))
+                       if (!link_class(tc))
+                               return NULL;
+       }
+       
+       /* check super class */
+
+       super = NULL;
+
+       /* Check for java/lang/Object. */
+
+       if (c->super == NULL) {
+               c->index = 0;
+               c->instancesize = sizeof(java_object_t);
+               
+               vftbllength = supervftbllength = 0;
+
+               c->finalizer = NULL;
+       }
+       else {
+               /* Get super class. */
+
+               super = c->super;
+
+               /* Link the super class if necessary. */
+               
+               if (!(super->state & CLASS_LINKED))
+                       if (!link_class(super))
+                               return NULL;
+
+               /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
+                  flags. */
+
+               c->flags |= (super->flags &
+                                        (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
+
+               /* handle array classes */
+
+               if (c->name->text[0] == '[')
+                       if (!(arraydesc = link_array(c)))
+                               return NULL;
+
+               if (c->flags & ACC_INTERFACE)
+                       c->index = interfaceindex++;
+               else
+                       c->index = super->index + 1;
+               
+               c->instancesize = super->instancesize;
+
+               vftbllength = supervftbllength = super->vftbl->vftbllength;
+               
+               c->finalizer = super->finalizer;
+       }
+       RT_TIMING_GET_TIME(time_resolving);
+
+
+       /* compute vftbl length */
+
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+
+               if (!(m->flags & ACC_STATIC)) { /* is instance method */
+                       tc = super;
+
+                       while (tc) {
+                               s4 j;
+
+                               for (j = 0; j < tc->methodscount; j++) {
+                                       if (method_canoverwrite(m, &(tc->methods[j]))) {
+                                               if (tc->methods[j].flags & ACC_PRIVATE)
+                                                       goto notfoundvftblindex;
+
+                                               /* package-private methods in other packages */
+                                               /* must not be overridden                    */
+                                               /* (see Java Language Specification 8.4.8.1) */
+                                               if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
+                                                        && !SAME_PACKAGE(c,tc) ) 
+                                               {
+                                                   goto notfoundvftblindex;
+                                               }
+
+                                               if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
+                                                       return NULL;
+
+                                               goto foundvftblindex;
+                                       }
+                               }
+
+                               tc = tc->super;
+                       }
+
+               notfoundvftblindex:
+                       m->vftblindex = (vftbllength++);
+               foundvftblindex:
+                       ;
+               }
+       }
+       RT_TIMING_GET_TIME(time_compute_vftbl);
+
+
+       /* Check all interfaces of an abstract class (maybe be an
+          interface too) for unimplemented methods.  Such methods are
+          called miranda-methods and are marked with the ACC_MIRANDA
+          flag.  VMClass.getDeclaredMethods does not return such
+          methods. */
+
+       if (c->flags & ACC_ABSTRACT) {
+               classinfo  *ic;
+               methodinfo *im;
+               s4 abstractmethodscount;
+               s4 j;
+               s4 k;
+
+               abstractmethodscount = 0;
+
+               /* check all interfaces of the abstract class */
+
+               for (i = 0; i < c->interfacescount; i++) {
+                       ic = c->interfaces[i];
+
+                       for (j = 0; j < ic->methodscount; j++) {
+                               im = &(ic->methods[j]);
+
+                               /* skip `<clinit>' and `<init>' */
+
+                               if ((im->name == utf_clinit) || (im->name == utf_init))
+                                       continue;
+
+                               for (tc = c; tc != NULL; tc = tc->super) {
+                                       for (k = 0; k < tc->methodscount; k++) {
+                                               if (method_canoverwrite(im, &(tc->methods[k])))
+                                                       goto noabstractmethod;
+                                       }
+                               }
+
+                               abstractmethodscount++;
+
+                       noabstractmethod:
+                               ;
+                       }
+               }
+
+               if (abstractmethodscount > 0) {
+                       methodinfo *am;
+
+                       /* reallocate methods memory */
+
+                       c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
+                                                                 c->methodscount + abstractmethodscount);
+
+                       for (i = 0; i < c->interfacescount; i++) {
+                               ic = c->interfaces[i];
+
+                               for (j = 0; j < ic->methodscount; j++) {
+                                       im = &(ic->methods[j]);
+
+                                       /* skip `<clinit>' and `<init>' */
+
+                                       if ((im->name == utf_clinit) || (im->name == utf_init))
+                                               continue;
+
+                                       for (tc = c; tc != NULL; tc = tc->super) {
+                                               for (k = 0; k < tc->methodscount; k++) {
+                                                       if (method_canoverwrite(im, &(tc->methods[k])))
+                                                               goto noabstractmethod2;
+                                               }
+                                       }
+
+                                       /* Copy the method found into the new c->methods
+                                          array and tag it as miranda-method. */
+
+                                       am = &(c->methods[c->methodscount]);
+                                       c->methodscount++;
+
+                                       MCOPY(am, im, methodinfo, 1);
+
+                                       am->vftblindex  = (vftbllength++);
+                                       am->clazz       = c;
+                                       am->flags      |= ACC_MIRANDA;
+
+                               noabstractmethod2:
+                                       ;
+                               }
+                       }
+               }
+       }
+       RT_TIMING_GET_TIME(time_abstract);
+
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_vftbl_len +=
+                       sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
+#endif
+
+       /* compute interfacetable length */
+
+       interfacetablelength = 0;
+
+       for (tc = c; tc != NULL; tc = tc->super) {
+               for (i = 0; i < tc->interfacescount; i++) {
+                       s4 h = class_highestinterface(tc->interfaces[i]) + 1;
+
+                       if (h > interfacetablelength)
+                               interfacetablelength = h;
+               }
+       }
+       RT_TIMING_GET_TIME(time_compute_iftbl);
+
+       /* allocate virtual function table */
+
+       v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
+                                                         sizeof(methodptr) * (vftbllength - 1) +
+                                                         sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
+       v = (vftbl_t *) (((methodptr *) v) +
+                                        (interfacetablelength - 1) * (interfacetablelength > 1));
+
+       c->vftbl                = v;
+       v->clazz                = c;
+       v->vftbllength          = vftbllength;
+       v->interfacetablelength = interfacetablelength;
+       v->arraydesc            = arraydesc;
+
+       /* store interface index in vftbl */
+
+       if (c->flags & ACC_INTERFACE)
+               v->baseval = -(c->index);
+
+       /* copy virtual function table of super class */
+
+       for (i = 0; i < supervftbllength; i++) 
+               v->table[i] = super->vftbl->table[i];
+
+       /* Fill the remaining vftbl slots with the AbstractMethodError
+          stub (all after the super class slots, because they are already
+          initialized). */
+
+       for (; i < vftbllength; i++) {
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+               if (opt_intrp)
+                       v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+               else
+# endif
+                       v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
+#else
+               v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+#endif
+       }
+
+       /* add method stubs into virtual function table */
+
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+
+               assert(m->stubroutine == NULL);
+
+               /* Don't create a compiler stub for abstract methods as they
+                  throw an AbstractMethodError with the default stub in the
+                  vftbl.  This entry is simply copied by sub-classes. */
+
+               if (m->flags & ACC_ABSTRACT)
+                       continue;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+               if (opt_intrp)
+                       m->stubroutine = intrp_createcompilerstub(m);
+               else
+#endif
+                       m->stubroutine = codegen_generate_stub_compiler(m);
+#else
+               m->stubroutine = intrp_createcompilerstub(m);
+#endif
+
+               /* static methods are not in the vftbl */
+
+               if (m->flags & ACC_STATIC)
+                       continue;
+
+               /* insert the stubroutine into the vftbl */
+
+               v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
+       }
+       RT_TIMING_GET_TIME(time_fill_vftbl);
+
+       /* compute instance size and offset of each field */
+       
+       for (i = 0; i < c->fieldscount; i++) {
+               s4 dsize;
+               fieldinfo *f = &(c->fields[i]);
+               
+               if (!(f->flags & ACC_STATIC)) {
+                       dsize = descriptor_typesize(f->parseddesc);
+                       c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
+                       f->offset = c->instancesize;
+                       c->instancesize += dsize;
+               }
+       }
+       RT_TIMING_GET_TIME(time_offsets);
+
+       /* initialize interfacetable and interfacevftbllength */
+
+       v->interfacevftbllength = MNEW(s4, interfacetablelength);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
+#endif
+
+       for (i = 0; i < interfacetablelength; i++) {
+               v->interfacevftbllength[i] = 0;
+               v->interfacetable[-i] = NULL;
+       }
+
+       /* add interfaces */
+
+       for (tc = c; tc != NULL; tc = tc->super)
+               for (i = 0; i < tc->interfacescount; i++)
+                       if (!linker_addinterface(c, tc->interfaces[i]))
+                               return NULL;
+
+       RT_TIMING_GET_TIME(time_fill_iftbl);
+
+       /* add finalizer method (not for java.lang.Object) */
+
+       if (super) {
+               methodinfo *fi;
+
+               fi = class_findmethod(c, utf_finalize, utf_void__void);
+
+               if (fi)
+                       if (!(fi->flags & ACC_STATIC))
+                               c->finalizer = fi;
+       }
+       RT_TIMING_GET_TIME(time_finalizer);
+
+       /* final tasks */
+
+       linker_compute_subclasses(c);
+
+       RT_TIMING_GET_TIME(time_subclasses);
+
+       /* revert the linking state and class is linked */
+
+       c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
+
+       /* check worklist */
+
+       /* XXX must this also be done in case of exception? */
+
+       while (worklist != NULL) {
+               method_worklist *wi = worklist;
+
+               worklist = worklist->next;
+
+               INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
+               jit_invalidate_code(wi->m);
+
+               /* XXX put worklist into dump memory? */
+               FREE(wi, method_worklist);
+       }
+
+       RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
+       RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
+       RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
+       RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
+       RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
+       RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
+       RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
+       RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
+       RT_TIMING_TIME_DIFF(time_finalizer    ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
+
+       /* just return c to show that we didn't had a problem */
+
+       return c;
+}
+
+
+/* link_array ******************************************************************
+
+   This function is called by link_class to create the arraydescriptor
+   for an array class.
+
+   This function returns NULL if the array cannot be linked because
+   the component type has not been linked yet.
+
+*******************************************************************************/
+
+static arraydescriptor *link_array(classinfo *c)
+{
+       classinfo       *comp;
+       s4               namelen;
+       arraydescriptor *desc;
+       vftbl_t         *compvftbl;
+       utf             *u;
+
+       comp = NULL;
+       namelen = c->name->blength;
+
+       /* Check the component type */
+
+       switch (c->name->text[1]) {
+       case '[':
+               /* c is an array of arrays. */
+               u = utf_new(c->name->text + 1, namelen - 1);
+               if (!(comp = load_class_from_classloader(u, c->classloader)))
+                       return NULL;
+               break;
+
+       case 'L':
+               /* c is an array of objects. */
+               u = utf_new(c->name->text + 2, namelen - 3);
+               if (!(comp = load_class_from_classloader(u, c->classloader)))
+                       return NULL;
+               break;
+       }
+
+       /* If the component type has not been linked, link it now */
+
+       assert(!comp || (comp->state & CLASS_LOADED));
+
+       if (comp && !(comp->state & CLASS_LINKED))
+               if (!link_class(comp))
+                       return NULL;
+
+       /* Allocate the arraydescriptor */
+
+       desc = NEW(arraydescriptor);
+
+       if (comp) {
+               /* c is an array of references */
+               desc->arraytype = ARRAYTYPE_OBJECT;
+               desc->componentsize = sizeof(void*);
+               desc->dataoffset = OFFSET(java_objectarray_t, data);
+               
+               compvftbl = comp->vftbl;
+
+               if (!compvftbl) {
+                       log_text("Component class has no vftbl");
+                       assert(0);
+               }
+
+               desc->componentvftbl = compvftbl;
+               
+               if (compvftbl->arraydesc) {
+                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
+
+                       if (compvftbl->arraydesc->dimension >= 255) {
+                               log_text("Creating array of dimension >255");
+                               assert(0);
+                       }
+
+                       desc->dimension = compvftbl->arraydesc->dimension + 1;
+                       desc->elementtype = compvftbl->arraydesc->elementtype;
+
+               } else {
+                       desc->elementvftbl = compvftbl;
+                       desc->dimension = 1;
+                       desc->elementtype = ARRAYTYPE_OBJECT;
+               }
+
+       } else {
+               /* c is an array of a primitive type */
+               switch (c->name->text[1]) {
+               case 'Z':
+                       desc->arraytype = ARRAYTYPE_BOOLEAN;
+                       desc->dataoffset = OFFSET(java_booleanarray_t,data);
+                       desc->componentsize = sizeof(u1);
+                       break;
+
+               case 'B':
+                       desc->arraytype = ARRAYTYPE_BYTE;
+                       desc->dataoffset = OFFSET(java_bytearray_t,data);
+                       desc->componentsize = sizeof(u1);
+                       break;
+
+               case 'C':
+                       desc->arraytype = ARRAYTYPE_CHAR;
+                       desc->dataoffset = OFFSET(java_chararray_t,data);
+                       desc->componentsize = sizeof(u2);
+                       break;
+
+               case 'D':
+                       desc->arraytype = ARRAYTYPE_DOUBLE;
+                       desc->dataoffset = OFFSET(java_doublearray_t,data);
+                       desc->componentsize = sizeof(double);
+                       break;
+
+               case 'F':
+                       desc->arraytype = ARRAYTYPE_FLOAT;
+                       desc->dataoffset = OFFSET(java_floatarray_t,data);
+                       desc->componentsize = sizeof(float);
+                       break;
+
+               case 'I':
+                       desc->arraytype = ARRAYTYPE_INT;
+                       desc->dataoffset = OFFSET(java_intarray_t,data);
+                       desc->componentsize = sizeof(s4);
+                       break;
+
+               case 'J':
+                       desc->arraytype = ARRAYTYPE_LONG;
+                       desc->dataoffset = OFFSET(java_longarray_t,data);
+                       desc->componentsize = sizeof(s8);
+                       break;
+
+               case 'S':
+                       desc->arraytype = ARRAYTYPE_SHORT;
+                       desc->dataoffset = OFFSET(java_shortarray_t,data);
+                       desc->componentsize = sizeof(s2);
+                       break;
+
+               default:
+                       exceptions_throw_noclassdeffounderror(c->name);
+                       return NULL;
+               }
+               
+               desc->componentvftbl = NULL;
+               desc->elementvftbl = NULL;
+               desc->dimension = 1;
+               desc->elementtype = desc->arraytype;
+       }
+
+       return desc;
+}
+
+
+/* linker_compute_subclasses ***************************************************
+
+   XXX
+
+   ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
+   This function needs to take the class renumber lock and stop the
+   world during class renumbering. The lock is used in C code which
+   is not that performance critical. Whereas JIT code uses critical
+   sections to atomically access the class values.
+
+*******************************************************************************/
+
+static void linker_compute_subclasses(classinfo *c)
+{
+       LOCK_MONITOR_ENTER(linker_classrenumber_lock);
+
+       if (!(c->flags & ACC_INTERFACE)) {
+               c->nextsub = NULL;
+               c->sub     = NULL;
+       }
+
+       if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
+               c->nextsub    = c->super->sub;
+               c->super->sub = c;
+       }
+
+       classvalue = 0;
+
+       /* compute class values */
+
+       linker_compute_class_values(class_java_lang_Object);
+
+       LOCK_MONITOR_EXIT(linker_classrenumber_lock);
+}
+
+
+/* linker_compute_class_values *************************************************
+
+   XXX
+
+*******************************************************************************/
+
+static void linker_compute_class_values(classinfo *c)
+{
+       classinfo *subs;
+
+       c->vftbl->baseval = ++classvalue;
+
+       subs = c->sub;
+
+       while (subs) {
+               linker_compute_class_values(subs);
+
+               subs = subs->nextsub;
+       }
+
+       c->vftbl->diffval = classvalue - c->vftbl->baseval;
+}
+
+
+/* linker_addinterface *********************************************************
+
+   Is needed by link_class for adding a VTBL to a class. All
+   interfaces implemented by ic are added as well.
+
+   RETURN VALUE:
+      true.........everything ok
+         false........an exception has been thrown
+
+*******************************************************************************/
+
+static bool linker_addinterface(classinfo *c, classinfo *ic)
+{
+       s4          j, k;
+       vftbl_t    *v;
+       s4          i;
+       classinfo  *sc;
+       methodinfo *m;
+
+       v = c->vftbl;
+       i = ic->index;
+
+       if (i >= v->interfacetablelength)
+               vm_abort("Internal error: interfacetable overflow");
+
+       /* if this interface has already been added, return immediately */
+
+       if (v->interfacetable[-i] != NULL)
+               return true;
+
+       if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
+               v->interfacevftbllength[i] = 1;
+               v->interfacetable[-i]      = MNEW(methodptr, 1);
+               v->interfacetable[-i][0]   = NULL;
+       }
+       else {
+               v->interfacevftbllength[i] = ic->methodscount;
+               v->interfacetable[-i]      = MNEW(methodptr, ic->methodscount);
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_vftbl_len += sizeof(methodptr) *
+                               (ic->methodscount + (ic->methodscount == 0));
+#endif
+
+               for (j = 0; j < ic->methodscount; j++) {
+                       for (sc = c; sc != NULL; sc = sc->super) {
+                               for (k = 0; k < sc->methodscount; k++) {
+                                       m = &(sc->methods[k]);
+
+                                       if (method_canoverwrite(m, &(ic->methods[j]))) {
+                                               /* method m overwrites the (abstract) method */
+#if defined(ENABLE_VERIFIER)
+                                               /* Add loading constraints (for the more
+                                                  general types of the method
+                                                  ic->methods[j]).  */
+                                               if (!classcache_add_constraints_for_params(
+                                                                       c->classloader, ic->classloader,
+                                                                       &(ic->methods[j])))
+                                               {
+                                                       return false;
+                                               }
+#endif
+
+                                               /* XXX taken from gcj */
+                                               /* check for ACC_STATIC: IncompatibleClassChangeError */
+
+                                               /* check for !ACC_PUBLIC: IllegalAccessError */
+
+                                               /* check for ACC_ABSTRACT: AbstracMethodError,
+                                                  not sure about that one */
+
+                                               v->interfacetable[-i][j] = v->table[m->vftblindex];
+                                               goto foundmethod;
+                                       }
+                               }
+                       }
+
+                       /* If no method was found, insert the AbstractMethodError
+                          stub. */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+                       if (opt_intrp)
+                               v->interfacetable[-i][j] =
+                                       (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+                       else
+# endif
+                               v->interfacetable[-i][j] =
+                                       (methodptr) (ptrint) &asm_abstractmethoderror;
+#else
+                       v->interfacetable[-i][j] =
+                               (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+#endif
+
+               foundmethod:
+                       ;
+               }
+       }
+
+       /* add superinterfaces of this interface */
+
+       for (j = 0; j < ic->interfacescount; j++)
+               if (!linker_addinterface(c, ic->interfaces[j]))
+                       return false;
+
+       /* everything ok */
+
+       return true;
+}
+
+
+/* class_highestinterface ******************************************************
+
+   Used by the function link_class to determine the amount of memory
+   needed for the interface table.
+
+*******************************************************************************/
+
+static s4 class_highestinterface(classinfo *c)
+{
+       s4 h;
+       s4 h2;
+       s4 i;
+       
+    /* check for ACC_INTERFACE bit already done in link_class_intern */
+
+    h = c->index;
+
+       for (i = 0; i < c->interfacescount; i++) {
+               h2 = class_highestinterface(c->interfaces[i]);
+
+               if (h2 > h)
+                       h = h2;
+       }
+
+       return h;
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vm/linker.h b/src/vm/linker.h
new file mode 100644 (file)
index 0000000..a11f80c
--- /dev/null
@@ -0,0 +1,162 @@
+/* src/vm/linker.h - class linker header
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _LINKER_H
+#define _LINKER_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct _vftbl vftbl_t;
+typedef struct arraydescriptor arraydescriptor;
+typedef struct primitivetypeinfo primitivetypeinfo;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/class.h"
+#include "vm/references.h"
+
+
+/* virtual function table ******************************************************
+
+   The vtbl has a bidirectional layout with open ends at both sides.
+   interfacetablelength gives the number of entries of the interface
+   table at the start of the vftbl. The vftbl pointer points to
+   &interfacetable[0].  vftbllength gives the number of entries of
+   table at the end of the vftbl.
+
+   runtime type check (checkcast):
+
+   Different methods are used for runtime type check depending on the
+   argument of checkcast/instanceof.
+       
+   A check against a class is implemented via relative numbering on
+   the class hierachy tree. The tree is numbered in a depth first
+   traversal setting the base field and the diff field. The diff field
+   gets the result of (high - base) so that a range check can be
+   implemented by an unsigned compare. A sub type test is done by
+   checking the inclusion of base of the sub class in the range of the
+   superclass.
+
+   A check against an interface is implemented via the
+   interfacevftbl. If the interfacevftbl contains a nonnull value a
+   class is a subclass of this interface.
+
+   interfacetable:
+
+   Like standard virtual methods interface methods are called using
+   virtual function tables. All interfaces are numbered sequentially
+   (starting with zero). For each class there exist an interface table
+   of virtual function tables for each implemented interface. The
+   length of the interface table is determined by the highest number
+   of an implemented interface.
+
+   The following example assumes a class which implements interface 0 and 3:
+
+   interfacetablelength = 4
+
+                  | ...       |            +----------+
+                  +-----------+            | method 2 |---> method z
+                  | class     |            | method 1 |---> method y
+                  +-----------+            | method 0 |---> method x
+                  | ivftbl  0 |----------> +----------+
+    vftblptr ---> +-----------+
+                  | ivftbl -1 |--> NULL    +----------+
+                  | ivftbl -2 |--> NULL    | method 1 |---> method x
+                  | ivftbl -3 |-----+      | method 0 |---> method a
+                  +-----------+     +----> +----------+
+     
+                              +---------------+
+                              | length 3 = 2  |
+                              | length 2 = 0  |
+                              | length 1 = 0  |
+                              | length 0 = 3  |
+    interfacevftbllength ---> +---------------+
+
+*******************************************************************************/
+
+struct _vftbl {
+       methodptr   *interfacetable[1];    /* interface table (access via macro)  */
+       classinfo   *clazz;                /* class, the vtbl belongs to          */
+       arraydescriptor *arraydesc;        /* for array classes, otherwise NULL   */
+       s4           vftbllength;          /* virtual function table length       */
+       s4           interfacetablelength; /* interface table length              */
+       s4           baseval;              /* base for runtime type check         */
+                                          /* (-index for interfaces)             */
+       s4           diffval;              /* high - base for runtime type check  */
+       s4          *interfacevftbllength; /* length of interface vftbls          */
+       methodptr    table[1];             /* class vftbl                         */
+};
+
+
+/* arraydescriptor *************************************************************
+
+   For every array class an arraydescriptor is allocated which
+   describes the array class. The arraydescriptor is referenced from
+   the vftbl of the array class.
+
+*******************************************************************************/
+
+struct arraydescriptor {
+       vftbl_t *componentvftbl; /* vftbl of the component type, NULL for primit. */
+       vftbl_t *elementvftbl;   /* vftbl of the element type, NULL for primitive */
+       s2       arraytype;      /* ARRAYTYPE_* constant                          */
+       s2       dimension;      /* dimension of the array (always >= 1)          */
+       s4       dataoffset;     /* offset of the array data from object pointer  */
+       s4       componentsize;  /* size of a component in bytes                  */
+       s2       elementtype;    /* ARRAYTYPE_* constant                          */
+};
+
+
+/* global variables ***********************************************************/
+
+/* This lock must be taken while renumbering classes or while atomically      */
+/* accessing classes.                                                         */
+
+extern java_object_t *linker_classrenumber_lock;
+
+
+/* function prototypes ********************************************************/
+
+void       linker_preinit(void);
+void       linker_init(void);
+classinfo *link_class(classinfo *c);
+
+#endif /* _LINKER_H */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/src/vm/loader.c b/src/vm/loader.c
new file mode 100644 (file)
index 0000000..218f695
--- /dev/null
@@ -0,0 +1,2226 @@
+/* src/vm/loader.c - class loader 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 <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "threads/lock-common.h"
+
+#include "toolbox/hashtable.h"
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/field.h"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/package.hpp"
+#include "vm/primitive.hpp"
+#include "vm/resolve.h"
+#include "vm/rt-timing.h"
+#include "vm/string.hpp"
+#include "vm/suck.h"
+#include "vm/vm.hpp"
+
+
+#if defined(ENABLE_JAVASE)
+# include "vm/annotation.h"
+# include "vm/stackmap.h"
+#endif
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#if defined(ENABLE_ZLIB)
+# include "vm/zip.h"
+#endif
+
+#if defined(ENABLE_JVMTI)
+# include "native/jvmti/cacaodbg.h"
+#endif
+
+
+/* global variables ***********************************************************/
+
+static hashtable *hashtable_classloader;
+
+
+/* loader_preinit **************************************************************
+
+   Initializes the classpath list and loads classes required for the
+   primitive table.
+
+   NOTE: Exceptions thrown during VM initialization are caught in the
+         exception functions themselves.
+
+*******************************************************************************/
+void loader_preinit(void)
+{
+#if defined(ENABLE_THREADS)
+       list_classpath_entry *lce;
+#endif
+
+       TRACESUBSYSTEMINITIALIZATION("loader_preinit");
+
+#if defined(ENABLE_THREADS)
+       /* Initialize the monitor pointer for zip/jar file locking. */
+
+       for (lce = list_first(list_classpath_entries); lce != NULL;
+                lce = list_next(list_classpath_entries, lce)) {
+               if (lce->type == CLASSPATH_ARCHIVE)
+                       LOCK_INIT_OBJECT_LOCK(lce);
+       }
+#endif
+
+       /* initialize classloader hashtable, 10 entries should be enough */
+
+       hashtable_classloader = NEW(hashtable);
+       hashtable_create(hashtable_classloader, 10);
+
+       /* Load the most basic classes. */
+
+       assert(VM_is_initializing() == true);
+
+       class_java_lang_Object     = load_class_bootstrap(utf_java_lang_Object);
+
+#if defined(ENABLE_JAVASE)
+       class_java_lang_Cloneable  = load_class_bootstrap(utf_java_lang_Cloneable);
+       class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
+#endif
+}
+
+
+/* loader_init *****************************************************************
+
+   Loads all classes required in the VM.
+
+   NOTE: Exceptions thrown during VM initialization are caught in the
+         exception functions themselves.
+
+*******************************************************************************/
+void loader_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("loader_init");
+
+       /* Load primitive-type wrapping classes. */
+
+       assert(VM_is_initializing() == true);
+
+#if defined(ENABLE_JAVASE)
+       class_java_lang_Void       = load_class_bootstrap(utf_java_lang_Void);
+#endif
+
+       class_java_lang_Boolean    = load_class_bootstrap(utf_java_lang_Boolean);
+       class_java_lang_Byte       = load_class_bootstrap(utf_java_lang_Byte);
+       class_java_lang_Character  = load_class_bootstrap(utf_java_lang_Character);
+       class_java_lang_Short      = load_class_bootstrap(utf_java_lang_Short);
+       class_java_lang_Integer    = load_class_bootstrap(utf_java_lang_Integer);
+       class_java_lang_Long       = load_class_bootstrap(utf_java_lang_Long);
+       class_java_lang_Float      = load_class_bootstrap(utf_java_lang_Float);
+       class_java_lang_Double     = load_class_bootstrap(utf_java_lang_Double);
+
+       /* Load important system classes. */
+
+       class_java_lang_Class      = load_class_bootstrap(utf_java_lang_Class);
+       class_java_lang_String     = load_class_bootstrap(utf_java_lang_String);
+
+#if defined(ENABLE_JAVASE)
+       class_java_lang_ClassLoader =
+               load_class_bootstrap(utf_java_lang_ClassLoader);
+
+       class_java_lang_SecurityManager =
+               load_class_bootstrap(utf_java_lang_SecurityManager);
+#endif
+
+       class_java_lang_System     =
+               load_class_bootstrap(utf_new_char("java/lang/System"));
+
+       class_java_lang_Thread     =
+               load_class_bootstrap(utf_new_char("java/lang/Thread"));
+
+#if defined(ENABLE_JAVASE)
+       class_java_lang_ThreadGroup =
+               load_class_bootstrap(utf_java_lang_ThreadGroup);
+#endif
+
+       class_java_lang_Throwable  = load_class_bootstrap(utf_java_lang_Throwable);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       class_java_lang_VMSystem   =
+               load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
+
+       class_java_lang_VMThread   =
+               load_class_bootstrap(utf_new_char("java/lang/VMThread"));
+
+       class_java_lang_VMThrowable =
+               load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
+#endif
+
+       /* Important system exceptions. */
+
+       class_java_lang_Exception  = load_class_bootstrap(utf_java_lang_Exception);
+
+       class_java_lang_ClassNotFoundException =
+               load_class_bootstrap(utf_java_lang_ClassNotFoundException);
+
+       class_java_lang_RuntimeException =
+               load_class_bootstrap(utf_java_lang_RuntimeException);
+
+       /* Some classes which may be used often. */
+
+#if defined(ENABLE_JAVASE)
+       class_java_lang_StackTraceElement      = load_class_bootstrap(utf_java_lang_StackTraceElement);
+
+       class_java_lang_reflect_Constructor    = load_class_bootstrap(utf_java_lang_reflect_Constructor);
+       class_java_lang_reflect_Field          = load_class_bootstrap(utf_java_lang_reflect_Field);
+       class_java_lang_reflect_Method         = load_class_bootstrap(utf_java_lang_reflect_Method);
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       class_java_lang_reflect_VMConstructor  = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
+       class_java_lang_reflect_VMField        = load_class_bootstrap(utf_java_lang_reflect_VMField);
+       class_java_lang_reflect_VMMethod       = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
+# endif
+
+       class_java_security_PrivilegedAction   = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
+
+       class_java_util_HashMap                = load_class_bootstrap(utf_new_char("java/util/HashMap"));
+       class_java_util_Vector                 = load_class_bootstrap(utf_java_util_Vector);
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       class_sun_misc_Signal                  = load_class_bootstrap(utf_new_char("sun/misc/Signal"));
+       class_sun_reflect_MagicAccessorImpl    = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
+# endif
+
+       arrayclass_java_lang_Object =
+               load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
+
+# if defined(ENABLE_ANNOTATIONS)
+       /* needed by annotation support */
+       class_sun_reflect_ConstantPool =
+               load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
+
+#  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       /* needed by GNU Classpaths annotation support */
+       class_sun_reflect_annotation_AnnotationParser =
+               load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
+#  endif
+# endif
+#endif
+}
+
+
+/* loader_hashtable_classloader_add ********************************************
+
+   Adds an entry to the classloader hashtable.
+
+   REMEMBER: Also use this to register native loaders!
+
+*******************************************************************************/
+
+classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
+{
+       hashtable_classloader_entry *cle;
+       u4   key;
+       u4   slot;
+
+       if (cl == NULL)
+               return NULL;
+
+       LOCK_MONITOR_ENTER(hashtable_classloader->header);
+
+       LLNI_CRITICAL_START;
+
+       /* key for entry is the hashcode of the classloader;
+          aligned to 16-byte boundaries */
+
+       key  = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
+       slot = key & (hashtable_classloader->size - 1);
+       cle  = hashtable_classloader->ptr[slot];
+
+       /* search hashchain for existing entry */
+
+       while (cle) {
+               if (cle->object == LLNI_DIRECT(cl))
+                       break;
+
+               cle = cle->hashlink;
+       }
+
+       LLNI_CRITICAL_END;
+
+       /* if no classloader was found, we create a new entry here */
+
+       if (cle == NULL) {
+               cle = NEW(hashtable_classloader_entry);
+
+#if defined(ENABLE_GC_CACAO)
+               /* register the classloader object with the GC */
+
+               gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
+#endif
+
+               LLNI_CRITICAL_START;
+
+               cle->object = LLNI_DIRECT(cl);
+
+               LLNI_CRITICAL_END;
+
+/*#define LOADER_DEBUG_CLASSLOADER*/
+#ifdef LOADER_DEBUG_CLASSLOADER
+               printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
+               class_print(LLNI_vftbl_direct(cl)->class);
+               printf("\n");
+               fflush(stdout);
+#endif
+
+               /* insert entry into hashtable */
+
+               cle->hashlink = hashtable_classloader->ptr[slot];
+               hashtable_classloader->ptr[slot] = cle;
+
+               /* update number of entries */
+
+               hashtable_classloader->entries++;
+       }
+
+
+       LOCK_MONITOR_EXIT(hashtable_classloader->header);
+
+#if defined(ENABLE_HANDLES)
+       return cle;
+#else
+       return cl;
+#endif
+}
+
+
+/* loader_hashtable_classloader_find *******************************************
+
+   Find an entry in the classloader hashtable.
+
+*******************************************************************************/
+
+classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
+{
+       hashtable_classloader_entry *cle;
+       u4   key;
+       u4   slot;
+
+       if (cl == NULL)
+               return NULL;
+
+       LLNI_CRITICAL_START;
+
+       /* key for entry is the hashcode of the classloader;
+          aligned to 16-byte boundaries */
+
+       key  = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
+       slot = key & (hashtable_classloader->size - 1);
+       cle  = hashtable_classloader->ptr[slot];
+
+       /* search hashchain for existing entry */
+
+       while (cle) {
+               if (cle->object == LLNI_DIRECT(cl))
+                       break;
+
+               cle = cle->hashlink;
+       }
+
+#ifdef LOADER_DEBUG_CLASSLOADER
+       if (cle == NULL) {
+               printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
+               class_print(LLNI_vftbl_direct(cl)->class);
+               printf("\n");
+               fflush(stdout);
+       }
+#endif
+
+       LLNI_CRITICAL_END;
+
+#if defined(ENABLE_HANDLES)
+       return cle;
+#else
+       return cl;
+#endif
+}
+
+
+/* loader_load_all_classes *****************************************************
+
+   Loads all classes specified in the BOOTCLASSPATH.
+
+*******************************************************************************/
+
+void loader_load_all_classes(void)
+{
+       list_classpath_entry    *lce;
+#if defined(ENABLE_ZLIB)
+       hashtable               *ht;
+       s4                       slot;
+       hashtable_zipfile_entry *htzfe;
+       utf                     *u;
+#endif
+
+       for (lce = list_first(list_classpath_entries); lce != NULL;
+                lce = list_next(list_classpath_entries, lce)) {
+#if defined(ENABLE_ZLIB)
+               if (lce->type == CLASSPATH_ARCHIVE) {
+                       /* get the classes hashtable */
+
+                       ht = lce->htclasses;
+
+                       for (slot = 0; slot < ht->size; slot++) {
+                               htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
+
+                               for (; htzfe; htzfe = htzfe->hashlink) {
+                                       u = htzfe->filename;
+
+                                       /* skip all entries in META-INF and .properties,
+                       .png files */
+
+                                       if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
+                                               strstr(u->text, ".properties") ||
+                                               strstr(u->text, ".png"))
+                                               continue;
+
+                                       /* load class from bootstrap classloader */
+
+                                       if (!load_class_bootstrap(u)) {
+                                               fprintf(stderr, "Error loading: ");
+                                               utf_fprint_printable_ascii_classname(stderr, u);
+                                               fprintf(stderr, "\n");
+
+#if !defined(NDEBUG)
+                                               /* print out exception and cause */
+
+                                               exceptions_print_current_exception();
+#endif
+                                       }
+                               }
+                       }
+
+               } else {
+#endif
+#if defined(ENABLE_ZLIB)
+               }
+#endif
+       }
+}
+
+
+/* loader_skip_attribute_body **************************************************
+
+   Skips an attribute the attribute_name_index has already been read.
+       
+   attribute_info {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 info[attribute_length];
+   }
+
+*******************************************************************************/
+
+bool loader_skip_attribute_body(classbuffer *cb)
+{
+       u4 attribute_length;
+
+       if (!suck_check_classbuffer_size(cb, 4))
+               return false;
+
+       attribute_length = suck_u4(cb);
+
+       if (!suck_check_classbuffer_size(cb, attribute_length))
+               return false;
+
+       suck_skip_nbytes(cb, attribute_length);
+
+       return true;
+}
+
+
+/* load_constantpool ***********************************************************
+
+   Loads the constantpool of a class, the entries are transformed into
+   a simpler format by resolving references (a detailed overview of
+   the compact structures can be found in global.h).
+
+*******************************************************************************/
+
+static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
+{
+
+       /* The following structures are used to save information which cannot be 
+          processed during the first pass. After the complete constantpool has 
+          been traversed the references can be resolved. 
+          (only in specific order)                                                */
+       
+       /* CONSTANT_Class entries */
+       typedef struct forward_class {
+               struct forward_class *next;
+               u2 thisindex;
+               u2 name_index;
+       } forward_class;
+
+       /* CONSTANT_String */
+       typedef struct forward_string {
+               struct forward_string *next;
+               u2 thisindex;
+               u2 string_index;
+       } forward_string;
+
+       /* CONSTANT_NameAndType */
+       typedef struct forward_nameandtype {
+               struct forward_nameandtype *next;
+               u2 thisindex;
+               u2 name_index;
+               u2 sig_index;
+       } forward_nameandtype;
+
+       /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
+       typedef struct forward_fieldmethint {
+               struct forward_fieldmethint *next;
+               u2 thisindex;
+               u1 tag;
+               u2 class_index;
+               u2 nameandtype_index;
+       } forward_fieldmethint;
+
+
+       classinfo *c;
+       u4 idx;
+
+       forward_class *forward_classes = NULL;
+       forward_string *forward_strings = NULL;
+       forward_nameandtype *forward_nameandtypes = NULL;
+       forward_fieldmethint *forward_fieldmethints = NULL;
+
+       forward_class *nfc;
+       forward_string *nfs;
+       forward_nameandtype *nfn;
+       forward_fieldmethint *nff;
+
+       u4 cpcount;
+       u1 *cptags;
+       void** cpinfos;
+
+       c = cb->clazz;
+
+       /* number of entries in the constant_pool table plus one */
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       cpcount = c->cpcount = suck_u2(cb);
+
+       /* allocate memory */
+       cptags  = c->cptags  = MNEW(u1, cpcount);
+       cpinfos = c->cpinfos = MNEW(void*, cpcount);
+
+       if (cpcount < 1) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool size");
+               return false;
+       }
+       
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
+#endif
+       
+       /* initialize constantpool */
+       for (idx = 0; idx < cpcount; idx++) {
+               cptags[idx] = CONSTANT_UNUSED;
+               cpinfos[idx] = NULL;
+       }
+
+                       
+       /******* first pass *******/
+       /* entries which cannot be resolved now are written into 
+          temporary structures and traversed again later        */
+                  
+       idx = 1;
+       while (idx < cpcount) {
+               u4 t;
+
+               /* get constant type */
+               if (!suck_check_classbuffer_size(cb, 1))
+                       return false;
+
+               t = suck_u1(cb);
+
+               switch (t) {
+               case CONSTANT_Class:
+                       nfc = DNEW(forward_class);
+
+                       nfc->next = forward_classes;
+                       forward_classes = nfc;
+
+                       nfc->thisindex = idx;
+                       /* reference to CONSTANT_NameAndType */
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       nfc->name_index = suck_u2(cb);
+
+                       idx++;
+                       break;
+                       
+               case CONSTANT_String:
+                       nfs = DNEW(forward_string);
+                               
+                       nfs->next = forward_strings;
+                       forward_strings = nfs;
+                               
+                       nfs->thisindex = idx;
+
+                       /* reference to CONSTANT_Utf8_info with string characters */
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       nfs->string_index = suck_u2(cb);
+                               
+                       idx++;
+                       break;
+
+               case CONSTANT_NameAndType:
+                       nfn = DNEW(forward_nameandtype);
+                               
+                       nfn->next = forward_nameandtypes;
+                       forward_nameandtypes = nfn;
+                               
+                       nfn->thisindex = idx;
+
+                       if (!suck_check_classbuffer_size(cb, 2 + 2))
+                               return false;
+
+                       /* reference to CONSTANT_Utf8_info containing simple name */
+                       nfn->name_index = suck_u2(cb);
+
+                       /* reference to CONSTANT_Utf8_info containing field or method
+                          descriptor */
+                       nfn->sig_index = suck_u2(cb);
+                               
+                       idx++;
+                       break;
+
+               case CONSTANT_Fieldref:
+               case CONSTANT_Methodref:
+               case CONSTANT_InterfaceMethodref:
+                       nff = DNEW(forward_fieldmethint);
+                       
+                       nff->next = forward_fieldmethints;
+                       forward_fieldmethints = nff;
+
+                       nff->thisindex = idx;
+                       /* constant type */
+                       nff->tag = t;
+
+                       if (!suck_check_classbuffer_size(cb, 2 + 2))
+                               return false;
+
+                       /* class or interface type that contains the declaration of the
+                          field or method */
+                       nff->class_index = suck_u2(cb);
+
+                       /* name and descriptor of the field or method */
+                       nff->nameandtype_index = suck_u2(cb);
+
+                       idx++;
+                       break;
+                               
+               case CONSTANT_Integer: {
+                       constant_integer *ci = NEW(constant_integer);
+
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_const_pool_len += sizeof(constant_integer);
+#endif
+
+                       if (!suck_check_classbuffer_size(cb, 4))
+                               return false;
+
+                       ci->value = suck_s4(cb);
+                       cptags[idx] = CONSTANT_Integer;
+                       cpinfos[idx] = ci;
+
+                       idx++;
+                       break;
+               }
+                               
+               case CONSTANT_Float: {
+                       constant_float *cf = NEW(constant_float);
+
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_const_pool_len += sizeof(constant_float);
+#endif
+
+                       if (!suck_check_classbuffer_size(cb, 4))
+                               return false;
+
+                       cf->value = suck_float(cb);
+                       cptags[idx] = CONSTANT_Float;
+                       cpinfos[idx] = cf;
+
+                       idx++;
+                       break;
+               }
+                               
+               case CONSTANT_Long: {
+                       constant_long *cl = NEW(constant_long);
+                                       
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_const_pool_len += sizeof(constant_long);
+#endif
+
+                       if (!suck_check_classbuffer_size(cb, 8))
+                               return false;
+
+                       cl->value = suck_s8(cb);
+                       cptags[idx] = CONSTANT_Long;
+                       cpinfos[idx] = cl;
+                       idx += 2;
+                       if (idx > cpcount) {
+                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
+                               return false;
+                       }
+                       break;
+               }
+                       
+               case CONSTANT_Double: {
+                       constant_double *cd = NEW(constant_double);
+                               
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_const_pool_len += sizeof(constant_double);
+#endif
+
+                       if (!suck_check_classbuffer_size(cb, 8))
+                               return false;
+
+                       cd->value = suck_double(cb);
+                       cptags[idx] = CONSTANT_Double;
+                       cpinfos[idx] = cd;
+                       idx += 2;
+                       if (idx > cpcount) {
+                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
+                               return false;
+                       }
+                       break;
+               }
+                               
+               case CONSTANT_Utf8: { 
+                       u4 length;
+
+                       /* number of bytes in the bytes array (not string-length) */
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       length = suck_u2(cb);
+                       cptags[idx] = CONSTANT_Utf8;
+
+                       /* validate the string */
+                       if (!suck_check_classbuffer_size(cb, length))
+                               return false;
+
+#ifdef ENABLE_VERIFIER
+                       if (opt_verify &&
+                               !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
+                       {
+                               exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
+                               return false;
+                       }
+#endif /* ENABLE_VERIFIER */
+                       /* insert utf-string into the utf-symboltable */
+                       cpinfos[idx] = utf_new((char *) cb->pos, length);
+
+                       /* skip bytes of the string (buffer size check above) */
+                       suck_skip_nbytes(cb, length);
+                       idx++;
+                       break;
+               }
+                                                                               
+               default:
+                       exceptions_throw_classformaterror(c, "Illegal constant pool type");
+                       return false;
+               }  /* end switch */
+       } /* end while */
+
+
+       /* resolve entries in temporary structures */
+
+       while (forward_classes) {
+               utf *name =
+                       class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
+               if (!name)
+                       return false;
+
+#ifdef ENABLE_VERIFIER
+               if (opt_verify && !is_valid_name_utf(name)) {
+                       exceptions_throw_classformaterror(c, "Class reference with invalid name");
+                       return false;
+               }
+#endif /* ENABLE_VERIFIER */
+
+               /* add all class references to the descriptor_pool */
+
+               if (!descriptor_pool_add_class(descpool, name))
+                       return false;
+
+               cptags[forward_classes->thisindex] = CONSTANT_Class;
+
+               /* the classref is created later */
+               cpinfos[forward_classes->thisindex] = name;
+
+               nfc = forward_classes;
+               forward_classes = forward_classes->next;
+       }
+
+       while (forward_strings) {
+               utf *text =
+                       class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
+               if (!text)
+                       return false;
+
+               /* resolve utf-string */
+               cptags[forward_strings->thisindex] = CONSTANT_String;
+               cpinfos[forward_strings->thisindex] = text;
+               
+               nfs = forward_strings;
+               forward_strings = forward_strings->next;
+       }
+
+       while (forward_nameandtypes) {
+               constant_nameandtype *cn = NEW(constant_nameandtype);   
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_const_pool_len += sizeof(constant_nameandtype);
+#endif
+
+               /* resolve simple name and descriptor */
+               cn->name = class_getconstant(c,
+                                                                        forward_nameandtypes->name_index,
+                                                                        CONSTANT_Utf8);
+               if (!cn->name)
+                       return false;
+
+               cn->descriptor = class_getconstant(c,
+                                                                                  forward_nameandtypes->sig_index,
+                                                                                  CONSTANT_Utf8);
+               if (!cn->descriptor)
+                       return false;
+
+#ifdef ENABLE_VERIFIER
+               if (opt_verify) {
+                       /* check name */
+                       if (!is_valid_name_utf(cn->name)) {
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal Field name \"%s\"",
+                                                                                                 cn->name->text);
+
+                               return false;
+                       }
+
+                       /* disallow referencing <clinit> among others */
+                       if (cn->name->text[0] == '<' && cn->name != utf_init) {
+                               exceptions_throw_classformaterror(c, "Illegal reference to special method");
+                               return false;
+                       }
+               }
+#endif /* ENABLE_VERIFIER */
+
+               cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
+               cpinfos[forward_nameandtypes->thisindex] = cn;
+
+               nfn = forward_nameandtypes;
+               forward_nameandtypes = forward_nameandtypes->next;
+       }
+
+       while (forward_fieldmethints) {
+               constant_nameandtype *nat;
+               constant_FMIref *fmi = NEW(constant_FMIref);
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_const_pool_len += sizeof(constant_FMIref);
+#endif
+               /* resolve simple name and descriptor */
+
+               nat = class_getconstant(c,
+                                                               forward_fieldmethints->nameandtype_index,
+                                                               CONSTANT_NameAndType);
+               if (!nat)
+                       return false;
+
+               /* add all descriptors in {Field,Method}ref to the descriptor_pool */
+
+               if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
+                       return false;
+
+               /* the classref is created later */
+
+               fmi->p.index = forward_fieldmethints->class_index;
+               fmi->name = nat->name;
+               fmi->descriptor = nat->descriptor;
+
+               cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
+               cpinfos[forward_fieldmethints->thisindex] = fmi;
+       
+               nff = forward_fieldmethints;
+               forward_fieldmethints = forward_fieldmethints->next;
+       }
+
+       /* everything was ok */
+
+       return true;
+}
+
+
+/* loader_load_attribute_signature *********************************************
+
+   Signature_attribute {
+       u2 attribute_name_index;
+          u4 atrribute_length;
+          u2 signature_index;
+   }
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
+{
+       classinfo *c;
+       u4         attribute_length;
+       u2         signature_index;
+
+       /* get classinfo */
+
+       c = cb->clazz;
+
+       /* check remaining bytecode */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 2) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       if (*signature != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple Signature attributes");
+               return false;
+       }
+
+       /* get signature */
+
+       signature_index = suck_u2(cb);
+
+       if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
+               return false;
+
+       return true;
+}
+#endif /* defined(ENABLE_JAVASE) */
+
+
+/* load_class_from_sysloader ***************************************************
+
+   Load the class with the given name using the system class loader
+
+   IN:
+       name.............the classname
+
+   RETURN VALUE:
+       the loaded class, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+classinfo *load_class_from_sysloader(utf *name)
+{
+       methodinfo    *m;
+       java_handle_t *clo;
+       classloader_t *cl;
+       classinfo     *c;
+
+       assert(class_java_lang_Object);
+       assert(class_java_lang_ClassLoader);
+       assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
+       
+       m = class_resolveclassmethod(class_java_lang_ClassLoader,
+                                                                utf_getSystemClassLoader,
+                                                                utf_void__java_lang_ClassLoader,
+                                                                class_java_lang_Object,
+                                                                false);
+
+       if (!m)
+               return false;
+
+       clo = vm_call_method(m, NULL);
+
+       if (!clo)
+               return false;
+
+       cl = loader_hashtable_classloader_add(clo);
+
+       c = load_class_from_classloader(name, cl);
+
+       return c;
+}
+
+
+/* load_class_from_classloader *************************************************
+
+   Load the class with the given name using the given user-defined class loader.
+
+   IN:
+       name.............the classname
+          cl...............user-defined class loader
+          
+   RETURN VALUE:
+       the loaded class, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       classinfo     *tmpc;
+       java_handle_t *string;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_lookup, time_prepare, time_java, 
+                                       time_cache;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       assert(name);
+
+       /* lookup if this class has already been loaded */
+
+       c = classcache_lookup(cl, name);
+
+       RT_TIMING_GET_TIME(time_lookup);
+       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
+
+       if (c != NULL)
+               return c;
+
+       /* if other class loader than bootstrap, call it */
+
+       if (cl != NULL) {
+               methodinfo *lc;
+               char       *text;
+               s4          namelen;
+
+               text = name->text;
+               namelen = name->blength;
+
+               /* handle array classes */
+               if (text[0] == '[') {
+                       classinfo *comp;
+                       utf       *u;
+
+                       switch (text[1]) {
+                       case 'L':
+                               /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
+                               if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
+                                       exceptions_throw_classnotfoundexception(name);
+                                       return false;
+                               }
+
+                               u = utf_new(text + 2, namelen - 3);
+
+                               if (!(comp = load_class_from_classloader(u, cl)))
+                                       return false;
+
+                               /* create the array class */
+
+                               c = class_array_of(comp, false);
+
+                               tmpc = classcache_store(cl, c, true);
+
+                               if (tmpc == NULL) {
+                                       /* exception, free the loaded class */
+                                       c->state &= ~CLASS_LOADING;
+                                       class_free(c);
+                               }
+
+                               return tmpc;
+
+                       case '[':
+                               /* load the component class */
+
+                               u = utf_new(text + 1, namelen - 1);
+
+                               if (!(comp = load_class_from_classloader(u, cl)))
+                                       return false;
+
+                               /* create the array class */
+
+                               c = class_array_of(comp, false);
+
+                               tmpc = classcache_store(cl, c, true);
+
+                               if (tmpc == NULL) {
+                                       /* exception, free the loaded class */
+                                       c->state &= ~CLASS_LOADING;
+                                       class_free(c);
+                               }
+
+                               return tmpc;
+
+                       default:
+                               /* primitive array classes are loaded by the bootstrap loader */
+
+                               c = load_class_bootstrap(name);
+
+                               return c;
+                       }
+               }
+
+               LLNI_class_get(cl, c);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+               /* OpenJDK uses this internal function because it's
+                  synchronized. */
+
+               lc = class_resolveclassmethod(c,
+                                                                         utf_loadClassInternal,
+                                                                         utf_java_lang_String__java_lang_Class,
+                                                                         NULL,
+                                                                         true);
+#else
+               lc = class_resolveclassmethod(c,
+                                                                         utf_loadClass,
+                                                                         utf_java_lang_String__java_lang_Class,
+                                                                         NULL,
+                                                                         true);
+#endif
+
+               if (lc == NULL)
+                       return false; /* exception */
+
+               /* move return value into `o' and cast it afterwards to a classinfo* */
+
+               string = javastring_new_slash_to_dot(name);
+
+               RT_TIMING_GET_TIME(time_prepare);
+
+               o = vm_call_method(lc, (java_handle_t *) cl, string);
+
+               RT_TIMING_GET_TIME(time_java);
+
+               c = LLNI_classinfo_unwrap(o);
+
+               if (c != NULL) {
+                       /* Store this class in the loaded class cache. If another
+                          class with the same (initloader,name) pair has been
+                          stored earlier it will be returned by classcache_store
+                          In this case classcache_store may not free the class
+                          because it has already been exposed to Java code which
+                          may have kept references to that class. */
+
+                   tmpc = classcache_store(cl, c, false);
+
+                       if (tmpc == NULL) {
+                               /* exception, free the loaded class */
+                               c->state &= ~CLASS_LOADING;
+                               class_free(c);
+                       }
+
+                       c = tmpc;
+               }
+
+               RT_TIMING_GET_TIME(time_cache);
+
+               RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
+               RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
+               RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
+
+               /* SUN compatible -verbose:class output */
+
+               if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
+                       printf("[Loaded ");
+                       utf_display_printable_ascii_classname(name);
+                       printf("]\n");
+               }
+
+#if defined(ENABLE_JVMTI)
+               /* fire Class Load JVMTI event */
+               if (jvmti) jvmti_ClassLoadPrepare(false, c);
+#endif
+
+
+               return c;
+       } 
+
+       c = load_class_bootstrap(name);
+
+       return c;
+}
+
+
+/* load_class_bootstrap ********************************************************
+       
+   Load the class with the given name using the bootstrap class loader.
+
+   IN:
+       name.............the classname
+
+   RETURN VALUE:
+       loaded classinfo, or
+          NULL if an exception has been thrown
+
+   SYNCHRONIZATION:
+       load_class_bootstrap is synchronized. It can be treated as an
+          atomic operation.
+
+*******************************************************************************/
+
+classinfo *load_class_bootstrap(utf *name)
+{
+       classbuffer *cb;
+       classinfo   *c;
+       classinfo   *r;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_lookup, time_array, time_suck, 
+                                       time_load, time_cache;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       /* for debugging */
+
+       assert(name);
+
+       /* lookup if this class has already been loaded */
+
+       r = classcache_lookup(NULL, name);
+
+       if (r != NULL) {
+               RT_TIMING_GET_TIME(time_lookup);
+               RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
+               
+               return r;
+       }
+
+       RT_TIMING_GET_TIME(time_lookup);
+       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
+               
+       /* create the classinfo */
+
+       c = class_create_classinfo(name);
+
+       /* handle array classes */
+
+       if (name->text[0] == '[') {
+               c = load_newly_created_array(c, NULL);
+
+               if (c == NULL)
+                       return NULL;
+
+               assert(c->state & CLASS_LOADED);
+
+               RT_TIMING_GET_TIME(time_array);
+               RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
+               
+               return c;
+       }
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getcompilingtime)
+               compilingtime_stop();
+
+       if (opt_getloadingtime)
+               loadingtime_start();
+#endif
+
+       /* load classdata, throw exception on error */
+
+       cb = suck_start(c);
+
+       if (cb == NULL) {
+               exceptions_throw_classnotfoundexception(name);
+               return NULL;
+       }
+
+       RT_TIMING_GET_TIME(time_suck);
+       
+       /* load the class from the buffer */
+
+       r = load_class_from_classbuffer(cb);
+
+       RT_TIMING_GET_TIME(time_load);
+       
+       if (r == NULL) {
+               /* the class could not be loaded, free the classinfo struct */
+
+               class_free(c);
+       }
+       else {
+               /* Store this class in the loaded class cache this step also
+                  checks the loading constraints. If the class has been
+                  loaded before, the earlier loaded class is returned. */
+
+               classinfo *res = classcache_store(NULL, c, true);
+
+               if (res == NULL) {
+                       /* exception */
+                       class_free(c);
+               }
+               else {
+                       /* Add the package name to the boot packages. */
+
+                       Package_add(c->packagename);
+               }
+
+               r = res;
+       }
+
+       RT_TIMING_GET_TIME(time_cache);
+       
+       /* SUN compatible -verbose:class output */
+
+       if (opt_verboseclass && r) {
+               printf("[Loaded ");
+               utf_display_printable_ascii_classname(name);
+               printf(" from %s]\n", cb->path);
+       }
+
+       /* free memory */
+
+       suck_stop(cb);
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_stop();
+
+       if (opt_getcompilingtime)
+               compilingtime_start();
+#endif
+
+       RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
+       RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
+       RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
+       RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
+
+       return r;
+}
+
+
+/* load_class_from_classbuffer_intern ******************************************
+       
+   Loads a class from a classbuffer into a given classinfo structure.
+   Super-classes are also loaded at this point and some verfication
+   checks are done.
+
+   SYNCHRONIZATION:
+       This function is NOT synchronized!
+   
+*******************************************************************************/
+
+static bool load_class_from_classbuffer_intern(classbuffer *cb)
+{
+       classinfo          *c;
+       classinfo          *tc;
+       utf                *name;
+       utf                *supername;
+       utf               **interfacesnames;
+       utf                *u;
+       constant_classref  *cr;
+       int16_t             index;
+
+       u4 i,j;
+       u4 ma, mi;
+       descriptor_pool *descpool;
+#if defined(ENABLE_STATISTICS)
+       u4 classrefsize;
+       u4 descsize;
+#endif
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_checks, time_ndpool, time_cpool,
+                                       time_setup, time_fields, time_methods, time_classrefs,
+                                       time_descs,     time_setrefs, time_parsefds, time_parsemds,
+                                       time_parsecpool, time_verify, time_attrs;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       /* Get the classbuffer's class. */
+
+       c = cb->clazz;
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
+               return false;
+
+       /* check signature */
+
+       if (suck_u4(cb) != MAGIC) {
+               exceptions_throw_classformaterror(c, "Bad magic number");
+               return false;
+       }
+
+       /* check version */
+
+       mi = suck_u2(cb);
+       ma = suck_u2(cb);
+
+       if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
+               exceptions_throw_unsupportedclassversionerror(c, ma, mi);
+               return false;
+       }
+
+       RT_TIMING_GET_TIME(time_checks);
+
+       /* create a new descriptor pool */
+
+       descpool = descriptor_pool_new(c);
+
+       RT_TIMING_GET_TIME(time_ndpool);
+
+       /* load the constant pool */
+
+       if (!load_constantpool(cb, descpool))
+               return false;
+
+       RT_TIMING_GET_TIME(time_cpool);
+
+       /* ACC flags */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* We OR the flags here, as we set already some flags in
+          class_create_classinfo. */
+
+       c->flags |= suck_u2(cb);
+
+       /* check ACC flags consistency */
+
+       if (c->flags & ACC_INTERFACE) {
+               if (!(c->flags & ACC_ABSTRACT)) {
+                       /* We work around this because interfaces in JDK 1.1 are
+                        * not declared abstract. */
+
+                       c->flags |= ACC_ABSTRACT;
+               }
+
+               if (c->flags & ACC_FINAL) {
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal class modifiers: 0x%X",
+                                                                                         c->flags);
+                       return false;
+               }
+
+               if (c->flags & ACC_SUPER) {
+                       c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
+               }
+       }
+
+       if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
+               exceptions_throw_classformaterror(c,
+                                                                                 "Illegal class modifiers: 0x%X",
+                                                                                 c->flags);
+               return false;
+       }
+
+       if (!suck_check_classbuffer_size(cb, 2 + 2))
+               return false;
+
+       /* This class. */
+
+       index = suck_u2(cb);
+
+       name = (utf *) class_getconstant(c, index, CONSTANT_Class);
+
+       if (name == NULL)
+               return false;
+
+       if (c->name == utf_not_named_yet) {
+               /* we finally have a name for this class */
+               c->name = name;
+               class_set_packagename(c);
+       }
+       else if (name != c->name) {
+               exceptions_throw_noclassdeffounderror_wrong_name(c, name);
+               return false;
+       }
+
+       /* Retrieve superclass. */
+
+       c->super = NULL;
+
+       index = suck_u2(cb);
+
+       if (index == 0) {
+               supername = NULL;
+
+               /* This is only allowed for java.lang.Object. */
+
+               if (c->name != utf_java_lang_Object) {
+                       exceptions_throw_classformaterror(c, "Bad superclass index");
+                       return false;
+               }
+       }
+       else {
+               supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
+
+               if (supername == NULL)
+                       return false;
+
+               /* java.lang.Object may not have a super class. */
+
+               if (c->name == utf_java_lang_Object) {
+                       exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
+                       return false;
+               }
+
+               /* Detect circularity. */
+
+               if (supername == c->name) {
+                       exceptions_throw_classcircularityerror(c);
+                       return false;
+               }
+
+               /* Interfaces must have java.lang.Object as super class. */
+
+               if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
+                       exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
+                       return false;
+               }
+       }
+
+       /* Parse the super interfaces. */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       c->interfacescount = suck_u2(cb);
+
+       if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
+               return false;
+
+       c->interfaces = MNEW(classinfo*, c->interfacescount);
+
+       /* Get the names of the super interfaces. */
+
+       interfacesnames = DMNEW(utf*, c->interfacescount);
+
+       for (i = 0; i < c->interfacescount; i++) {
+               index = suck_u2(cb);
+
+               u = (utf *) class_getconstant(c, index, CONSTANT_Class);
+
+               if (u == NULL)
+                       return false;
+
+               interfacesnames[i] = u;
+       }
+
+       RT_TIMING_GET_TIME(time_setup);
+
+       /* Parse fields. */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       c->fieldscount = suck_u2(cb);
+       c->fields      = MNEW(fieldinfo, c->fieldscount);
+
+       MZERO(c->fields, fieldinfo, c->fieldscount);
+
+       for (i = 0; i < c->fieldscount; i++) {
+               if (!field_load(cb, &(c->fields[i]), descpool))
+                       return false;
+       }
+
+       RT_TIMING_GET_TIME(time_fields);
+
+       /* Parse methods. */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       c->methodscount = suck_u2(cb);
+       c->methods      = MNEW(methodinfo, c->methodscount);
+
+       MZERO(c->methods, methodinfo, c->methodscount);
+       
+       for (i = 0; i < c->methodscount; i++) {
+               if (!method_load(cb, &(c->methods[i]), descpool))
+                       return false;
+       }
+
+       RT_TIMING_GET_TIME(time_methods);
+
+       /* create the class reference table */
+
+       c->classrefs =
+               descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
+
+       RT_TIMING_GET_TIME(time_classrefs);
+
+       /* allocate space for the parsed descriptors */
+
+       descriptor_pool_alloc_parsed_descriptors(descpool);
+       c->parseddescs =
+               descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat) {
+               descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
+               count_classref_len += classrefsize;
+               count_parsed_desc_len += descsize;
+       }
+#endif
+
+       RT_TIMING_GET_TIME(time_descs);
+
+       /* put the classrefs in the constant pool */
+
+       for (i = 0; i < c->cpcount; i++) {
+               if (c->cptags[i] == CONSTANT_Class) {
+                       utf *name = (utf *) c->cpinfos[i];
+                       c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
+               }
+       }
+
+       /* Resolve the super class. */
+
+       if (supername != NULL) {
+               cr = descriptor_pool_lookup_classref(descpool, supername);
+
+               if (cr == NULL)
+                       return false;
+
+               /* XXX This should be done better. */
+               tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
+
+               if (tc == NULL) {
+                       resolve_handle_pending_exception(true);
+                       return false;
+               }
+
+               /* Interfaces are not allowed as super classes. */
+
+               if (tc->flags & ACC_INTERFACE) {
+                       exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
+                       return false;
+               }
+
+               /* Don't allow extending final classes */
+
+               if (tc->flags & ACC_FINAL) {
+                       exceptions_throw_verifyerror(NULL,
+                                                                                "Cannot inherit from final class");
+                       return false;
+               }
+
+               /* Store the super class. */
+
+               c->super = tc;
+       }
+
+       /* Resolve the super interfaces. */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               u  = interfacesnames[i];
+               cr = descriptor_pool_lookup_classref(descpool, u);
+
+               if (cr == NULL)
+                       return false;
+
+               /* XXX This should be done better. */
+               tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
+
+               if (tc == NULL) {
+                       resolve_handle_pending_exception(true);
+                       return false;
+               }
+
+               /* Detect circularity. */
+
+               if (tc == c) {
+                       exceptions_throw_classcircularityerror(c);
+                       return false;
+               }
+
+               if (!(tc->flags & ACC_INTERFACE)) {
+                       exceptions_throw_incompatibleclasschangeerror(tc,
+                                                                                                                 "Implementing class");
+                       return false;
+               }
+
+               /* Store the super interface. */
+
+               c->interfaces[i] = tc;
+       }
+
+       RT_TIMING_GET_TIME(time_setrefs);
+
+       /* Parse the field descriptors. */
+
+       for (i = 0; i < c->fieldscount; i++) {
+               c->fields[i].parseddesc =
+                       descriptor_pool_parse_field_descriptor(descpool,
+                                                                                                  c->fields[i].descriptor);
+               if (!c->fields[i].parseddesc)
+                       return false;
+       }
+
+       RT_TIMING_GET_TIME(time_parsefds);
+
+       /* parse method descriptors */
+
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &c->methods[i];
+               m->parseddesc =
+                       descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
+                                                                                                       m->flags, class_get_self_classref(m->clazz));
+               if (!m->parseddesc)
+                       return false;
+
+               for (j = 0; j < m->rawexceptiontablelength; j++) {
+                       if (!m->rawexceptiontable[j].catchtype.any)
+                               continue;
+
+                       if ((m->rawexceptiontable[j].catchtype.ref =
+                                descriptor_pool_lookup_classref(descpool,
+                                               (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
+                               return false;
+               }
+
+               for (j = 0; j < m->thrownexceptionscount; j++) {
+                       if (!m->thrownexceptions[j].any)
+                               continue;
+
+                       if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
+                                               (utf *) m->thrownexceptions[j].any)) == NULL)
+                               return false;
+               }
+       }
+
+       RT_TIMING_GET_TIME(time_parsemds);
+
+       /* parse the loaded descriptors */
+
+       for (i = 0; i < c->cpcount; i++) {
+               constant_FMIref *fmi;
+               s4               index;
+
+               switch (c->cptags[i]) {
+               case CONSTANT_Fieldref:
+                       fmi = (constant_FMIref *) c->cpinfos[i];
+                       fmi->parseddesc.fd =
+                               descriptor_pool_parse_field_descriptor(descpool,
+                                                                                                          fmi->descriptor);
+                       if (!fmi->parseddesc.fd)
+                               return false;
+
+                       index = fmi->p.index;
+                       fmi->p.classref =
+                               (constant_classref *) class_getconstant(c, index,
+                                                                                                               CONSTANT_Class);
+                       if (!fmi->p.classref)
+                               return false;
+                       break;
+               case CONSTANT_Methodref:
+               case CONSTANT_InterfaceMethodref:
+                       fmi = (constant_FMIref *) c->cpinfos[i];
+                       index = fmi->p.index;
+                       fmi->p.classref =
+                               (constant_classref *) class_getconstant(c, index,
+                                                                                                               CONSTANT_Class);
+                       if (!fmi->p.classref)
+                               return false;
+                       fmi->parseddesc.md =
+                               descriptor_pool_parse_method_descriptor(descpool,
+                                                                                                               fmi->descriptor,
+                                                                                                               ACC_UNDEF,
+                                                                                                               fmi->p.classref);
+                       if (!fmi->parseddesc.md)
+                               return false;
+                       break;
+               }
+       }
+
+       RT_TIMING_GET_TIME(time_parsecpool);
+
+#ifdef ENABLE_VERIFIER
+       /* Check if all fields and methods can be uniquely
+        * identified by (name,descriptor). */
+
+       if (opt_verify) {
+               /* We use a hash table here to avoid making the
+                * average case quadratic in # of methods, fields.
+                */
+               static int shift = 0;
+               u2 *hashtab;
+               u2 *next; /* for chaining colliding hash entries */
+               size_t len;
+               size_t hashlen;
+               u2 index;
+               u2 old;
+
+               /* Allocate hashtable */
+               len = c->methodscount;
+               if (len < c->fieldscount) len = c->fieldscount;
+               hashlen = 5 * len;
+               hashtab = MNEW(u2,(hashlen + len));
+               next = hashtab + hashlen;
+
+               /* Determine bitshift (to get good hash values) */
+               if (!shift) {
+                       len = sizeof(utf);
+                       while (len) {
+                               len >>= 1;
+                               shift++;
+                       }
+               }
+
+               /* Check fields */
+               memset(hashtab, 0, sizeof(u2) * (hashlen + len));
+
+               for (i = 0; i < c->fieldscount; ++i) {
+                       fieldinfo *fi = c->fields + i;
+
+                       /* It's ok if we lose bits here */
+                       index = ((((size_t) fi->name) +
+                                         ((size_t) fi->descriptor)) >> shift) % hashlen;
+
+                       if ((old = hashtab[index])) {
+                               old--;
+                               next[i] = old;
+                               do {
+                                       if (c->fields[old].name == fi->name &&
+                                               c->fields[old].descriptor == fi->descriptor) {
+                                               exceptions_throw_classformaterror(c, "Repetitive field name/signature");
+                                               return false;
+                                       }
+                               } while ((old = next[old]));
+                       }
+                       hashtab[index] = i + 1;
+               }
+
+               /* Check methods */
+               memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
+
+               for (i = 0; i < c->methodscount; ++i) {
+                       methodinfo *mi = c->methods + i;
+
+                       /* It's ok if we lose bits here */
+                       index = ((((size_t) mi->name) +
+                                         ((size_t) mi->descriptor)) >> shift) % hashlen;
+
+                       if ((old = hashtab[index])) {
+                               old--;
+                               next[i] = old;
+                               do {
+                                       if (c->methods[old].name == mi->name &&
+                                               c->methods[old].descriptor == mi->descriptor) {
+                                               exceptions_throw_classformaterror(c, "Repetitive method name/signature");
+                                               return false;
+                                       }
+                               } while ((old = next[old]));
+                       }
+                       hashtab[index] = i + 1;
+               }
+
+               MFREE(hashtab, u2, (hashlen + len));
+       }
+#endif /* ENABLE_VERIFIER */
+
+       RT_TIMING_GET_TIME(time_verify);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat) {
+               size_classinfo  += sizeof(classinfo*) * c->interfacescount;
+               size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
+               size_methodinfo += sizeof(methodinfo) * c->methodscount;
+       }
+#endif
+
+       /* load attribute structures */
+
+       if (!class_load_attributes(cb))
+               return false;
+
+       /* Pre Java 1.5 version don't check this. This implementation is
+          like Java 1.5 do it: for class file version 45.3 we don't check
+          it, older versions are checked. */
+
+       if (((ma == 45) && (mi > 3)) || (ma > 45)) {
+               /* check if all data has been read */
+               s4 classdata_left = ((cb->data + cb->size) - cb->pos);
+
+               if (classdata_left > 0) {
+                       exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
+                       return false;
+               }
+       }
+
+       RT_TIMING_GET_TIME(time_attrs);
+
+       RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
+       RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
+       RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
+       RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
+       RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
+       RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
+       RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
+       RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
+       RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
+       RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
+       RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
+       RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
+       RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
+       RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
+       RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
+
+       return true;
+}
+
+
+/* load_class_from_classbuffer *************************************************
+
+   Convenience wrapper for load_class_from_classbuffer.
+
+   SYNCHRONIZATION:
+       This function is NOT synchronized!
+   
+*******************************************************************************/
+
+classinfo *load_class_from_classbuffer(classbuffer *cb)
+{
+       classinfo *c;
+       bool       result;
+       int32_t    dumpmarker;
+
+       /* Get the classbuffer's class. */
+
+       c = cb->clazz;
+
+       /* Check if the class is already loaded. */
+
+       if (c->state & CLASS_LOADED)
+               return c;
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_class_loads++;
+#endif
+
+#if !defined(NDEBUG)
+       if (loadverbose)
+               log_message_class("Loading class: ", c);
+#endif
+
+       /* Mark start of dump memory area. */
+
+       DMARKER;
+
+       /* Class is currently loading. */
+
+       c->state |= CLASS_LOADING;
+
+       /* Parse the classbuffer. */
+
+       result = load_class_from_classbuffer_intern(cb);
+
+       /* Release dump area. */
+
+       DRELEASE;
+
+       /* An error occurred. */
+
+       if (result == false) {
+               /* Revert loading state. */
+
+               c->state = (c->state & ~CLASS_LOADING);
+
+               return NULL;
+       }
+
+       /* Revert loading state and set loaded. */
+
+       c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
+
+#if defined(ENABLE_JVMTI)
+       /* fire Class Prepare JVMTI event */
+
+       if (jvmti)
+               jvmti_ClassLoadPrepare(true, c);
+#endif
+
+#if !defined(NDEBUG)
+       if (loadverbose)
+               log_message_class("Loading done class: ", c);
+#endif
+
+       return c;
+}
+
+
+/* load_newly_created_array ****************************************************
+
+   Load a newly created array class.
+
+       RETURN VALUE:
+           c....................the array class C has been loaded
+               other classinfo......the array class was found in the class cache, 
+                                    C has been freed
+           NULL.................an exception has been thrown
+
+       Note:
+               This is an internal function. Do not use it unless you know exactly
+               what you are doing!
+
+               Use one of the load_class_... functions for general array class loading.
+
+*******************************************************************************/
+
+classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
+{
+       classinfo         *comp = NULL;
+       methodinfo        *clone;
+       methoddesc        *clonedesc;
+       constant_classref *classrefs;
+       char              *text;
+       s4                 namelen;
+       utf               *u;
+
+       text    = c->name->text;
+       namelen = c->name->blength;
+
+       /* Check array class name */
+
+       if ((namelen < 2) || (text[0] != '[')) {
+               exceptions_throw_classnotfoundexception(c->name);
+               return NULL;
+       }
+
+       /* Check the element type */
+
+       switch (text[1]) {
+       case '[':
+               /* c is an array of arrays. We have to create the component class. */
+
+               u = utf_new(text + 1, namelen - 1);
+
+               comp = load_class_from_classloader(u, loader);
+
+               if (comp == NULL)
+                       return NULL;
+
+               assert(comp->state & CLASS_LOADED);
+
+               /* the array's flags are that of the component class */
+               c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
+               c->classloader = comp->classloader;
+               break;
+
+       case 'L':
+               /* c is an array of objects. */
+
+               /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
+               if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
+                       exceptions_throw_classnotfoundexception(c->name);
+                       return NULL;
+               }
+
+               u = utf_new(text + 2, namelen - 3);
+
+               if (!(comp = load_class_from_classloader(u, loader)))
+                       return NULL;
+
+               assert(comp->state & CLASS_LOADED);
+
+               /* the array's flags are that of the component class */
+               c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
+               c->classloader = comp->classloader;
+               break;
+
+       default:
+               /* c is an array of a primitive type */
+
+               /* check for cases like `[II' and whether the character is a
+                  valid primitive type */
+
+               if ((namelen > 2) || (Primitive_get_class_by_char(text[1]) == NULL)) {
+                       exceptions_throw_classnotfoundexception(c->name);
+                       return NULL;
+               }
+
+               /* the accessibility of the array class is public (VM Spec 5.3.3) */
+               c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
+               c->classloader = NULL;
+       }
+
+       assert(class_java_lang_Object);
+#if defined(ENABLE_JAVASE)
+       assert(class_java_lang_Cloneable);
+       assert(class_java_io_Serializable);
+#endif
+
+       /* Setup the array class. */
+
+       c->super = class_java_lang_Object;
+
+#if defined(ENABLE_JAVASE)
+
+       c->interfacescount = 2;
+    c->interfaces      = MNEW(classinfo*, 2);
+       c->interfaces[0]   = class_java_lang_Cloneable;
+       c->interfaces[1]   = class_java_io_Serializable;
+
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+
+       c->interfacescount = 0;
+       c->interfaces      = NULL;
+
+#else
+# error unknow Java configuration
+#endif
+
+       c->methodscount = 1;
+       c->methods      = MNEW(methodinfo, c->methodscount);
+
+       MZERO(c->methods, methodinfo, c->methodscount);
+
+       classrefs = MNEW(constant_classref, 2);
+
+       CLASSREF_INIT(classrefs[0], c, c->name);
+       CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
+
+       /* create descriptor for clone method */
+       /* we need one paramslot which is reserved for the 'this' parameter */
+       clonedesc = NEW(methoddesc);
+       clonedesc->returntype.type = TYPE_ADR;
+       clonedesc->returntype.classref = classrefs + 1;
+       clonedesc->returntype.arraydim = 0;
+       /* initialize params to "empty", add real params below in
+          descriptor_params_from_paramtypes */
+       clonedesc->paramcount = 0;
+       clonedesc->paramslots = 0;
+       clonedesc->paramtypes[0].classref = classrefs + 0;
+       clonedesc->params = NULL;
+
+       /* create methodinfo */
+
+       clone = c->methods;
+       MSET(clone, 0, methodinfo, 1);
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(&clone->header);
+#endif
+
+       /* ATTENTION: if you delete the ACC_NATIVE below, set
+          clone->maxlocals=1 (interpreter related) */
+
+       clone->flags      = ACC_PUBLIC | ACC_NATIVE;
+       clone->name       = utf_clone;
+       clone->descriptor = utf_void__java_lang_Object;
+       clone->parseddesc = clonedesc;
+       clone->clazz      = c;
+
+       /* parse the descriptor to get the register allocation */
+
+       if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
+               return false;
+
+       clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
+
+       /* XXX: field: length? */
+
+       /* array classes are not loaded from class files */
+
+       c->state          |= CLASS_LOADED;
+       c->parseddescs    = (u1 *) clonedesc;
+       c->parseddescsize = sizeof(methodinfo);
+       c->classrefs      = classrefs;
+       c->classrefcount  = 1;
+
+       /* insert class into the loaded class cache */
+       /* XXX free classinfo if NULL returned? */
+
+       return classcache_store(loader, c, true);
+}
+
+
+/* loader_close ****************************************************************
+
+   Frees all resources.
+       
+*******************************************************************************/
+
+void loader_close(void)
+{
+       /* empty */
+}
+
+
+/*
+ * 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/loader.h b/src/vm/loader.h
new file mode 100644 (file)
index 0000000..3b2c353
--- /dev/null
@@ -0,0 +1,182 @@
+/* src/vm/loader.h - class loader header
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _LOADER_H
+#define _LOADER_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct classbuffer classbuffer;
+
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "vm/types.h"
+
+#include "vm/descriptor.h"
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/method.h"
+#include "vm/references.h"
+#include "vm/utf8.h"
+
+
+/* constant pool entries *******************************************************
+
+       All constant pool entries need a data structure which contain the entrys
+       value. In some cases this structure exist already, in the remaining cases
+       this structure must be generated:
+
+               kind                      structure                     generated?
+       ----------------------------------------------------------------------
+    CONSTANT_Class               constant_classref                  yes
+    CONSTANT_Fieldref            constant_FMIref                    yes
+    CONSTANT_Methodref           constant_FMIref                    yes
+    CONSTANT_InterfaceMethodref  constant_FMIref                    yes
+    CONSTANT_String              unicode                             no
+    CONSTANT_Integer             constant_integer                   yes
+    CONSTANT_Float               constant_float                     yes
+    CONSTANT_Long                constant_long                      yes
+    CONSTANT_Double              constant_double                    yes
+    CONSTANT_NameAndType         constant_nameandtype               yes
+    CONSTANT_Utf8                unicode                             no
+    CONSTANT_UNUSED              -
+
+*******************************************************************************/
+
+typedef struct {            /* Integer                                        */
+       s4 value;
+} constant_integer;
+
+       
+typedef struct {            /* Float                                          */
+       float value;
+} constant_float;
+
+
+typedef struct {            /* Long                                           */
+       s8 value;
+} constant_long;
+       
+
+typedef struct {            /* Double                                         */
+       double value;
+} constant_double;
+
+
+typedef struct {            /* NameAndType (Field or Method)                  */
+       utf *name;              /* field/method name                              */
+       utf *descriptor;        /* field/method type descriptor string            */
+} constant_nameandtype;
+
+
+/* classbuffer ****************************************************************/
+
+struct classbuffer {
+       classinfo *clazz;                   /* pointer to classinfo structure     */
+       uint8_t   *data;                    /* pointer to byte code               */
+       int32_t    size;                    /* size of the byte code              */
+       uint8_t   *pos;                     /* current read position              */
+       char      *path;                    /* path to file (for debugging)       */
+};
+
+
+/* hashtable_classloader_entry *************************************************
+
+   ATTENTION: The pointer to the classloader object needs to be the
+   first field of the entry, so that it can be used as an indirection
+   cell. This is checked by gc_init() during startup.
+
+*******************************************************************************/
+
+typedef struct hashtable_classloader_entry hashtable_classloader_entry;
+
+struct hashtable_classloader_entry {
+       java_object_t               *object;
+       hashtable_classloader_entry *hashlink;
+};
+
+
+/* classloader *****************************************************************
+
+   [!ENABLE_HANDLES]: The classloader is a Java Object which cannot move.
+   [ENABLE_HANDLES] : The classloader entry itself is a static handle for a
+                      given classloader (use loader_hashtable_classloader_foo).
+
+*******************************************************************************/
+
+#if defined(ENABLE_HANDLES)
+typedef hashtable_classloader_entry classloader_t;
+#else
+typedef java_object_t               classloader_t;
+#endif
+
+
+/* function prototypes ********************************************************/
+
+void loader_preinit(void);
+void loader_init(void);
+
+/* classloader management functions */
+classloader_t *loader_hashtable_classloader_add(java_handle_t *cl);
+classloader_t *loader_hashtable_classloader_find(java_handle_t *cl);
+
+void loader_load_all_classes(void);
+
+bool loader_skip_attribute_body(classbuffer *cb);
+
+#if defined(ENABLE_JAVASE)
+bool loader_load_attribute_signature(classbuffer *cb, utf **signature);
+#endif
+
+/* free resources */
+void loader_close(void);
+
+/* class loading functions */
+classinfo *load_class_from_sysloader(utf *name);
+classinfo *load_class_from_classloader(utf *name, classloader_t *cl);
+classinfo *load_class_bootstrap(utf *name);
+
+/* (don't use the following directly) */
+classinfo *load_class_from_classbuffer(classbuffer *cb);
+classinfo *load_newly_created_array(classinfo *c, classloader_t *loader);
+
+#endif /* _LOADER_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/method.c b/src/vm/method.c
new file mode 100644 (file)
index 0000000..08171f1
--- /dev/null
@@ -0,0 +1,1215 @@
+/* src/vm/method.c - method functions
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "threads/lock-common.h"
+
+#include "vm/array.h"
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/resolve.h"
+#include "vm/suck.h"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+#include "vm/jit/code.h"
+#include "vm/jit/methodheader.h"
+
+
+#if !defined(NDEBUG) && defined(ENABLE_INLINING)
+#define INLINELOG(code)  do { if (opt_TraceInlining) { code } } while (0)
+#else
+#define INLINELOG(code)
+#endif
+
+
+/* global variables ***********************************************************/
+
+methodinfo *method_java_lang_reflect_Method_invoke;
+
+
+/* method_init *****************************************************************
+
+   Initialize method subsystem.
+
+*******************************************************************************/
+
+void method_init(void)
+{
+#if defined(ENABLE_JAVASE)
+       /* Sanity check. */
+
+       if (class_java_lang_reflect_Method == NULL)
+               vm_abort("method_init: class_java_lang_reflect_Method is NULL");
+
+       /* Cache java.lang.reflect.Method.invoke() */
+
+       method_java_lang_reflect_Method_invoke =
+               class_findmethod(class_java_lang_reflect_Method, utf_invoke, NULL);
+
+       if (method_java_lang_reflect_Method_invoke == NULL)
+               vm_abort("method_init: Could not resolve method java.lang.reflect.Method.invoke().");
+#endif
+}
+
+
+/* method_load *****************************************************************
+
+   Loads a method from the class file and fills an existing methodinfo
+   structure.
+
+   method_info {
+       u2 access_flags;
+          u2 name_index;
+          u2 descriptor_index;
+          u2 attributes_count;
+          attribute_info attributes[attribute_count];
+   }
+
+   attribute_info {
+       u2 attribute_name_index;
+          u4 attribute_length;
+          u1 info[attribute_length];
+   }
+
+   LineNumberTable_attribute {
+       u2 attribute_name_index;
+          u4 attribute_length;
+          u2 line_number_table_length;
+          {
+              u2 start_pc;
+                  u2 line_number;
+          } line_number_table[line_number_table_length];
+   }
+
+*******************************************************************************/
+
+bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
+{
+       classinfo *c;
+       int argcount;
+       s4         i, j, k, l;
+       utf       *u;
+       u2         name_index;
+       u2         descriptor_index;
+       u2         attributes_count;
+       u2         attribute_name_index;
+       utf       *attribute_name;
+       u2         code_attributes_count;
+       u2         code_attribute_name_index;
+       utf       *code_attribute_name;
+
+       /* get classinfo */
+
+       c = cb->clazz;
+
+       LOCK_INIT_OBJECT_LOCK(&(m->header));
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_all_methods++;
+#endif
+
+       /* all fields of m have been zeroed in load_class_from_classbuffer */
+
+       m->clazz = c;
+       
+       if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
+               return false;
+
+       /* access flags */
+
+       m->flags = suck_u2(cb);
+
+       /* name */
+
+       name_index = suck_u2(cb);
+
+       if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
+               return false;
+
+       m->name = u;
+
+       /* descriptor */
+
+       descriptor_index = suck_u2(cb);
+
+       if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
+               return false;
+
+       m->descriptor = u;
+
+       if (!descriptor_pool_add(descpool, u, &argcount))
+               return false;
+
+#ifdef ENABLE_VERIFIER
+       if (opt_verify) {
+               if (!is_valid_name_utf(m->name)) {
+                       exceptions_throw_classformaterror(c, "Method with invalid name");
+                       return false;
+               }
+
+               if (m->name->text[0] == '<' &&
+                       m->name != utf_init && m->name != utf_clinit) {
+                       exceptions_throw_classformaterror(c, "Method with invalid special name");
+                       return false;
+               }
+       }
+#endif /* ENABLE_VERIFIER */
+       
+       if (!(m->flags & ACC_STATIC))
+               argcount++; /* count the 'this' argument */
+
+#ifdef ENABLE_VERIFIER
+       if (opt_verify) {
+               if (argcount > 255) {
+                       exceptions_throw_classformaterror(c, "Too many arguments in signature");
+                       return false;
+               }
+
+               /* check flag consistency */
+               if (m->name != utf_clinit) {
+                       i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
+
+                       if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal method modifiers: 0x%X",
+                                                                                                 m->flags);
+                               return false;
+                       }
+
+                       if (m->flags & ACC_ABSTRACT) {
+                               if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
+                                                                ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
+                                       exceptions_throw_classformaterror(c,
+                                                                                                         "Illegal method modifiers: 0x%X",
+                                                                                                         m->flags);
+                                       return false;
+                               }
+                       }
+
+                       if (c->flags & ACC_INTERFACE) {
+                               if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
+                                       exceptions_throw_classformaterror(c,
+                                                                                                         "Illegal method modifiers: 0x%X",
+                                                                                                         m->flags);
+                                       return false;
+                               }
+                       }
+
+                       if (m->name == utf_init) {
+                               if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
+                                                               ACC_NATIVE | ACC_ABSTRACT)) {
+                                       exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
+                                       return false;
+                               }
+                       }
+               }
+       }
+#endif /* ENABLE_VERIFIER */
+
+       /* mark the method as monomorphic until further notice */
+
+       m->flags |= ACC_METHOD_MONOMORPHIC;
+
+       /* non-abstract methods have an implementation in this class */
+
+       if (!(m->flags & ACC_ABSTRACT))
+               m->flags |= ACC_METHOD_IMPLEMENTED;
+               
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* attributes count */
+
+       attributes_count = suck_u2(cb);
+
+       for (i = 0; i < attributes_count; i++) {
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               /* attribute name index */
+
+               attribute_name_index = suck_u2(cb);
+
+               attribute_name =
+                       class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
+
+               if (attribute_name == NULL)
+                       return false;
+
+               if (attribute_name == utf_Code) {
+                       /* Code */
+
+                       if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
+                               exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
+                               return false;
+                       }
+                       
+                       if (m->jcode) {
+                               exceptions_throw_classformaterror(c, "Multiple Code attributes");
+                               return false;
+                       }
+
+                       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
+                               return false;
+
+                       suck_u4(cb);
+                       m->maxstack = suck_u2(cb);
+                       m->maxlocals = suck_u2(cb);
+
+                       if (m->maxlocals < argcount) {
+                               exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
+                               return false;
+                       }
+                       
+                       if (!suck_check_classbuffer_size(cb, 4))
+                               return false;
+
+                       m->jcodelength = suck_u4(cb);
+
+                       if (m->jcodelength == 0) {
+                               exceptions_throw_classformaterror(c, "Code of a method has length 0");
+                               return false;
+                       }
+                       
+                       if (m->jcodelength > 65535) {
+                               exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
+                               return false;
+                       }
+
+                       if (!suck_check_classbuffer_size(cb, m->jcodelength))
+                               return false;
+
+                       m->jcode = MNEW(u1, m->jcodelength);
+                       suck_nbytes(m->jcode, cb, m->jcodelength);
+
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       m->rawexceptiontablelength = suck_u2(cb);
+                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
+                               return false;
+
+                       m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
+
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat) {
+                               count_vmcode_len += m->jcodelength + 18;
+                               count_extable_len +=
+                                       m->rawexceptiontablelength * sizeof(raw_exception_entry);
+                       }
+#endif
+
+                       for (j = 0; j < m->rawexceptiontablelength; j++) {
+                               u4 idx;
+                               m->rawexceptiontable[j].startpc   = suck_u2(cb);
+                               m->rawexceptiontable[j].endpc     = suck_u2(cb);
+                               m->rawexceptiontable[j].handlerpc = suck_u2(cb);
+
+                               idx = suck_u2(cb);
+
+                               if (!idx) {
+                                       m->rawexceptiontable[j].catchtype.any = NULL;
+                               }
+                               else {
+                                       /* the classref is created later */
+                                       if (!(m->rawexceptiontable[j].catchtype.any =
+                                                 (utf *) class_getconstant(c, idx, CONSTANT_Class)))
+                                               return false;
+                               }
+                       }
+
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       /* code attributes count */
+
+                       code_attributes_count = suck_u2(cb);
+
+                       for (k = 0; k < code_attributes_count; k++) {
+                               if (!suck_check_classbuffer_size(cb, 2))
+                                       return false;
+
+                               /* code attribute name index */
+
+                               code_attribute_name_index = suck_u2(cb);
+
+                               code_attribute_name =
+                                       class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8);
+
+                               if (code_attribute_name == NULL)
+                                       return false;
+
+                               /* check which code attribute */
+
+                               if (code_attribute_name == utf_LineNumberTable) {
+                                       /* LineNumberTable */
+
+                                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                                               return false;
+
+                                       /* attribute length */
+
+                                       (void) suck_u4(cb);
+
+                                       /* line number table length */
+
+                                       m->linenumbercount = suck_u2(cb);
+
+                                       if (!suck_check_classbuffer_size(cb,
+                                                                                               (2 + 2) * m->linenumbercount))
+                                               return false;
+
+                                       m->linenumbers = MNEW(lineinfo, m->linenumbercount);
+
+#if defined(ENABLE_STATISTICS)
+                                       if (opt_stat)
+                                               size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
+#endif
+                                       
+                                       for (l = 0; l < m->linenumbercount; l++) {
+                                               m->linenumbers[l].start_pc    = suck_u2(cb);
+                                               m->linenumbers[l].line_number = suck_u2(cb);
+                                       }
+                               }
+#if defined(ENABLE_JAVASE)
+                               else if (code_attribute_name == utf_StackMapTable) {
+                                       /* StackTableMap */
+
+                                       if (!stackmap_load_attribute_stackmaptable(cb, m))
+                                               return false;
+                               }
+#endif
+                               else {
+                                       /* unknown code attribute */
+
+                                       if (!loader_skip_attribute_body(cb))
+                                               return false;
+                               }
+                       }
+               }
+               else if (attribute_name == utf_Exceptions) {
+                       /* Exceptions */
+
+                       if (m->thrownexceptions != NULL) {
+                               exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
+                               return false;
+                       }
+
+                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                               return false;
+
+                       /* attribute length */
+
+                       (void) suck_u4(cb);
+
+                       m->thrownexceptionscount = suck_u2(cb);
+
+                       if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
+                               return false;
+
+                       m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
+
+                       for (j = 0; j < m->thrownexceptionscount; j++) {
+                               /* the classref is created later */
+                               if (!((m->thrownexceptions)[j].any =
+                                         (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
+                                       return false;
+                       }
+               }
+#if defined(ENABLE_JAVASE)
+               else if (attribute_name == utf_Signature) {
+                       /* Signature */
+
+                       if (!loader_load_attribute_signature(cb, &(m->signature)))
+                               return false;
+               }
+
+#if defined(ENABLE_ANNOTATIONS)
+               else if (attribute_name == utf_RuntimeVisibleAnnotations) {
+                       /* RuntimeVisibleAnnotations */
+                       if (!annotation_load_method_attribute_runtimevisibleannotations(cb, m))
+                               return false;
+               }
+               else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
+                       /* RuntimeInvisibleAnnotations */
+                       if (!annotation_load_method_attribute_runtimeinvisibleannotations(cb, m))
+                               return false;
+               }
+               else if (attribute_name == utf_RuntimeVisibleParameterAnnotations) {
+                       /* RuntimeVisibleParameterAnnotations */
+                       if (!annotation_load_method_attribute_runtimevisibleparameterannotations(cb, m))
+                               return false;
+               }
+               else if (attribute_name == utf_RuntimeInvisibleParameterAnnotations) {
+                       /* RuntimeInvisibleParameterAnnotations */
+                       if (!annotation_load_method_attribute_runtimeinvisibleparameterannotations(cb, m))
+                               return false;
+               }
+               else if (attribute_name == utf_AnnotationDefault) {
+                       /* AnnotationDefault */
+                       if (!annotation_load_method_attribute_annotationdefault(cb, m))
+                               return false;
+               }
+#endif
+#endif
+               else {
+                       /* unknown attribute */
+
+                       if (!loader_skip_attribute_body(cb))
+                               return false;
+               }
+       }
+
+       if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
+               exceptions_throw_classformaterror(c, "Missing Code attribute");
+               return false;
+       }
+
+#if defined(ENABLE_REPLACEMENT)
+       /* initialize the hit countdown field */
+
+       m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
+#endif
+
+       /* everything was ok */
+
+       return true;
+}
+
+
+/* method_free *****************************************************************
+
+   Frees all memory that was allocated for this method.
+
+*******************************************************************************/
+
+void method_free(methodinfo *m)
+{
+       if (m->jcode)
+               MFREE(m->jcode, u1, m->jcodelength);
+
+       if (m->rawexceptiontable)
+               MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
+
+       code_free_code_of_method(m);
+
+       if (m->stubroutine) {
+               if (m->flags & ACC_NATIVE) {
+                       removenativestub(m->stubroutine);
+
+               } else {
+                       removecompilerstub(m->stubroutine);
+               }
+       }
+}
+
+
+/* method_canoverwrite *********************************************************
+
+   Check if m and old are identical with respect to type and
+   name. This means that old can be overwritten with m.
+       
+*******************************************************************************/
+
+bool method_canoverwrite(methodinfo *m, methodinfo *old)
+{
+       if (m->name != old->name)
+               return false;
+
+       if (m->descriptor != old->descriptor)
+               return false;
+
+       if (m->flags & ACC_STATIC)
+               return false;
+
+       return true;
+}
+
+
+/* method_new_builtin **********************************************************
+
+   Creates a minimal methodinfo structure for builtins. This comes handy
+   when dealing with builtin stubs or stacktraces.
+
+*******************************************************************************/
+
+methodinfo *method_new_builtin(builtintable_entry *bte)
+{
+       methodinfo *m;
+
+       /* allocate the methodinfo structure */
+
+       m = NEW(methodinfo);
+
+       /* initialize methodinfo structure */
+
+       MZERO(m, methodinfo, 1);
+       LOCK_INIT_OBJECT_LOCK(&(m->header));
+
+       m->flags      = ACC_METHOD_BUILTIN;
+       m->parseddesc = bte->md;
+       m->name       = bte->name;
+       m->descriptor = bte->descriptor;
+
+       /* return the newly created methodinfo */
+
+       return m;
+}
+
+
+/* method_vftbl_lookup *********************************************************
+
+   Does a method lookup in the passed virtual function table.  This
+   function does exactly the same thing as JIT, but additionally
+   relies on the fact, that the methodinfo pointer is at the first
+   data segment slot (even for compiler stubs).
+
+*******************************************************************************/
+
+methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
+{
+       methodptr   mptr;
+       methodptr  *pmptr;
+       methodinfo *resm;                   /* pointer to new resolved method     */
+
+       /* If the method is not an instance method, just return it. */
+
+       if (m->flags & ACC_STATIC)
+               return m;
+
+       assert(vftbl);
+
+       /* Get the method from the virtual function table.  Is this an
+          interface method? */
+
+       if (m->clazz->flags & ACC_INTERFACE) {
+               pmptr = vftbl->interfacetable[-(m->clazz->index)];
+               mptr  = pmptr[(m - m->clazz->methods)];
+       }
+       else {
+               mptr = vftbl->table[m->vftblindex];
+       }
+
+       /* and now get the codeinfo pointer from the first data segment slot */
+
+       resm = code_get_methodinfo_for_pv(mptr);
+
+       return resm;
+}
+
+
+/* method_get_parametercount **************************************************
+
+   Use the descriptor of a method to determine the number of parameters
+   of the method. The this pointer of non-static methods is not counted.
+
+   IN:
+       m........the method of which the parameters should be counted
+
+   RETURN VALUE:
+       The parameter count or -1 on error.
+
+*******************************************************************************/
+
+int32_t method_get_parametercount(methodinfo *m)
+{
+       methoddesc *md;             /* method descriptor of m   */
+       int32_t     paramcount = 0; /* the parameter count of m */
+
+       md = m->parseddesc;
+       
+       /* is the descriptor fully parsed? */
+
+       if (md->params == NULL) {
+               if (!descriptor_params_from_paramtypes(md, m->flags)) {
+                       return -1;
+               }
+       }
+
+       paramcount = md->paramcount;
+
+       /* skip `this' pointer */
+
+       if (!(m->flags & ACC_STATIC)) {
+               --paramcount;
+       }
+
+       return paramcount;
+}
+
+
+/* method_get_parametertypearray ***********************************************
+
+   Use the descriptor of a method to generate a java.lang.Class array
+   which contains the classes of the parametertypes of the method.
+
+   This function is called by java.lang.reflect.{Constructor,Method}.
+
+*******************************************************************************/
+
+java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
+{
+       methoddesc                *md;
+       typedesc                  *paramtypes;
+       int32_t                    paramcount;
+       java_handle_objectarray_t *oa;
+       int32_t                    i;
+       classinfo                 *c;
+
+       md = m->parseddesc;
+
+       /* is the descriptor fully parsed? */
+
+       if (m->parseddesc->params == NULL)
+               if (!descriptor_params_from_paramtypes(md, m->flags))
+                       return NULL;
+
+       paramtypes = md->paramtypes;
+       paramcount = md->paramcount;
+
+       /* skip `this' pointer */
+
+       if (!(m->flags & ACC_STATIC)) {
+               paramtypes++;
+               paramcount--;
+       }
+
+       /* create class-array */
+
+       oa = builtin_anewarray(paramcount, class_java_lang_Class);
+
+       if (oa == NULL)
+               return NULL;
+
+    /* get classes */
+
+       for (i = 0; i < paramcount; i++) {
+               if (!resolve_class_from_typedesc(&paramtypes[i], true, false, &c))
+                       return NULL;
+
+               LLNI_array_direct(oa, i) = (java_object_t *) c;
+       }
+
+       return oa;
+}
+
+
+/* method_get_exceptionarray ***************************************************
+
+   Get the exceptions which can be thrown by a method.
+
+*******************************************************************************/
+
+java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
+{
+       java_handle_objectarray_t *oa;
+       classinfo                 *c;
+       s4                         i;
+
+       /* create class-array */
+
+       oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
+
+       if (oa == NULL)
+               return NULL;
+
+       /* iterate over all exceptions and store the class in the array */
+
+       for (i = 0; i < m->thrownexceptionscount; i++) {
+               c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
+
+               if (c == NULL)
+                       return NULL;
+
+               LLNI_array_direct(oa, i) = (java_object_t *) c;
+       }
+
+       return oa;
+}
+
+
+/* method_returntype_get *******************************************************
+
+   Get the return type of the method.
+
+*******************************************************************************/
+
+classinfo *method_returntype_get(methodinfo *m)
+{
+       typedesc  *td;
+       classinfo *c;
+
+       td = &(m->parseddesc->returntype);
+
+       if (!resolve_class_from_typedesc(td, true, false, &c))
+               return NULL;
+
+       return c;
+}
+
+
+/* method_count_implementations ************************************************
+
+   Count the implementations of a method in a class cone (a class and all its
+   subclasses.)
+
+   IN:
+       m................the method to count
+          c................class at which to start the counting (this class and
+                           all its subclasses will be searched)
+
+   OUT:
+       *found...........if found != NULL, *found receives the method
+                           implementation that was found. This value is only
+                                               meaningful if the return value is 1.
+
+   RETURN VALUE:
+       the number of implementations found
+
+*******************************************************************************/
+
+s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
+{
+       s4          count;
+       methodinfo *mp;
+       methodinfo *mend;
+       classinfo  *child;
+
+       count = 0;
+
+       mp = c->methods;
+       mend = mp + c->methodscount;
+
+       for (; mp < mend; ++mp) {
+               if (method_canoverwrite(mp, m)) {
+                       if (found)
+                               *found = mp;
+                       count++;
+                       break;
+               }
+       }
+
+       for (child = c->sub; child != NULL; child = child->nextsub) {
+               count += method_count_implementations(m, child, found);
+       }
+
+       return count;
+}
+
+
+/* method_get_annotations ******************************************************
+
+   Get a methods' unparsed annotations in a byte array.
+
+   IN:
+       m........the method of which the annotations should be returned
+
+   RETURN VALUE:
+       The unparsed annotations in a byte array (or NULL if there aren't any).
+
+*******************************************************************************/
+
+java_handle_bytearray_t *method_get_annotations(methodinfo *m)
+{
+#if defined(ENABLE_ANNOTATIONS)
+       classinfo     *c;                  /* methods' declaring class          */
+       int            slot;               /* methods' slot                     */
+       java_handle_t *annotations;        /* methods' unparsed annotations     */
+       java_handle_t *method_annotations; /* all methods' unparsed annotations */
+                                          /* of the declaring class            */
+
+       c           = m->clazz;
+       slot        = m - c->methods;
+       annotations = NULL;
+
+       LLNI_classinfo_field_get(c, method_annotations, method_annotations);
+
+       /* the method_annotations array might be shorter then the method
+        * count if the methods above a certain index have no annotations.
+        */     
+       if (method_annotations != NULL &&
+               array_length_get(method_annotations) > slot) {
+               annotations = array_objectarray_element_get(
+                       (java_handle_objectarray_t*)method_annotations, slot);
+       }
+       
+       return (java_handle_bytearray_t*)annotations;
+#else
+       return NULL;
+#endif
+}
+
+
+/* method_get_parameterannotations ********************************************
+
+   Get a methods' unparsed parameter annotations in an array of byte
+   arrays.
+
+   IN:
+       m........the method of which the parameter annotations should be
+                   returned
+
+   RETURN VALUE:
+       The unparsed parameter annotations in a byte array (or NULL if
+          there aren't any).
+
+*******************************************************************************/
+
+java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
+{
+#if defined(ENABLE_ANNOTATIONS)
+       classinfo     *c;                           /* methods' declaring class */
+       int            slot;                        /* methods' slot            */
+       java_handle_t *parameterAnnotations;        /* methods' unparsed        */
+                                                   /* parameter annotations    */
+       java_handle_t *method_parameterannotations; /* all methods' unparsed    */
+                                                   /* parameter annotations of */
+                                                   /* the declaring class      */
+
+       c                    = m->clazz;
+       slot                 = m - c->methods;
+       parameterAnnotations = NULL;
+
+       LLNI_classinfo_field_get(
+               c, method_parameterannotations, method_parameterannotations);
+
+       /* the method_annotations array might be shorter then the method
+        * count if the methods above a certain index have no annotations.
+        */     
+       if (method_parameterannotations != NULL &&
+               array_length_get(method_parameterannotations) > slot) {
+               parameterAnnotations = array_objectarray_element_get(
+                               (java_handle_objectarray_t*)method_parameterannotations,
+                               slot);
+       }
+       
+       return (java_handle_bytearray_t*)parameterAnnotations;
+#else
+       return NULL;
+#endif
+}
+
+
+/* method_get_annotationdefault ***********************************************
+
+   Get a methods' unparsed annotation default value in a byte array.
+   
+   IN:
+       m........the method of which the annotation default value should be
+                   returned
+
+   RETURN VALUE:
+       The unparsed annotation default value in a byte array (or NULL if
+          there isn't one).
+
+*******************************************************************************/
+
+java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
+{
+#if defined(ENABLE_ANNOTATIONS)
+       classinfo     *c;                         /* methods' declaring class     */
+       int            slot;                      /* methods' slot                */
+       java_handle_t *annotationDefault;         /* methods' unparsed            */
+                                                 /* annotation default value     */
+       java_handle_t *method_annotationdefaults; /* all methods' unparsed        */
+                                                 /* annotation default values of */
+                                                 /* the declaring class          */
+
+       c                 = m->clazz;
+       slot              = m - c->methods;
+       annotationDefault = NULL;
+
+       LLNI_classinfo_field_get(
+               c, method_annotationdefaults, method_annotationdefaults);
+
+       /* the method_annotations array might be shorter then the method
+        * count if the methods above a certain index have no annotations.
+        */     
+       if (method_annotationdefaults != NULL &&
+               array_length_get(method_annotationdefaults) > slot) {
+               annotationDefault = array_objectarray_element_get(
+                               (java_handle_objectarray_t*)method_annotationdefaults, slot);
+       }
+       
+       return (java_handle_bytearray_t*)annotationDefault;
+#else
+       return NULL;
+#endif
+}
+
+
+/* method_add_to_worklist ******************************************************
+
+   Add the method to the given worklist. If the method already occurs in
+   the worklist, the worklist remains unchanged.
+
+*******************************************************************************/
+
+static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
+{
+       method_worklist *wi;
+
+       for (wi = *wl; wi != NULL; wi = wi->next)
+               if (wi->m == m)
+                       return;
+
+       wi = NEW(method_worklist);
+       wi->next = *wl;
+       wi->m = m;
+
+       *wl = wi;
+}
+
+
+/* method_add_assumption_monomorphic *******************************************
+
+   Record the assumption that the method is monomorphic.
+
+   IN:
+      m.................the method
+         caller............the caller making the assumption
+
+*******************************************************************************/
+
+void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
+{
+       method_assumption *as;
+
+       /* XXX LOCKING FOR THIS FUNCTION? */
+
+       /* check if we already have registered this assumption */
+
+       for (as = m->assumptions; as != NULL; as = as->next) {
+               if (as->context == caller)
+                       return;
+       }
+
+       /* register the assumption */
+
+       as = NEW(method_assumption);
+       as->next = m->assumptions;
+       as->context = caller;
+
+       m->assumptions = as;
+}
+
+/* method_break_assumption_monomorphic *****************************************
+
+   Break the assumption that this method is monomorphic. All callers that
+   have registered this assumption are added to the worklist.
+
+   IN:
+      m.................the method
+         wl................worklist where to add invalidated callers
+
+*******************************************************************************/
+
+void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
+{
+       method_assumption *as;
+
+       /* XXX LOCKING FOR THIS FUNCTION? */
+
+       for (as = m->assumptions; as != NULL; as = as->next) {
+               INLINELOG(
+                       printf("ASSUMPTION BROKEN (monomorphism): ");
+                       method_print(m);
+                       printf(" in ");
+                       method_println(as->context);
+               );
+
+               method_add_to_worklist(as->context, wl);
+
+#if defined(ENABLE_TLH) && 0
+               /* XXX hack */
+               method_assumption *as2;
+               as2 = m->assumptions;
+               m->assumptions = NULL;
+               method_break_assumption_monomorphic(as->context, wl);
+               /*
+               assert(m->assumptions == NULL);
+               m->assumptions = as2;*/
+#endif
+
+       }
+}
+
+/* method_printflags ***********************************************************
+
+   Prints the flags of a method to stdout like.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_printflags(methodinfo *m)
+{
+       if (m == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       if (m->flags & ACC_PUBLIC)             printf(" PUBLIC");
+       if (m->flags & ACC_PRIVATE)            printf(" PRIVATE");
+       if (m->flags & ACC_PROTECTED)          printf(" PROTECTED");
+       if (m->flags & ACC_STATIC)             printf(" STATIC");
+       if (m->flags & ACC_FINAL)              printf(" FINAL");
+       if (m->flags & ACC_SYNCHRONIZED)       printf(" SYNCHRONIZED");
+       if (m->flags & ACC_VOLATILE)           printf(" VOLATILE");
+       if (m->flags & ACC_TRANSIENT)          printf(" TRANSIENT");
+       if (m->flags & ACC_NATIVE)             printf(" NATIVE");
+       if (m->flags & ACC_INTERFACE)          printf(" INTERFACE");
+       if (m->flags & ACC_ABSTRACT)           printf(" ABSTRACT");
+       if (m->flags & ACC_METHOD_BUILTIN)     printf(" (builtin)");
+       if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
+       if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_print ****************************************************************
+
+   Prints a method to stdout like:
+
+   java.lang.Object.<init>()V
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_print(methodinfo *m)
+{
+       if (m == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       if (m->clazz != NULL)
+               utf_display_printable_ascii_classname(m->clazz->name);
+       else
+               printf("NULL");
+       printf(".");
+       utf_display_printable_ascii(m->name);
+       utf_display_printable_ascii(m->descriptor);
+
+       method_printflags(m);
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_println **************************************************************
+
+   Prints a method plus new line to stdout like:
+
+   java.lang.Object.<init>()V
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_println(methodinfo *m)
+{
+       if (opt_debugcolor) printf("\033[31m"); /* red */
+       method_print(m);
+       if (opt_debugcolor) printf("\033[m");   
+       printf("\n");
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_methodref_print ******************************************************
+
+   Prints a method reference to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_methodref_print(constant_FMIref *mr)
+{
+       if (!mr) {
+               printf("(constant_FMIref *)NULL");
+               return;
+       }
+
+       if (IS_FMIREF_RESOLVED(mr)) {
+               printf("<method> ");
+               method_print(mr->p.method);
+       }
+       else {
+               printf("<methodref> ");
+               utf_display_printable_ascii_classname(mr->p.classref->name);
+               printf(".");
+               utf_display_printable_ascii(mr->name);
+               utf_display_printable_ascii(mr->descriptor);
+       }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_methodref_println ****************************************************
+
+   Prints a method reference to stdout, followed by a newline.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_methodref_println(constant_FMIref *mr)
+{
+       method_methodref_print(mr);
+       printf("\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/method.h b/src/vm/method.h
new file mode 100644 (file)
index 0000000..076b25a
--- /dev/null
@@ -0,0 +1,229 @@
+/* src/vm/method.h - method functions header
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _METHOD_H
+#define _METHOD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* forward typedefs ***********************************************************/
+
+typedef struct methodinfo          methodinfo; 
+typedef struct raw_exception_entry raw_exception_entry;
+typedef struct lineinfo            lineinfo; 
+typedef struct method_assumption   method_assumption;
+typedef struct method_worklist     method_worklist;
+typedef struct codeinfo            codeinfo;
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/builtin.h"
+#include "vm/descriptor.h"
+#include "vm/global.h"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/references.h"
+
+#if defined(ENABLE_JAVASE)
+# include "vm/stackmap.h"
+#endif
+
+#include "vm/utf8.h"
+
+
+#if defined(ENABLE_REPLACEMENT)
+/* Initial value for the hit countdown field of each method. */
+#define METHOD_INITIAL_HIT_COUNTDOWN  1000
+#endif
+
+
+/* methodinfo *****************************************************************/
+
+struct methodinfo {                 /* method structure                       */
+       java_object_t header;           /* we need this in jit's monitorenter     */
+       s4            flags;            /* ACC flags                              */
+       utf          *name;             /* name of method                         */
+       utf          *descriptor;       /* JavaVM descriptor string of method     */
+#if defined(ENABLE_JAVASE)
+       utf          *signature;        /* Signature attribute                    */
+       stack_map_t  *stack_map;        /* StackMapTable attribute                */
+#endif
+
+       methoddesc   *parseddesc;       /* parsed descriptor                      */
+                            
+       classinfo    *clazz;            /* class, the method belongs to           */
+       s4            vftblindex;       /* index of method in virtual function    */
+                                       /* table (if it is a virtual method)      */
+       s4            maxstack;         /* maximum stack depth of method          */
+       s4            maxlocals;        /* maximum number of local variables      */
+       s4            jcodelength;      /* length of JavaVM code                  */
+       u1           *jcode;            /* pointer to JavaVM code                 */
+
+       s4            rawexceptiontablelength;  /* exceptiontable length          */
+       raw_exception_entry *rawexceptiontable; /* the exceptiontable             */
+
+       u2            thrownexceptionscount; /* number of exceptions attribute    */
+       classref_or_classinfo *thrownexceptions; /* except. a method may throw    */
+
+       u2            linenumbercount;  /* number of linenumber attributes        */
+       lineinfo     *linenumbers;      /* array of lineinfo items                */
+
+       u1           *stubroutine;      /* stub for compiling or calling natives  */
+       codeinfo     *code;             /* current code of this method            */
+
+#if defined(ENABLE_LSRA)
+       s4            maxlifetimes;     /* helper for lsra                        */
+#endif
+
+       methodinfo   *overwrites;       /* method that is directly overwritten    */
+       method_assumption *assumptions; /* list of assumptions about this method  */
+
+#if defined(ENABLE_REPLACEMENT)
+       s4            hitcountdown;     /* decreased for each hit                 */
+#endif
+
+#if defined(ENABLE_DEBUG_FILTER)
+       u1            filtermatches;    /* flags indicating which filters the method matches */
+#endif
+
+#if defined(ENABLE_ESCAPE)
+       u1           *paramescape;
+#endif
+};
+
+/* method_assumption ***********************************************************
+
+   This struct is used for registering assumptions about methods.
+
+*******************************************************************************/
+
+struct method_assumption {
+       method_assumption *next;
+       methodinfo        *context;
+};
+
+
+/* method_worklist *************************************************************
+
+   List node used for method worklists.
+
+*******************************************************************************/
+
+struct method_worklist {
+       method_worklist *next;
+       methodinfo      *m;
+};
+
+
+/* raw_exception_entry ********************************************************/
+
+/* exception table entry read by the loader */
+
+struct raw_exception_entry {    /* exceptiontable entry in a method           */
+       classref_or_classinfo catchtype; /* catchtype of exc. (0 == catchall)     */
+       u2              startpc;    /* start pc of guarded area (inclusive)       */
+       u2              endpc;      /* end pc of guarded area (exklusive)         */
+       u2              handlerpc;  /* pc of exception handler                    */
+};
+
+
+/* lineinfo *******************************************************************/
+
+struct lineinfo {
+       u2 start_pc;
+       u2 line_number;
+};
+
+
+/* global variables ***********************************************************/
+
+extern methodinfo *method_java_lang_reflect_Method_invoke;
+
+
+/* inline functions ***********************************************************/
+
+inline static bool method_is_builtin(methodinfo* m)
+{
+       return m->flags & ACC_METHOD_BUILTIN;
+}
+
+
+/* function prototypes ********************************************************/
+
+void method_init(void);
+
+bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool);
+void method_free(methodinfo *m);
+bool method_canoverwrite(methodinfo *m, methodinfo *old);
+
+methodinfo *method_new_builtin(builtintable_entry *bte);
+
+methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m);
+
+int32_t                    method_get_parametercount(methodinfo *m);
+java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m);
+java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m);
+classinfo                 *method_returntype_get(methodinfo *m);
+
+void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller);
+void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl);
+
+s4   method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found);
+
+java_handle_bytearray_t *method_get_annotations(methodinfo *m);
+java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m);
+java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m);
+
+#if !defined(NDEBUG)
+void method_printflags(methodinfo *m);
+void method_print(methodinfo *m);
+void method_println(methodinfo *m);
+void method_methodref_print(constant_FMIref *mr);
+void method_methodref_println(constant_FMIref *mr);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _METHOD_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/options.c b/src/vm/options.c
new file mode 100644 (file)
index 0000000..0366ebe
--- /dev/null
@@ -0,0 +1,866 @@
+/* src/vm/options.c - contains global options
+
+   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 <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+
+#include "vm/options.h"
+#include "vm/os.hpp"
+#include "vm/vm.hpp"
+
+
+/* command line option ********************************************************/
+
+s4    opt_index = 0;            /* index of processed arguments               */
+char *opt_arg;                  /* this one exports the option argument       */
+
+bool opt_foo = false;           /* option for development                     */
+
+bool opt_jar = false;
+
+#if defined(ENABLE_JIT)
+bool opt_jit = true;            /* JIT mode execution (default)               */
+bool opt_intrp = false;         /* interpreter mode execution                 */
+#else
+bool opt_jit = false;           /* JIT mode execution                         */
+bool opt_intrp = true;          /* interpreter mode execution (default)       */
+#endif
+
+bool opt_run = true;
+
+s4   opt_heapmaxsize   = 0;     /* maximum heap size                          */
+s4   opt_heapstartsize = 0;     /* initial heap size                          */
+s4   opt_stacksize     = 0;     /* thread stack size                          */
+
+bool opt_verbose = false;
+bool opt_debugcolor = false;   /* use ANSI terminal sequences                */
+bool compileall = false;
+
+bool loadverbose = false;
+bool initverbose = false;
+
+bool opt_verboseclass     = false;
+bool opt_verbosegc        = false;
+bool opt_verbosejni       = false;
+bool opt_verbosecall      = false;      /* trace all method invocation        */
+
+bool showmethods = false;
+bool showconstantpool = false;
+bool showutf = false;
+
+char *opt_method = NULL;
+char *opt_signature = NULL;
+
+bool compileverbose =  false;           /* trace compiler actions             */
+bool showstack = false;
+
+bool opt_showdisassemble    = false;    /* generate disassembler listing      */
+bool opt_shownops           = false;
+bool opt_showddatasegment   = false;    /* generate data segment listing      */
+bool opt_showintermediate   = false;    /* generate intermediate code listing */
+
+bool checkbounds = true;       /* check array bounds                         */
+bool opt_noieee = false;       /* don't implement ieee compliant floats      */
+bool checksync = true;         /* do synchronization                         */
+#if defined(ENABLE_LOOP)
+bool opt_loops = false;        /* optimize array accesses in loops           */
+#endif
+
+bool makeinitializations = true;
+
+#if defined(ENABLE_STATISTICS)
+bool opt_stat    = false;
+bool opt_getloadingtime = false;   /* to measure the runtime                 */
+bool opt_getcompilingtime = false; /* compute compile time                   */
+#endif
+#if defined(ENABLE_VERIFIER)
+bool opt_verify  = true;       /* true if classfiles should be verified      */
+#endif
+
+#if defined(ENABLE_PROFILING)
+bool opt_prof    = false;
+bool opt_prof_bb = false;
+#endif
+
+#if defined(ENABLE_OPAGENT)
+bool opt_opagent = false;
+#endif
+
+/* optimization options *******************************************************/
+
+#if defined(ENABLE_IFCONV)
+bool opt_ifconv = false;
+#endif
+
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+bool opt_lsra = false;
+#endif
+#if defined(ENABLE_SSA)
+bool opt_ssa_dce = false;          /* enable dead code elemination */
+bool opt_ssa_cp = false;           /* enable copy propagation      */
+#endif
+
+
+/* interpreter options ********************************************************/
+
+#if defined(ENABLE_INTRP)
+bool opt_no_dynamic = false;            /* suppress dynamic superinstructions */
+bool opt_no_replication = false;        /* don't use replication in intrp     */
+bool opt_no_quicksuper = false;         /* instructions for quickening cannot be
+                                                                                  part of dynamic superinstructions */
+
+s4   opt_static_supers = 0x7fffffff;
+bool vm_debug = false;          /* XXX this should be called `opt_trace'      */
+#endif
+
+#if defined(ENABLE_DEBUG_FILTER)
+const char *opt_filter_verbosecall_include = 0;
+const char *opt_filter_verbosecall_exclude = 0;
+const char *opt_filter_show_method = 0;
+#endif
+
+
+/* -XX options ****************************************************************/
+
+/* NOTE: For better readability keep these alpha-sorted. */
+
+/* Options which must always be available (production options in
+   HotSpot). */
+
+int64_t  opt_MaxDirectMemorySize          = -1;
+int      opt_MaxPermSize                  = 0;
+int      opt_PermSize                     = 0;
+int      opt_ThreadStackSize              = 0;
+
+/* Debugging options which can be turned off. */
+
+int      opt_DebugExceptions              = 0;
+int      opt_DebugFinalizer               = 0;
+#if defined(ENABLE_JITCACHE)
+int      opt_DebugJitCache                = 0;
+#endif
+int      opt_DebugLocalReferences         = 0;
+int      opt_DebugLocks                   = 0;
+int      opt_DebugPackage                 = 0;
+int      opt_DebugPatcher                 = 0;
+int      opt_DebugProperties              = 0;
+int      opt_DebugStackFrameInfo          = 0;
+int      opt_DebugStackTrace              = 0;
+int      opt_DebugThreads                 = 0;
+#if defined(ENABLE_DISASSEMBLER)
+int      opt_DisassembleStubs             = 0;
+#endif
+#if defined(ENABLE_OPAGENT)
+int      opt_EnableOpagent                = 0;
+#endif
+#if defined(ENABLE_GC_CACAO)
+int      opt_GCDebugRootSet               = 0;
+int      opt_GCStress                     = 0;
+#endif
+#if defined(ENABLE_INLINING)
+int      opt_Inline                       = 0;
+#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
+int      opt_InlineAll                    = 0;
+int      opt_InlineCount                  = INT_MAX;
+int      opt_InlineMaxSize                = INT_MAX;
+int      opt_InlineMinSize                = 0;
+#endif
+#endif
+int      opt_PrintConfig                  = 0;
+int      opt_ProfileGCMemoryUsage         = 0;
+int      opt_ProfileMemoryUsage           = 0;
+FILE    *opt_ProfileMemoryUsageGNUPlot    = NULL;
+#if defined(ENABLE_REPLACEMENT)
+int      opt_TestReplacement              = 0;
+#endif
+int      opt_TraceCompilerCalls           = 0;
+int      opt_TraceExceptions              = 0;
+int      opt_TraceHPI                     = 0;
+#if defined(ENABLE_INLINING) && !defined(NDEBUG)
+int      opt_TraceInlining                = 0;
+#endif
+int      opt_TraceJavaCalls               = 0;
+int      opt_TraceJNICalls                = 0;
+int      opt_TraceJVMCalls                = 0;
+int      opt_TraceJVMCallsVerbose         = 0;
+int      opt_TraceLinkClass               = 0;
+#if defined(ENABLE_REPLACEMENT)
+int      opt_TraceReplacement             = 0;
+#endif
+int      opt_TraceSubsystemInitialization = 0;
+int      opt_TraceTraps                   = 0;
+
+
+enum {
+       OPT_TYPE_BOOLEAN,
+       OPT_TYPE_VALUE
+};
+
+enum {
+       /* Options which must always be available (production options in
+          HotSpot). */
+
+       OPT_MaxDirectMemorySize,
+       OPT_MaxPermSize,
+       OPT_PermSize,
+       OPT_ThreadStackSize,
+
+       /* Debugging options which can be turned off. */
+
+       OPT_DebugExceptions,
+       OPT_DebugFinalizer,
+  OPT_DebugJitCache,
+       OPT_DebugLocalReferences,
+       OPT_DebugLocks,
+       OPT_DebugPackage,
+       OPT_DebugPatcher,
+       OPT_DebugProperties,
+       OPT_DebugStackFrameInfo,
+       OPT_DebugStackTrace,
+       OPT_DebugThreads,
+       OPT_DisassembleStubs,
+       OPT_EnableOpagent,
+       OPT_GCDebugRootSet,
+       OPT_GCStress,
+       OPT_Inline,
+       OPT_InlineAll,
+       OPT_InlineCount,
+       OPT_InlineMaxSize,
+       OPT_InlineMinSize,
+       OPT_PrintConfig,
+       OPT_ProfileGCMemoryUsage,
+       OPT_ProfileMemoryUsage,
+       OPT_ProfileMemoryUsageGNUPlot,
+       OPT_TestReplacement,
+       OPT_TraceCompilerCalls,
+       OPT_TraceExceptions,
+       OPT_TraceHPI,
+       OPT_TraceInlining,
+       OPT_TraceJavaCalls,
+       OPT_TraceJNICalls,
+       OPT_TraceJVMCalls,
+       OPT_TraceJVMCallsVerbose,
+       OPT_TraceLinkClass,
+       OPT_TraceReplacement,
+       OPT_TraceSubsystemInitialization,
+       OPT_TraceTraps,
+       OPT_Vmlog,
+       OPT_VmlogStrings,
+       OPT_VmlogIgnore
+};
+
+
+option_t options_XX[] = {
+       /* Options which must always be available (production options in
+          HotSpot). */
+
+       { "MaxDirectMemorySize",          OPT_MaxDirectMemorySize,          OPT_TYPE_VALUE,   "Maximum total size of NIO direct-buffer allocations" },
+       { "MaxPermSize",                  OPT_MaxPermSize,                  OPT_TYPE_VALUE,   "not implemented" },
+       { "PermSize",                     OPT_PermSize,                     OPT_TYPE_VALUE,   "not implemented" },
+       { "ThreadStackSize",              OPT_ThreadStackSize,              OPT_TYPE_VALUE,   "TODO" },
+
+       /* Debugging options which can be turned off. */
+
+       { "DebugExceptions",              OPT_DebugExceptions,              OPT_TYPE_BOOLEAN, "debug exceptions" },
+       { "DebugFinalizer",               OPT_DebugFinalizer,               OPT_TYPE_BOOLEAN, "debug finalizer thread" },
+#if defined (ENABLE_JITCACHE)
+  { "DebugJitCache",                OPT_DebugJitCache,                OPT_TYPE_BOOLEAN, "debug JIT cache actions" },
+#endif
+       { "DebugLocalReferences",         OPT_DebugLocalReferences,         OPT_TYPE_BOOLEAN, "print debug information for local reference tables" },
+       { "DebugLocks",                   OPT_DebugLocks,                   OPT_TYPE_BOOLEAN, "print debug information for locks" },
+       { "DebugPackage",                 OPT_DebugPackage,                 OPT_TYPE_BOOLEAN, "debug Java boot-packages" },
+       { "DebugPatcher",                 OPT_DebugPatcher,                 OPT_TYPE_BOOLEAN, "debug JIT code patching" },
+       { "DebugProperties",              OPT_DebugProperties,              OPT_TYPE_BOOLEAN, "print debug information for properties" },
+       { "DebugStackFrameInfo",          OPT_DebugStackFrameInfo,          OPT_TYPE_BOOLEAN, "TODO" },
+       { "DebugStackTrace",              OPT_DebugStackTrace,              OPT_TYPE_BOOLEAN, "debug stacktrace creation" },
+       { "DebugThreads",                 OPT_DebugThreads,                 OPT_TYPE_BOOLEAN, "print debug information for threads" },
+#if defined(ENABLE_DISASSEMBLER)
+       { "DisassembleStubs",             OPT_DisassembleStubs,             OPT_TYPE_BOOLEAN, "disassemble builtin and native stubs when generated" },
+#endif
+#if defined(ENABLE_OPAGENT)
+       { "EnableOpagent",                OPT_EnableOpagent,                OPT_TYPE_BOOLEAN, "enable providing JIT output to Oprofile" },
+#endif
+#if defined(ENABLE_GC_CACAO)
+       { "GCDebugRootSet",               OPT_GCDebugRootSet,               OPT_TYPE_BOOLEAN, "GC: print root-set at collection" },
+       { "GCStress",                     OPT_GCStress,                     OPT_TYPE_BOOLEAN, "GC: forced collection at every allocation" },
+#endif
+#if defined(ENABLE_INLINING)
+       { "Inline",                       OPT_Inline,                       OPT_TYPE_BOOLEAN, "enable method inlining" },
+#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
+       { "InlineAll",                    OPT_InlineAll,                    OPT_TYPE_BOOLEAN, "use inlining in all compilations" },
+       { "InlineCount",                  OPT_InlineCount,                  OPT_TYPE_VALUE,   "stop inlining after the given number of roots" },
+       { "InlineMaxSize",                OPT_InlineMaxSize,                OPT_TYPE_VALUE,   "maximum size for inlined result" },
+       { "InlineMinSize",                OPT_InlineMinSize,                OPT_TYPE_VALUE,   "minimum size for inlined result" },
+#endif
+#endif
+       { "PrintConfig",                  OPT_PrintConfig,                  OPT_TYPE_BOOLEAN, "print VM configuration" },
+       { "ProfileGCMemoryUsage",         OPT_ProfileGCMemoryUsage,         OPT_TYPE_VALUE,   "profiles GC memory usage in the given interval, <value> is in seconds (default: 5)" },
+       { "ProfileMemoryUsage",           OPT_ProfileMemoryUsage,           OPT_TYPE_VALUE,   "TODO" },
+       { "ProfileMemoryUsageGNUPlot",    OPT_ProfileMemoryUsageGNUPlot,    OPT_TYPE_VALUE,   "TODO" },
+#if defined(ENABLE_REPLACEMENT)
+       { "TestReplacement",              OPT_TestReplacement,              OPT_TYPE_BOOLEAN, "activate all replacement points during code generation" },
+#endif
+       { "TraceCompilerCalls",           OPT_TraceCompilerCalls,           OPT_TYPE_BOOLEAN, "trace JIT compiler calls" },
+       { "TraceExceptions",              OPT_TraceExceptions,              OPT_TYPE_BOOLEAN, "trace Exception throwing" },
+       { "TraceHPI",                     OPT_TraceHPI,                     OPT_TYPE_BOOLEAN, "Trace Host Porting Interface (HPI)" },
+#if defined(ENABLE_INLINING) && !defined(NDEBUG)
+       { "TraceInlining",                OPT_TraceInlining,                OPT_TYPE_VALUE,   "trace method inlining with the given verbosity level (default: 1)" },
+#endif
+#if !defined(ENABLE_VMLOG)
+       { "TraceJavaCalls",               OPT_TraceJavaCalls,               OPT_TYPE_BOOLEAN, "trace Java method calls" },
+#endif
+       { "TraceJNICalls",                OPT_TraceJNICalls,                OPT_TYPE_BOOLEAN, "trace JNI method calls" },
+       { "TraceJVMCalls",                OPT_TraceJVMCalls,                OPT_TYPE_BOOLEAN, "trace JVM method calls but omit very frequent ones" },
+       { "TraceJVMCallsVerbose",         OPT_TraceJVMCallsVerbose,         OPT_TYPE_BOOLEAN, "trace all JVM method calls" },
+       { "TraceLinkClass",               OPT_TraceLinkClass,               OPT_TYPE_BOOLEAN, "trace class linking" },
+#if defined(ENABLE_REPLACEMENT)
+       { "TraceReplacement",             OPT_TraceReplacement,             OPT_TYPE_VALUE,   "trace on-stack replacement with the given verbosity level (default: 1)" },
+#endif
+       { "TraceSubsystemInitialization", OPT_TraceSubsystemInitialization, OPT_TYPE_BOOLEAN, "trace initialization of subsystems" },
+       { "TraceTraps",                   OPT_TraceTraps,                   OPT_TYPE_BOOLEAN, "trace traps generated by JIT code" },
+#if defined(ENABLE_VMLOG)
+       { "Vmlog",                        OPT_Vmlog,                        OPT_TYPE_VALUE,   "prefix for vmlog trace files (enables vmlog)" },
+       { "VmlogStrings",                 OPT_VmlogStrings,                 OPT_TYPE_VALUE,   "prefix of vmlog string file to load" },
+       { "VmlogIgnore",                  OPT_VmlogIgnore,                  OPT_TYPE_VALUE,   "prefix of vmlog ignore file to load" },
+#endif
+
+       /* end marker */
+
+       { NULL,                           -1,                               -1,               NULL }
+};
+
+
+/* options_get *****************************************************************
+
+   DOCUMENT ME!!!
+
+*******************************************************************************/
+
+int options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
+{
+       char *option;
+       int   i;
+
+       if (opt_index >= vm_args->nOptions)
+               return OPT_DONE;
+
+       /* get the current option */
+
+       option = vm_args->options[opt_index].optionString;
+
+       if ((option == NULL) || (option[0] != '-'))
+               return OPT_DONE;
+
+       for (i = 0; opts[i].name; i++) {
+               if (!opts[i].arg) {
+                       /* boolean option found */
+
+                       if (strcmp(option + 1, opts[i].name) == 0) {
+                               opt_index++;
+                               return opts[i].value;
+                       }
+
+               } else {
+                       /* parameter option found */
+
+                       /* with a space between */
+
+                       if (strcmp(option + 1, opts[i].name) == 0) {
+                               opt_index++;
+
+                               if (opt_index < vm_args->nOptions) {
+                                       opt_arg = os_strdup(vm_args->options[opt_index].optionString);
+                                       opt_index++;
+                                       return opts[i].value;
+                               }
+
+                               return OPT_ERROR;
+
+                       } else {
+                               /* parameter and option have no space between */
+
+                               /* FIXME: this assumption is plain wrong, hits you if there is a
+                                * parameter with no argument starting with same letter as param with argument
+                                * but named after that one, ouch! */
+
+                               size_t l = os_strlen(opts[i].name);
+
+                               if (os_strlen(option + 1) > l) {
+                                       if (memcmp(option + 1, opts[i].name, l) == 0) {
+                                               opt_index++;
+                                               opt_arg = os_strdup(option + 1 + l);
+                                               return opts[i].value;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return OPT_ERROR;
+}
+
+
+/* options_xxusage *************************************************************
+
+   Print usage message for debugging options.
+
+*******************************************************************************/
+
+static void options_xxusage(void)
+{
+       option_t   *opt;
+       int         length;
+       int         i;
+       const char *c;
+
+       /* Prevent compiler warning. */
+
+       length = 0;
+
+       for (opt = options_XX; opt->name != NULL; opt++) {
+               printf("    -XX:");
+
+               switch (opt->type) {
+               case OPT_TYPE_BOOLEAN:
+                       printf("+%s", opt->name);
+                       length = os_strlen("    -XX:+") + os_strlen(opt->name);
+                       break;
+
+               case OPT_TYPE_VALUE:
+                       printf("%s=<value>", opt->name);
+                       length = os_strlen("    -XX:") + os_strlen(opt->name) +
+                               os_strlen("=<value>");
+                       break;
+
+               default:
+                       vm_abort("options_xxusage: unkown option type %d", opt->type);
+               }
+
+               /* Check if the help fits into one 80-column line.
+                  Documentation starts at column 29. */
+
+               if (length < (29 - 1)) {
+                       /* Print missing spaces up to column 29. */
+
+                       for (i = length; i < 29; i++)
+                               printf(" ");
+               }
+               else {
+                       printf("\n");
+                       printf("                             "); /* 29 spaces */
+               }
+
+               /* Check documentation length. */
+
+               length = os_strlen(opt->doc);
+
+               if (length < (80 - 29)) {
+                       printf("%s", opt->doc);
+               }
+               else {
+                       for (c = opt->doc, i = 29; *c != 0; c++, i++) {
+                               /* If we are at the end of the line, break it. */
+
+                               if (i == 80) {
+                                       printf("\n");
+                                       printf("                             "); /* 29 spaces */
+                                       i = 29;
+                               }
+
+                               printf("%c", *c);
+                       }
+               }
+
+               printf("\n");
+       }
+
+       /* exit with error code */
+
+       exit(1);
+}
+
+
+/* options_xx ******************************************************************
+
+   Handle -XX: options.
+
+*******************************************************************************/
+
+void options_xx(JavaVMInitArgs *vm_args)
+{
+       const char *name;
+       const char *start;
+       char       *end;
+       int         length;
+       int         enable;
+       char       *value;
+       option_t   *opt;
+       char       *filename;
+       FILE       *file;
+       int         i;
+
+       /* Iterate over all passed options. */
+
+       for (i = 0; i < vm_args->nOptions; i++) {
+               /* Get the current option. */
+
+               name = vm_args->options[i].optionString;
+
+               /* Check for help (-XX). */
+
+               if (strcmp(name, "-XX") == 0)
+                       options_xxusage();
+
+               /* Check if the option start with -XX. */
+
+               start = strstr(name, "-XX:");
+
+               if ((start == NULL) || (start != name))
+                       continue;
+
+               /* Check if the option is a boolean option. */
+
+               if (name[4] == '+') {
+                       start  = name + 4 + 1;
+                       enable = 1;
+               }
+               else if (name[4] == '-') {
+                       start  = name + 4 + 1;
+                       enable = 0;
+               }
+               else {
+                       start  = name + 4;
+                       enable = -1;
+               }
+
+               /* Search for a '=' in the option name and get the option name
+                  length and the value of the option. */
+
+               end = strchr(start, '=');
+
+               if (end == NULL) {
+                       length = os_strlen(start);
+                       value  = NULL;
+               }
+               else {
+                       length = end - start;
+                       value  = end + 1;
+               }
+
+               /* Search the option in the option array. */
+
+               for (opt = options_XX; opt->name != NULL; opt++) {
+                       if (strncmp(opt->name, start, length) == 0) {
+                               /* Check if the options passed fits to the type. */
+
+                               switch (opt->type) {
+                               case OPT_TYPE_BOOLEAN:
+                                       if ((enable == -1) || (value != NULL))
+                                               options_xxusage();
+                                       break;
+                               case OPT_TYPE_VALUE:
+                                       if ((enable != -1) || (value == NULL))
+                                               options_xxusage();
+                                       break;
+                               default:
+                                       vm_abort("options_xx: unknown option type %d for option %s",
+                                                        opt->type, opt->name);
+                               }
+
+                               break;
+                       }
+               }
+
+               /* Process the option. */
+
+               switch (opt->value) {
+
+               /* Options which must always be available (production options
+                  in HotSpot). */
+
+               case OPT_MaxDirectMemorySize:
+                       opt_MaxDirectMemorySize = os_atoi(value);
+                       break;
+
+               case OPT_MaxPermSize:
+                       /* Currently ignored. */
+                       break;
+
+               case OPT_PermSize:
+                       /* Currently ignored. */
+                       break;
+
+               case OPT_ThreadStackSize:
+                       /* currently ignored */
+                       break;
+
+               /* Debugging options which can be turned off. */
+
+               case OPT_DebugExceptions:
+                       opt_DebugExceptions = enable;
+                       break;
+
+               case OPT_DebugFinalizer:
+                       opt_DebugFinalizer = enable;
+                       break;
+
+#if defined(ENABLE_JITCACHE)
+    case OPT_DebugJitCache:
+      opt_DebugJitCache = enable;
+      break;
+#endif
+
+               case OPT_DebugLocalReferences:
+                       opt_DebugLocalReferences = enable;
+                       break;
+
+               case OPT_DebugLocks:
+                       opt_DebugLocks = enable;
+                       break;
+
+               case OPT_DebugPackage:
+                       opt_DebugPackage = enable;
+                       break;
+
+               case OPT_DebugPatcher:
+                       opt_DebugPatcher = enable;
+                       break;
+
+               case OPT_DebugProperties:
+                       opt_DebugProperties = enable;
+                       break;
+
+               case OPT_DebugStackFrameInfo:
+                       opt_DebugStackFrameInfo = enable;
+                       break;
+
+               case OPT_DebugStackTrace:
+                       opt_DebugStackTrace = enable;
+                       break;
+
+               case OPT_DebugThreads:
+                       opt_DebugThreads = enable;
+                       break;
+
+#if defined(ENABLE_DISASSEMBLER)
+               case OPT_DisassembleStubs:
+                       opt_DisassembleStubs = enable;
+                       break;
+#endif
+
+#if defined(ENABLE_OPAGENT)
+               case OPT_EnableOpagent:
+                       opt_EnableOpagent = enable;
+                       break;
+#endif
+
+#if defined(ENABLE_GC_CACAO)
+               case OPT_GCDebugRootSet:
+                       opt_GCDebugRootSet = enable;
+                       break;
+
+               case OPT_GCStress:
+                       opt_GCStress = enable;
+                       break;
+#endif
+
+#if defined(ENABLE_INLINING)
+               case OPT_Inline:
+                       opt_Inline = enable;
+                       break;
+#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
+               case OPT_InlineAll:
+                       opt_InlineAll = enable;
+                       break;
+
+               case OPT_InlineCount:
+                       if (value != NULL)
+                               opt_InlineCount = os_atoi(value);
+                       break;
+
+               case OPT_InlineMaxSize:
+                       if (value != NULL)
+                               opt_InlineMaxSize = os_atoi(value);
+                       break;
+
+               case OPT_InlineMinSize:
+                       if (value != NULL)
+                               opt_InlineMinSize = os_atoi(value);
+                       break;
+#endif
+#endif
+
+               case OPT_PrintConfig:
+                       opt_PrintConfig = enable;
+                       break;
+
+               case OPT_ProfileGCMemoryUsage:
+                       if (value == NULL)
+                               opt_ProfileGCMemoryUsage = 5;
+                       else
+                               opt_ProfileGCMemoryUsage = os_atoi(value);
+                       break;
+
+               case OPT_ProfileMemoryUsage:
+                       if (value == NULL)
+                               opt_ProfileMemoryUsage = 5;
+                       else
+                               opt_ProfileMemoryUsage = os_atoi(value);
+
+# if defined(ENABLE_STATISTICS)
+                       /* we also need statistics */
+
+                       opt_stat = true;
+# endif
+                       break;
+
+               case OPT_ProfileMemoryUsageGNUPlot:
+                       if (value == NULL)
+                               filename = "profile.dat";
+                       else
+                               filename = value;
+
+                       file = fopen(filename, "w");
+
+                       if (file == NULL)
+                               vm_abort_errno("options_xx: fopen failed");
+
+                       opt_ProfileMemoryUsageGNUPlot = file;
+                       break;
+
+#if defined(ENABLE_REPLACEMENT)
+               case OPT_TestReplacement:
+                       opt_TestReplacement = enable;
+                       break;
+#endif
+
+               case OPT_TraceCompilerCalls:
+                       opt_TraceCompilerCalls = enable;
+                       break;
+
+               case OPT_TraceExceptions:
+                       opt_TraceExceptions = enable;
+                       break;
+
+               case OPT_TraceHPI:
+                       opt_TraceHPI = enable;
+                       break;
+
+#if defined(ENABLE_INLINING) && !defined(NDEBUG)
+               case OPT_TraceInlining:
+                       if (value == NULL)
+                               opt_TraceInlining = 1;
+                       else
+                               opt_TraceInlining = os_atoi(value);
+                       break;
+#endif
+
+               case OPT_TraceJavaCalls:
+                       opt_verbosecall = enable;
+                       opt_TraceJavaCalls = enable;
+                       break;
+
+               case OPT_TraceJNICalls:
+                       opt_TraceJNICalls = enable;
+                       break;
+
+               case OPT_TraceJVMCalls:
+                       opt_TraceJVMCalls = enable;
+                       break;
+
+               case OPT_TraceJVMCallsVerbose:
+                       opt_TraceJVMCallsVerbose = enable;
+                       break;
+
+               case OPT_TraceLinkClass:
+                       opt_TraceLinkClass = enable;
+                       break;
+
+#if defined(ENABLE_REPLACEMENT)
+               case OPT_TraceReplacement:
+                       if (value == NULL)
+                               opt_TraceReplacement = 1;
+                       else
+                               opt_TraceReplacement = os_atoi(value);
+                       break;
+#endif
+
+               case OPT_TraceSubsystemInitialization:
+                       opt_TraceSubsystemInitialization = enable;
+                       break;
+
+               case OPT_TraceTraps:
+                       opt_TraceTraps = enable;
+                       break;
+
+#if defined(ENABLE_VMLOG)
+               case OPT_Vmlog:
+                       if (value == NULL)
+                               vmlog_cacao_set_prefix("vmlog");
+                       else
+                               vmlog_cacao_set_prefix(value);
+                       opt_verbosecall = 1;
+                       opt_TraceJavaCalls = 1;
+                       break;
+
+               case OPT_VmlogStrings:
+                       if (value != NULL)
+                               vmlog_cacao_set_stringprefix(value);
+                       break;
+
+               case OPT_VmlogIgnore:
+                       if (value != NULL)
+                               vmlog_cacao_set_ignoreprefix(value);
+                       break;
+#endif
+
+               default:
+                       printf("Unknown -XX option: %s\n", name);
+                       break;
+               }
+       }
+}
+
+
+/*
+ * 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/options.h b/src/vm/options.h
new file mode 100644 (file)
index 0000000..28fdf1d
--- /dev/null
@@ -0,0 +1,281 @@
+/* src/vm/options.h - define global options extern
+
+   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 _OPTIONS_H
+#define _OPTIONS_H
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "native/jni.h"
+
+#include "vm/global.h"
+
+
+/* reserved option numbers ****************************************************/
+
+/* define these negative since the other options are an enum */
+
+#define OPT_DONE       -1
+#define OPT_ERROR      -2
+#define OPT_IGNORE     -3
+
+
+typedef struct opt_struct opt_struct;
+
+struct opt_struct {
+       const char *name;
+       bool        arg;
+       int         value;
+};
+
+
+typedef struct option_t option_t;
+
+struct option_t {
+       const char *name;
+       int         value;
+       int         type;
+       const char *doc;
+};
+
+
+/* global variables ***********************************************************/
+
+extern s4    opt_index;
+extern char *opt_arg;
+
+extern bool opt_foo;
+
+extern bool opt_jit;
+extern bool opt_intrp;
+
+extern bool opt_jar;
+extern bool opt_run;
+
+extern s4   opt_heapmaxsize;
+extern s4   opt_heapstartsize;
+extern s4   opt_stacksize;
+
+extern bool opt_verbose;
+extern bool opt_debugcolor;
+extern bool compileall;
+
+extern bool loadverbose;         /* Print debug messages during loading */
+extern bool initverbose;         /* Log class initialization */ 
+
+extern bool opt_verboseclass;
+extern bool opt_verbosegc;
+extern bool opt_verbosejni;
+extern bool opt_verbosecall;
+
+extern bool showmethods;
+extern bool showconstantpool;
+extern bool showutf;
+
+extern char *opt_method;
+extern char *opt_signature;
+
+extern bool compileverbose;
+extern bool showstack;
+
+extern bool opt_showdisassemble;
+extern bool opt_shownops;
+extern bool opt_showddatasegment;
+extern bool opt_showintermediate;
+
+extern bool checkbounds;
+extern bool opt_noieee;
+extern bool checksync;
+#if defined(ENABLE_LOOP)
+extern bool opt_loops;
+#endif
+
+extern bool makeinitializations;
+
+#if defined(ENABLE_STATISTICS)
+extern bool opt_stat;
+extern bool opt_getloadingtime;
+extern bool opt_getcompilingtime;
+#endif
+#if defined(ENABLE_VERIFIER)
+extern bool opt_verify;
+#endif
+
+#if defined(ENABLE_PROFILING)
+extern bool opt_prof;
+extern bool opt_prof_bb;
+#endif
+
+/* optimization options *******************************************************/
+
+#if defined(ENABLE_IFCONV)
+extern bool opt_ifconv;
+#endif
+
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+extern bool opt_lsra;
+#endif
+#if defined(ENABLE_SSA)
+extern bool opt_ssa_dce;          /* enable dead code elemination */
+extern bool opt_ssa_cp;           /* enable copy propagation      */
+#endif
+
+/* interpreter options ********************************************************/
+
+#if defined(ENABLE_INTRP)
+extern bool opt_no_dynamic;
+extern bool opt_no_replication;
+extern bool opt_no_quicksuper;
+
+extern s4   opt_static_supers;
+extern bool vm_debug;
+#endif
+
+/* debug output filtering options *********************************************/
+
+#if defined(ENABLE_DEBUG_FILTER)
+extern const char *opt_filter_verbosecall_include;
+extern const char *opt_filter_verbosecall_exclude;
+extern const char *opt_filter_show_method;
+#endif
+
+
+/* -XX options ****************************************************************/
+
+/* NOTE: For better readability keep these alpha-sorted. */
+
+/* Options which must always be available (production options in
+   HotSpot). */
+
+extern int64_t  opt_MaxDirectMemorySize;
+extern int      opt_MaxPermSize;
+extern int      opt_PermSize;
+extern int      opt_ThreadStackSize;
+
+/* Debugging options which can be turned off. */
+
+extern int      opt_DebugExceptions;
+extern int      opt_DebugFinalizer;
+#if defined(ENABLE_JITCACHE)
+extern int      opt_DebugJitCache;
+#endif
+extern int      opt_DebugLocalReferences;
+extern int      opt_DebugLocks;
+extern int      opt_DebugPatcher;
+extern int      opt_DebugPackage;
+extern int      opt_DebugProperties;
+extern int      opt_DebugStackFrameInfo;
+extern int      opt_DebugStackTrace;
+extern int      opt_DebugThreads;
+#if defined(ENABLE_DISASSEMBLER)
+extern int      opt_DisassembleStubs;
+#endif
+#if defined(ENABLE_OPAGENT)
+extern int      opt_EnableOpagent;
+#endif
+#if defined(ENABLE_GC_CACAO)
+extern int      opt_GCDebugRootSet;
+extern int      opt_GCStress;
+#endif
+#if defined(ENABLE_INLINING)
+extern int      opt_Inline;
+#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
+extern int      opt_InlineAll;
+extern int      opt_InlineCount;
+extern int      opt_InlineMaxSize;
+extern int      opt_InlineMinSize;
+#endif
+#endif
+extern int      opt_PrintConfig;
+extern int      opt_ProfileGCMemoryUsage;
+extern int      opt_ProfileMemoryUsage;
+extern FILE    *opt_ProfileMemoryUsageGNUPlot;
+#if defined(ENABLE_REPLACEMENT)
+extern int      opt_TestReplacement;
+#endif
+extern int      opt_TraceCompilerCalls;
+extern int      opt_TraceExceptions;
+extern int      opt_TraceHPI;
+#if defined(ENABLE_INLINING) && !defined(NDEBUG)
+extern int      opt_TraceInlining;
+#endif
+extern int      opt_TraceJavaCalls;
+extern int      opt_TraceJNICalls;
+extern int      opt_TraceJVMCalls;
+extern int      opt_TraceJVMCallsVerbose;
+extern int      opt_TraceLinkClass;
+#if defined(ENABLE_REPLACEMENT)
+extern int      opt_TraceReplacement;
+#endif
+extern int      opt_TraceSubsystemInitialization;
+extern int      opt_TraceTraps;
+
+
+/* function prototypes ********************************************************/
+
+int  options_get(opt_struct *opts, JavaVMInitArgs *vm_args);
+void options_xx(JavaVMInitArgs *vm_args);
+
+
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+# define TRACESUBSYSTEMINITIALIZATION(text)                                            \
+    do {                                                                                                               \
+        if (opt_TraceSubsystemInitialization) {                                        \
+            log_println("[Initializing subsystem: %s]", text); \
+        }                                                                                                              \
+    } while (0)
+#else
+# define TRACESUBSYSTEMINITIALIZATION(text)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OPTIONS_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/os.cpp b/src/vm/os.cpp
new file mode 100644 (file)
index 0000000..0c920a8
--- /dev/null
@@ -0,0 +1,205 @@
+/* src/vm/os.cpp - system (OS) functions
+
+   Copyright (C) 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"
+
+/* NOTE: In this file we check for all system headers, because we wrap
+   all system calls into functions for better portability. */
+
+#if defined(HAVE_ERRNO_H)
+# include <errno.h>
+#endif
+
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#endif
+
+#if defined(HAVE_STRING_H)
+# include <string.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined(HAVE_SYS_MMAN_H)
+# include <sys/mman.h>
+#endif
+
+#if defined(__DARWIN__)
+# include <mach/mach.h>
+# include <mach/mach_host.h>
+# include <mach/host_info.h>
+#endif
+
+/* this should work on BSD */
+/* #include <sys/sysctl.h> */
+
+#include "vm/vm.hpp"
+
+
+/**
+ * Maps anonymous memory, even on systems not defining
+ * MAP_ANON(YMOUS).
+ *
+ * @param ...
+ */
+void* os::mmap_anonymous(void *addr, size_t len, int prot, int flags)
+{
+       void* p;
+
+#if defined(MAP_ANON) || defined(MAP_ANONYMOUS)
+       p = mmap(addr, len, prot,
+# if defined(MAP_ANON)
+                        MAP_ANON | flags,
+# else
+                        MAP_ANONYMOUS | flags,
+# endif
+                        -1, 0);
+#else
+       int fd;
+
+       fd = open("/dev/zero", O_RDONLY, 0);
+
+       if (fd == -1)
+               vm_abort("os::mmap_anonymous: open failed: %s", os::strerror(errno));
+
+       p = mmap(addr, len, prot, flags, fd, 0);
+#endif
+
+#if defined(MAP_FAILED)
+       if (p == MAP_FAILED)
+#else
+       if (p == (void *) -1)
+#endif
+               vm_abort("os::mmap_anonymous: mmap failed: %s", os::strerror(errno));
+
+       return p;
+}
+
+
+/**
+ * Returns the number of online processors in the system.
+ *
+ * @return Number of online processors.
+ */
+int os::processors_online(void)
+{
+#if defined(_SC_NPROC_ONLN)
+
+       return (int) sysconf(_SC_NPROC_ONLN);
+
+#elif defined(_SC_NPROCESSORS_ONLN)
+
+       return (int) sysconf(_SC_NPROCESSORS_ONLN);
+
+#elif defined(__DARWIN__)
+
+       host_basic_info_data_t hinfo;
+       mach_msg_type_number_t hinfo_count = HOST_BASIC_INFO_COUNT;
+       kern_return_t rc;
+
+       rc = host_info(mach_host_self(), HOST_BASIC_INFO,
+                                  (host_info_t) &hinfo, &hinfo_count);
+       if (rc != KERN_SUCCESS) {
+               return -1;
+       }
+
+       /* XXX michi: according to my infos this should be
+          hinfo.max_cpus, can someone please confirm or deny that? */
+       return (int) hinfo.avail_cpus;
+
+#elif defined(__FREEBSD__)
+# error IMPLEMENT ME!
+
+       /* this should work in BSD */
+       /*
+       int ncpu, mib[2], rc;
+       size_t len;
+
+       mib[0] = CTL_HW;
+       mib[1] = HW_NCPU;
+       len = sizeof(ncpu);
+       rc = sysctl(mib, 2, &ncpu, &len, NULL, 0);
+
+       return (int32_t) ncpu;
+       */
+
+#else
+
+       return 1;
+
+#endif
+}
+
+
+// Legacy C interface.
+
+extern "C" {
+       void*  os_mmap_anonymous(void *addr, size_t len, int prot, int flags) { return os::mmap_anonymous(addr, len, prot, flags); }
+
+       void   os_abort(void) { os::abort(); }
+       int    os_access(const char* pathname, int mode) { return os::access(pathname, mode); }
+       int    os_atoi(const char* nptr) { return os::atoi(nptr); }
+       void*  os_calloc(size_t nmemb, size_t size) { return os::calloc(nmemb, size); }
+#if defined(ENABLE_JRE_LAYOUT)
+       char*  os_dirname(char* path) { return os::dirname(path); }
+#endif
+       int    os_dlclose(void* handle) { return os::dlclose(handle); }
+       char*  os_dlerror(void) { return os::dlerror(); }
+       void*  os_dlopen(const char* filename, int flag) { return os::dlopen(filename, flag); }
+       void*  os_dlsym(void* handle, const char* symbol) { return os::dlsym(handle, symbol); }
+       int    os_fclose(FILE* fp) { return os::fclose(fp); }
+       FILE*  os_fopen(const char* path, const char* mode) { return os::fopen(path, mode); }
+       size_t os_fread(void* ptr, size_t size, size_t nmemb, FILE* stream) { return os::fread(ptr, size, nmemb, stream); }
+       void   os_free(void* ptr) { os::free(ptr); }
+       int    os_getpagesize(void) { return os::getpagesize(); }
+       void*  os_memcpy(void* dest, const void* src, size_t n) { return os::memcpy(dest, src, n); }
+       void*  os_memset(void* s, int c, size_t n) { return os::memset(s, c, n); }
+       int    os_mprotect(void* addr, size_t len, int prot) { return os::mprotect(addr, len, prot); }
+       int    os_scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*)) { return os::scandir(dir, namelist, filter, compar); }
+       int    os_stat(const char* path, struct stat* buf) { return os::stat(path, buf); }
+       char*  os_strcat(char* dest, const char* src) { return os::strcat(dest, src); }
+       char*  os_strcpy(char* dest, const char* src) { return os::strcpy(dest, src); }
+       char*  os_strdup(const char* s) { return os::strdup(s); }
+       int    os_strlen(const char* s) { return os::strlen(s); }
+
+}
+
+
+/*
+ * 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/os.hpp b/src/vm/os.hpp
new file mode 100644 (file)
index 0000000..243ffc0
--- /dev/null
@@ -0,0 +1,609 @@
+/* src/vm/os.hpp - system (OS) functions
+
+   Copyright (C) 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 _OS_HPP
+#define _OS_HPP
+
+#include "config.h"
+
+/* NOTE: In this file we check for all system headers, because we wrap
+   all system calls into inline functions for better portability. */
+
+#if defined(HAVE_DIRENT_H)
+# include <dirent.h>
+#endif
+
+#if defined(HAVE_DLFCN_H)
+# include <dlfcn.h>
+#endif
+
+#if defined(HAVE_ERRNO_H)
+# include <errno.h>
+#endif
+
+#if defined(HAVE_FCNTL_H)
+# include <fcntl.h>
+#endif
+
+#if defined(ENABLE_JRE_LAYOUT)
+# if defined(HAVE_LIBGEN_H)
+#  include <libgen.h>
+# endif
+#endif
+
+#if defined(HAVE_SIGNAL_H)
+# include <signal.h>
+#endif
+
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#endif
+
+#if defined(HAVE_STDIO_H)
+# include <stdio.h>
+#endif
+
+#if defined(HAVE_STDLIB_H)
+# include <stdlib.h>
+#endif
+
+#if defined(HAVE_STRING_H)
+# include <string.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#if defined(HAVE_SYS_MMAN_H)
+# include <sys/mman.h>
+#endif
+
+#if defined(HAVE_SYS_SOCKET_H)
+# include <sys/socket.h>
+#endif
+
+#if defined(HAVE_SYS_STAT_H)
+# include <sys/stat.h>
+#endif
+
+#if defined(HAVE_SYS_TYPES_H)
+# include <sys/types.h>
+#endif
+
+
+#ifdef __cplusplus
+
+// Class wrapping system (OS) functions.
+class os {
+public:
+       // Inline functions.
+       static inline void   abort();
+       static inline int    accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
+       static inline int    access(const char *pathname, int mode);
+       static inline int    atoi(const char* nptr);
+       static inline void*  calloc(size_t nmemb, size_t size);
+       static inline int    close(int fd);
+       static inline int    connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen);
+#if defined(ENABLE_JRE_LAYOUT)
+       static inline char*  dirname(char* path);
+#endif
+       static inline int    dlclose(void* handle);
+       static inline char*  dlerror(void);
+       static inline void*  dlopen(const char* filename, int flag);
+       static inline void*  dlsym(void* handle, const char* symbol);
+       static inline int    fclose(FILE* fp);
+       static inline FILE*  fopen(const char* path, const char* mode);
+       static inline size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
+       static inline void   free(void* ptr);
+       static inline int    gethostname(char* name, size_t len);
+       static inline int    getpagesize(void);
+       static inline int    getsockname(int s, struct sockaddr* name, socklen_t* namelen);
+       static inline int    getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen);
+       static inline int    listen(int sockfd, int backlog);
+       static inline void*  malloc(size_t size);
+       static inline void*  memcpy(void* dest, const void* src, size_t n);
+       static inline void*  memset(void* s, int c, size_t n);
+       static inline int    mprotect(void* addr, size_t len, int prot);
+       static inline int    scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
+       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);
+       static inline int    stat(const char* path, struct stat* buf);
+#if defined(__SOLARIS__)
+       static inline int    str2sig(const char* str, int* signum);
+#endif
+       static inline char*  strcat(char* dest, const char* src);
+       static inline char*  strcpy(char* dest, const char* src);
+       static inline char*  strdup(const char* s);
+       static inline size_t strlen(const char* s);
+       static inline char*  strerror(int errnum);
+
+       static void* mmap_anonymous(void *addr, size_t len, int prot, int flags);
+       static int   processors_online(void);
+};
+
+
+inline void os::abort(void)
+{
+#if defined(HAVE_ABORT)
+       ::abort();
+#else
+# error abort not available
+#endif
+}
+
+inline int os::accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen)
+{
+#if defined(HAVE_ACCEPT)
+       return ::accept(sockfd, addr, addrlen);
+#else
+# error accept not available
+#endif
+}
+
+inline int os::access(const char* pathname, int mode)
+{
+#if defined(HAVE_ACCESS)
+       return ::access(pathname, mode);
+#else
+# error access not available
+#endif
+}
+
+inline int os::atoi(const char* nptr)
+{
+#if defined(HAVE_ATOI)
+       return ::atoi(nptr);
+#else
+# error atoi not available
+#endif
+}
+
+inline void* os::calloc(size_t nmemb, size_t size)
+{
+#if defined(HAVE_CALLOC)
+       return ::calloc(nmemb, size);
+#else
+# error calloc not available
+#endif
+}
+
+inline int os::close(int fd)
+{
+#if defined(HAVE_CLOSE)
+       return ::close(fd);
+#else
+# error close not available
+#endif
+}
+
+inline int os::connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen)
+{
+#if defined(HAVE_CONNECT)
+       return ::connect(sockfd, serv_addr, addrlen);
+#else
+# error connect not available
+#endif
+}
+
+#if defined(ENABLE_JRE_LAYOUT)
+inline char* os::dirname(char* path)
+{
+#if defined(HAVE_DIRNAME)
+       return ::dirname(path);
+#else
+# error dirname not available
+#endif
+}
+#endif
+
+inline int os::dlclose(void* handle)
+{
+#if defined(HAVE_DLCLOSE)
+       return ::dlclose(handle);
+#else
+# error dlclose not available
+#endif
+}
+
+inline char* os::dlerror(void)
+{
+#if defined(HAVE_DLERROR)
+       return ::dlerror();
+#else
+# error dlerror not available
+#endif
+}
+
+inline void* os::dlopen(const char* filename, int flag)
+{
+#if defined(HAVE_DLOPEN)
+       return ::dlopen(filename, flag);
+#else
+# error dlopen not available
+#endif
+}
+
+inline void* os::dlsym(void* handle, const char* symbol)
+{
+#if defined(HAVE_DLSYM)
+       return ::dlsym(handle, symbol);
+#else
+# error dlsym not available
+#endif
+}
+
+inline int os::fclose(FILE* fp)
+{
+#if defined(HAVE_FCLOSE)
+       return ::fclose(fp);
+#else
+# error fclose not available
+#endif
+}
+
+inline FILE* os::fopen(const char* path, const char* mode)
+{
+#if defined(HAVE_FOPEN)
+       return ::fopen(path, mode);
+#else
+# error fopen not available
+#endif
+}
+
+inline size_t os::fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
+{
+#if defined(HAVE_FREAD)
+       return ::fread(ptr, size, nmemb, stream);
+#else
+# error fread not available
+#endif
+}
+
+inline static int system_fseek(FILE *stream, off_t offset, int whence)
+{
+#if defined(HAVE_FSEEK)
+       return fseek(stream, offset, whence);
+#else
+# error fseek not available
+#endif
+}
+
+inline void os::free(void* ptr)
+{
+#if defined(HAVE_FREE)
+       ::free(ptr);
+#else
+# error free not available
+#endif
+}
+
+inline static int system_fsync(int fd)
+{
+#if defined(HAVE_FSYNC)
+       return fsync(fd);
+#else
+# error fsync not available
+#endif
+}
+
+inline static int system_ftruncate(int fd, off_t length)
+{
+#if defined(HAVE_FTRUNCATE)
+       return ftruncate(fd, length);
+#else
+# error ftruncate not available
+#endif
+}
+
+inline int os::gethostname(char* name, size_t len)
+{
+#if defined(HAVE_GETHOSTNAME)
+       return ::gethostname(name, len);
+#else
+# error gethostname not available
+#endif
+}
+
+inline int os::getpagesize(void)
+{
+#if defined(HAVE_GETPAGESIZE)
+       return ::getpagesize();
+#else
+# error getpagesize not available
+#endif
+}
+
+inline int os::getsockname(int s, struct sockaddr* name, socklen_t* namelen)
+{
+#if defined(HAVE_GETSOCKNAME)
+       return ::getsockname(s, name, namelen);
+#else
+# error getsockname not available
+#endif
+}
+
+inline int os::getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)
+{
+#if defined(HAVE_GETSOCKOPT)
+       return ::getsockopt(s, level, optname, optval, optlen);
+#else
+# error getsockopt not available
+#endif
+}
+
+inline int os::listen(int sockfd, int backlog)
+{
+#if defined(HAVE_LISTEN)
+       return ::listen(sockfd, backlog);
+#else
+# error listen not available
+#endif
+}
+
+inline static off_t system_lseek(int fildes, off_t offset, int whence)
+{
+#if defined(HAVE_LSEEK)
+       return lseek(fildes, offset, whence);
+#else
+# error lseek not available
+#endif
+}
+
+inline void* os::malloc(size_t size)
+{
+#if defined(HAVE_MALLOC)
+       return ::malloc(size);
+#else
+# error malloc not available
+#endif
+}
+
+inline void* os::memcpy(void* dest, const void* src, size_t n)
+{
+#if defined(HAVE_MEMCPY)
+       return ::memcpy(dest, src, n);
+#else
+# error memcpy not available
+#endif
+}
+
+inline void* os::memset(void* s, int c, size_t n)
+{
+#if defined(HAVE_MEMSET)
+       return ::memset(s, c, n);
+#else
+# error memset not available
+#endif
+}
+
+inline int os::mprotect(void* addr, size_t len, int prot)
+{
+#if defined(HAVE_MPROTECT)
+       return ::mprotect(addr, len, prot);
+#else
+# error mprotect not available
+#endif
+}
+
+inline static int system_open(const char *pathname, int flags, mode_t mode)
+{
+#if defined(HAVE_OPEN)
+       return open(pathname, flags, mode);
+#else
+# error open not available
+#endif
+}
+
+inline static ssize_t system_read(int fd, void *buf, size_t count)
+{
+#if defined(HAVE_READ)
+       return read(fd, buf, count);
+#else
+# error read not available
+#endif
+}
+
+inline static void *system_realloc(void *ptr, size_t size)
+{
+#if defined(HAVE_REALLOC)
+       return realloc(ptr, size);
+#else
+# error realloc not available
+#endif
+}
+
+inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
+/*
+#elif defined(__SOLARIS__)
+inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **))
+#elif defined(__IRIX__)
+inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(dirent_t *), int(*compar)(dirent_t **, dirent_t **))
+#else
+inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(struct dirent *), int(*compar)(const void *, const void *))
+#endif
+*/
+{
+#if defined(HAVE_SCANDIR)
+# if defined(__LINUX__)
+       return ::scandir(dir, namelist, filter, compar);
+#elif defined(__SOLARIS__)
+       return ::scandir(dir, namelist, filter, (int (*)(const dirent**, const dirent**)) compar);
+# else
+       return ::scandir(dir, namelist, (int (*)(struct dirent*)) filter, compar);
+# endif
+#else
+# error scandir not available
+#endif
+}
+
+inline int os::setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen)
+{
+#if defined(HAVE_SETSOCKOPT)
+       return ::setsockopt(s, level, optname, optval, optlen);
+#else
+# error setsockopt not available
+#endif
+}
+
+inline int os::shutdown(int s, int how)
+{
+#if defined(HAVE_SHUTDOWN)
+       return ::shutdown(s, how);
+#else
+# error shutdown not available
+#endif
+}
+
+inline int os::socket(int domain, int type, int protocol)
+{
+#if defined(HAVE_SOCKET)
+       return ::socket(domain, type, protocol);
+#else
+# error socket not available
+#endif
+}
+
+inline int os::stat(const char* path, struct stat* buf)
+{
+#if defined(HAVE_STAT)
+       return ::stat(path, buf);
+#else
+# error stat not available
+#endif
+}
+
+#if defined(__SOLARIS__)
+inline int os::str2sig(const char* str, int* signum)
+{
+#if defined(HAVE_STR2SIG)
+       return ::str2sig(str, signum);
+#else
+# error str2sig not available
+#endif
+}
+#endif
+
+inline char* os::strcat(char* dest, const char* src)
+{
+#if defined(HAVE_STRCAT)
+       return ::strcat(dest, src);
+#else
+# error strcat not available
+#endif
+}
+
+inline char* os::strcpy(char* dest, const char* src)
+{
+#if defined(HAVE_STRCPY)
+       return ::strcpy(dest, src);
+#else
+# error strcpy not available
+#endif
+}
+
+inline char* os::strdup(const char* s)
+{
+#if defined(HAVE_STRDUP)
+       return ::strdup(s);
+#else
+# error strdup not available
+#endif
+}
+
+inline char* os::strerror(int errnum)
+{
+#if defined(HAVE_STRERROR)
+       return ::strerror(errnum);
+#else
+# error strerror not available
+#endif
+}
+
+inline size_t os::strlen(const char* s)
+{
+#if defined(HAVE_STRLEN)
+       return ::strlen(s);
+#else
+# error strlen not available
+#endif
+}
+
+inline static ssize_t system_write(int fd, const void *buf, size_t count)
+{
+#if defined(HAVE_WRITE)
+       return write(fd, buf, count);
+#else
+# error write not available
+#endif
+}
+
+#else
+
+void*  os_mmap_anonymous(void *addr, size_t len, int prot, int flags);
+
+void   os_abort(void);
+int    os_access(const char* pathname, int mode);
+int    os_atoi(const char* nptr);
+void*  os_calloc(size_t nmemb, size_t size);
+char*  os_dirname(char* path);
+int    os_dlclose(void* handle);
+char*  os_dlerror(void);
+void*  os_dlopen(const char* filename, int flag);
+void*  os_dlsym(void* handle, const char* symbol);
+int    os_fclose(FILE* fp);
+FILE*  os_fopen(const char* path, const char* mode);
+size_t os_fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
+void   os_free(void* ptr);
+int    os_getpagesize(void);
+void*  os_memcpy(void* dest, const void* src, size_t n);
+void*  os_memset(void* s, int c, size_t n);
+int    os_mprotect(void* addr, size_t len, int prot);
+int    os_scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
+int    os_stat(const char* path, struct stat* buf);
+char*  os_strcat(char* dest, const char* src);
+char*  os_strcpy(char* dest, const char* src);
+char*  os_strdup(const char* s);
+int    os_strlen(const char* s);
+
+#endif
+
+#endif // _OS_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 647baf1914f6794d7c98504964d2ac670970a134..5e5d3b2004ef910b911f256ce371dac47813d0a0 100644 (file)
 
 #include "native/jni.h"
 
-#include "native/include/java_lang_String.h"
-
+#include "vm/options.h"
 #include "vm/package.hpp"
-#include "vm/stringlocal.h"
-
-#include "vmcore/options.h"
-#include "vmcore/utf8.h"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
 
 
 /* internal property structure ************************************************/
diff --git a/src/vm/primitive.c b/src/vm/primitive.c
deleted file mode 100644 (file)
index ca55726..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/* src/vm/primitive.c - primitive types
-
-   Copyright (C) 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/jni.h"
-#include "native/llni.h"
-
-#include "native/include/java_lang_Boolean.h"
-#include "native/include/java_lang_Byte.h"
-#include "native/include/java_lang_Short.h"
-#include "native/include/java_lang_Character.h"
-#include "native/include/java_lang_Integer.h"
-#include "native/include/java_lang_Long.h"
-#include "native/include/java_lang_Float.h"
-#include "native/include/java_lang_Double.h"
-
-#include "vm/builtin.h"
-#include "vm/global.h"
-#include "vm/primitive.h"
-#include "vm/vm.h"
-
-#include "vmcore/class.h"
-#include "vmcore/utf8.h"
-
-
-/* primitive_class_get_by_name *************************************************
-
-   Returns the primitive class of the given class name.
-
-*******************************************************************************/
-
-classinfo *primitive_class_get_by_name(utf *name)
-{
-       int i;
-
-       /* search table of primitive classes */
-
-       for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
-               if (primitivetype_table[i].name == name)
-                       return primitivetype_table[i].class_primitive;
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-/* primitive_class_get_by_type *************************************************
-
-   Returns the primitive class of the given type.
-
-*******************************************************************************/
-
-classinfo *primitive_class_get_by_type(int type)
-{
-       return primitivetype_table[type].class_primitive;
-}
-
-
-/* primitive_class_get_by_char *************************************************
-
-   Returns the primitive class of the given type.
-
-*******************************************************************************/
-
-classinfo *primitive_class_get_by_char(char ch)
-{
-       int index;
-
-       switch (ch) {
-       case 'I':
-               index = PRIMITIVETYPE_INT;
-               break;
-       case 'J':
-               index = PRIMITIVETYPE_LONG;
-               break;
-       case 'F':
-               index = PRIMITIVETYPE_FLOAT;
-               break;
-       case 'D':
-               index = PRIMITIVETYPE_DOUBLE;
-               break;
-       case 'B':
-               index = PRIMITIVETYPE_BYTE;
-               break;
-       case 'C':
-               index = PRIMITIVETYPE_CHAR;
-               break;
-       case 'S':
-               index = PRIMITIVETYPE_SHORT;
-               break;
-       case 'Z':
-               index = PRIMITIVETYPE_BOOLEAN;
-               break;
-       case 'V':
-               index = PRIMITIVETYPE_VOID;
-               break;
-       default:
-               return NULL;
-       }
-
-       return primitivetype_table[index].class_primitive;
-}
-
-
-/* primitive_arrayclass_get_by_name ********************************************
-
-   Returns the primitive array-class of the given primitive class
-   name.
-
-*******************************************************************************/
-
-classinfo *primitive_arrayclass_get_by_name(utf *name)
-{
-       int i;
-
-       /* search table of primitive classes */
-
-       for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
-               if (primitivetype_table[i].name == name)
-                       return primitivetype_table[i].arrayclass;
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-/* primitive_arrayclass_get_by_type ********************************************
-
-   Returns the primitive array-class of the given type.
-
-*******************************************************************************/
-
-classinfo *primitive_arrayclass_get_by_type(int type)
-{
-       return primitivetype_table[type].arrayclass;
-}
-
-
-/* primitive_type_get_by_wrapperclass ******************************************
-
-   Returns the primitive type of the given wrapper-class.
-
-*******************************************************************************/
-
-int primitive_type_get_by_wrapperclass(classinfo *c)
-{
-       int i;
-
-       /* Search primitive table. */
-
-       for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
-               if (primitivetype_table[i].class_wrap == c)
-                       return i;
-
-       /* Invalid primitive wrapper-class. */
-
-       return -1;
-}
-
-
-/* primitive_box ***************************************************************
-
-   Box a primitive of the given type.  If the type is an object,
-   simply return it.
-
-*******************************************************************************/
-
-java_handle_t *primitive_box(int type, imm_union value)
-{
-       java_handle_t *o;
-
-       switch (type) {
-       case PRIMITIVETYPE_BOOLEAN:
-               o = primitive_box_boolean(value.i);
-               break;
-       case PRIMITIVETYPE_BYTE:
-               o = primitive_box_byte(value.i);
-               break;
-       case PRIMITIVETYPE_CHAR:
-               o = primitive_box_char(value.i);
-               break;
-       case PRIMITIVETYPE_SHORT:
-               o = primitive_box_short(value.i);
-               break;
-       case PRIMITIVETYPE_INT:
-               o = primitive_box_int(value.i);
-               break;
-       case PRIMITIVETYPE_LONG:
-               o = primitive_box_long(value.l);
-               break;
-       case PRIMITIVETYPE_FLOAT:
-               o = primitive_box_float(value.f);
-               break;
-       case PRIMITIVETYPE_DOUBLE:
-               o = primitive_box_double(value.d);
-               break;
-       case PRIMITIVETYPE_VOID:
-               o = value.a;
-               break;
-       default:
-               o = NULL;
-               vm_abort("primitive_box: invalid primitive type %d", type);
-       }
-
-       return o;
-}
-
-
-/* primitive_unbox *************************************************************
-
-   Unbox a primitive of the given type.  If the type is an object,
-   simply return it.
-
-*******************************************************************************/
-
-imm_union primitive_unbox(java_handle_t *o)
-{
-       classinfo *c;
-       int        type;
-       imm_union  value;
-
-       if (o == NULL) {
-               value.a = NULL;
-               return value;
-       }
-
-       LLNI_class_get(o, c);
-
-       type = primitive_type_get_by_wrapperclass(c);
-
-       switch (type) {
-       case PRIMITIVETYPE_BOOLEAN:
-               value.i = primitive_unbox_boolean(o);
-               break;
-       case PRIMITIVETYPE_BYTE:
-               value.i = primitive_unbox_byte(o);
-               break;
-       case PRIMITIVETYPE_CHAR:
-               value.i = primitive_unbox_char(o);
-               break;
-       case PRIMITIVETYPE_SHORT:
-               value.i = primitive_unbox_short(o);
-               break;
-       case PRIMITIVETYPE_INT:
-               value.i = primitive_unbox_int(o);
-               break;
-       case PRIMITIVETYPE_LONG:
-               value.l = primitive_unbox_long(o);
-               break;
-       case PRIMITIVETYPE_FLOAT:
-               value.f = primitive_unbox_float(o);
-               break;
-       case PRIMITIVETYPE_DOUBLE:
-               value.d = primitive_unbox_double(o);
-               break;
-       case -1:
-               /* If type is -1 the object is not a primitive box but a
-                  normal object. */
-               value.a = o;
-               break;
-       default:
-               vm_abort("primitive_unbox: invalid primitive type %d", type);
-       }
-
-       return value;
-}
-
-
-/* primitive_box_xxx ***********************************************************
-
-   Box a primitive type.
-
-*******************************************************************************/
-
-#define PRIMITIVE_BOX_TYPE(name, object, type)      \
-java_handle_t *primitive_box_##name(type value)     \
-{                                                   \
-       java_handle_t      *o;                          \
-       java_lang_##object *jo;                         \
-                                                    \
-       o = builtin_new(class_java_lang_##object);      \
-                                                    \
-       if (o == NULL)                                  \
-               return NULL;                                \
-                                                    \
-       jo = (java_lang_##object *) o;                  \
-                                                    \
-       LLNI_field_set_val(jo, value, value);           \
-                                                    \
-       return o;                                       \
-}
-
-PRIMITIVE_BOX_TYPE(boolean, Boolean,   int32_t)
-PRIMITIVE_BOX_TYPE(byte,    Byte,      int32_t)
-PRIMITIVE_BOX_TYPE(char,    Character, int32_t)
-PRIMITIVE_BOX_TYPE(short,   Short,     int32_t)
-PRIMITIVE_BOX_TYPE(int,     Integer,   int32_t)
-PRIMITIVE_BOX_TYPE(long,    Long,      int64_t)
-PRIMITIVE_BOX_TYPE(float,   Float,     float)
-PRIMITIVE_BOX_TYPE(double,  Double,    double)
-
-
-/* primitive_unbox_xxx *********************************************************
-
-   Unbox a primitive type.
-
-*******************************************************************************/
-
-#define PRIMITIVE_UNBOX_TYPE(name, object, type)  \
-type primitive_unbox_##name(java_handle_t *o)     \
-{                                                 \
-       java_lang_##object *jo;                       \
-       type                value;                    \
-                                                  \
-       jo = (java_lang_##object *) o;                \
-                                                  \
-       LLNI_field_get_val(jo, value, value);         \
-                                                  \
-       return value;                                 \
-}
-
-PRIMITIVE_UNBOX_TYPE(boolean, Boolean,   int32_t)
-PRIMITIVE_UNBOX_TYPE(byte,    Byte,      int32_t)
-PRIMITIVE_UNBOX_TYPE(char,    Character, int32_t)
-PRIMITIVE_UNBOX_TYPE(short,   Short,     int32_t)
-PRIMITIVE_UNBOX_TYPE(int,     Integer,   int32_t)
-PRIMITIVE_UNBOX_TYPE(long,    Long,      int64_t)
-PRIMITIVE_UNBOX_TYPE(float,   Float,     float)
-PRIMITIVE_UNBOX_TYPE(double,  Double,    double)
-
-
-/*
- * 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/primitive.cpp b/src/vm/primitive.cpp
new file mode 100644 (file)
index 0000000..2b1b27a
--- /dev/null
@@ -0,0 +1,493 @@
+/* src/vm/primitive.cpp - primitive types
+
+   Copyright (C) 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/jni.h"
+#include "native/llni.h"
+
+#include "vm/builtin.h"
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/primitive.hpp"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+/**
+ * Returns the primitive class of the given class name.
+ *
+ * @param name Name of the class.
+ *
+ * @return Class structure.
+ */
+classinfo* Primitive::get_class_by_name(utf *name)
+{
+       int i;
+
+       /* search table of primitive classes */
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
+               if (primitivetype_table[i].name == name)
+                       return primitivetype_table[i].class_primitive;
+
+       /* keep compiler happy */
+
+       return NULL;
+}
+
+
+/**
+ * Returns the primitive class of the given type.
+ *
+ * @param type Integer type of the class.
+ *
+ * @return Class structure.
+ */
+classinfo* Primitive::get_class_by_type(int type)
+{
+       return primitivetype_table[type].class_primitive;
+}
+
+
+/**
+ * Returns the primitive class of the given type.
+ *
+ * @param ch 
+ *
+ * @return Class structure.
+ */
+classinfo* Primitive::get_class_by_char(char ch)
+{
+       int index;
+
+       switch (ch) {
+       case 'I':
+               index = PRIMITIVETYPE_INT;
+               break;
+       case 'J':
+               index = PRIMITIVETYPE_LONG;
+               break;
+       case 'F':
+               index = PRIMITIVETYPE_FLOAT;
+               break;
+       case 'D':
+               index = PRIMITIVETYPE_DOUBLE;
+               break;
+       case 'B':
+               index = PRIMITIVETYPE_BYTE;
+               break;
+       case 'C':
+               index = PRIMITIVETYPE_CHAR;
+               break;
+       case 'S':
+               index = PRIMITIVETYPE_SHORT;
+               break;
+       case 'Z':
+               index = PRIMITIVETYPE_BOOLEAN;
+               break;
+       case 'V':
+               index = PRIMITIVETYPE_VOID;
+               break;
+       default:
+               return NULL;
+       }
+
+       return primitivetype_table[index].class_primitive;
+}
+
+
+/**
+ * Returns the primitive array-class of the given primitive class
+ * name.
+ *
+ * @param name Name of the class.
+ *
+ * @return Class structure.
+ */
+classinfo* Primitive::get_arrayclass_by_name(utf *name)
+{
+       int i;
+
+       /* search table of primitive classes */
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
+               if (primitivetype_table[i].name == name)
+                       return primitivetype_table[i].arrayclass;
+
+       /* keep compiler happy */
+
+       return NULL;
+}
+
+
+/**
+ * Returns the primitive array-class of the given type.
+ *
+ * @param type Integer type of the class.
+ *
+ * @return Class structure.
+ */
+classinfo* Primitive::get_arrayclass_by_type(int type)
+{
+       return primitivetype_table[type].arrayclass;
+}
+
+
+/**
+ * Returns the primitive type of the given wrapper-class.
+ *
+ * @param c Class structure.
+ *
+ * @return Integer type of the class.
+ */
+int Primitive::get_type_by_wrapperclass(classinfo *c)
+{
+       int i;
+
+       /* Search primitive table. */
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
+               if (primitivetype_table[i].class_wrap == c)
+                       return i;
+
+       /* Invalid primitive wrapper-class. */
+
+       return -1;
+}
+
+
+/**
+ * Box a primitive of the given type.  If the type is an object,
+ * simply return it.
+ *
+ * @param type  Type of the passed value.
+ * @param value Value to box.
+ *
+ * @return Handle of the boxing Java object.
+ */
+java_handle_t* Primitive::box(int type, imm_union value)
+{
+       java_handle_t* o;
+
+       switch (type) {
+       case PRIMITIVETYPE_BOOLEAN:
+               o = box((uint8_t) value.i);
+               break;
+       case PRIMITIVETYPE_BYTE:
+               o = box((int8_t) value.i);
+               break;
+       case PRIMITIVETYPE_CHAR:
+               o = box((uint16_t) value.i);
+               break;
+       case PRIMITIVETYPE_SHORT:
+               o = box((int16_t) value.i);
+               break;
+       case PRIMITIVETYPE_INT:
+               o = box(value.i);
+               break;
+       case PRIMITIVETYPE_LONG:
+               o = box(value.l);
+               break;
+       case PRIMITIVETYPE_FLOAT:
+               o = box(value.f);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               o = box(value.d);
+               break;
+       case PRIMITIVETYPE_VOID:
+               o = (java_handle_t*) value.a;
+               break;
+       default:
+               o = NULL;
+               vm_abort("primitive_box: invalid primitive type %d", type);
+       }
+
+       return o;
+}
+
+
+/**
+ * Unbox a primitive of the given type.  If the type is an object,
+ * simply return it.
+ *
+ * @param h Handle of the Java object.
+ *
+ * @return Unboxed value as union.
+ */
+imm_union Primitive::unbox(java_handle_t *h)
+{
+       classinfo *c;
+       int        type;
+       imm_union  value;
+
+       if (h == NULL) {
+               value.a = NULL;
+               return value;
+       }
+
+       LLNI_class_get(h, c);
+
+       type = get_type_by_wrapperclass(c);
+
+       switch (type) {
+       case PRIMITIVETYPE_BOOLEAN:
+               value.i = unbox_boolean(h);
+               break;
+       case PRIMITIVETYPE_BYTE:
+               value.i = unbox_byte(h);
+               break;
+       case PRIMITIVETYPE_CHAR:
+               value.i = unbox_char(h);
+               break;
+       case PRIMITIVETYPE_SHORT:
+               value.i = unbox_short(h);
+               break;
+       case PRIMITIVETYPE_INT:
+               value.i = unbox_int(h);
+               break;
+       case PRIMITIVETYPE_LONG:
+               value.l = unbox_long(h);
+               break;
+       case PRIMITIVETYPE_FLOAT:
+               value.f = unbox_float(h);
+               break;
+       case PRIMITIVETYPE_DOUBLE:
+               value.d = unbox_double(h);
+               break;
+       case -1:
+               /* If type is -1 the object is not a primitive box but a
+                  normal object. */
+               value.a = h;
+               break;
+       default:
+               vm_abort("Primitive::unbox: invalid primitive type %d", type);
+       }
+
+       return value;
+}
+
+
+/**
+ * Box a primitive type.
+ */
+java_handle_t* Primitive::box(uint8_t value)
+{
+       java_handle_t *h = builtin_new(class_java_lang_Boolean);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_Boolean b(h);
+       b.set_value(value);
+
+       return h;
+}
+
+java_handle_t* Primitive::box(int8_t value)
+{
+       java_handle_t *h = builtin_new(class_java_lang_Byte);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_Byte b(h);
+       b.set_value(value);
+
+       return h;
+}
+
+java_handle_t* Primitive::box(uint16_t value)
+{
+       java_handle_t *h = builtin_new(class_java_lang_Character);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_Character c(h);
+       c.set_value(value);
+
+       return h;
+}
+
+java_handle_t* Primitive::box(int16_t value)
+{
+       java_handle_t *h = builtin_new(class_java_lang_Short);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_Short s(h);
+       s.set_value(value);
+
+       return h;
+}
+
+java_handle_t* Primitive::box(int32_t value)
+{
+       java_handle_t *h = builtin_new(class_java_lang_Integer);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_Integer i(h);
+       i.set_value(value);
+
+       return h;
+}
+
+java_handle_t* Primitive::box(int64_t value)
+{
+       java_handle_t *h = builtin_new(class_java_lang_Long);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_Long l(h);
+       l.set_value(value);
+
+       return h;
+}
+
+java_handle_t* Primitive::box(float value)
+{
+       java_handle_t *h = builtin_new(class_java_lang_Float);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_Float f(h);
+       f.set_value(value);
+
+       return h;
+}
+
+java_handle_t* Primitive::box(double value)
+{
+       java_handle_t *h = builtin_new(class_java_lang_Double);
+
+       if (h == NULL)
+               return NULL;
+
+       java_lang_Double d(h);
+       d.set_value(value);
+
+       return h;
+}
+
+
+
+/**
+ * Unbox a primitive type.
+ */
+
+// template<class T> T Primitive::unbox(java_handle_t *h)
+// {
+//     return java_lang_Boolean::get_value(h);
+// }
+
+inline uint8_t Primitive::unbox_boolean(java_handle_t *h)
+{
+       java_lang_Boolean b(h);
+       return b.get_value();
+}
+
+inline int8_t Primitive::unbox_byte(java_handle_t *h)
+{
+       java_lang_Byte b(h);
+       return b.get_value();
+}
+
+inline uint16_t Primitive::unbox_char(java_handle_t *h)
+{
+       java_lang_Character c(h);
+       return c.get_value();
+}
+
+inline int16_t Primitive::unbox_short(java_handle_t *h)
+{
+       java_lang_Short s(h);
+       return s.get_value();
+}
+
+inline int32_t Primitive::unbox_int(java_handle_t *h)
+{
+       java_lang_Integer i(h);
+       return i.get_value();
+}
+
+inline int64_t Primitive::unbox_long(java_handle_t *h)
+{
+       java_lang_Long l(h);
+       return l.get_value();
+}
+
+inline float Primitive::unbox_float(java_handle_t *h)
+{
+       java_lang_Float f(h);
+       return f.get_value();
+}
+
+inline double Primitive::unbox_double(java_handle_t *h)
+{
+       java_lang_Double d(h);
+       return d.get_value();
+}
+
+
+
+// Legacy C interface.
+
+extern "C" {
+
+       classinfo* Primitive_get_class_by_name(utf *name) { return Primitive::get_class_by_name(name); }
+classinfo* Primitive_get_class_by_type(int type) { return Primitive::get_class_by_type(type); }
+classinfo* Primitive_get_class_by_char(char ch) { return Primitive::get_class_by_char(ch); }
+classinfo* Primitive_get_arrayclass_by_name(utf *name) { return Primitive::get_arrayclass_by_name(name); }
+classinfo* Primitive_get_arrayclass_by_type(int type) { return Primitive::get_arrayclass_by_type(type); }
+int Primitive_get_type_by_wrapperclass(classinfo *c) { return Primitive::get_type_by_wrapperclass(c); }
+java_handle_t* Primitive_box(int type, imm_union value) { return Primitive::box(type, value); }
+imm_union Primitive_unbox(java_handle_t *h) { return Primitive::unbox(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/primitive.h b/src/vm/primitive.h
deleted file mode 100644 (file)
index f5ce4d6..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/* src/vm/primitive.c - primitive types
-
-   Copyright (C) 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
-
-   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 _PRIMITIVE_H
-#define _PRIMITIVE_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/linker.h"
-#include "vmcore/utf8.h"
-
-
-/* primitive data types *******************************************************/
-
-/* These values are used in parsed descriptors and in some other
-   places were the different types handled internally as TYPE_INT have
-   to be distinguished. */
-
-#define PRIMITIVETYPE_COUNT  11  /* number of primitive types (+ dummies)     */
-
-/* CAUTION: Don't change the numerical values! These constants are
-   used as indices into the primitive type table. */
-
-#define PRIMITIVETYPE_INT     TYPE_INT
-#define PRIMITIVETYPE_LONG    TYPE_LNG
-#define PRIMITIVETYPE_FLOAT   TYPE_FLT
-#define PRIMITIVETYPE_DOUBLE  TYPE_DBL
-#define PRIMITIVETYPE_DUMMY1  TYPE_ADR     /* not used! */
-#define PRIMITIVETYPE_BYTE    5
-#define PRIMITIVETYPE_CHAR    6
-#define PRIMITIVETYPE_SHORT   7
-#define PRIMITIVETYPE_BOOLEAN 8
-#define PRIMITIVETYPE_DUMMY2  9            /* not used! */
-#define PRIMITIVETYPE_VOID    TYPE_VOID
-
-
-/* primitivetypeinfo **********************************************************/
-
-struct primitivetypeinfo {
-       char      *cname;                    /* char name of primitive class      */
-       utf       *name;                     /* name of primitive class           */
-       classinfo *class_wrap;               /* class for wrapping primitive type */
-       classinfo *class_primitive;          /* primitive class                   */
-       char      *wrapname;                 /* name of class for wrapping        */
-       char       typesig;                  /* one character type signature      */
-       char      *arrayname;                /* name of primitive array class     */
-       classinfo *arrayclass;               /* primitive array class             */
-};
-
-
-/* global variables ***********************************************************/
-
-/* This array can be indexed by the PRIMITIVETYPE_ and ARRAYTYPE_
-   constants (except ARRAYTYPE_OBJECT). */
-
-extern primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT];
-
-
-/* function prototypes ********************************************************/
-
-/* this function is in src/vmcore/primitivecore.c */
-void       primitive_init(void);
-void       primitive_postinit(void);
-
-classinfo *primitive_class_get_by_name(utf *name);
-classinfo *primitive_class_get_by_type(int type);
-classinfo *primitive_class_get_by_char(char ch);
-
-classinfo *primitive_arrayclass_get_by_name(utf *name);
-classinfo *primitive_arrayclass_get_by_type(int type);
-
-int        primitive_type_get_by_wrapperclass(classinfo *c);
-
-java_handle_t *primitive_box(int type, imm_union value);
-imm_union      primitive_unbox(java_handle_t *o);
-
-java_handle_t *primitive_box_boolean(int32_t value);
-java_handle_t *primitive_box_byte(int32_t value);
-java_handle_t *primitive_box_char(int32_t value);
-java_handle_t *primitive_box_short(int32_t value);
-java_handle_t *primitive_box_int(int32_t value);
-java_handle_t *primitive_box_long(int64_t value);
-java_handle_t *primitive_box_float(float value);
-java_handle_t *primitive_box_double(double value);
-
-int32_t        primitive_unbox_boolean(java_handle_t *o);
-int32_t        primitive_unbox_byte(java_handle_t *o);
-int32_t        primitive_unbox_char(java_handle_t *o);
-int32_t        primitive_unbox_short(java_handle_t *o);
-int32_t        primitive_unbox_int(java_handle_t *o);
-int64_t        primitive_unbox_long(java_handle_t *o);
-float          primitive_unbox_float(java_handle_t *o);
-double         primitive_unbox_double(java_handle_t *o);
-
-#endif /* _PRIMITIVE_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/primitive.hpp b/src/vm/primitive.hpp
new file mode 100644 (file)
index 0000000..d99883d
--- /dev/null
@@ -0,0 +1,155 @@
+/* src/vm/primitive.hpp - primitive types
+
+   Copyright (C) 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 _PRIMITIVE_HPP
+#define _PRIMITIVE_HPP
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/linker.h"
+#include "vm/utf8.h"
+
+
+#ifdef __cplusplus
+
+class Primitive {
+public:
+       static classinfo*     get_class_by_name(utf *name);
+       static classinfo*     get_class_by_type(int type);
+       static classinfo*     get_class_by_char(char ch);
+       static classinfo*     get_arrayclass_by_name(utf* name);
+       static classinfo*     get_arrayclass_by_type(int type);
+
+       static int            get_type_by_wrapperclass(classinfo *c);
+
+       static java_handle_t* box(int type, imm_union value);
+
+       static java_handle_t* box(uint8_t value);
+       static java_handle_t* box(int8_t value);
+       static java_handle_t* box(uint16_t value);
+       static java_handle_t* box(int16_t value);
+       static java_handle_t* box(int32_t value);
+       static java_handle_t* box(int64_t value);
+       static java_handle_t* box(float value);
+       static java_handle_t* box(double value);
+
+       static imm_union      unbox(java_handle_t *o);
+
+       static uint8_t        unbox_boolean(java_handle_t* o);
+       static int8_t         unbox_byte(java_handle_t* o);
+       static uint16_t       unbox_char(java_handle_t* o);
+       static int16_t        unbox_short(java_handle_t* o);
+       static int32_t        unbox_int(java_handle_t* o);
+       static int64_t        unbox_long(java_handle_t* o);
+       static float          unbox_float(java_handle_t* o);
+       static double         unbox_double(java_handle_t* o);
+};
+
+#endif
+
+/* primitive data types *******************************************************/
+
+/* These values are used in parsed descriptors and in some other
+   places were the different types handled internally as TYPE_INT have
+   to be distinguished. */
+
+#define PRIMITIVETYPE_COUNT  11  /* number of primitive types (+ dummies)     */
+
+/* CAUTION: Don't change the numerical values! These constants are
+   used as indices into the primitive type table. */
+
+#define PRIMITIVETYPE_INT     TYPE_INT
+#define PRIMITIVETYPE_LONG    TYPE_LNG
+#define PRIMITIVETYPE_FLOAT   TYPE_FLT
+#define PRIMITIVETYPE_DOUBLE  TYPE_DBL
+#define PRIMITIVETYPE_DUMMY1  TYPE_ADR     /* not used! */
+#define PRIMITIVETYPE_BYTE    5
+#define PRIMITIVETYPE_CHAR    6
+#define PRIMITIVETYPE_SHORT   7
+#define PRIMITIVETYPE_BOOLEAN 8
+#define PRIMITIVETYPE_DUMMY2  9            /* not used! */
+#define PRIMITIVETYPE_VOID    TYPE_VOID
+
+
+/* primitivetypeinfo **********************************************************/
+
+struct primitivetypeinfo {
+       char      *cname;                    /* char name of primitive class      */
+       utf       *name;                     /* name of primitive class           */
+       classinfo *class_wrap;               /* class for wrapping primitive type */
+       classinfo *class_primitive;          /* primitive class                   */
+       char      *wrapname;                 /* name of class for wrapping        */
+       char       typesig;                  /* one character type signature      */
+       char      *arrayname;                /* name of primitive array class     */
+       classinfo *arrayclass;               /* primitive array class             */
+};
+
+
+/* global variables ***********************************************************/
+
+/* This array can be indexed by the PRIMITIVETYPE_ and ARRAYTYPE_
+   constants (except ARRAYTYPE_OBJECT). */
+
+extern primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT];
+
+/* this function is in src/vm/primitivecore.c */
+void       primitive_init(void);
+void       primitive_postinit(void);
+
+#ifndef __cplusplus
+// Legacy C interface.
+classinfo *Primitive_get_class_by_name(utf *name);
+classinfo *Primitive_get_class_by_type(int type);
+classinfo *Primitive_get_class_by_char(char ch);
+
+classinfo *Primitive_get_arrayclass_by_name(utf *name);
+classinfo *Primitive_get_arrayclass_by_type(int type);
+
+int        Primitive_get_type_by_wrapperclass(classinfo *c);
+
+java_handle_t *Primitive_box(int type, imm_union value);
+imm_union      Primitive_unbox(java_handle_t *h);
+#endif
+
+#endif // _PRIMITIVE_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:
+ */
diff --git a/src/vm/primitivecore.c b/src/vm/primitivecore.c
new file mode 100644 (file)
index 0000000..0444bf8
--- /dev/null
@@ -0,0 +1,244 @@
+/* src/vm/primitivecore.c - core functions for primitive types
+
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+/* primitivetype_table *********************************************************
+
+   Structure for primitive classes: contains the class for wrapping
+   the primitive type, the primitive class, the name of the class for
+   wrapping, the one character type signature and the name of the
+   primitive class.
+   CAUTION: Don't change the order of the types. This table is indexed
+   by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
+
+*******************************************************************************/
+
+primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
+       { "int"     , NULL, NULL, NULL, "java/lang/Integer",   'I', "[I", NULL },
+       { "long"    , NULL, NULL, NULL, "java/lang/Long",      'J', "[J", NULL },
+       { "float"   , NULL, NULL, NULL, "java/lang/Float",     'F', "[F", NULL },
+       { "double"  , NULL, NULL, NULL, "java/lang/Double",    'D', "[D", NULL },
+       { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
+       { "byte"    , NULL, NULL, NULL, "java/lang/Byte",      'B', "[B", NULL },
+       { "char"    , NULL, NULL, NULL, "java/lang/Character", 'C', "[C", NULL },
+       { "short"   , NULL, NULL, NULL, "java/lang/Short",     'S', "[S", NULL },
+       { "boolean" , NULL, NULL, NULL, "java/lang/Boolean",   'Z', "[Z", NULL },
+       { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
+#if defined(ENABLE_JAVASE)
+       { "void"    , NULL, NULL, NULL, "java/lang/Void",      'V', NULL, NULL }
+#else
+       { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
+#endif
+};
+
+
+/* primitive_init **************************************************************
+
+   Fill the primitive type table with the primitive-type classes,
+   array-classes and wrapper classes.  This is important in the VM
+   startup.
+
+   We split this primitive-type table initialization because of
+   annotations in the bootstrap classes.
+
+   But we may get a problem if we have annotations in:
+
+   java/lang/Object
+   java/lang/Cloneable
+   java/io/Serializable
+
+   Also see: loader_preinit and linker_preinit.
+
+*******************************************************************************/
+
+void primitive_init(void)
+{  
+       utf       *name;
+       classinfo *c;
+       utf       *u;
+       classinfo *ac;
+       int        i;
+
+       TRACESUBSYSTEMINITIALIZATION("primitive_init");
+
+       /* Load and link primitive-type classes and array-classes. */
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
+               /* Skip dummy entries. */
+
+               if (primitivetype_table[i].cname == NULL)
+                       continue;
+
+               /* create UTF-8 name */
+
+               name = utf_new_char(primitivetype_table[i].cname);
+
+               primitivetype_table[i].name = name;
+
+               /* create primitive class */
+
+               c = class_create_classinfo(name);
+
+               /* Primitive type classes don't have a super class. */
+
+               c->super = NULL;
+
+               /* set flags and mark it as primitive class */
+
+               c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT | ACC_CLASS_PRIMITIVE;
+               
+               /* prevent loader from loading primitive class */
+
+               c->state |= CLASS_LOADED;
+
+               /* INFO: don't put primitive classes into the classcache */
+
+               if (!link_class(c))
+                       vm_abort("linker_init: linking failed");
+
+               /* Just to be sure. */
+
+               assert(c->state & CLASS_LOADED);
+               assert(c->state & CLASS_LINKED);
+
+               primitivetype_table[i].class_primitive = c;
+
+               /* Create primitive array class. */
+
+               if (primitivetype_table[i].arrayname != NULL) {
+                       u  = utf_new_char(primitivetype_table[i].arrayname);
+                       ac = class_create_classinfo(u);
+                       ac = load_newly_created_array(ac, NULL);
+
+                       if (ac == NULL)
+                               vm_abort("primitive_init: loading failed");
+
+                       assert(ac->state & CLASS_LOADED);
+
+                       if (!link_class(ac))
+                               vm_abort("primitive_init: linking failed");
+
+                       /* Just to be sure. */
+
+                       assert(ac->state & CLASS_LOADED);
+                       assert(ac->state & CLASS_LINKED);
+
+                       primitivetype_table[i].arrayclass = ac;
+               }
+       }
+
+       /* We use two for-loops to have the array-classes already in the
+          primitive-type table (hint: annotations in wrapper-classes). */
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
+               /* Skip dummy entries. */
+
+               if (primitivetype_table[i].cname == NULL)
+                       continue;
+
+               /* Create class for wrapping the primitive type. */
+
+               u = utf_new_char(primitivetype_table[i].wrapname);
+               c = load_class_bootstrap(u);
+
+               if (c == NULL)
+                       vm_abort("primitive_init: loading failed");
+
+               if (!link_class(c))
+                       vm_abort("primitive_init: linking failed");
+
+               /* Just to be sure. */
+
+               assert(c->state & CLASS_LOADED);
+               assert(c->state & CLASS_LINKED);
+
+               primitivetype_table[i].class_wrap = c;
+       }
+}
+
+
+/* primitive_postinit **********************************************************
+
+   Finish the primitive-type table initialization.  In this step we
+   set the vftbl of the primitive-type classes.
+
+   This is necessary because java/lang/Class is loaded and linked
+   after the primitive types have been linked.
+
+   We have to do that in an extra function, as the primitive types are
+   not stored in the classcache.
+
+*******************************************************************************/
+
+void primitive_postinit(void)
+{
+       classinfo *c;
+       int        i;
+
+       TRACESUBSYSTEMINITIALIZATION("primitive_postinit");
+
+       assert(class_java_lang_Class);
+       assert(class_java_lang_Class->vftbl);
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
+               /* Skip dummy entries. */
+
+               if (primitivetype_table[i].cname == NULL)
+                       continue;
+
+               c = primitivetype_table[i].class_primitive;
+
+               c->object.header.vftbl = class_java_lang_Class->vftbl;
+       }
+}
+
+
+/*
+ * 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 29a200aa671136a3ebf31f3d608337a15391354d..33090078164d16d4c8889d58d2cd4e2a324c1777 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 
+#include <stdint.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/utsname.h>
 
-#include "vm/types.h"
-
 #include "mm/memory.h"
 
 #include "native/jni.h"
 #include "native/llni.h"
 
-#include "vm/global.h"                      /* required by java_lang_String.h */
-#include "native/include/java_lang_String.h"
-
 #include "toolbox/list.h"
 #include "toolbox/util.h"
 
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
 #include "vm/properties.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
 
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/system.h"
-
 
 /* internal property structure ************************************************/
 
 typedef struct list_properties_entry_t list_properties_entry_t;
 
 struct list_properties_entry_t {
-       char       *key;
-       char       *value;
+       const char* key;
+       const char* value;
        listnode_t  linkage;
 };
 
@@ -139,8 +135,8 @@ void properties_set(void)
 
           Now let's strip two levels. */
 
-       p = system_dirname(p);
-       p = system_dirname(p);
+       p = os_dirname(p);
+       p = os_dirname(p);
 
 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
 
@@ -177,7 +173,7 @@ void properties_set(void)
 
        /* Check if that libjvm.so exists. */
 
-       if (system_access(java_home, F_OK) == 0) {
+       if (os_access(java_home, F_OK) == 0) {
                /* Yes, we add /jre to java.home. */
 
                strcpy(java_home, p);
@@ -578,7 +574,7 @@ void properties_set(void)
 
 *******************************************************************************/
 
-void properties_add(char *key, char *value)
+void properties_add(const char *key, const char *value)
 {
        list_properties_entry_t *pe;
 
@@ -625,7 +621,7 @@ void properties_add(char *key, char *value)
 
 *******************************************************************************/
 
-char *properties_get(char *key)
+const char *properties_get(const char *key)
 {
        list_properties_entry_t *pe;
 
@@ -645,7 +641,7 @@ char *properties_get(char *key)
 
 *******************************************************************************/
 
-void properties_system_add(java_handle_t *p, char *key, char *value)
+void properties_system_add(java_handle_t *p, const char *key, const char *value)
 {
        classinfo     *c;
        methodinfo    *m;
index a468aec5769678b5a9c74ca9a9841a38a7e96015..def2ed1dd80447fe07161ac2399aca2e84be7a74 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/properties.h - handling commandline properties
 
-   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.
 
 
 #include "config.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stdint.h>
 
 #include "vm/global.h"
 void  properties_init(void);
 void  properties_set(void);
 
-void  properties_add(char *key, char *value);
-char *properties_get(char *key);
+void        properties_add(const char *key, const char *value);
+const char *properties_get(const char *key);
 
-void  properties_system_add(java_handle_t *p, char *key, char *value);
+void  properties_system_add(java_handle_t *p, const char *key, const char *value);
 
 #if defined(ENABLE_JAVASE)
 void  properties_system_add_all(java_handle_t *p);
@@ -51,6 +53,10 @@ void  properties_system_add_all(java_handle_t *p);
 
 void  properties_dump(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _PROPERTIES_H */
 
 
diff --git a/src/vm/references.h b/src/vm/references.h
new file mode 100644 (file)
index 0000000..73eb721
--- /dev/null
@@ -0,0 +1,167 @@
+/* src/vm/references.h - references to classes/fields/methods
+
+   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 _REFERENCES_H_
+#define _REFERENCES_H_
+
+/* forward typedefs ***********************************************************/
+
+typedef struct constant_classref constant_classref;
+typedef struct constant_FMIref   constant_FMIref;
+
+
+/* constant_classref **********************************************************/
+
+struct constant_classref {
+       void             *pseudo_vftbl; /* for distinguishing it from classinfo   */
+       struct classinfo *referer;    /* class containing the reference           */
+       struct utf       *name;       /* name of the class refered to             */
+};
+
+
+/* classref_or_classinfo ******************************************************/
+
+typedef union classref_or_classinfo {
+       constant_classref *ref;       /* a symbolic class reference               */
+       struct classinfo  *cls;       /* an already loaded class                  */
+       void              *any;       /* used for general access (x != NULL,...)  */
+} classref_or_classinfo;
+
+
+/* parseddesc_t ***************************************************************/
+
+typedef union parseddesc {
+       struct typedesc   *fd;        /* parsed field descriptor                  */
+       struct methoddesc *md;        /* parsed method descriptor                 */
+       void              *any;       /* used for simple test against NULL        */
+} parseddesc_t;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/class.h"
+#include "vm/descriptor.h"
+#include "vm/field.h"
+#include "vm/global.h"
+#include "vm/method.h"
+#include "vm/utf8.h"
+
+
+/*----------------------------------------------------------------------------*/
+/* References                                                                 */
+/*                                                                            */
+/* This header files defines the following types used for references to       */
+/* classes/methods/fields and descriptors:                                    */
+/*                                                                            */
+/*     classinfo *                a loaded class                              */
+/*     constant_classref          a symbolic reference                        */
+/*     classref_or_classinfo      a loaded class or a symbolic reference      */
+/*                                                                            */
+/*     constant_FMIref            a symb. ref. to a field/method/intf.method  */
+/*                                                                            */
+/*     typedesc *                 describes a field type                      */
+/*     methoddesc *               descrives a method type                     */
+/*     parseddesc                 describes a field type or a method type     */
+/*----------------------------------------------------------------------------*/
+
+/* structs ********************************************************************/
+
+/* constant_FMIref ************************************************************/
+
+struct constant_FMIref{      /* Fieldref, Methodref and InterfaceMethodref    */
+       union {
+               s4                 index;     /* used only within the loader          */
+               constant_classref *classref;  /* class having this field/meth./intfm. */
+               fieldinfo         *field;     /* resolved field                       */
+               methodinfo        *method;    /* resolved method                      */
+       } p;
+       utf         *name;       /* field/method/interfacemethod name             */
+       utf         *descriptor; /* field/method/intfmeth. type descriptor string */
+       parseddesc_t parseddesc; /* parsed descriptor                             */
+};
+
+
+/* macros *********************************************************************/
+
+/* a value that never occurrs in classinfo.header.vftbl                       */
+#define CLASSREF_PSEUDO_VFTBL ((void *) 1)
+
+/* macro for testing if a classref_or_classinfo is a classref                 */
+/* `reforinfo` is only evaluated once                                         */
+#define IS_CLASSREF(reforinfo)  \
+       ((reforinfo).ref->pseudo_vftbl == CLASSREF_PSEUDO_VFTBL)
+
+/* macro for testing if a constant_FMIref has been resolved                   */
+/* `fmiref` is only evaluated once                                            */
+#define IS_FMIREF_RESOLVED(fmiref)  \
+       ((fmiref)->p.classref->pseudo_vftbl != CLASSREF_PSEUDO_VFTBL)
+
+/* the same as IS_CLASSREF, but also check against NULL */
+#define IS_XCLASSREF(reforinfo)  \
+       ((reforinfo).any && IS_CLASSREF(reforinfo))
+
+/* macro for casting a classref/classinfo * to a classref_or_classinfo        */
+#define CLASSREF_OR_CLASSINFO(value) \
+       (*((classref_or_classinfo *)(&(value))))
+
+/* macro for accessing the name of a classref/classinfo                       */
+#define CLASSREF_OR_CLASSINFO_NAME(value) \
+       (IS_CLASSREF(value) ? (value).ref->name : (value).cls->name)
+
+/* macro for accessing the class name of a method reference                   */
+#define METHODREF_CLASSNAME(fmiref) \
+       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.method->clazz->name \
+                                                               : (fmiref)->p.classref->name)
+
+/* macro for accessing the class name of a field reference                   */
+#define FIELDREF_CLASSNAME(fmiref) \
+       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.field->clazz->name \
+                                                               : (fmiref)->p.classref->name)
+
+/* initialize a constant_classref with referer `ref` and name `classname`     */
+
+#define CLASSREF_INIT(c,ref,classname) \
+    do { \
+        (c).pseudo_vftbl = CLASSREF_PSEUDO_VFTBL; \
+        (c).referer = (ref); \
+        (c).name = (classname); \
+    } while (0)
+
+#endif /* _REFERENCES_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 a98388550e533d90431e95ef0b5bd482492122a2..8bd21c916974c5d1f93dd2e0b3a3ce2322696b47 100644 (file)
 #include "mm/memory.h"
 
 #include "vm/access.h"
-#include "vm/exceptions.h"
+#include "vm/classcache.h"
+#include "vm/descriptor.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/primitive.h"
+#include "vm/globals.hpp"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
 #include "vm/resolve.h"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/verify/typeinfo.h"
 
-#include "vmcore/classcache.h"
-#include "vmcore/descriptor.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 
 /******************************************************************************/
 /* DEBUG HELPERS                                                              */
@@ -500,7 +500,7 @@ bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, class
        else {
                /* a primitive type */
 
-               cls = primitive_class_get_by_type(d->decltype);
+               cls = Primitive_get_class_by_type(d->primitivetype);
 
                assert(cls->state & CLASS_LOADED);
 
@@ -1329,7 +1329,7 @@ resolve_result_t resolve_field_lazy(methodinfo *refmethod,
 
        fi = class_resolvefield(container,
                                                        fieldref->name, fieldref->descriptor,
-                                                       referer, true);
+                                                       referer);
        if (!fi) {
                /* The field does not exist. But since we were called lazily, */
                /* this error must not be reported now. (It will be reported   */
@@ -1427,7 +1427,7 @@ bool resolve_field(unresolved_field *ref,
 
        fi = class_resolvefield(container,
                                                        ref->fieldref->name,ref->fieldref->descriptor,
-                                                       referer,true);
+                                                       referer);
        if (!fi) {
                if (mode == resolveLazy) {
                        /* The field does not exist. But since we were called lazily, */
index 68138206815c9566209c982953dc879e64c11799..fa9ccaddc650c84a450581fb5da787f901ac53d7 100644 (file)
@@ -37,17 +37,16 @@ typedef struct unresolved_subtype_set unresolved_subtype_set;
 #include "config.h"
 #include "vm/types.h"
 
+#include "vm/class.h"
+#include "vm/field.h"
 #include "vm/global.h"
+#include "vm/method.h"
+#include "vm/references.h"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/verify/typeinfo.h"
 
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/method.h"
-#include "vmcore/references.h"
-
 
 /* constants ******************************************************************/
 
diff --git a/src/vm/rt-timing.c b/src/vm/rt-timing.c
new file mode 100644 (file)
index 0000000..2064de2
--- /dev/null
@@ -0,0 +1,203 @@
+/* src/vm/rt-timing.c - POSIX real-time timing utilities
+
+   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 <errno.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/global.h"
+#include "vm/rt-timing.h"
+
+
+struct rt_timing_stat {
+       int index;
+       int totalindex;
+       const char *name;
+};
+
+static struct rt_timing_stat rt_timing_stat_defs[] = {
+    { RT_TIMING_JIT_CHECKS      ,RT_TIMING_JIT_TOTAL , "checks at beginning" },
+    { RT_TIMING_JIT_PARSE       ,RT_TIMING_JIT_TOTAL , "parse" },
+    { RT_TIMING_JIT_STACK       ,RT_TIMING_JIT_TOTAL , "analyse_stack" },
+    { RT_TIMING_JIT_TYPECHECK   ,RT_TIMING_JIT_TOTAL , "typecheck" },
+    { RT_TIMING_JIT_LOOP        ,RT_TIMING_JIT_TOTAL , "loop" },
+    { RT_TIMING_JIT_IFCONV      ,RT_TIMING_JIT_TOTAL , "if conversion" },
+    { RT_TIMING_JIT_ALLOC       ,RT_TIMING_JIT_TOTAL , "register allocation" },
+    { RT_TIMING_JIT_RPLPOINTS   ,RT_TIMING_JIT_TOTAL , "replacement point generation" },
+    { RT_TIMING_JIT_CODEGEN     ,RT_TIMING_JIT_TOTAL , "codegen" },
+    { RT_TIMING_JIT_TOTAL       ,-1                  , "total compile time" },
+    { -1                        ,-1                  , "" },
+
+    { RT_TIMING_LINK_RESOLVE    ,RT_TIMING_LINK_TOTAL, "link: resolve superclass/superinterfaces"},
+    { RT_TIMING_LINK_C_VFTBL    ,RT_TIMING_LINK_TOTAL, "link: compute vftbl length"},
+    { RT_TIMING_LINK_ABSTRACT   ,RT_TIMING_LINK_TOTAL, "link: handle abstract methods"},
+    { RT_TIMING_LINK_C_IFTBL    ,RT_TIMING_LINK_TOTAL, "link: compute interface table"},
+    { RT_TIMING_LINK_F_VFTBL    ,RT_TIMING_LINK_TOTAL, "link: fill vftbl"},
+    { RT_TIMING_LINK_OFFSETS    ,RT_TIMING_LINK_TOTAL, "link: set offsets"},
+    { RT_TIMING_LINK_F_IFTBL    ,RT_TIMING_LINK_TOTAL, "link: fill interface table"},
+    { RT_TIMING_LINK_FINALIZER  ,RT_TIMING_LINK_TOTAL, "link: set finalizer"},
+    { RT_TIMING_LINK_EXCEPTS    ,RT_TIMING_LINK_TOTAL, "link: resolve exception classes"},
+    { RT_TIMING_LINK_SUBCLASS   ,RT_TIMING_LINK_TOTAL, "link: re-calculate subclass indices"},
+    { RT_TIMING_LINK_TOTAL      ,-1                  , "total link time" },
+    { -1                        ,-1                  , "" },
+       
+       { RT_TIMING_LOAD_CHECKS     ,RT_TIMING_LOAD_TOTAL, "load: initial checks"},
+       { RT_TIMING_LOAD_NDPOOL     ,RT_TIMING_LOAD_TOTAL, "load: new descriptor pool"},
+       { RT_TIMING_LOAD_CPOOL      ,RT_TIMING_LOAD_TOTAL, "load: load constant pool"},
+       { RT_TIMING_LOAD_SETUP      ,RT_TIMING_LOAD_TOTAL, "load: class setup"},
+       { RT_TIMING_LOAD_FIELDS     ,RT_TIMING_LOAD_TOTAL, "load: load fields"},
+       { RT_TIMING_LOAD_METHODS    ,RT_TIMING_LOAD_TOTAL, "load: load methods"},
+       { RT_TIMING_LOAD_CLASSREFS  ,RT_TIMING_LOAD_TOTAL, "load: create classrefs"},
+       { RT_TIMING_LOAD_DESCS      ,RT_TIMING_LOAD_TOTAL, "load: allocate descriptors"},
+       { RT_TIMING_LOAD_SETREFS    ,RT_TIMING_LOAD_TOTAL, "load: set classrefs"},
+       { RT_TIMING_LOAD_PARSEFDS   ,RT_TIMING_LOAD_TOTAL, "load: parse field descriptors"},
+       { RT_TIMING_LOAD_PARSEMDS   ,RT_TIMING_LOAD_TOTAL, "load: parse method descriptors"},
+       { RT_TIMING_LOAD_PARSECP    ,RT_TIMING_LOAD_TOTAL, "load: parse descriptors in constant pool"},
+       { RT_TIMING_LOAD_VERIFY     ,RT_TIMING_LOAD_TOTAL, "load: verifier checks"},
+       { RT_TIMING_LOAD_ATTRS      ,RT_TIMING_LOAD_TOTAL, "load: load attributes"},
+       { RT_TIMING_LOAD_TOTAL      ,-1                  , "total load time (from classbuffer)"},
+    { -1                        ,-1                  , "" },
+
+       { RT_TIMING_LOAD_BOOT_LOOKUP,-1                       , "boot: lookup in classcache"},
+       { RT_TIMING_LOAD_BOOT_ARRAY ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: load array classes"},
+       { RT_TIMING_LOAD_BOOT_SUCK  ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: suck class files"},
+       { RT_TIMING_LOAD_BOOT_LOAD  ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: load from class buffer"},
+       { RT_TIMING_LOAD_BOOT_CACHE ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: store in classcache"},
+       { RT_TIMING_LOAD_BOOT_TOTAL ,-1                       , "total bootstrap loader time"},
+    { -1                        ,-1                       , "" },
+
+       { RT_TIMING_LOAD_CL_LOOKUP  ,-1                       , "classloader: lookup in classcache" },
+       { RT_TIMING_LOAD_CL_PREPARE ,-1                       , "classloader: prepare loader call" },
+       { RT_TIMING_LOAD_CL_JAVA    ,-1                       , "classloader: loader Java code" },
+       { RT_TIMING_LOAD_CL_CACHE   ,-1                       , "classloader: store in classcache" },
+    { -1                        ,-1                       , "" },
+
+       { RT_TIMING_NEW_OBJECT      ,-1                       , "builtin_new time" },
+       { RT_TIMING_NEW_ARRAY       ,-1                       , "builtin_newarray time" },
+    { -1                        ,-1                       , "" },
+
+       { RT_TIMING_GC_ALLOC        ,-1                       , "heap allocation time" },
+#if defined(ENABLE_GC_CACAO)
+       { RT_TIMING_GC_SUSPEND      ,RT_TIMING_GC_TOTAL       , "gc: suspending threads" },
+       { RT_TIMING_GC_ROOTSET1     ,RT_TIMING_GC_TOTAL       , "gc: rootset finding" },
+       { RT_TIMING_GC_MARK         ,RT_TIMING_GC_TOTAL       , "gc: marking phase" },
+       { RT_TIMING_GC_COMPACT      ,RT_TIMING_GC_TOTAL       , "gc: compaction phase" },
+       { RT_TIMING_GC_ROOTSET2     ,RT_TIMING_GC_TOTAL       , "gc: rootset writeback" },
+       { RT_TIMING_GC_TOTAL        ,-1                       , "total garbage collection time" },
+#endif
+       { -1                        ,-1                       , "" },
+
+#if defined(ENABLE_REPLACEMENT)
+       { RT_TIMING_REPLACE         ,-1                       , "replacement" },
+       { -1                        ,-1                       , "" },
+#endif
+
+       { RT_TIMING_1               ,-1                       , "temporary timer 1" },
+       { RT_TIMING_2               ,-1                       , "temporary timer 2" },
+       { RT_TIMING_3               ,-1                       , "temporary timer 3" },
+       { RT_TIMING_4               ,-1                       , "temporary timer 4" },
+       { -1                        ,-1                       , "" },
+
+    { 0                         ,-1                       , NULL }
+};
+
+static long long rt_timing_sum[RT_TIMING_N] = { 0 };
+
+void rt_timing_gettime(struct timespec *ts)
+{
+       if (clock_gettime(CLOCK_THREAD_CPUTIME_ID,ts) != 0) {
+               fprintf(stderr,"could not get time by clock_gettime: %s\n",strerror(errno));
+               abort();
+       }
+}
+
+long rt_timing_diff_usec(struct timespec *a,struct timespec *b)
+{
+       long diff;
+       time_t atime;
+
+       diff = (b->tv_nsec - a->tv_nsec) / 1000;
+       atime = a->tv_sec;
+       while (atime < b->tv_sec) {
+               atime++;
+               diff += 1000000;
+       }
+       return diff;
+}
+
+void rt_timing_time_diff(struct timespec *a,struct timespec *b,int index)
+{
+       long diff;
+
+       diff = rt_timing_diff_usec(a,b);
+       rt_timing_sum[index] += diff;
+}
+
+void rt_timing_print_time_stats(FILE *file)
+{
+       struct rt_timing_stat *stats;
+       double total;
+
+       for (stats = rt_timing_stat_defs; stats->name; ++stats) {
+               if (stats->index < 0) {
+                       fprintf(file,"%s\n",stats->name);
+                       continue;
+               }
+               
+               if (stats->totalindex >= 0) {
+                       total = rt_timing_sum[stats->totalindex];
+                       fprintf(file,"%12lld usec %3.0f%% %s\n",
+                                       rt_timing_sum[stats->index],
+                                       (total != 0.0) ? rt_timing_sum[stats->index] / total * 100.0 : 0.0,
+                                       stats->name);
+               }
+               else {
+                       fprintf(file,"%12lld usec      %s\n",
+                                       rt_timing_sum[stats->index],
+                                       stats->name);
+               }
+       }
+}
+
+/*
+ * 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/rt-timing.h b/src/vm/rt-timing.h
new file mode 100644 (file)
index 0000000..26d31a4
--- /dev/null
@@ -0,0 +1,148 @@
+/* src/vm/rt-timing.h - POSIX real-time timing utilities
+
+   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 _RT_TIMING_H
+#define _RT_TIMING_H
+
+#include "config.h"
+
+#if defined(ENABLE_RT_TIMING)
+
+#include <time.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/global.h"
+
+
+#define RT_TIMING_GET_TIME(ts) \
+       rt_timing_gettime(&(ts));
+
+#define RT_TIMING_TIME_DIFF(a,b,index) \
+       rt_timing_time_diff(&(a),&(b),(index));
+
+#define RT_TIMING_JIT_CHECKS       0
+#define RT_TIMING_JIT_PARSE        1
+#define RT_TIMING_JIT_STACK        2
+#define RT_TIMING_JIT_TYPECHECK    3
+#define RT_TIMING_JIT_LOOP         4
+#define RT_TIMING_JIT_IFCONV       5
+#define RT_TIMING_JIT_ALLOC        6
+#define RT_TIMING_JIT_RPLPOINTS    7
+#define RT_TIMING_JIT_CODEGEN      8
+#define RT_TIMING_JIT_TOTAL        9
+
+#define RT_TIMING_LINK_RESOLVE     10
+#define RT_TIMING_LINK_C_VFTBL     11
+#define RT_TIMING_LINK_ABSTRACT    12
+#define RT_TIMING_LINK_C_IFTBL     13
+#define RT_TIMING_LINK_F_VFTBL     14
+#define RT_TIMING_LINK_OFFSETS     15
+#define RT_TIMING_LINK_F_IFTBL     16
+#define RT_TIMING_LINK_FINALIZER   17
+#define RT_TIMING_LINK_EXCEPTS     18
+#define RT_TIMING_LINK_SUBCLASS    19
+#define RT_TIMING_LINK_TOTAL       20
+
+#define RT_TIMING_LOAD_CHECKS      21
+#define RT_TIMING_LOAD_NDPOOL      22
+#define RT_TIMING_LOAD_CPOOL       23
+#define RT_TIMING_LOAD_SETUP       24
+#define RT_TIMING_LOAD_FIELDS      25
+#define RT_TIMING_LOAD_METHODS     26
+#define RT_TIMING_LOAD_CLASSREFS   27
+#define RT_TIMING_LOAD_DESCS       28
+#define RT_TIMING_LOAD_SETREFS     29
+#define RT_TIMING_LOAD_PARSEFDS    30
+#define RT_TIMING_LOAD_PARSEMDS    31
+#define RT_TIMING_LOAD_PARSECP     32
+#define RT_TIMING_LOAD_VERIFY      33
+#define RT_TIMING_LOAD_ATTRS       34
+#define RT_TIMING_LOAD_TOTAL       35
+
+#define RT_TIMING_LOAD_BOOT_LOOKUP 36
+#define RT_TIMING_LOAD_BOOT_ARRAY  37
+#define RT_TIMING_LOAD_BOOT_SUCK   38
+#define RT_TIMING_LOAD_BOOT_LOAD   39
+#define RT_TIMING_LOAD_BOOT_CACHE  40
+#define RT_TIMING_LOAD_BOOT_TOTAL  41
+
+#define RT_TIMING_LOAD_CL_LOOKUP   42
+#define RT_TIMING_LOAD_CL_PREPARE  43
+#define RT_TIMING_LOAD_CL_JAVA     44
+#define RT_TIMING_LOAD_CL_CACHE    45
+
+#define RT_TIMING_NEW_OBJECT       46
+#define RT_TIMING_NEW_ARRAY        47
+
+#define RT_TIMING_GC_ALLOC         48
+#define RT_TIMING_GC_SUSPEND       49
+#define RT_TIMING_GC_ROOTSET1      50
+#define RT_TIMING_GC_MARK          51
+#define RT_TIMING_GC_COMPACT       52
+#define RT_TIMING_GC_ROOTSET2      53
+#define RT_TIMING_GC_TOTAL         54
+
+#define RT_TIMING_REPLACE          55
+
+#define RT_TIMING_1                56
+#define RT_TIMING_2                57
+#define RT_TIMING_3                58
+#define RT_TIMING_4                59
+
+#define RT_TIMING_N                60
+
+void rt_timing_gettime(struct timespec *ts);
+
+void rt_timing_time_diff(struct timespec *a,struct timespec *b,int index);
+
+long rt_timing_diff_usec(struct timespec *a,struct timespec *b);
+
+void rt_timing_print_time_stats(FILE *file);
+
+#else /* !defined(ENABLE_RT_TIMING) */
+
+#define RT_TIMING_GET_TIME(ts)
+#define RT_TIMING_TIME_DIFF(a,b,index)
+
+#endif /* defined(ENABLE_RT_TIMING) */
+
+#endif /* _RT_TIMING_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 5cdd0ed3ae7bf0327220b860369661b6b98e0b3f..b8b84104b506534b98d761ccdef0e893baf0875d 100644 (file)
 
 #include "arch.h"
 
-#include "threads/thread.h"
+#if defined(ENABLE_GC_BOEHM)
+# include "mm/memory.h"
+#endif
 
-#include "vm/exceptions.h"
-#include "vm/signallocal.h"
-#include "vm/vm.h"
+#include "threads/thread.hpp"
 
-#include "vmcore/options.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/signallocal.h"
+#include "vm/vm.hpp"
 
 #if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
+# include "vm/statistics.h"
 #endif
 
 
@@ -185,7 +190,7 @@ bool signal_init(void)
 #if defined(ENABLE_THREADS)
        /* SIGHUP handler for threads_thread_interrupt */
 
-       signal_register_signal(SIGHUP, (functionptr) signal_handler_sighup, 0);
+       signal_register_signal(Signal_INTERRUPT_SYSTEM_CALL, (functionptr) signal_handler_sighup, 0);
 #endif
 
 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
@@ -246,6 +251,7 @@ static void signal_thread(void)
        threadobject *t;
        sigset_t      mask;
        int           sig;
+       int result;
 
        t = THREADOBJECT;
 
@@ -271,14 +277,14 @@ static void signal_thread(void)
                thread_set_state_waiting(t);
 #endif
 
-               /* XXX We don't check for an error here, although the man-page
-                  states sigwait does not return an error (which is wrong!),
-                  but it seems to make problems with Boehm-GC.  We should
-                  revisit this code with our new exact-GC. */
+               // sigwait can return EINTR (unlike what the Linux man-page
+               // says).
+               do {
+                       result = sigwait(&mask, &sig);
+               } while (result == EINTR);
 
-/*             if (sigwait(&mask, &sig) != 0) */
-/*                     vm_abort_errno("signal_thread: sigwait failed"); */
-               (void) sigwait(&mask, &sig);
+               if (result != 0)
+                       vm_abort_errnum(result, "signal_thread: sigwait failed");
 
 #if defined(ENABLE_THREADS)
                thread_set_state_runnable(t);
@@ -318,6 +324,24 @@ void signal_thread_handler(int sig)
                        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
        }
 }
 
index 7d4e70e38944a5f12f940842618ddd10b22e9be1..799e4bfcb1da6243c18c24d4c891e3e8325c2426 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/signallocal.h - machine independent signal functions
 
-   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.
 
 
 #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);
@@ -65,6 +78,10 @@ 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 */
 
 
diff --git a/src/vm/stackmap.c b/src/vm/stackmap.c
new file mode 100644 (file)
index 0000000..690349c
--- /dev/null
@@ -0,0 +1,519 @@
+/* src/vm/stackmap.c - class attribute StackMapTable
+
+   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 "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/stackmap.h"
+#include "vm/statistics.h"
+#include "vm/suck.h"
+
+
+/* stackmap_get_verification_type_info *****************************************
+
+   union verification_type_info {
+       Top_variable_info;
+          Integer_variable_info;
+          Float_variable_info;
+          Long_variable_info;
+          Double_variable_info;
+          Null_variable_info;
+          UninitializedThis_variable_info;
+          Object_variable_info;
+          Uninitialized_variable_info;
+   }
+
+   Top_variable_info {
+       u1 tag = ITEM_Top;  // 0
+   }
+
+   Integer_variable_info {
+       u1 tag = ITEM_Integer;  // 1
+   }
+
+   Float_variable_info {
+       u1 tag = ITEM_Float;  // 2
+   }
+
+   Long_variable_info {
+       u1 tag = ITEM_Long;  // 4
+   }
+
+   Double_variable_info {
+       u1 tag = ITEM_Double;  // 3
+   }
+
+   Null_variable_info {
+       u1 tag = ITEM_Null;  // 5
+   }
+
+   UninitializedThis_variable_info {
+       u1 tag = ITEM_UninitializedThis;  // 6
+   }
+
+   Object_variable_info {
+       u1 tag = ITEM_Object;  // 7
+          u2 cpool_index;
+   }
+
+   Uninitialized_variable_info {
+       u1 tag = ITEM_Uninitialized;  // 8
+          u2 offset;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_verification_type_info(classbuffer *cb, verification_type_info_t *verification_type_info)
+{
+       /* get verification type */
+
+       if (!suck_check_classbuffer_size(cb, 1))
+               return false;
+
+       verification_type_info->tag = suck_u1(cb);
+
+       /* process the tag */
+
+       switch (verification_type_info->tag) {
+       case ITEM_Top:
+       case ITEM_Integer:
+       case ITEM_Float:
+       case ITEM_Long:
+       case ITEM_Double:
+       case ITEM_Null:
+       case ITEM_UninitializedThis:
+               break;
+
+       case ITEM_Object:
+               /* get constant pool index */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               verification_type_info->Object_variable_info.cpool_index = suck_u2(cb);
+               break;
+
+       case ITEM_Uninitialized:
+               /* get offset */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               verification_type_info->Uninitialized_variable_info.offset = suck_u2(cb);
+               break;
+       }
+
+       return true;
+}
+
+
+/* stackmap_get_same_locals_1_stack_item_frame *********************************
+
+   same_locals_1_stack_item_frame {
+       u1 frame_type = SAME_LOCALS_1_STACK_ITEM;  // 64-127
+          verification_type_info stack[1];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_locals_1_stack_item_frame(classbuffer *cb, stack_map_frame_t *stack_map_frame)
+{
+       same_locals_1_stack_item_frame_t *same_locals_1_stack_item_frame;
+
+       /* for convenience */
+
+       same_locals_1_stack_item_frame =
+               &(stack_map_frame->same_locals_1_stack_item_frame);
+
+       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame->stack[0])))
+               return false;
+
+       return true;
+}
+
+
+/* stackmap_get_same_locals_1_stack_item_frame_extended ************************
+
+   same_locals_1_stack_item_frame_extended {
+       u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED;  // 247
+          u2 offset_delta;
+          verification_type_info stack[1];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_locals_1_stack_item_frame_extended(classbuffer *cb, stack_map_frame_t *stack_map_frame)
+{
+       same_locals_1_stack_item_frame_extended_t *same_locals_1_stack_item_frame_extended;
+
+       /* for convenience */
+
+       same_locals_1_stack_item_frame_extended =
+               &(stack_map_frame->same_locals_1_stack_item_frame_extended);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       same_locals_1_stack_item_frame_extended->offset_delta = suck_u2(cb);
+
+       /* process stack */
+
+       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame_extended->stack[0])))
+               return false;
+
+       return true;
+}
+
+
+/* stackmap_get_chop_frame *****************************************************
+
+   chop_frame {
+       u1 frame_type = CHOP_FRAME;  // 248-250
+          u2 offset_delta;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_chop_frame(classbuffer *cb,
+                                                                       stack_map_frame_t *stack_map_frame)
+{
+       chop_frame_t *chop_frame;
+
+       /* for convenience */
+
+       chop_frame = &(stack_map_frame->chop_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       chop_frame->offset_delta = suck_u2(cb);
+
+       return true;
+}
+
+
+/* stackmap_get_same_frame_extended ********************************************
+
+   same_frame_extended {
+       u1 frame_type = SAME_FRAME_EXTENDED;  // 251
+          u2 offset_delta;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_frame_extended(classbuffer *cb,
+                                                                                        stack_map_frame_t *stack_map_frame)
+{
+       same_frame_extended_t *same_frame_extended;
+
+       /* for convenience */
+
+       same_frame_extended = &(stack_map_frame->same_frame_extended);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       same_frame_extended->offset_delta = suck_u2(cb);
+
+       return true;
+}
+
+
+/* stackmap_get_append_frame ***************************************************
+
+   append_frame {
+       u1 frame_type = APPEND_FRAME;  // 252-254
+          u2 offset_delta;
+          verification_type_info locals[frame_Type - 251];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_append_frame(classbuffer *cb,
+                                                                         stack_map_frame_t *stack_map_frame)
+{
+       append_frame_t *append_frame;
+       s4              number_of_locals;
+       s4              i;
+
+       /* for convenience */
+
+       append_frame = &(stack_map_frame->append_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       append_frame->offset_delta = suck_u2(cb);
+
+       /* allocate locals array */
+
+       number_of_locals = append_frame->frame_type - 251;
+
+       append_frame->locals = DMNEW(verification_type_info_t, number_of_locals);
+
+       /* process all locals */
+
+       for (i = 0; i < number_of_locals; i++)
+               if (!stackmap_get_verification_type_info(cb, &(append_frame->locals[i])))
+                       return false;
+
+       return true;
+}
+
+
+/* stackmap_get_full_frame *****************************************************
+
+   full_frame {
+       u1 frame_type = FULL_FRAME;
+          u2 offset_delta;
+          u2 number_of_locals;
+          verification_type_info locals[number_of_locals];
+          u2 number_of_stack_items;
+          verification_type_info stack[number_of_stack_items];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_full_frame(classbuffer *cb,
+                                                                       stack_map_frame_t *stack_map_frame)
+{
+       full_frame_t *full_frame;
+       s4 i;
+
+       /* for convenience */
+
+       full_frame = &(stack_map_frame->full_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2 + 2))
+               return false;
+
+       /*  get offset delta */
+
+       stack_map_frame->full_frame.offset_delta = suck_u2(cb);
+
+       /* get number of locals */
+
+       full_frame->number_of_locals = suck_u2(cb);
+
+       /* allocate locals array */
+
+       full_frame->locals =
+               DMNEW(verification_type_info_t, full_frame->number_of_locals);
+
+       /* process all locals */
+
+       for (i = 0; i < full_frame->number_of_locals; i++)
+               if (!stackmap_get_verification_type_info(cb, &(full_frame->locals[i])))
+                       return false;
+
+       /* get number of stack items */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       full_frame->number_of_stack_items = suck_u2(cb);
+
+       /* allocate stack array */
+
+       full_frame->stack =
+               DMNEW(verification_type_info_t, full_frame->number_of_stack_items);
+
+       /* process all stack items */
+
+       for (i = 0; i < full_frame->number_of_stack_items; i++)
+               if (!stackmap_get_verification_type_info(cb, &(full_frame->stack[i])))
+                       return false;
+
+       return true;
+}
+
+
+/* stackmap_load_attribute_stackmaptable ***************************************
+
+   stack_map {
+          u2 attribute_name_index;
+          u4 attribute_length;
+          u2 number_of_entries;
+          stack_map_frame entries[number_of_entries];
+   }
+
+   union stack_map_frame {
+       same_frame;
+          same_locals_1_stack_item_frame;
+          same_locals_1_stack_item_frame_extended;
+          chop_frame;
+          same_frame_extended;
+          append_frame;
+          full_frame;
+   }
+
+   same_frame {
+       u1 frame_type = SAME;  // 0-63
+   }
+
+*******************************************************************************/
+
+bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m)
+{
+       classinfo       *c;
+       stack_map_t     *stack_map;
+       s4               i;
+       u1               frame_type;
+
+       /* get classinfo */
+
+       c = cb->clazz;
+
+       /* allocate stack map structure */
+
+       stack_map = DNEW(stack_map_t);
+
+       STATISTICS(size_stack_map += sizeof(stack_map_t));
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* attribute_length */
+
+       stack_map->attribute_length = suck_u4(cb);
+
+       if (!suck_check_classbuffer_size(cb, stack_map->attribute_length))
+               return false;
+
+       /* get number of entries */
+
+       stack_map->number_of_entries = suck_u2(cb);
+
+       /* process all entries */
+
+       stack_map->entries = DMNEW(stack_map_frame_t, stack_map->number_of_entries);
+
+       for (i = 0; i < stack_map->number_of_entries; i++) {
+               /* get the frame type */
+
+               frame_type = suck_u1(cb);
+
+               stack_map->entries[i].frame_type = frame_type;
+
+               /* process frame */
+
+               if (frame_type <= FRAME_TYPE_SAME) {
+                       /* same_frame */
+               }
+               else if (frame_type <= FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM) {
+                       /* same_locals_1_stack_item_frame */
+
+                       if (!stackmap_get_same_locals_1_stack_item_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_RESERVED) {
+                       /* reserved */
+
+                       exceptions_throw_classformaterror(c, "reserved frame type");
+                       return false;
+               }
+               else if (frame_type == FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
+                       /* same_locals_1_stack_item_frame_extended */
+
+                       if (!stackmap_get_same_locals_1_stack_item_frame_extended(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_CHOP) {
+                       /* chop_frame */
+
+                       if (!stackmap_get_chop_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type == FRAME_TYPE_SAME_FRAME_EXTENDED) {
+                       /* same_frame_extended */
+
+                       if (!stackmap_get_same_frame_extended(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_APPEND) {
+                       /* append_frame */
+
+                       if (!stackmap_get_append_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type == FRAME_TYPE_FULL_FRAME) {
+                       /* full_frame */
+
+                       if (!stackmap_get_full_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+       }
+
+       /* store stack map in method structure */
+
+#if 0
+       /* currently not used */
+
+       m->stack_map = stack_map;
+#endif
+
+       return true;
+}
+
+
+/*
+ * 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/stackmap.h b/src/vm/stackmap.h
new file mode 100644 (file)
index 0000000..e2c6b93
--- /dev/null
@@ -0,0 +1,229 @@
+/* src/vm/stackmap.h - class attribute StackMapTable
+
+   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 _STACKMAP_H
+#define _STACKMAP_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct stack_map_t                       stack_map_t;
+typedef union  stack_map_frame_t                 stack_map_frame_t;
+typedef struct same_locals_1_stack_item_frame_t  same_locals_1_stack_item_frame_t;
+typedef struct same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended_t;
+typedef struct chop_frame_t                      chop_frame_t;
+typedef struct same_frame_extended_t             same_frame_extended_t;
+typedef struct append_frame_t                    append_frame_t;
+typedef struct full_frame_t                      full_frame_t;
+
+typedef union  verification_type_info_t          verification_type_info_t;
+typedef struct Top_variable_info_t                  Top_variable_info_t;
+typedef struct Integer_variable_info_t           Integer_variable_info_t;
+typedef struct Float_variable_info_t             Float_variable_info_t;
+typedef struct Long_variable_info_t              Long_variable_info_t;
+typedef struct Double_variable_info_t            Double_variable_info_t;
+typedef struct Null_variable_info_t              Null_variable_info_t;
+typedef struct UninitializedThis_variable_info_t UninitializedThis_variable_info_t;
+typedef struct Object_variable_info_t            Object_variable_info_t;
+typedef struct Uninitialized_variable_info_t     Uninitialized_variable_info_t;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+
+
+/* verification_type_info *****************************************************/
+
+#define ITEM_Top                  0
+#define ITEM_Integer              1
+#define ITEM_Float                2
+#define ITEM_Double               3
+#define ITEM_Long                 4
+#define ITEM_Null                 5
+#define ITEM_UninitializedThis    6
+#define ITEM_Object               7
+#define ITEM_Uninitialized        8
+
+struct Top_variable_info_t {
+       u1 tag;
+};
+
+struct Integer_variable_info_t {
+       u1 tag;
+};
+
+struct Float_variable_info_t {
+       u1 tag;
+};
+
+struct Long_variable_info_t {
+       u1 tag;
+};
+
+struct Double_variable_info_t {
+       u1 tag;
+};
+
+struct Null_variable_info_t {
+       u1 tag;
+};
+
+struct UninitializedThis_variable_info_t {
+       u1 tag;
+};
+
+struct Object_variable_info_t {
+       u1 tag;
+       u2 cpool_index;
+};
+
+struct Uninitialized_variable_info_t {
+       u1 tag;
+       u2 offset;
+};
+
+union verification_type_info_t {
+       u1 tag;
+       Top_variable_info_t                   Top_variable_info;
+       Integer_variable_info_t           Integer_variable_info;
+       Float_variable_info_t             Float_variable_info;
+       Long_variable_info_t              Long_variable_info;
+       Double_variable_info_t            Double_variable_info;
+       Null_variable_info_t              Null_variable_info;
+       UninitializedThis_variable_info_t UninitializedThis_variable_info;
+       Object_variable_info_t            Object_variable_info;
+       Uninitialized_variable_info_t     Uninitialized_variable_info;
+};
+
+
+/* stack_map_t ****************************************************************/
+
+struct stack_map_t {
+       u2                 attribute_name_index;
+       u4                 attribute_length;
+       u2                 number_of_entries;
+       stack_map_frame_t *entries;
+};
+
+
+/* same_locals_1_stack_item_frame_t *******************************************/
+
+struct same_locals_1_stack_item_frame_t {
+       u1                       frame_type;
+       verification_type_info_t stack[1];
+};
+
+
+/* same_locals_1_stack_item_frame_extended_t **********************************/
+
+struct same_locals_1_stack_item_frame_extended_t {
+       u1                       frame_type;
+       u2                       offset_delta;
+       verification_type_info_t stack[1];
+};
+
+
+/* chop_frame_t ***************************************************************/
+
+struct chop_frame_t {
+       u1 frame_type;
+       u2 offset_delta;
+};
+
+
+/* same_frame_extended_t ******************************************************/
+
+struct same_frame_extended_t {
+       u1 frame_type;
+       u2 offset_delta;
+};
+
+
+/* append_frame_t *************************************************************/
+
+struct append_frame_t {
+       u1                        frame_type;
+       u2                        offset_delta;
+       verification_type_info_t *locals;
+};
+
+
+/* full_frame_t ***************************************************************/
+
+struct full_frame_t {
+       u1                        frame_type;
+       u2                        offset_delta;
+       u2                        number_of_locals;
+       verification_type_info_t *locals;
+       u2                        number_of_stack_items;
+       verification_type_info_t *stack;
+};
+
+
+/* stack_map_frame_t **********************************************************/
+
+#define FRAME_TYPE_SAME                                 63   /* 0-63          */
+#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM             127  /* 0-127         */
+#define FRAME_TYPE_RESERVED                             246  /* 128-246       */
+#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED    247  /* 247           */
+#define FRAME_TYPE_CHOP                                 250  /* 248-250       */
+#define FRAME_TYPE_SAME_FRAME_EXTENDED                  251  /* 251           */
+#define FRAME_TYPE_APPEND                               254  /* 252-254       */
+#define FRAME_TYPE_FULL_FRAME                           255  /* 255           */
+
+union stack_map_frame_t {
+       u1                                        frame_type;
+       same_locals_1_stack_item_frame_t          same_locals_1_stack_item_frame;
+       same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended;
+       chop_frame_t                              chop_frame;
+       same_frame_extended_t                     same_frame_extended;
+       append_frame_t                            append_frame;
+       full_frame_t                              full_frame;
+};
+
+
+/* function prototypes ********************************************************/
+
+bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m);
+
+#endif /* _STACKMAP_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/statistics.c b/src/vm/statistics.c
new file mode 100644 (file)
index 0000000..37d1946
--- /dev/null
@@ -0,0 +1,822 @@
+/* src/vm/statistics.c - global variables for statistics
+
+   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 <stdint.h>
+#include <string.h> 
+
+#if defined(HAVE_TIME_H)
+# include <time.h>
+#endif
+
+#if defined(HAVE_SYS_TIME_H)
+# include <sys/time.h>
+#endif
+
+#if defined(HAVE_SYS_RESOURCE_H)
+# include <sys/resource.h>
+#endif
+
+#include "vm/types.h"
+
+#include "mm/gc.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/class.h"
+#include "vm/field.h"
+#include "vm/global.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
+
+#include "vm/jit/code.h"
+
+
+/* global variables ***********************************************************/
+
+static s8 loadingtime = 0;              /* accumulated loading time           */
+static s8 loadingstarttime = 0;
+static s8 loadingstoptime = 0;
+static s4 loadingtime_recursion = 0;
+
+static s8 compilingtime = 0;            /* accumulated compile time           */
+static s8 compilingstarttime = 0;
+static s8 compilingstoptime = 0;
+static s4 compilingtime_recursion = 0;
+
+s4 codememusage = 0;
+s4 maxcodememusage = 0;
+
+s4 memoryusage = 0;
+s4 maxmemusage = 0;
+
+s4 maxdumpsize = 0;
+
+s4 globalallocateddumpsize = 0;
+s4 globaluseddumpsize = 0;
+
+
+/* variables for measurements *************************************************/
+
+s4 size_classinfo        = 0;
+s4 size_fieldinfo        = 0;
+s4 size_methodinfo       = 0;
+s4 size_lineinfo         = 0;
+s4 size_codeinfo         = 0;
+
+s4 size_stub_native      = 0;
+
+s4 size_stack_map        = 0;
+s4 size_string           = 0;
+
+s4 size_threadobject     = 0;
+int32_t size_thread_index_t = 0;
+int32_t size_stacksize      = 0;
+
+s4 size_lock_record      = 0;
+s4 size_lock_hashtable   = 0;
+s4 size_lock_waiter      = 0;
+
+int32_t count_linenumbertable = 0;
+int32_t size_linenumbertable  = 0;
+
+s4 size_patchref         = 0;
+
+s4 size_cachedref           = 0;
+
+u8 count_calls_java_to_native = 0;
+u8 count_calls_native_to_java = 0;
+
+int count_const_pool_len = 0;
+int count_classref_len = 0;
+int count_parsed_desc_len = 0;
+int count_vftbl_len = 0;
+int count_all_methods = 0;
+int count_methods_marked_used = 0;  /* RTA */
+
+int count_vmcode_len = 0;
+int count_extable_len = 0;
+int count_class_loads = 0;
+int count_class_inits = 0;
+
+int count_utf_len = 0;                  /* size of utf hash                   */
+int count_utf_new = 0;                  /* calls of utf_new                   */
+int count_utf_new_found  = 0;           /* calls of utf_new with fast return  */
+
+int count_locals_conflicts = 0;         /* register allocator statistics */
+int count_locals_spilled = 0;
+int count_locals_register = 0;
+int count_ss_spilled = 0;
+int count_ss_register = 0;
+int count_methods_allocated_by_lsra = 0;
+int count_mem_move_bb = 0;
+int count_interface_size = 0;
+int count_argument_mem_ss = 0;
+int count_argument_reg_ss = 0;
+int count_method_in_register = 0;
+int count_mov_reg_reg = 0;
+int count_mov_mem_reg = 0;
+int count_mov_reg_mem = 0;
+int count_mov_mem_mem = 0;
+
+int count_jit_calls = 0;
+int count_methods = 0;
+int count_spills_read_ila = 0;
+int count_spills_read_flt = 0;
+int count_spills_read_dbl = 0;
+int count_spills_write_ila = 0;
+int count_spills_write_flt = 0;
+int count_spills_write_dbl = 0;
+int count_pcmd_activ = 0;
+int count_pcmd_drop = 0;
+int count_pcmd_zero = 0;
+int count_pcmd_const_store = 0;
+int count_pcmd_const_alu = 0;
+int count_pcmd_const_bra = 0;
+int count_pcmd_load = 0;
+int count_pcmd_move = 0;
+int count_load_instruction = 0;
+int count_pcmd_store = 0;
+int count_pcmd_store_comb = 0;
+int count_dup_instruction = 0;
+int count_pcmd_op = 0;
+int count_pcmd_mem = 0;
+int count_pcmd_met = 0;
+int count_pcmd_bra = 0;
+int count_pcmd_table = 0;
+int count_pcmd_return = 0;
+int count_pcmd_returnx = 0;
+int count_check_null = 0;
+int count_check_bound = 0;
+int count_max_basic_blocks = 0;
+int count_basic_blocks = 0;
+int count_javainstr = 0;
+int count_max_javainstr = 0;
+int count_javacodesize = 0;
+int count_javaexcsize = 0;
+int count_calls = 0;
+int count_tryblocks = 0;
+int count_code_len = 0;
+int count_data_len = 0;
+int count_cstub_len = 0;
+int count_max_new_stack = 0;
+int count_upper_bound_new_stack = 0;
+
+int count_emit_branch = 0;
+int count_emit_branch_8bit = 0;
+int count_emit_branch_16bit = 0;
+int count_emit_branch_32bit = 0;
+int count_emit_branch_64bit = 0;
+
+s4 count_branches_resolved   = 0;
+s4 count_branches_unresolved = 0;
+
+u8 count_jni_callXmethod_calls=0;
+u8 count_jni_calls=0;
+
+
+static int count_block_stack_init[11] = {
+       0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 
+       0
+};
+int *count_block_stack = count_block_stack_init;
+static int count_analyse_iterations_init[5] = {
+       0, 0, 0, 0, 0
+};
+int *count_analyse_iterations = count_analyse_iterations_init;
+static int count_method_bb_distribution_init[9] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0
+};
+int *count_method_bb_distribution = count_method_bb_distribution_init;
+static int count_block_size_distribution_init[18] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0
+};
+int *count_block_size_distribution = count_block_size_distribution_init;
+static int count_store_length_init[21] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0
+};
+int *count_store_length = count_store_length_init;
+static int count_store_depth_init[11] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0
+};
+int *count_store_depth = count_store_depth_init;
+
+
+/* instruction scheduler statistics *******************************************/
+
+s4 count_schedule_basic_blocks = 0;
+s4 count_schedule_nodes = 0;
+s4 count_schedule_leaders = 0;
+s4 count_schedule_max_leaders = 0;
+s4 count_schedule_critical_path = 0;
+
+
+/* jnicallXmethodinvokation ***************************************************
+
+   increments the jni CallXMethod invokation count by one
+       
+*******************************************************************************/
+
+void jnicallXmethodnvokation(void)
+{
+       /* XXX do locking here */
+       count_jni_callXmethod_calls++;
+}
+
+
+/* jniinvokation *************************************************************
+
+   increments the jni overall  invokation count by one
+       
+*******************************************************************************/
+
+void jniinvokation(void)
+{
+       /* XXX do locking here */
+       count_jni_calls++;
+}
+
+
+/* getcputime *********************************** ******************************
+
+   Returns the used CPU time in microseconds
+       
+*******************************************************************************/
+
+s8 getcputime(void)
+{
+#if defined(HAVE_GETRUSAGE)
+       struct rusage ru;
+       int sec, usec;
+
+       getrusage(RUSAGE_SELF, &ru);
+
+       sec  = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
+       usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec;
+
+       return sec * 1000000 + usec;
+#else
+       /* If we don't have getrusage, simply return 0. */
+
+       return 0;
+#endif
+}
+
+
+/* loadingtime_stop ************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void loadingtime_start(void)
+{
+       loadingtime_recursion++;
+
+       if (loadingtime_recursion == 1)
+               loadingstarttime = getcputime();
+}
+
+
+/* loadingtime_stop ************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void loadingtime_stop(void)
+{
+       if (loadingtime_recursion == 1) {
+               loadingstoptime = getcputime();
+               loadingtime += (loadingstoptime - loadingstarttime);
+       }
+
+       loadingtime_recursion--;
+}
+
+
+/* compilingtime_stop **********************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void compilingtime_start(void)
+{
+       compilingtime_recursion++;
+
+       if (compilingtime_recursion == 1)
+               compilingstarttime = getcputime();
+}
+
+
+/* compilingtime_stop **********************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void compilingtime_stop(void)
+{
+       if (compilingtime_recursion == 1) {
+               compilingstoptime = getcputime();
+               compilingtime += (compilingstoptime - compilingstarttime);
+       }
+
+       compilingtime_recursion--;
+}
+
+
+/* print_times *****************************************************************
+
+   Prints a summary of CPU time usage.
+
+*******************************************************************************/
+
+void print_times(void)
+{
+       s8 totaltime;
+       s8 runtime;
+
+       totaltime = getcputime();
+       runtime = totaltime - loadingtime - compilingtime;
+
+#if SIZEOF_VOID_P == 8
+       dolog("Time for loading classes: %6ld ms", loadingtime / 1000);
+       dolog("Time for compiling code:  %6ld ms", compilingtime / 1000);
+       dolog("Time for running program: %6ld ms", runtime / 1000);
+       dolog("Total time:               %6ld ms", totaltime / 1000);
+#else
+       dolog("Time for loading classes: %6lld ms", loadingtime / 1000);
+       dolog("Time for compiling code:  %6lld ms", compilingtime / 1000);
+       dolog("Time for running program: %6lld ms", runtime / 1000);
+       dolog("Total time:               %6lld ms", totaltime / 1000);
+#endif
+}
+
+
+/* print_stats *****************************************************************
+
+   outputs detailed compiler statistics
+
+*******************************************************************************/
+
+void print_stats(void)
+{
+       s4    i;
+       float f;
+       s4    sum;
+
+
+       dolog("Number of JIT compiler calls: %6d", count_jit_calls);
+       dolog("Number of compiled methods:   %6d", count_methods);
+
+       dolog("Number of compiled basic blocks:               %6d",
+                 count_basic_blocks);
+       dolog("Number of max. basic blocks per method:        %6d",
+                 count_max_basic_blocks);
+
+       dolog("Number of compiled JavaVM instructions:        %6d",
+                 count_javainstr);
+       dolog("Number of max. JavaVM instructions per method: %6d",
+                 count_max_javainstr);
+       dolog("Size of compiled JavaVM instructions:          %6d(%d)",
+                 count_javacodesize, count_javacodesize - count_methods * 18);
+
+       dolog("Size of compiled Exception Tables:      %d", count_javaexcsize);
+       dolog("Number of Machine-Instructions: %d", count_code_len >> 2);
+       dolog("Number of Spills (write to memory) <all [i/l/a|flt|dbl]>: %d [%d|%d|%d]",
+               count_spills_write_ila + count_spills_write_flt + count_spills_write_dbl,
+               count_spills_write_ila, count_spills_write_flt, count_spills_write_dbl);
+       dolog("Number of Spills (read from memory) <all [i/l/a|flt|dbl]>: %d [%d|%d|%d]",
+               count_spills_read_ila + count_spills_read_flt + count_spills_read_dbl,
+               count_spills_read_ila, count_spills_read_flt, count_spills_read_dbl);
+       dolog("Number of Activ    Pseudocommands: %6d", count_pcmd_activ);
+       dolog("Number of Drop     Pseudocommands: %6d", count_pcmd_drop);
+       dolog("Number of Const    Pseudocommands: %6d (zero:%5d)",
+                 count_pcmd_load, count_pcmd_zero);
+       dolog("Number of ConstAlu Pseudocommands: %6d (cmp: %5d, store:%5d)",
+                 count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
+       dolog("Number of Move     Pseudocommands: %6d", count_pcmd_move);
+       dolog("Number of Load     Pseudocommands: %6d", count_load_instruction);
+       dolog("Number of Store    Pseudocommands: %6d (combined: %5d)",
+                 count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
+       dolog("Number of OP       Pseudocommands: %6d", count_pcmd_op);
+       dolog("Number of DUP      Pseudocommands: %6d", count_dup_instruction);
+       dolog("Number of Mem      Pseudocommands: %6d", count_pcmd_mem);
+       dolog("Number of Method   Pseudocommands: %6d", count_pcmd_met);
+       dolog("Number of Branch   Pseudocommands: %6d (rets:%5d, Xrets: %5d)",
+                 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
+       log_println("                resolved branches: %6d", count_branches_resolved);
+       log_println("              unresolved branches: %6d", count_branches_unresolved);
+       dolog("Number of Table    Pseudocommands: %6d", count_pcmd_table);
+       dolog("Number of Useful   Pseudocommands: %6d", count_pcmd_table +
+                 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
+       dolog("Number of Null Pointer Checks:     %6d", count_check_null);
+       dolog("Number of Array Bound Checks:      %6d", count_check_bound);
+       dolog("Number of Try-Blocks: %d", count_tryblocks);
+
+       dolog("Number of branch_emit (total, 8bit/16bit/32bit/64bit offset): %d, %d/%d/%d/%d",
+               count_emit_branch,  count_emit_branch_8bit,  count_emit_branch_16bit, 
+                                                       count_emit_branch_32bit, count_emit_branch_64bit);
+
+       dolog("Maximal count of stack elements:   %d", count_max_new_stack);
+       dolog("Upper bound of max stack elements: %d", count_upper_bound_new_stack);
+       dolog("Distribution of stack sizes at block boundary");
+       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_block_stack[0], count_block_stack[1], count_block_stack[2],
+                 count_block_stack[3], count_block_stack[4], count_block_stack[5],
+                 count_block_stack[6], count_block_stack[7], count_block_stack[8],
+                 count_block_stack[9], count_block_stack[10]);
+       dolog("Distribution of store stack depth");
+       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_depth[0], count_store_depth[1], count_store_depth[2],
+                 count_store_depth[3], count_store_depth[4], count_store_depth[5],
+                 count_store_depth[6], count_store_depth[7], count_store_depth[8],
+                 count_store_depth[9], count_store_depth[10]);
+       dolog("Distribution of store creator chains first part");
+       dolog("     0     1     2     3     4     5     6     7     8     9");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_length[0], count_store_length[1], count_store_length[2],
+                 count_store_length[3], count_store_length[4], count_store_length[5],
+                 count_store_length[6], count_store_length[7], count_store_length[8],
+                 count_store_length[9]);
+       dolog("Distribution of store creator chains second part");
+       dolog("    10    11    12    13    14    15    16    17    18    19  >=20");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_length[10], count_store_length[11],
+                 count_store_length[12], count_store_length[13],
+                 count_store_length[14], count_store_length[15],
+                 count_store_length[16], count_store_length[17],
+                 count_store_length[18], count_store_length[19],
+                 count_store_length[20]);
+       dolog("Distribution of analysis iterations");
+       dolog("     1     2     3     4   >=5");
+       dolog("%6d%6d%6d%6d%6d",
+                 count_analyse_iterations[0], count_analyse_iterations[1],
+                 count_analyse_iterations[2], count_analyse_iterations[3],
+                 count_analyse_iterations[4]);
+
+
+       /* Distribution of basic blocks per method ********************************/
+
+       log_println("Distribution of basic blocks per method:");
+       log_println("   <=5  <=10  <=15  <=20  <=30  <=40  <=50  <=75   >75");
+
+       log_start();
+       for (i = 0; i <= 8; i++)
+               log_print("%6d", count_method_bb_distribution[i]);
+       log_finish();
+
+       /* print ratio */
+
+       f = (float) count_methods;
+
+       log_start();
+       for (i = 0; i <= 8; i++)
+               log_print("%6.2f", (float) count_method_bb_distribution[i] / f);
+       log_finish();
+
+       /* print cumulated ratio */
+
+       log_start();
+       for (i = 0, sum = 0; i <= 8; i++) {
+               sum += count_method_bb_distribution[i];
+               log_print("%6.2f", (float) sum / f);
+       }
+       log_finish();
+
+
+       /* Distribution of basic block sizes **************************************/
+
+       log_println("Distribution of basic block sizes:");
+       log_println("     0     1     2     3     4     5     6     7     8     9   <13   <15   <17   <19   <21   <26   <31   >30");
+
+       /* print block sizes */
+
+       log_start();
+       for (i = 0; i <= 17; i++)
+               log_print("%6d", count_block_size_distribution[i]);
+       log_finish();
+
+       /* print ratio */
+
+       f = (float) count_basic_blocks;
+
+       log_start();
+       for (i = 0; i <= 17; i++)
+               log_print("%6.2f", (float) count_block_size_distribution[i] / f);
+       log_finish();
+
+       /* print cumulated ratio */
+
+       log_start();
+       for (i = 0, sum = 0; i <= 17; i++) {
+               sum += count_block_size_distribution[i];
+               log_print("%6.2f", (float) sum / f);
+       }
+       log_finish();
+
+       statistics_print_memory_usage();
+
+       dolog("Number of class loads:    %6d", count_class_loads);
+       dolog("Number of class inits:    %6d", count_class_inits);
+       dolog("Number of loaded Methods: %6d\n", count_all_methods);
+
+       dolog("Calls of utf_new:                 %6d", count_utf_new);
+       dolog("Calls of utf_new (element found): %6d\n", count_utf_new_found);
+
+
+       /* LSRA statistics ********************************************************/
+
+       dolog("Moves reg -> reg:     %6d", count_mov_reg_reg);
+       dolog("Moves mem -> reg:     %6d", count_mov_mem_reg);
+       dolog("Moves reg -> mem:     %6d", count_mov_reg_mem);
+       dolog("Moves mem -> mem:     %6d", count_mov_mem_mem);
+
+       dolog("Methods allocated by LSRA:         %6d",
+                 count_methods_allocated_by_lsra);
+       dolog("Conflicts between local Variables: %6d", count_locals_conflicts);
+       dolog("Local Variables held in Memory:    %6d", count_locals_spilled);
+       dolog("Local Variables held in Registers: %6d", count_locals_register);
+       dolog("Stackslots held in Memory:         %6d", count_ss_spilled);
+       dolog("Stackslots held in Registers:      %6d", count_ss_register);
+       dolog("Memory moves at BB Boundaries:     %6d", count_mem_move_bb);
+       dolog("Number of interface slots:         %6d\n", count_interface_size);
+       dolog("Number of Argument stack slots in register:  %6d",
+                 count_argument_reg_ss);
+       dolog("Number of Argument stack slots in memory:    %6d\n",
+                 count_argument_mem_ss);
+       dolog("Number of Methods kept in registers:         %6d\n",
+                 count_method_in_register);
+
+
+       /* instruction scheduler statistics ***************************************/
+
+#if defined(USE_SCHEDULER)
+       dolog("Instruction scheduler statistics:");
+       dolog("Number of basic blocks:       %7d", count_schedule_basic_blocks);
+       dolog("Number of nodes:              %7d", count_schedule_nodes);
+       dolog("Number of leaders nodes:      %7d", count_schedule_leaders);
+       dolog("Number of max. leaders nodes: %7d", count_schedule_max_leaders);
+       dolog("Length of critical path:      %7d\n", count_schedule_critical_path);
+#endif
+
+
+       /* call statistics ********************************************************/
+
+       dolog("Function call statistics:");
+       dolog("Number of jni->CallXMethod function invokations: %ld",
+                 count_jni_callXmethod_calls);
+       dolog("Overall number of jni invokations:               %ld",
+                 count_jni_calls);
+
+       log_println("java-to-native calls:   %10ld", count_calls_java_to_native);
+       log_println("native-to-java calls:   %10ld", count_calls_native_to_java);
+
+
+       /* now print other statistics ********************************************/
+
+#if defined(ENABLE_INTRP)
+       print_dynamic_super_statistics();
+#endif
+}
+
+
+/* statistics_print_date *******************************************************
+
+   Print current date and time.
+
+*******************************************************************************/
+
+void statistics_print_date(void)
+{
+  time_t t;
+  struct tm tm;
+
+#if defined(HAVE_TIME)
+  time(&t);
+#else
+# error !HAVE_TIME
+#endif
+
+#if defined(HAVE_LOCALTIME_R)
+  localtime_r(&t, &tm);
+#else
+# error !HAVE_LOCALTIME_R
+#endif
+
+  log_println("%d-%02d-%02d %02d:%02d:%02d",
+                         1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
+                         tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
+
+
+/* statistics_print_memory_usage ***********************************************
+
+   Print current memory usage.
+
+*******************************************************************************/
+
+void statistics_print_memory_usage(void)
+{
+       s4 sum;
+
+       log_println("memory usage ----------------------");
+       log_println("");
+       log_println("code:                      %10d", count_code_len);
+       log_println("data:                      %10d", count_data_len);
+       log_println("                            ----------");
+
+       sum =
+               count_code_len +
+               count_data_len;
+
+       log_println("                           %10d", sum);
+
+       log_println("");
+
+       log_println("classinfo  (%3d B):        %10d", (int) sizeof(classinfo), size_classinfo);
+       log_println("fieldinfo  (%3d B):        %10d", (int) sizeof(fieldinfo), size_fieldinfo);
+       log_println("methodinfo (%3d B):        %10d", (int) sizeof(methodinfo), size_methodinfo);
+       log_println("lineinfo   (%3d B):        %10d", (int) sizeof(lineinfo), size_lineinfo);
+       log_println("codeinfo   (%3d B):        %10d", (int) sizeof(codeinfo), size_codeinfo);
+       log_println("                            ----------");
+
+       sum =
+               size_classinfo +
+               size_fieldinfo +
+               size_methodinfo +
+               size_lineinfo +
+               size_codeinfo;
+
+       log_println("                           %10d", sum);
+
+       log_println("");
+
+       log_println("linenumber tables (%5d): %10d", count_linenumbertable, size_linenumbertable);
+       log_println("exception tables:          %10d", count_extable_len);
+       log_println("patcher references:        %10d", size_patchref);
+       log_println("cached references:         %10d", size_cachedref);
+       log_println("                            ----------");
+
+       sum =
+               size_linenumbertable +
+               count_extable_len +
+               size_patchref +
+               size_cachedref;
+
+       log_println("                           %10d", sum);
+
+       log_println("");
+
+       log_println("constant pool:             %10d", count_const_pool_len);
+       log_println("classref:                  %10d", count_classref_len);
+       log_println("parsed descriptors:        %10d", count_parsed_desc_len);
+       log_println("vftbl:                     %10d", count_vftbl_len);
+       log_println("compiler stubs:            %10d", count_cstub_len);
+       log_println("native stubs:              %10d", size_stub_native);
+       log_println("utf:                       %10d", count_utf_len);
+       log_println("vmcode:                    %10d", count_vmcode_len);
+       log_println("stack map:                 %10d", size_stack_map);
+       log_println("string:                    %10d", size_string);
+       log_println("threadobject:              %10d", size_threadobject);
+       log_println("thread index:              %10d", size_thread_index_t);
+       log_println("stack size:                %10d", size_stacksize);
+       log_println("lock record:               %10d", size_lock_record);
+       log_println("lock hashtable:            %10d", size_lock_hashtable);
+       log_println("lock waiter:               %10d", size_lock_waiter);
+       log_println("                            ----------");
+
+       sum =
+               count_const_pool_len +
+               count_classref_len +
+               count_parsed_desc_len + 
+               count_vftbl_len +
+               count_cstub_len +
+               size_stub_native +
+               count_utf_len +
+               count_vmcode_len +
+               size_stack_map +
+               size_string +
+               size_threadobject +
+               size_thread_index_t +
+               size_stacksize +
+               size_lock_record +
+               size_lock_hashtable +
+               size_lock_waiter;
+
+       log_println("                           %10d", sum);
+
+       log_println("");
+
+       log_println("max. code memory:          %10d", maxcodememusage);
+       log_println("max. heap memory:          %10d", maxmemusage);
+       log_println("max. dump memory:          %10d", maxdumpsize);
+       log_println("");
+       log_println("heap memory not freed:     %10d", (int32_t) memoryusage);
+       log_println("dump memory not freed:     %10d", (int32_t) globalallocateddumpsize);
+
+       log_println("");
+}
+
+
+/* statistics_print_gc_memory_usage ********************************************
+
+   Print current GC memory usage.
+
+*******************************************************************************/
+
+void statistics_print_gc_memory_usage(void)
+{
+       static int64_t count = 0;
+       int64_t max;
+       int64_t size;
+       int64_t free;
+       int64_t used;
+       int64_t total;
+
+       count++;
+
+       max   = gc_get_max_heap_size();
+       size  = gc_get_heap_size();
+       free  = gc_get_free_bytes();
+       used  = size - free;
+       total = gc_get_total_bytes();
+
+       if (opt_ProfileMemoryUsageGNUPlot) {
+               if (count == 1)
+                       fprintf(opt_ProfileMemoryUsageGNUPlot, "plot \"profile.dat\" using 1:2 with lines title \"max. Java heap size\", \"profile.dat\" using 1:3 with lines title \"Java heap size\", \"profile.dat\" using 1:4 with lines title \"used\", \"profile.dat\" using 1:5 with lines title \"free\"\n");
+
+#if SIZEOF_VOID_P == 8
+               fprintf(opt_ProfileMemoryUsageGNUPlot, "%ld %ld %ld %ld %ld\n", count, max, size, used, free);
+#else
+               fprintf(opt_ProfileMemoryUsageGNUPlot, "%lld %lld %lld %lld %lld\n", count, max, size, used, free);
+#endif
+
+               fflush(opt_ProfileMemoryUsageGNUPlot);
+       }
+       else {
+               log_println("GC memory usage -------------------");
+               log_println("");
+               log_println("max. Java heap size: %10lld", max);
+               log_println("");
+               log_println("Java heap size:      %10lld", size);
+               log_println("used:                %10lld", used);
+               log_println("free:                %10lld", free);
+               log_println("totally used:        %10lld", total);
+               log_println("");
+       }
+}
+
+
+/*
+ * 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/statistics.h b/src/vm/statistics.h
new file mode 100644 (file)
index 0000000..46bebed
--- /dev/null
@@ -0,0 +1,268 @@
+/* src/vm/statistics.h - exports global varables for statistics
+
+   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 _STATISTICS_H
+#define _STATISTICS_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+
+/* statistic macros ***********************************************************/
+
+#if defined(ENABLE_STATISTICS)
+#define STATISTICS(x) \
+    do { \
+        if (opt_stat) { \
+            x; \
+        } \
+    } while (0)
+#else
+#define STATISTICS(x)    /* nothing */
+#endif
+
+/* in_  inline statistics */
+
+#define IN_MAX                  9
+#define IN_UNIQUEVIRT           0x0000 
+#define IN_UNIQUE_INTERFACE     0x0001
+#define IN_OUTSIDERS            0x0004
+#define IN_MAXDEPTH             0x0008
+#define IN_MAXCODE              0x0010
+#define IN_JCODELENGTH          0x0020
+#define IN_EXCEPTION            0x0040
+#define IN_NOT_UNIQUE_VIRT      0x0080
+#define IN_NOT_UNIQUE_INTERFACE 0x0100
+
+#define N_UNIQUEVIRT            0
+#define N_UNIQUE_INTERFACE      1
+#define N_OUTSIDERS             2
+#define N_MAXDEPTH             3       
+#define N_MAXCODE               4 
+#define N_JCODELENGTH           5 
+#define N_EXCEPTION            6 
+#define N_NOT_UNIQUE_VIRT       7 
+#define N_NOT_UNIQUE_INTERFACE  8 
+
+
+/* global variables ***********************************************************/
+
+extern s4 codememusage;
+extern s4 maxcodememusage;
+
+extern s4 memoryusage;
+extern s4 maxmemusage;
+
+extern s4 maxdumpsize;
+
+extern s4 globalallocateddumpsize;
+extern s4 globaluseddumpsize;
+
+
+/* variables for measurements *************************************************/
+
+extern s4 size_classinfo;
+extern s4 size_fieldinfo;
+extern s4 size_methodinfo;
+extern s4 size_lineinfo;
+extern s4 size_codeinfo;
+
+extern s4 size_stub_native;
+
+extern s4 size_stack_map;
+extern s4 size_string;
+
+extern s4 size_threadobject;
+extern int32_t size_thread_index_t;
+extern int32_t size_stacksize;
+
+extern s4 size_lock_record;
+extern s4 size_lock_hashtable;
+extern s4 size_lock_waiter;
+
+extern int32_t count_linenumbertable;
+extern int32_t size_linenumbertable;
+
+extern s4 size_patchref;
+
+extern s4 size_cachedref;
+
+extern u8 count_calls_java_to_native;
+extern u8 count_calls_native_to_java;
+
+extern int count_const_pool_len;
+extern int count_classref_len;
+extern int count_parsed_desc_len;
+extern int count_vftbl_len;
+extern int count_all_methods;
+extern int count_methods_marked_used;  /*RTA*/
+extern int count_vmcode_len;
+extern int count_extable_len;
+extern int count_class_loads;
+extern int count_class_inits;
+
+extern int count_utf_len;               /* size of utf hash                   */
+extern int count_utf_new;
+extern int count_utf_new_found;
+
+extern int count_locals_conflicts;
+extern int count_locals_spilled;
+extern int count_locals_register;
+extern int count_ss_spilled;
+extern int count_ss_register;
+extern int count_methods_allocated_by_lsra;
+extern int count_mem_move_bb;
+extern int count_interface_size;
+extern int count_argument_mem_ss;
+extern int count_argument_reg_ss;
+extern int count_method_in_register;
+extern int count_mov_reg_reg;
+extern int count_mov_mem_reg;
+extern int count_mov_reg_mem;
+extern int count_mov_mem_mem;
+
+extern int count_jit_calls;
+extern int count_methods;
+extern int count_spills_read_ila;
+extern int count_spills_read_flt;
+extern int count_spills_read_dbl;
+extern int count_spills_write_ila;
+extern int count_spills_write_flt;
+extern int count_spills_write_dbl;
+extern int count_pcmd_activ;
+extern int count_pcmd_drop;
+extern int count_pcmd_zero;
+extern int count_pcmd_const_store;
+extern int count_pcmd_const_alu;
+extern int count_pcmd_const_bra;
+extern int count_pcmd_load;
+extern int count_pcmd_move;
+extern int count_load_instruction;
+extern int count_pcmd_store;
+extern int count_pcmd_store_comb;
+extern int count_dup_instruction;
+extern int count_pcmd_op;
+extern int count_pcmd_mem;
+extern int count_pcmd_met;
+extern int count_pcmd_bra;
+extern int count_pcmd_table;
+extern int count_pcmd_return;
+extern int count_pcmd_returnx;
+extern int count_check_null;
+extern int count_check_bound;
+extern int count_max_basic_blocks;
+extern int count_basic_blocks;
+extern int count_max_javainstr;
+extern int count_javainstr;
+extern int count_javacodesize;
+extern int count_javaexcsize;
+extern int count_calls;
+extern int count_tryblocks;
+extern int count_code_len;
+extern int count_data_len;
+extern int count_cstub_len;
+extern int count_max_new_stack;
+extern int count_upper_bound_new_stack;
+
+extern int count_emit_branch;
+extern int count_emit_branch_8bit;
+extern int count_emit_branch_16bit;
+extern int count_emit_branch_32bit;
+extern int count_emit_branch_64bit;
+
+extern s4 count_branches_resolved;
+extern s4 count_branches_unresolved;
+
+extern int *count_block_stack;
+extern int *count_analyse_iterations;
+extern int *count_method_bb_distribution;
+extern int *count_block_size_distribution;
+extern int *count_store_length;
+extern int *count_store_depth;
+                                /* in_  inline statistics */
+extern int count_in;
+extern int count_in_uniqVirt;
+extern int count_in_uniqIntf;
+extern int count_in_rejected;
+extern int count_in_rejected_mult;
+extern int count_in_outsiders;
+extern int count_in_uniqueVirt_not_inlined;
+extern int count_in_uniqueInterface_not_inlined;
+extern int count_in_maxDepth;
+extern int count_in_maxMethods;
+
+extern u2 count_in_not   [512];
+
+/* instruction scheduler statistics *******************************************/
+
+extern s4 count_schedule_basic_blocks;
+extern s4 count_schedule_nodes;
+extern s4 count_schedule_leaders;
+extern s4 count_schedule_max_leaders;
+extern s4 count_schedule_critical_path;
+
+
+/* function prototypes ********************************************************/
+
+s8 getcputime(void);
+
+void loadingtime_start(void);
+void loadingtime_stop(void);
+void compilingtime_start(void);
+void compilingtime_stop(void);
+
+void print_times(void);
+void print_stats(void);
+
+void statistics_print_date(void);
+void statistics_print_memory_usage(void);
+void statistics_print_gc_memory_usage(void);
+
+void mem_usagelog(bool givewarnings);
+
+void compiledinvokation(void);
+void jnicallXmethodnvokation(void);
+void jniinvokation(void);
+
+#endif /* _STATISTICS_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/string.c b/src/vm/string.c
deleted file mode 100644 (file)
index f24e411..0000000
+++ /dev/null
@@ -1,805 +0,0 @@
-/* src/vm/string.c - java.lang.String related 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 "vmcore/system.h"
-
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-
-#include "native/include/java_lang_String.h"
-
-#include "threads/lock-common.h"
-
-#include "vm/array.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/primitive.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-#include "vmcore/utf8.h"
-
-
-/* global variables ***********************************************************/
-
-/* hashsize must be power of 2 */
-
-#define HASHTABLE_STRING_SIZE    2048   /* initial size of javastring-hash    */
-
-hashtable hashtable_string;             /* hashtable for javastrings          */
-
-#if defined(ENABLE_THREADS)
-static java_object_t *lock_hashtable_string;
-#endif
-
-
-/* XXX preliminary typedef, will be removed once string.c and utf8.c are
-   unified. */
-
-#if defined(ENABLE_HANDLES)
-typedef heap_java_lang_String heapstring_t;
-#else
-typedef java_lang_String heapstring_t;
-#endif
-
-
-/* string_init *****************************************************************
-
-   Initialize the string hashtable lock.
-
-*******************************************************************************/
-
-bool string_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("string_init");
-
-       /* create string (javastring) hashtable */
-
-       hashtable_create(&hashtable_string, HASHTABLE_STRING_SIZE);
-
-#if defined(ENABLE_THREADS)
-       /* create string hashtable lock object */
-
-       lock_hashtable_string = NEW(java_object_t);
-
-       LOCK_INIT_OBJECT_LOCK(lock_hashtable_string);
-#endif
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* stringtable_update **********************************************************
-
-   Traverses the javastring hashtable and sets the vftbl-entries of
-   javastrings which were temporarily set to NULL, because
-   java.lang.Object was not yet loaded.
-
-*******************************************************************************/
-void stringtable_update(void)
-{
-       heapstring_t     *js;
-       java_chararray_t *a;
-       literalstring    *s;       /* hashtable entry */
-       int i;
-
-       for (i = 0; i < hashtable_string.size; i++) {
-               s = hashtable_string.ptr[i];
-               if (s) {
-                       while (s) {
-                               js = (heapstring_t *) s->string;
-                               
-                               if ((js == NULL) || (js->value == NULL)) {
-                                       /* error in hashtable found */
-
-                                       vm_abort("stringtable_update: invalid literalstring in hashtable");
-                               }
-
-                               a = js->value;
-
-                               if (!js->header.vftbl) 
-                                       /* vftbl of javastring is NULL */ 
-                                       js->header.vftbl = class_java_lang_String->vftbl;
-
-                               if (!a->header.objheader.vftbl) 
-                                       /* vftbl of character-array is NULL */ 
-                                       a->header.objheader.vftbl =
-                                               primitive_arrayclass_get_by_type(ARRAYTYPE_CHAR)->vftbl;
-
-                               /* follow link in external hash chain */
-                               s = s->hashlink;
-                       }       
-               }               
-       }
-}
-
-
-/* javastring_new_from_utf_buffer **********************************************
-
-   Create a new object of type java/lang/String with the text from
-   the specified utf8 buffer.
-
-   IN:
-      buffer.......points to first char in the buffer
-         blength......number of bytes to read from the buffer
-
-   RETURN VALUE:
-      the java.lang.String object, or
-      NULL if an exception has been thrown
-
-*******************************************************************************/
-
-static java_handle_t *javastring_new_from_utf_buffer(const char *buffer,
-                                                                                                                u4 blength)
-{
-       const char *utf_ptr;            /* current utf character in utf string    */
-       u4 utflength;                   /* length of utf-string if uncompressed   */
-       java_handle_t     *o;
-       java_lang_String  *s;           /* result-string                          */
-       java_handle_chararray_t *a;
-       u4 i;
-
-       assert(buffer);
-
-       utflength = utf_get_number_of_u2s_for_buffer(buffer,blength);
-
-       o = builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(utflength);
-
-       /* javastring or character-array could not be created */
-
-       if ((o == NULL) || (a == NULL))
-               return NULL;
-
-       /* decompress utf-string */
-
-       utf_ptr = buffer;
-
-       for (i = 0; i < utflength; i++)
-               LLNI_array_direct(a, i) = utf_nextu2((char **) &utf_ptr);
-       
-       /* set fields of the javastring-object */
-
-       s = (java_lang_String *) o;
-
-       LLNI_field_set_ref(s, value , a);
-       LLNI_field_set_val(s, offset, 0);
-       LLNI_field_set_val(s, count , utflength);
-
-       return o;
-}
-
-
-/* javastring_safe_new_from_utf8 ***********************************************
-
-   Create a new object of type java/lang/String with the text from
-   the specified UTF-8 string. This function is safe for invalid UTF-8.
-   (Invalid characters will be replaced by U+fffd.)
-
-   IN:
-      text.........the UTF-8 string, zero-terminated.
-
-   RETURN VALUE:
-      the java.lang.String object, or
-      NULL if an exception has been thrown
-
-*******************************************************************************/
-
-java_handle_t *javastring_safe_new_from_utf8(const char *text)
-{
-       java_handle_t           *o;
-       java_handle_chararray_t *a;
-       java_lang_String        *s;
-       s4 nbytes;
-       s4 len;
-
-       if (text == NULL)
-               return NULL;
-
-       /* Get number of bytes. We need this to completely emulate the messy */
-       /* behaviour of the RI. :(                                           */
-
-       nbytes = strlen(text);
-
-       /* calculate number of Java characters */
-
-       len = utf8_safe_number_of_u2s(text, nbytes);
-
-       /* allocate the String object and the char array */
-
-       o = builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(len);
-
-       /* javastring or character-array could not be created? */
-
-       if ((o == NULL) || (a == NULL))
-               return NULL;
-
-       /* decompress UTF-8 string */
-
-       utf8_safe_convert_to_u2s(text, nbytes, LLNI_array_data(a));
-
-       /* set fields of the String object */
-
-       s = (java_lang_String *) o;
-
-       LLNI_field_set_ref(s, value , a);
-       LLNI_field_set_val(s, offset, 0);
-       LLNI_field_set_val(s, count , len);
-
-       return o;
-}
-
-
-/* javastring_new_from_utf_string **********************************************
-
-   Create a new object of type java/lang/String with the text from
-   the specified zero-terminated utf8 string.
-
-   IN:
-      buffer.......points to first char in the buffer
-         blength......number of bytes to read from the buffer
-
-   RETURN VALUE:
-      the java.lang.String object, or
-      NULL if an exception has been thrown
-
-*******************************************************************************/
-
-java_handle_t *javastring_new_from_utf_string(const char *utfstr)
-{
-       assert(utfstr);
-
-       return javastring_new_from_utf_buffer(utfstr, strlen(utfstr));
-}
-
-
-/* javastring_new **************************************************************
-
-   creates a new object of type java/lang/String with the text of 
-   the specified utf8-string
-
-   return: pointer to the string or NULL if memory is exhausted.       
-
-*******************************************************************************/
-
-java_handle_t *javastring_new(utf *u)
-{
-       char *utf_ptr;                  /* current utf character in utf string    */
-       u4 utflength;                   /* length of utf-string if uncompressed   */
-       java_handle_t           *o;
-       java_handle_chararray_t *a;
-       java_lang_String        *s;
-       s4 i;
-
-       if (u == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       utf_ptr = u->text;
-       utflength = utf_get_number_of_u2s(u);
-
-       o = builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(utflength);
-
-       /* javastring or character-array could not be created */
-
-       if ((o == NULL) || (a == NULL))
-               return NULL;
-
-       /* decompress utf-string */
-
-       for (i = 0; i < utflength; i++)
-               LLNI_array_direct(a, i) = utf_nextu2(&utf_ptr);
-       
-       /* set fields of the javastring-object */
-
-       s = (java_lang_String *) o;
-
-       LLNI_field_set_ref(s, value , a);
-       LLNI_field_set_val(s, offset, 0);
-       LLNI_field_set_val(s, count , utflength);
-
-       return o;
-}
-
-
-/* javastring_new_slash_to_dot *************************************************
-
-   creates a new object of type java/lang/String with the text of 
-   the specified utf8-string with slashes changed to dots
-
-   return: pointer to the string or NULL if memory is exhausted.       
-
-*******************************************************************************/
-
-java_handle_t *javastring_new_slash_to_dot(utf *u)
-{
-       char *utf_ptr;                  /* current utf character in utf string    */
-       u4 utflength;                   /* length of utf-string if uncompressed   */
-       java_handle_t           *o;
-       java_handle_chararray_t *a;
-       java_lang_String        *s;
-       s4 i;
-       u2 ch;
-
-       if (u == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       utf_ptr = u->text;
-       utflength = utf_get_number_of_u2s(u);
-
-       o = builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(utflength);
-
-       /* javastring or character-array could not be created */
-       if ((o == NULL) || (a == NULL))
-               return NULL;
-
-       /* decompress utf-string */
-
-       for (i = 0; i < utflength; i++) {
-               ch = utf_nextu2(&utf_ptr);
-               if (ch == '/')
-                       ch = '.';
-               LLNI_array_direct(a, i) = ch;
-       }
-       
-       /* set fields of the javastring-object */
-
-       s = (java_lang_String *) o;
-
-       LLNI_field_set_ref(s, value , a);
-       LLNI_field_set_val(s, offset, 0);
-       LLNI_field_set_val(s, count , utflength);
-
-       return o;
-}
-
-
-/* javastring_new_from_ascii ***************************************************
-
-   creates a new java/lang/String object which contains the given ASCII
-   C-string converted to UTF-16.
-
-   IN:
-      text.........string of ASCII characters
-
-   RETURN VALUE:
-      the java.lang.String object, or 
-      NULL if an exception has been thrown.
-
-*******************************************************************************/
-
-java_handle_t *javastring_new_from_ascii(const char *text)
-{
-       s4 i;
-       s4 len;                             /* length of the string               */
-       java_handle_t           *o;
-       java_lang_String        *s;
-       java_handle_chararray_t *a;
-
-       if (text == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       len = strlen(text);
-
-       o = builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(len);
-
-       /* javastring or character-array could not be created */
-
-       if ((o == NULL) || (a == NULL))
-               return NULL;
-
-       /* copy text */
-
-       for (i = 0; i < len; i++)
-               LLNI_array_direct(a, i) = text[i];
-       
-       /* set fields of the javastring-object */
-
-       s = (java_lang_String *) o;
-
-       LLNI_field_set_ref(s, value , a);
-       LLNI_field_set_val(s, offset, 0);
-       LLNI_field_set_val(s, count , len);
-
-       return o;
-}
-
-
-/* javastring_tochar ***********************************************************
-
-   converts a Java string into a C string.
-       
-   return: pointer to C string
-       
-   Caution: calling method MUST release the allocated memory!
-       
-*******************************************************************************/
-
-char *javastring_tochar(java_handle_t *so) 
-{
-       java_lang_String        *s = (java_lang_String *) so;
-       java_handle_chararray_t *a;
-       int32_t                  count;
-       int32_t                  offset;
-       char *buf;
-       s4 i;
-       
-       if (!s)
-               return "";
-
-       LLNI_field_get_ref(s, value, a);
-
-       if (!a)
-               return "";
-
-       LLNI_field_get_val(s, count, count);
-       LLNI_field_get_val(s, offset, offset);
-
-       buf = MNEW(char, count + 1);
-
-       for (i = 0; i < count; i++)
-               buf[i] = LLNI_array_direct(a, offset + i);
-
-       buf[i] = '\0';
-
-       return buf;
-}
-
-
-/* javastring_toutf ************************************************************
-
-   Make utf symbol from javastring.
-
-*******************************************************************************/
-
-utf *javastring_toutf(java_handle_t *string, bool isclassname)
-{
-       java_lang_String        *s;
-       java_handle_chararray_t *value;
-       int32_t                  count;
-       int32_t                  offset;
-
-       s = (java_lang_String *) string;
-
-       if (s == NULL)
-               return utf_null;
-
-       LLNI_field_get_ref(s, value, value);
-
-       if (value == NULL)
-               return utf_null;
-
-       LLNI_field_get_val(s, count, count);
-       LLNI_field_get_val(s, offset, offset);
-
-       return utf_new_u2(LLNI_array_data(value) + offset, count, isclassname);
-}
-
-
-/* literalstring_u2 ************************************************************
-
-   Searches for the literalstring with the specified u2-array in the
-   string hashtable, if there is no such string a new one is created.
-
-   If copymode is true a copy of the u2-array is made.
-
-*******************************************************************************/
-
-static java_object_t *literalstring_u2(java_chararray_t *a, u4 length,
-                                                                          u4 offset, bool copymode)
-{
-    literalstring    *s;                /* hashtable element                  */
-    heapstring_t     *js;               /* u2-array wrapped in javastring     */
-    java_chararray_t *ca;               /* copy of u2-array                   */
-    u4                key;
-    u4                slot;
-    u2                i;
-
-       LOCK_MONITOR_ENTER(lock_hashtable_string);
-
-    /* find location in hashtable */
-
-    key  = unicode_hashkey(a->data + offset, length);
-    slot = key & (hashtable_string.size - 1);
-    s    = hashtable_string.ptr[slot];
-
-    while (s) {
-               js = (heapstring_t *) s->string;
-
-               if (length == js->count) {
-                       /* compare text */
-
-                       for (i = 0; i < length; i++)
-                               if (a->data[offset + i] != js->value->data[i])
-                                       goto nomatch;
-
-                       /* string already in hashtable, free memory */
-
-                       if (!copymode)
-                               mem_free(a, sizeof(java_chararray_t) + sizeof(u2) * (length - 1) + 10);
-
-                       LOCK_MONITOR_EXIT(lock_hashtable_string);
-
-                       return (java_object_t *) js;
-               }
-
-       nomatch:
-               /* follow link in external hash chain */
-               s = s->hashlink;
-    }
-
-    if (copymode) {
-               /* create copy of u2-array for new javastring */
-               u4 arraysize = sizeof(java_chararray_t) + sizeof(u2) * (length - 1) + 10;
-               ca = mem_alloc(arraysize);
-/*             memcpy(ca, a, arraysize); */
-               memcpy(&(ca->header), &(a->header), sizeof(java_array_t));
-               memcpy(&(ca->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
-
-    } else {
-               ca = a;
-       }
-
-    /* location in hashtable found, complete arrayheader */
-
-    ca->header.objheader.vftbl =
-               primitive_arrayclass_get_by_type(ARRAYTYPE_CHAR)->vftbl;
-    ca->header.size            = length;
-
-       assert(class_java_lang_String);
-       assert(class_java_lang_String->state & CLASS_LOADED);
-
-       /* create new javastring */
-
-       js = NEW(heapstring_t);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_string += sizeof(heapstring_t);
-#endif
-
-#if defined(ENABLE_THREADS)
-       lock_init_object_lock(&js->header);
-#endif
-
-       js->header.vftbl = class_java_lang_String->vftbl;
-       js->value  = ca;
-       js->offset = 0;
-       js->count  = length;
-
-       /* create new literalstring */
-
-       s = NEW(literalstring);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_string += sizeof(literalstring);
-#endif
-
-       s->hashlink = hashtable_string.ptr[slot];
-       s->string   = (java_object_t *) js;
-       hashtable_string.ptr[slot] = s;
-
-       /* update number of hashtable entries */
-
-       hashtable_string.entries++;
-
-       /* reorganization of hashtable */       
-
-       if (hashtable_string.entries > (hashtable_string.size * 2)) {
-               /* reorganization of hashtable, average length of the external
-                  chains is approx. 2 */
-
-               u4             i;
-               literalstring *s;
-               literalstring *nexts;
-               heapstring_t  *tmpjs;
-               hashtable      newhash;                          /* the new hashtable */
-      
-               /* create new hashtable, double the size */
-
-               hashtable_create(&newhash, hashtable_string.size * 2);
-               newhash.entries = hashtable_string.entries;
-      
-               /* transfer elements to new hashtable */
-
-               for (i = 0; i < hashtable_string.size; i++) {
-                       s = hashtable_string.ptr[i];
-
-                       while (s) {
-                               nexts = s->hashlink;
-                               tmpjs = (heapstring_t *) s->string;
-                               slot  = unicode_hashkey(tmpjs->value->data, tmpjs->count) & (newhash.size - 1);
-         
-                               s->hashlink = newhash.ptr[slot];
-                               newhash.ptr[slot] = s;
-       
-                               /* follow link in external hash chain */
-                               s = nexts;
-                       }
-               }
-       
-               /* dispose old table */
-
-               MFREE(hashtable_string.ptr, void*, hashtable_string.size);
-               hashtable_string = newhash;
-       }
-
-       LOCK_MONITOR_EXIT(lock_hashtable_string);
-
-       return (java_object_t *) js;
-}
-
-
-/* literalstring_new ***********************************************************
-
-   Creates a new literalstring with the text of the utf-symbol and inserts
-   it into the string hashtable.
-
-*******************************************************************************/
-
-java_object_t *literalstring_new(utf *u)
-{
-    char             *utf_ptr;       /* pointer to current unicode character  */
-                                        /* utf string                            */
-    u4                utflength;     /* length of utf-string if uncompressed  */
-    java_chararray_t *a;             /* u2-array constructed from utf string  */
-    u4                i;
-
-       utf_ptr = u->text;
-       utflength = utf_get_number_of_u2s(u);
-
-    /* allocate memory */ 
-    a = mem_alloc(sizeof(java_chararray_t) + sizeof(u2) * (utflength - 1) + 10);
-
-    /* convert utf-string to u2-array */
-    for (i = 0; i < utflength; i++)
-               a->data[i] = utf_nextu2(&utf_ptr);
-
-    return literalstring_u2(a, utflength, 0, false);
-}
-
-
-/* literalstring_free **********************************************************
-
-   Removes a literalstring from memory.
-
-*******************************************************************************/
-
-#if 0
-/* TWISTI This one is currently not used. */
-
-static void literalstring_free(java_object_t* string)
-{
-       heapstring_t     *s;
-       java_chararray_t *a;
-
-       s = (heapstring_t *) string;
-       a = s->value;
-
-       /* dispose memory of java.lang.String object */
-       FREE(s, heapstring_t);
-
-       /* dispose memory of java-characterarray */
-       FREE(a, sizeof(java_chararray_t) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
-}
-#endif
-
-
-/* javastring_intern ***********************************************************
-
-   Intern the given Java string.
-
-   XXX NOTE: Literal Strings are direct references since they are not placed
-   onto the GC-Heap. That's why this function looks so "different".
-
-*******************************************************************************/
-
-java_handle_t *javastring_intern(java_handle_t *s)
-{
-       java_lang_String *so;
-       java_chararray_t *value;
-       int32_t           count;
-       int32_t           offset;
-/*     java_lang_String *o; */
-       java_object_t    *o; /* XXX see note above */
-
-       so = (java_lang_String *) s;
-
-       value  = LLNI_field_direct(so, value); /* XXX see note above */
-       LLNI_field_get_val(so, count, count);
-       LLNI_field_get_val(so, offset, offset);
-
-       o = literalstring_u2(value, count, offset, true);
-
-       return LLNI_WRAP(o); /* XXX see note above */
-}
-
-
-/* javastring_fprint ***********************************************************
-
-   Print the given Java string to the given stream.
-
-*******************************************************************************/
-
-void javastring_fprint(java_handle_t *s, FILE *stream)
-{
-       java_lang_String        *so;
-       java_handle_chararray_t *value;
-       int32_t                  count;
-       int32_t                  offset;
-       uint16_t                 c;
-       int                      i;
-
-       so = (java_lang_String *) s;
-
-       LLNI_field_get_ref(so, value, value);
-       LLNI_field_get_val(so, count, count);
-       LLNI_field_get_val(so, offset, offset);
-
-       for (i = offset; i < offset + count; i++) {
-               c = LLNI_array_direct(value, i);
-               fputc(c, stream);
-       }
-}
-
-
-/*
- * 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/string.cpp b/src/vm/string.cpp
new file mode 100644 (file)
index 0000000..71224d0
--- /dev/null
@@ -0,0 +1,715 @@
+/* src/vm/string.cpp - java.lang.String related 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 "vm/os.hpp"
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+
+#include "threads/lock-common.h"
+
+#include "vm/array.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/javaobjects.hpp"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/statistics.h"
+#include "vm/string.hpp"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+
+
+/* global variables ***********************************************************/
+
+/* hashsize must be power of 2 */
+
+#define HASHTABLE_STRING_SIZE    2048   /* initial size of javastring-hash    */
+
+static hashtable hashtable_string;      /* hashtable for javastrings          */
+static Mutex* mutex;
+
+
+/* string_init *****************************************************************
+
+   Initialize the string hashtable lock.
+
+*******************************************************************************/
+
+bool string_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("string_init");
+
+       /* create string (javastring) hashtable */
+
+       hashtable_create(&hashtable_string, HASHTABLE_STRING_SIZE);
+
+       mutex = new Mutex();
+
+       /* everything's ok */
+
+       return true;
+}
+
+
+/* stringtable_update **********************************************************
+
+   Traverses the javastring hashtable and sets the vftbl-entries of
+   javastrings which were temporarily set to NULL, because
+   java.lang.Object was not yet loaded.
+
+*******************************************************************************/
+void stringtable_update(void)
+{
+       java_chararray_t *a;
+       literalstring    *s;       /* hashtable entry */
+
+       for (unsigned int i = 0; i < hashtable_string.size; i++) {
+               s = (literalstring*) hashtable_string.ptr[i];
+
+               if (s) {
+                       while (s) {
+                               // FIXME
+                               java_lang_String js(LLNI_WRAP(s->string));
+                               
+                               if (js.is_null() || (js.get_value() == NULL)) {
+                                       /* error in hashtable found */
+
+                                       vm_abort("stringtable_update: invalid literalstring in hashtable");
+                               }
+
+                               a = LLNI_UNWRAP(js.get_value());
+
+                               if (js.get_vftbl() == NULL)
+                                       // FIXME
+                                       LLNI_UNWRAP(js.get_handle())->vftbl = class_java_lang_String->vftbl;
+
+                               if (a->header.objheader.vftbl == NULL)
+                                       a->header.objheader.vftbl = Primitive::get_arrayclass_by_type(ARRAYTYPE_CHAR)->vftbl;
+
+                               /* follow link in external hash chain */
+                               s = s->hashlink;
+                       }       
+               }               
+       }
+}
+
+
+/* javastring_new_from_utf_buffer **********************************************
+
+   Create a new object of type java/lang/String with the text from
+   the specified utf8 buffer.
+
+   IN:
+      buffer.......points to first char in the buffer
+         blength......number of bytes to read from the buffer
+
+   RETURN VALUE:
+      the java.lang.String object, or
+      NULL if an exception has been thrown
+
+*******************************************************************************/
+
+static java_handle_t *javastring_new_from_utf_buffer(const char *buffer, u4 blength)
+{
+       const char *utf_ptr;            /* current utf character in utf string    */
+
+       assert(buffer);
+
+       int32_t utflength = utf_get_number_of_u2s_for_buffer(buffer, blength);
+
+       java_handle_t*           h  = builtin_new(class_java_lang_String);
+       java_handle_chararray_t* ca = builtin_newarray_char(utflength);
+
+       /* javastring or character-array could not be created */
+
+       if ((h == NULL) || (ca == NULL))
+               return NULL;
+
+       /* decompress utf-string */
+
+       utf_ptr = buffer;
+
+       for (int32_t i = 0; i < utflength; i++)
+               LLNI_array_direct(ca, i) = utf_nextu2((char **) &utf_ptr);
+       
+       /* set fields of the javastring-object */
+
+       java_lang_String jls(h, ca, utflength);
+
+       return jls.get_handle();
+}
+
+
+/* javastring_safe_new_from_utf8 ***********************************************
+
+   Create a new object of type java/lang/String with the text from
+   the specified UTF-8 string. This function is safe for invalid UTF-8.
+   (Invalid characters will be replaced by U+fffd.)
+
+   IN:
+      text.........the UTF-8 string, zero-terminated.
+
+   RETURN VALUE:
+      the java.lang.String object, or
+      NULL if an exception has been thrown
+
+*******************************************************************************/
+
+java_handle_t *javastring_safe_new_from_utf8(const char *text)
+{
+       if (text == NULL)
+               return NULL;
+
+       /* Get number of bytes. We need this to completely emulate the messy */
+       /* behaviour of the RI. :(                                           */
+
+       int32_t nbytes = strlen(text);
+
+       /* calculate number of Java characters */
+
+       int32_t len = utf8_safe_number_of_u2s(text, nbytes);
+
+       /* allocate the String object and the char array */
+
+       java_handle_t*           h  = builtin_new(class_java_lang_String);
+       java_handle_chararray_t* ca = builtin_newarray_char(len);
+
+       /* javastring or character-array could not be created? */
+
+       if ((h == NULL) || (ca == NULL))
+               return NULL;
+
+       /* decompress UTF-8 string */
+
+       utf8_safe_convert_to_u2s(text, nbytes, LLNI_array_data(ca));
+
+       /* set fields of the String object */
+
+       java_lang_String jls(h, ca, len);
+
+       return jls.get_handle();
+}
+
+
+/* javastring_new_from_utf_string **********************************************
+
+   Create a new object of type java/lang/String with the text from
+   the specified zero-terminated utf8 string.
+
+   IN:
+      buffer.......points to first char in the buffer
+         blength......number of bytes to read from the buffer
+
+   RETURN VALUE:
+      the java.lang.String object, or
+      NULL if an exception has been thrown
+
+*******************************************************************************/
+
+java_handle_t *javastring_new_from_utf_string(const char *utfstr)
+{
+       assert(utfstr);
+
+       return javastring_new_from_utf_buffer(utfstr, strlen(utfstr));
+}
+
+
+/* javastring_new **************************************************************
+
+   creates a new object of type java/lang/String with the text of 
+   the specified utf8-string
+
+   return: pointer to the string or NULL if memory is exhausted.       
+
+*******************************************************************************/
+
+java_handle_t *javastring_new(utf *u)
+{
+       if (u == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       char*   utf_ptr   = u->text;
+       int32_t utflength = utf_get_number_of_u2s(u);
+
+       java_handle_t*           h  = builtin_new(class_java_lang_String);
+       java_handle_chararray_t* ca = builtin_newarray_char(utflength);
+
+       /* javastring or character-array could not be created */
+
+       if ((h == NULL) || (ca == NULL))
+               return NULL;
+
+       /* decompress utf-string */
+
+       for (int32_t i = 0; i < utflength; i++)
+               LLNI_array_direct(ca, i) = utf_nextu2(&utf_ptr);
+       
+       /* set fields of the javastring-object */
+
+       java_lang_String jls(h, ca, utflength);
+
+       return jls.get_handle();
+}
+
+
+/* javastring_new_slash_to_dot *************************************************
+
+   creates a new object of type java/lang/String with the text of 
+   the specified utf8-string with slashes changed to dots
+
+   return: pointer to the string or NULL if memory is exhausted.       
+
+*******************************************************************************/
+
+java_handle_t *javastring_new_slash_to_dot(utf *u)
+{
+       if (u == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       char*   utf_ptr   = u->text;
+       int32_t utflength = utf_get_number_of_u2s(u);
+
+       java_handle_t*           h  = builtin_new(class_java_lang_String);
+       java_handle_chararray_t* ca = builtin_newarray_char(utflength);
+
+       /* javastring or character-array could not be created */
+       if ((h == NULL) || (ca == NULL))
+               return NULL;
+
+       /* decompress utf-string */
+
+       for (int32_t i = 0; i < utflength; i++) {
+               uint16_t ch = utf_nextu2(&utf_ptr);
+
+               if (ch == '/')
+                       ch = '.';
+
+               LLNI_array_direct(ca, i) = ch;
+       }
+       
+       /* set fields of the javastring-object */
+
+       java_lang_String jls(h, ca, utflength);
+
+       return jls.get_handle();
+}
+
+
+/* javastring_new_from_ascii ***************************************************
+
+   creates a new java/lang/String object which contains the given ASCII
+   C-string converted to UTF-16.
+
+   IN:
+      text.........string of ASCII characters
+
+   RETURN VALUE:
+      the java.lang.String object, or 
+      NULL if an exception has been thrown.
+
+*******************************************************************************/
+
+java_handle_t *javastring_new_from_ascii(const char *text)
+{
+       if (text == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       int32_t len = strlen(text);
+
+       java_handle_t*           h  = builtin_new(class_java_lang_String);
+       java_handle_chararray_t* ca = builtin_newarray_char(len);
+
+       /* javastring or character-array could not be created */
+
+       if ((h == NULL) || (ca == NULL))
+               return NULL;
+
+       /* copy text */
+
+       for (int32_t i = 0; i < len; i++)
+               LLNI_array_direct(ca, i) = text[i];
+       
+       /* set fields of the javastring-object */
+
+       java_lang_String jls(h, ca, len);
+
+       return jls.get_handle();
+}
+
+
+/* javastring_tochar ***********************************************************
+
+   converts a Java string into a C string.
+       
+   return: pointer to C string
+       
+   Caution: calling method MUST release the allocated memory!
+       
+*******************************************************************************/
+
+char* javastring_tochar(java_handle_t* h)
+{
+       java_lang_String jls(h);
+
+       if (jls.is_null())
+               return (char*) "";
+
+       java_handle_chararray_t* ca = jls.get_value();
+
+       if (ca == NULL)
+               return (char*) "";
+
+       int32_t count  = jls.get_count();
+       int32_t offset = jls.get_offset();
+
+       char* buf = MNEW(char, count + 1);
+
+       int32_t i;
+       for (i = 0; i < count; i++)
+               buf[i] = LLNI_array_direct(ca, offset + i);
+
+       buf[i] = '\0';
+
+       return buf;
+}
+
+
+/* javastring_toutf ************************************************************
+
+   Make utf symbol from javastring.
+
+*******************************************************************************/
+
+utf *javastring_toutf(java_handle_t *string, bool isclassname)
+{
+       java_lang_String jls(string);
+
+       if (jls.is_null())
+               return utf_null;
+
+       java_handle_chararray_t* value = jls.get_value();
+
+       if (jls.get_value() == NULL)
+               return utf_null;
+
+       int32_t count  = jls.get_count();
+       int32_t offset = jls.get_offset();
+
+       return utf_new_u2(LLNI_array_data(value) + offset, count, isclassname);
+}
+
+
+/* literalstring_u2 ************************************************************
+
+   Searches for the literalstring with the specified u2-array in the
+   string hashtable, if there is no such string a new one is created.
+
+   If copymode is true a copy of the u2-array is made.
+
+*******************************************************************************/
+
+static java_object_t *literalstring_u2(java_chararray_t *a, int32_t length,
+                                                                          u4 offset, bool copymode)
+{
+    literalstring    *s;                /* hashtable element                  */
+    java_chararray_t *ca;               /* copy of u2-array                   */
+    u4                key;
+    u4                slot;
+    u2                i;
+
+       mutex->lock();
+
+    /* find location in hashtable */
+
+    key  = unicode_hashkey(a->data + offset, length);
+    slot = key & (hashtable_string.size - 1);
+    s    = (literalstring*) hashtable_string.ptr[slot];
+
+    while (s) {
+               // FIXME
+               java_lang_String js(LLNI_WRAP(s->string));
+
+               if (length == js.get_count()) {
+                       /* compare text */
+
+                       for (i = 0; i < length; i++)
+                               // FIXME This is not handle capable!
+                               
+                               if (a->data[offset + i] != ((java_chararray_t*) LLNI_UNWRAP(js.get_value()))->data[i])
+                                       goto nomatch;
+
+                       /* string already in hashtable, free memory */
+
+                       if (!copymode)
+                               mem_free(a, sizeof(java_chararray_t) + sizeof(u2) * (length - 1) + 10);
+
+                       mutex->unlock();
+
+                       return (java_object_t*) LLNI_UNWRAP(js.get_handle());
+               }
+
+       nomatch:
+               /* follow link in external hash chain */
+               s = s->hashlink;
+    }
+
+    if (copymode) {
+               /* create copy of u2-array for new javastring */
+               u4 arraysize = sizeof(java_chararray_t) + sizeof(u2) * (length - 1) + 10;
+               ca = (java_chararray_t*) mem_alloc(arraysize);
+/*             memcpy(ca, a, arraysize); */
+               memcpy(&(ca->header), &(a->header), sizeof(java_array_t));
+               memcpy(&(ca->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10);
+    }
+       else {
+               ca = a;
+       }
+
+    /* location in hashtable found, complete arrayheader */
+
+    ca->header.objheader.vftbl = Primitive::get_arrayclass_by_type(ARRAYTYPE_CHAR)->vftbl;
+    ca->header.size            = length;
+
+       assert(class_java_lang_String);
+       assert(class_java_lang_String->state & CLASS_LOADED);
+
+       // Create a new java.lang.String object on the system heap.
+       java_object_t* o = (java_object_t*) MNEW(uint8_t, class_java_lang_String->instancesize);
+       // FIXME
+       java_handle_t* h = LLNI_WRAP(o);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_string += sizeof(class_java_lang_String->instancesize);
+#endif
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(o);
+#endif
+
+       o->vftbl = class_java_lang_String->vftbl;
+
+       // FIXME
+       java_lang_String jls(h, LLNI_WRAP(ca), length);
+
+       /* create new literalstring */
+
+       s = NEW(literalstring);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_string += sizeof(literalstring);
+#endif
+
+       s->hashlink = (literalstring*) hashtable_string.ptr[slot];
+       s->string   = (java_object_t*) LLNI_UNWRAP(jls.get_handle());
+       hashtable_string.ptr[slot] = s;
+
+       /* update number of hashtable entries */
+
+       hashtable_string.entries++;
+
+       /* reorganization of hashtable */       
+
+       if (hashtable_string.entries > (hashtable_string.size * 2)) {
+               /* reorganization of hashtable, average length of the external
+                  chains is approx. 2 */
+
+               u4             i;
+               literalstring *s;
+               literalstring *nexts;
+               hashtable      newhash;                          /* the new hashtable */
+      
+               /* create new hashtable, double the size */
+
+               hashtable_create(&newhash, hashtable_string.size * 2);
+               newhash.entries = hashtable_string.entries;
+      
+               /* transfer elements to new hashtable */
+
+               for (i = 0; i < hashtable_string.size; i++) {
+                       s = (literalstring*) hashtable_string.ptr[i];
+
+                       while (s) {
+                               nexts = s->hashlink;
+                               java_lang_String tmpjls(LLNI_WRAP(s->string));
+                               // FIXME This is not handle capable!
+                               slot  = unicode_hashkey(((java_chararray_t*) LLNI_UNWRAP(tmpjls.get_value()))->data, tmpjls.get_count()) & (newhash.size - 1);
+         
+                               s->hashlink = (literalstring*) newhash.ptr[slot];
+                               newhash.ptr[slot] = s;
+       
+                               /* follow link in external hash chain */
+                               s = nexts;
+                       }
+               }
+       
+               /* dispose old table */
+
+               MFREE(hashtable_string.ptr, void*, hashtable_string.size);
+               hashtable_string = newhash;
+       }
+
+       mutex->unlock();
+
+       return (java_object_t*) LLNI_UNWRAP(jls.get_handle());
+}
+
+
+/* literalstring_new ***********************************************************
+
+   Creates a new literalstring with the text of the utf-symbol and inserts
+   it into the string hashtable.
+
+*******************************************************************************/
+
+java_object_t *literalstring_new(utf *u)
+{
+    char             *utf_ptr;       /* pointer to current unicode character  */
+                                        /* utf string                            */
+    u4                utflength;     /* length of utf-string if uncompressed  */
+    java_chararray_t *a;             /* u2-array constructed from utf string  */
+    u4                i;
+
+       utf_ptr = u->text;
+       utflength = utf_get_number_of_u2s(u);
+
+    /* allocate memory */ 
+    a = (java_chararray_t*) mem_alloc(sizeof(java_chararray_t) + sizeof(u2) * (utflength - 1) + 10);
+
+    /* convert utf-string to u2-array */
+    for (i = 0; i < utflength; i++)
+               a->data[i] = utf_nextu2(&utf_ptr);
+
+    return literalstring_u2(a, utflength, 0, false);
+}
+
+
+/* literalstring_free **********************************************************
+
+   Removes a literalstring from memory.
+
+*******************************************************************************/
+
+#if 0
+/* TWISTI This one is currently not used. */
+
+static void literalstring_free(java_object_t* string)
+{
+       heapstring_t     *s;
+       java_chararray_t *a;
+
+       s = (heapstring_t *) string;
+       a = s->value;
+
+       /* dispose memory of java.lang.String object */
+       FREE(s, heapstring_t);
+
+       /* dispose memory of java-characterarray */
+       FREE(a, sizeof(java_chararray_t) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
+}
+#endif
+
+
+/* javastring_intern ***********************************************************
+
+   Intern the given Java string.
+
+   XXX NOTE: Literal Strings are direct references since they are not placed
+   onto the GC-Heap. That's why this function looks so "different".
+
+*******************************************************************************/
+
+java_handle_t *javastring_intern(java_handle_t *string)
+{
+       java_lang_String jls(string);
+
+       java_handle_chararray_t* value = jls.get_value();
+       // FIXME
+       java_chararray_t* ca = LLNI_UNWRAP(value); /* XXX see note above */
+
+       int32_t count  = jls.get_count();
+       int32_t offset = jls.get_offset();
+
+       java_object_t* o = literalstring_u2(ca, count, offset, true); /* XXX see note above */
+
+       return LLNI_WRAP(o); /* XXX see note above */
+}
+
+
+/* javastring_fprint ***********************************************************
+
+   Print the given Java string to the given stream.
+
+*******************************************************************************/
+
+void javastring_fprint(java_handle_t *s, FILE *stream)
+{
+       java_lang_String jls(s);
+
+       java_handle_chararray_t* value = jls.get_value();
+
+       int32_t count  = jls.get_count();
+       int32_t offset = jls.get_offset();
+
+       for (int32_t i = offset; i < offset + count; i++) {
+               uint16_t c = LLNI_array_direct(value, i);
+               fputc(c, stream);
+       }
+}
+
+
+/*
+ * 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/string.hpp b/src/vm/string.hpp
new file mode 100644 (file)
index 0000000..096f219
--- /dev/null
@@ -0,0 +1,108 @@
+/* src/vm/string.hpp - string header
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _STRINGLOCAL_H
+#define _STRINGLOCAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct literalstring literalstring;
+
+
+#include "config.h"
+
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+
+#include "vm/global.h"
+#include "vm/os.hpp"
+#include "vm/utf8.h"
+
+
+/* data structure of internal javastrings stored in global hashtable **********/
+
+struct literalstring {
+       literalstring     *hashlink;        /* link for external hash chain       */
+       java_object_t     *string;  
+};
+
+
+/* function prototypes ********************************************************/
+
+/* initialize string subsystem */
+bool string_init(void);
+
+void stringtable_update(void);
+
+/* creates a new object of type java/lang/String from a utf-text */
+java_handle_t *javastring_new(utf *text);
+
+/* creates a new object of type java/lang/String from a utf-text, changes slashes to dots */
+java_handle_t *javastring_new_slash_to_dot(utf *text);
+
+/* creates a new object of type java/lang/String from an ASCII c-string */
+java_handle_t *javastring_new_from_ascii(const char *text);
+
+/* creates a new object of type java/lang/String from UTF-8 */
+java_handle_t *javastring_new_from_utf_string(const char *utfstr);
+
+/* creates a new object of type java/lang/String from (possibly invalid) UTF-8 */
+java_handle_t *javastring_safe_new_from_utf8(const char *text);
+
+/* make c-string from a javastring (debugging) */
+char *javastring_tochar(java_handle_t *string);
+
+/* make utf symbol from javastring */
+utf *javastring_toutf(java_handle_t *string, bool isclassname);
+
+/* creates a new javastring with the text of the utf-symbol */
+java_object_t *literalstring_new(utf *u);
+
+java_handle_t *javastring_intern(java_handle_t *s);
+void           javastring_fprint(java_handle_t *s, FILE *stream);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STRINGLOCAL_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/stringlocal.h b/src/vm/stringlocal.h
deleted file mode 100644 (file)
index 74ffc23..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* src/vm/stringlocal.h - string header
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _STRINGLOCAL_H
-#define _STRINGLOCAL_H
-
-typedef struct literalstring literalstring;
-
-
-#include "config.h"
-
-#include "vmcore/system.h"
-
-#include "vm/types.h"
-
-#include "toolbox/hashtable.h"
-
-#include "vm/global.h"
-
-#include "vmcore/utf8.h"
-
-
-/* data structure of internal javastrings stored in global hashtable **********/
-
-struct literalstring {
-       literalstring     *hashlink;        /* link for external hash chain       */
-       java_object_t     *string;  
-};
-
-
-/* javastring-hashtable */
-extern hashtable hashtable_string;
-
-
-/* function prototypes ********************************************************/
-
-/* initialize string subsystem */
-bool string_init(void);
-
-void stringtable_update(void);
-
-/* creates a new object of type java/lang/String from a utf-text */
-java_handle_t *javastring_new(utf *text);
-
-/* creates a new object of type java/lang/String from a utf-text, changes slashes to dots */
-java_handle_t *javastring_new_slash_to_dot(utf *text);
-
-/* creates a new object of type java/lang/String from an ASCII c-string */
-java_handle_t *javastring_new_from_ascii(const char *text);
-
-/* creates a new object of type java/lang/String from UTF-8 */
-java_handle_t *javastring_new_from_utf_string(const char *utfstr);
-
-/* creates a new object of type java/lang/String from (possibly invalid) UTF-8 */
-java_handle_t *javastring_safe_new_from_utf8(const char *text);
-
-/* make c-string from a javastring (debugging) */
-char *javastring_tochar(java_handle_t *string);
-
-/* make utf symbol from javastring */
-utf *javastring_toutf(java_handle_t *string, bool isclassname);
-
-/* creates a new javastring with the text of the utf-symbol */
-java_object_t *literalstring_new(utf *u);
-
-java_handle_t *javastring_intern(java_handle_t *s);
-void           javastring_fprint(java_handle_t *s, FILE *stream);
-
-#endif /* _STRINGLOCAL_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/suck.c b/src/vm/suck.c
new file mode 100644 (file)
index 0000000..ddbf0f8
--- /dev/null
@@ -0,0 +1,627 @@
+/* src/vm/suck.c - functions to read LE ordered types from a buffer
+
+   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 <stdlib.h>
+
+#include "vm/types.h"
+
+#include "arch.h"
+
+#include "mm/memory.h"
+
+#include "threads/lock-common.h"
+
+#include "toolbox/list.h"
+#include "toolbox/logging.h"
+#include "toolbox/util.h"
+
+#include "vm/exceptions.hpp"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
+#include "vm/properties.h"
+#include "vm/suck.h"
+#include "vm/vm.hpp"
+#include "vm/zip.h"
+
+
+/* global variables ***********************************************************/
+
+list_t *list_classpath_entries;
+
+
+/* suck_init *******************************************************************
+
+   Initializes the suck subsystem like initializing the classpath
+   entries list.
+
+*******************************************************************************/
+
+bool suck_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("suck_init");
+
+       list_classpath_entries = list_create(OFFSET(list_classpath_entry, linkage));
+
+       /* everything's ok */
+
+       return true;
+}
+
+
+/* scandir_filter **************************************************************
+
+   Filters for zip/jar files.
+
+*******************************************************************************/
+
+static int scandir_filter(const struct dirent *a)
+{
+       s4 namlen;
+
+#if defined(_DIRENT_HAVE_D_NAMLEN)
+       namlen = a->d_namlen;
+#else
+       namlen = strlen(a->d_name);
+#endif
+
+       if ((strncasecmp(a->d_name + namlen - 4, ".zip", 4) == 0) ||
+               (strncasecmp(a->d_name + namlen - 4, ".jar", 4) == 0))
+               return 1;
+
+       return 0;
+}
+
+
+/* suck_add ********************************************************************
+
+   Adds a classpath to the global classpath entries list.
+
+*******************************************************************************/
+
+void suck_add(char *classpath)
+{
+       list_classpath_entry *lce;
+       char                 *start;
+       char                 *end;
+       char                 *filename;
+       s4                    filenamelen;
+       bool                  is_zip;
+       char                 *cwd;
+       s4                    cwdlen;
+#if defined(ENABLE_ZLIB)
+       hashtable            *ht;
+#endif
+
+       /* parse the classpath string */
+
+       for (start = classpath; (*start) != '\0'; ) {
+
+               /* search for ':' delimiter to get the end of the current entry */
+               for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
+
+               if (start != end) {
+                       is_zip = false;
+                       filenamelen = end - start;
+
+                       if (filenamelen > 4) {
+                               if ((strncasecmp(end - 4, ".zip", 4) == 0) ||
+                                       (strncasecmp(end - 4, ".jar", 4) == 0)) {
+                                       is_zip = true;
+                               }
+                       }
+
+                       /* save classpath entries as absolute pathnames */
+
+                       cwd = NULL;
+                       cwdlen = 0;
+
+                       if (*start != '/') {                      /* XXX fix me for win32 */
+                               cwd = _Jv_getcwd();
+                               cwdlen = strlen(cwd) + strlen("/");
+                       }
+
+                       /* allocate memory for filename and fill it */
+
+                       filename = MNEW(char, filenamelen + cwdlen + strlen("/") +
+                                                       strlen("0"));
+
+                       if (cwd) {
+                               strcpy(filename, cwd);
+                               strcat(filename, "/");
+                               strncat(filename, start, filenamelen);
+
+                               /* add cwd length to file length */
+                               filenamelen += cwdlen;
+
+                       } else {
+                               strncpy(filename, start, filenamelen);
+                               filename[filenamelen] = '\0';
+                       }
+
+                       lce = NULL;
+
+                       if (is_zip) {
+#if defined(ENABLE_ZLIB)
+                               ht = zip_open(filename);
+
+                               if (ht != NULL) {
+                                       lce = NEW(list_classpath_entry);
+
+                                       lce->type      = CLASSPATH_ARCHIVE;
+                                       lce->htclasses = ht;
+                                       lce->path      = filename;
+                                       lce->pathlen   = filenamelen;
+
+                                       /* SUN compatible -verbose:class output */
+
+                                       if (opt_verboseclass)
+                                               printf("[Opened %s]\n", filename);
+                               }
+
+#else
+                               vm_abort("suck_add: zip/jar files not supported");
+#endif
+                       }
+                       else {
+                               if (filename[filenamelen - 1] != '/') {/* XXX fixme for win32 */
+                                       filename[filenamelen] = '/';
+                                       filename[filenamelen + 1] = '\0';
+                                       filenamelen++;
+                               }
+
+                               lce = NEW(list_classpath_entry);
+
+                               lce->type    = CLASSPATH_PATH;
+                               lce->path    = filename;
+                               lce->pathlen = filenamelen;
+                       }
+
+                       /* add current classpath entry, if no error */
+
+                       if (lce != NULL)
+                               list_add_last(list_classpath_entries, lce);
+               }
+
+               /* goto next classpath entry, skip ':' delimiter */
+
+               if ((*end) == ':')
+                       start = end + 1;
+               else
+                       start = end;
+       }
+}
+
+
+/* suck_add_from_property ******************************************************
+
+   Adds a classpath form a property entry to the global classpath
+   entries list.
+
+*******************************************************************************/
+
+void suck_add_from_property(const char *key)
+{
+       const char     *value;
+       const char     *start;
+       const char     *end;
+       char           *path;
+       s4              pathlen;
+       struct dirent **namelist;
+       s4              n;
+       s4              i;
+       s4              namlen;
+       char           *boot_class_path;
+       char           *p;
+
+       /* get the property value */
+
+       value = properties_get(key);
+
+       if (value == NULL)
+               return;
+
+       /* get the directory entries of the property */
+
+       for (start = value; (*start) != '\0'; ) {
+
+               /* search for ':' delimiter to get the end of the current entry */
+
+               for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
+
+               /* found an entry */
+
+               if (start != end) {
+                       /* allocate memory for the path entry */
+
+                       pathlen = end - start;
+                       path = MNEW(char, pathlen + strlen("0"));
+
+                       /* copy and terminate the string */
+
+                       strncpy(path, start, pathlen);
+                       path[pathlen] = '\0';
+
+                       /* Reset namelist to NULL for the freeing in an error case
+                          (see below). */
+
+                       namelist = NULL;
+
+                       /* scan the directory found for zip/jar files */
+
+                       n = os_scandir(path, &namelist, scandir_filter, alphasort);
+
+                       /* On error, just continue, this should be ok. */
+
+                       if (n > 0) {
+                               for (i = 0; i < n; i++) {
+#if defined(_DIRENT_HAVE_D_NAMLEN)
+                                       namlen = namelist[i]->d_namlen;
+#else
+                                       namlen = strlen(namelist[i]->d_name);
+#endif
+
+                                       /* Allocate memory for bootclasspath. */
+
+                                       // FIXME Make boot_class_path const char*.
+                                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+
+                                       p = MNEW(char,
+                                                        pathlen + strlen("/") + namlen +
+                                                        strlen(":") +
+                                                        strlen(boot_class_path) +
+                                                        strlen("0"));
+
+                                       /* Prepend the file found to the bootclasspath. */
+
+                                       strcpy(p, path);
+                                       strcat(p, "/");
+                                       strcat(p, namelist[i]->d_name);
+                                       strcat(p, ":");
+                                       strcat(p, boot_class_path);
+
+                                       properties_add("sun.boot.class.path", p);
+                                       properties_add("java.boot.class.path", p);
+
+                                       MFREE(boot_class_path, char, strlen(boot_class_path));
+
+                                       /* free the memory allocated by scandir */
+                                       /* (We use `free` as the memory came from the C library.) */
+
+                                       free(namelist[i]);
+                               }
+                       }
+
+                       /* On some systems (like Linux) when n == 0, then namelist
+                          returned from scnadir is NULL, thus we don't have to
+                          free it.
+                          (Use `free` as the memory came from the C library.) */
+
+                       if (namelist != NULL)
+                               free(namelist);
+
+                       MFREE(path, char, pathlen + strlen("0"));
+               }
+
+               /* goto next entry, skip ':' delimiter */
+
+               if ((*end) == ':')
+                       start = end + 1;
+               else
+                       start = end;
+       }
+}
+
+
+/* suck_check_classbuffer_size *************************************************
+
+   Assert that at least <len> bytes are left to read <len> is limited
+   to the range of non-negative s4 values.
+
+*******************************************************************************/
+
+bool suck_check_classbuffer_size(classbuffer *cb, s4 len)
+{
+#ifdef ENABLE_VERIFIER
+       if (len < 0 || ((cb->data + cb->size) - cb->pos) < len) {
+               exceptions_throw_classformaterror(cb->clazz, "Truncated class file");
+               return false;
+       }
+#endif /* ENABLE_VERIFIER */
+
+       return true;
+}
+
+
+u1 suck_u1(classbuffer *cb)
+{
+       u1 a;
+
+       a = SUCK_BE_U1(cb->pos);
+       cb->pos++;
+
+       return a;
+}
+
+
+u2 suck_u2(classbuffer *cb)
+{
+       u2 a;
+
+       a = SUCK_BE_U2(cb->pos);
+       cb->pos += 2;
+
+       return a;
+}
+
+
+u4 suck_u4(classbuffer *cb)
+{
+       u4 a;
+
+       a = SUCK_BE_U4(cb->pos);
+       cb->pos += 4;
+
+       return a;
+}
+
+
+u8 suck_u8(classbuffer *cb)
+{
+#if U8_AVAILABLE == 1
+       u8 a;
+
+       a = SUCK_BE_U8(cb->pos);
+       cb->pos += 8;
+
+       return a;
+#else
+       u8 v;
+
+       v.high = suck_u4(cb);
+       v.low = suck_u4(cb);
+
+       return v;
+#endif
+}
+
+
+float suck_float(classbuffer *cb)
+{
+       float f;
+
+#if WORDS_BIGENDIAN == 0
+       u1 buffer[4];
+       u2 i;
+
+       for (i = 0; i < 4; i++)
+               buffer[3 - i] = suck_u1(cb);
+
+       MCOPY((u1 *) (&f), buffer, u1, 4);
+#else
+       suck_nbytes((u1*) (&f), cb, 4);
+#endif
+
+       assert(sizeof(float) == 4);
+       
+       return f;
+}
+
+
+double suck_double(classbuffer *cb)
+{
+       double d;
+
+#if WORDS_BIGENDIAN == 0
+       u1 buffer[8];
+       u2 i;   
+
+# if defined(__ARM__) && defined(__ARMEL__) && !defined(__VFP_FP__)
+       /*
+        * On little endian ARM processors when using FPA, word order
+        * of doubles is still big endian. So take that into account
+        * here. When using VFP, word order of doubles follows byte
+        * order. (michi 2005/07/24)
+        */
+       for (i = 0; i < 4; i++)
+               buffer[3 - i] = suck_u1(cb);
+       for (i = 0; i < 4; i++)
+               buffer[7 - i] = suck_u1(cb);
+# else
+       for (i = 0; i < 8; i++)
+               buffer[7 - i] = suck_u1(cb);
+# endif /* defined(__ARM__) && ... */
+
+       MCOPY((u1 *) (&d), buffer, u1, 8);
+#else 
+       suck_nbytes((u1*) (&d), cb, 8);
+#endif
+
+       assert(sizeof(double) == 8);
+       
+       return d;
+}
+
+
+/* suck_nbytes *****************************************************************
+
+   Transfer block of classfile data into a buffer.
+
+*******************************************************************************/
+
+void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
+{
+       MCOPY(buffer, cb->pos, u1, len);
+       cb->pos += len;
+}
+
+
+/* suck_skip_nbytes ************************************************************
+
+   Skip block of classfile data.
+
+*******************************************************************************/
+
+void suck_skip_nbytes(classbuffer *cb, s4 len)
+{
+       cb->pos += len;
+}
+
+
+/* suck_start ******************************************************************
+
+   Returns true if classbuffer is already loaded or a file for the
+   specified class has succussfully been read in. All directories of
+   the searchpath are used to find the classfile (<classname>.class).
+   Returns NULL if no classfile is found and writes an error message.
+       
+*******************************************************************************/
+
+classbuffer *suck_start(classinfo *c)
+{
+       list_classpath_entry *lce;
+       char                 *filename;
+       s4                    filenamelen;
+       char                 *path;
+       FILE                 *classfile;
+       s4                    len;
+       struct stat           buffer;
+       classbuffer          *cb;
+
+       /* initialize return value */
+
+       cb = NULL;
+
+       /* get the classname as char string (do it here for the warning at
+       the end of the function) */
+
+       filenamelen = utf_bytes(c->name) + strlen(".class") + strlen("0");
+       filename = MNEW(char, filenamelen);
+
+       utf_copy(filename, c->name);
+       strcat(filename, ".class");
+
+       /* walk through all classpath entries */
+
+       for (lce = list_first(list_classpath_entries); lce != NULL && cb == NULL;
+                lce = list_next(list_classpath_entries, lce)) {
+#if defined(ENABLE_ZLIB)
+               if (lce->type == CLASSPATH_ARCHIVE) {
+
+                       /* enter a monitor on zip/jar archives */
+
+                       LOCK_MONITOR_ENTER(lce);
+
+                       /* try to get the file in current archive */
+
+                       cb = zip_get(lce, c);
+
+                       /* leave the monitor */
+
+                       LOCK_MONITOR_EXIT(lce);
+
+               } else {
+#endif /* defined(ENABLE_ZLIB) */
+                       path = MNEW(char, lce->pathlen + filenamelen);
+                       strcpy(path, lce->path);
+                       strcat(path, filename);
+
+                       classfile = os_fopen(path, "r");
+
+                       if (classfile) {                                   /* file exists */
+                               if (!os_stat(path, &buffer)) {     /* read classfile data */
+                                       cb = NEW(classbuffer);
+                                       cb->clazz = c;
+                                       cb->size  = buffer.st_size;
+                                       cb->data  = MNEW(u1, cb->size);
+                                       cb->pos   = cb->data;
+                                       cb->path  = lce->path;
+
+                                       /* read class data */
+
+                                       len = os_fread((void *) cb->data, 1, cb->size,
+                                                                          classfile);
+
+                                       if (len != buffer.st_size) {
+                                               suck_stop(cb);
+/*                                             if (ferror(classfile)) { */
+/*                                             } */
+                                       }
+
+                                       /* close the class file */
+
+                                       os_fclose(classfile);
+                               }
+                       }
+
+                       MFREE(path, char, lce->pathlen + filenamelen);
+#if defined(ENABLE_ZLIB)
+               }
+#endif
+       }
+
+       if (opt_verbose)
+               if (cb == NULL)
+                       dolog("Warning: Can not open class file '%s'", filename);
+
+       MFREE(filename, char, filenamelen);
+
+       return cb;
+}
+
+
+/* suck_stop *******************************************************************
+
+   Frees memory for buffer with classfile data.
+
+   CAUTION: This function may only be called if buffer has been
+   allocated by suck_start with reading a file.
+       
+*******************************************************************************/
+
+void suck_stop(classbuffer *cb)
+{
+       /* free memory */
+
+       MFREE(cb->data, u1, cb->size);
+       FREE(cb, classbuffer);
+}
+
+
+/*
+ * 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/suck.h b/src/vm/suck.h
new file mode 100644 (file)
index 0000000..da06570
--- /dev/null
@@ -0,0 +1,207 @@
+/* src/vm/suck.h - functions to read LE ordered types from a buffer
+
+   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 _SUCK_H
+#define _SUCK_H
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+#include "toolbox/list.h"
+
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+
+
+/* list_classpath_entry *******************************************************/
+
+enum {
+       CLASSPATH_PATH,
+       CLASSPATH_ARCHIVE
+};
+
+typedef struct list_classpath_entry list_classpath_entry;
+
+struct list_classpath_entry {
+#if defined(ENABLE_THREADS)
+       java_object_t      header;              /* monitor locking on zip/jar files   */
+#endif
+       s4                 type;
+       char              *path;
+       s4                 pathlen;
+#if defined(ENABLE_ZLIB)
+       hashtable         *htclasses;
+#endif
+       listnode_t         linkage;
+};
+
+
+/* macros to read LE and BE types from a buffer ********************************
+
+   BE macros are for Java class file loading.
+   LE macros are for ZIP file loading.
+
+*******************************************************************************/
+
+/* LE macros (for ZIP files ) *************************************************/
+
+#if defined(__I386__) || defined(__X86_64__)
+
+/* we can optimize the LE access on little endian machines without alignment */
+
+#define SUCK_LE_U1(p)    *((u1 *) (p))
+#define SUCK_LE_U2(p)    *((u2 *) (p))
+#define SUCK_LE_U4(p)    *((u4 *) (p))
+
+#if U8_AVAILABLE == 1
+#define SUCK_LE_U8(p)    *((u8 *) (p))
+#endif
+
+#else /* defined(__I386__) || defined(__X86_64__) */
+
+#define SUCK_LE_U1(p) \
+      ((u1) (p)[0])
+
+#define SUCK_LE_U2(p) \
+    ((((u2) (p)[1]) << 8) + \
+      ((u2) (p)[0]))
+
+#define SUCK_LE_U4(p) \
+    ((((u4) (p)[3]) << 24) + \
+     (((u4) (p)[2]) << 16) + \
+     (((u4) (p)[1]) << 8) + \
+      ((u4) (p)[0]))
+
+#if U8_AVAILABLE == 1
+#define SUCK_LE_U8(p) \
+    ((((u8) (p)[7]) << 56) + \
+     (((u8) (p)[6]) << 48) + \
+     (((u8) (p)[5]) << 40) + \
+     (((u8) (p)[4]) << 32) + \
+     (((u8) (p)[3]) << 24) + \
+     (((u8) (p)[2]) << 16) + \
+     (((u8) (p)[1]) << 8) + \
+      ((u8) (p)[0]))
+#endif
+
+#endif /* defined(__I386__) || defined(__X86_64__) */
+
+
+/* BE macros (for Java class files ) ******************************************/
+
+#define SUCK_BE_U1(p) \
+      ((u1) (p)[0])
+
+#define SUCK_BE_U2(p) \
+    ((((u2) (p)[0]) << 8) + \
+      ((u2) (p)[1]))
+
+#define SUCK_BE_U4(p) \
+    ((((u4) (p)[0]) << 24) + \
+     (((u4) (p)[1]) << 16) + \
+     (((u4) (p)[2]) << 8) + \
+      ((u4) (p)[3]))
+
+#if U8_AVAILABLE == 1
+#define SUCK_BE_U8(p) \
+    ((((u8) (p)[0]) << 56) + \
+     (((u8) (p)[1]) << 48) + \
+     (((u8) (p)[2]) << 40) + \
+     (((u8) (p)[3]) << 32) + \
+     (((u8) (p)[4]) << 24) + \
+     (((u8) (p)[5]) << 16) + \
+     (((u8) (p)[6]) << 8) + \
+      ((u8) (p)[7]))
+#endif
+
+
+#define SUCK_BE_S1(p)    (s1) SUCK_BE_U1(p)
+#define SUCK_BE_S2(p)    (s2) SUCK_BE_U2(p)
+#define SUCK_BE_S4(p)    (s4) SUCK_BE_U4(p)
+#define SUCK_BE_S8(p)    (s8) SUCK_BE_U8(p)
+
+
+/* signed suck defines ********************************************************/
+
+#define suck_s1(a)    (s1) suck_u1((a))
+#define suck_s2(a)    (s2) suck_u2((a))
+#define suck_s4(a)    (s4) suck_u4((a))
+#define suck_s8(a)    (s8) suck_u8((a))
+
+
+/* export variables ***********************************************************/
+
+extern list_t *list_classpath_entries;
+
+
+/* function prototypes ********************************************************/
+
+bool suck_init(void);
+
+void suck_add(char *classpath);
+void suck_add_from_property(const char *key);
+
+bool suck_check_classbuffer_size(classbuffer *cb, s4 len);
+
+u1 suck_u1(classbuffer *cb);
+u2 suck_u2(classbuffer *cb);
+u4 suck_u4(classbuffer *cb);
+u8 suck_u8(classbuffer *cb);
+
+float suck_float(classbuffer *cb);
+double suck_double(classbuffer *cb);
+
+void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len);
+void suck_skip_nbytes(classbuffer *cb, s4 len);
+
+classbuffer *suck_start(classinfo *c);
+
+void suck_stop(classbuffer *cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SUCK_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/utf8.c b/src/vm/utf8.c
new file mode 100644 (file)
index 0000000..7616aa1
--- /dev/null
@@ -0,0 +1,1934 @@
+/* src/vm/utf8.c - utf8 string 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 <string.h>
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "threads/lock-common.h"
+
+#include "toolbox/hashtable.h"
+
+#include "vm/exceptions.hpp"
+#include "vm/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/utf8.h"
+
+
+/* global variables ***********************************************************/
+
+/* hashsize must be power of 2 */
+
+#define HASHTABLE_UTF_SIZE    16384     /* initial size of utf-hash           */
+
+hashtable *hashtable_utf;               /* hashtable for utf8-symbols         */
+
+
+/* utf-symbols for pointer comparison of frequently used strings **************/
+
+utf *utf_java_lang_Object;
+
+utf *utf_java_lang_Class;
+utf *utf_java_lang_ClassLoader;
+utf *utf_java_lang_Cloneable;
+utf *utf_java_lang_SecurityManager;
+utf *utf_java_lang_String;
+utf *utf_java_lang_ThreadGroup;
+utf *utf_java_lang_ref_SoftReference;
+utf *utf_java_lang_ref_WeakReference;
+utf *utf_java_lang_ref_PhantomReference;
+utf *utf_java_io_Serializable;
+
+utf *utf_java_lang_Throwable;
+utf *utf_java_lang_Error;
+
+utf *utf_java_lang_AbstractMethodError;
+utf *utf_java_lang_ClassCircularityError;
+utf *utf_java_lang_ClassFormatError;
+utf *utf_java_lang_ExceptionInInitializerError;
+utf *utf_java_lang_IncompatibleClassChangeError;
+utf *utf_java_lang_InstantiationError;
+utf *utf_java_lang_InternalError;
+utf *utf_java_lang_LinkageError;
+utf *utf_java_lang_NoClassDefFoundError;
+utf *utf_java_lang_NoSuchFieldError;
+utf *utf_java_lang_NoSuchMethodError;
+utf *utf_java_lang_OutOfMemoryError;
+utf *utf_java_lang_UnsatisfiedLinkError;
+utf *utf_java_lang_UnsupportedClassVersionError;
+utf *utf_java_lang_VerifyError;
+utf *utf_java_lang_VirtualMachineError;
+
+utf *utf_java_lang_Exception;
+
+utf *utf_java_lang_ArithmeticException;
+utf *utf_java_lang_ArrayIndexOutOfBoundsException;
+utf *utf_java_lang_ArrayStoreException;
+utf *utf_java_lang_ClassCastException;
+utf *utf_java_lang_ClassNotFoundException;
+utf *utf_java_lang_CloneNotSupportedException;
+utf *utf_java_lang_IllegalAccessException;
+utf *utf_java_lang_IllegalArgumentException;
+utf *utf_java_lang_IllegalMonitorStateException;
+utf *utf_java_lang_InstantiationException;
+utf *utf_java_lang_InterruptedException;
+utf *utf_java_lang_NegativeArraySizeException;
+utf *utf_java_lang_NullPointerException;
+utf *utf_java_lang_RuntimeException;
+utf *utf_java_lang_StringIndexOutOfBoundsException;
+
+utf *utf_java_lang_reflect_InvocationTargetException;
+
+utf *utf_java_security_PrivilegedActionException;
+
+#if defined(ENABLE_JAVASE)
+utf* utf_java_lang_Void;
+#endif
+
+utf* utf_java_lang_Boolean;
+utf* utf_java_lang_Byte;
+utf* utf_java_lang_Character;
+utf* utf_java_lang_Short;
+utf* utf_java_lang_Integer;
+utf* utf_java_lang_Long;
+utf* utf_java_lang_Float;
+utf* utf_java_lang_Double;
+
+#if defined(ENABLE_JAVASE)
+utf *utf_java_lang_StackTraceElement;
+utf *utf_java_lang_reflect_Constructor;
+utf *utf_java_lang_reflect_Field;
+utf *utf_java_lang_reflect_Method;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+utf *utf_java_lang_reflect_VMConstructor;
+utf *utf_java_lang_reflect_VMField;
+utf *utf_java_lang_reflect_VMMethod;
+# endif
+
+utf *utf_java_util_Vector;
+#endif
+
+utf *utf_InnerClasses;                  /* InnerClasses                       */
+utf *utf_ConstantValue;                 /* ConstantValue                      */
+utf *utf_Code;                          /* Code                               */
+utf *utf_Exceptions;                    /* Exceptions                         */
+utf *utf_LineNumberTable;               /* LineNumberTable                    */
+utf *utf_SourceFile;                    /* SourceFile                         */
+
+#if defined(ENABLE_JAVASE)
+utf *utf_EnclosingMethod;
+utf *utf_Signature;
+utf *utf_StackMapTable;
+
+#if defined(ENABLE_ANNOTATIONS)
+utf *utf_RuntimeVisibleAnnotations;            /* RuntimeVisibleAnnotations            */
+utf *utf_RuntimeInvisibleAnnotations;          /* RuntimeInvisibleAnnotations          */
+utf *utf_RuntimeVisibleParameterAnnotations;   /* RuntimeVisibleParameterAnnotations   */
+utf *utf_RuntimeInvisibleParameterAnnotations; /* RuntimeInvisibleParameterAnnotations */
+utf *utf_AnnotationDefault;                    /* AnnotationDefault                    */
+#endif
+#endif
+
+utf *utf_init;                          /* <init>                             */
+utf *utf_clinit;                        /* <clinit>                           */
+utf *utf_clone;                         /* clone                              */
+utf *utf_finalize;                      /* finalize                           */
+utf *utf_invoke;
+utf *utf_main;
+utf *utf_run;                           /* run                                */
+
+utf *utf_add;
+utf *utf_dispatch;
+utf *utf_remove;
+utf *utf_addThread;
+utf *utf_removeThread;
+utf *utf_put;
+utf *utf_get;
+utf *utf_uncaughtException;
+utf *utf_value;
+
+utf *utf_fillInStackTrace;
+utf *utf_findNative;
+utf *utf_getSystemClassLoader;
+utf *utf_initCause;
+utf *utf_loadClass;
+utf *utf_loadClassInternal;
+utf *utf_printStackTrace;
+
+utf *utf_division_by_zero;
+
+utf *utf_Z;                             /* Z                                  */
+utf *utf_B;                             /* B                                  */
+utf *utf_C;                             /* C                                  */
+utf *utf_S;                             /* S                                  */
+utf *utf_I;                             /* I                                  */
+utf *utf_J;                             /* J                                  */
+utf *utf_F;                             /* F                                  */
+utf *utf_D;                             /* D                                  */
+
+utf *utf_void__void;                    /* ()V                                */
+utf *utf_boolean__void;                 /* (Z)V                               */
+utf *utf_byte__void;                    /* (B)V                               */
+utf *utf_char__void;                    /* (C)V                               */
+utf *utf_short__void;                   /* (S)V                               */
+utf *utf_int__void;                     /* (I)V                               */
+utf *utf_long__void;                    /* (J)V                               */
+utf *utf_float__void;                   /* (F)V                               */
+utf *utf_double__void;                  /* (D)V                               */
+
+utf *utf_void__java_lang_ClassLoader;   /* ()Ljava/lang/ClassLoader;          */
+utf *utf_void__java_lang_Object;        /* ()Ljava/lang/Object;               */
+utf *utf_void__java_lang_Throwable;     /* ()Ljava/lang/Throwable;            */
+utf *utf_java_lang_ClassLoader_java_lang_String__J;
+utf *utf_java_lang_Exception__V;        /* (Ljava/lang/Exception;)V           */
+utf *utf_java_lang_Object__java_lang_Object;
+utf *utf_java_lang_String__void;        /* (Ljava/lang/String;)V              */
+utf *utf_java_lang_String__java_lang_Class;
+utf *utf_java_lang_Thread__V;           /* (Ljava/lang/Thread;)V              */
+utf *utf_java_lang_Thread_java_lang_Throwable__V;
+utf *utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V;
+utf *utf_java_lang_Throwable__void;     /* (Ljava/lang/Throwable;)V           */
+utf *utf_java_lang_Throwable__java_lang_Throwable;
+
+utf *utf_not_named_yet;                 /* special name for unnamed classes   */
+utf *utf_null;
+utf *array_packagename;
+
+
+/* utf_init ********************************************************************
+
+   Initializes the utf8 subsystem.
+
+*******************************************************************************/
+
+void utf8_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("utf8_init");
+
+       /* create utf8 hashtable */
+
+       hashtable_utf = NEW(hashtable);
+
+       hashtable_create(hashtable_utf, HASHTABLE_UTF_SIZE);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_utf_len += sizeof(utf*) * hashtable_utf->size;
+#endif
+
+       /* create utf-symbols for pointer comparison of frequently used strings */
+
+       utf_java_lang_Object           = utf_new_char("java/lang/Object");
+
+       utf_java_lang_Class            = utf_new_char("java/lang/Class");
+       utf_java_lang_ClassLoader      = utf_new_char("java/lang/ClassLoader");
+       utf_java_lang_Cloneable        = utf_new_char("java/lang/Cloneable");
+       utf_java_lang_SecurityManager  = utf_new_char("java/lang/SecurityManager");
+       utf_java_lang_String           = utf_new_char("java/lang/String");
+       utf_java_lang_ThreadGroup      = utf_new_char("java/lang/ThreadGroup");
+
+       utf_java_lang_ref_SoftReference =
+               utf_new_char("java/lang/ref/SoftReference");
+
+       utf_java_lang_ref_WeakReference =
+               utf_new_char("java/lang/ref/WeakReference");
+
+       utf_java_lang_ref_PhantomReference =
+               utf_new_char("java/lang/ref/PhantomReference");
+
+       utf_java_io_Serializable       = utf_new_char("java/io/Serializable");
+
+       utf_java_lang_Throwable        = utf_new_char("java/lang/Throwable");
+       utf_java_lang_Error            = utf_new_char("java/lang/Error");
+
+       utf_java_lang_ClassCircularityError =
+               utf_new_char("java/lang/ClassCircularityError");
+
+       utf_java_lang_ClassFormatError = utf_new_char("java/lang/ClassFormatError");
+
+       utf_java_lang_ExceptionInInitializerError =
+               utf_new_char("java/lang/ExceptionInInitializerError");
+
+       utf_java_lang_IncompatibleClassChangeError =
+               utf_new_char("java/lang/IncompatibleClassChangeError");
+
+       utf_java_lang_InstantiationError =
+               utf_new_char("java/lang/InstantiationError");
+
+       utf_java_lang_InternalError    = utf_new_char("java/lang/InternalError");
+       utf_java_lang_LinkageError     = utf_new_char("java/lang/LinkageError");
+
+       utf_java_lang_NoClassDefFoundError =
+               utf_new_char("java/lang/NoClassDefFoundError");
+
+       utf_java_lang_OutOfMemoryError = utf_new_char("java/lang/OutOfMemoryError");
+
+       utf_java_lang_UnsatisfiedLinkError =
+               utf_new_char("java/lang/UnsatisfiedLinkError");
+
+       utf_java_lang_UnsupportedClassVersionError =
+               utf_new_char("java/lang/UnsupportedClassVersionError");
+
+       utf_java_lang_VerifyError      = utf_new_char("java/lang/VerifyError");
+
+       utf_java_lang_VirtualMachineError =
+               utf_new_char("java/lang/VirtualMachineError");
+
+#if defined(ENABLE_JAVASE)
+       utf_java_lang_AbstractMethodError =
+               utf_new_char("java/lang/AbstractMethodError");
+
+       utf_java_lang_NoSuchFieldError =
+               utf_new_char("java/lang/NoSuchFieldError");
+
+       utf_java_lang_NoSuchMethodError =
+               utf_new_char("java/lang/NoSuchMethodError");
+#endif
+
+       utf_java_lang_Exception        = utf_new_char("java/lang/Exception");
+
+       utf_java_lang_ArithmeticException =
+               utf_new_char("java/lang/ArithmeticException");
+
+       utf_java_lang_ArrayIndexOutOfBoundsException =
+               utf_new_char("java/lang/ArrayIndexOutOfBoundsException");
+
+       utf_java_lang_ArrayStoreException =
+               utf_new_char("java/lang/ArrayStoreException");
+
+       utf_java_lang_ClassCastException =
+               utf_new_char("java/lang/ClassCastException");
+
+       utf_java_lang_ClassNotFoundException =
+               utf_new_char("java/lang/ClassNotFoundException");
+
+       utf_java_lang_CloneNotSupportedException =
+               utf_new_char("java/lang/CloneNotSupportedException");
+
+       utf_java_lang_IllegalAccessException =
+               utf_new_char("java/lang/IllegalAccessException");
+
+       utf_java_lang_IllegalArgumentException =
+               utf_new_char("java/lang/IllegalArgumentException");
+
+       utf_java_lang_IllegalMonitorStateException =
+               utf_new_char("java/lang/IllegalMonitorStateException");
+
+       utf_java_lang_InstantiationException =
+               utf_new_char("java/lang/InstantiationException");
+
+       utf_java_lang_InterruptedException =
+               utf_new_char("java/lang/InterruptedException");
+
+       utf_java_lang_NegativeArraySizeException =
+               utf_new_char("java/lang/NegativeArraySizeException");
+
+       utf_java_lang_NullPointerException =
+               utf_new_char("java/lang/NullPointerException");
+
+       utf_java_lang_RuntimeException =
+               utf_new_char("java/lang/RuntimeException");
+
+       utf_java_lang_StringIndexOutOfBoundsException =
+               utf_new_char("java/lang/StringIndexOutOfBoundsException");
+
+       utf_java_lang_reflect_InvocationTargetException =
+               utf_new_char("java/lang/reflect/InvocationTargetException");
+
+       utf_java_security_PrivilegedActionException =
+               utf_new_char("java/security/PrivilegedActionException");
+#if defined(ENABLE_JAVASE)
+       utf_java_lang_Void             = utf_new_char("java/lang/Void");
+#endif
+
+       utf_java_lang_Boolean          = utf_new_char("java/lang/Boolean");
+       utf_java_lang_Byte             = utf_new_char("java/lang/Byte");
+       utf_java_lang_Character        = utf_new_char("java/lang/Character");
+       utf_java_lang_Short            = utf_new_char("java/lang/Short");
+       utf_java_lang_Integer          = utf_new_char("java/lang/Integer");
+       utf_java_lang_Long             = utf_new_char("java/lang/Long");
+       utf_java_lang_Float            = utf_new_char("java/lang/Float");
+       utf_java_lang_Double           = utf_new_char("java/lang/Double");
+
+#if defined(ENABLE_JAVASE)
+       utf_java_lang_StackTraceElement =
+               utf_new_char("java/lang/StackTraceElement");
+
+       utf_java_lang_reflect_Constructor =
+               utf_new_char("java/lang/reflect/Constructor");
+
+       utf_java_lang_reflect_Field    = utf_new_char("java/lang/reflect/Field");
+       utf_java_lang_reflect_Method   = utf_new_char("java/lang/reflect/Method");
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       utf_java_lang_reflect_VMConstructor = utf_new_char("java/lang/reflect/VMConstructor");
+       utf_java_lang_reflect_VMField       = utf_new_char("java/lang/reflect/VMField");
+       utf_java_lang_reflect_VMMethod      = utf_new_char("java/lang/reflect/VMMethod");
+# endif
+
+       utf_java_util_Vector           = utf_new_char("java/util/Vector");
+#endif
+
+       utf_InnerClasses               = utf_new_char("InnerClasses");
+       utf_ConstantValue              = utf_new_char("ConstantValue");
+       utf_Code                       = utf_new_char("Code");
+       utf_Exceptions                 = utf_new_char("Exceptions");
+       utf_LineNumberTable            = utf_new_char("LineNumberTable");
+       utf_SourceFile                 = utf_new_char("SourceFile");
+
+#if defined(ENABLE_JAVASE)
+       utf_EnclosingMethod            = utf_new_char("EnclosingMethod");
+       utf_Signature                  = utf_new_char("Signature");
+       utf_StackMapTable              = utf_new_char("StackMapTable");
+
+# if defined(ENABLE_ANNOTATIONS)
+       utf_RuntimeVisibleAnnotations            = utf_new_char("RuntimeVisibleAnnotations");
+       utf_RuntimeInvisibleAnnotations          = utf_new_char("RuntimeInvisibleAnnotations");
+       utf_RuntimeVisibleParameterAnnotations   = utf_new_char("RuntimeVisibleParameterAnnotations");
+       utf_RuntimeInvisibleParameterAnnotations = utf_new_char("RuntimeInvisibleParameterAnnotations");
+       utf_AnnotationDefault                    = utf_new_char("AnnotationDefault");
+# endif
+#endif
+
+       utf_init                           = utf_new_char("<init>");
+       utf_clinit                         = utf_new_char("<clinit>");
+       utf_clone                      = utf_new_char("clone");
+       utf_finalize                   = utf_new_char("finalize");
+       utf_invoke                     = utf_new_char("invoke");
+       utf_main                       = utf_new_char("main");
+       utf_run                        = utf_new_char("run");
+
+       utf_add                        = utf_new_char("add");
+       utf_dispatch                   = utf_new_char("dispatch");
+       utf_remove                     = utf_new_char("remove");
+       utf_addThread                  = utf_new_char("addThread");
+       utf_removeThread               = utf_new_char("removeThread");
+       utf_put                        = utf_new_char("put");
+       utf_get                        = utf_new_char("get");
+       utf_uncaughtException          = utf_new_char("uncaughtException");
+       utf_value                      = utf_new_char("value");
+
+       utf_fillInStackTrace           = utf_new_char("fillInStackTrace");
+       utf_findNative                 = utf_new_char("findNative");
+       utf_getSystemClassLoader       = utf_new_char("getSystemClassLoader");
+       utf_initCause                  = utf_new_char("initCause");
+       utf_loadClass                  = utf_new_char("loadClass");
+       utf_loadClassInternal          = utf_new_char("loadClassInternal");
+       utf_printStackTrace            = utf_new_char("printStackTrace");
+
+       utf_division_by_zero           = utf_new_char("/ by zero");
+
+       utf_Z                          = utf_new_char("Z");
+       utf_B                          = utf_new_char("B");
+       utf_C                          = utf_new_char("C");
+       utf_S                          = utf_new_char("S");
+       utf_I                          = utf_new_char("I");
+       utf_J                          = utf_new_char("J");
+       utf_F                          = utf_new_char("F");
+       utf_D                          = utf_new_char("D");
+
+       utf_void__void                 = utf_new_char("()V");
+       utf_boolean__void              = utf_new_char("(Z)V");
+       utf_byte__void                 = utf_new_char("(B)V");
+       utf_char__void                 = utf_new_char("(C)V");
+       utf_short__void                = utf_new_char("(S)V");
+       utf_int__void                  = utf_new_char("(I)V");
+       utf_long__void                 = utf_new_char("(J)V");
+       utf_float__void                = utf_new_char("(F)V");
+       utf_double__void               = utf_new_char("(D)V");
+       utf_void__java_lang_Object     = utf_new_char("()Ljava/lang/Object;");
+       utf_void__java_lang_Throwable  = utf_new_char("()Ljava/lang/Throwable;");
+
+       utf_void__java_lang_ClassLoader =
+               utf_new_char("()Ljava/lang/ClassLoader;");
+
+       utf_java_lang_ClassLoader_java_lang_String__J =
+               utf_new_char("(Ljava/lang/ClassLoader;Ljava/lang/String;)J");
+
+       utf_java_lang_Exception__V     = utf_new_char("(Ljava/lang/Exception;)V");
+
+       utf_java_lang_Object__java_lang_Object =
+               utf_new_char("(Ljava/lang/Object;)Ljava/lang/Object;");
+
+       utf_java_lang_String__void     = utf_new_char("(Ljava/lang/String;)V");
+
+       utf_java_lang_String__java_lang_Class =
+               utf_new_char("(Ljava/lang/String;)Ljava/lang/Class;");
+
+       utf_java_lang_Thread__V        = utf_new_char("(Ljava/lang/Thread;)V");
+
+       utf_java_lang_Thread_java_lang_Throwable__V =
+               utf_new_char("(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
+
+       utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V =
+               utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
+
+       utf_java_lang_Throwable__void  = utf_new_char("(Ljava/lang/Throwable;)V");
+
+       utf_java_lang_Throwable__java_lang_Throwable =
+               utf_new_char("(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
+
+       utf_null                       = utf_new_char("null");
+       utf_not_named_yet              = utf_new_char("\t<not_named_yet>");
+       array_packagename              = utf_new_char("\t<the array package>");
+}
+
+
+/* utf_hashkey *****************************************************************
+
+   The hashkey is computed from the utf-text by using up to 8
+   characters.  For utf-symbols longer than 15 characters 3 characters
+   are taken from the beginning and the end, 2 characters are taken
+   from the middle.
+
+*******************************************************************************/
+
+#define nbs(val) ((u4) *(++text) << val) /* get next byte, left shift by val  */
+#define fbs(val) ((u4) *(  text) << val) /* get first byte, left shift by val */
+
+u4 utf_hashkey(const char *text, u4 length)
+{
+       const char *start_pos = text;       /* pointer to utf text                */
+       u4 a;
+
+       switch (length) {
+       case 0: /* empty string */
+               return 0;
+
+       case 1: return fbs(0);
+       case 2: return fbs(0) ^ nbs(3);
+       case 3: return fbs(0) ^ nbs(3) ^ nbs(5);
+       case 4: return fbs(0) ^ nbs(2) ^ nbs(4) ^ nbs(6);
+       case 5: return fbs(0) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(6);
+       case 6: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(5) ^ nbs(6);
+       case 7: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(5) ^ nbs(6);
+       case 8: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(5) ^ nbs(6) ^ nbs(7);
+
+       case 9:
+               a = fbs(0);
+               a ^= nbs(1);
+               a ^= nbs(2);
+               text++;
+               return a ^ nbs(4) ^ nbs(5) ^ nbs(6) ^ nbs(7) ^ nbs(8);
+
+       case 10:
+               a = fbs(0);
+               text++;
+               a ^= nbs(2);
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text++;
+               return a ^ nbs(6) ^ nbs(7) ^ nbs(8) ^ nbs(9);
+
+       case 11:
+               a = fbs(0);
+               text++;
+               a ^= nbs(2);
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text++;
+               return a ^ nbs(6) ^ nbs(7) ^ nbs(8) ^ nbs(9) ^ nbs(10);
+
+       case 12:
+               a = fbs(0);
+               text += 2;
+               a ^= nbs(2);
+               a ^= nbs(3);
+               text++;
+               a ^= nbs(5);
+               a ^= nbs(6);
+               a ^= nbs(7);
+               text++;
+               return a ^ nbs(9) ^ nbs(10);
+
+       case 13:
+               a = fbs(0);
+               a ^= nbs(1);
+               text++;
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text += 2;      
+               a ^= nbs(7);
+               a ^= nbs(8);
+               text += 2;
+               return a ^ nbs(9) ^ nbs(10);
+
+       case 14:
+               a = fbs(0);
+               text += 2;      
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text += 2;      
+               a ^= nbs(7);
+               a ^= nbs(8);
+               text += 2;
+               return a ^ nbs(9) ^ nbs(10) ^ nbs(11);
+
+       case 15:
+               a = fbs(0);
+               text += 2;      
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text += 2;      
+               a ^= nbs(7);
+               a ^= nbs(8);
+               text += 2;
+               return a ^ nbs(9) ^ nbs(10) ^ nbs(11);
+
+       default:  /* 3 characters from beginning */
+               a = fbs(0);
+               text += 2;
+               a ^= nbs(3);
+               a ^= nbs(4);
+
+               /* 2 characters from middle */
+               text = start_pos + (length / 2);
+               a ^= fbs(5);
+               text += 2;
+               a ^= nbs(6);    
+
+               /* 3 characters from end */
+               text = start_pos + length - 4;
+
+               a ^= fbs(7);
+               text++;
+
+               return a ^ nbs(10) ^ nbs(11);
+    }
+}
+
+/* utf_full_hashkey ************************************************************
+
+   This function computes a hash value using all bytes in the string.
+
+   The algorithm is the "One-at-a-time" algorithm as published
+   by Bob Jenkins on http://burtleburtle.net/bob/hash/doobs.html.
+
+*******************************************************************************/
+
+u4 utf_full_hashkey(const char *text, u4 length)
+{
+       register const unsigned char *p = (const unsigned char *) text;
+       register u4 hash;
+       register u4 i;
+
+       hash = 0;
+       for (i=length; i--;)
+       {
+           hash += *p++;
+           hash += (hash << 10);
+           hash ^= (hash >> 6);
+       }
+       hash += (hash << 3);
+       hash ^= (hash >> 11);
+       hash += (hash << 15);
+
+       return hash;
+}
+
+/* unicode_hashkey *************************************************************
+
+   Compute the hashkey of a unicode string.
+
+*******************************************************************************/
+
+u4 unicode_hashkey(u2 *text, u2 len)
+{
+       return utf_hashkey((char *) text, len);
+}
+
+
+/* utf_new *********************************************************************
+
+   Creates a new utf-symbol, the text of the symbol is passed as a
+   u1-array. The function searches the utf-hashtable for a utf-symbol
+   with this text. On success the element returned, otherwise a new
+   hashtable element is created.
+
+   If the number of entries in the hashtable exceeds twice the size of
+   the hashtable slots a reorganization of the hashtable is done and
+   the utf symbols are copied to a new hashtable with doubled size.
+
+*******************************************************************************/
+
+utf *utf_new(const char *text, u2 length)
+{
+       u4 key;                             /* hashkey computed from utf-text     */
+       u4 slot;                            /* slot in hashtable                  */
+       utf *u;                             /* hashtable element                  */
+       u2 i;
+
+       LOCK_MONITOR_ENTER(hashtable_utf->header);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_utf_new++;
+#endif
+
+       key  = utf_hashkey(text, length);
+       slot = key & (hashtable_utf->size - 1);
+       u    = hashtable_utf->ptr[slot];
+
+       /* search external hash chain for utf-symbol */
+
+       while (u) {
+               if (u->blength == length) {
+                       /* compare text of hashtable elements */
+
+                       for (i = 0; i < length; i++)
+                               if (text[i] != u->text[i])
+                                       goto nomatch;
+                       
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_utf_new_found++;
+#endif
+
+                       /* symbol found in hashtable */
+
+                       LOCK_MONITOR_EXIT(hashtable_utf->header);
+
+                       return u;
+               }
+
+       nomatch:
+               u = u->hashlink; /* next element in external chain */
+       }
+
+       /* location in hashtable found, create new utf element */
+
+       u = NEW(utf);
+
+       u->blength  = length;               /* length in bytes of utfstring       */
+       u->hashlink = hashtable_utf->ptr[slot]; /* link in external hashchain     */
+       u->text     = mem_alloc(length + 1);/* allocate memory for utf-text       */
+
+       memcpy(u->text, text, length);      /* copy utf-text                      */
+       u->text[length] = '\0';
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_utf_len += sizeof(utf) + length + 1;
+#endif
+
+       hashtable_utf->ptr[slot] = u;       /* insert symbol into table           */
+       hashtable_utf->entries++;           /* update number of entries           */
+
+       if (hashtable_utf->entries > (hashtable_utf->size * 2)) {
+
+        /* reorganization of hashtable, average length of the external
+           chains is approx. 2 */
+
+               hashtable *newhash;                              /* the new hashtable */
+               u4         i;
+               utf       *u;
+               utf       *nextu;
+               u4         slot;
+
+               /* create new hashtable, double the size */
+
+               newhash = hashtable_resize(hashtable_utf, hashtable_utf->size * 2);
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_utf_len += sizeof(utf*) * hashtable_utf->size;
+#endif
+
+               /* transfer elements to new hashtable */
+
+               for (i = 0; i < hashtable_utf->size; i++) {
+                       u = hashtable_utf->ptr[i];
+
+                       while (u) {
+                               nextu = u->hashlink;
+                               slot  = utf_hashkey(u->text, u->blength) & (newhash->size - 1);
+                                               
+                               u->hashlink = (utf *) newhash->ptr[slot];
+                               newhash->ptr[slot] = u;
+
+                               /* follow link in external hash chain */
+
+                               u = nextu;
+                       }
+               }
+       
+               /* dispose old table */
+
+               hashtable_free(hashtable_utf);
+
+               hashtable_utf = newhash;
+       }
+
+       LOCK_MONITOR_EXIT(hashtable_utf->header);
+
+       return u;
+}
+
+
+/* utf_new_u2 ******************************************************************
+
+   Make utf symbol from u2 array, if isclassname is true '.' is
+   replaced by '/'.
+
+*******************************************************************************/
+
+utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
+{
+       char *buffer;                   /* memory buffer for  unicode characters  */
+       char *pos;                      /* pointer to current position in buffer  */
+       u4 left;                        /* unicode characters left                */
+       u4 buflength;                   /* utf length in bytes of the u2 array    */
+       utf *result;                    /* resulting utf-string                   */
+       int i;          
+
+       /* determine utf length in bytes and allocate memory */
+
+       buflength = u2_utflength(unicode_pos, unicode_length); 
+       buffer    = MNEW(char, buflength);
+       left = buflength;
+       pos  = buffer;
+
+       for (i = 0; i++ < unicode_length; unicode_pos++) {
+               /* next unicode character */
+               u2 c = *unicode_pos;
+               
+               if ((c != 0) && (c < 0x80)) {
+                       /* 1 character */       
+                       left--;
+               if ((int) left < 0) break;
+                       /* convert classname */
+                       if (isclassname && c == '.')
+                               *pos++ = '/';
+                       else
+                               *pos++ = (char) c;
+
+               } else if (c < 0x800) {             
+                       /* 2 characters */                              
+               unsigned char high = c >> 6;
+               unsigned char low  = c & 0x3F;
+                       left = left - 2;
+               if ((int) left < 0) break;
+               *pos++ = high | 0xC0; 
+               *pos++ = low  | 0x80;     
+
+               } else {         
+               /* 3 characters */                              
+               char low  = c & 0x3f;
+               char mid  = (c >> 6) & 0x3F;
+               char high = c >> 12;
+                       left = left - 3;
+               if ((int) left < 0) break;
+               *pos++ = high | 0xE0; 
+               *pos++ = mid  | 0x80;  
+               *pos++ = low  | 0x80;   
+               }
+       }
+       
+       /* insert utf-string into symbol-table */
+       result = utf_new(buffer,buflength);
+
+       MFREE(buffer, char, buflength);
+
+       return result;
+}
+
+
+/* utf_new_char ****************************************************************
+
+   Creates a new utf symbol, the text for this symbol is passed as a
+   c-string ( = char* ).
+
+*******************************************************************************/
+
+utf *utf_new_char(const char *text)
+{
+       return utf_new(text, strlen(text));
+}
+
+
+/* utf_new_char_classname ******************************************************
+
+   Creates a new utf symbol, the text for this symbol is passed as a
+   c-string ( = char* ) "." characters are going to be replaced by
+   "/". Since the above function is used often, this is a separte
+   function, instead of an if.
+
+*******************************************************************************/
+
+utf *utf_new_char_classname(const char *text)
+{
+       if (strchr(text, '.')) {
+               char *txt = strdup(text);
+               char *end = txt + strlen(txt);
+               char *c;
+               utf *tmpRes;
+
+               for (c = txt; c < end; c++)
+                       if (*c == '.') *c = '/';
+
+               tmpRes = utf_new(txt, strlen(txt));
+               FREE(txt, 0);
+
+               return tmpRes;
+
+       } else
+               return utf_new(text, strlen(text));
+}
+
+
+/* utf_nextu2 ******************************************************************
+
+   Read the next unicode character from the utf string and increment
+   the utf-string pointer accordingly.
+
+   CAUTION: This function is unsafe for input that was not checked 
+            by is_valid_utf!
+
+*******************************************************************************/
+
+u2 utf_nextu2(char **utf_ptr)
+{
+    /* uncompressed unicode character */
+    u2 unicode_char = 0;
+    /* current position in utf text */ 
+    unsigned char *utf = (unsigned char *) (*utf_ptr);
+    /* bytes representing the unicode character */
+    unsigned char ch1, ch2, ch3;
+    /* number of bytes used to represent the unicode character */
+    int len = 0;
+       
+    switch ((ch1 = utf[0]) >> 4) {
+       default: /* 1 byte */
+               (*utf_ptr)++;
+               return (u2) ch1;
+       case 0xC: 
+       case 0xD: /* 2 bytes */
+               if (((ch2 = utf[1]) & 0xC0) == 0x80) {
+                       unsigned char high = ch1 & 0x1F;
+                       unsigned char low  = ch2 & 0x3F;
+                       unicode_char = (high << 6) + low;
+                       len = 2;
+               }
+               break;
+
+       case 0xE: /* 2 or 3 bytes */
+               if (((ch2 = utf[1]) & 0xC0) == 0x80) {
+                       if (((ch3 = utf[2]) & 0xC0) == 0x80) {
+                               unsigned char low  = ch3 & 0x3f;
+                               unsigned char mid  = ch2 & 0x3f;
+                               unsigned char high = ch1 & 0x0f;
+                               unicode_char = (((high << 6) + mid) << 6) + low;
+                               len = 3;
+                       } else
+                               len = 2;                                           
+               }
+               break;
+    }
+
+    /* update position in utf-text */
+    *utf_ptr = (char *) (utf + len);
+
+    return unicode_char;
+}
+
+
+/* utf_bytes *******************************************************************
+
+   Determine number of bytes (aka. octets) in the utf string.
+
+   IN:
+      u............utf string
+
+   OUT:
+      The number of octets of this utf string.
+         There is _no_ terminating zero included in this count.
+
+*******************************************************************************/
+
+u4 utf_bytes(utf *u)
+{
+       return u->blength;
+}
+
+
+/* utf_get_number_of_u2s_for_buffer ********************************************
+
+   Determine number of UTF-16 u2s in the given UTF-8 buffer
+
+   CAUTION: This function is unsafe for input that was not checked 
+            by is_valid_utf!
+
+   CAUTION: Use this function *only* when you want to convert an UTF-8 buffer
+   to an array of u2s (UTF-16) and want to know how many of them you will get.
+   All other uses of this function are probably wrong.
+
+   IN:
+      buffer........points to first char in buffer
+         blength.......number of _bytes_ in the buffer
+
+   OUT:
+      the number of u2s needed to hold this string in UTF-16 encoding.
+         There is _no_ terminating zero included in this count.
+
+   NOTE: Unlike utf_get_number_of_u2s, this function never throws an
+   exception.
+
+*******************************************************************************/
+
+u4 utf_get_number_of_u2s_for_buffer(const char *buffer, u4 blength)
+{
+       const char *endpos;                 /* points behind utf string           */
+       const char *utf_ptr;                /* current position in utf text       */
+       u4 len = 0;                         /* number of unicode characters       */
+
+       utf_ptr = buffer;
+       endpos = utf_ptr + blength;
+
+       while (utf_ptr < endpos) {
+               len++;
+               /* next unicode character */
+               utf_nextu2((char **)&utf_ptr);
+       }
+
+       assert(utf_ptr == endpos);
+
+       return len;
+}
+
+
+/* utf_get_number_of_u2s *******************************************************
+
+   Determine number of UTF-16 u2s in the utf string.
+
+   CAUTION: This function is unsafe for input that was not checked 
+            by is_valid_utf!
+
+   CAUTION: Use this function *only* when you want to convert a utf string
+   to an array of u2s and want to know how many of them you will get.
+   All other uses of this function are probably wrong.
+
+   IN:
+      u............utf string
+
+   OUT:
+      the number of u2s needed to hold this string in UTF-16 encoding.
+         There is _no_ terminating zero included in this count.
+         XXX 0 if a NullPointerException has been thrown (see below)
+
+*******************************************************************************/
+
+u4 utf_get_number_of_u2s(utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+       u4 len = 0;                         /* number of unicode characters       */
+
+       /* XXX this is probably not checked by most callers! Review this after */
+       /* the invalid uses of this function have been eliminated */
+       if (u == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) {
+               len++;
+               /* next unicode character */
+               utf_nextu2(&utf_ptr);
+       }
+
+       if (utf_ptr != endpos) {
+               /* string ended abruptly */
+               exceptions_throw_internalerror("Illegal utf8 string");
+               return 0;
+       }
+
+       return len;
+}
+
+
+/* utf8_safe_number_of_u2s *****************************************************
+
+   Determine number of UTF-16 u2s needed for decoding the given UTF-8 string.
+   (For invalid UTF-8 the U+fffd replacement character will be counted.)
+
+   This function is safe even for invalid UTF-8 strings.
+
+   IN:
+      text..........zero-terminated(!) UTF-8 string (may be invalid)
+                       must NOT be NULL
+         nbytes........strlen(text). (This is needed to completely emulate
+                       the RI).
+
+   OUT:
+      the number of u2s needed to hold this string in UTF-16 encoding.
+         There is _no_ terminating zero included in this count.
+
+*******************************************************************************/
+
+s4 utf8_safe_number_of_u2s(const char *text, s4 nbytes) {
+       register const unsigned char *t;
+       register s4 byte;
+       register s4 len;
+       register const unsigned char *tlimit;
+       s4 byte1;
+       s4 byte2;
+       s4 byte3;
+       s4 value;
+       s4 skip;
+
+       assert(text);
+       assert(nbytes >= 0);
+
+       len = 0;
+       t = (const unsigned char *) text;
+       tlimit = t + nbytes;
+
+       /* CAUTION: Keep this code in sync with utf8_safe_convert_to_u2s! */
+
+       while (1) {
+               byte = *t++;
+
+               if (byte & 0x80) {
+                       /* highest bit set, non-ASCII character */
+
+                       if ((byte & 0xe0) == 0xc0) {
+                               /* 2-byte: should be 110..... 10...... ? */
+
+                               if ((*t++ & 0xc0) == 0x80)
+                                       ; /* valid 2-byte */
+                               else
+                                       t--; /* invalid */
+                       }
+                       else if ((byte & 0xf0) == 0xe0) {
+                               /* 3-byte: should be 1110.... 10...... 10...... */
+                               /*                            ^t                */
+
+                               if (t + 2 > tlimit)
+                                       return len + 1; /* invalid, stop here */
+
+                               if ((*t++ & 0xc0) == 0x80) {
+                                       if ((*t++ & 0xc0) == 0x80)
+                                               ; /* valid 3-byte */
+                                       else
+                                               t--; /* invalid */
+                               }
+                               else
+                                       t--; /* invalid */
+                       }
+                       else if ((byte & 0xf8) == 0xf0) {
+                               /* 4-byte: should be 11110... 10...... 10...... 10...... */
+                               /*                            ^t                         */
+
+                               if (t + 3 > tlimit)
+                                       return len + 1; /* invalid, stop here */
+
+                               if (((byte1 = *t++) & 0xc0) == 0x80) {
+                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
+                                               if (((byte3 = *t++) & 0xc0) == 0x80) {
+                                                       /* valid 4-byte UTF-8? */
+                                                       value = ((byte  & 0x07) << 18)
+                                                                 | ((byte1 & 0x3f) << 12)
+                                                                 | ((byte2 & 0x3f) <<  6)
+                                                                 | ((byte3 & 0x3f)      );
+
+                                                       if (value > 0x10FFFF)
+                                                               ; /* invalid */
+                                                       else if (value > 0xFFFF)
+                                                               len += 1; /* we need surrogates */
+                                                       else
+                                                               ; /* 16bit suffice */
+                                               }
+                                               else
+                                                       t--; /* invalid */
+                                       }
+                                       else
+                                               t--; /* invalid */
+                               }
+                               else
+                                       t--; /* invalid */
+                       }
+                       else if ((byte & 0xfc) == 0xf8) {
+                               /* invalid 5-byte */
+                               if (t + 4 > tlimit)
+                                       return len + 1; /* invalid, stop here */
+
+                               skip = 4;
+                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
+                                       t++;
+                       }
+                       else if ((byte & 0xfe) == 0xfc) {
+                               /* invalid 6-byte */
+                               if (t + 5 > tlimit)
+                                       return len + 1; /* invalid, stop here */
+
+                               skip = 5;
+                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
+                                       t++;
+                       }
+                       else
+                               ; /* invalid */
+               }
+               else {
+                       /* NUL */
+
+                       if (byte == 0)
+                               break;
+
+                       /* ASCII character, common case */
+               }
+
+               len++;
+       }
+
+       return len;
+}
+
+
+/* utf8_safe_convert_to_u2s ****************************************************
+
+   Convert the given UTF-8 string to UTF-16 into a pre-allocated buffer.
+   (Invalid UTF-8 will be replaced with the U+fffd replacement character.)
+   Use utf8_safe_number_of_u2s to determine the number of u2s to allocate.
+
+   This function is safe even for invalid UTF-8 strings.
+
+   IN:
+      text..........zero-terminated(!) UTF-8 string (may be invalid)
+                       must NOT be NULL
+         nbytes........strlen(text). (This is needed to completely emulate
+                                       the RI).
+         buffer........a preallocated array of u2s to receive the decoded
+                       string. Use utf8_safe_number_of_u2s to get the
+                                       required number of u2s for allocating this.
+
+*******************************************************************************/
+
+#define UNICODE_REPLACEMENT  0xfffd
+
+void utf8_safe_convert_to_u2s(const char *text, s4 nbytes, u2 *buffer) {
+       register const unsigned char *t;
+       register s4 byte;
+       register const unsigned char *tlimit;
+       s4 byte1;
+       s4 byte2;
+       s4 byte3;
+       s4 value;
+       s4 skip;
+
+       assert(text);
+       assert(nbytes >= 0);
+
+       t = (const unsigned char *) text;
+       tlimit = t + nbytes;
+
+       /* CAUTION: Keep this code in sync with utf8_safe_number_of_u2s! */
+
+       while (1) {
+               byte = *t++;
+
+               if (byte & 0x80) {
+                       /* highest bit set, non-ASCII character */
+
+                       if ((byte & 0xe0) == 0xc0) {
+                               /* 2-byte: should be 110..... 10...... */
+
+                               if (((byte1 = *t++) & 0xc0) == 0x80) {
+                                       /* valid 2-byte UTF-8 */
+                                       *buffer++ = ((byte  & 0x1f) << 6)
+                                                         | ((byte1 & 0x3f)     );
+                               }
+                               else {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       t--;
+                               }
+                       }
+                       else if ((byte & 0xf0) == 0xe0) {
+                               /* 3-byte: should be 1110.... 10...... 10...... */
+
+                               if (t + 2 > tlimit) {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       return;
+                               }
+
+                               if (((byte1 = *t++) & 0xc0) == 0x80) {
+                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
+                                               /* valid 3-byte UTF-8 */
+                                               *buffer++ = ((byte  & 0x0f) << 12)
+                                                                 | ((byte1 & 0x3f) <<  6)
+                                                                 | ((byte2 & 0x3f)      );
+                                       }
+                                       else {
+                                               *buffer++ = UNICODE_REPLACEMENT;
+                                               t--;
+                                       }
+                               }
+                               else {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       t--;
+                               }
+                       }
+                       else if ((byte & 0xf8) == 0xf0) {
+                               /* 4-byte: should be 11110... 10...... 10...... 10...... */
+
+                               if (t + 3 > tlimit) {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       return;
+                               }
+
+                               if (((byte1 = *t++) & 0xc0) == 0x80) {
+                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
+                                               if (((byte3 = *t++) & 0xc0) == 0x80) {
+                                                       /* valid 4-byte UTF-8? */
+                                                       value = ((byte  & 0x07) << 18)
+                                                                 | ((byte1 & 0x3f) << 12)
+                                                                 | ((byte2 & 0x3f) <<  6)
+                                                                 | ((byte3 & 0x3f)      );
+
+                                                       if (value > 0x10FFFF) {
+                                                               *buffer++ = UNICODE_REPLACEMENT;
+                                                       }
+                                                       else if (value > 0xFFFF) {
+                                                               /* we need surrogates */
+                                                               *buffer++ = 0xd800 | ((value >> 10) - 0x40);
+                                                               *buffer++ = 0xdc00 | (value & 0x03ff);
+                                                       }
+                                                       else
+                                                               *buffer++ = value; /* 16bit suffice */
+                                               }
+                                               else {
+                                                       *buffer++ = UNICODE_REPLACEMENT;
+                                                       t--;
+                                               }
+                                       }
+                                       else {
+                                               *buffer++ = UNICODE_REPLACEMENT;
+                                               t--;
+                                       }
+                               }
+                               else {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       t--;
+                               }
+                       }
+                       else if ((byte & 0xfc) == 0xf8) {
+                               if (t + 4 > tlimit) {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       return;
+                               }
+
+                               skip = 4;
+                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
+                                       t++;
+                               *buffer++ = UNICODE_REPLACEMENT;
+                       }
+                       else if ((byte & 0xfe) == 0xfc) {
+                               if (t + 5 > tlimit) {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       return;
+                               }
+
+                               skip = 5;
+                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
+                                       t++;
+                               *buffer++ = UNICODE_REPLACEMENT;
+                       }
+                       else
+                               *buffer++ = UNICODE_REPLACEMENT;
+               }
+               else {
+                       /* NUL */
+
+                       if (byte == 0)
+                               break;
+
+                       /* ASCII character, common case */
+
+                       *buffer++ = byte;
+               }
+       }
+}
+
+
+/* u2_utflength ****************************************************************
+
+   Returns the utf length in bytes of a u2 array.
+
+*******************************************************************************/
+
+u4 u2_utflength(u2 *text, u4 u2_length)
+{
+       u4 result_len = 0;                  /* utf length in bytes                */
+       u2 ch;                              /* current unicode character          */
+       u4 len;
+       
+       for (len = 0; len < u2_length; len++) {
+               /* next unicode character */
+               ch = *text++;
+         
+               /* determine bytes required to store unicode character as utf */
+               if (ch && (ch < 0x80)) 
+                       result_len++;
+               else if (ch < 0x800)
+                       result_len += 2;        
+               else 
+                       result_len += 3;        
+       }
+
+    return result_len;
+}
+
+
+/* utf_copy ********************************************************************
+
+   Copy the given utf string byte-for-byte to a buffer.
+
+   IN:
+      buffer.......the buffer
+         u............the utf string
+
+*******************************************************************************/
+
+void utf_copy(char *buffer, utf *u)
+{
+       /* our utf strings are zero-terminated (done by utf_new) */
+       MCOPY(buffer, u->text, char, u->blength + 1);
+}
+
+
+/* utf_cat *********************************************************************
+
+   Append the given utf string byte-for-byte to a buffer.
+
+   IN:
+      buffer.......the buffer
+         u............the utf string
+
+*******************************************************************************/
+
+void utf_cat(char *buffer, utf *u)
+{
+       /* our utf strings are zero-terminated (done by utf_new) */
+       MCOPY(buffer + strlen(buffer), u->text, char, u->blength + 1);
+}
+
+
+/* utf_copy_classname **********************************************************
+
+   Copy the given utf classname byte-for-byte to a buffer.
+   '/' is replaced by '.'
+
+   IN:
+      buffer.......the buffer
+         u............the utf string
+
+*******************************************************************************/
+
+void utf_copy_classname(char *buffer, utf *u)
+{
+       char *bufptr;
+       char *srcptr;
+       char *endptr;
+       char ch;
+
+       bufptr = buffer;
+       srcptr = u->text;
+       endptr = UTF_END(u) + 1; /* utfs are zero-terminared by utf_new */
+
+       while (srcptr != endptr) {
+               ch = *srcptr++;
+               if (ch == '/')
+                       ch = '.';
+               *bufptr++ = ch;
+       }
+}
+
+
+/* utf_cat *********************************************************************
+
+   Append the given utf classname byte-for-byte to a buffer.
+   '/' is replaced by '.'
+
+   IN:
+      buffer.......the buffer
+         u............the utf string
+
+*******************************************************************************/
+
+void utf_cat_classname(char *buffer, utf *u)
+{
+       utf_copy_classname(buffer + strlen(buffer), u);
+}
+
+/* utf_display_printable_ascii *************************************************
+
+   Write utf symbol to stdout (for debugging purposes).
+   Non-printable and non-ASCII characters are printed as '?'.
+
+*******************************************************************************/
+
+void utf_display_printable_ascii(utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+
+       if (u == NULL) {
+               printf("NULL");
+               fflush(stdout);
+               return;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) {
+               /* read next unicode character */
+
+               u2 c = utf_nextu2(&utf_ptr);
+
+               if ((c >= 32) && (c <= 127))
+                       printf("%c", c);
+               else
+                       printf("?");
+       }
+
+       fflush(stdout);
+}
+
+
+/* utf_display_printable_ascii_classname ***************************************
+
+   Write utf symbol to stdout with `/' converted to `.' (for debugging
+   purposes).
+   Non-printable and non-ASCII characters are printed as '?'.
+
+*******************************************************************************/
+
+void utf_display_printable_ascii_classname(utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+
+       if (u == NULL) {
+               printf("NULL");
+               fflush(stdout);
+               return;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) {
+               /* read next unicode character */
+
+               u2 c = utf_nextu2(&utf_ptr);
+
+               if (c == '/')
+                       c = '.';
+
+               if ((c >= 32) && (c <= 127))
+                       printf("%c", c);
+               else
+                       printf("?");
+       }
+
+       fflush(stdout);
+}
+
+
+/* utf_sprint_convert_to_latin1 ************************************************
+       
+   Write utf symbol into c-string (for debugging purposes).
+   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
+   invalid results.
+
+*******************************************************************************/
+
+void utf_sprint_convert_to_latin1(char *buffer, utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+       u2 pos = 0;                         /* position in c-string               */
+
+       if (!u) {
+               strcpy(buffer, "NULL");
+               return;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) 
+               /* copy next unicode character */       
+               buffer[pos++] = utf_nextu2(&utf_ptr);
+
+       /* terminate string */
+       buffer[pos] = '\0';
+}
+
+
+/* utf_sprint_convert_to_latin1_classname **************************************
+       
+   Write utf symbol into c-string with `/' converted to `.' (for debugging
+   purposes).
+   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
+   invalid results.
+
+*******************************************************************************/
+
+void utf_sprint_convert_to_latin1_classname(char *buffer, utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+       u2 pos = 0;                         /* position in c-string               */
+
+       if (!u) {
+               strcpy(buffer, "NULL");
+               return;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) {
+               /* copy next unicode character */       
+               u2 c = utf_nextu2(&utf_ptr);
+               if (c == '/') c = '.';
+               buffer[pos++] = c;
+       }
+
+       /* terminate string */
+       buffer[pos] = '\0';
+}
+
+
+/* utf_strcat_convert_to_latin1 ************************************************
+       
+   Like libc strcat, but uses an utf8 string.
+   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
+   invalid results.
+
+*******************************************************************************/
+
+void utf_strcat_convert_to_latin1(char *buffer, utf *u)
+{
+       utf_sprint_convert_to_latin1(buffer + strlen(buffer), u);
+}
+
+
+/* utf_strcat_convert_to_latin1_classname **************************************
+       
+   Like libc strcat, but uses an utf8 string.
+   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
+   invalid results.
+
+*******************************************************************************/
+
+void utf_strcat_convert_to_latin1_classname(char *buffer, utf *u)
+{
+       utf_sprint_convert_to_latin1_classname(buffer + strlen(buffer), u);
+}
+
+
+/* utf_fprint_printable_ascii **************************************************
+       
+   Write utf symbol into file.
+   Non-printable and non-ASCII characters are printed as '?'.
+
+*******************************************************************************/
+
+void utf_fprint_printable_ascii(FILE *file, utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+
+       if (!u)
+               return;
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) { 
+               /* read next unicode character */                
+               u2 c = utf_nextu2(&utf_ptr);                            
+
+               if (c >= 32 && c <= 127) fprintf(file, "%c", c);
+               else fprintf(file, "?");
+       }
+}
+
+
+/* utf_fprint_printable_ascii_classname ****************************************
+       
+   Write utf symbol into file with `/' converted to `.'.
+   Non-printable and non-ASCII characters are printed as '?'.
+
+*******************************************************************************/
+
+void utf_fprint_printable_ascii_classname(FILE *file, utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+
+    if (!u)
+               return;
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) { 
+               /* read next unicode character */                
+               u2 c = utf_nextu2(&utf_ptr);                            
+               if (c == '/') c = '.';
+
+               if (c >= 32 && c <= 127) fprintf(file, "%c", c);
+               else fprintf(file, "?");
+       }
+}
+
+
+/* is_valid_utf ****************************************************************
+
+   Return true if the given string is a valid UTF-8 string.
+
+   utf_ptr...points to first character
+   end_pos...points after last character
+
+*******************************************************************************/
+
+/*  static unsigned long min_codepoint[6] = {0,1L<<7,1L<<11,1L<<16,1L<<21,1L<<26}; */
+
+bool is_valid_utf(char *utf_ptr, char *end_pos)
+{
+       int bytes;
+       int len,i;
+       char c;
+       unsigned long v;
+
+       if (end_pos < utf_ptr) return false;
+       bytes = end_pos - utf_ptr;
+       while (bytes--) {
+               c = *utf_ptr++;
+
+               if (!c) return false;                     /* 0x00 is not allowed */
+               if ((c & 0x80) == 0) continue;            /* ASCII */
+
+               if      ((c & 0xe0) == 0xc0) len = 1;     /* 110x xxxx */
+               else if ((c & 0xf0) == 0xe0) len = 2;     /* 1110 xxxx */
+               else if ((c & 0xf8) == 0xf0) len = 3;     /* 1111 0xxx */
+               else if ((c & 0xfc) == 0xf8) len = 4;     /* 1111 10xx */
+               else if ((c & 0xfe) == 0xfc) len = 5;     /* 1111 110x */
+               else return false;                        /* invalid leading byte */
+
+               if (len > 2) return false;                /* Java limitation */
+
+               v = (unsigned long)c & (0x3f >> len);
+               
+               if ((bytes -= len) < 0) return false;     /* missing bytes */
+
+               for (i = len; i--; ) {
+                       c = *utf_ptr++;
+                       if ((c & 0xc0) != 0x80)               /* 10xx xxxx */
+                               return false;
+                       v = (v << 6) | (c & 0x3f);
+               }
+
+               if (v == 0) {
+                       if (len != 1) return false;           /* Java special */
+
+               } else {
+                       /* Sun Java seems to allow overlong UTF-8 encodings */
+                       
+                       /* if (v < min_codepoint[len]) */
+                               /* XXX throw exception? */
+               }
+
+               /* surrogates in UTF-8 seem to be allowed in Java classfiles */
+               /* if (v >= 0xd800 && v <= 0xdfff) return false; */ /* surrogates */
+
+               /* even these seem to be allowed */
+               /* if (v == 0xfffe || v == 0xffff) return false; */ /* invalid codepoints */
+       }
+
+       return true;
+}
+
+
+/* is_valid_name ***************************************************************
+
+   Return true if the given string may be used as a class/field/method
+   name. (Currently this only disallows empty strings and control
+   characters.)
+
+   NOTE: The string is assumed to have passed is_valid_utf!
+
+   utf_ptr...points to first character
+   end_pos...points after last character
+
+*******************************************************************************/
+
+bool is_valid_name(char *utf_ptr, char *end_pos)
+{
+       if (end_pos <= utf_ptr) return false; /* disallow empty names */
+
+       while (utf_ptr < end_pos) {
+               unsigned char c = *utf_ptr++;
+
+               if (c < 0x20) return false; /* disallow control characters */
+               if (c == 0xc0 && (unsigned char) *utf_ptr == 0x80)  /* disallow zero */
+                       return false;
+       }
+
+       return true;
+}
+
+bool is_valid_name_utf(utf *u)
+{
+       return is_valid_name(u->text, UTF_END(u));
+}
+
+
+/* utf_show ********************************************************************
+
+   Writes the utf symbols in the utfhash to stdout and displays the
+   number of external hash chains grouped according to the chainlength
+   (for debugging purposes).
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void utf_show(void)
+{
+
+#define CHAIN_LIMIT 20               /* limit for seperated enumeration */
+
+       u4 chain_count[CHAIN_LIMIT]; /* numbers of chains */
+       u4 max_chainlength = 0;      /* maximum length of the chains */
+       u4 sum_chainlength = 0;      /* sum of the chainlengths */
+       u4 beyond_limit = 0;         /* number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */
+       u4 i;
+
+       printf("UTF-HASH:\n");
+
+       /* show element of utf-hashtable */
+
+       for (i = 0; i < hashtable_utf->size; i++) {
+               utf *u = hashtable_utf->ptr[i];
+
+               if (u) {
+                       printf("SLOT %d: ", (int) i);
+
+                       while (u) {
+                               printf("'");
+                               utf_display_printable_ascii(u);
+                               printf("' ");
+                               u = u->hashlink;
+                       }       
+                       printf("\n");
+               }
+       }
+
+       printf("UTF-HASH: %d slots for %d entries\n", 
+                  (int) hashtable_utf->size, (int) hashtable_utf->entries );
+
+       if (hashtable_utf->entries == 0)
+               return;
+
+       printf("chains:\n  chainlength    number of chains    %% of utfstrings\n");
+
+       for (i=0;i<CHAIN_LIMIT;i++)
+               chain_count[i]=0;
+
+       /* count numbers of hashchains according to their length */
+       for (i=0; i<hashtable_utf->size; i++) {
+                 
+               utf *u = (utf*) hashtable_utf->ptr[i];
+               u4 chain_length = 0;
+
+               /* determine chainlength */
+               while (u) {
+                       u = u->hashlink;
+                       chain_length++;
+               }
+
+               /* update sum of all chainlengths */
+               sum_chainlength+=chain_length;
+
+               /* determine the maximum length of the chains */
+               if (chain_length>max_chainlength)
+                       max_chainlength = chain_length;
+
+               /* update number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */
+               if (chain_length>=CHAIN_LIMIT) {
+                       beyond_limit+=chain_length;
+                       chain_length=CHAIN_LIMIT-1;
+               }
+
+               /* update number of hashchains of current length */
+               chain_count[chain_length]++;
+       }
+
+       /* display results */  
+       for (i=1;i<CHAIN_LIMIT-1;i++) 
+               printf("       %2d %17d %18.2f%%\n",i,chain_count[i],(((float) chain_count[i]*i*100)/hashtable_utf->entries));
+         
+       printf("     >=%2d %17d %18.2f%%\n",CHAIN_LIMIT-1,chain_count[CHAIN_LIMIT-1],((float) beyond_limit*100)/hashtable_utf->entries);
+
+
+       printf("max. chainlength:%5d\n",max_chainlength);
+
+       /* avg. chainlength = sum of chainlengths / number of chains */
+       printf("avg. chainlength:%5.2f\n",(float) sum_chainlength / (hashtable_utf->size-chain_count[0]));
+}
+#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/utf8.h b/src/vm/utf8.h
new file mode 100644 (file)
index 0000000..91d2a2d
--- /dev/null
@@ -0,0 +1,307 @@
+/* src/vm/utf8.h - utf8 string 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 _UTF_H
+#define _UTF_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct utf utf;
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+
+/* data structure for utf8 symbols ********************************************/
+
+struct utf {
+       utf  *hashlink;                     /* link for external hash chain       */
+       s4    blength;                      /* text length in bytes               */
+       char *text;                         /* pointer to text                    */
+};
+
+/* to determine the end of utf strings */
+
+#define UTF_END(u)    ((char *) u->text + u->blength)
+
+
+/* utf-symbols for pointer comparison of frequently used strings **************/
+
+extern utf *utf_java_lang_Object;
+
+extern utf *utf_java_lang_Class;
+extern utf *utf_java_lang_ClassLoader;
+extern utf *utf_java_lang_Cloneable;
+extern utf *utf_java_lang_SecurityManager;
+extern utf *utf_java_lang_String;
+extern utf *utf_java_lang_ThreadGroup;
+extern utf *utf_java_lang_ref_SoftReference;
+extern utf *utf_java_lang_ref_WeakReference;
+extern utf *utf_java_lang_ref_PhantomReference;
+extern utf *utf_java_io_Serializable;
+
+extern utf *utf_java_lang_Throwable;
+extern utf *utf_java_lang_Error;
+
+extern utf *utf_java_lang_AbstractMethodError;
+extern utf *utf_java_lang_ClassCircularityError;
+extern utf *utf_java_lang_ClassFormatError;
+extern utf *utf_java_lang_ExceptionInInitializerError;
+extern utf *utf_java_lang_IncompatibleClassChangeError;
+extern utf *utf_java_lang_InstantiationError;
+extern utf *utf_java_lang_InternalError;
+extern utf *utf_java_lang_LinkageError;
+extern utf *utf_java_lang_NoClassDefFoundError;
+extern utf *utf_java_lang_NoSuchFieldError;
+extern utf *utf_java_lang_NoSuchMethodError;
+extern utf *utf_java_lang_OutOfMemoryError;
+extern utf *utf_java_lang_UnsatisfiedLinkError;
+extern utf *utf_java_lang_UnsupportedClassVersionError;
+extern utf *utf_java_lang_VerifyError;
+extern utf *utf_java_lang_VirtualMachineError;
+
+extern utf *utf_java_lang_Exception;
+
+extern utf *utf_java_lang_ArithmeticException;
+extern utf *utf_java_lang_ArrayIndexOutOfBoundsException;
+extern utf *utf_java_lang_ArrayStoreException;
+extern utf *utf_java_lang_ClassCastException;
+extern utf *utf_java_lang_ClassNotFoundException;
+extern utf *utf_java_lang_CloneNotSupportedException;
+extern utf *utf_java_lang_IllegalAccessException;
+extern utf *utf_java_lang_IllegalArgumentException;
+extern utf *utf_java_lang_IllegalMonitorStateException;
+extern utf *utf_java_lang_InstantiationException;
+extern utf *utf_java_lang_InterruptedException;
+extern utf *utf_java_lang_NegativeArraySizeException;
+extern utf *utf_java_lang_NullPointerException;
+extern utf *utf_java_lang_RuntimeException;
+extern utf *utf_java_lang_StringIndexOutOfBoundsException;
+
+extern utf *utf_java_lang_reflect_InvocationTargetException;
+
+extern utf *utf_java_security_PrivilegedActionException;
+
+#if defined(ENABLE_JAVASE)
+extern utf* utf_java_lang_Void;
+#endif
+
+extern utf* utf_java_lang_Boolean;
+extern utf* utf_java_lang_Byte;
+extern utf* utf_java_lang_Character;
+extern utf* utf_java_lang_Short;
+extern utf* utf_java_lang_Integer;
+extern utf* utf_java_lang_Long;
+extern utf* utf_java_lang_Float;
+extern utf* utf_java_lang_Double;
+
+#if defined(ENABLE_JAVASE)
+extern utf *utf_java_lang_StackTraceElement;
+extern utf *utf_java_lang_reflect_Constructor;
+extern utf *utf_java_lang_reflect_Field;
+extern utf *utf_java_lang_reflect_Method;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+extern utf *utf_java_lang_reflect_VMConstructor;
+extern utf *utf_java_lang_reflect_VMField;
+extern utf *utf_java_lang_reflect_VMMethod;
+# endif
+
+extern utf *utf_java_util_Vector;
+#endif
+
+extern utf *utf_InnerClasses;
+extern utf *utf_ConstantValue;
+extern utf *utf_Code;
+extern utf *utf_Exceptions;
+extern utf *utf_LineNumberTable;
+extern utf *utf_SourceFile;
+
+#if defined(ENABLE_JAVASE)
+extern utf *utf_EnclosingMethod;
+extern utf *utf_Signature;
+extern utf *utf_StackMapTable;
+
+#if defined(ENABLE_ANNOTATIONS)
+extern utf *utf_RuntimeVisibleAnnotations;
+extern utf *utf_RuntimeInvisibleAnnotations;
+extern utf *utf_RuntimeVisibleParameterAnnotations;
+extern utf *utf_RuntimeInvisibleParameterAnnotations;
+extern utf *utf_AnnotationDefault;
+#endif
+#endif
+
+extern utf *utf_init;
+extern utf *utf_clinit;
+extern utf *utf_clone;
+extern utf *utf_finalize;
+extern utf *utf_invoke;
+extern utf *utf_main;
+extern utf *utf_run;
+
+extern utf *utf_add;
+extern utf *utf_dispatch;
+extern utf *utf_remove;
+extern utf *utf_addThread;
+extern utf *utf_removeThread;
+extern utf *utf_put;
+extern utf *utf_get;
+extern utf *utf_uncaughtException;
+extern utf *utf_value;
+
+extern utf *utf_fillInStackTrace;
+extern utf *utf_findNative;
+extern utf *utf_getSystemClassLoader;
+extern utf *utf_initCause;
+extern utf *utf_loadClass;
+extern utf *utf_loadClassInternal;
+extern utf *utf_printStackTrace;
+
+extern utf *utf_division_by_zero;
+
+extern utf *utf_Z;
+extern utf *utf_B;
+extern utf *utf_C;
+extern utf *utf_S;
+extern utf *utf_I;
+extern utf *utf_J;
+extern utf *utf_F;
+extern utf *utf_D;
+
+extern utf *utf_void__void;
+extern utf *utf_boolean__void;
+extern utf *utf_byte__void;
+extern utf *utf_char__void;
+extern utf *utf_short__void;
+extern utf *utf_int__void;
+extern utf *utf_long__void;
+extern utf *utf_float__void;
+extern utf *utf_double__void;
+
+extern utf *utf_void__java_lang_ClassLoader;
+extern utf *utf_void__java_lang_Object;
+extern utf *utf_void__java_lang_Throwable;
+extern utf *utf_java_lang_ClassLoader_java_lang_String__J;
+extern utf *utf_java_lang_Exception__V;
+extern utf *utf_java_lang_Object__java_lang_Object;
+extern utf *utf_java_lang_String__void;
+extern utf *utf_java_lang_String__java_lang_Class;
+extern utf *utf_java_lang_Thread__V;
+extern utf *utf_java_lang_Thread_java_lang_Throwable__V;
+extern utf *utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V;
+extern utf *utf_java_lang_Throwable__void;
+extern utf *utf_java_lang_Throwable__java_lang_Throwable;
+
+extern utf *utf_not_named_yet;
+extern utf *utf_null;
+extern utf *array_packagename;
+
+
+/* function prototypes ********************************************************/
+
+/* initialize the utf8 subsystem */
+void utf8_init(void);
+
+u4 utf_hashkey(const char *text, u4 length);
+u4 utf_full_hashkey(const char *text, u4 length);
+
+/* determine hashkey of a unicode-symbol */
+u4 unicode_hashkey(u2 *text, u2 length);
+
+/* create new utf-symbol */
+utf *utf_new(const char *text, u2 length);
+
+/* make utf symbol from u2 array */
+utf *utf_new_u2(u2 *unicodedata, u4 unicodelength, bool isclassname);
+
+utf *utf_new_char(const char *text);
+utf *utf_new_char_classname(const char *text);
+
+/* get number of bytes */
+u4 utf_bytes(utf *u);
+
+/* get next unicode character of a utf-string */
+u2 utf_nextu2(char **utf);
+
+/* get (number of) unicode characters of a utf string (safe) */
+s4 utf8_safe_number_of_u2s(const char *text, s4 nbytes);
+void utf8_safe_convert_to_u2s(const char *text, s4 nbytes, u2 *buffer);
+
+/* get (number of) unicode characters of a utf string (UNSAFE!) */
+u4 utf_get_number_of_u2s(utf *u);
+u4 utf_get_number_of_u2s_for_buffer(const char *buffer, u4 blength);
+
+/* determine utf length in bytes of a u2 array */
+u4 u2_utflength(u2 *text, u4 u2_length);
+
+void utf_copy(char *buffer, utf *u);
+void utf_cat(char *buffer, utf *u);
+void utf_copy_classname(char *buffer, utf *u);
+void utf_cat_classname(char *buffer, utf *u);
+
+/* write utf symbol to file/buffer */
+void utf_display_printable_ascii(utf *u);
+void utf_display_printable_ascii_classname(utf *u);
+
+void utf_sprint_convert_to_latin1(char *buffer, utf *u);
+void utf_sprint_convert_to_latin1_classname(char *buffer, utf *u);
+
+void utf_strcat_convert_to_latin1(char *buffer, utf *u);
+void utf_strcat_convert_to_latin1_classname(char *buffer, utf *u);
+
+void utf_fprint_printable_ascii(FILE *file, utf *u);
+void utf_fprint_printable_ascii_classname(FILE *file, utf *u);
+
+/* check if a UTF-8 string is valid */
+bool is_valid_utf(char *utf_ptr, char *end_pos);
+
+/* check if a UTF-8 string may be used as a class/field/method name */
+bool is_valid_name(char *utf_ptr, char *end_pos);
+bool is_valid_name_utf(utf *u);
+
+/* show utf-table */
+void utf_show(void);
+
+#endif /* _UTF_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/vm.c b/src/vm/vm.c
deleted file mode 100644 (file)
index 84a9a73..0000000
+++ /dev/null
@@ -1,2670 +0,0 @@
-/* src/vm/vm.c - VM startup and shutdown 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 <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "vm/types.h"
-
-#include "arch.h"
-#include "md-abi.h"
-
-#include "vm/jit/abi-asm.h"
-
-#include "mm/codememory.h"
-#include "mm/gc-common.h"
-#include "mm/memory.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/localref.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_Object.h"             /* required by j.l.C */
-#include "native/include/java_lang_String.h"             /* required by j.l.C */
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-# include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
-# include "native/include/java_lang_ClassLoader.h"       /* required by j.l.C */
-#endif
-
-#include "native/include/java_lang_Class.h"
-
-#include "native/vm/nativevm.h"
-
-#include "threads/lock-common.h"
-#include "threads/mutex.h"
-#include "threads/threadlist.h"
-#include "threads/thread.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/array.h"
-
-#if defined(ENABLE_ASSERTION)
-#include "vm/assertion.h"
-#endif
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/finalizer.h"
-#include "vm/global.h"
-#include "vm/initialize.h"
-#include "vm/package.hpp"
-#include "vm/primitive.h"
-#include "vm/properties.h"
-#include "vm/signallocal.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/argument.h"
-#include "vm/jit/asmpart.h"
-#include "vm/jit/code.h"
-#include "vm/jit/jitcache.h"
-
-#if defined(ENABLE_DISASSEMBLER)
-# include "vm/jit/disass.h"
-#endif
-
-#include "vm/jit/jit.h"
-#include "vm/jit/methodtree.h"
-
-#if defined(ENABLE_PROFILING)
-# include "vm/jit/optimizing/profile.h"
-#endif
-
-#include "vm/jit/optimizing/recompile.h"
-
-#if defined(ENABLE_PYTHON)
-# include "vm/jit/python.h"
-#endif
-
-#include "vm/jit/trap.h"
-
-#include "vmcore/classcache.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-#include "vmcore/suck.h"
-#include "vmcore/system.h"
-
-#if defined(ENABLE_JVMTI)
-# include "native/jvmti/cacaodbg.h"
-#endif
-
-#if defined(ENABLE_VMLOG)
-#include <vmlog_cacao.h>
-#endif
-
-
-/* Invocation API variables ***************************************************/
-
-_Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
-_Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
-
-
-/* global variables ***********************************************************/
-
-s4 vms = 0;                             /* number of VMs created              */
-
-bool vm_initializing = false;
-bool vm_created      = false;
-bool vm_exiting      = false;
-
-static classinfo *mainclass = NULL;
-
-#if defined(ENABLE_INTRP)
-u1 *intrp_main_stack = NULL;
-#endif
-
-
-/* define heap sizes **********************************************************/
-
-#define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
-#define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
-#define STACK_SIZE               128 * 1024 /* default 64kB                   */
-
-
-/* define command line options ************************************************/
-
-enum {
-       OPT_FOO,
-
-       /* Java options */
-
-       OPT_JAR,
-
-       OPT_D32,
-       OPT_D64,
-
-       OPT_CLASSPATH,
-       OPT_D,
-
-       OPT_VERBOSE,
-
-       OPT_VERSION,
-       OPT_SHOWVERSION,
-       OPT_FULLVERSION,
-
-       OPT_HELP,
-       OPT_X,
-       OPT_XX,
-
-       OPT_EA,
-       OPT_DA,
-       OPT_EA_NOARG,
-       OPT_DA_NOARG,
-    
-
-       OPT_ESA,
-       OPT_DSA,
-
-       /* Java non-standard options */
-
-       OPT_JIT,
-       OPT_INTRP,
-
-       OPT_BOOTCLASSPATH,
-       OPT_BOOTCLASSPATH_A,
-       OPT_BOOTCLASSPATH_P,
-
-       OPT_BOOTCLASSPATH_C,
-
-#if defined(ENABLE_PROFILING)
-       OPT_PROF,
-       OPT_PROF_OPTION,
-#endif
-
-       OPT_MS,
-       OPT_MX,
-
-       /* CACAO options */
-
-       OPT_VERBOSE1,
-       OPT_NOIEEE,
-
-#if defined(ENABLE_STATISTICS)
-       OPT_TIME,
-       OPT_STAT,
-#endif
-
-       OPT_LOG,
-       OPT_CHECK,
-       OPT_LOAD,
-       OPT_SHOW,
-       OPT_DEBUGCOLOR,
-
-#if !defined(NDEBUG)
-       OPT_ALL,
-       OPT_METHOD,
-       OPT_SIGNATURE,
-#endif
-
-#if defined(ENABLE_VERIFIER)
-       OPT_NOVERIFY,
-#if defined(TYPECHECK_VERBOSE)
-       OPT_VERBOSETC,
-#endif
-#endif /* defined(ENABLE_VERIFIER) */
-
-       /* optimization options */
-
-#if defined(ENABLE_LOOP)
-       OPT_OLOOP,
-#endif
-       
-#if defined(ENABLE_IFCONV)
-       OPT_IFCONV,
-#endif
-
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
-       OPT_LSRA,
-#endif
-
-#if defined(ENABLE_INTRP)
-       /* interpreter options */
-
-       OPT_NO_DYNAMIC,
-       OPT_NO_REPLICATION,
-       OPT_NO_QUICKSUPER,
-       OPT_STATIC_SUPERS,
-       OPT_TRACE,
-#endif
-
-       OPT_SS,
-
-#ifdef ENABLE_JVMTI
-       OPT_DEBUG,
-       OPT_XRUNJDWP,
-       OPT_NOAGENT,
-       OPT_AGENTLIB,
-       OPT_AGENTPATH,
-#endif
-
-#if defined(ENABLE_DEBUG_FILTER)
-       OPT_FILTER_VERBOSECALL_INCLUDE,
-       OPT_FILTER_VERBOSECALL_EXCLUDE,
-       OPT_FILTER_SHOW_METHOD,
-#endif
-
-       DUMMY
-};
-
-
-opt_struct opts[] = {
-       { "foo",               false, OPT_FOO },
-
-       /* Java options */
-
-       { "jar",               false, OPT_JAR },
-
-       { "d32",               false, OPT_D32 },
-       { "d64",               false, OPT_D64 },
-       { "client",            false, OPT_IGNORE },
-       { "server",            false, OPT_IGNORE },
-       { "jvm",               false, OPT_IGNORE },
-       { "hotspot",           false, OPT_IGNORE },
-
-       { "classpath",         true,  OPT_CLASSPATH },
-       { "cp",                true,  OPT_CLASSPATH },
-       { "D",                 true,  OPT_D },
-       { "version",           false, OPT_VERSION },
-       { "showversion",       false, OPT_SHOWVERSION },
-       { "fullversion",       false, OPT_FULLVERSION },
-       { "help",              false, OPT_HELP },
-       { "?",                 false, OPT_HELP },
-       { "X",                 false, OPT_X },
-       { "XX:",               true,  OPT_XX },
-
-       { "ea:",               true,  OPT_EA },
-       { "da:",               true,  OPT_DA },
-       { "ea",                false, OPT_EA_NOARG },
-       { "da",                false, OPT_DA_NOARG },
-
-       { "enableassertions:",  true,  OPT_EA },
-       { "disableassertions:", true,  OPT_DA },
-       { "enableassertions",   false, OPT_EA_NOARG },
-       { "disableassertions",  false, OPT_DA_NOARG },
-
-       { "esa",                     false, OPT_ESA },
-       { "enablesystemassertions",  false, OPT_ESA },
-       { "dsa",                     false, OPT_DSA },
-       { "disablesystemassertions", false, OPT_DSA },
-
-       { "noasyncgc",         false, OPT_IGNORE },
-#if defined(ENABLE_VERIFIER)
-       { "noverify",          false, OPT_NOVERIFY },
-       { "Xverify:none",      false, OPT_NOVERIFY },
-#endif
-       { "v",                 false, OPT_VERBOSE1 },
-       { "verbose:",          true,  OPT_VERBOSE },
-
-#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
-       { "verbosetc",         false, OPT_VERBOSETC },
-#endif
-#if defined(__ALPHA__)
-       { "noieee",            false, OPT_NOIEEE },
-#endif
-#if defined(ENABLE_STATISTICS)
-       { "time",              false, OPT_TIME },
-       { "stat",              false, OPT_STAT },
-#endif
-       { "log",               true,  OPT_LOG },
-       { "c",                 true,  OPT_CHECK },
-       { "l",                 false, OPT_LOAD },
-
-#if !defined(NDEBUG)
-       { "all",               false, OPT_ALL },
-       { "sig",               true,  OPT_SIGNATURE },
-#endif
-
-#if defined(ENABLE_LOOP)
-       { "oloop",             false, OPT_OLOOP },
-#endif
-#if defined(ENABLE_IFCONV)
-       { "ifconv",            false, OPT_IFCONV },
-#endif
-#if defined(ENABLE_LSRA)
-       { "lsra",              false, OPT_LSRA },
-#endif
-#if  defined(ENABLE_SSA)
-       { "lsra",              true, OPT_LSRA },
-#endif
-
-#if defined(ENABLE_INTRP)
-       /* interpreter options */
-
-       { "trace",             false, OPT_TRACE },
-       { "static-supers",     true,  OPT_STATIC_SUPERS },
-       { "no-dynamic",        false, OPT_NO_DYNAMIC },
-       { "no-replication",    false, OPT_NO_REPLICATION },
-       { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
-#endif
-
-       /* JVMTI Agent Command Line Options */
-#ifdef ENABLE_JVMTI
-       { "agentlib:",         true,  OPT_AGENTLIB },
-       { "agentpath:",        true,  OPT_AGENTPATH },
-#endif
-
-       /* Java non-standard options */
-
-       { "Xjit",              false, OPT_JIT },
-       { "Xint",              false, OPT_INTRP },
-       { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
-       { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
-       { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
-       { "Xbootclasspath/c:", true,  OPT_BOOTCLASSPATH_C },
-
-#ifdef ENABLE_JVMTI
-       { "Xdebug",            false, OPT_DEBUG },
-       { "Xnoagent",          false, OPT_NOAGENT },
-       { "Xrunjdwp",          true,  OPT_XRUNJDWP },
-#endif 
-
-       { "Xms",               true,  OPT_MS },
-       { "ms",                true,  OPT_MS },
-       { "Xmx",               true,  OPT_MX },
-       { "mx",                true,  OPT_MX },
-       { "Xss",               true,  OPT_SS },
-       { "ss",                true,  OPT_SS },
-
-#if defined(ENABLE_PROFILING)
-       { "Xprof:",            true,  OPT_PROF_OPTION },
-       { "Xprof",             false, OPT_PROF },
-#endif
-
-       /* keep these at the end of the list */
-
-#if !defined(NDEBUG)
-       { "m",                 true,  OPT_METHOD },
-#endif
-
-       { "s",                 true,  OPT_SHOW },
-       { "debug-color",      false,  OPT_DEBUGCOLOR },
-
-#if defined(ENABLE_DEBUG_FILTER)
-       { "XXfi",              true,  OPT_FILTER_VERBOSECALL_INCLUDE },
-       { "XXfx",              true,  OPT_FILTER_VERBOSECALL_EXCLUDE },
-       { "XXfm",              true,  OPT_FILTER_SHOW_METHOD },
-#endif
-
-       { NULL,                false, 0 }
-};
-
-
-/* usage ***********************************************************************
-
-   Prints the correct usage syntax to stdout.
-
-*******************************************************************************/
-
-void usage(void)
-{
-       puts("Usage: cacao [-options] classname [arguments]");
-       puts("               (to run a class file)");
-       puts("   or  cacao [-options] -jar jarfile [arguments]");
-       puts("               (to run a standalone jar file)\n");
-
-       puts("where options include:");
-       puts("    -d32                     use 32-bit data model if available");
-       puts("    -d64                     use 64-bit data model if available");
-       puts("    -client                  compatibility (currently ignored)");
-       puts("    -server                  compatibility (currently ignored)");
-       puts("    -jvm                     compatibility (currently ignored)");
-       puts("    -hotspot                 compatibility (currently ignored)\n");
-
-       puts("    -cp <path>               specify a path to look for classes");
-       puts("    -classpath <path>        specify a path to look for classes");
-       puts("    -D<name>=<value>         add an entry to the property list");
-       puts("    -verbose[:class|gc|jni]  enable specific verbose output");
-       puts("    -version                 print product version and exit");
-       puts("    -fullversion             print jpackage-compatible product version and exit");
-       puts("    -showversion             print product version and continue");
-       puts("    -help, -?                print this help message");
-       puts("    -X                       print help on non-standard Java options");
-       puts("    -XX                      print help on debugging options");
-    puts("    -ea[:<packagename>...|:<classname>]");
-    puts("    -enableassertions[:<packagename>...|:<classname>]");
-       puts("                             enable assertions with specified granularity");
-       puts("    -da[:<packagename>...|:<classname>]");
-       puts("    -disableassertions[:<packagename>...|:<classname>]");
-       puts("                             disable assertions with specified granularity");
-       puts("    -esa | -enablesystemassertions");
-       puts("                             enable system assertions");
-       puts("    -dsa | -disablesystemassertions");
-       puts("                             disable system assertions");
-
-#ifdef ENABLE_JVMTI
-       puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
-       puts ("                                         for jdwp help use: -agentlib:jdwp=help");
-       puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
-#endif
-
-       /* exit with error code */
-
-       exit(1);
-}   
-
-
-static void Xusage(void)
-{
-#if defined(ENABLE_JIT)
-       puts("    -Xjit                    JIT mode execution (default)");
-#endif
-#if defined(ENABLE_INTRP)
-       puts("    -Xint                    interpreter mode execution");
-#endif
-       puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
-    puts("                             value is set as bootstrap class path");
-       puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
-       puts("                             value is appended to the bootstrap class path");
-       puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
-       puts("                             value is prepended to the bootstrap class path");
-       puts("    -Xbootclasspath/c:<zip/jar files and directories separated by :>");
-       puts("                             value is used as Java core library, but the");
-       puts("                             hardcoded VM interface classes are prepended");
-       printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
-       printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
-       printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
-
-#if defined(ENABLE_PROFILING)
-       puts("    -Xprof[:bb]              collect and print profiling data");
-#endif
-
-#if defined(ENABLE_JVMTI)
-    /* -Xdebug option depend on gnu classpath JDWP options. options: 
-        transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
-       puts("    -Xdebug                  enable remote debugging\n");
-       puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
-       puts("                             enable remote debugging\n");
-#endif 
-
-       /* exit with error code */
-
-       exit(1);
-}   
-
-
-#if 0
-static void XXusage(void)
-{
-       puts("    -v                       write state-information");
-#if !defined(NDEBUG)
-       puts("    -verbose:jit             enable specific verbose output");
-       puts("    -debug-color             colored output for ANSI terms");
-#endif
-#ifdef TYPECHECK_VERBOSE
-       puts("    -verbosetc               write debug messages while typechecking");
-#endif
-#if defined(__ALPHA__)
-       puts("    -noieee                  don't use ieee compliant arithmetic");
-#endif
-#if defined(ENABLE_VERIFIER)
-       puts("    -noverify                don't verify classfiles");
-#endif
-#if defined(ENABLE_STATISTICS)
-       puts("    -time                    measure the runtime");
-       puts("    -stat                    detailed compiler statistics");
-#endif
-       puts("    -log logfile             specify a name for the logfile");
-       puts("    -c(heck)b(ounds)         don't check array bounds");
-       puts("            s(ync)           don't check for synchronization");
-#if defined(ENABLE_LOOP)
-       puts("    -oloop                   optimize array accesses in loops");
-#endif
-       puts("    -l                       don't start the class after loading");
-#if !defined(NDEBUG)
-       puts("    -all                     compile all methods, no execution");
-       puts("    -m                       compile only a specific method");
-       puts("    -sig                     specify signature for a specific method");
-#endif
-
-       puts("    -s...                    show...");
-       puts("      (c)onstants            the constant pool");
-       puts("      (m)ethods              class fields and methods");
-       puts("      (u)tf                  the utf - hash");
-       puts("      (i)ntermediate         intermediate representation");
-#if defined(ENABLE_DISASSEMBLER)
-       puts("      (a)ssembler            disassembled listing");
-       puts("      n(o)ps                 show NOPs in disassembler output");
-#endif
-       puts("      (d)atasegment          data segment listing");
-
-#if defined(ENABLE_IFCONV)
-       puts("    -ifconv                  use if-conversion");
-#endif
-#if defined(ENABLE_LSRA)
-       puts("    -lsra                    use linear scan register allocation");
-#endif
-#if defined(ENABLE_SSA)
-       puts("    -lsra:...                use linear scan register allocation (with SSA)");
-       puts("       (d)ead code elimination");
-       puts("       (c)opy propagation");
-#endif
-#if defined(ENABLE_DEBUG_FILTER)
-       puts("    -XXfi <regex>            begin of dynamic scope for verbosecall filter");
-       puts("    -XXfx <regex>            end of dynamic scope for verbosecall filter");
-       puts("    -XXfm <regex>            filter for show options");
-#endif
-       /* exit with error code */
-
-       exit(1);
-}
-#endif
-
-
-/* version *********************************************************************
-
-   Only prints cacao version information.
-
-*******************************************************************************/
-
-static void version(bool opt_exit)
-{
-       puts("java version \""JAVA_VERSION"\"");
-       puts("CACAO version "VERSION"\n");
-
-       puts("Copyright (C) 1996-2005, 2006, 2007, 2008");
-       puts("CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
-       puts("This is free software; see the source for copying conditions.  There is NO");
-       puts("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
-
-       /* exit normally, if requested */
-
-       if (opt_exit)
-               exit(0);
-}
-
-
-/* fullversion *****************************************************************
-
-   Prints a Sun compatible version information (required e.g. by
-   jpackage, www.jpackage.org).
-
-*******************************************************************************/
-
-static void fullversion(void)
-{
-       puts("java full version \"cacao-"JAVA_VERSION"\"");
-
-       /* exit normally */
-
-       exit(0);
-}
-
-
-static void vm_printconfig(void)
-{
-       puts("Configure/Build options:\n");
-       puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
-#if defined(__VERSION__)
-       puts("  CC         : "VERSION_CC" ("__VERSION__")");
-#else
-       puts("  CC         : "VERSION_CC"");
-#endif
-       puts("  CFLAGS     : "VERSION_CFLAGS"\n");
-
-       puts("Default variables:\n");
-       printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
-       printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
-       printf("  stack size                     : %d\n", STACK_SIZE);
-
-#if defined(ENABLE_JRE_LAYOUT)
-       /* When we're building with JRE-layout, the default paths are the
-          same as the runtime paths. */
-#else
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       puts("  gnu.classpath.boot.library.path: "JAVA_RUNTIME_LIBRARY_LIBDIR);
-       puts("  java.boot.class.path           : "CACAO_VM_ZIP":"JAVA_RUNTIME_LIBRARY_CLASSES"");
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       puts("  sun.boot.library.path          : "JAVA_RUNTIME_LIBRARY_LIBDIR);
-       puts("  java.boot.class.path           : "JAVA_RUNTIME_LIBRARY_CLASSES);
-# endif
-#endif
-
-       puts("");
-
-       puts("Runtime variables:\n");
-       printf("  maximum heap size              : %d\n", opt_heapmaxsize);
-       printf("  initial heap size              : %d\n", opt_heapstartsize);
-       printf("  stack size                     : %d\n", opt_stacksize);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       printf("  gnu.classpath.boot.library.path: %s\n", properties_get("gnu.classpath.boot.library.path"));
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       printf("  sun.boot.library.path          : %s\n", properties_get("sun.boot.library.path"));
-#endif
-
-       printf("  java.boot.class.path           : %s\n", properties_get("java.boot.class.path"));
-       printf("  java.class.path                : %s\n", properties_get("java.class.path"));
-}
-
-
-/* forward declarations *******************************************************/
-
-static char *vm_get_mainclass_from_jar(char *mainstring);
-#if !defined(NDEBUG)
-static void  vm_compile_all(void);
-static void  vm_compile_method(char* mainname);
-#endif
-
-
-/* vm_createjvm ****************************************************************
-
-   Implementation for JNI_CreateJavaVM.
-
-*******************************************************************************/
-
-bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
-{
-       JavaVMInitArgs *_vm_args;
-       _Jv_JNIEnv     *env;
-       _Jv_JavaVM     *vm;
-
-       /* get the arguments for the new JVM */
-
-       _vm_args = (JavaVMInitArgs *) vm_args;
-
-       /* get the VM and Env tables (must be set before vm_create) */
-
-       env = NEW(_Jv_JNIEnv);
-
-#if defined(ENABLE_JNI)
-       env->env = &_Jv_JNINativeInterface;
-#endif
-
-       /* XXX Set the global variable.  Maybe we should do that differently. */
-
-       _Jv_env = env;
-
-       /* create and fill a JavaVM structure */
-
-       vm = NEW(_Jv_JavaVM);
-
-#if defined(ENABLE_JNI)
-       vm->functions = &_Jv_JNIInvokeInterface;
-#endif
-
-       /* XXX Set the global variable.  Maybe we should do that differently. */
-       /* XXX JVMTI Agents needs a JavaVM  */
-
-       _Jv_jvm = vm;
-
-       /* actually create the JVM */
-
-       if (!vm_create(_vm_args))
-               goto error;
-
-       /* now return the values */
-
-       *p_vm  = (JavaVM *) vm;
-       *p_env = (void *) env;
-
-       return true;
-
- error:
-       /* release allocated memory */
-
-       FREE(env, _Jv_JNIEnv);
-       FREE(vm, _Jv_JavaVM);
-
-       return false;
-}
-
-
-/* vm_create *******************************************************************
-
-   Creates a JVM.  Called by vm_createjvm.
-
-*******************************************************************************/
-
-bool vm_create(JavaVMInitArgs *vm_args)
-{
-       int   len;
-       char *p;
-       char *boot_class_path;
-       char *class_path;
-       int   opt;
-       int   i, j;
-       bool  opt_version;
-       bool  opt_exit;
-
-#if defined(ENABLE_JVMTI)
-       lt_dlhandle  handle;
-       char *libname, *agentarg;
-       bool jdwp,agentbypath;
-       jdwp = agentbypath = false;
-#endif
-
-#if defined(ENABLE_JNI)
-       /* Check the JNI version requested. */
-
-       if (!jni_version_check(vm_args->version))
-               return false;
-#endif
-
-       /* We only support 1 JVM instance. */
-
-       if (vms > 0)
-               return false;
-
-       /* Install the exit handler. */
-
-       if (atexit(vm_exit_handler))
-               vm_abort("atexit failed: %s\n", strerror(errno));
-
-       /* Set some options. */
-
-       opt_version       = false;
-       opt_exit          = false;
-
-       opt_noieee        = false;
-
-       opt_heapmaxsize   = HEAP_MAXSIZE;
-       opt_heapstartsize = HEAP_STARTSIZE;
-       opt_stacksize     = STACK_SIZE;
-
-       /* Initialize the properties list before command-line handling.
-          Otherwise -XX:+PrintConfig crashes. */
-
-       properties_init();
-
-       /* First of all, parse the -XX options. */
-
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_init_options();
-#endif
-
-       options_xx(vm_args);
-
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_init();
-#endif
-
-       /* We need to check if the actual size of a java.lang.Class object
-          is smaller or equal than the assumption made in
-          src/vmcore/class.h. */
-
-       if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
-               vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
-
-       /* set the VM starttime */
-
-       _Jv_jvm->starttime = builtin_currenttimemillis();
-
-#if defined(ENABLE_JVMTI)
-       /* initialize JVMTI related  **********************************************/
-       jvmti = false;
-#endif
-
-       /* Fill the properties before command-line handling. */
-
-       properties_set();
-
-       /* iterate over all passed options */
-
-       while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
-               switch (opt) {
-               case OPT_FOO:
-                       opt_foo = true;
-                       break;
-
-               case OPT_IGNORE:
-                       break;
-                       
-               case OPT_JAR:
-                       opt_jar = true;
-                       break;
-
-               case OPT_D32:
-#if SIZEOF_VOID_P == 8
-                       puts("Running a 32-bit JVM is not supported on this platform.");
-                       exit(1);
-#endif
-                       break;
-
-               case OPT_D64:
-#if SIZEOF_VOID_P == 4
-                       puts("Running a 64-bit JVM is not supported on this platform.");
-                       exit(1);
-#endif
-                       break;
-
-               case OPT_CLASSPATH:
-                       /* Forget old classpath and set the argument as new
-                          classpath. */
-
-                       class_path = properties_get("java.class.path");
-
-                       p = MNEW(char, strlen(opt_arg) + strlen("0"));
-
-                       strcpy(p, opt_arg);
-
-#if defined(ENABLE_JAVASE)
-                       properties_add("java.class.path", p);
-#endif
-
-                       MFREE(class_path, char, strlen(class_path));
-                       break;
-
-               case OPT_D:
-                       for (i = 0; i < strlen(opt_arg); i++) {
-                               if (opt_arg[i] == '=') {
-                                       opt_arg[i] = '\0';
-                                       properties_add(opt_arg, opt_arg + i + 1);
-                                       goto opt_d_done;
-                               }
-                       }
-
-                       /* if no '=' is given, just create an empty property */
-
-                       properties_add(opt_arg, "");
-
-               opt_d_done:
-                       break;
-
-               case OPT_BOOTCLASSPATH:
-                       /* Forget default bootclasspath and set the argument as
-                          new boot classpath. */
-
-                       boot_class_path = properties_get("sun.boot.class.path");
-
-                       p = MNEW(char, strlen(opt_arg) + strlen("0"));
-
-                       strcpy(p, opt_arg);
-
-                       properties_add("sun.boot.class.path", p);
-                       properties_add("java.boot.class.path", p);
-
-                       MFREE(boot_class_path, char, strlen(boot_class_path));
-                       break;
-
-               case OPT_BOOTCLASSPATH_A:
-                       /* Append to bootclasspath. */
-
-                       boot_class_path = properties_get("sun.boot.class.path");
-
-                       len = strlen(boot_class_path);
-
-                       p = MREALLOC(boot_class_path,
-                                                char,
-                                                len + strlen("0"),
-                                                len + strlen(":") +
-                                                strlen(opt_arg) + strlen("0"));
-
-                       strcat(p, ":");
-                       strcat(p, opt_arg);
-
-                       properties_add("sun.boot.class.path", p);
-                       properties_add("java.boot.class.path", p);
-                       break;
-
-               case OPT_BOOTCLASSPATH_P:
-                       /* Prepend to bootclasspath. */
-
-                       boot_class_path = properties_get("sun.boot.class.path");
-
-                       len = strlen(boot_class_path);
-
-                       p = MNEW(char, strlen(opt_arg) + strlen(":") + len + strlen("0"));
-
-                       strcpy(p, opt_arg);
-                       strcat(p, ":");
-                       strcat(p, boot_class_path);
-
-                       properties_add("sun.boot.class.path", p);
-                       properties_add("java.boot.class.path", p);
-
-                       MFREE(boot_class_path, char, len);
-                       break;
-
-               case OPT_BOOTCLASSPATH_C:
-                       /* Use as Java core library, but prepend VM interface
-                          classes. */
-
-                       boot_class_path = properties_get("sun.boot.class.path");
-
-                       len =
-                               strlen(CACAO_VM_ZIP) +
-                               strlen(":") +
-                               strlen(opt_arg) +
-                               strlen("0");
-
-                       p = MNEW(char, len);
-
-                       strcpy(p, CACAO_VM_ZIP);
-                       strcat(p, ":");
-                       strcat(p, opt_arg);
-
-                       properties_add("sun.boot.class.path", p);
-                       properties_add("java.boot.class.path", p);
-
-                       MFREE(boot_class_path, char, strlen(boot_class_path));
-                       break;
-
-#if defined(ENABLE_JVMTI)
-               case OPT_DEBUG:
-                       /* this option exists only for compatibility reasons */
-                       break;
-
-               case OPT_NOAGENT:
-                       /* I don't know yet what Xnoagent should do. This is only for 
-                          compatiblity with eclipse - motse */
-                       break;
-
-               case OPT_XRUNJDWP:
-                       agentbypath = true;
-                       jvmti       = true;
-                       jdwp        = true;
-
-                       len =
-                               strlen(CACAO_LIBDIR) +
-                               strlen("/libjdwp.so=") +
-                               strlen(opt_arg) +
-                               strlen("0");
-
-                       agentarg = MNEW(char, len);
-
-                       strcpy(agentarg, CACAO_LIBDIR);
-                       strcat(agentarg, "/libjdwp.so=");
-                       strcat(agentarg, &opt_arg[1]);
-                       break;
-
-               case OPT_AGENTPATH:
-                       agentbypath = true;
-
-               case OPT_AGENTLIB:
-                       jvmti = true;
-                       agentarg = opt_arg;
-                       break;
-#endif
-                       
-               case OPT_MX:
-               case OPT_MS:
-               case OPT_SS:
-                       {
-                               char c;
-                               c = opt_arg[strlen(opt_arg) - 1];
-
-                               if ((c == 'k') || (c == 'K')) {
-                                       j = atoi(opt_arg) * 1024;
-
-                               } else if ((c == 'm') || (c == 'M')) {
-                                       j = atoi(opt_arg) * 1024 * 1024;
-
-                               } else
-                                       j = atoi(opt_arg);
-
-                               if (opt == OPT_MX)
-                                       opt_heapmaxsize = j;
-                               else if (opt == OPT_MS)
-                                       opt_heapstartsize = j;
-                               else
-                                       opt_stacksize = j;
-                       }
-                       break;
-
-               case OPT_VERBOSE1:
-                       opt_verbose = true;
-                       break;
-
-               case OPT_VERBOSE:
-                       if (strcmp("class", opt_arg) == 0) {
-                               opt_verboseclass = true;
-                       }
-                       else if (strcmp("gc", opt_arg) == 0) {
-                               opt_verbosegc = true;
-                       }
-                       else if (strcmp("jni", opt_arg) == 0) {
-                               opt_verbosejni = true;
-                       }
-#if !defined(NDEBUG)
-                       else if (strcmp("jit", opt_arg) == 0) {
-                               opt_verbose = true;
-                               loadverbose = true;
-                               initverbose = true;
-                               compileverbose = true;
-                       }
-#endif
-                       else {
-                               printf("Unknown -verbose option: %s\n", opt_arg);
-                               usage();
-                       }
-                       break;
-
-               case OPT_DEBUGCOLOR:
-                       opt_debugcolor = true;
-                       break;
-
-#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
-               case OPT_VERBOSETC:
-                       opt_typecheckverbose = true;
-                       break;
-#endif
-                               
-               case OPT_VERSION:
-                       opt_version = true;
-                       opt_exit    = true;
-                       break;
-
-               case OPT_FULLVERSION:
-                       fullversion();
-                       break;
-
-               case OPT_SHOWVERSION:
-                       opt_version = true;
-                       break;
-
-               case OPT_NOIEEE:
-                       opt_noieee = true;
-                       break;
-
-#if defined(ENABLE_VERIFIER)
-               case OPT_NOVERIFY:
-                       opt_verify = false;
-                       break;
-#endif
-
-#if defined(ENABLE_STATISTICS)
-               case OPT_TIME:
-                       opt_getcompilingtime = true;
-                       opt_getloadingtime = true;
-                       break;
-                                       
-               case OPT_STAT:
-                       opt_stat = true;
-                       break;
-#endif
-                                       
-               case OPT_LOG:
-                       log_init(opt_arg);
-                       break;
-                       
-               case OPT_CHECK:
-                       for (i = 0; i < strlen(opt_arg); i++) {
-                               switch (opt_arg[i]) {
-                               case 'b':
-                                       checkbounds = false;
-                                       break;
-                               case 's':
-                                       checksync = false;
-                                       break;
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-                       
-               case OPT_LOAD:
-                       opt_run = false;
-                       makeinitializations = false;
-                       break;
-
-#if !defined(NDEBUG)
-               case OPT_ALL:
-                       compileall = true;
-                       opt_run = false;
-                       makeinitializations = false;
-                       break;
-
-               case OPT_METHOD:
-                       opt_run = false;
-                       opt_method = opt_arg;
-                       makeinitializations = false;
-                       break;
-
-               case OPT_SIGNATURE:
-                       opt_signature = opt_arg;
-                       break;
-#endif
-
-               case OPT_SHOW:       /* Display options */
-                       for (i = 0; i < strlen(opt_arg); i++) {         
-                               switch (opt_arg[i]) {
-                               case 'c':
-                                       showconstantpool = true;
-                                       break;
-
-                               case 'u':
-                                       showutf = true;
-                                       break;
-
-                               case 'm':
-                                       showmethods = true;
-                                       break;
-
-                               case 'i':
-                                       opt_showintermediate = true;
-                                       compileverbose = true;
-                                       break;
-
-#if defined(ENABLE_DISASSEMBLER)
-                               case 'a':
-                                       opt_showdisassemble = true;
-                                       compileverbose = true;
-                                       break;
-
-                               case 'o':
-                                       opt_shownops = true;
-                                       break;
-#endif
-
-                               case 'd':
-                                       opt_showddatasegment = true;
-                                       break;
-
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-                       
-#if defined(ENABLE_LOOP)
-               case OPT_OLOOP:
-                       opt_loops = true;
-                       break;
-#endif
-
-#if defined(ENABLE_IFCONV)
-               case OPT_IFCONV:
-                       opt_ifconv = true;
-                       break;
-#endif
-
-#if defined(ENABLE_LSRA)
-               case OPT_LSRA:
-                       opt_lsra = true;
-                       break;
-#endif
-#if  defined(ENABLE_SSA)
-               case OPT_LSRA:
-                       opt_lsra = true;
-                       for (i = 0; i < strlen(opt_arg); i++) {         
-                               switch (opt_arg[i]) {
-                               case 'c':
-                                       opt_ssa_cp = true;
-                                       break;
-
-                               case 'd':
-                                       opt_ssa_dce = true;
-                                       break;
-
-                               case ':':
-                                       break;
-
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-#endif
-
-               case OPT_HELP:
-                       usage();
-                       break;
-
-               case OPT_X:
-                       Xusage();
-                       break;
-
-               case OPT_XX:
-                       /* Already parsed. */
-                       break;
-
-               case OPT_EA:
-#if defined(ENABLE_ASSERTION)
-                       assertion_ea_da(opt_arg, true);
-#endif
-                       break;
-
-               case OPT_DA:
-#if defined(ENABLE_ASSERTION)
-                       assertion_ea_da(opt_arg, false);
-#endif
-                       break;
-
-               case OPT_EA_NOARG:
-#if defined(ENABLE_ASSERTION)
-                       assertion_user_enabled = true;
-#endif
-                       break;
-
-               case OPT_DA_NOARG:
-#if defined(ENABLE_ASSERTION)
-                       assertion_user_enabled = false;
-#endif
-                       break;
-
-               case OPT_ESA:
-#if defined(ENABLE_ASSERTION)
-                       assertion_system_enabled = true;
-#endif
-                       break;
-
-               case OPT_DSA:
-#if defined(ENABLE_ASSERTION)
-                       assertion_system_enabled = false;
-#endif
-                       break;
-
-#if defined(ENABLE_PROFILING)
-               case OPT_PROF_OPTION:
-                       /* use <= to get the last \0 too */
-
-                       for (i = 0, j = 0; i <= strlen(opt_arg); i++) {
-                               if (opt_arg[i] == ',')
-                                       opt_arg[i] = '\0';
-
-                               if (opt_arg[i] == '\0') {
-                                       if (strcmp("bb", opt_arg + j) == 0)
-                                               opt_prof_bb = true;
-
-                                       else {
-                                               printf("Unknown option: -Xprof:%s\n", opt_arg + j);
-                                               usage();
-                                       }
-
-                                       /* set k to next char */
-
-                                       j = i + 1;
-                               }
-                       }
-                       /* fall through */
-
-               case OPT_PROF:
-                       opt_prof = true;
-                       break;
-#endif
-
-               case OPT_JIT:
-#if defined(ENABLE_JIT)
-                       opt_jit = true;
-#else
-                       printf("-Xjit option not enabled.\n");
-                       exit(1);
-#endif
-                       break;
-
-               case OPT_INTRP:
-#if defined(ENABLE_INTRP)
-                       opt_intrp = true;
-#else
-                       printf("-Xint option not enabled.\n");
-                       exit(1);
-#endif
-                       break;
-
-#if defined(ENABLE_INTRP)
-               case OPT_STATIC_SUPERS:
-                       opt_static_supers = atoi(opt_arg);
-                       break;
-
-               case OPT_NO_DYNAMIC:
-                       opt_no_dynamic = true;
-                       break;
-
-               case OPT_NO_REPLICATION:
-                       opt_no_replication = true;
-                       break;
-
-               case OPT_NO_QUICKSUPER:
-                       opt_no_quicksuper = true;
-                       break;
-
-               case OPT_TRACE:
-                       vm_debug = true;
-                       break;
-#endif
-
-#if defined(ENABLE_DEBUG_FILTER)
-               case OPT_FILTER_VERBOSECALL_INCLUDE:
-                       opt_filter_verbosecall_include = opt_arg;
-                       break;
-
-               case OPT_FILTER_VERBOSECALL_EXCLUDE:
-                       opt_filter_verbosecall_exclude = opt_arg;
-                       break;
-
-               case OPT_FILTER_SHOW_METHOD:
-                       opt_filter_show_method = opt_arg;
-                       break;
-
-#endif
-               default:
-                       printf("Unknown option: %s\n",
-                                  vm_args->options[opt_index].optionString);
-                       usage();
-               }
-       }
-
-#if defined(ENABLE_JVMTI)
-       if (jvmti) {
-               jvmti_set_phase(JVMTI_PHASE_ONLOAD);
-               jvmti_agentload(agentarg, agentbypath, &handle, &libname);
-
-               if (jdwp)
-                       MFREE(agentarg, char, strlen(agentarg));
-
-               jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
-       }
-#endif
-
-       /* initialize this JVM ****************************************************/
-
-       vm_initializing = true;
-
-       /* initialize the garbage collector */
-
-       gc_init(opt_heapmaxsize, opt_heapstartsize);
-
-#if defined(ENABLE_THREADS)
-       /* BEFORE: threads_preinit */
-
-       threadlist_init();
-
-       /* AFTER: gc_init (directly after, as this initializes the
-          stopworldlock lock */
-
-       threads_preinit();
-       lock_init();
-       critical_init();
-#endif
-
-       /* install architecture dependent signal handlers */
-
-       if (!signal_init())
-               vm_abort("vm_create: signal_init failed");
-
-#if defined(ENABLE_INTRP)
-       /* Allocate main thread stack on the Java heap. */
-
-       if (opt_intrp) {
-               intrp_main_stack = GCMNEW(u1, opt_stacksize);
-               MSET(intrp_main_stack, 0, u1, opt_stacksize);
-       }
-#endif
-
-       /* AFTER: threads_preinit */
-
-       if (!string_init())
-               vm_abort("vm_create: string_init failed");
-
-       /* AFTER: threads_preinit */
-
-       utf8_init();
-
-       /* AFTER: thread_preinit */
-
-       if (!suck_init())
-               vm_abort("vm_create: suck_init failed");
-
-       suck_add_from_property("java.endorsed.dirs");
-
-       /* Now we have all options handled and we can print the version
-          information.
-
-          AFTER: suck_add_from_property("java.endorsed.dirs"); */
-
-       if (opt_version)
-               version(opt_exit);
-
-       /* AFTER: utf8_init */
-
-       boot_class_path = properties_get("sun.boot.class.path");
-       suck_add(boot_class_path);
-
-       /* initialize the classcache hashtable stuff: lock, hashtable
-          (must be done _after_ threads_preinit) */
-
-       if (!classcache_init())
-               vm_abort("vm_create: classcache_init failed");
-
-       /* Initialize the code memory management. */
-       /* AFTER: threads_preinit */
-
-       codememory_init();
-
-       /* initialize the finalizer stuff (must be done _after_
-          threads_preinit) */
-
-       if (!finalizer_init())
-               vm_abort("vm_create: finalizer_init failed");
-
-       /* Initialize the JIT compiler. */
-
-       jit_init();
-       code_init();
-       methodtree_init();
-
-#if defined(ENABLE_PYTHON)
-       pythonpass_init();
-#endif
-
-       /* BEFORE: loader_preinit */
-
-       Package_initialize();
-
-       /* AFTER: utf8_init, classcache_init */
-
-       loader_preinit();
-       linker_preinit();
-
-       /* AFTER: loader_preinit, linker_preinit */
-
-       primitive_init();
-
-       loader_init();
-       linker_init();
-
-       /* AFTER: loader_init, linker_init */
-
-       primitive_postinit();
-       method_init();
-
-#if defined(ENABLE_JIT)
-       trap_init();
-#endif
-
-       if (!builtin_init())
-               vm_abort("vm_create: builtin_init failed");
-
-       /* Initialize the native subsystem. */
-       /* BEFORE: threads_init */
-
-       if (!native_init())
-               vm_abort("vm_create: native_init failed");
-
-       /* Register the native methods implemented in the VM. */
-       /* BEFORE: threads_init */
-
-       nativevm_preinit();
-
-#if defined(ENABLE_JNI)
-       /* Initialize the JNI subsystem (must be done _before_
-          threads_init, as threads_init can call JNI methods
-          (e.g. NewGlobalRef). */
-
-       if (!jni_init())
-               vm_abort("vm_create: jni_init failed");
-#endif
-
-#if defined(ENABLE_JNI) || defined(ENABLE_HANDLES)
-       /* Initialize the local reference table for the main thread. */
-       /* BEFORE: threads_init */
-
-       if (!localref_table_init())
-               vm_abort("vm_create: localref_table_init failed");
-#endif
-
-       /* Iinitialize some important system classes. */
-       /* BEFORE: threads_init */
-
-       initialize_init();
-
-#if defined(ENABLE_THREADS)
-       threads_init();
-#endif
-
-       /* Initialize the native VM subsystem. */
-       /* AFTER: threads_init (at least for SUN's classes) */
-
-       nativevm_init();
-
-#if defined(ENABLE_PROFILING)
-       /* initialize profiling */
-
-       if (!profile_init())
-               vm_abort("vm_create: profile_init failed");
-#endif
-
-#if defined(ENABLE_THREADS)
-       /* initialize recompilation */
-
-       if (!recompile_init())
-               vm_abort("vm_create: recompile_init failed");
-
-       /* start the signal handler thread */
-
-#if defined(__LINUX__)
-       /* XXX Remove for exact-GC. */
-       if (threads_pthreads_implementation_nptl)
-#endif
-               if (!signal_start_thread())
-                       vm_abort("vm_create: signal_start_thread failed");
-
-       /* finally, start the finalizer thread */
-
-       if (!finalizer_start_thread())
-               vm_abort("vm_create: finalizer_start_thread failed");
-
-# if !defined(NDEBUG)
-       /* start the memory profiling thread */
-
-       if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
-               if (!memory_start_thread())
-                       vm_abort("vm_create: memory_start_thread failed");
-# endif
-
-       /* start the recompilation thread (must be done before the
-          profiling thread) */
-
-       if (!recompile_start_thread())
-               vm_abort("vm_create: recompile_start_thread failed");
-
-# if defined(ENABLE_PROFILING)
-       /* start the profile sampling thread */
-
-/*     if (opt_prof) */
-/*             if (!profile_start_thread()) */
-/*                     vm_abort("vm_create: profile_start_thread failed"); */
-# endif
-#endif
-
-#if defined(ENABLE_JVMTI)
-# if defined(ENABLE_GC_CACAO)
-       /* XXX this will not work with the new indirection cells for classloaders!!! */
-       assert(0);
-# endif
-       if (jvmti) {
-               /* add agent library to native library hashtable */
-               native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
-       }
-#endif
-
-       /* Increment the number of VMs. */
-
-       vms++;
-
-       /* Initialization is done, VM is created.. */
-
-       vm_created      = true;
-       vm_initializing = false;
-
-       /* Print the VM configuration after all stuff is set and the VM is
-          initialized. */
-
-       if (opt_PrintConfig)
-               vm_printconfig();
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* vm_run **********************************************************************
-
-   Runs the main-method of the passed class.
-
-*******************************************************************************/
-
-void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
-{
-       char*                      option;
-       char*                      mainname;
-       char*                      p;
-       utf                       *mainutf;
-       classinfo                 *mainclass;
-       java_handle_t             *e;
-       methodinfo                *m;
-       java_handle_objectarray_t *oa; 
-       s4                         oalength;
-       utf                       *u;
-       java_handle_t             *s;
-       int                        status;
-       int                        i;
-
-       // Prevent compiler warnings.
-       oa = NULL;
-
-#if !defined(NDEBUG)
-       if (compileall) {
-               vm_compile_all();
-               return;
-       }
-#endif
-
-       /* Get the main class plus it's arguments. */
-
-       mainname = NULL;
-
-       if (opt_index < vm_args->nOptions) {
-               /* Get main-class argument. */
-
-               mainname = vm_args->options[opt_index].optionString;
-
-               /* If the main class argument is a jar file, put it into the
-                  classpath. */
-
-               if (opt_jar == true) {
-                       p = MNEW(char, strlen(mainname) + strlen("0"));
-
-                       strcpy(p, mainname);
-
-#if defined(ENABLE_JAVASE)
-                       properties_add("java.class.path", p);
-#endif
-               }
-               else {
-                       /* Replace dots with slashes in the class name. */
-
-                       for (i = 0; i < strlen(mainname); i++)
-                               if (mainname[i] == '.')
-                                       mainname[i] = '/';
-               }
-
-               /* Build argument array.  Move index to first argument. */
-
-               opt_index++;
-
-               oalength = vm_args->nOptions - opt_index;
-
-               oa = builtin_anewarray(oalength, class_java_lang_String);
-
-               for (i = 0; i < oalength; i++) {
-                       option = vm_args->options[opt_index + i].optionString;
-
-                       u = utf_new_char(option);
-                       s = javastring_new(u);
-
-                       array_objectarray_element_set(oa, i, s);
-               }
-       }
-
-       /* Do we have a main-class argument? */
-
-       if (mainname == NULL)
-               usage();
-
-#if !defined(NDEBUG)
-       if (opt_method != NULL) {
-               vm_compile_method(mainname);
-               return;
-       }
-#endif
-
-       /* set return value to OK */
-
-       status = 0;
-
-       if (opt_jar == true) {
-               /* open jar file with java.util.jar.JarFile */
-
-               mainname = vm_get_mainclass_from_jar(mainname);
-
-               if (mainname == NULL)
-                       vm_exit(1);
-       }
-
-       /* load the main class */
-
-       mainutf = utf_new_char(mainname);
-
-#if defined(ENABLE_JAVAME_CLDC1_1)
-       mainclass = load_class_bootstrap(mainutf);
-#else
-       mainclass = load_class_from_sysloader(mainutf);
-#endif
-
-       /* error loading class */
-
-       e = exceptions_get_and_clear_exception();
-
-       if ((e != NULL) || (mainclass == NULL)) {
-               exceptions_throw_noclassdeffounderror_cause(e);
-               exceptions_print_stacktrace(); 
-               vm_exit(1);
-       }
-
-       if (!link_class(mainclass)) {
-               exceptions_print_stacktrace();
-               vm_exit(1);
-       }
-                       
-       /* find the `main' method of the main class */
-
-       m = class_resolveclassmethod(mainclass,
-                                                                utf_new_char("main"), 
-                                                                utf_new_char("([Ljava/lang/String;)V"),
-                                                                class_java_lang_Object,
-                                                                false);
-
-       if (exceptions_get_exception()) {
-               exceptions_print_stacktrace();
-               vm_exit(1);
-       }
-
-       /* there is no main method or it isn't static */
-
-       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
-               exceptions_clear_exception();
-               exceptions_throw_nosuchmethoderror(mainclass,
-                                                                                  utf_new_char("main"), 
-                                                                                  utf_new_char("([Ljava/lang/String;)V"));
-
-               exceptions_print_stacktrace();
-               vm_exit(1);
-       }
-
-#ifdef TYPEINFO_DEBUG_TEST
-       /* test the typeinfo system */
-       typeinfo_test();
-#endif
-
-#if defined(ENABLE_JVMTI)
-       jvmti_set_phase(JVMTI_PHASE_LIVE);
-#endif
-
-       /* set ThreadMXBean variables */
-
-       _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
-       _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
-
-       if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
-               _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
-               _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
-                       _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
-
-       /* start the main thread */
-
-       (void) vm_call_method(m, NULL, oa);
-
-       /* exception occurred? */
-
-       if (exceptions_get_exception()) {
-               exceptions_print_stacktrace();
-               status = 1;
-       }
-
-#if defined(ENABLE_THREADS)
-    /* Detach the main thread so that it appears to have ended when
-          the application's main method exits. */
-
-       if (!thread_detach_current_thread())
-               vm_abort("vm_run: Could not detach main thread.");
-#endif
-
-       /* Destroy the JavaVM. */
-
-       (void) vm_destroy(vm);
-
-       /* And exit. */
-
-       vm_exit(status);
-}
-
-
-/* vm_destroy ******************************************************************
-
-   Unloads a Java VM and reclaims its resources.
-
-*******************************************************************************/
-
-int vm_destroy(JavaVM *vm)
-{
-#if defined(ENABLE_THREADS)
-       /* Create a a trivial new Java waiter thread called
-          "DestroyJavaVM". */
-
-       JavaVMAttachArgs args;
-
-       args.name  = "DestroyJavaVM";
-       args.group = NULL;
-
-       if (!thread_attach_current_thread(&args, false))
-               return 1;
-
-       /* Wait until we are the last non-daemon thread. */
-
-       threads_join_all_threads();
-#endif
-
-       /* VM is gone. */
-
-       vm_created = false;
-
-       /* Everything is ok. */
-
-       return 0;
-}
-
-
-/* vm_exit *********************************************************************
-
-   Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
-
-*******************************************************************************/
-
-void vm_exit(s4 status)
-{
-       methodinfo *m;
-
-       /* signal that we are exiting */
-
-       vm_exiting = true;
-
-       assert(class_java_lang_System);
-       assert(class_java_lang_System->state & CLASS_LOADED);
-
-#if defined(ENABLE_JVMTI)
-       if (jvmti || (dbgcom!=NULL)) {
-               jvmti_set_phase(JVMTI_PHASE_DEAD);
-               if (jvmti) jvmti_agentunload();
-       }
-#endif
-
-       if (!link_class(class_java_lang_System)) {
-               exceptions_print_stacktrace();
-               exit(1);
-       }
-
-       /* call java.lang.System.exit(I)V */
-
-       m = class_resolveclassmethod(class_java_lang_System,
-                                                                utf_new_char("exit"),
-                                                                utf_int__void,
-                                                                class_java_lang_Object,
-                                                                true);
-       
-       if (m == NULL) {
-               exceptions_print_stacktrace();
-               exit(1);
-       }
-
-       /* call the exit function with passed exit status */
-
-       (void) vm_call_method(m, NULL, status);
-
-       /* If we had an exception, just ignore the exception and exit with
-          the proper code. */
-
-       vm_shutdown(status);
-}
-
-
-/* vm_shutdown *****************************************************************
-
-   Terminates the system immediately without freeing memory explicitly
-   (to be used only for abnormal termination).
-       
-*******************************************************************************/
-
-void vm_shutdown(s4 status)
-{
-       if (opt_verbose 
-#if defined(ENABLE_STATISTICS)
-               || opt_getcompilingtime || opt_stat
-#endif
-          ) 
-       {
-               log_text("CACAO terminated by shutdown");
-               dolog("Exit status: %d\n", (s4) status);
-
-       }
-
-#if defined(ENABLE_JVMTI)
-       /* terminate cacaodbgserver */
-       if (dbgcom!=NULL) {
-               mutex_lock(&dbgcomlock);
-               dbgcom->running=1;
-               mutex_unlock(&dbgcomlock);
-               jvmti_cacaodbgserver_quit();
-       }       
-#endif
-
-#if defined (ENABLE_JITCACHE)
-       jitcache_quit();
-#endif
-
-       exit(status);
-}
-
-
-/* vm_exit_handler *************************************************************
-
-   The exit_handler function is called upon program termination.
-
-   ATTENTION: Don't free system resources here! Some threads may still
-   be running as this is called from VMRuntime.exit(). The OS does the
-   cleanup for us.
-
-*******************************************************************************/
-
-void vm_exit_handler(void)
-{
-#if !defined(NDEBUG)
-       if (showmethods)
-               class_showmethods(mainclass);
-
-       if (showconstantpool)
-               class_showconstantpool(mainclass);
-
-       if (showutf)
-               utf_show();
-
-# if defined(ENABLE_PROFILING)
-       if (opt_prof)
-               profile_printstats();
-# endif
-#endif /* !defined(NDEBUG) */
-
-#if defined(ENABLE_RT_TIMING)
-       rt_timing_print_time_stats(stderr);
-#endif
-
-#if defined(ENABLE_CYCLES_STATS)
-       builtin_print_cycles_stats(stderr);
-       stacktrace_print_cycles_stats(stderr);
-#endif
-
-       if (opt_verbose 
-#if defined(ENABLE_STATISTICS)
-               || opt_getcompilingtime || opt_stat
-#endif
-          ) 
-       {
-               log_text("CACAO terminated");
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat) {
-                       print_stats();
-#ifdef TYPECHECK_STATISTICS
-                       typecheck_print_statistics(get_logfile());
-#endif
-               }
-
-               if (opt_getcompilingtime)
-                       print_times();
-#endif /* defined(ENABLE_STATISTICS) */
-       }
-       /* vm_print_profile(stderr);*/
-}
-
-
-/* vm_abort ********************************************************************
-
-   Prints an error message and aborts the VM.
-
-   IN:
-       text ... error message to print
-
-*******************************************************************************/
-
-void vm_abort(const char *text, ...)
-{
-       va_list ap;
-
-       /* Print the log message. */
-
-       log_start();
-
-       va_start(ap, text);
-       log_vprint(text, ap);
-       va_end(ap);
-
-       log_finish();
-
-       /* Now abort the VM. */
-
-       system_abort();
-}
-
-
-/* vm_abort_errnum *************************************************************
-
-   Prints an error message, appends ":" plus the strerror-message of
-   errnum and aborts the VM.
-
-   IN:
-       errnum ... error number
-       text ..... error message to print
-
-*******************************************************************************/
-
-void vm_abort_errnum(int errnum, const char *text, ...)
-{
-       va_list ap;
-
-       /* Print the log message. */
-
-       log_start();
-
-       va_start(ap, text);
-       log_vprint(text, ap);
-       va_end(ap);
-
-       /* Print the strerror-message of errnum. */
-
-       log_print(": %s", system_strerror(errnum));
-
-       log_finish();
-
-       /* Now abort the VM. */
-
-       system_abort();
-}
-
-
-/* vm_abort_errno **************************************************************
-
-   Equal to vm_abort_errnum, but uses errno to get the error number.
-
-   IN:
-       text ... error message to print
-
-*******************************************************************************/
-
-void vm_abort_errno(const char *text, ...)
-{
-       va_list ap;
-
-       va_start(ap, text);
-       vm_abort_errnum(errno, text, ap);
-       va_end(ap);
-}
-
-
-/* vm_abort_disassemble ********************************************************
-
-   Prints an error message, disassemble the given code range (if
-   enabled) and aborts the VM.
-
-   IN:
-       pc.......PC to disassemble
-          count....number of instructions to disassemble
-
-*******************************************************************************/
-
-void vm_abort_disassemble(void *pc, int count, const char *text, ...)
-{
-       va_list ap;
-#if defined(ENABLE_DISASSEMBLER)
-       int     i;
-#endif
-
-       /* Print debug message. */
-
-       log_start();
-
-       va_start(ap, text);
-       log_vprint(text, ap);
-       va_end(ap);
-
-       log_finish();
-
-       /* Print the PC. */
-
-#if SIZEOF_VOID_P == 8
-       log_println("PC=0x%016lx", pc);
-#else
-       log_println("PC=0x%08x", pc);
-#endif
-
-#if defined(ENABLE_DISASSEMBLER)
-       log_println("machine instructions at PC:");
-
-       /* Disassemble the given number of instructions. */
-
-       for (i = 0; i < count; i++)
-               pc = disassinstr(pc);
-#endif
-
-       vm_abort("Aborting...");
-}
-
-
-/* vm_get_mainclass_from_jar ***************************************************
-
-   Gets the name of the main class from a JAR's manifest file.
-
-*******************************************************************************/
-
-static char *vm_get_mainclass_from_jar(char *mainname)
-{
-       classinfo     *c;
-       java_handle_t *o;
-       methodinfo    *m;
-       java_handle_t *s;
-
-       c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
-
-       if (c == NULL) {
-               exceptions_print_stacktrace();
-               return NULL;
-       }
-
-       /* create JarFile object */
-
-       o = builtin_new(c);
-
-       if (o == NULL) {
-               exceptions_print_stacktrace();
-               return NULL;
-       }
-
-       m = class_resolveclassmethod(c,
-                                                                utf_init, 
-                                                                utf_java_lang_String__void,
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (m == NULL) {
-               exceptions_print_stacktrace();
-               return NULL;
-       }
-
-       s = javastring_new_from_ascii(mainname);
-
-       (void) vm_call_method(m, o, s);
-
-       if (exceptions_get_exception()) {
-               exceptions_print_stacktrace();
-               return NULL;
-       }
-
-       /* get manifest object */
-
-       m = class_resolveclassmethod(c,
-                                                                utf_new_char("getManifest"), 
-                                                                utf_new_char("()Ljava/util/jar/Manifest;"),
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (m == NULL) {
-               exceptions_print_stacktrace();
-               return NULL;
-       }
-
-       o = vm_call_method(m, o);
-
-       if (o == NULL) {
-               fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainname);
-               return NULL;
-       }
-
-
-       /* get Main Attributes */
-
-       LLNI_class_get(o, c);
-
-       m = class_resolveclassmethod(c,
-                                                                utf_new_char("getMainAttributes"), 
-                                                                utf_new_char("()Ljava/util/jar/Attributes;"),
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (m == NULL) {
-               exceptions_print_stacktrace();
-               return NULL;
-       }
-
-       o = vm_call_method(m, o);
-
-       if (o == NULL) {
-               fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainname);
-               return NULL;
-       }
-
-
-       /* get property Main-Class */
-
-       LLNI_class_get(o, c);
-
-       m = class_resolveclassmethod(c,
-                                                                utf_new_char("getValue"), 
-                                                                utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (m == NULL) {
-               exceptions_print_stacktrace();
-               return NULL;
-       }
-
-       s = javastring_new_from_ascii("Main-Class");
-
-       o = vm_call_method(m, o, s);
-
-       if (o == NULL) {
-               fprintf(stderr, "Failed to load Main-Class manifest attribute from\n");
-               fprintf(stderr, "%s\n", mainname);
-               return NULL;
-       }
-
-       return javastring_tochar(o);
-}
-
-
-/* vm_compile_all **************************************************************
-
-   Compile all methods found in the bootclasspath.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-static void vm_compile_all(void)
-{
-       classinfo              *c;
-       methodinfo             *m;
-       u4                      slot;
-       classcache_name_entry  *nmen;
-       classcache_class_entry *clsen;
-       s4                      i;
-
-       /* create all classes found in the bootclasspath */
-       /* XXX currently only works with zip/jar's */
-
-       loader_load_all_classes();
-
-       /* link all classes */
-
-       for (slot = 0; slot < hashtable_classcache.size; slot++) {
-               nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-
-               for (; nmen; nmen = nmen->hashlink) {
-                       /* iterate over all class entries */
-
-                       for (clsen = nmen->classes; clsen; clsen = clsen->next) {
-                               c = clsen->classobj;
-
-                               if (c == NULL)
-                                       continue;
-
-                               if (!(c->state & CLASS_LINKED)) {
-                                       if (!link_class(c)) {
-                                               fprintf(stderr, "Error linking: ");
-                                               utf_fprint_printable_ascii_classname(stderr, c->name);
-                                               fprintf(stderr, "\n");
-
-                                               /* print out exception and cause */
-
-                                               exceptions_print_current_exception();
-
-                                               /* goto next class */
-
-                                               continue;
-                                       }
-                               }
-
-                               /* compile all class methods */
-
-                               for (i = 0; i < c->methodscount; i++) {
-                                       m = &(c->methods[i]);
-
-                                       if (m->jcode != NULL) {
-                                               if (!jit_compile(m)) {
-                                                       fprintf(stderr, "Error compiling: ");
-                                                       utf_fprint_printable_ascii_classname(stderr, c->name);
-                                                       fprintf(stderr, ".");
-                                                       utf_fprint_printable_ascii(stderr, m->name);
-                                                       utf_fprint_printable_ascii(stderr, m->descriptor);
-                                                       fprintf(stderr, "\n");
-
-                                                       /* print out exception and cause */
-
-                                                       exceptions_print_current_exception();
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* vm_compile_method ***********************************************************
-
-   Compile a specific method.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-static void vm_compile_method(char* mainname)
-{
-       methodinfo *m;
-
-       /* create, load and link the main class */
-
-       mainclass = load_class_bootstrap(utf_new_char(mainname));
-
-       if (mainclass == NULL)
-               exceptions_print_stacktrace();
-
-       if (!link_class(mainclass))
-               exceptions_print_stacktrace();
-
-       if (opt_signature != NULL) {
-               m = class_resolveclassmethod(mainclass,
-                                                                        utf_new_char(opt_method),
-                                                                        utf_new_char(opt_signature),
-                                                                        mainclass,
-                                                                        false);
-       }
-       else {
-               m = class_resolveclassmethod(mainclass,
-                                                                        utf_new_char(opt_method),
-                                                                        NULL,
-                                                                        mainclass,
-                                                                        false);
-       }
-
-       if (m == NULL)
-               vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
-                                opt_method, opt_signature ? opt_signature : "");
-               
-       jit_compile(m);
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* vm_call_array ***************************************************************
-
-   Calls a Java method with a variable number of arguments, passed via
-   an argument array.
-
-   ATTENTION: This function has to be used outside the nativeworld.
-
-*******************************************************************************/
-
-#define VM_CALL_ARRAY(name, type)                                 \
-static type vm_call##name##_array(methodinfo *m, uint64_t *array) \
-{                                                                 \
-       methoddesc *md;                                               \
-       void       *pv;                                               \
-       type        value;                                            \
-                                                                  \
-       assert(m->code != NULL);                                      \
-                                                                  \
-       md = m->parseddesc;                                           \
-       pv = m->code->entrypoint;                                     \
-                                                                  \
-       STATISTICS(count_calls_native_to_java++);                     \
-                                                                  \
-       value = asm_vm_call_method##name(pv, array, md->memuse);      \
-                                                                  \
-       return value;                                                 \
-}
-
-static java_handle_t *vm_call_array(methodinfo *m, uint64_t *array)
-{
-       methoddesc    *md;
-       void          *pv;
-       java_object_t *o;
-
-       assert(m->code != NULL);
-
-       md = m->parseddesc;
-       pv = m->code->entrypoint;
-
-       STATISTICS(count_calls_native_to_java++);
-
-       o = asm_vm_call_method(pv, array, md->memuse);
-
-       if (md->returntype.type == TYPE_VOID)
-               o = NULL;
-
-       return LLNI_WRAP(o);
-}
-
-VM_CALL_ARRAY(_int,    int32_t)
-VM_CALL_ARRAY(_long,   int64_t)
-VM_CALL_ARRAY(_float,  float)
-VM_CALL_ARRAY(_double, double)
-
-
-/* vm_call_method **************************************************************
-
-   Calls a Java method with a variable number of arguments.
-
-*******************************************************************************/
-
-#define VM_CALL_METHOD(name, type)                                  \
-type vm_call_method##name(methodinfo *m, java_handle_t *o, ...)     \
-{                                                                   \
-       va_list ap;                                                     \
-       type    value;                                                  \
-                                                                    \
-       va_start(ap, o);                                                \
-       value = vm_call_method##name##_valist(m, o, ap);                \
-       va_end(ap);                                                     \
-                                                                    \
-       return value;                                                   \
-}
-
-VM_CALL_METHOD(,        java_handle_t *)
-VM_CALL_METHOD(_int,    int32_t)
-VM_CALL_METHOD(_long,   int64_t)
-VM_CALL_METHOD(_float,  float)
-VM_CALL_METHOD(_double, double)
-
-
-/* vm_call_method_valist *******************************************************
-
-   Calls a Java method with a variable number of arguments, passed via
-   a va_list.
-
-*******************************************************************************/
-
-#define VM_CALL_METHOD_VALIST(name, type)                               \
-type vm_call_method##name##_valist(methodinfo *m, java_handle_t *o,     \
-                                                                  va_list ap)                          \
-{                                                                       \
-       uint64_t *array;                                                    \
-       type      value;                                                    \
-       int32_t   dumpmarker;                                               \
-                                                                        \
-       if (m->code == NULL)                                                \
-               if (!jit_compile(m))                                            \
-                       return 0;                                                   \
-                                                                        \
-       THREAD_NATIVEWORLD_EXIT;                                            \
-       DMARKER;                                                            \
-                                                                        \
-       array = argument_vmarray_from_valist(m, o, ap);                     \
-       value = vm_call##name##_array(m, array);                            \
-                                                                        \
-       DRELEASE;                                                           \
-       THREAD_NATIVEWORLD_ENTER;                                           \
-                                                                        \
-       return value;                                                       \
-}
-
-VM_CALL_METHOD_VALIST(,        java_handle_t *)
-VM_CALL_METHOD_VALIST(_int,    int32_t)
-VM_CALL_METHOD_VALIST(_long,   int64_t)
-VM_CALL_METHOD_VALIST(_float,  float)
-VM_CALL_METHOD_VALIST(_double, double)
-
-
-/* vm_call_method_jvalue *******************************************************
-
-   Calls a Java method with a variable number of arguments, passed via
-   a jvalue array.
-
-*******************************************************************************/
-
-#define VM_CALL_METHOD_JVALUE(name, type)                               \
-type vm_call_method##name##_jvalue(methodinfo *m, java_handle_t *o,     \
-                                                          const jvalue *args)                  \
-{                                                                       \
-       uint64_t *array;                                                    \
-       type      value;                                                    \
-       int32_t   dumpmarker;                                               \
-                                                                        \
-       if (m->code == NULL)                                                \
-               if (!jit_compile(m))                                            \
-                       return 0;                                                   \
-                                                                        \
-       THREAD_NATIVEWORLD_EXIT;                                            \
-       DMARKER;                                                            \
-                                                                        \
-       array = argument_vmarray_from_jvalue(m, o, args);                   \
-       value = vm_call##name##_array(m, array);                            \
-                                                                        \
-       DRELEASE;                                                           \
-       THREAD_NATIVEWORLD_ENTER;                                           \
-                                                                        \
-       return value;                                                       \
-}
-
-VM_CALL_METHOD_JVALUE(,        java_handle_t *)
-VM_CALL_METHOD_JVALUE(_int,    int32_t)
-VM_CALL_METHOD_JVALUE(_long,   int64_t)
-VM_CALL_METHOD_JVALUE(_float,  float)
-VM_CALL_METHOD_JVALUE(_double, double)
-
-
-/* vm_call_method_objectarray **************************************************
-
-   Calls a Java method with a variable number if arguments, passed via
-   an objectarray of boxed values. Returns a boxed value.
-
-*******************************************************************************/
-
-java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
-                                                                                 java_handle_objectarray_t *params)
-{
-       uint64_t      *array;
-       java_handle_t *xptr;
-       java_handle_t *ro;
-       imm_union      value;
-       int32_t        dumpmarker;
-
-       /* Prevent compiler warnings. */
-
-       ro = NULL;
-
-       /* compile methods which are not yet compiled */
-
-       if (m->code == NULL)
-               if (!jit_compile(m))
-                       return NULL;
-
-       /* leave the nativeworld */
-
-       THREAD_NATIVEWORLD_EXIT;
-
-       /* mark start of dump memory area */
-
-       DMARKER;
-
-       /* Fill the argument array from a object-array. */
-
-       array = argument_vmarray_from_objectarray(m, o, params);
-
-       if (array == NULL) {
-               /* release dump area */
-
-               DRELEASE;
-
-               /* enter the nativeworld again */
-
-               THREAD_NATIVEWORLD_ENTER;
-
-               exceptions_throw_illegalargumentexception();
-
-               return NULL;
-       }
-
-       switch (m->parseddesc->returntype.decltype) {
-       case PRIMITIVETYPE_VOID:
-               value.a = vm_call_array(m, array);
-               break;
-
-       case PRIMITIVETYPE_BOOLEAN:
-       case PRIMITIVETYPE_BYTE:
-       case PRIMITIVETYPE_CHAR:
-       case PRIMITIVETYPE_SHORT:
-       case PRIMITIVETYPE_INT:
-               value.i = vm_call_int_array(m, array);
-               break;
-
-       case PRIMITIVETYPE_LONG:
-               value.l = vm_call_long_array(m, array);
-               break;
-
-       case PRIMITIVETYPE_FLOAT:
-               value.f = vm_call_float_array(m, array);
-               break;
-
-       case PRIMITIVETYPE_DOUBLE:
-               value.d = vm_call_double_array(m, array);
-               break;
-
-       case TYPE_ADR:
-               ro = vm_call_array(m, array);
-               break;
-
-       default:
-               vm_abort("vm_call_method_objectarray: invalid return type %d", m->parseddesc->returntype.decltype);
-       }
-
-       /* release dump area */
-
-       DRELEASE;
-
-       /* enter the nativeworld again */
-
-       THREAD_NATIVEWORLD_ENTER;
-
-       /* box the return value if necesarry */
-
-       if (m->parseddesc->returntype.decltype != TYPE_ADR)
-               ro = primitive_box(m->parseddesc->returntype.decltype, value);
-
-       /* check for an exception */
-
-       xptr = exceptions_get_exception();
-
-       if (xptr != NULL) {
-               /* clear exception pointer, we are calling JIT code again */
-
-               exceptions_clear_exception();
-
-               exceptions_throw_invocationtargetexception(xptr);
-       }
-
-       return ro;
-}
-
-
-/*
- * 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/vm.cpp b/src/vm/vm.cpp
new file mode 100644 (file)
index 0000000..0f099b7
--- /dev/null
@@ -0,0 +1,2684 @@
+/* src/vm/vm.cpp - VM startup and shutdown 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 <stdint.h>
+
+#include <exception>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "vm/types.h"
+
+#include "arch.h"
+#include "md-abi.h"
+
+#include "vm/jit/abi-asm.h"
+
+#include "mm/codememory.h"
+#include "mm/gc.hpp"
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+#include "native/localref.h"
+#include "native/native.h"
+
+#include "native/vm/nativevm.h"
+
+#include "threads/lock-common.h"
+#include "threads/threadlist.h"
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/array.h"
+
+#if defined(ENABLE_ASSERTION)
+#include "vm/assertion.h"
+#endif
+
+#include "vm/builtin.h"
+#include "vm/classcache.h"
+#include "vm/exceptions.hpp"
+#include "vm/finalizer.h"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/os.hpp"
+#include "vm/package.hpp"
+#include "vm/primitive.hpp"
+#include "vm/properties.h"
+#include "vm/signallocal.h"
+#include "vm/statistics.h"
+#include "vm/string.hpp"
+#include "vm/suck.h"
+#include "vm/vm.hpp"
+
+#include "vm/jit/argument.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/code.h"
+
+#if defined(ENABLE_DISASSEMBLER)
+# include "vm/jit/disass.h"
+#endif
+
+#include "vm/jit/jit.h"
+#include "vm/jit/jitcache.h"
+#include "vm/jit/methodtree.h"
+
+#if defined(ENABLE_PROFILING)
+# include "vm/jit/optimizing/profile.h"
+#endif
+
+#include "vm/jit/optimizing/recompile.h"
+
+#if defined(ENABLE_PYTHON)
+# include "vm/jit/python.h"
+#endif
+
+#include "vm/jit/trap.h"
+
+#if defined(ENABLE_JVMTI)
+# include "native/jvmti/cacaodbg.h"
+#endif
+
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
+
+/**
+ * This is _the_ instance of the VM.
+ */
+VM* vm;
+
+
+/* global variables ***********************************************************/
+
+s4 vms = 0;                             /* number of VMs created              */
+
+static classinfo *mainclass = NULL;
+
+#if defined(ENABLE_INTRP)
+u1 *intrp_main_stack = NULL;
+#endif
+
+
+/* define heap sizes **********************************************************/
+
+#define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
+#define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
+#define STACK_SIZE               128 * 1024 /* default 64kB                   */
+
+
+/* define command line options ************************************************/
+
+enum {
+       OPT_FOO,
+
+       /* Java options */
+
+       OPT_JAR,
+
+       OPT_D32,
+       OPT_D64,
+
+       OPT_CLASSPATH,
+       OPT_D,
+
+       OPT_VERBOSE,
+
+       OPT_VERSION,
+       OPT_SHOWVERSION,
+       OPT_FULLVERSION,
+
+       OPT_HELP,
+       OPT_X,
+       OPT_XX,
+
+       OPT_EA,
+       OPT_DA,
+       OPT_EA_NOARG,
+       OPT_DA_NOARG,
+    
+
+       OPT_ESA,
+       OPT_DSA,
+
+       /* Java non-standard options */
+
+       OPT_JIT,
+       OPT_INTRP,
+
+       OPT_BOOTCLASSPATH,
+       OPT_BOOTCLASSPATH_A,
+       OPT_BOOTCLASSPATH_P,
+
+       OPT_BOOTCLASSPATH_C,
+
+#if defined(ENABLE_PROFILING)
+       OPT_PROF,
+       OPT_PROF_OPTION,
+#endif
+
+       OPT_MS,
+       OPT_MX,
+
+       /* CACAO options */
+
+       OPT_VERBOSE1,
+       OPT_NOIEEE,
+
+#if defined(ENABLE_STATISTICS)
+       OPT_TIME,
+       OPT_STAT,
+#endif
+
+       OPT_LOG,
+       OPT_CHECK,
+       OPT_LOAD,
+       OPT_SHOW,
+       OPT_DEBUGCOLOR,
+
+#if !defined(NDEBUG)
+       OPT_ALL,
+       OPT_METHOD,
+       OPT_SIGNATURE,
+#endif
+
+#if defined(ENABLE_VERIFIER)
+       OPT_NOVERIFY,
+#if defined(TYPECHECK_VERBOSE)
+       OPT_VERBOSETC,
+#endif
+#endif /* defined(ENABLE_VERIFIER) */
+
+       /* optimization options */
+
+#if defined(ENABLE_LOOP)
+       OPT_OLOOP,
+#endif
+       
+#if defined(ENABLE_IFCONV)
+       OPT_IFCONV,
+#endif
+
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+       OPT_LSRA,
+#endif
+
+#if defined(ENABLE_INTRP)
+       /* interpreter options */
+
+       OPT_NO_DYNAMIC,
+       OPT_NO_REPLICATION,
+       OPT_NO_QUICKSUPER,
+       OPT_STATIC_SUPERS,
+       OPT_TRACE,
+#endif
+
+       OPT_SS,
+
+#ifdef ENABLE_JVMTI
+       OPT_DEBUG,
+       OPT_XRUNJDWP,
+       OPT_NOAGENT,
+       OPT_AGENTLIB,
+       OPT_AGENTPATH,
+#endif
+
+#if defined(ENABLE_DEBUG_FILTER)
+       OPT_FILTER_VERBOSECALL_INCLUDE,
+       OPT_FILTER_VERBOSECALL_EXCLUDE,
+       OPT_FILTER_SHOW_METHOD,
+#endif
+
+       DUMMY
+};
+
+
+opt_struct opts[] = {
+       { "foo",               false, OPT_FOO },
+
+       /* Java options */
+
+       { "jar",               false, OPT_JAR },
+
+       { "d32",               false, OPT_D32 },
+       { "d64",               false, OPT_D64 },
+       { "client",            false, OPT_IGNORE },
+       { "server",            false, OPT_IGNORE },
+       { "jvm",               false, OPT_IGNORE },
+       { "hotspot",           false, OPT_IGNORE },
+
+       { "classpath",         true,  OPT_CLASSPATH },
+       { "cp",                true,  OPT_CLASSPATH },
+       { "D",                 true,  OPT_D },
+       { "version",           false, OPT_VERSION },
+       { "showversion",       false, OPT_SHOWVERSION },
+       { "fullversion",       false, OPT_FULLVERSION },
+       { "help",              false, OPT_HELP },
+       { "?",                 false, OPT_HELP },
+       { "X",                 false, OPT_X },
+       { "XX:",               true,  OPT_XX },
+
+       { "ea:",               true,  OPT_EA },
+       { "da:",               true,  OPT_DA },
+       { "ea",                false, OPT_EA_NOARG },
+       { "da",                false, OPT_DA_NOARG },
+
+       { "enableassertions:",  true,  OPT_EA },
+       { "disableassertions:", true,  OPT_DA },
+       { "enableassertions",   false, OPT_EA_NOARG },
+       { "disableassertions",  false, OPT_DA_NOARG },
+
+       { "esa",                     false, OPT_ESA },
+       { "enablesystemassertions",  false, OPT_ESA },
+       { "dsa",                     false, OPT_DSA },
+       { "disablesystemassertions", false, OPT_DSA },
+
+       { "noasyncgc",         false, OPT_IGNORE },
+#if defined(ENABLE_VERIFIER)
+       { "noverify",          false, OPT_NOVERIFY },
+       { "Xverify:none",      false, OPT_NOVERIFY },
+#endif
+       { "v",                 false, OPT_VERBOSE1 },
+       { "verbose:",          true,  OPT_VERBOSE },
+
+#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
+       { "verbosetc",         false, OPT_VERBOSETC },
+#endif
+#if defined(__ALPHA__)
+       { "noieee",            false, OPT_NOIEEE },
+#endif
+#if defined(ENABLE_STATISTICS)
+       { "time",              false, OPT_TIME },
+       { "stat",              false, OPT_STAT },
+#endif
+       { "log",               true,  OPT_LOG },
+       { "c",                 true,  OPT_CHECK },
+       { "l",                 false, OPT_LOAD },
+
+#if !defined(NDEBUG)
+       { "all",               false, OPT_ALL },
+       { "sig",               true,  OPT_SIGNATURE },
+#endif
+
+#if defined(ENABLE_LOOP)
+       { "oloop",             false, OPT_OLOOP },
+#endif
+#if defined(ENABLE_IFCONV)
+       { "ifconv",            false, OPT_IFCONV },
+#endif
+#if defined(ENABLE_LSRA)
+       { "lsra",              false, OPT_LSRA },
+#endif
+#if  defined(ENABLE_SSA)
+       { "lsra",              true, OPT_LSRA },
+#endif
+
+#if defined(ENABLE_INTRP)
+       /* interpreter options */
+
+       { "trace",             false, OPT_TRACE },
+       { "static-supers",     true,  OPT_STATIC_SUPERS },
+       { "no-dynamic",        false, OPT_NO_DYNAMIC },
+       { "no-replication",    false, OPT_NO_REPLICATION },
+       { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
+#endif
+
+       /* JVMTI Agent Command Line Options */
+#ifdef ENABLE_JVMTI
+       { "agentlib:",         true,  OPT_AGENTLIB },
+       { "agentpath:",        true,  OPT_AGENTPATH },
+#endif
+
+       /* Java non-standard options */
+
+       { "Xjit",              false, OPT_JIT },
+       { "Xint",              false, OPT_INTRP },
+       { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
+       { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
+       { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
+       { "Xbootclasspath/c:", true,  OPT_BOOTCLASSPATH_C },
+
+#ifdef ENABLE_JVMTI
+       { "Xdebug",            false, OPT_DEBUG },
+       { "Xnoagent",          false, OPT_NOAGENT },
+       { "Xrunjdwp",          true,  OPT_XRUNJDWP },
+#endif 
+
+       { "Xms",               true,  OPT_MS },
+       { "ms",                true,  OPT_MS },
+       { "Xmx",               true,  OPT_MX },
+       { "mx",                true,  OPT_MX },
+       { "Xss",               true,  OPT_SS },
+       { "ss",                true,  OPT_SS },
+
+#if defined(ENABLE_PROFILING)
+       { "Xprof:",            true,  OPT_PROF_OPTION },
+       { "Xprof",             false, OPT_PROF },
+#endif
+
+       /* keep these at the end of the list */
+
+#if !defined(NDEBUG)
+       { "m",                 true,  OPT_METHOD },
+#endif
+
+       { "s",                 true,  OPT_SHOW },
+       { "debug-color",      false,  OPT_DEBUGCOLOR },
+
+#if defined(ENABLE_DEBUG_FILTER)
+       { "XXfi",              true,  OPT_FILTER_VERBOSECALL_INCLUDE },
+       { "XXfx",              true,  OPT_FILTER_VERBOSECALL_EXCLUDE },
+       { "XXfm",              true,  OPT_FILTER_SHOW_METHOD },
+#endif
+
+       { NULL,                false, 0 }
+};
+
+
+/* usage ***********************************************************************
+
+   Prints the correct usage syntax to stdout.
+
+*******************************************************************************/
+
+void usage(void)
+{
+       puts("Usage: cacao [-options] classname [arguments]");
+       puts("               (to run a class file)");
+       puts("   or  cacao [-options] -jar jarfile [arguments]");
+       puts("               (to run a standalone jar file)\n");
+
+       puts("where options include:");
+       puts("    -d32                     use 32-bit data model if available");
+       puts("    -d64                     use 64-bit data model if available");
+       puts("    -client                  compatibility (currently ignored)");
+       puts("    -server                  compatibility (currently ignored)");
+       puts("    -jvm                     compatibility (currently ignored)");
+       puts("    -hotspot                 compatibility (currently ignored)\n");
+
+       puts("    -cp <path>               specify a path to look for classes");
+       puts("    -classpath <path>        specify a path to look for classes");
+       puts("    -D<name>=<value>         add an entry to the property list");
+       puts("    -verbose[:class|gc|jni]  enable specific verbose output");
+       puts("    -version                 print product version and exit");
+       puts("    -fullversion             print jpackage-compatible product version and exit");
+       puts("    -showversion             print product version and continue");
+       puts("    -help, -?                print this help message");
+       puts("    -X                       print help on non-standard Java options");
+       puts("    -XX                      print help on debugging options");
+    puts("    -ea[:<packagename>...|:<classname>]");
+    puts("    -enableassertions[:<packagename>...|:<classname>]");
+       puts("                             enable assertions with specified granularity");
+       puts("    -da[:<packagename>...|:<classname>]");
+       puts("    -disableassertions[:<packagename>...|:<classname>]");
+       puts("                             disable assertions with specified granularity");
+       puts("    -esa | -enablesystemassertions");
+       puts("                             enable system assertions");
+       puts("    -dsa | -disablesystemassertions");
+       puts("                             disable system assertions");
+
+#ifdef ENABLE_JVMTI
+       puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
+       puts ("                                         for jdwp help use: -agentlib:jdwp=help");
+       puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
+#endif
+
+       /* exit with error code */
+
+       exit(1);
+}   
+
+
+static void Xusage(void)
+{
+#if defined(ENABLE_JIT)
+       puts("    -Xjit                    JIT mode execution (default)");
+#endif
+#if defined(ENABLE_INTRP)
+       puts("    -Xint                    interpreter mode execution");
+#endif
+       puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
+    puts("                             value is set as bootstrap class path");
+       puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
+       puts("                             value is appended to the bootstrap class path");
+       puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
+       puts("                             value is prepended to the bootstrap class path");
+       puts("    -Xbootclasspath/c:<zip/jar files and directories separated by :>");
+       puts("                             value is used as Java core library, but the");
+       puts("                             hardcoded VM interface classes are prepended");
+       printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
+       printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
+       printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
+
+#if defined(ENABLE_PROFILING)
+       puts("    -Xprof[:bb]              collect and print profiling data");
+#endif
+
+#if defined(ENABLE_JVMTI)
+    /* -Xdebug option depend on gnu classpath JDWP options. options: 
+        transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
+       puts("    -Xdebug                  enable remote debugging\n");
+       puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
+       puts("                             enable remote debugging\n");
+#endif 
+
+       /* exit with error code */
+
+       exit(1);
+}   
+
+
+#if 0
+static void XXusage(void)
+{
+       puts("    -v                       write state-information");
+#if !defined(NDEBUG)
+       puts("    -verbose:jit             enable specific verbose output");
+       puts("    -debug-color             colored output for ANSI terms");
+#endif
+#ifdef TYPECHECK_VERBOSE
+       puts("    -verbosetc               write debug messages while typechecking");
+#endif
+#if defined(__ALPHA__)
+       puts("    -noieee                  don't use ieee compliant arithmetic");
+#endif
+#if defined(ENABLE_VERIFIER)
+       puts("    -noverify                don't verify classfiles");
+#endif
+#if defined(ENABLE_STATISTICS)
+       puts("    -time                    measure the runtime");
+       puts("    -stat                    detailed compiler statistics");
+#endif
+       puts("    -log logfile             specify a name for the logfile");
+       puts("    -c(heck)b(ounds)         don't check array bounds");
+       puts("            s(ync)           don't check for synchronization");
+#if defined(ENABLE_LOOP)
+       puts("    -oloop                   optimize array accesses in loops");
+#endif
+       puts("    -l                       don't start the class after loading");
+#if !defined(NDEBUG)
+       puts("    -all                     compile all methods, no execution");
+       puts("    -m                       compile only a specific method");
+       puts("    -sig                     specify signature for a specific method");
+#endif
+
+       puts("    -s...                    show...");
+       puts("      (c)onstants            the constant pool");
+       puts("      (m)ethods              class fields and methods");
+       puts("      (u)tf                  the utf - hash");
+       puts("      (i)ntermediate         intermediate representation");
+#if defined(ENABLE_DISASSEMBLER)
+       puts("      (a)ssembler            disassembled listing");
+       puts("      n(o)ps                 show NOPs in disassembler output");
+#endif
+       puts("      (d)atasegment          data segment listing");
+
+#if defined(ENABLE_IFCONV)
+       puts("    -ifconv                  use if-conversion");
+#endif
+#if defined(ENABLE_LSRA)
+       puts("    -lsra                    use linear scan register allocation");
+#endif
+#if defined(ENABLE_SSA)
+       puts("    -lsra:...                use linear scan register allocation (with SSA)");
+       puts("       (d)ead code elimination");
+       puts("       (c)opy propagation");
+#endif
+#if defined(ENABLE_DEBUG_FILTER)
+       puts("    -XXfi <regex>            begin of dynamic scope for verbosecall filter");
+       puts("    -XXfx <regex>            end of dynamic scope for verbosecall filter");
+       puts("    -XXfm <regex>            filter for show options");
+#endif
+       /* exit with error code */
+
+       exit(1);
+}
+#endif
+
+
+/* version *********************************************************************
+
+   Only prints cacao version information.
+
+*******************************************************************************/
+
+static void version(bool opt_exit)
+{
+       puts("java version \""JAVA_VERSION"\"");
+       puts("CACAO version "VERSION"\n");
+
+       puts("Copyright (C) 1996-2005, 2006, 2007, 2008");
+       puts("CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
+       puts("This is free software; see the source for copying conditions.  There is NO");
+       puts("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
+
+       /* exit normally, if requested */
+
+       if (opt_exit)
+               exit(0);
+}
+
+
+/* fullversion *****************************************************************
+
+   Prints a Sun compatible version information (required e.g. by
+   jpackage, www.jpackage.org).
+
+*******************************************************************************/
+
+static void fullversion(void)
+{
+       puts("java full version \"cacao-"JAVA_VERSION"\"");
+
+       /* exit normally */
+
+       exit(0);
+}
+
+
+static void vm_printconfig(void)
+{
+       puts("Configure/Build options:\n");
+       puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
+#if defined(__VERSION__)
+       puts("  CC         : "VERSION_CC" ("__VERSION__")");
+#else
+       puts("  CC         : "VERSION_CC"");
+#endif
+       puts("  CFLAGS     : "VERSION_CFLAGS"\n");
+
+       puts("Default variables:\n");
+       printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
+       printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
+       printf("  stack size                     : %d\n", STACK_SIZE);
+
+#if defined(ENABLE_JRE_LAYOUT)
+       /* When we're building with JRE-layout, the default paths are the
+          same as the runtime paths. */
+#else
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       puts("  gnu.classpath.boot.library.path: "JAVA_RUNTIME_LIBRARY_LIBDIR);
+       puts("  java.boot.class.path           : "CACAO_VM_ZIP":"JAVA_RUNTIME_LIBRARY_CLASSES"");
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       puts("  sun.boot.library.path          : "JAVA_RUNTIME_LIBRARY_LIBDIR);
+       puts("  java.boot.class.path           : "JAVA_RUNTIME_LIBRARY_CLASSES);
+# endif
+#endif
+
+       puts("");
+
+       puts("Runtime variables:\n");
+       printf("  maximum heap size              : %d\n", opt_heapmaxsize);
+       printf("  initial heap size              : %d\n", opt_heapstartsize);
+       printf("  stack size                     : %d\n", opt_stacksize);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       printf("  gnu.classpath.boot.library.path: %s\n", properties_get("gnu.classpath.boot.library.path"));
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       printf("  sun.boot.library.path          : %s\n", properties_get("sun.boot.library.path"));
+#endif
+
+       printf("  java.boot.class.path           : %s\n", properties_get("java.boot.class.path"));
+       printf("  java.class.path                : %s\n", properties_get("java.class.path"));
+}
+
+
+/* forward declarations *******************************************************/
+
+static char *vm_get_mainclass_from_jar(char *mainstring);
+#if !defined(NDEBUG)
+static void  vm_compile_all(void);
+static void  vm_compile_method(char* mainname);
+#endif
+
+
+/**
+ * Implementation for JNI_CreateJavaVM.  This function creates a VM
+ * object.
+ *
+ * @param p_vm
+ * @param p_env
+ * @param vm_args
+ *
+ * @return true on success, false otherwise.
+ */
+bool VM::create(JavaVM** p_vm, void** p_env, void* vm_args)
+{
+       JavaVMInitArgs* _vm_args;
+
+       // Get the arguments for the new JVM.
+       _vm_args = (JavaVMInitArgs *) vm_args;
+
+       // Instantiate a new VM.
+       try {
+               vm = new VM(_vm_args);
+       }
+       catch (std::exception e) {
+               // FIXME How can we delete the resources allocated?
+//             /* release allocated memory */
+//             FREE(env, _Jv_JNIEnv);
+//             FREE(vm, _Jv_JavaVM);
+
+               vm = NULL;
+
+               return false;
+       }
+
+       // Return the values.
+
+       *p_vm  = vm->get_javavm();
+       *p_env = vm->get_jnienv();
+
+       return true;
+}
+
+
+/**
+ * C wrapper for VM::create.
+ */
+extern "C" {
+       bool VM_create(JavaVM** p_vm, void** p_env, void* vm_args)
+       {
+               return VM::create(p_vm, p_env, vm_args);
+       }
+}
+
+
+/**
+ * VM constructor.
+ */
+VM::VM(JavaVMInitArgs* vm_args)
+{
+       // Very first thing to do: we are initializing.
+       _initializing = true;
+
+       // Make ourself globally visible.
+       // XXX Is this a good idea?
+       vm = this;
+
+       /* create and fill a JavaVM structure */
+
+       _javavm = new JavaVM();
+
+#if defined(ENABLE_JNI)
+       _javavm->functions = &_Jv_JNIInvokeInterface;
+#endif
+
+       /* get the VM and Env tables (must be set before vm_create) */
+       /* XXX JVMTI Agents needs a JavaVM  */
+
+       _jnienv = new JNIEnv();
+
+#if defined(ENABLE_JNI)
+       _jnienv->functions = &_Jv_JNINativeInterface;
+#endif
+
+       /* actually create the JVM */
+
+       int   len;
+       char *p;
+       char *boot_class_path;
+       char *class_path;
+       int   opt;
+       bool  opt_version;
+       bool  opt_exit;
+
+#if defined(ENABLE_JVMTI)
+       lt_dlhandle  handle;
+       char *libname, *agentarg;
+       bool jdwp,agentbypath;
+       jdwp = agentbypath = false;
+#endif
+
+#if defined(ENABLE_JNI)
+       /* Check the JNI version requested. */
+
+       if (!jni_version_check(vm_args->version))
+               throw std::exception();
+#endif
+
+       /* We only support 1 JVM instance. */
+
+       if (vms > 0)
+               throw std::exception();
+
+       /* Install the exit handler. */
+
+       if (atexit(vm_exit_handler))
+               vm_abort("atexit failed: %s\n", strerror(errno));
+
+       /* Set some options. */
+
+       opt_version       = false;
+       opt_exit          = false;
+
+       opt_noieee        = false;
+
+       opt_heapmaxsize   = HEAP_MAXSIZE;
+       opt_heapstartsize = HEAP_STARTSIZE;
+       opt_stacksize     = STACK_SIZE;
+
+       /* Initialize the properties list before command-line handling.
+          Otherwise -XX:+PrintConfig crashes. */
+
+       properties_init();
+
+       /* First of all, parse the -XX options. */
+
+#if defined(ENABLE_VMLOG)
+       vmlog_cacao_init_options();
+#endif
+
+       options_xx(vm_args);
+
+#if defined(ENABLE_VMLOG)
+       vmlog_cacao_init();
+#endif
+
+       /* We need to check if the actual size of a java.lang.Class object
+          is smaller or equal than the assumption made in
+          src/vm/class.h. */
+
+#warning FIXME We need to check the size of java.lang.Class!!!
+//     if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
+//             vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
+
+       /* set the VM starttime */
+
+       _starttime = builtin_currenttimemillis();
+
+#if defined(ENABLE_JVMTI)
+       /* initialize JVMTI related  **********************************************/
+       jvmti = false;
+#endif
+
+       /* Fill the properties before command-line handling. */
+
+       properties_set();
+
+       /* iterate over all passed options */
+
+       while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
+               switch (opt) {
+               case OPT_FOO:
+                       opt_foo = true;
+                       break;
+
+               case OPT_IGNORE:
+                       break;
+                       
+               case OPT_JAR:
+                       opt_jar = true;
+                       break;
+
+               case OPT_D32:
+#if SIZEOF_VOID_P == 8
+                       puts("Running a 32-bit JVM is not supported on this platform.");
+                       exit(1);
+#endif
+                       break;
+
+               case OPT_D64:
+#if SIZEOF_VOID_P == 4
+                       puts("Running a 64-bit JVM is not supported on this platform.");
+                       exit(1);
+#endif
+                       break;
+
+               case OPT_CLASSPATH:
+                       /* Forget old classpath and set the argument as new
+                          classpath. */
+
+                       // FIXME Make class_path const char*.
+                       class_path = (char*) properties_get("java.class.path");
+
+                       p = MNEW(char, strlen(opt_arg) + strlen("0"));
+
+                       strcpy(p, opt_arg);
+
+#if defined(ENABLE_JAVASE)
+                       properties_add("java.class.path", p);
+#endif
+
+                       MFREE(class_path, char, strlen(class_path));
+                       break;
+
+               case OPT_D:
+                       for (unsigned int i = 0; i < strlen(opt_arg); i++) {
+                               if (opt_arg[i] == '=') {
+                                       opt_arg[i] = '\0';
+                                       properties_add(opt_arg, opt_arg + i + 1);
+                                       goto opt_d_done;
+                               }
+                       }
+
+                       /* if no '=' is given, just create an empty property */
+
+                       properties_add(opt_arg, "");
+
+               opt_d_done:
+                       break;
+
+               case OPT_BOOTCLASSPATH:
+                       /* Forget default bootclasspath and set the argument as
+                          new boot classpath. */
+
+                       // FIXME Make boot_class_path const char*.
+                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+
+                       p = MNEW(char, strlen(opt_arg) + strlen("0"));
+
+                       strcpy(p, opt_arg);
+
+                       properties_add("sun.boot.class.path", p);
+                       properties_add("java.boot.class.path", p);
+
+                       MFREE(boot_class_path, char, strlen(boot_class_path));
+                       break;
+
+               case OPT_BOOTCLASSPATH_A:
+                       /* Append to bootclasspath. */
+
+                       // FIXME Make boot_class_path const char*.
+                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+
+                       len = strlen(boot_class_path);
+
+                       // XXX (char*) quick hack
+                       p = (char*) MREALLOC(boot_class_path,
+                                                char,
+                                                len + strlen("0"),
+                                                len + strlen(":") +
+                                                strlen(opt_arg) + strlen("0"));
+
+                       strcat(p, ":");
+                       strcat(p, opt_arg);
+
+                       properties_add("sun.boot.class.path", p);
+                       properties_add("java.boot.class.path", p);
+                       break;
+
+               case OPT_BOOTCLASSPATH_P:
+                       /* Prepend to bootclasspath. */
+
+                       // FIXME Make boot_class_path const char*.
+                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+
+                       len = strlen(boot_class_path);
+
+                       p = MNEW(char, strlen(opt_arg) + strlen(":") + len + strlen("0"));
+
+                       strcpy(p, opt_arg);
+                       strcat(p, ":");
+                       strcat(p, boot_class_path);
+
+                       properties_add("sun.boot.class.path", p);
+                       properties_add("java.boot.class.path", p);
+
+                       MFREE(boot_class_path, char, len);
+                       break;
+
+               case OPT_BOOTCLASSPATH_C:
+                       /* Use as Java core library, but prepend VM interface
+                          classes. */
+
+                       // FIXME Make boot_class_path const char*.
+                       boot_class_path = (char*) properties_get("sun.boot.class.path");
+
+                       len =
+                               strlen(CACAO_VM_ZIP) +
+                               strlen(":") +
+                               strlen(opt_arg) +
+                               strlen("0");
+
+                       p = MNEW(char, len);
+
+                       strcpy(p, CACAO_VM_ZIP);
+                       strcat(p, ":");
+                       strcat(p, opt_arg);
+
+                       properties_add("sun.boot.class.path", p);
+                       properties_add("java.boot.class.path", p);
+
+                       MFREE(boot_class_path, char, strlen(boot_class_path));
+                       break;
+
+#if defined(ENABLE_JVMTI)
+               case OPT_DEBUG:
+                       /* this option exists only for compatibility reasons */
+                       break;
+
+               case OPT_NOAGENT:
+                       /* I don't know yet what Xnoagent should do. This is only for 
+                          compatiblity with eclipse - motse */
+                       break;
+
+               case OPT_XRUNJDWP:
+                       agentbypath = true;
+                       jvmti       = true;
+                       jdwp        = true;
+
+                       len =
+                               strlen(CACAO_LIBDIR) +
+                               strlen("/libjdwp.so=") +
+                               strlen(opt_arg) +
+                               strlen("0");
+
+                       agentarg = MNEW(char, len);
+
+                       strcpy(agentarg, CACAO_LIBDIR);
+                       strcat(agentarg, "/libjdwp.so=");
+                       strcat(agentarg, &opt_arg[1]);
+                       break;
+
+               case OPT_AGENTPATH:
+                       agentbypath = true;
+
+               case OPT_AGENTLIB:
+                       jvmti = true;
+                       agentarg = opt_arg;
+                       break;
+#endif
+                       
+               case OPT_MX:
+               case OPT_MS:
+               case OPT_SS:
+                       {
+                               char c;
+                               int j;
+
+                               c = opt_arg[strlen(opt_arg) - 1];
+
+                               if ((c == 'k') || (c == 'K')) {
+                                       j = atoi(opt_arg) * 1024;
+
+                               } else if ((c == 'm') || (c == 'M')) {
+                                       j = atoi(opt_arg) * 1024 * 1024;
+
+                               } else
+                                       j = atoi(opt_arg);
+
+                               if (opt == OPT_MX)
+                                       opt_heapmaxsize = j;
+                               else if (opt == OPT_MS)
+                                       opt_heapstartsize = j;
+                               else
+                                       opt_stacksize = j;
+                       }
+                       break;
+
+               case OPT_VERBOSE1:
+                       opt_verbose = true;
+                       break;
+
+               case OPT_VERBOSE:
+                       if (strcmp("class", opt_arg) == 0) {
+                               opt_verboseclass = true;
+                       }
+                       else if (strcmp("gc", opt_arg) == 0) {
+                               opt_verbosegc = true;
+                       }
+                       else if (strcmp("jni", opt_arg) == 0) {
+                               opt_verbosejni = true;
+                       }
+#if !defined(NDEBUG)
+                       else if (strcmp("jit", opt_arg) == 0) {
+                               opt_verbose = true;
+                               loadverbose = true;
+                               initverbose = true;
+                               compileverbose = true;
+                       }
+#endif
+                       else {
+                               printf("Unknown -verbose option: %s\n", opt_arg);
+                               usage();
+                       }
+                       break;
+
+               case OPT_DEBUGCOLOR:
+                       opt_debugcolor = true;
+                       break;
+
+#if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
+               case OPT_VERBOSETC:
+                       opt_typecheckverbose = true;
+                       break;
+#endif
+                               
+               case OPT_VERSION:
+                       opt_version = true;
+                       opt_exit    = true;
+                       break;
+
+               case OPT_FULLVERSION:
+                       fullversion();
+                       break;
+
+               case OPT_SHOWVERSION:
+                       opt_version = true;
+                       break;
+
+               case OPT_NOIEEE:
+                       opt_noieee = true;
+                       break;
+
+#if defined(ENABLE_VERIFIER)
+               case OPT_NOVERIFY:
+                       opt_verify = false;
+                       break;
+#endif
+
+#if defined(ENABLE_STATISTICS)
+               case OPT_TIME:
+                       opt_getcompilingtime = true;
+                       opt_getloadingtime = true;
+                       break;
+                                       
+               case OPT_STAT:
+                       opt_stat = true;
+                       break;
+#endif
+                                       
+               case OPT_LOG:
+                       log_init(opt_arg);
+                       break;
+                       
+               case OPT_CHECK:
+                       for (unsigned int i = 0; i < strlen(opt_arg); i++) {
+                               switch (opt_arg[i]) {
+                               case 'b':
+                                       checkbounds = false;
+                                       break;
+                               case 's':
+                                       checksync = false;
+                                       break;
+                               default:
+                                       usage();
+                               }
+                       }
+                       break;
+                       
+               case OPT_LOAD:
+                       opt_run = false;
+                       makeinitializations = false;
+                       break;
+
+#if !defined(NDEBUG)
+               case OPT_ALL:
+                       compileall = true;
+                       opt_run = false;
+                       makeinitializations = false;
+                       break;
+
+               case OPT_METHOD:
+                       opt_run = false;
+                       opt_method = opt_arg;
+                       makeinitializations = false;
+                       break;
+
+               case OPT_SIGNATURE:
+                       opt_signature = opt_arg;
+                       break;
+#endif
+
+               case OPT_SHOW:       /* Display options */
+                       for (unsigned int i = 0; i < strlen(opt_arg); i++) {            
+                               switch (opt_arg[i]) {
+                               case 'c':
+                                       showconstantpool = true;
+                                       break;
+
+                               case 'u':
+                                       showutf = true;
+                                       break;
+
+                               case 'm':
+                                       showmethods = true;
+                                       break;
+
+                               case 'i':
+                                       opt_showintermediate = true;
+                                       compileverbose = true;
+                                       break;
+
+#if defined(ENABLE_DISASSEMBLER)
+                               case 'a':
+                                       opt_showdisassemble = true;
+                                       compileverbose = true;
+                                       break;
+
+                               case 'o':
+                                       opt_shownops = true;
+                                       break;
+#endif
+
+                               case 'd':
+                                       opt_showddatasegment = true;
+                                       break;
+
+                               default:
+                                       usage();
+                               }
+                       }
+                       break;
+                       
+#if defined(ENABLE_LOOP)
+               case OPT_OLOOP:
+                       opt_loops = true;
+                       break;
+#endif
+
+#if defined(ENABLE_IFCONV)
+               case OPT_IFCONV:
+                       opt_ifconv = true;
+                       break;
+#endif
+
+#if defined(ENABLE_LSRA)
+               case OPT_LSRA:
+                       opt_lsra = true;
+                       break;
+#endif
+#if  defined(ENABLE_SSA)
+               case OPT_LSRA:
+                       opt_lsra = true;
+                       for (unsigned int i = 0; i < strlen(opt_arg); i++) {            
+                               switch (opt_arg[i]) {
+                               case 'c':
+                                       opt_ssa_cp = true;
+                                       break;
+
+                               case 'd':
+                                       opt_ssa_dce = true;
+                                       break;
+
+                               case ':':
+                                       break;
+
+                               default:
+                                       usage();
+                               }
+                       }
+                       break;
+#endif
+
+               case OPT_HELP:
+                       usage();
+                       break;
+
+               case OPT_X:
+                       Xusage();
+                       break;
+
+               case OPT_XX:
+                       /* Already parsed. */
+                       break;
+
+               case OPT_EA:
+#if defined(ENABLE_ASSERTION)
+                       assertion_ea_da(opt_arg, true);
+#endif
+                       break;
+
+               case OPT_DA:
+#if defined(ENABLE_ASSERTION)
+                       assertion_ea_da(opt_arg, false);
+#endif
+                       break;
+
+               case OPT_EA_NOARG:
+#if defined(ENABLE_ASSERTION)
+                       assertion_user_enabled = true;
+#endif
+                       break;
+
+               case OPT_DA_NOARG:
+#if defined(ENABLE_ASSERTION)
+                       assertion_user_enabled = false;
+#endif
+                       break;
+
+               case OPT_ESA:
+#if defined(ENABLE_ASSERTION)
+                       assertion_system_enabled = true;
+#endif
+                       break;
+
+               case OPT_DSA:
+#if defined(ENABLE_ASSERTION)
+                       assertion_system_enabled = false;
+#endif
+                       break;
+
+#if defined(ENABLE_PROFILING)
+               case OPT_PROF_OPTION:
+                       /* use <= to get the last \0 too */
+
+                       for (unsigned int i = 0, j = 0; i <= strlen(opt_arg); i++) {
+                               if (opt_arg[i] == ',')
+                                       opt_arg[i] = '\0';
+
+                               if (opt_arg[i] == '\0') {
+                                       if (strcmp("bb", opt_arg + j) == 0)
+                                               opt_prof_bb = true;
+
+                                       else {
+                                               printf("Unknown option: -Xprof:%s\n", opt_arg + j);
+                                               usage();
+                                       }
+
+                                       /* set k to next char */
+
+                                       j = i + 1;
+                               }
+                       }
+                       /* fall through */
+
+               case OPT_PROF:
+                       opt_prof = true;
+                       break;
+#endif
+
+               case OPT_JIT:
+#if defined(ENABLE_JIT)
+                       opt_jit = true;
+#else
+                       printf("-Xjit option not enabled.\n");
+                       exit(1);
+#endif
+                       break;
+
+               case OPT_INTRP:
+#if defined(ENABLE_INTRP)
+                       opt_intrp = true;
+#else
+                       printf("-Xint option not enabled.\n");
+                       exit(1);
+#endif
+                       break;
+
+#if defined(ENABLE_INTRP)
+               case OPT_STATIC_SUPERS:
+                       opt_static_supers = atoi(opt_arg);
+                       break;
+
+               case OPT_NO_DYNAMIC:
+                       opt_no_dynamic = true;
+                       break;
+
+               case OPT_NO_REPLICATION:
+                       opt_no_replication = true;
+                       break;
+
+               case OPT_NO_QUICKSUPER:
+                       opt_no_quicksuper = true;
+                       break;
+
+               case OPT_TRACE:
+                       vm_debug = true;
+                       break;
+#endif
+
+#if defined(ENABLE_DEBUG_FILTER)
+               case OPT_FILTER_VERBOSECALL_INCLUDE:
+                       opt_filter_verbosecall_include = opt_arg;
+                       break;
+
+               case OPT_FILTER_VERBOSECALL_EXCLUDE:
+                       opt_filter_verbosecall_exclude = opt_arg;
+                       break;
+
+               case OPT_FILTER_SHOW_METHOD:
+                       opt_filter_show_method = opt_arg;
+                       break;
+
+#endif
+               default:
+                       printf("Unknown option: %s\n",
+                                  vm_args->options[opt_index].optionString);
+                       usage();
+               }
+       }
+
+#if defined(ENABLE_JVMTI)
+       if (jvmti) {
+               jvmti_set_phase(JVMTI_PHASE_ONLOAD);
+               jvmti_agentload(agentarg, agentbypath, &handle, &libname);
+
+               if (jdwp)
+                       MFREE(agentarg, char, strlen(agentarg));
+
+               jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
+       }
+#endif
+
+       /* initialize the garbage collector */
+
+       gc_init(opt_heapmaxsize, opt_heapstartsize);
+
+#if defined(ENABLE_THREADS)
+       /* BEFORE: threads_preinit */
+
+       threadlist_init();
+
+       /* AFTER: gc_init */
+
+       threads_preinit();
+       lock_init();
+#endif
+
+       /* install architecture dependent signal handlers */
+
+       if (!signal_init())
+               vm_abort("vm_create: signal_init failed");
+
+#if defined(ENABLE_INTRP)
+       /* Allocate main thread stack on the Java heap. */
+
+       if (opt_intrp) {
+               intrp_main_stack = GCMNEW(u1, opt_stacksize);
+               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+       }
+#endif
+
+       /* AFTER: threads_preinit */
+
+       if (!string_init())
+               vm_abort("vm_create: string_init failed");
+
+       /* AFTER: threads_preinit */
+
+       utf8_init();
+
+       /* AFTER: thread_preinit */
+
+       if (!suck_init())
+               vm_abort("vm_create: suck_init failed");
+
+       suck_add_from_property("java.endorsed.dirs");
+
+       /* Now we have all options handled and we can print the version
+          information.
+
+          AFTER: suck_add_from_property("java.endorsed.dirs"); */
+
+       if (opt_version)
+               version(opt_exit);
+
+       /* AFTER: utf8_init */
+
+       // FIXME Make boot_class_path const char*.
+       boot_class_path = (char*) properties_get("sun.boot.class.path");
+       suck_add(boot_class_path);
+
+       /* initialize the classcache hashtable stuff: lock, hashtable
+          (must be done _after_ threads_preinit) */
+
+       if (!classcache_init())
+               vm_abort("vm_create: classcache_init failed");
+
+       /* Initialize the code memory management. */
+       /* AFTER: threads_preinit */
+
+       codememory_init();
+
+       /* initialize the finalizer stuff (must be done _after_
+          threads_preinit) */
+
+       if (!finalizer_init())
+               vm_abort("vm_create: finalizer_init failed");
+
+       /* Initialize the JIT compiler. */
+
+       jit_init();
+       code_init();
+       methodtree_init();
+
+#if defined(ENABLE_PYTHON)
+       pythonpass_init();
+#endif
+
+       /* BEFORE: loader_preinit */
+
+       Package::initialize();
+
+       /* AFTER: utf8_init, classcache_init */
+
+       loader_preinit();
+       linker_preinit();
+
+       /* AFTER: loader_preinit, linker_preinit */
+
+       primitive_init();
+
+       loader_init();
+       linker_init();
+
+       /* AFTER: loader_init, linker_init */
+
+       primitive_postinit();
+       method_init();
+
+#if defined(ENABLE_JIT)
+       trap_init();
+#endif
+
+       if (!builtin_init())
+               vm_abort("vm_create: builtin_init failed");
+
+       /* Initialize the native subsystem. */
+       /* BEFORE: threads_init */
+
+       if (!native_init())
+               vm_abort("vm_create: native_init failed");
+
+       /* Register the native methods implemented in the VM. */
+       /* BEFORE: threads_init */
+
+       nativevm_preinit();
+
+#if defined(ENABLE_JNI)
+       /* Initialize the JNI subsystem (must be done _before_
+          threads_init, as threads_init can call JNI methods
+          (e.g. NewGlobalRef). */
+
+       if (!jni_init())
+               vm_abort("vm_create: jni_init failed");
+#endif
+
+#if defined(ENABLE_JNI) || defined(ENABLE_HANDLES)
+       /* Initialize the local reference table for the main thread. */
+       /* BEFORE: threads_init */
+
+       if (!localref_table_init())
+               vm_abort("vm_create: localref_table_init failed");
+#endif
+
+       /* Iinitialize some important system classes. */
+       /* BEFORE: threads_init */
+
+       initialize_init();
+
+#if defined(ENABLE_THREADS)
+       threads_init();
+#endif
+
+       /* Initialize the native VM subsystem. */
+       /* AFTER: threads_init (at least for SUN's classes) */
+
+       nativevm_init();
+
+#if defined(ENABLE_PROFILING)
+       /* initialize profiling */
+
+       if (!profile_init())
+               vm_abort("vm_create: profile_init failed");
+#endif
+
+#if defined(ENABLE_THREADS)
+       /* initialize recompilation */
+
+       if (!recompile_init())
+               vm_abort("vm_create: recompile_init failed");
+
+       /* start the signal handler thread */
+
+#if defined(__LINUX__)
+       /* XXX Remove for exact-GC. */
+       if (threads_pthreads_implementation_nptl)
+#endif
+               if (!signal_start_thread())
+                       vm_abort("vm_create: signal_start_thread failed");
+
+       /* finally, start the finalizer thread */
+
+       if (!finalizer_start_thread())
+               vm_abort("vm_create: finalizer_start_thread failed");
+
+# if !defined(NDEBUG)
+       /* start the memory profiling thread */
+
+       if (opt_ProfileMemoryUsage || opt_ProfileGCMemoryUsage)
+               if (!memory_start_thread())
+                       vm_abort("vm_create: memory_start_thread failed");
+# endif
+
+       /* start the recompilation thread (must be done before the
+          profiling thread) */
+
+       if (!recompile_start_thread())
+               vm_abort("vm_create: recompile_start_thread failed");
+
+# if defined(ENABLE_PROFILING)
+       /* start the profile sampling thread */
+
+/*     if (opt_prof) */
+/*             if (!profile_start_thread()) */
+/*                     vm_abort("vm_create: profile_start_thread failed"); */
+# endif
+#endif
+
+#if defined(ENABLE_JVMTI)
+# if defined(ENABLE_GC_CACAO)
+       /* XXX this will not work with the new indirection cells for classloaders!!! */
+       assert(0);
+# endif
+       if (jvmti) {
+               /* add agent library to native library hashtable */
+               native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
+       }
+#endif
+
+       /* Increment the number of VMs. */
+
+       vms++;
+
+       // Initialization is done, VM is created.
+       _created      = true;
+       _initializing = false;
+       
+       /* Print the VM configuration after all stuff is set and the VM is
+          initialized. */
+
+       if (opt_PrintConfig)
+               vm_printconfig();
+}
+
+
+/* vm_run **********************************************************************
+
+   Runs the main-method of the passed class.
+
+*******************************************************************************/
+
+void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
+{
+       char*                      option;
+       char*                      mainname;
+       char*                      p;
+       utf                       *mainutf;
+       classinfo                 *mainclass;
+       java_handle_t             *e;
+       methodinfo                *m;
+       java_handle_objectarray_t *oa; 
+       s4                         oalength;
+       utf                       *u;
+       java_handle_t             *s;
+       int                        status;
+
+       // Prevent compiler warnings.
+       oa = NULL;
+
+#if !defined(NDEBUG)
+       if (compileall) {
+               vm_compile_all();
+               return;
+       }
+#endif
+
+       /* Get the main class plus it's arguments. */
+
+       mainname = NULL;
+
+       if (opt_index < vm_args->nOptions) {
+               /* Get main-class argument. */
+
+               mainname = vm_args->options[opt_index].optionString;
+
+               /* If the main class argument is a jar file, put it into the
+                  classpath. */
+
+               if (opt_jar == true) {
+                       p = MNEW(char, strlen(mainname) + strlen("0"));
+
+                       strcpy(p, mainname);
+
+#if defined(ENABLE_JAVASE)
+                       properties_add("java.class.path", p);
+#endif
+               }
+               else {
+                       /* Replace dots with slashes in the class name. */
+
+                       for (unsigned int i = 0; i < strlen(mainname); i++)
+                               if (mainname[i] == '.')
+                                       mainname[i] = '/';
+               }
+
+               /* Build argument array.  Move index to first argument. */
+
+               opt_index++;
+
+               oalength = vm_args->nOptions - opt_index;
+
+               oa = builtin_anewarray(oalength, class_java_lang_String);
+
+               for (int i = 0; i < oalength; i++) {
+                       option = vm_args->options[opt_index + i].optionString;
+
+                       u = utf_new_char(option);
+                       s = javastring_new(u);
+
+                       array_objectarray_element_set(oa, i, s);
+               }
+       }
+
+       /* Do we have a main-class argument? */
+
+       if (mainname == NULL)
+               usage();
+
+#if !defined(NDEBUG)
+       if (opt_method != NULL) {
+               vm_compile_method(mainname);
+               return;
+       }
+#endif
+
+       /* set return value to OK */
+
+       status = 0;
+
+       if (opt_jar == true) {
+               /* open jar file with java.util.jar.JarFile */
+
+               mainname = vm_get_mainclass_from_jar(mainname);
+
+               if (mainname == NULL)
+                       vm_exit(1);
+       }
+
+       /* load the main class */
+
+       mainutf = utf_new_char(mainname);
+
+#if defined(ENABLE_JAVAME_CLDC1_1)
+       mainclass = load_class_bootstrap(mainutf);
+#else
+       mainclass = load_class_from_sysloader(mainutf);
+#endif
+
+       /* error loading class */
+
+       e = exceptions_get_and_clear_exception();
+
+       if ((e != NULL) || (mainclass == NULL)) {
+               exceptions_throw_noclassdeffounderror_cause(e);
+               exceptions_print_stacktrace(); 
+               vm_exit(1);
+       }
+
+       if (!link_class(mainclass)) {
+               exceptions_print_stacktrace();
+               vm_exit(1);
+       }
+                       
+       /* find the `main' method of the main class */
+
+       m = class_resolveclassmethod(mainclass,
+                                                                utf_new_char("main"), 
+                                                                utf_new_char("([Ljava/lang/String;)V"),
+                                                                class_java_lang_Object,
+                                                                false);
+
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
+               vm_exit(1);
+       }
+
+       /* there is no main method or it isn't static */
+
+       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
+               exceptions_clear_exception();
+               exceptions_throw_nosuchmethoderror(mainclass,
+                                                                                  utf_new_char("main"), 
+                                                                                  utf_new_char("([Ljava/lang/String;)V"));
+
+               exceptions_print_stacktrace();
+               vm_exit(1);
+       }
+
+#ifdef TYPEINFO_DEBUG_TEST
+       /* test the typeinfo system */
+       typeinfo_test();
+#endif
+
+#if defined(ENABLE_JVMTI)
+       jvmti_set_phase(JVMTI_PHASE_LIVE);
+#endif
+
+       /* set ThreadMXBean variables */
+
+//     _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
+//     _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
+
+//     if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
+//             _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
+//             _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
+//                     _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
+#warning Move to C++
+
+       /* start the main thread */
+
+       (void) vm_call_method(m, NULL, oa);
+
+       /* exception occurred? */
+
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
+               status = 1;
+       }
+
+#if defined(ENABLE_THREADS)
+    /* Detach the main thread so that it appears to have ended when
+          the application's main method exits. */
+
+       if (!thread_detach_current_thread())
+               vm_abort("vm_run: Could not detach main thread.");
+#endif
+
+       /* Destroy the JavaVM. */
+
+       (void) vm_destroy(vm);
+
+       /* And exit. */
+
+       vm_exit(status);
+}
+
+
+/* vm_destroy ******************************************************************
+
+   Unloads a Java VM and reclaims its resources.
+
+*******************************************************************************/
+
+int vm_destroy(JavaVM *vm)
+{
+#if defined(ENABLE_THREADS)
+       /* Create a a trivial new Java waiter thread called
+          "DestroyJavaVM". */
+
+       JavaVMAttachArgs args;
+
+       args.name  = (char*) "DestroyJavaVM";
+       args.group = NULL;
+
+       if (!thread_attach_current_thread(&args, false))
+               return 1;
+
+       /* Wait until we are the last non-daemon thread. */
+
+       threads_join_all_threads();
+#endif
+
+       /* VM is gone. */
+
+//     _created = false;
+#warning Move to C++
+
+       /* Everything is ok. */
+
+       return 0;
+}
+
+
+/* vm_exit *********************************************************************
+
+   Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
+
+*******************************************************************************/
+
+void vm_exit(s4 status)
+{
+       methodinfo *m;
+
+       /* signal that we are exiting */
+
+//     _exiting = true;
+#warning Move to C++
+
+       assert(class_java_lang_System);
+       assert(class_java_lang_System->state & CLASS_LOADED);
+
+#if defined(ENABLE_JVMTI)
+       if (jvmti || (dbgcom!=NULL)) {
+               jvmti_set_phase(JVMTI_PHASE_DEAD);
+               if (jvmti) jvmti_agentunload();
+       }
+#endif
+
+       if (!link_class(class_java_lang_System)) {
+               exceptions_print_stacktrace();
+               exit(1);
+       }
+
+       /* call java.lang.System.exit(I)V */
+
+       m = class_resolveclassmethod(class_java_lang_System,
+                                                                utf_new_char("exit"),
+                                                                utf_int__void,
+                                                                class_java_lang_Object,
+                                                                true);
+       
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               exit(1);
+       }
+
+       /* call the exit function with passed exit status */
+
+       (void) vm_call_method(m, NULL, status);
+
+       /* If we had an exception, just ignore the exception and exit with
+          the proper code. */
+
+       vm_shutdown(status);
+}
+
+
+/* vm_shutdown *****************************************************************
+
+   Terminates the system immediately without freeing memory explicitly
+   (to be used only for abnormal termination).
+       
+*******************************************************************************/
+
+void vm_shutdown(s4 status)
+{
+       if (opt_verbose 
+#if defined(ENABLE_STATISTICS)
+               || opt_getcompilingtime || opt_stat
+#endif
+          ) 
+       {
+               log_text("CACAO terminated by shutdown");
+               dolog("Exit status: %d\n", (s4) status);
+
+       }
+
+#if defined(ENABLE_JVMTI)
+       /* terminate cacaodbgserver */
+       if (dbgcom!=NULL) {
+               mutex_lock(&dbgcomlock);
+               dbgcom->running=1;
+               mutex_unlock(&dbgcomlock);
+               jvmti_cacaodbgserver_quit();
+       }       
+#endif
+
+#if defined (ENABLE_JITCACHE)
+  jitcache_quit();
+#endif
+
+       exit(status);
+}
+
+
+/* vm_exit_handler *************************************************************
+
+   The exit_handler function is called upon program termination.
+
+   ATTENTION: Don't free system resources here! Some threads may still
+   be running as this is called from VMRuntime.exit(). The OS does the
+   cleanup for us.
+
+*******************************************************************************/
+
+void vm_exit_handler(void)
+{
+#if !defined(NDEBUG)
+       if (showmethods)
+               class_showmethods(mainclass);
+
+       if (showconstantpool)
+               class_showconstantpool(mainclass);
+
+       if (showutf)
+               utf_show();
+
+# if defined(ENABLE_PROFILING)
+       if (opt_prof)
+               profile_printstats();
+# endif
+#endif /* !defined(NDEBUG) */
+
+#if defined(ENABLE_RT_TIMING)
+       rt_timing_print_time_stats(stderr);
+#endif
+
+#if defined(ENABLE_CYCLES_STATS)
+       builtin_print_cycles_stats(stderr);
+       stacktrace_print_cycles_stats(stderr);
+#endif
+
+       if (opt_verbose 
+#if defined(ENABLE_STATISTICS)
+               || opt_getcompilingtime || opt_stat
+#endif
+          ) 
+       {
+               log_text("CACAO terminated");
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat) {
+                       print_stats();
+#ifdef TYPECHECK_STATISTICS
+                       typecheck_print_statistics(get_logfile());
+#endif
+               }
+
+               if (opt_getcompilingtime)
+                       print_times();
+#endif /* defined(ENABLE_STATISTICS) */
+       }
+       /* vm_print_profile(stderr);*/
+}
+
+
+/* vm_abort ********************************************************************
+
+   Prints an error message and aborts the VM.
+
+   IN:
+       text ... error message to print
+
+*******************************************************************************/
+
+void vm_abort(const char *text, ...)
+{
+       va_list ap;
+
+       /* Print the log message. */
+
+       log_start();
+
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+
+       log_finish();
+
+       /* Now abort the VM. */
+
+       os::abort();
+}
+
+
+/* vm_abort_errnum *************************************************************
+
+   Prints an error message, appends ":" plus the strerror-message of
+   errnum and aborts the VM.
+
+   IN:
+       errnum ... error number
+       text ..... error message to print
+
+*******************************************************************************/
+
+void vm_abort_errnum(int errnum, const char *text, ...)
+{
+       va_list ap;
+
+       /* Print the log message. */
+
+       log_start();
+
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+
+       /* Print the strerror-message of errnum. */
+
+       log_print(": %s", os::strerror(errnum));
+
+       log_finish();
+
+       /* Now abort the VM. */
+
+       os::abort();
+}
+
+
+/* vm_abort_errno **************************************************************
+
+   Equal to vm_abort_errnum, but uses errno to get the error number.
+
+   IN:
+       text ... error message to print
+
+*******************************************************************************/
+
+void vm_abort_errno(const char *text, ...)
+{
+       va_list ap;
+
+       va_start(ap, text);
+       vm_abort_errnum(errno, text, ap);
+       va_end(ap);
+}
+
+
+/* vm_abort_disassemble ********************************************************
+
+   Prints an error message, disassemble the given code range (if
+   enabled) and aborts the VM.
+
+   IN:
+       pc.......PC to disassemble
+          count....number of instructions to disassemble
+
+*******************************************************************************/
+
+void vm_abort_disassemble(void *pc, int count, const char *text, ...)
+{
+       va_list ap;
+#if defined(ENABLE_DISASSEMBLER)
+       int     i;
+#endif
+
+       /* Print debug message. */
+
+       log_start();
+
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+
+       log_finish();
+
+       /* Print the PC. */
+
+#if SIZEOF_VOID_P == 8
+       log_println("PC=0x%016lx", pc);
+#else
+       log_println("PC=0x%08x", pc);
+#endif
+
+#if defined(ENABLE_DISASSEMBLER)
+       log_println("machine instructions at PC:");
+
+       /* Disassemble the given number of instructions. */
+
+       for (i = 0; i < count; i++)
+               // FIXME disassinstr should use void*.
+               pc = disassinstr((u1*) pc);
+#endif
+
+       vm_abort("Aborting...");
+}
+
+
+/* vm_get_mainclass_from_jar ***************************************************
+
+   Gets the name of the main class from a JAR's manifest file.
+
+*******************************************************************************/
+
+static char *vm_get_mainclass_from_jar(char *mainname)
+{
+       classinfo     *c;
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *s;
+
+       c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
+
+       if (c == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+
+       /* create JarFile object */
+
+       o = builtin_new(c);
+
+       if (o == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+
+       m = class_resolveclassmethod(c,
+                                                                utf_init, 
+                                                                utf_java_lang_String__void,
+                                                                class_java_lang_Object,
+                                                                true);
+
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+
+       s = javastring_new_from_ascii(mainname);
+
+       (void) vm_call_method(m, o, s);
+
+       if (exceptions_get_exception()) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+
+       /* get manifest object */
+
+       m = class_resolveclassmethod(c,
+                                                                utf_new_char("getManifest"), 
+                                                                utf_new_char("()Ljava/util/jar/Manifest;"),
+                                                                class_java_lang_Object,
+                                                                true);
+
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+
+       o = vm_call_method(m, o);
+
+       if (o == NULL) {
+               fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainname);
+               return NULL;
+       }
+
+
+       /* get Main Attributes */
+
+       LLNI_class_get(o, c);
+
+       m = class_resolveclassmethod(c,
+                                                                utf_new_char("getMainAttributes"), 
+                                                                utf_new_char("()Ljava/util/jar/Attributes;"),
+                                                                class_java_lang_Object,
+                                                                true);
+
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+
+       o = vm_call_method(m, o);
+
+       if (o == NULL) {
+               fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainname);
+               return NULL;
+       }
+
+
+       /* get property Main-Class */
+
+       LLNI_class_get(o, c);
+
+       m = class_resolveclassmethod(c,
+                                                                utf_new_char("getValue"), 
+                                                                utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
+                                                                class_java_lang_Object,
+                                                                true);
+
+       if (m == NULL) {
+               exceptions_print_stacktrace();
+               return NULL;
+       }
+
+       s = javastring_new_from_ascii("Main-Class");
+
+       o = vm_call_method(m, o, s);
+
+       if (o == NULL) {
+               fprintf(stderr, "Failed to load Main-Class manifest attribute from\n");
+               fprintf(stderr, "%s\n", mainname);
+               return NULL;
+       }
+
+       return javastring_tochar(o);
+}
+
+
+/* vm_compile_all **************************************************************
+
+   Compile all methods found in the bootclasspath.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+static void vm_compile_all(void)
+{
+       classinfo              *c;
+       methodinfo             *m;
+       u4                      slot;
+       classcache_name_entry  *nmen;
+       classcache_class_entry *clsen;
+       s4                      i;
+
+       /* create all classes found in the bootclasspath */
+       /* XXX currently only works with zip/jar's */
+
+       loader_load_all_classes();
+
+       /* link all classes */
+
+       for (slot = 0; slot < hashtable_classcache.size; slot++) {
+               nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+
+               for (; nmen; nmen = nmen->hashlink) {
+                       /* iterate over all class entries */
+
+                       for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+                               c = clsen->classobj;
+
+                               if (c == NULL)
+                                       continue;
+
+                               if (!(c->state & CLASS_LINKED)) {
+                                       if (!link_class(c)) {
+                                               fprintf(stderr, "Error linking: ");
+                                               utf_fprint_printable_ascii_classname(stderr, c->name);
+                                               fprintf(stderr, "\n");
+
+                                               /* print out exception and cause */
+
+                                               exceptions_print_current_exception();
+
+                                               /* goto next class */
+
+                                               continue;
+                                       }
+                               }
+
+                               /* compile all class methods */
+
+                               for (i = 0; i < c->methodscount; i++) {
+                                       m = &(c->methods[i]);
+
+                                       if (m->jcode != NULL) {
+                                               if (!jit_compile(m)) {
+                                                       fprintf(stderr, "Error compiling: ");
+                                                       utf_fprint_printable_ascii_classname(stderr, c->name);
+                                                       fprintf(stderr, ".");
+                                                       utf_fprint_printable_ascii(stderr, m->name);
+                                                       utf_fprint_printable_ascii(stderr, m->descriptor);
+                                                       fprintf(stderr, "\n");
+
+                                                       /* print out exception and cause */
+
+                                                       exceptions_print_current_exception();
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* vm_compile_method ***********************************************************
+
+   Compile a specific method.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+static void vm_compile_method(char* mainname)
+{
+       methodinfo *m;
+
+       /* create, load and link the main class */
+
+       mainclass = load_class_bootstrap(utf_new_char(mainname));
+
+       if (mainclass == NULL)
+               exceptions_print_stacktrace();
+
+       if (!link_class(mainclass))
+               exceptions_print_stacktrace();
+
+       if (opt_signature != NULL) {
+               m = class_resolveclassmethod(mainclass,
+                                                                        utf_new_char(opt_method),
+                                                                        utf_new_char(opt_signature),
+                                                                        mainclass,
+                                                                        false);
+       }
+       else {
+               m = class_resolveclassmethod(mainclass,
+                                                                        utf_new_char(opt_method),
+                                                                        NULL,
+                                                                        mainclass,
+                                                                        false);
+       }
+
+       if (m == NULL)
+               vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
+                                opt_method, opt_signature ? opt_signature : "");
+               
+       jit_compile(m);
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* vm_call_array ***************************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   an argument array.
+
+   ATTENTION: This function has to be used outside the nativeworld.
+
+*******************************************************************************/
+
+#define VM_CALL_ARRAY(name, type)                                 \
+static type vm_call##name##_array(methodinfo *m, uint64_t *array) \
+{                                                                 \
+       methoddesc *md;                                               \
+       void       *pv;                                               \
+       type        value;                                            \
+                                                                  \
+       assert(m->code != NULL);                                      \
+                                                                  \
+       md = m->parseddesc;                                           \
+       pv = m->code->entrypoint;                                     \
+                                                                  \
+       STATISTICS(count_calls_native_to_java++);                     \
+                                                                  \
+       value = asm_vm_call_method##name(pv, array, md->memuse);      \
+                                                                  \
+       return value;                                                 \
+}
+
+static java_handle_t *vm_call_array(methodinfo *m, uint64_t *array)
+{
+       methoddesc    *md;
+       void          *pv;
+       java_object_t *o;
+
+       assert(m->code != NULL);
+
+       md = m->parseddesc;
+       pv = m->code->entrypoint;
+
+       STATISTICS(count_calls_native_to_java++);
+
+       o = asm_vm_call_method(pv, array, md->memuse);
+
+       if (md->returntype.type == TYPE_VOID)
+               o = NULL;
+
+       return LLNI_WRAP(o);
+}
+
+VM_CALL_ARRAY(_int,    int32_t)
+VM_CALL_ARRAY(_long,   int64_t)
+VM_CALL_ARRAY(_float,  float)
+VM_CALL_ARRAY(_double, double)
+
+
+/* vm_call_method **************************************************************
+
+   Calls a Java method with a variable number of arguments.
+
+*******************************************************************************/
+
+#define VM_CALL_METHOD(name, type)                                  \
+type vm_call_method##name(methodinfo *m, java_handle_t *o, ...)     \
+{                                                                   \
+       va_list ap;                                                     \
+       type    value;                                                  \
+                                                                    \
+       va_start(ap, o);                                                \
+       value = vm_call_method##name##_valist(m, o, ap);                \
+       va_end(ap);                                                     \
+                                                                    \
+       return value;                                                   \
+}
+
+VM_CALL_METHOD(,        java_handle_t *)
+VM_CALL_METHOD(_int,    int32_t)
+VM_CALL_METHOD(_long,   int64_t)
+VM_CALL_METHOD(_float,  float)
+VM_CALL_METHOD(_double, double)
+
+
+/* vm_call_method_valist *******************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a va_list.
+
+*******************************************************************************/
+
+#define VM_CALL_METHOD_VALIST(name, type)                               \
+type vm_call_method##name##_valist(methodinfo *m, java_handle_t *o,     \
+                                                                  va_list ap)                          \
+{                                                                       \
+       uint64_t *array;                                                    \
+       type      value;                                                    \
+       int32_t   dumpmarker;                                               \
+                                                                        \
+       if (m->code == NULL)                                                \
+               if (!jit_compile(m))                                            \
+                       return 0;                                                   \
+                                                                        \
+       THREAD_NATIVEWORLD_EXIT;                                            \
+       DMARKER;                                                            \
+                                                                        \
+       array = argument_vmarray_from_valist(m, o, ap);                     \
+       value = vm_call##name##_array(m, array);                            \
+                                                                        \
+       DRELEASE;                                                           \
+       THREAD_NATIVEWORLD_ENTER;                                           \
+                                                                        \
+       return value;                                                       \
+}
+
+VM_CALL_METHOD_VALIST(,        java_handle_t *)
+VM_CALL_METHOD_VALIST(_int,    int32_t)
+VM_CALL_METHOD_VALIST(_long,   int64_t)
+VM_CALL_METHOD_VALIST(_float,  float)
+VM_CALL_METHOD_VALIST(_double, double)
+
+
+/* vm_call_method_jvalue *******************************************************
+
+   Calls a Java method with a variable number of arguments, passed via
+   a jvalue array.
+
+*******************************************************************************/
+
+#define VM_CALL_METHOD_JVALUE(name, type)                               \
+type vm_call_method##name##_jvalue(methodinfo *m, java_handle_t *o,     \
+                                                          const jvalue *args)                  \
+{                                                                       \
+       uint64_t *array;                                                    \
+       type      value;                                                    \
+       int32_t   dumpmarker;                                               \
+                                                                        \
+       if (m->code == NULL)                                                \
+               if (!jit_compile(m))                                            \
+                       return 0;                                                   \
+                                                                        \
+       THREAD_NATIVEWORLD_EXIT;                                            \
+       DMARKER;                                                            \
+                                                                        \
+       array = argument_vmarray_from_jvalue(m, o, args);                   \
+       value = vm_call##name##_array(m, array);                            \
+                                                                        \
+       DRELEASE;                                                           \
+       THREAD_NATIVEWORLD_ENTER;                                           \
+                                                                        \
+       return value;                                                       \
+}
+
+VM_CALL_METHOD_JVALUE(,        java_handle_t *)
+VM_CALL_METHOD_JVALUE(_int,    int32_t)
+VM_CALL_METHOD_JVALUE(_long,   int64_t)
+VM_CALL_METHOD_JVALUE(_float,  float)
+VM_CALL_METHOD_JVALUE(_double, double)
+
+
+/* vm_call_method_objectarray **************************************************
+
+   Calls a Java method with a variable number if arguments, passed via
+   an objectarray of boxed values. Returns a boxed value.
+
+*******************************************************************************/
+
+java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
+                                                                                 java_handle_objectarray_t *params)
+{
+       uint64_t      *array;
+       java_handle_t *xptr;
+       java_handle_t *ro;
+       imm_union      value;
+       int32_t        dumpmarker;
+
+       /* Prevent compiler warnings. */
+
+       ro = NULL;
+
+       /* compile methods which are not yet compiled */
+
+       if (m->code == NULL)
+               if (!jit_compile(m))
+                       return NULL;
+
+       /* leave the nativeworld */
+
+       THREAD_NATIVEWORLD_EXIT;
+
+       /* mark start of dump memory area */
+
+       DMARKER;
+
+       /* Fill the argument array from a object-array. */
+
+       array = argument_vmarray_from_objectarray(m, o, params);
+
+       if (array == NULL) {
+               /* release dump area */
+
+               DRELEASE;
+
+               /* enter the nativeworld again */
+
+               THREAD_NATIVEWORLD_ENTER;
+
+               exceptions_throw_illegalargumentexception();
+
+               return NULL;
+       }
+
+       switch (m->parseddesc->returntype.primitivetype) {
+       case PRIMITIVETYPE_VOID:
+               value.a = vm_call_array(m, array);
+               break;
+
+       case PRIMITIVETYPE_BOOLEAN:
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               value.i = vm_call_int_array(m, array);
+               break;
+
+       case PRIMITIVETYPE_LONG:
+               value.l = vm_call_long_array(m, array);
+               break;
+
+       case PRIMITIVETYPE_FLOAT:
+               value.f = vm_call_float_array(m, array);
+               break;
+
+       case PRIMITIVETYPE_DOUBLE:
+               value.d = vm_call_double_array(m, array);
+               break;
+
+       case TYPE_ADR:
+               ro = vm_call_array(m, array);
+               break;
+
+       default:
+               vm_abort("vm_call_method_objectarray: invalid return type %d", m->parseddesc->returntype.primitivetype);
+       }
+
+       /* release dump area */
+
+       DRELEASE;
+
+       /* enter the nativeworld again */
+
+       THREAD_NATIVEWORLD_ENTER;
+
+       /* box the return value if necesarry */
+
+       if (m->parseddesc->returntype.primitivetype != TYPE_ADR)
+               ro = Primitive::box(m->parseddesc->returntype.primitivetype, value);
+
+       /* check for an exception */
+
+       xptr = exceptions_get_exception();
+
+       if (xptr != NULL) {
+               /* clear exception pointer, we are calling JIT code again */
+
+               exceptions_clear_exception();
+
+               exceptions_throw_invocationtargetexception(xptr);
+       }
+
+       return ro;
+}
+
+
+/* Legacy C interface *********************************************************/
+
+extern "C" {
+
+JavaVM* VM_get_javavm()      { return vm->get_javavm(); }
+JNIEnv* VM_get_jnienv()      { return vm->get_jnienv(); }
+bool    VM_is_initializing() { return vm->is_initializing(); }
+bool    VM_is_created()      { return vm->is_created(); }
+int64_t VM_get_starttime()   { return vm->get_starttime(); }
+
+}
+
+
+/*
+ * 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/vm.h b/src/vm/vm.h
deleted file mode 100644 (file)
index 6c5fe4e..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* src/vm/vm.h - basic JVM 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 _VM_H
-#define _VM_H
-
-#include "config.h"
-
-#include <stdarg.h>
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "native/jni.h"
-
-#include "vm/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-
-
-/* export global variables ****************************************************/
-
-extern _Jv_JavaVM *_Jv_jvm;
-extern _Jv_JNIEnv *_Jv_env;
-
-extern bool vm_initializing;
-extern bool vm_created;
-extern bool vm_exiting;
-
-#if defined(ENABLE_INTRP)
-extern u1 *intrp_main_stack;
-#endif
-
-
-/* function prototypes ********************************************************/
-
-void usage(void);
-
-bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args);
-bool vm_create(JavaVMInitArgs *vm_args);
-void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args);
-s4   vm_destroy(JavaVM *vm);
-void vm_exit(s4 status);
-void vm_shutdown(s4 status);
-
-void vm_exit_handler(void);
-
-void vm_abort(const char *text, ...);
-void vm_abort_errnum(int errnum, const char *text, ...);
-void vm_abort_errno(const char *text, ...);
-void vm_abort_disassemble(void *pc, int count, const char *text, ...);
-
-/* Java method calling functions */
-
-java_handle_t *vm_call_method(methodinfo *m, java_handle_t *o, ...);
-java_handle_t *vm_call_method_valist(methodinfo *m, java_handle_t *o,
-                                                                                va_list ap);
-java_handle_t *vm_call_method_jvalue(methodinfo *m, java_handle_t *o,
-                                                                                const jvalue *args);
-
-int32_t vm_call_method_int(methodinfo *m, java_handle_t *o, ...);
-int32_t vm_call_method_int_valist(methodinfo *m, java_handle_t *o, va_list ap);
-int32_t vm_call_method_int_jvalue(methodinfo *m, java_handle_t *o, const jvalue *args);
-
-int64_t vm_call_method_long(methodinfo *m, java_handle_t *o, ...);
-int64_t vm_call_method_long_valist(methodinfo *m, java_handle_t *o, va_list ap);
-int64_t vm_call_method_long_jvalue(methodinfo *m, java_handle_t *o, const jvalue *args);
-
-float   vm_call_method_float(methodinfo *m, java_handle_t *o, ...);
-float   vm_call_method_float_valist(methodinfo *m, java_handle_t *o, va_list ap);
-float   vm_call_method_float_jvalue(methodinfo *m, java_handle_t *o, const jvalue *args);
-
-double  vm_call_method_double(methodinfo *m, java_handle_t *o, ...);
-double  vm_call_method_double_valist(methodinfo *m, java_handle_t *o, va_list ap);
-double  vm_call_method_double_jvalue(methodinfo *m, java_handle_t *o, const jvalue *args);
-
-java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params);
-
-#endif /* _VM_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/vm.hpp b/src/vm/vm.hpp
new file mode 100644 (file)
index 0000000..e074b7a
--- /dev/null
@@ -0,0 +1,179 @@
+/* src/vm/vm.hpp - basic JVM 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 _VM_HPP
+#define _VM_HPP
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "native/jni.h"
+
+#include "vm/global.h"
+
+#include "vm/class.h"
+#include "vm/method.h"
+
+#ifdef __cplusplus
+
+/**
+ * Represent an instance of a VM.
+ */
+class VM {
+private:
+       // JNI variables.
+       JavaVM* _javavm;
+       JNIEnv* _jnienv;
+
+       // VM variables.
+       bool    _initializing;
+       bool    _created;
+       bool    _exiting;
+       int64_t _starttime;
+
+public:
+       // Constructor, Destructor.
+       VM(JavaVMInitArgs*);
+       ~VM();
+
+       // Static methods.
+       static bool create(JavaVM** p_vm, void** p_env, void* vm_args);
+
+       // Getters for private members.
+       JavaVM* get_javavm()      { return _javavm; }
+       JNIEnv* get_jnienv()      { return _jnienv; }
+       bool    is_initializing() { return _initializing; }
+       bool    is_created()      { return _created; }
+       bool    is_exiting()      { return _exiting; }
+       int64_t get_starttime()   { return _starttime; }
+};
+
+
+/**
+ * This is _the_ instance of the VM.
+ */
+extern VM* vm;
+
+#else
+
+JavaVM* VM_get_javavm();
+JNIEnv* VM_get_jnienv();
+bool    VM_is_initializing();
+bool    VM_is_created();
+int64_t VM_get_starttime();
+
+#endif
+
+/* These C methods are the exported interface. ********************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool VM_create(JavaVM** p_vm, void** p_env, void* vm_args);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* export global variables ****************************************************/
+
+#if defined(ENABLE_INTRP)
+extern u1 *intrp_main_stack;
+#endif
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void usage(void);
+
+bool vm_create(JavaVMInitArgs *vm_args);
+void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args);
+s4   vm_destroy(JavaVM *vm);
+void vm_exit(s4 status);
+void vm_shutdown(s4 status);
+
+void vm_exit_handler(void);
+
+void vm_abort(const char *text, ...);
+void vm_abort_errnum(int errnum, const char *text, ...);
+void vm_abort_errno(const char *text, ...);
+void vm_abort_disassemble(void *pc, int count, const char *text, ...);
+
+/* Java method calling functions */
+
+java_handle_t *vm_call_method(methodinfo *m, java_handle_t *o, ...);
+java_handle_t *vm_call_method_valist(methodinfo *m, java_handle_t *o,
+                                                                                va_list ap);
+java_handle_t *vm_call_method_jvalue(methodinfo *m, java_handle_t *o,
+                                                                                const jvalue *args);
+
+int32_t vm_call_method_int(methodinfo *m, java_handle_t *o, ...);
+int32_t vm_call_method_int_valist(methodinfo *m, java_handle_t *o, va_list ap);
+int32_t vm_call_method_int_jvalue(methodinfo *m, java_handle_t *o, const jvalue *args);
+
+int64_t vm_call_method_long(methodinfo *m, java_handle_t *o, ...);
+int64_t vm_call_method_long_valist(methodinfo *m, java_handle_t *o, va_list ap);
+int64_t vm_call_method_long_jvalue(methodinfo *m, java_handle_t *o, const jvalue *args);
+
+float   vm_call_method_float(methodinfo *m, java_handle_t *o, ...);
+float   vm_call_method_float_valist(methodinfo *m, java_handle_t *o, va_list ap);
+float   vm_call_method_float_jvalue(methodinfo *m, java_handle_t *o, const jvalue *args);
+
+double  vm_call_method_double(methodinfo *m, java_handle_t *o, ...);
+double  vm_call_method_double_valist(methodinfo *m, java_handle_t *o, va_list ap);
+double  vm_call_method_double_jvalue(methodinfo *m, java_handle_t *o, const jvalue *args);
+
+java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _VM_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:
+ */
diff --git a/src/vm/zip.c b/src/vm/zip.c
new file mode 100644 (file)
index 0000000..da8f078
--- /dev/null
@@ -0,0 +1,459 @@
+/* src/vm/zip.c - ZIP file handling for bootstrap classloader
+
+   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 <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <zlib.h>
+#include <sys/mman.h>
+
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+
+#include "mm/memory.h"
+
+#include "vm/global.h"
+#include "vm/suck.h"
+#include "vm/utf8.h"
+#include "vm/vm.hpp"
+#include "vm/zip.h"
+
+
+/* start size for classes hashtable *******************************************/
+
+#define HASHTABLE_CLASSES_SIZE    (1 << 10)
+
+
+/* info taken from:
+   http://www.pkware.com/business_and_developers/developer/popups/appnote.txt
+*/
+
+/* all signatures in the ZIP file have a length of 4 bytes ********************/
+
+#define SIGNATURE_LENGTH    4
+
+/* Central directory structure *************************************************
+
+   [file header 1]
+   .
+   .
+   . 
+   [file header n]
+   [digital signature] 
+   
+   File header:
+   
+     central file header signature   4 bytes  (0x02014b50)
+     version made by                 2 bytes
+     version needed to extract       2 bytes
+     general purpose bit flag        2 bytes
+     compression method              2 bytes
+     last mod file time              2 bytes
+     last mod file date              2 bytes
+     crc-32                          4 bytes
+     compressed size                 4 bytes
+     uncompressed size               4 bytes
+     file name length                2 bytes
+     extra field length              2 bytes
+     file comment length             2 bytes
+     disk number start               2 bytes
+     internal file attributes        2 bytes
+     external file attributes        4 bytes
+     relative offset of local header 4 bytes
+   
+     file name (variable size)
+     extra field (variable size)
+     file comment (variable size)
+
+   Digital signature:
+   
+     header signature                4 bytes  (0x05054b50)
+     size of data                    2 bytes
+     signature data (variable size)
+
+*******************************************************************************/
+
+#define CDSFH_HEADER_SIZE            46
+
+#define CDSFH_SIGNATURE              0x02014b50
+#define CDSFH_COMPRESSION_METHOD     10
+#define CDSFH_COMPRESSED_SIZE        20
+#define CDSFH_UNCOMPRESSED_SIZE      24
+#define CDSFH_FILE_NAME_LENGTH       28
+#define CDSFH_EXTRA_FIELD_LENGTH     30
+#define CDSFH_FILE_COMMENT_LENGTH    32
+#define CDSFH_RELATIVE_OFFSET        42
+#define CDSFH_FILENAME               46
+
+typedef struct cdsfh cdsfh;
+
+struct cdsfh {
+       u2 compressionmethod;
+       u4 compressedsize;
+       u4 uncompressedsize;
+       u2 filenamelength;
+       u2 extrafieldlength;
+       u2 filecommentlength;
+       u4 relativeoffset;
+};
+
+
+/* End of central directory record *********************************************
+
+   end of central dir signature    4 bytes  (0x06054b50)
+   number of this disk             2 bytes
+   number of the disk with the
+   start of the central directory  2 bytes
+   total number of entries in the
+   central directory on this disk  2 bytes
+   total number of entries in
+   the central directory           2 bytes
+   size of the central directory   4 bytes
+   offset of start of central
+   directory with respect to
+   the starting disk number        4 bytes
+   .ZIP file comment length        2 bytes
+   .ZIP file comment       (variable size)
+
+*******************************************************************************/
+
+#define EOCDR_SIGNATURE              0x06054b50
+#define EOCDR_ENTRIES                10
+#define EOCDR_OFFSET                 16
+
+typedef struct eocdr eocdr;
+
+struct eocdr {
+       u2 entries;
+       u4 offset;
+};
+
+
+/* zip_open ********************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+hashtable *zip_open(char *path)
+{
+       hashtable               *ht;
+       hashtable_zipfile_entry *htzfe;
+       int                      fd;
+       u1                       lfh_signature[SIGNATURE_LENGTH];
+       off_t                    len;
+       u1                      *filep;
+       s4                       i;
+       u1                      *p;
+       eocdr                    eocdr;
+       cdsfh                    cdsfh;
+       const char              *filename;
+       const char              *classext;
+       utf                     *u;
+       u4                       key;       /* hashkey computed from utf-text     */
+       u4                       slot;      /* slot in hashtable                  */
+
+       /* first of all, open the file */
+
+       if ((fd = open(path, O_RDONLY)) == -1)
+               return NULL;
+
+       /* check for signature in first local file header */
+
+       if (read(fd, lfh_signature, SIGNATURE_LENGTH) != SIGNATURE_LENGTH)
+               return NULL;
+
+       if (SUCK_LE_U4(lfh_signature) != LFH_SIGNATURE)
+               return NULL;
+
+       /* get the file length */
+
+       if ((len = lseek(fd, 0, SEEK_END)) == -1)
+               return NULL;
+
+       /* we better mmap the file */
+
+       filep = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
+
+       /* some older compilers, like DEC OSF cc, don't like comparisons
+       on void* types */
+
+       if ((ptrint) filep == (ptrint) MAP_FAILED)
+               return NULL;
+
+       /* find end of central directory record */
+
+       for (p = filep + len; p >= filep; p--)
+               if (SUCK_LE_U4(p) == EOCDR_SIGNATURE)
+                       break;
+
+       /* get number of entries in central directory */
+
+       eocdr.entries = SUCK_LE_U2(p + EOCDR_ENTRIES);
+       eocdr.offset  = SUCK_LE_U4(p + EOCDR_OFFSET);
+
+       /* create hashtable for filenames */
+
+       ht = NEW(hashtable);
+
+       hashtable_create(ht, HASHTABLE_CLASSES_SIZE);
+
+       /* add all file entries into the hashtable */
+
+       for (i = 0, p = filep + eocdr.offset; i < eocdr.entries; i++) {
+               /* check file header signature */
+
+               if (SUCK_LE_U4(p) != CDSFH_SIGNATURE)
+                       return NULL;
+
+               /* we found an entry */
+
+               cdsfh.compressionmethod = SUCK_LE_U2(p + CDSFH_COMPRESSION_METHOD);
+               cdsfh.compressedsize    = SUCK_LE_U4(p + CDSFH_COMPRESSED_SIZE);
+               cdsfh.uncompressedsize  = SUCK_LE_U4(p + CDSFH_UNCOMPRESSED_SIZE);
+               cdsfh.filenamelength    = SUCK_LE_U2(p + CDSFH_FILE_NAME_LENGTH);
+               cdsfh.extrafieldlength  = SUCK_LE_U2(p + CDSFH_EXTRA_FIELD_LENGTH);
+               cdsfh.filecommentlength = SUCK_LE_U2(p + CDSFH_FILE_COMMENT_LENGTH);
+               cdsfh.relativeoffset    = SUCK_LE_U4(p + CDSFH_RELATIVE_OFFSET);
+
+               /* create utf8 string of filename, strip .class from classes */
+
+               filename = (const char *) (p + CDSFH_FILENAME);
+               classext = filename + cdsfh.filenamelength - strlen(".class");
+
+               /* skip directory entries */
+
+               if (filename[cdsfh.filenamelength - 1] != '/') {
+                       if (strncmp(classext, ".class", strlen(".class")) == 0)
+                               u = utf_new(filename, cdsfh.filenamelength - strlen(".class"));
+                       else
+                               u = utf_new(filename, cdsfh.filenamelength);
+
+                       /* insert class into hashtable */
+
+                       htzfe = NEW(hashtable_zipfile_entry);
+
+                       htzfe->filename          = u;
+                       htzfe->compressionmethod = cdsfh.compressionmethod;
+                       htzfe->compressedsize    = cdsfh.compressedsize;
+                       htzfe->uncompressedsize  = cdsfh.uncompressedsize;
+                       htzfe->data              = filep + cdsfh.relativeoffset;
+
+                       /* get hashtable slot */
+
+                       key  = utf_hashkey(u->text, u->blength);
+                       slot = key & (ht->size - 1);
+
+                       /* insert into external chain */
+
+                       htzfe->hashlink = ht->ptr[slot];
+
+                       /* insert hashtable zipfile entry */
+
+                       ht->ptr[slot] = htzfe;
+                       ht->entries++;
+               }
+
+               /* move to next central directory structure file header */
+
+               p = p +
+                       CDSFH_HEADER_SIZE +
+                       cdsfh.filenamelength +
+                       cdsfh.extrafieldlength +
+                       cdsfh.filecommentlength;
+       }
+
+       /* return pointer to hashtable */
+
+       return ht;
+}
+
+
+/* zip_find ********************************************************************
+
+   Search for the given filename in the classpath entries of a zip file.
+
+   NOTE: The '.class' extension is stripped when reading a zip file, so if
+   you want to find a .class file, you must search for its name _without_
+   the '.class' extension. 
+   XXX I dont like that, it makes foo and foo.class ambiguous. -Edwin
+
+   IN:
+      lce..........the classpath entries for the zip file
+         u............the filename to look for
+
+   RETURN VALUE:
+      hashtable_zipfile_entry * of the entry if found, or
+         NULL if not found
+
+*******************************************************************************/
+
+hashtable_zipfile_entry *zip_find(list_classpath_entry *lce, utf *u)
+{
+       hashtable               *ht;
+       u4                       key;       /* hashkey computed from utf-text     */
+       u4                       slot;      /* slot in hashtable                  */
+       hashtable_zipfile_entry *htzfe;     /* hashtable element                  */
+
+       /* get classes hashtable from the classpath entry */
+
+       ht = lce->htclasses;
+
+       /* get the hashtable slot of the name searched */
+
+       key   = utf_hashkey(u->text, u->blength);
+       slot  = key & (ht->size - 1);
+       htzfe = ht->ptr[slot];
+
+       /* search external hash chain for utf-symbol */
+
+       while (htzfe) {
+               if (htzfe->filename == u)
+                       return htzfe;
+
+               /* next element in external chain */
+
+               htzfe = htzfe->hashlink;
+       }
+
+       /* file not found in this archive */
+
+       return NULL;
+}
+
+
+/* zip_get ********************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+classbuffer *zip_get(list_classpath_entry *lce, classinfo *c)
+{
+       hashtable_zipfile_entry *htzfe;
+       lfh                      lfh;
+       u1                      *indata;
+       u1                      *outdata;
+       z_stream                 zs;
+       int                      err;
+       classbuffer             *cb;
+
+       /* try to find the class in the current archive */
+
+       htzfe = zip_find(lce, c->name);
+
+       if (htzfe == NULL)
+               return NULL;
+
+       /* read stuff from local file header */
+
+       lfh.filenamelength   = SUCK_LE_U2(htzfe->data + LFH_FILE_NAME_LENGTH);
+       lfh.extrafieldlength = SUCK_LE_U2(htzfe->data + LFH_EXTRA_FIELD_LENGTH);
+
+       indata = htzfe->data +
+               LFH_HEADER_SIZE +
+               lfh.filenamelength +
+               lfh.extrafieldlength;
+
+       /* allocate buffer for uncompressed data */
+
+       outdata = MNEW(u1, htzfe->uncompressedsize);
+
+       /* how is the file stored? */
+
+       switch (htzfe->compressionmethod) {
+       case Z_DEFLATED:
+               /* fill z_stream structure */
+
+               zs.next_in   = indata;
+               zs.avail_in  = htzfe->compressedsize;
+               zs.next_out  = outdata;
+               zs.avail_out = htzfe->uncompressedsize;
+
+               zs.zalloc = Z_NULL;
+               zs.zfree  = Z_NULL;
+               zs.opaque = Z_NULL;
+
+               /* initialize this inflate run */
+
+               if (inflateInit2(&zs, -MAX_WBITS) != Z_OK)
+                       vm_abort("zip_get: inflateInit2 failed: %s", strerror(errno));
+
+               /* decompress the file into buffer */
+
+               err = inflate(&zs, Z_SYNC_FLUSH);
+
+               if ((err != Z_STREAM_END) && (err != Z_OK))
+                       vm_abort("zip_get: inflate failed: %s", strerror(errno));
+
+               /* finish this inflate run */
+
+               if (inflateEnd(&zs) != Z_OK)
+                       vm_abort("zip_get: inflateEnd failed: %s", strerror(errno));
+               break;
+
+       case 0:
+               /* uncompressed file, just copy the data */
+               MCOPY(outdata, indata, u1, htzfe->compressedsize);
+               break;
+
+       default:
+               vm_abort("zip_get: unknown compression method %d",
+                                htzfe->compressionmethod);
+       }
+       
+       /* allocate classbuffer */
+
+       cb = NEW(classbuffer);
+
+       cb->clazz = c;
+       cb->size  = htzfe->uncompressedsize;
+       cb->data  = outdata;
+       cb->pos   = outdata;
+       cb->path  = lce->path;
+
+       /* return the filled classbuffer structure */
+
+       return 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/zip.h b/src/vm/zip.h
new file mode 100644 (file)
index 0000000..0e22cc5
--- /dev/null
@@ -0,0 +1,118 @@
+/* src/vm/zip.c - ZIP file handling for bootstrap classloader
+
+   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 _ZIP_H
+#define _ZIP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/suck.h"
+#include "vm/utf8.h"
+
+
+/* Local file header ***********************************************************
+
+   local file header signature     4 bytes  (0x04034b50)
+   version needed to extract       2 bytes
+   general purpose bit flag        2 bytes
+   compression method              2 bytes
+   last mod file time              2 bytes
+   last mod file date              2 bytes
+   crc-32                          4 bytes
+   compressed size                 4 bytes
+   uncompressed size               4 bytes
+   file name length                2 bytes
+   extra field length              2 bytes
+
+   file name (variable size)
+   extra field (variable size)
+
+*******************************************************************************/
+
+#define LFH_HEADER_SIZE              30
+
+#define LFH_SIGNATURE                0x04034b50
+#define LFH_FILE_NAME_LENGTH         26
+#define LFH_EXTRA_FIELD_LENGTH       28
+
+typedef struct lfh lfh;
+
+struct lfh {
+       u2 compressionmethod;
+       u4 compressedsize;
+       u4 uncompressedsize;
+       u2 filenamelength;
+       u2 extrafieldlength;
+};
+
+/* hashtable_zipfile_entry ****************************************************/
+
+typedef struct hashtable_zipfile_entry hashtable_zipfile_entry;
+
+struct hashtable_zipfile_entry {
+       utf                     *filename;
+       u2                       compressionmethod;
+       u4                       compressedsize;
+       u4                       uncompressedsize;
+       u1                      *data;
+       hashtable_zipfile_entry *hashlink;
+};
+
+
+/* function prototypes ********************************************************/
+
+hashtable *zip_open(char *path);
+hashtable_zipfile_entry *zip_find(list_classpath_entry *lce, utf *u);
+classbuffer *zip_get(list_classpath_entry *lce, classinfo *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZIP_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/vmcore/Makefile.am b/src/vmcore/Makefile.am
deleted file mode 100644 (file)
index 1b288f4..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-## src/vmcore/Makefile.am
-##
-## Copyright (C) 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
-##
-## 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.
-
-
-AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR)
-
-LIBS =
-
-if ENABLE_JAVASE
-if ENABLE_ANNOTATIONS
-ANNOTATION_SOURCES = \
-       annotation.c \
-       annotation.h
-endif
-
-STACKMAP_SOURCES = \
-       stackmap.c \
-       stackmap.h
-endif
-
-if ENABLE_RT_TIMING
-RT_TIMING_SOURCES = \
-       rt-timing.c \
-       rt-timing.h
-endif
-
-if ENABLE_STATISTICS
-STATISTICS_SOURCES = \
-       statistics.c \
-       statistics.h
-endif
-
-if ENABLE_ZLIB
-ZLIB_SOURCES = \
-       zip.c \
-       zip.h
-endif
-
-noinst_LTLIBRARIES = \
-       libvmcore.la
-
-libvmcore_la_SOURCES = \
-       $(ANNOTATION_SOURCES) \
-       class.c \
-       class.h \
-       classcache.c \
-       classcache.h \
-       descriptor.c \
-       descriptor.h \
-       field.c \
-       field.h \
-       linker.c \
-       linker.h \
-       loader.c \
-       loader.h \
-       method.c \
-       method.h \
-       options.c \
-       options.h \
-       primitivecore.c \
-       references.h \
-       $(RT_TIMING_SOURCES) \
-       $(STACKMAP_SOURCES) \
-       $(STATISTICS_SOURCES) \
-       suck.c \
-       suck.h \
-       system.c \
-       system.h \
-       utf8.c \
-       utf8.h \
-       $(ZLIB_SOURCES)
-
-
-## Local variables:
-## mode: Makefile
-## indent-tabs-mode: t
-## c-basic-offset: 4
-## tab-width: 8
-## compile-command: "automake --add-missing"
-## End:
diff --git a/src/vmcore/annotation.c b/src/vmcore/annotation.c
deleted file mode 100644 (file)
index 4d7021d..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-/* src/vmcore/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 "vm/types.h"
-#include "vm/array.h"
-#include "vm/builtin.h"
-#include "vm/primitive.h"
-
-#include "mm/memory.h"
-
-#include "toolbox/logging.h"
-
-#include "vmcore/annotation.h"
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/suck.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_arrayclass_get_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 vmcore/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/vmcore/annotation.h b/src/vmcore/annotation.h
deleted file mode 100644 (file)
index 7ec071d..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* src/vmcore/annotation.h - class annotations
-
-   Copyright (C) 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
-
-   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/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-
-
-/* function prototypes ********************************************************/
-
-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);
-
-#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/vmcore/class.c b/src/vmcore/class.c
deleted file mode 100644 (file)
index 51470ab..0000000
+++ /dev/null
@@ -1,2606 +0,0 @@
-/* src/vmcore/class.c - class related 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "arch.h"
-
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "threads/lock-common.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/array.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/resolve.h"
-
-#include "vm/jit/asmpart.h"
-#include "vm/jit/jitcache.h"
-
-#include "vmcore/class.h"
-#include "vmcore/classcache.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#include "vmcore/suck.h"
-#include "vmcore/utf8.h"
-
-
-#if defined(ENABLE_JAVASE)
-/* We need to define some reflection functions here since we cannot
-   include native/vm/reflect.h as it includes generated header
-   files. */
-
-java_object_t *reflect_constructor_new(methodinfo *m);
-java_object_t *reflect_field_new(fieldinfo *f);
-java_object_t *reflect_method_new(methodinfo *m);
-#endif
-
-
-/* global variables ***********************************************************/
-
-/* frequently used classes ****************************************************/
-
-/* Important system classes. */
-
-classinfo *class_java_lang_Object;
-classinfo *class_java_lang_Class;
-classinfo *class_java_lang_ClassLoader;
-classinfo *class_java_lang_Cloneable;
-classinfo *class_java_lang_SecurityManager;
-classinfo *class_java_lang_String;
-classinfo *class_java_lang_System;
-classinfo *class_java_lang_Thread;
-classinfo *class_java_lang_ThreadGroup;
-classinfo *class_java_lang_Throwable;
-classinfo *class_java_io_Serializable;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-classinfo *class_java_lang_VMSystem;
-classinfo *class_java_lang_VMThread;
-classinfo *class_java_lang_VMThrowable;
-#endif
-
-/* Important system exceptions. */
-
-classinfo *class_java_lang_Exception;
-classinfo *class_java_lang_ClassNotFoundException;
-classinfo *class_java_lang_RuntimeException;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-classinfo *class_sun_reflect_MagicAccessorImpl;
-#endif
-
-#if defined(ENABLE_JAVASE)
-classinfo *class_java_lang_Void;
-#endif
-classinfo *class_java_lang_Boolean;
-classinfo *class_java_lang_Byte;
-classinfo *class_java_lang_Character;
-classinfo *class_java_lang_Short;
-classinfo *class_java_lang_Integer;
-classinfo *class_java_lang_Long;
-classinfo *class_java_lang_Float;
-classinfo *class_java_lang_Double;
-
-/* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-classinfo *class_java_lang_StackTraceElement;
-classinfo *class_java_lang_reflect_Constructor;
-classinfo *class_java_lang_reflect_Field;
-classinfo *class_java_lang_reflect_Method;
-classinfo *class_java_security_PrivilegedAction;
-classinfo *class_java_util_Vector;
-classinfo *class_java_util_HashMap;
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-classinfo *class_java_lang_reflect_VMConstructor;
-classinfo *class_java_lang_reflect_VMField;
-classinfo *class_java_lang_reflect_VMMethod;
-# endif
-
-classinfo *arrayclass_java_lang_Object;
-
-# if defined(ENABLE_ANNOTATIONS)
-classinfo *class_sun_reflect_ConstantPool;
-#  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-classinfo *class_sun_reflect_annotation_AnnotationParser;
-#  endif
-# endif
-#endif
-
-/* pseudo classes for the typechecker */
-
-classinfo *pseudo_class_Arraystub;
-classinfo *pseudo_class_Null;
-classinfo *pseudo_class_New;
-
-
-/* class_set_packagename *******************************************************
-
-   Derive the package name from the class name and store it in the
-   struct.
-
-   An internal package name consists of the package name plus the
-   trailing '/', e.g. "java/lang/".
-
-   For classes in the unnamed package, the package name is set to
-   NULL.
-
-*******************************************************************************/
-
-void class_set_packagename(classinfo *c)
-{
-       char *p;
-       char *start;
-
-       p     = UTF_END(c->name) - 1;
-       start = c->name->text;
-
-       if (c->name->text[0] == '[') {
-               /* Set packagename of arrays to the element's package. */
-
-               for (; *start == '['; start++);
-
-               /* Skip the 'L' in arrays of references. */
-
-               if (*start == 'L')
-                       start++;
-       }
-
-       /* Search for last '/'. */
-
-       for (; (p > start) && (*p != '/'); --p);
-
-       /* If we found a '/' we set the package name plus the trailing
-          '/'.  Otherwise we set the packagename to NULL. */
-
-       if (p > start)
-               c->packagename = utf_new(start, p - start + 1);
-       else
-               c->packagename = NULL;
-}
-
-
-/* class_create_classinfo ******************************************************
-
-   Create a new classinfo struct. The class name is set to the given utf *,
-   most other fields are initialized to zero.
-
-   Note: classname may be NULL. In this case a not-yet-named classinfo is
-         created. The name must be filled in later and class_set_packagename
-                must be called after that.
-
-*******************************************************************************/
-
-classinfo *class_create_classinfo(utf *classname)
-{
-       classinfo *c;
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_classinfo += sizeof(classinfo);
-#endif
-
-       /* we use a safe name for temporarily unnamed classes */
-
-       if (classname == NULL)
-               classname = utf_not_named_yet;
-
-#if !defined(NDEBUG)
-       if (initverbose)
-               log_message_utf("Creating class: ", classname);
-#endif
-
-#if !defined(ENABLE_GC_BOEHM)
-       c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
-       /*c = NEW(classinfo);
-       MZERO(c, classinfo, 1);*/
-#else
-       c = GCNEW_UNCOLLECTABLE(classinfo, 1);
-       /* GCNEW_UNCOLLECTABLE clears the allocated memory */
-#endif
-
-       c->name = classname;
-
-       /* Set the header.vftbl of all loaded classes to the one of
-       java.lang.Class, so Java code can use a class as object. */
-
-       if (class_java_lang_Class != NULL)
-               if (class_java_lang_Class->vftbl != NULL)
-                       c->object.header.vftbl = class_java_lang_Class->vftbl;
-
-#if defined(ENABLE_JAVASE)
-       /* check if the class is a reference class and flag it */
-
-       if (classname == utf_java_lang_ref_SoftReference) {
-               c->flags |= ACC_CLASS_REFERENCE_SOFT;
-       }
-       else if (classname == utf_java_lang_ref_WeakReference) {
-               c->flags |= ACC_CLASS_REFERENCE_WEAK;
-       }
-       else if (classname == utf_java_lang_ref_PhantomReference) {
-               c->flags |= ACC_CLASS_REFERENCE_PHANTOM;
-       }
-#endif
-
-       if (classname != utf_not_named_yet)
-               class_set_packagename(c);
-#if defined (ENABLE_JITCACHE)
-    c->cache_file_fd = 0;
-#endif
-
-       LOCK_INIT_OBJECT_LOCK(&c->object.header);
-
-       return c;
-}
-
-
-/* class_postset_header_vftbl **************************************************
-
-   Set the header.vftbl of all classes created before java.lang.Class
-   was linked.  This is necessary that Java code can use a class as
-   object.
-
-*******************************************************************************/
-
-void class_postset_header_vftbl(void)
-{
-       classinfo *c;
-       u4 slot;
-       classcache_name_entry *nmen;
-       classcache_class_entry *clsen;
-
-       assert(class_java_lang_Class);
-
-       for (slot = 0; slot < hashtable_classcache.size; slot++) {
-               nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-
-               for (; nmen; nmen = nmen->hashlink) {
-                       /* iterate over all class entries */
-
-                       for (clsen = nmen->classes; clsen; clsen = clsen->next) {
-                               c = clsen->classobj;
-
-                               /* now set the the vftbl */
-
-                               if (c->object.header.vftbl == NULL)
-                                       c->object.header.vftbl = class_java_lang_Class->vftbl;
-                       }
-               }
-       }
-}
-
-/* class_define ****************************************************************
-
-   Calls the loader and defines a class in the VM.
-
-*******************************************************************************/
-
-classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
-{
-       classinfo   *c;
-       classinfo   *r;
-       classbuffer *cb;
-
-       if (name != NULL) {
-               /* check if this class has already been defined */
-
-               c = classcache_lookup_defined_or_initiated(cl, name);
-
-               if (c != NULL) {
-                       exceptions_throw_linkageerror("duplicate class definition: ", c);
-                       return NULL;
-               }
-       } 
-
-       /* create a new classinfo struct */
-
-       c = class_create_classinfo(name);
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_start();
-#endif
-
-       /* build a classbuffer with the given data */
-
-       cb = NEW(classbuffer);
-
-       cb->clazz = c;
-       cb->size  = length;
-       cb->data  = data;
-       cb->pos   = cb->data;
-
-       /* preset the defining classloader */
-
-       c->classloader = cl;
-
-       /* load the class from this buffer */
-
-       r = load_class_from_classbuffer(cb);
-
-       /* free memory */
-
-       FREE(cb, classbuffer);
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_stop();
-#endif
-
-       if (r == NULL) {
-               /* If return value is NULL, we had a problem and the class is
-                  not loaded.  Now free the allocated memory, otherwise we
-                  could run into a DOS. */
-
-               class_free(c);
-
-               return NULL;
-       }
-
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       /* Store the protection domain. */
-
-       c->protectiondomain = pd;
-# endif
-#endif
-
-       /* Store the newly defined class in the class cache. This call
-          also checks whether a class of the same name has already been
-          defined by the same defining loader, and if so, replaces the
-          newly created class by the one defined earlier. */
-
-       /* Important: The classinfo given to classcache_store must be
-                     fully prepared because another thread may return
-                     this pointer after the lookup at to top of this
-                     function directly after the class cache lock has
-                     been released. */
-
-       c = classcache_store(cl, c, true);
-
-       return c;
-}
-
-
-/* class_load_attribute_sourcefile *********************************************
-
-   SourceFile_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-          u2 sourcefile_index;
-   }
-
-*******************************************************************************/
-
-static bool class_load_attribute_sourcefile(classbuffer *cb)
-{
-       classinfo *c;
-       u4         attribute_length;
-       u2         sourcefile_index;
-       utf       *sourcefile;
-
-       /* get classinfo */
-
-       c = cb->clazz;
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2))
-               return false;
-
-       /* check attribute length */
-
-       attribute_length = suck_u4(cb);
-
-       if (attribute_length != 2) {
-               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-               return false;
-       }
-
-       /* there can be no more than one SourceFile attribute */
-
-       if (c->sourcefile != NULL) {
-               exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
-               return false;
-       }
-
-       /* get sourcefile */
-
-       sourcefile_index = suck_u2(cb);
-       sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
-
-       if (sourcefile == NULL)
-               return false;
-
-       /* store sourcefile */
-
-       c->sourcefile = sourcefile;
-
-       return true;
-}
-
-
-/* class_load_attribute_enclosingmethod ****************************************
-
-   EnclosingMethod_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-          u2 class_index;
-          u2 method_index;
-   }
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-static bool class_load_attribute_enclosingmethod(classbuffer *cb)
-{
-       classinfo             *c;
-       u4                     attribute_length;
-       u2                     class_index;
-       u2                     method_index;
-       classref_or_classinfo  cr;
-       constant_nameandtype  *cn;
-
-       /* get classinfo */
-
-       c = cb->clazz;
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
-               return false;
-
-       /* check attribute length */
-
-       attribute_length = suck_u4(cb);
-
-       if (attribute_length != 4) {
-               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-               return false;
-       }
-
-       /* there can be no more than one EnclosingMethod attribute */
-
-       if (c->enclosingmethod != NULL) {
-               exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
-               return false;
-       }
-
-       /* get class index */
-
-       class_index = suck_u2(cb);
-       cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
-
-       /* get method index */
-
-       method_index = suck_u2(cb);
-       cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
-
-       /* store info in classinfo */
-
-       c->enclosingclass.any = cr.any;
-       c->enclosingmethod    = cn;
-
-       return true;
-}
-#endif /* defined(ENABLE_JAVASE) */
-
-
-/* class_load_attributes *******************************************************
-
-   Read attributes from ClassFile.
-
-   attribute_info {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       u1 info[attribute_length];
-   }
-
-   InnerClasses_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-   }
-
-*******************************************************************************/
-
-bool class_load_attributes(classbuffer *cb)
-{
-       classinfo             *c;
-       uint16_t               attributes_count;
-       uint16_t               attribute_name_index;
-       utf                   *attribute_name;
-       innerclassinfo        *info;
-       classref_or_classinfo  inner;
-       classref_or_classinfo  outer;
-       utf                   *name;
-       uint16_t               flags;
-       int                    i, j;
-
-       c = cb->clazz;
-
-       /* get attributes count */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       attributes_count = suck_u2(cb);
-
-       for (i = 0; i < attributes_count; i++) {
-               /* get attribute name */
-
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               attribute_name_index = suck_u2(cb);
-               attribute_name =
-                       class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
-
-               if (attribute_name == NULL)
-                       return false;
-
-               if (attribute_name == utf_InnerClasses) {
-                       /* InnerClasses */
-
-                       if (c->innerclass != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
-                               return false;
-                       }
-                               
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* skip attribute length */
-                       suck_u4(cb);
-
-                       /* number of records */
-                       c->innerclasscount = suck_u2(cb);
-
-                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
-                               return false;
-
-                       /* allocate memory for innerclass structure */
-                       c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
-
-                       for (j = 0; j < c->innerclasscount; j++) {
-                               /* The innerclass structure contains a class with an encoded
-                                  name, its defining scope, its simple name and a bitmask of
-                                  the access flags. */
-                                                               
-                               info = c->innerclass + j;
-
-                               inner.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
-                               outer.ref = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
-                               name      = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
-                               flags     = suck_u2(cb);
-
-                               /* If the current inner-class is the currently loaded
-                                  class check for some special flags. */
-
-                               if (inner.ref->name == c->name) {
-                                       /* If an inner-class is not a member, its
-                                          outer-class is NULL. */
-
-                                       if (outer.ref != NULL) {
-                                               c->flags |= ACC_CLASS_MEMBER;
-
-                                               /* A member class doesn't have an
-                                                  EnclosingMethod attribute, so set the
-                                                  enclosing-class to be the same as the
-                                                  declaring-class. */
-
-                                               c->declaringclass = outer;
-                                               c->enclosingclass = outer;
-                                       }
-
-                                       /* If an inner-class is anonymous, its name is
-                                          NULL. */
-
-                                       if (name == NULL)
-                                               c->flags |= ACC_CLASS_ANONYMOUS;
-                               }
-
-                               info->inner_class = inner;
-                               info->outer_class = outer;
-                               info->name        = name;
-                               info->flags       = flags;
-                       }
-               }
-               else if (attribute_name == utf_SourceFile) {
-                       /* SourceFile */
-
-                       if (!class_load_attribute_sourcefile(cb))
-                               return false;
-               }
-#if defined(ENABLE_JAVASE)
-               else if (attribute_name == utf_EnclosingMethod) {
-                       /* EnclosingMethod */
-
-                       if (!class_load_attribute_enclosingmethod(cb))
-                               return false;
-               }
-               else if (attribute_name == utf_Signature) {
-                       /* Signature */
-
-                       if (!loader_load_attribute_signature(cb, &(c->signature)))
-                               return false;
-               }
-#endif
-
-#if defined(ENABLE_ANNOTATIONS)
-               else if (attribute_name == utf_RuntimeVisibleAnnotations) {
-                       /* RuntimeVisibleAnnotations */
-                       if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
-                               return false;
-               }
-               else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
-                       /* RuntimeInvisibleAnnotations */
-                       if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
-                               return false;
-               }
-#endif
-
-               else {
-                       /* unknown attribute */
-
-                       if (!loader_skip_attribute_body(cb))
-                               return false;
-               }
-       }
-
-       return true;
-}
-
-
-/* class_freepool **************************************************************
-
-       Frees all resources used by this classes Constant Pool.
-
-*******************************************************************************/
-
-static void class_freecpool(classinfo *c)
-{
-       u4 idx;
-       u4 tag;
-       voidptr info;
-       
-       if (c->cptags && c->cpinfos) {
-               for (idx = 0; idx < c->cpcount; idx++) {
-                       tag = c->cptags[idx];
-                       info = c->cpinfos[idx];
-               
-                       if (info != NULL) {
-                               switch (tag) {
-                               case CONSTANT_Fieldref:
-                               case CONSTANT_Methodref:
-                               case CONSTANT_InterfaceMethodref:
-                                       FREE(info, constant_FMIref);
-                                       break;
-                               case CONSTANT_Integer:
-                                       FREE(info, constant_integer);
-                                       break;
-                               case CONSTANT_Float:
-                                       FREE(info, constant_float);
-                                       break;
-                               case CONSTANT_Long:
-                                       FREE(info, constant_long);
-                                       break;
-                               case CONSTANT_Double:
-                                       FREE(info, constant_double);
-                                       break;
-                               case CONSTANT_NameAndType:
-                                       FREE(info, constant_nameandtype);
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       if (c->cptags)
-               MFREE(c->cptags, u1, c->cpcount);
-
-       if (c->cpinfos)
-               MFREE(c->cpinfos, voidptr, c->cpcount);
-}
-
-
-/* class_getconstant ***********************************************************
-
-   Retrieves the value at position 'pos' of the constantpool of a
-   class. If the type of the value is other than 'ctype', an error is
-   thrown.
-
-*******************************************************************************/
-
-voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
-{
-       /* check index and type of constantpool entry */
-       /* (pos == 0 is caught by type comparison) */
-
-       if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
-               exceptions_throw_classformaterror(c, "Illegal constant pool index");
-               return NULL;
-       }
-
-       return c->cpinfos[pos];
-}
-
-
-/* innerclass_getconstant ******************************************************
-
-   Like class_getconstant, but if cptags is ZERO, null is returned.
-       
-*******************************************************************************/
-
-voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
-{
-       /* invalid position in constantpool */
-
-       if (pos >= c->cpcount) {
-               exceptions_throw_classformaterror(c, "Illegal constant pool index");
-               return NULL;
-       }
-
-       /* constantpool entry of type 0 */      
-
-       if (c->cptags[pos] == 0)
-               return NULL;
-
-       /* check type of constantpool entry */
-
-       if (c->cptags[pos] != ctype) {
-               exceptions_throw_classformaterror(c, "Illegal constant pool index");
-               return NULL;
-       }
-               
-       return c->cpinfos[pos];
-}
-
-
-/* class_free ******************************************************************
-
-   Frees all resources used by the class.
-
-*******************************************************************************/
-
-void class_free(classinfo *c)
-{
-       s4 i;
-       vftbl_t *v;
-
-#if defined(ENABLE_JITCACHE)
-/* TODO: Find a way around the linker problem */
-/*    jitcache_freeclass(c);*/
-#endif
-
-       class_freecpool(c);
-
-       if (c->interfaces != NULL)
-               MFREE(c->interfaces, classinfo*, c->interfacescount);
-
-       if (c->fields) {
-               for (i = 0; i < c->fieldscount; i++)
-                       field_free(&(c->fields[i]));
-               MFREE(c->fields, fieldinfo, c->fieldscount);
-       }
-       
-       if (c->methods) {
-               for (i = 0; i < c->methodscount; i++)
-                       method_free(&(c->methods[i]));
-               MFREE(c->methods, methodinfo, c->methodscount);
-       }
-
-       if ((v = c->vftbl) != NULL) {
-               if (v->arraydesc)
-                       mem_free(v->arraydesc,sizeof(arraydescriptor));
-               
-               for (i = 0; i < v->interfacetablelength; i++) {
-                       MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
-               }
-               MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
-
-               i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
-                   sizeof(methodptr*) * (v->interfacetablelength -
-                                        (v->interfacetablelength > 0));
-               v = (vftbl_t*) (((methodptr*) v) -
-                                               (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
-               mem_free(v, i);
-       }
-
-       if (c->innerclass)
-               MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
-
-       /*      if (c->classvftbl)
-               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
-       
-/*     GCFREE(c); */
-}
-
-
-/* get_array_class *************************************************************
-
-   Returns the array class with the given name for the given
-   classloader, or NULL if an exception occurred.
-
-   Note: This function does eager loading. 
-
-*******************************************************************************/
-
-static classinfo *get_array_class(utf *name,classloader_t *initloader,
-                                                                                       classloader_t *defloader,bool link)
-{
-       classinfo *c;
-       
-       /* lookup this class in the classcache */
-       c = classcache_lookup(initloader,name);
-       if (!c)
-               c = classcache_lookup_defined(defloader,name);
-
-       if (!c) {
-               /* we have to create it */
-               c = class_create_classinfo(name);
-               c = load_newly_created_array(c,initloader);
-               if (c == NULL)
-                       return NULL;
-       }
-
-       assert(c);
-       assert(c->state & CLASS_LOADED);
-       assert(c->classloader == defloader);
-
-       if (link && !(c->state & CLASS_LINKED))
-               if (!link_class(c))
-                       return NULL;
-
-       assert(!link || (c->state & CLASS_LINKED));
-
-       return c;
-}
-
-
-/* class_array_of **************************************************************
-
-   Returns an array class with the given component class. The array
-   class is dynamically created if neccessary.
-
-*******************************************************************************/
-
-classinfo *class_array_of(classinfo *component, bool link)
-{
-       classloader_t     *cl;
-    s4                 namelen;
-    char              *namebuf;
-       utf               *u;
-       classinfo         *c;
-       int32_t            dumpmarker;
-
-       cl = component->classloader;
-
-       DMARKER;
-
-    /* Assemble the array class name */
-    namelen = component->name->blength;
-    
-    if (component->name->text[0] == '[') {
-        /* the component is itself an array */
-        namebuf = DMNEW(char, namelen + 1);
-        namebuf[0] = '[';
-        MCOPY(namebuf + 1, component->name->text, char, namelen);
-        namelen++;
-    }
-       else {
-        /* the component is a non-array class */
-        namebuf = DMNEW(char, namelen + 3);
-        namebuf[0] = '[';
-        namebuf[1] = 'L';
-        MCOPY(namebuf + 2, component->name->text, char, namelen);
-        namebuf[2 + namelen] = ';';
-        namelen += 3;
-    }
-
-       u = utf_new(namebuf, namelen);
-
-       c = get_array_class(u, cl, cl, link);
-
-       DRELEASE;
-
-       return c;
-}
-
-
-/* class_multiarray_of *********************************************************
-
-   Returns an array class with the given dimension and element class.
-   The array class is dynamically created if neccessary.
-
-*******************************************************************************/
-
-classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
-{
-    s4 namelen;
-    char *namebuf;
-       classinfo *c;
-       int32_t    dumpmarker;
-
-       DMARKER;
-
-       if (dim < 1) {
-               log_text("Invalid array dimension requested");
-               assert(0);
-       }
-
-    /* Assemble the array class name */
-    namelen = element->name->blength;
-    
-    if (element->name->text[0] == '[') {
-        /* the element is itself an array */
-        namebuf = DMNEW(char, namelen + dim);
-        memcpy(namebuf + dim, element->name->text, namelen);
-        namelen += dim;
-    }
-    else {
-        /* the element is a non-array class */
-        namebuf = DMNEW(char, namelen + 2 + dim);
-        namebuf[dim] = 'L';
-        memcpy(namebuf + dim + 1, element->name->text, namelen);
-        namelen += (2 + dim);
-        namebuf[namelen - 1] = ';';
-    }
-       memset(namebuf, '[', dim);
-
-       c = get_array_class(utf_new(namebuf, namelen),
-                                               element->classloader,
-                                               element->classloader,
-                                               link);
-
-       DRELEASE;
-
-       return c;
-}
-
-
-/* class_lookup_classref *******************************************************
-
-   Looks up the constant_classref for a given classname in the classref
-   tables of a class.
-
-   IN:
-       cls..............the class containing the reference
-          name.............the name of the class refered to
-
-    RETURN VALUE:
-          a pointer to a constant_classref, or 
-          NULL if the reference was not found
-   
-*******************************************************************************/
-
-constant_classref *class_lookup_classref(classinfo *cls, utf *name)
-{
-       constant_classref *ref;
-       extra_classref *xref;
-       int count;
-
-       assert(cls);
-       assert(name);
-       assert(!cls->classrefcount || cls->classrefs);
-       
-       /* first search the main classref table */
-       count = cls->classrefcount;
-       ref = cls->classrefs;
-       for (; count; --count, ++ref)
-               if (ref->name == name)
-                       return ref;
-
-       /* next try the list of extra classrefs */
-       for (xref = cls->extclassrefs; xref; xref = xref->next) {
-               if (xref->classref.name == name)
-                       return &(xref->classref);
-       }
-
-       /* not found */
-       return NULL;
-}
-
-
-/* class_get_classref **********************************************************
-
-   Returns the constant_classref for a given classname.
-
-   IN:
-       cls..............the class containing the reference
-          name.............the name of the class refered to
-
-   RETURN VALUE:
-       a pointer to a constant_classref (never NULL)
-
-   NOTE:
-       The given name is not checked for validity!
-   
-*******************************************************************************/
-
-constant_classref *class_get_classref(classinfo *cls, utf *name)
-{
-       constant_classref *ref;
-       extra_classref *xref;
-
-       assert(cls);
-       assert(name);
-
-       ref = class_lookup_classref(cls,name);
-       if (ref)
-               return ref;
-
-       xref = NEW(extra_classref);
-       CLASSREF_INIT(xref->classref,cls,name);
-
-       xref->next = cls->extclassrefs;
-       cls->extclassrefs = xref;
-
-       return &(xref->classref);
-}
-
-
-/* class_get_self_classref *****************************************************
-
-   Returns the constant_classref to the class itself.
-
-   IN:
-       cls..............the class containing the reference
-
-   RETURN VALUE:
-       a pointer to a constant_classref (never NULL)
-
-*******************************************************************************/
-
-constant_classref *class_get_self_classref(classinfo *cls)
-{
-       /* XXX this should be done in a faster way. Maybe always make */
-       /* the classref of index 0 a self reference.                  */
-       return class_get_classref(cls,cls->name);
-}
-
-/* class_get_classref_multiarray_of ********************************************
-
-   Returns an array type reference with the given dimension and element class
-   reference.
-
-   IN:
-       dim..............the requested dimension
-                           dim must be in [1;255]. This is NOT checked!
-          ref..............the component class reference
-
-   RETURN VALUE:
-       a pointer to the class reference for the array type
-
-   NOTE:
-       The referer of `ref` is used as the referer for the new classref.
-
-*******************************************************************************/
-
-constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
-{
-    s4 namelen;
-    char *namebuf;
-       constant_classref *cr;
-       int32_t            dumpmarker;
-
-       assert(ref);
-       assert(dim >= 1 && dim <= 255);
-
-       DMARKER;
-
-    /* Assemble the array class name */
-    namelen = ref->name->blength;
-    
-    if (ref->name->text[0] == '[') {
-        /* the element is itself an array */
-        namebuf = DMNEW(char, namelen + dim);
-        memcpy(namebuf + dim, ref->name->text, namelen);
-        namelen += dim;
-    }
-    else {
-        /* the element is a non-array class */
-        namebuf = DMNEW(char, namelen + 2 + dim);
-        namebuf[dim] = 'L';
-        memcpy(namebuf + dim + 1, ref->name->text, namelen);
-        namelen += (2 + dim);
-        namebuf[namelen - 1] = ';';
-    }
-       memset(namebuf, '[', dim);
-
-    cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
-
-       DRELEASE;
-
-       return cr;
-}
-
-
-/* class_get_classref_component_of *********************************************
-
-   Returns the component classref of a given array type reference
-
-   IN:
-       ref..............the array type reference
-
-   RETURN VALUE:
-       a reference to the component class, or
-          NULL if `ref` is not an object array type reference
-
-   NOTE:
-       The referer of `ref` is used as the referer for the new classref.
-
-*******************************************************************************/
-
-constant_classref *class_get_classref_component_of(constant_classref *ref)
-{
-       s4 namelen;
-       char *name;
-       
-       assert(ref);
-
-       name = ref->name->text;
-       if (*name++ != '[')
-               return NULL;
-       
-       namelen = ref->name->blength - 1;
-       if (*name == 'L') {
-               name++;
-               namelen -= 2;
-       }
-       else if (*name != '[') {
-               return NULL;
-       }
-
-    return class_get_classref(ref->referer, utf_new(name, namelen));
-}
-
-
-/* class_findmethod ************************************************************
-       
-   Searches a 'classinfo' structure for a method having the given name
-   and descriptor. If descriptor is NULL, it is ignored.
-
-*******************************************************************************/
-
-methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
-{
-       methodinfo *m;
-       s4          i;
-
-       for (i = 0; i < c->methodscount; i++) {
-               m = &(c->methods[i]);
-
-               if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
-                       return m;
-       }
-
-       return NULL;
-}
-
-
-/* class_resolvemethod *********************************************************
-       
-   Searches a class and it's super classes for a method.
-
-   Superinterfaces are *not* searched.
-
-*******************************************************************************/
-
-methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
-{
-       methodinfo *m;
-
-       while (c) {
-               m = class_findmethod(c, name, desc);
-
-               if (m)
-                       return m;
-
-               /* JVM Specification bug: 
-
-                  It is important NOT to resolve special <init> and <clinit>
-                  methods to super classes or interfaces; yet, this is not
-                  explicited in the specification.  Section 5.4.3.3 should be
-                  updated appropriately.  */
-
-               if (name == utf_init || name == utf_clinit)
-                       return NULL;
-
-               c = c->super;
-       }
-
-       return NULL;
-}
-
-
-/* class_resolveinterfacemethod_intern *****************************************
-
-   Internally used helper function. Do not use this directly.
-
-*******************************************************************************/
-
-static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
-                                                                                                          utf *name, utf *desc)
-{
-       methodinfo *m;
-       s4          i;
-
-       /* try to find the method in the class */
-
-       m = class_findmethod(c, name, desc);
-
-       if (m != NULL)
-               return m;
-
-       /* No method found?  Try the super interfaces. */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
-
-               if (m != NULL)
-                       return m;
-       }
-
-       /* no method found */
-
-       return NULL;
-}
-
-
-/* class_resolveclassmethod ****************************************************
-       
-   Resolves a reference from REFERER to a method with NAME and DESC in
-   class C.
-
-   If the method cannot be resolved the return value is NULL. If
-   EXCEPT is true *exceptionptr is set, too.
-
-*******************************************************************************/
-
-methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
-                                                                        classinfo *referer, bool throwexception)
-{
-       classinfo  *cls;
-       methodinfo *m;
-       s4          i;
-
-/*     if (c->flags & ACC_INTERFACE) { */
-/*             if (throwexception) */
-/*                     *exceptionptr = */
-/*                             new_exception(string_java_lang_IncompatibleClassChangeError); */
-/*             return NULL; */
-/*     } */
-
-       /* try class c and its superclasses */
-
-       cls = c;
-
-       m = class_resolvemethod(cls, name, desc);
-
-       if (m != NULL)
-               goto found;
-
-       /* Try the super interfaces. */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
-
-               if (m != NULL)
-                       goto found;
-       }
-       
-       if (throwexception)
-               exceptions_throw_nosuchmethoderror(c, name, desc);
-
-       return NULL;
-
- found:
-       if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
-               if (throwexception)
-                       exceptions_throw_abstractmethoderror();
-
-               return NULL;
-       }
-
-       /* XXX check access rights */
-
-       return m;
-}
-
-
-/* class_resolveinterfacemethod ************************************************
-
-   Resolves a reference from REFERER to a method with NAME and DESC in
-   interface C.
-
-   If the method cannot be resolved the return value is NULL. If
-   EXCEPT is true *exceptionptr is set, too.
-
-*******************************************************************************/
-
-methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
-                                                                                classinfo *referer, bool throwexception)
-{
-       methodinfo *mi;
-
-       if (!(c->flags & ACC_INTERFACE)) {
-               if (throwexception)
-                       exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
-
-               return NULL;
-       }
-
-       mi = class_resolveinterfacemethod_intern(c, name, desc);
-
-       if (mi != NULL)
-               return mi;
-
-       /* try class java.lang.Object */
-
-       mi = class_findmethod(class_java_lang_Object, name, desc);
-
-       if (mi != NULL)
-               return mi;
-
-       if (throwexception)
-               exceptions_throw_nosuchmethoderror(c, name, desc);
-
-       return NULL;
-}
-
-
-/* class_findfield *************************************************************
-       
-   Searches for field with specified name and type in a classinfo
-   structure. If no such field is found NULL is returned.
-
-*******************************************************************************/
-
-fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
-{
-       s4 i;
-
-       for (i = 0; i < c->fieldscount; i++)
-               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
-                       return &(c->fields[i]);
-
-       if (c->super != NULL)
-               return class_findfield(c->super, name, desc);
-
-       return NULL;
-}
-
-
-/* class_findfield_approx ******************************************************
-       
-   Searches in 'classinfo'-structure for a field with the specified
-   name.
-
-*******************************************************************************/
-fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
-{
-       s4 i;
-
-       /* get field index */
-
-       i = class_findfield_index_by_name(c, name);
-
-       /* field was not found, return */
-
-       if (i == -1)
-               return NULL;
-
-       /* return field address */
-
-       return &(c->fields[i]);
-}
-
-
-s4 class_findfield_index_by_name(classinfo *c, utf *name)
-{
-       s4 i;
-
-       for (i = 0; i < c->fieldscount; i++) {
-               /* compare field names */
-
-               if ((c->fields[i].name == name))
-                       return i;
-       }
-
-       /* field was not found, raise exception */      
-
-       exceptions_throw_nosuchfielderror(c, name);
-
-       return -1;
-}
-
-
-/****************** Function: class_resolvefield_int ***************************
-
-    This is an internally used helper function. Do not use this directly.
-
-       Tries to resolve a field having the given name and type.
-    If the field cannot be resolved, NULL is returned.
-
-*******************************************************************************/
-
-static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
-{
-       fieldinfo *fi;
-       s4         i;
-
-       /* search for field in class c */
-
-       for (i = 0; i < c->fieldscount; i++) { 
-               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
-                       return &(c->fields[i]);
-               }
-    }
-
-       /* Try super interfaces recursively. */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               fi = class_resolvefield_int(c->interfaces[i], name, desc);
-
-               if (fi != NULL)
-                       return fi;
-       }
-
-       /* Try super class. */
-
-       if (c->super != NULL)
-               return class_resolvefield_int(c->super, name, desc);
-
-       /* not found */
-
-       return NULL;
-}
-
-
-/********************* Function: class_resolvefield ***************************
-       
-       Resolves a reference from REFERER to a field with NAME and DESC in class C.
-
-    If the field cannot be resolved the return value is NULL. If EXCEPT is
-    true *exceptionptr is set, too.
-
-*******************************************************************************/
-
-fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
-                                                         classinfo *referer, bool throwexception)
-{
-       fieldinfo *fi;
-
-       fi = class_resolvefield_int(c, name, desc);
-
-       if (!fi) {
-               if (throwexception)
-                       exceptions_throw_nosuchfielderror(c, name);
-
-               return NULL;
-       }
-
-       /* XXX check access rights */
-
-       return fi;
-}
-
-
-/* class_issubclass ************************************************************
-
-   Checks if sub is a descendant of super.
-       
-*******************************************************************************/
-
-bool class_issubclass(classinfo *sub, classinfo *super)
-{
-       classinfo *c;
-
-       c = sub;
-
-       for (;;) {
-               /* We reached java/lang/Object and did not find the requested
-                  super class. */
-
-               if (c == NULL)
-                       return false;
-
-               /* We found the requested super class. */
-
-               if (c == super)
-                       return true;
-
-               c = c->super;
-       }
-}
-
-
-/* class_isanysubclass *********************************************************
-
-   Checks a subclass relation between two classes. Implemented
-   interfaces are interpreted as super classes.
-
-   Return value: 1 ... sub is subclass of super
-                 0 ... otherwise
-
-*******************************************************************************/
-
-bool class_isanysubclass(classinfo *sub, classinfo *super)
-{
-       uint32_t diffval;
-       bool     result;
-
-       /* This is the trivial case. */
-
-       if (sub == super)
-               return true;
-
-       /* Primitive classes are only subclasses of themselves. */
-
-       if (class_is_primitive(sub) || class_is_primitive(super))
-               return false;
-
-       /* Check for interfaces. */
-
-       if (super->flags & ACC_INTERFACE) {
-               result = (sub->vftbl->interfacetablelength > super->index) &&
-                       (sub->vftbl->interfacetable[-super->index] != NULL);
-       }
-       else {
-               /* java.lang.Object is the only super class of any
-                  interface. */
-
-               if (sub->flags & ACC_INTERFACE)
-                       return (super == class_java_lang_Object);
-
-               LOCK_MONITOR_ENTER(linker_classrenumber_lock);
-
-               diffval = sub->vftbl->baseval - super->vftbl->baseval;
-               result  = diffval <= (uint32_t) super->vftbl->diffval;
-
-               LOCK_MONITOR_EXIT(linker_classrenumber_lock);
-       }
-
-       return result;
-}
-
-
-/* class_is_assignable_from ****************************************************
-
-   Return whether an instance of the "from" class parameter would be
-   an instance of this class "to" as well.
-
-   ARGUMENTS:
-       to ..... class
-          from ... class
-
-   RETURN:
-       true .... is assignable
-          false ... is not assignable
-
-*******************************************************************************/
-
-bool class_is_assignable_from(classinfo *to, classinfo *from)
-{
-       if (!(to->state & CLASS_LINKED))
-               if (!link_class(to))
-                       return false;
-
-       if (!(from->state & CLASS_LINKED))
-               if (!link_class(from))
-                       return false;
-
-       return class_isanysubclass(from, to);
-}
-
-
-/* class_is_instance ***********************************************************
-
-   Return if the given Java object is an instance of the given class.
-
-   ARGUMENTS:
-       c ... class
-          h ... Java object
-
-   RETURN:
-       true .... is instance
-          false ... is not instance
-
-*******************************************************************************/
-
-bool class_is_instance(classinfo *c, java_handle_t *h)
-{
-       if (!(c->state & CLASS_LINKED))
-               if (!link_class(c))
-                       return false;
-
-       return builtin_instanceof(h, c);
-}
-
-
-/* class_get_componenttype *****************************************************
-
-   Return the component class of the given class.  If the given class
-   is not an array, return NULL.
-
-*******************************************************************************/
-
-classinfo *class_get_componenttype(classinfo *c)
-{
-       classinfo       *component;
-       arraydescriptor *ad;
-       
-       /* XXX maybe we could find a way to do this without linking. */
-       /* This way should be safe and easy, however.                */
-
-       if (!(c->state & CLASS_LINKED))
-               if (!link_class(c))
-                       return NULL;
-
-       ad = c->vftbl->arraydesc;
-       
-       if (ad == NULL)
-               return NULL;
-       
-       if (ad->arraytype == ARRAYTYPE_OBJECT)
-               component = ad->componentvftbl->clazz;
-       else
-               component = primitive_class_get_by_type(ad->arraytype);
-               
-       return component;
-}
-
-
-/* class_get_declaredclasses ***************************************************
-
-   Return an array of declared classes of the given class.
-
-*******************************************************************************/
-
-java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly)
-{
-       classref_or_classinfo  inner;
-       classref_or_classinfo  outer;
-       utf                   *outername;
-       int                    declaredclasscount;  /* number of declared classes */
-       int                    pos;                     /* current declared class */
-       java_handle_objectarray_t *oa;               /* array of declared classes */
-       int                    i;
-       classinfo             *ic;
-
-       declaredclasscount = 0;
-
-       if (!class_is_primitive(c) && !class_is_array(c)) {
-               /* Determine number of declared classes. */
-
-               for (i = 0; i < c->innerclasscount; i++) {
-                       /* Get outer-class.  If the inner-class is not a member
-                          class, the outer-class is NULL. */
-
-                       outer = c->innerclass[i].outer_class;
-
-                       if (outer.any == NULL)
-                               continue;
-
-                       /* Check if outer-class is a classref or a real class and
-               get the class name from the structure. */
-
-                       outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
-
-                       /* Outer class is this class. */
-
-                       if ((outername == c->name) &&
-                               ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC)))
-                               declaredclasscount++;
-               }
-       }
-
-       /* Allocate Class[] and check for OOM. */
-
-       oa = builtin_anewarray(declaredclasscount, class_java_lang_Class);
-
-       if (oa == NULL)
-               return NULL;
-
-       for (i = 0, pos = 0; i < c->innerclasscount; i++) {
-               inner = c->innerclass[i].inner_class;
-               outer = c->innerclass[i].outer_class;
-
-               /* Get outer-class.  If the inner-class is not a member class,
-                  the outer-class is NULL. */
-
-               if (outer.any == NULL)
-                       continue;
-
-               /* Check if outer_class is a classref or a real class and get
-                  the class name from the structure. */
-
-               outername = IS_CLASSREF(outer) ? outer.ref->name : outer.cls->name;
-
-               /* Outer class is this class. */
-
-               if ((outername == c->name) &&
-                       ((publicOnly == 0) || (c->innerclass[i].flags & ACC_PUBLIC))) {
-
-                       ic = resolve_classref_or_classinfo_eager(inner, false);
-
-                       if (ic == NULL)
-                               return NULL;
-
-                       if (!(ic->state & CLASS_LINKED))
-                               if (!link_class(ic))
-                                       return NULL;
-
-                       LLNI_array_direct(oa, pos++) = (java_object_t *) ic;
-               }
-       }
-
-       return oa;
-}
-
-
-/**
- * Return an array of declared constructors of the given class.
- *
- * @param c          class to get the constructors of
- * @param publicOnly show only public fields
- *
- * @return array of java.lang.reflect.Constructor
- */
-#if defined(ENABLE_JAVASE)
-java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
-{
-       methodinfo*                m;
-       java_handle_objectarray_t* oa;
-       java_handle_t*             rc;
-       int                        count;
-       int                        index;
-       int                        i;
-
-       /* Determine number of constructors. */
-
-       count = 0;
-
-       for (i = 0; i < c->methodscount; i++) {
-               m = &(c->methods[i]);
-
-               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
-                       (m->name == utf_init))
-                       count++;
-       }
-
-       /* Create array of constructors. */
-
-       oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
-
-       if (oa == NULL)
-               return NULL;
-
-       /* Get the constructors and store them in the array. */
-
-       for (i = 0, index = 0; i < c->methodscount; i++) {
-               m = &(c->methods[i]);
-
-               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
-                       (m->name == utf_init)) {
-                       /* Create Constructor object.  This is actualy a
-                          java_lang_reflect_Constructor pointer, but we use a
-                          java_handle_t here, because we don't have the header
-                          available when building vmcore. */
-
-                       rc = reflect_constructor_new(m);
-
-                       /* Store object into array. */
-
-                       array_objectarray_element_set(oa, index, rc);
-                       index++;
-               }
-       }
-
-       return oa;
-}
-#endif
-
-
-/* class_get_declaredfields ****************************************************
-
-   Return an array of declared fields of the given class.
-
-   ARGUMENTS:
-       c ............ class to get the fields of
-          publicOnly ... show only public fields
-
-   RETURN:
-       array of java.lang.reflect.Field
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
-{
-       java_handle_objectarray_t *oa;
-       fieldinfo                 *f;
-       java_handle_t             *h;
-       int                        count;
-       int                        index;
-       int                        i;
-
-       /* Determine number of fields. */
-
-       count = 0;
-
-       for (i = 0; i < c->fieldscount; i++)
-               if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
-                       count++;
-
-       /* Create array of fields. */
-
-       oa = builtin_anewarray(count, class_java_lang_reflect_Field);
-
-       if (oa == NULL)
-               return NULL;
-
-       /* Get the fields and store them in the array. */
-
-       for (i = 0, index = 0; i < c->fieldscount; i++) {
-               f = &(c->fields[i]);
-
-               if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
-                       /* Create Field object.  This is actualy a
-                          java_lang_reflect_Field pointer, but we use a
-                          java_handle_t here, because we don't have the header
-                          available when building vmcore. */
-
-                       h = reflect_field_new(f);
-
-                       /* Store object into array. */
-
-                       array_objectarray_element_set(oa, index, h);
-                       index++;
-               }
-       }
-
-       return oa;
-}
-#endif
-
-
-/* class_get_declaredmethods ***************************************************
-
-   Return an array of declared methods of the given class.
-
-   ARGUMENTS:
-       c ............ class to get the methods of
-          publicOnly ... show only public methods
-
-   RETURN:
-       array of java.lang.reflect.Method
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
-{
-       java_handle_objectarray_t *oa;         /* result: array of Method-objects */
-       methodinfo                *m;     /* the current method to be represented */
-       java_handle_t             *h;
-       int                        count;
-       int                        index;
-       int                        i;
-
-       /* JOWENN: array classes do not declare methods according to mauve
-          test.  It should be considered, if we should return to my old
-          clone method overriding instead of declaring it as a member
-          function. */
-
-       if (class_is_array(c))
-               return builtin_anewarray(0, class_java_lang_reflect_Method);
-
-       /* Determine number of methods. */
-
-       count = 0;
-
-       for (i = 0; i < c->methodscount; i++) {
-               m = &(c->methods[i]);
-
-               if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
-                       ((m->name != utf_init) && (m->name != utf_clinit)) &&
-                       !(m->flags & ACC_MIRANDA))
-                       count++;
-       }
-
-       /* Create array of methods. */
-
-       oa = builtin_anewarray(count, class_java_lang_reflect_Method);
-
-       if (oa == NULL)
-               return NULL;
-
-       /* Get the methods and store them in the array. */
-
-       for (i = 0, index = 0; i < c->methodscount; i++) {
-               m = &(c->methods[i]);
-
-               if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
-                       ((m->name != utf_init) && (m->name != utf_clinit)) &&
-                       !(m->flags & ACC_MIRANDA)) {
-                       /* Create method object.  This is actualy a
-                          java_lang_reflect_Method pointer, but we use a
-                          java_handle_t here, because we don't have the header
-                          available when building vmcore. */
-
-                       h = reflect_method_new(m);
-
-                       /* Store object into array. */
-
-                       array_objectarray_element_set(oa, index, h);
-                       index++;
-               }
-       }
-
-       return oa;
-}
-#endif
-
-
-/* class_get_declaringclass ****************************************************
-
-   If the class or interface given is a member of another class,
-   return the declaring class.  For array and primitive classes return
-   NULL.
-
-*******************************************************************************/
-
-classinfo *class_get_declaringclass(classinfo *c)
-{
-       classref_or_classinfo  cr;
-       classinfo             *dc;
-
-       /* Get declaring class. */
-
-       cr = c->declaringclass;
-
-       if (cr.any == NULL)
-               return NULL;
-
-       /* Resolve the class if necessary. */
-
-       if (IS_CLASSREF(cr)) {
-/*             dc = resolve_classref_eager(cr.ref); */
-               dc = resolve_classref_or_classinfo_eager(cr, true);
-
-               if (dc == NULL)
-                       return NULL;
-
-               /* Store the resolved class in the class structure. */
-
-               cr.cls = dc;
-       }
-
-       dc = cr.cls;
-
-       return dc;
-}
-
-
-/* class_get_enclosingclass ****************************************************
-
-   Return the enclosing class for the given class.
-
-*******************************************************************************/
-
-classinfo *class_get_enclosingclass(classinfo *c)
-{
-       classref_or_classinfo  cr;
-       classinfo             *ec;
-
-       /* Get enclosing class. */
-
-       cr = c->enclosingclass;
-
-       if (cr.any == NULL)
-               return NULL;
-
-       /* Resolve the class if necessary. */
-
-       if (IS_CLASSREF(cr)) {
-/*             ec = resolve_classref_eager(cr.ref); */
-               ec = resolve_classref_or_classinfo_eager(cr, true);
-
-               if (ec == NULL)
-                       return NULL;
-
-               /* Store the resolved class in the class structure. */
-
-               cr.cls = ec;
-       }
-
-       ec = cr.cls;
-
-       return ec;
-}
-
-
-/**
- * Return the enclosing constructor as java.lang.reflect.Constructor
- * object for the given class.
- *
- * @param c class to return the enclosing constructor for
- *
- * @return java.lang.reflect.Constructor object of the enclosing
- * constructor
- */
-#if defined(ENABLE_JAVASE)
-java_handle_t* class_get_enclosingconstructor(classinfo *c)
-{
-       methodinfo*    m;
-       java_handle_t* rc;
-
-       m = class_get_enclosingmethod_raw(c);
-
-       if (m == NULL)
-               return NULL;
-
-       /* Check for <init>. */
-
-       if (m->name != utf_init)
-               return NULL;
-
-       /* Create Constructor object. */
-
-       rc = reflect_constructor_new(m);
-
-       return rc;
-}
-#endif
-
-
-/* class_get_enclosingmethod ***************************************************
-
-   Return the enclosing method for the given class.
-
-   IN:
-       c ... class to return the enclosing method for
-
-   RETURN:
-       methodinfo of the enclosing method
-
-*******************************************************************************/
-
-methodinfo *class_get_enclosingmethod_raw(classinfo *c)
-{
-       constant_nameandtype *cn;
-       classinfo            *ec;
-       methodinfo           *m;
-
-       /* get enclosing class and method */
-
-       ec = class_get_enclosingclass(c);
-       cn = c->enclosingmethod;
-
-       /* check for enclosing class and method */
-
-       if (ec == NULL)
-               return NULL;
-
-       if (cn == NULL)
-               return NULL;
-
-       /* find method in enclosing class */
-
-       m = class_findmethod(ec, cn->name, cn->descriptor);
-
-       if (m == NULL) {
-               exceptions_throw_internalerror("Enclosing method doesn't exist");
-               return NULL;
-       }
-
-       return m;
-}
-
-
-/**
- * Return the enclosing method as java.lang.reflect.Method object for
- * the given class.
- *
- * @param c class to return the enclosing method for
- *
- * @return java.lang.reflect.Method object of the enclosing method
- */
-#if defined(ENABLE_JAVASE)
-java_handle_t* class_get_enclosingmethod(classinfo *c)
-{
-       methodinfo*    m;
-       java_handle_t* rm;
-
-       m = class_get_enclosingmethod_raw(c);
-
-       if (m == NULL)
-               return NULL;
-
-       /* check for <init> */
-
-       if (m->name == utf_init)
-               return NULL;
-
-       /* create java.lang.reflect.Method object */
-
-       rm = reflect_method_new(m);
-
-       return rm;
-}
-#endif
-
-
-/* class_get_interfaces ********************************************************
-
-   Return an array of interfaces of the given class.
-
-*******************************************************************************/
-
-java_handle_objectarray_t *class_get_interfaces(classinfo *c)
-{
-       classinfo                 *ic;
-       java_handle_objectarray_t *oa;
-       u4                         i;
-
-       if (!(c->state & CLASS_LINKED))
-               if (!link_class(c))
-                       return NULL;
-
-       oa = builtin_anewarray(c->interfacescount, class_java_lang_Class);
-
-       if (oa == NULL)
-               return NULL;
-
-       for (i = 0; i < c->interfacescount; i++) {
-               ic = c->interfaces[i];
-
-               LLNI_array_direct(oa, i) = (java_object_t *) ic;
-       }
-
-       return oa;
-}
-
-
-/* class_get_annotations *******************************************************
-
-   Get the unparsed declared annotations in a byte array
-   of the given class.
-
-   IN:
-       c........the class of which the annotations should be returned
-
-   RETURN VALUE:
-       The unparsed declared annotations in a byte array
-       (or NULL if there aren't any).
-
-*******************************************************************************/
-
-java_handle_bytearray_t *class_get_annotations(classinfo *c)
-{
-#if defined(ENABLE_ANNOTATIONS)
-       java_handle_t *annotations; /* unparsed annotations */
-
-       LLNI_classinfo_field_get(c, annotations, annotations);
-
-       return (java_handle_bytearray_t*)annotations;
-#else
-       return NULL;
-#endif
-}
-
-
-/* class_get_modifiers *********************************************************
-
-   Get the modifier flags of the given class.
-
-   IN:
-       c....the class of which the modifier flags should be returned
-          ignoreInnerClassesAttrib
-   RETURN VALUE:
-       modifier flags
-
-*******************************************************************************/
-
-int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
-{
-       classref_or_classinfo  inner;
-       classref_or_classinfo  outer;
-       utf                   *innername;
-       int                    i;
-
-       if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
-               /* search for passed class as inner class */
-
-               for (i = 0; i < c->innerclasscount; i++) {
-                       inner = c->innerclass[i].inner_class;
-                       outer = c->innerclass[i].outer_class;
-
-                       /* Check if inner is a classref or a real class and get
-               the name of the structure */
-
-                       innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
-
-                       /* innerclass is this class */
-
-                       if (innername == c->name) {
-                               /* has the class actually an outer class? */
-
-                               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;
-                       }
-               }
-       }
-
-       /* passed class is no inner class or it was not requested */
-
-       return c->flags & ACC_CLASS_REFLECT_MASK;
-}
-
-
-/* class_get_signature *********************************************************
-
-   Return the signature of the given class.  For array and primitive
-   classes return NULL.
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-utf *class_get_signature(classinfo *c)
-{
-       /* For array and primitive classes return NULL. */
-
-       if (class_is_array(c) || class_is_primitive(c))
-               return NULL;
-
-       return c->signature;
-}
-#endif
-
-
-/* class_printflags ************************************************************
-
-   Prints flags of a class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_printflags(classinfo *c)
-{
-       if (c == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
-       if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
-       if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
-       if (c->flags & ACC_STATIC)       printf(" STATIC");
-       if (c->flags & ACC_FINAL)        printf(" FINAL");
-       if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
-       if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
-       if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
-       if (c->flags & ACC_NATIVE)       printf(" NATIVE");
-       if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
-       if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
-}
-#endif
-
-
-/* class_print *****************************************************************
-
-   Prints classname plus flags.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_print(classinfo *c)
-{
-       if (c == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       utf_display_printable_ascii(c->name);
-       class_printflags(c);
-}
-#endif
-
-
-/* class_classref_print ********************************************************
-
-   Prints classname plus referer class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_print(constant_classref *cr)
-{
-       if (cr == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       utf_display_printable_ascii(cr->name);
-       printf("(ref.by ");
-       if (cr->referer)
-               class_print(cr->referer);
-       else
-               printf("NULL");
-       printf(")");
-}
-#endif
-
-
-/* class_println ***************************************************************
-
-   Prints classname plus flags and new line.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_println(classinfo *c)
-{
-       class_print(c);
-       printf("\n");
-}
-#endif
-
-
-/* class_classref_println ******************************************************
-
-   Prints classname plus referer class and new line.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_println(constant_classref *cr)
-{
-       class_classref_print(cr);
-       printf("\n");
-}
-#endif
-
-
-/* class_classref_or_classinfo_print *******************************************
-
-   Prints classname plus referer class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_or_classinfo_print(classref_or_classinfo c)
-{
-       if (c.any == NULL) {
-               printf("(classref_or_classinfo) NULL");
-               return;
-       }
-       if (IS_CLASSREF(c))
-               class_classref_print(c.ref);
-       else
-               class_print(c.cls);
-}
-#endif
-
-
-/* class_classref_or_classinfo_println *****************************************
-
-   Prints classname plus referer class and a newline.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_or_classinfo_println(classref_or_classinfo c)
-{
-       class_classref_or_classinfo_print(c);
-       printf("\n");
-}
-#endif
-
-
-/* class_showconstantpool ******************************************************
-
-   Dump the constant pool of the given class to stdout.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_showconstantpool (classinfo *c) 
-{
-       u4 i;
-       voidptr e;
-
-       printf ("---- dump of constant pool ----\n");
-
-       for (i=0; i<c->cpcount; i++) {
-               printf ("#%d:  ", (int) i);
-               
-               e = c -> cpinfos [i];
-               if (e) {
-                       
-                       switch (c -> cptags [i]) {
-                       case CONSTANT_Class:
-                               printf ("Classreference -> ");
-                               utf_display_printable_ascii ( ((constant_classref*)e) -> name );
-                               break;
-                       case CONSTANT_Fieldref:
-                               printf ("Fieldref -> ");
-                               field_fieldref_print((constant_FMIref *) e);
-                               break;
-                       case CONSTANT_Methodref:
-                               printf ("Methodref -> ");
-                               method_methodref_print((constant_FMIref *) e);
-                               break;
-                       case CONSTANT_InterfaceMethodref:
-                               printf ("InterfaceMethod -> ");
-                               method_methodref_print((constant_FMIref *) e);
-                               break;
-                       case CONSTANT_String:
-                               printf ("String -> ");
-                               utf_display_printable_ascii (e);
-                               break;
-                       case CONSTANT_Integer:
-                               printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
-                               break;
-                       case CONSTANT_Float:
-                               printf ("Float -> %f", ((constant_float*)e) -> value);
-                               break;
-                       case CONSTANT_Double:
-                               printf ("Double -> %f", ((constant_double*)e) -> value);
-                               break;
-                       case CONSTANT_Long:
-                               {
-                                       u8 v = ((constant_long*)e) -> value;
-#if U8_AVAILABLE
-                                       printf ("Long -> %ld", (long int) v);
-#else
-                                       printf ("Long -> HI: %ld, LO: %ld\n", 
-                                                       (long int) v.high, (long int) v.low);
-#endif 
-                               }
-                               break;
-                       case CONSTANT_NameAndType:
-                               {
-                                       constant_nameandtype *cnt = e;
-                                       printf ("NameAndType: ");
-                                       utf_display_printable_ascii (cnt->name);
-                                       printf (" ");
-                                       utf_display_printable_ascii (cnt->descriptor);
-                               }
-                               break;
-                       case CONSTANT_Utf8:
-                               printf ("Utf8 -> ");
-                               utf_display_printable_ascii (e);
-                               break;
-                       default: 
-                               log_text("Invalid type of ConstantPool-Entry");
-                               assert(0);
-                       }
-               }
-
-               printf ("\n");
-       }
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* class_showmethods ***********************************************************
-
-   Dump info about the fields and methods of the given class to stdout.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_showmethods (classinfo *c)
-{
-       s4 i;
-       
-       printf("--------- Fields and Methods ----------------\n");
-       printf("Flags: ");
-       class_printflags(c);
-       printf("\n");
-
-       printf("This: ");
-       utf_display_printable_ascii(c->name);
-       printf("\n");
-
-       if (c->super) {
-               printf("Super: ");
-               utf_display_printable_ascii(c->super->name);
-               printf ("\n");
-       }
-
-       printf("Index: %d\n", c->index);
-       
-       printf("Interfaces:\n");        
-       for (i = 0; i < c->interfacescount; i++) {
-               printf("   ");
-               utf_display_printable_ascii(c->interfaces[i]->name);
-               printf (" (%d)\n", c->interfaces[i]->index);
-       }
-
-       printf("Fields:\n");
-       for (i = 0; i < c->fieldscount; i++)
-               field_println(&(c->fields[i]));
-
-       printf("Methods:\n");
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &(c->methods[i]);
-
-               if (!(m->flags & ACC_STATIC))
-                       printf("vftblindex: %d   ", m->vftblindex);
-
-               method_println(m);
-       }
-
-       printf ("Virtual function table:\n");
-       for (i = 0; i < c->vftbl->vftbllength; i++)
-               printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
-}
-#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/vmcore/class.h b/src/vmcore/class.h
deleted file mode 100644 (file)
index 4b8be1b..0000000
+++ /dev/null
@@ -1,571 +0,0 @@
-/* src/vmcore/class.h - class related functions header
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _CLASS_H
-#define _CLASS_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct classinfo      classinfo; 
-typedef struct innerclassinfo innerclassinfo;
-typedef struct extra_classref extra_classref;
-typedef struct castinfo       castinfo;
-
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "toolbox/list.h"
-
-#include "vm/global.h"
-#include "vm/stringlocal.h"
-
-#if defined(ENABLE_JAVASE)
-# include "vmcore/annotation.h"
-#endif
-
-#include "vmcore/field.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-#include "vmcore/references.h"
-#include "vmcore/utf8.h"
-
-/* class state defines ********************************************************/
-
-#define CLASS_LOADING         0x0001
-#define CLASS_LOADED          0x0002
-#define CLASS_LINKING         0x0004
-#define CLASS_LINKED          0x0008
-#define CLASS_INITIALIZING    0x0010
-#define CLASS_INITIALIZED     0x0020
-#define CLASS_ERROR           0x0040
-
-
-/* some macros ****************************************************************/
-
-#define CLASS_IS_OR_ALMOST_INITIALIZED(c) \
-    (((c)->state & CLASS_INITIALIZING) || ((c)->state & CLASS_INITIALIZED))
-
-
-/* classinfo ******************************************************************/
-
-/* We define this dummy structure of java_lang_Class so we can
-   bootstrap cacaoh without needing a java_lang_Class.h file.  Whether
-   the size of the dummy structure is big enough is checked during
-   runtime in vm_create. */
-
-typedef struct {
-       java_object_t      header;
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       intptr_t           padding[4];
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       intptr_t           padding[19];
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-       intptr_t           padding[3];
-#else
-# error unknown classpath configuration
-#endif
-} dummy_java_lang_Class;
-
-struct classinfo {                /* class structure                          */
-       dummy_java_lang_Class object;
-
-       s4          flags;            /* ACC flags                                */
-       utf        *name;             /* class name                               */
-
-       s4          cpcount;          /* number of entries in constant pool       */
-       u1         *cptags;           /* constant pool tags                       */
-       voidptr    *cpinfos;          /* pointer to constant pool info structures */
-
-       s4          classrefcount;    /* number of symbolic class references      */
-       constant_classref *classrefs; /* table of symbolic class references       */
-       extra_classref *extclassrefs; /* additional classrefs                     */
-       s4          parseddescsize;   /* size of the parsed descriptors block     */
-       u1         *parseddescs;      /* parsed descriptors                       */
-
-       classinfo  *super;            /* super class                              */
-       classinfo  *sub;              /* sub class pointer                        */
-       classinfo  *nextsub;          /* pointer to next class in sub class list  */
-
-       int32_t     interfacescount;  /* number of interfaces                     */
-       classinfo **interfaces;       /* super interfaces                         */
-
-       int32_t     fieldscount;      /* number of fields                         */
-       fieldinfo  *fields;           /* field table                              */
-
-       int32_t     methodscount;     /* number of methods                        */
-       methodinfo *methods;          /* method table                             */
-
-       s4          state;            /* current class state                      */
-       s4          index;            /* hierarchy depth (classes) or index       */
-                                     /* (interfaces)                             */
-       s4          instancesize;     /* size of an instance of this class        */
-
-       vftbl_t    *vftbl;            /* pointer to virtual function table        */
-
-       methodinfo *finalizer;        /* finalizer method                         */
-
-       u2          innerclasscount;  /* number of inner classes                  */
-       innerclassinfo *innerclass;
-
-       classref_or_classinfo  declaringclass;
-       classref_or_classinfo  enclosingclass;  /* enclosing class                */
-       constant_nameandtype  *enclosingmethod; /* enclosing method               */
-
-       utf        *packagename;      /* full name of the package                 */
-       utf        *sourcefile;       /* SourceFile attribute                     */
-#if defined(ENABLE_JAVASE)
-       utf        *signature;        /* Signature attribute                      */
-#if defined(ENABLE_ANNOTATIONS)
-       /* All the annotation attributes are NULL (and not a zero length array)   */
-       /* if there is nothing.                                                   */
-       java_object_t *annotations;   /* annotations of this class                */
-       
-       java_object_t *method_annotations; /* array of annotations of the methods */
-       java_object_t *method_parameterannotations; /* array of parameter         */
-                                     /* annotations of the methods               */
-       java_object_t *method_annotationdefaults; /* array of annotation default  */
-                                     /* values of the methods                    */
-
-       java_object_t *field_annotations; /* array of annotations of the fields   */
-
-#endif
-#endif
-       classloader_t *classloader;       /* NULL for bootstrap classloader         */
-
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       java_object_t      *protectiondomain;
-       java_objectarray_t *signers;
-# endif
-#endif
-#if defined(ENABLE_JITCACHE)
-       int         cache_file_fd;
-#endif
-};
-
-
-/* innerclassinfo *************************************************************/
-
-struct innerclassinfo {
-       classref_or_classinfo inner_class; /* inner class pointer                 */
-       classref_or_classinfo outer_class; /* outer class pointer                 */
-       utf                  *name;        /* innerclass name                     */
-       s4                    flags;       /* ACC flags                           */
-};
-
-
-/* extra_classref **************************************************************
-
-   for classrefs not occurring within descriptors
-
-*******************************************************************************/
-
-struct extra_classref {
-       extra_classref    *next;
-       constant_classref  classref;
-};
-
-
-/* castinfo *******************************************************************/
-
-struct castinfo {
-       s4 super_baseval;
-       s4 super_diffval;
-       s4 sub_baseval;
-};
-
-
-/* global variables ***********************************************************/
-
-/* frequently used classes ****************************************************/
-
-/* Important system classes. */
-
-extern classinfo *class_java_lang_Object;
-extern classinfo *class_java_lang_Class;
-extern classinfo *class_java_lang_ClassLoader;
-extern classinfo *class_java_lang_Cloneable;
-extern classinfo *class_java_lang_SecurityManager;
-extern classinfo *class_java_lang_String;
-extern classinfo *class_java_lang_System;
-extern classinfo *class_java_lang_Thread;
-extern classinfo *class_java_lang_ThreadGroup;
-extern classinfo *class_java_lang_Throwable;
-extern classinfo *class_java_io_Serializable;
-
-/* Important system exceptions. */
-
-extern classinfo *class_java_lang_Exception;
-extern classinfo *class_java_lang_ClassNotFoundException;
-extern classinfo *class_java_lang_RuntimeException;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-extern classinfo *class_java_lang_VMSystem;
-extern classinfo *class_java_lang_VMThread;
-extern classinfo *class_java_lang_VMThrowable;
-#endif
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-extern classinfo *class_sun_reflect_MagicAccessorImpl;
-#endif
-
-#if defined(ENABLE_JAVASE)
-extern classinfo *class_java_lang_Void;
-#endif
-
-extern classinfo *class_java_lang_Boolean;
-extern classinfo *class_java_lang_Byte;
-extern classinfo *class_java_lang_Character;
-extern classinfo *class_java_lang_Short;
-extern classinfo *class_java_lang_Integer;
-extern classinfo *class_java_lang_Long;
-extern classinfo *class_java_lang_Float;
-extern classinfo *class_java_lang_Double;
-
-/* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-extern classinfo *class_java_lang_StackTraceElement;
-extern classinfo *class_java_lang_reflect_Constructor;
-extern classinfo *class_java_lang_reflect_Field;
-extern classinfo *class_java_lang_reflect_Method;
-extern classinfo *class_java_security_PrivilegedAction;
-extern classinfo *class_java_util_Vector;
-extern classinfo *class_java_util_HashMap;
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-extern classinfo *class_java_lang_reflect_VMConstructor;
-extern classinfo *class_java_lang_reflect_VMField;
-extern classinfo *class_java_lang_reflect_VMMethod;
-# endif
-
-extern classinfo *arrayclass_java_lang_Object;
-
-# if defined(ENABLE_ANNOTATIONS)
-extern classinfo *class_sun_reflect_ConstantPool;
-#  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-extern classinfo *class_sun_reflect_annotation_AnnotationParser;
-#  endif
-# endif
-#endif
-
-
-/* pseudo classes for the type checker ****************************************/
-
-/*
- * pseudo_class_Arraystub
- *     (extends Object implements Cloneable, java.io.Serializable)
- *
- *     If two arrays of incompatible component types are merged,
- *     the resulting reference has no accessible components.
- *     The result does, however, implement the interfaces Cloneable
- *     and java.io.Serializable. This pseudo class is used internally
- *     to represent such results. (They are *not* considered arrays!)
- *
- * pseudo_class_Null
- *
- *     This pseudo class is used internally to represent the
- *     null type.
- *
- * pseudo_class_New
- *
- *     This pseudo class is used internally to represent the
- *     the 'uninitialized object' type.
- */
-
-extern classinfo *pseudo_class_Arraystub;
-extern classinfo *pseudo_class_Null;
-extern classinfo *pseudo_class_New;
-
-
-/* inline functions ***********************************************************/
-
-/**
- * Returns the classname of the class, where slashes ('/') are
- * replaced by dots ('.').
- *
- * @param c class to get name of
- * @return classname
- */
-inline static java_handle_t* class_get_classname(classinfo* c)
-{
-       java_handle_t *s;
-
-       /* Create a java string. */
-
-       s = javastring_new_slash_to_dot(c->name);
-
-       return s;
-}
-
-
-/* class_is_primitive **********************************************************
-
-   Checks if the given class is a primitive class.
-
-*******************************************************************************/
-
-static inline bool class_is_primitive(classinfo *c)
-{
-       if (c->flags & ACC_CLASS_PRIMITIVE)
-               return true;
-
-       return false;
-}
-
-
-/* class_is_anonymousclass *****************************************************
-
-   Checks if the given class is an anonymous class.
-
-*******************************************************************************/
-
-static inline bool class_is_anonymousclass(classinfo *c)
-{
-       if (c->flags & ACC_CLASS_ANONYMOUS)
-               return true;
-
-       return false;
-}
-
-
-/* class_is_array **************************************************************
-
-   Checks if the given class is an array class.
-
-*******************************************************************************/
-
-static inline bool class_is_array(classinfo *c)
-{
-       if (!(c->state & CLASS_LINKED))
-               if (!link_class(c))
-                       return false;
-
-       return (c->vftbl->arraydesc != NULL);
-}
-
-
-/* class_is_interface **********************************************************
-
-   Checks if the given class is an interface.
-
-*******************************************************************************/
-
-static inline bool class_is_interface(classinfo *c)
-{
-       if (c->flags & ACC_INTERFACE)
-               return true;
-
-       return false;
-}
-
-
-/* class_is_localclass *********************************************************
-
-   Checks if the given class is a local class.
-
-*******************************************************************************/
-
-static inline bool class_is_localclass(classinfo *c)
-{
-       if ((c->enclosingmethod != NULL) && !class_is_anonymousclass(c))
-               return true;
-
-       return false;
-}
-
-
-/* class_is_memberclass ********************************************************
-
-   Checks if the given class is a member class.
-
-*******************************************************************************/
-
-static inline bool class_is_memberclass(classinfo *c)
-{
-       if (c->flags & ACC_CLASS_MEMBER)
-               return true;
-
-       return false;
-}
-
-
-/* class_get_classloader *******************************************************
-
-   Return the classloader of the given class.
-
-*******************************************************************************/
-
-static inline classloader_t *class_get_classloader(classinfo *c)
-{
-       classloader_t *cl;
-
-       cl = c->classloader;
-
-       /* The classloader may be NULL. */
-
-       return cl;
-}
-
-
-/* class_get_superclass ********************************************************
-
-   Return the super class of the given class.
-
-*******************************************************************************/
-
-static inline classinfo *class_get_superclass(classinfo *c)
-{
-       /* For interfaces we return NULL. */
-
-       if (c->flags & ACC_INTERFACE)
-               return NULL;
-
-       /* For java/lang/Object, primitive-type and Void classes c->super
-          is NULL and we return NULL. */
-
-       return c->super;
-}
-
-
-/* function prototypes ********************************************************/
-
-classinfo *class_create_classinfo(utf *u);
-void       class_postset_header_vftbl(void);
-classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd);
-void       class_set_packagename(classinfo *c);
-
-bool       class_load_attributes(classbuffer *cb);
-
-/* retrieve constantpool element */
-voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype);
-voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype);
-
-/* frees all resources used by the class */
-void class_free(classinfo *);
-
-/* return an array class with the given component class */
-classinfo *class_array_of(classinfo *component,bool link);
-
-/* return an array class with the given dimension and element class */
-classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link);
-
-/* return a classref for the given class name */
-/* (does a linear search!)                    */
-constant_classref *class_lookup_classref(classinfo *cls,utf *name);
-
-/* return a classref for the given class name */
-/* (does a linear search!)                    */
-constant_classref *class_get_classref(classinfo *cls,utf *name);
-
-/* return a classref to the class itself */
-/* (does a linear search!)                    */
-constant_classref *class_get_self_classref(classinfo *cls);
-
-/* return a classref for an array with the given dimension of with the */
-/* given component type */
-constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref);
-
-/* return a classref for the component type of the given array type */
-constant_classref *class_get_classref_component_of(constant_classref *ref);
-
-/* get a class' field by name and descriptor */
-fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc);
-
-/* search 'classinfo'-structure for a field with the specified name */
-fieldinfo *class_findfield_by_name(classinfo *c, utf *name);
-s4 class_findfield_index_by_name(classinfo *c, utf *name);
-
-/* search class for a field */
-fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer, bool throwexception);
-
-/* search for a method with a specified name and descriptor */
-methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc);
-methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *dest);
-methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
-methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
-
-bool                       class_issubclass(classinfo *sub, classinfo *super);
-bool                       class_isanysubclass(classinfo *sub, classinfo *super);
-bool                       class_is_assignable_from(classinfo *to, classinfo *from);
-bool                       class_is_instance(classinfo *c, java_handle_t *h);
-
-classloader_t             *class_get_classloader(classinfo *c);
-classinfo                 *class_get_superclass(classinfo *c);
-classinfo                 *class_get_componenttype(classinfo *c);
-java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOnly);
-java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly);
-java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly);
-java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly);
-classinfo                 *class_get_declaringclass(classinfo *c);
-classinfo                 *class_get_enclosingclass(classinfo *c);
-java_handle_t*             class_get_enclosingconstructor(classinfo *c);
-methodinfo*                class_get_enclosingmethod_raw(classinfo *c);
-java_handle_t*             class_get_enclosingmethod(classinfo *c);
-java_handle_objectarray_t *class_get_interfaces(classinfo *c);
-java_handle_bytearray_t   *class_get_annotations(classinfo *c);
-int32_t                    class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib);
-java_handle_t             *class_get_name(classinfo *c);
-
-#if defined(ENABLE_JAVASE)
-utf                       *class_get_signature(classinfo *c);
-#endif
-
-/* some debugging functions */
-
-#if !defined(NDEBUG)
-void class_printflags(classinfo *c);
-void class_print(classinfo *c);
-void class_println(classinfo *c);
-void class_classref_print(constant_classref *cr);
-void class_classref_println(constant_classref *cr);
-void class_classref_or_classinfo_print(classref_or_classinfo c);
-void class_classref_or_classinfo_println(classref_or_classinfo c);
-#endif
-
-/* debug purposes */
-void class_showmethods(classinfo *c);
-void class_showconstantpool(classinfo *c);
-
-#endif /* _CLASS_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/vmcore/classcache.c b/src/vmcore/classcache.c
deleted file mode 100644 (file)
index 76fc825..0000000
+++ /dev/null
@@ -1,1588 +0,0 @@
-/* src/vmcore/classcache.c - loaded class cache and loading constraints
-
-   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 "mm/memory.h"
-
-#include "threads/lock-common.h"
-
-#include "toolbox/hashtable.h"
-#include "toolbox/logging.h"
-
-#include "vm/exceptions.h"
-
-#include "vmcore/classcache.h"
-#include "vmcore/options.h"
-#include "vmcore/utf8.h"
-
-
-/*************************************************************************
-
-  Class Cache
-
-  The classcache has two functions:
-  
-       1) caching the resolution of class references
-       2) storing and checking loading constraints
-
-  We will use the following terms in this description:
-
-       N          a class name: a utf string
-       (N,L)      a class reference with initiating loader L and class name N
-       C          a class (object): the result of resolving a reference (N,L)
-               We will write resultion as
-                               C = *(N,L)
-       (N,L1,L2)  a loading constraint indicating that (N,L1) and (N,L2) must
-                  resolve to the same class C. So (N,L1,L2) means
-                               *(N,L1) = *(N,L2)
-
-  The functions of the classcache require:
-
-    1) a mapping (N,L) |--> C for looking up prior resolution results.
-       2) storing the current set of loading constraints { (N,L1,L2) }
-
-  These functions can be rearranged like that:
-
-    a mapping N |--> (a mapping L |--> C or NULL, 
-                         a set of constraints {(L1,L2)})
-
-  Thus we can treat the mapping and constraints for each name N
-  separately. The implementation does this by keeping a hash table
-  mapping a name N to a `classcache_name_entry` which contains all
-  info with respect to N.
-
-  For a class name N we can define an equivalence relation ~N~ on
-  class loaders:
-
-       L1 ~N~ L2  <==>  *(N,L1) = *(N,L2)
-
-  A loading constraint (N,L1,L2) implies L1 ~N~ L2.
-
-  Also, if two references (N,L1) and (N,L2) resolve to the same class C
-  we have L1 ~N~ L2 because class loaders are required to return
-  consistent resolutions for a name N [XXX].
-
-  A `classcache_name_entry` keeps a set of tuples { (Cx,IL,CL) },
-  where
-               Cx...is a class C or NULL
-               IL...is the set of initiating loaders
-               CL...is the set of constrained loaders
-               
-  Such a tuple is called `classcache_class_entry` in the source code.
-
-  The following holds for each tuple (Cx,IL,CL):
-
-    .  (Cx is NULL) implies IL = {}.
-          
-       .  If Cx is a class, IL is the set of loaders that have been
-          recorded as initiating loaders for Cx. IL may be the
-          empty set {} in case Cx has already been defined but no
-          initiating loader has been recorded, yet.
-  
-    .  (IL u CL) is a subset of an equivalence class of ~N~.
-
-                (This means that all loaders in IL and CL must resolve
-                the name N to the same class.)
-
-  The following holds for the set of tuples { (Cx,IL,CL) }:
-
-    .  For a given class C there is at most one tuple with Cx = C
-          in the set. (There may be an arbitrary number of tuples
-          with Cx = NULL, however.)
-
-       .  For a given loader L there is at most one tuple with
-          L in (IL u CL).
-
-  The implementation stores sets of loaders as linked lists of
-  `classcache_loader_entry`s.
-
-  Comments about manipulating the classcache can be found in the
-  individual functions below.
-*************************************************************************/
-
-
-/* initial number of slots in the classcache hash table */
-#define CLASSCACHE_INIT_SIZE  2048
-
-/*============================================================================*/
-/* DEBUG HELPERS                                                              */
-/*============================================================================*/
-
-/* #define CLASSCACHE_VERBOSE */
-
-/*============================================================================*/
-/* STATISTICS                                                                 */
-/*============================================================================*/
-
-/*#define CLASSCACHE_STATS*/
-
-#ifdef CLASSCACHE_STATS
-static int stat_classnames_stored = 0;
-static int stat_classes_stored = 0;
-static int stat_trivial_constraints = 0;
-static int stat_nontriv_constraints = 0;
-static int stat_nontriv_constraints_both = 0;
-static int stat_nontriv_constraints_merged = 0;
-static int stat_nontriv_constraints_one = 0;
-static int stat_nontriv_constraints_none = 0;
-static int stat_new_loader_entry = 0;
-static int stat_merge_class_entries = 0;
-static int stat_merge_loader_entries = 0;
-static int stat_lookup = 0;
-static int stat_lookup_class_entry_checked = 0;
-static int stat_lookup_loader_checked = 0;
-static int stat_lookup_name = 0;
-static int stat_lookup_name_entry = 0;
-static int stat_lookup_name_notfound = 0;
-static int stat_lookup_new_name = 0;
-static int stat_lookup_new_name_entry = 0;
-static int stat_lookup_new_name_collisions = 0;
-static int stat_rehash_names = 0;
-static int stat_rehash_names_collisions = 0;
-
-#define CLASSCACHE_COUNT(cnt)  (cnt)++
-#define CLASSCACHE_COUNTIF(cond,cnt)  do{if(cond) (cnt)++;} while(0)
-
-void classcache_print_statistics(FILE *file) {
-       fprintf(file,"classnames stored   : %8d\n",stat_classnames_stored);
-       fprintf(file,"classes stored      : %8d\n",stat_classes_stored);
-       fprintf(file,"trivial constraints : %8d\n",stat_trivial_constraints);
-       fprintf(file,"non-triv constraints: %8d\n",stat_nontriv_constraints);
-       fprintf(file,"   both loaders rec.: %8d\n",stat_nontriv_constraints_both);
-       fprintf(file,"       merged       : %8d\n",stat_nontriv_constraints_merged);
-       fprintf(file,"   one loader rec.  : %8d\n",stat_nontriv_constraints_one);
-       fprintf(file,"   no loaders rec.  : %8d\n",stat_nontriv_constraints_none);
-       fprintf(file,"new loader entries  : %8d\n",stat_new_loader_entry);
-       fprintf(file,"merge class entries : %8d\n",stat_merge_class_entries);
-       fprintf(file,"merge loader entries: %8d\n",stat_merge_loader_entries);
-       fprintf(file,"lookups             : %8d\n",stat_lookup);
-       fprintf(file,"   class entries ckd: %8d\n",stat_lookup_class_entry_checked);
-       fprintf(file,"   loader checked   : %8d\n",stat_lookup_loader_checked);
-       fprintf(file,"lookup name         : %8d\n",stat_lookup_name);
-       fprintf(file,"   entries checked  : %8d\n",stat_lookup_name_entry);
-       fprintf(file,"   not found        : %8d\n",stat_lookup_name_notfound);
-       fprintf(file,"lookup (new) name   : %8d\n",stat_lookup_new_name);
-       fprintf(file,"   entries checked  : %8d\n",stat_lookup_new_name_entry);
-       fprintf(file,"   new collisions   : %8d\n",stat_lookup_new_name_collisions);
-       fprintf(file,"names rehashed      : %8d times\n",stat_rehash_names);
-       fprintf(file,"    collisions      : %8d\n",stat_rehash_names_collisions);
-}
-#else
-#define CLASSCACHE_COUNT(cnt)
-#define CLASSCACHE_COUNTIF(cond,cnt)
-#endif
-
-/*============================================================================*/
-/* THREAD-SAFE LOCKING                                                        */
-/*============================================================================*/
-
-       /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-       /* CAUTION: The static functions below are */
-       /*          NOT synchronized!              */
-       /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-#if defined(ENABLE_THREADS)
-# define CLASSCACHE_LOCK()      LOCK_MONITOR_ENTER(lock_hashtable_classcache)
-# define CLASSCACHE_UNLOCK()    LOCK_MONITOR_EXIT(lock_hashtable_classcache)
-#else
-# define CLASSCACHE_LOCK()
-# define CLASSCACHE_UNLOCK()
-#endif
-
-/*============================================================================*/
-/* GLOBAL VARIABLES                                                           */
-/*============================================================================*/
-
-hashtable hashtable_classcache;
-
-#if defined(ENABLE_THREADS)
-static java_object_t *lock_hashtable_classcache;
-#endif
-
-
-/*============================================================================*/
-/*                                                                            */
-/*============================================================================*/
-
-/* prototypes */
-
-static void classcache_free_class_entry(classcache_class_entry *clsen);
-static void classcache_remove_class_entry(classcache_name_entry *en,
-                                                                                 classcache_class_entry *clsen);
-
-/* hash function to use */
-
-#define CLASSCACHE_HASH utf_full_hashkey
-
-/* classcache_init *************************************************************
-   Initialize the class cache
-
-   Note: NOT synchronized!
-  
-*******************************************************************************/
-
-bool classcache_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("classcache_init");
-
-       /* create the hashtable */
-
-       hashtable_create(&hashtable_classcache, CLASSCACHE_INIT_SIZE);
-
-#if defined(ENABLE_THREADS)
-       /* create utf hashtable lock object */
-
-       lock_hashtable_classcache = NEW(java_object_t);
-
-       LOCK_INIT_OBJECT_LOCK(lock_hashtable_classcache);
-#endif
-
-       /* everything's ok */
-
-       return true;
-}
-
-/* classcache_new_loader_entry *************************************************
-   Create a new classcache_loader_entry struct
-   (internally used helper function)
-  
-   IN:
-       loader...........the ClassLoader object
-          next.............the next classcache_loader_entry
-
-   RETURN VALUE:
-       the new classcache_loader_entry
-  
-*******************************************************************************/
-
-static classcache_loader_entry * classcache_new_loader_entry(
-                                                                       classloader_t * loader,
-                                                                       classcache_loader_entry * next)
-{
-       classcache_loader_entry *lden;
-
-       lden = NEW(classcache_loader_entry);
-       lden->loader = loader;
-       lden->next = next;
-       CLASSCACHE_COUNT(stat_new_loader_entry);
-
-       return lden;
-}
-
-/* classcache_merge_loaders ****************************************************
-   Merge two lists of loaders into one
-   (internally used helper function)
-  
-   IN:
-       lista............first list (may be NULL)
-          listb............second list (may be NULL)
-
-   RETURN VALUE:
-       the merged list (may be NULL)
-
-   NOTE:
-       The lists given as arguments are destroyed!
-  
-*******************************************************************************/
-
-static classcache_loader_entry * classcache_merge_loaders(
-                                                                       classcache_loader_entry * lista,
-                                                                       classcache_loader_entry * listb)
-{
-       classcache_loader_entry *result;
-       classcache_loader_entry *ldenA;
-       classcache_loader_entry *ldenB;
-       classcache_loader_entry **chain;
-
-       CLASSCACHE_COUNT(stat_merge_loader_entries);
-
-       /* XXX This is a quadratic algorithm. If this ever
-        * becomes a problem, the loader lists should be
-        * stored as sorted lists and merged in linear time. */
-
-       result = NULL;
-       chain = &result;
-
-       for (ldenA = lista; ldenA; ldenA = ldenA->next) {
-
-               for (ldenB = listb; ldenB; ldenB = ldenB->next) {
-                       if (ldenB->loader == ldenA->loader)
-                               goto common_element;
-               }
-
-               /* this loader is only in lista */
-               *chain = ldenA;
-               chain = &(ldenA->next);
-
-         common_element:
-               /* XXX free the duplicated element */
-               ;
-       }
-
-       /* concat listb to the result */
-       *chain = listb;
-
-       return result;
-}
-
-/* classcache_merge_class_entries **********************************************
-   Merge two `classcache_class_entry`s into one.
-   (internally used helper function)
-  
-   IN:
-       en...............the classcache_name_entry containing both class entries
-       clsenA...........first class entry, will receive the result
-          clsenB...........second class entry
-
-   PRE-CONDITION:
-       Either both entries must have the same classobj, or one of them has
-          classobj == NULL.
-
-   NOTE:
-       clsenB is freed by this function!
-  
-*******************************************************************************/
-
-static void classcache_merge_class_entries(classcache_name_entry *en,
-                                                                                  classcache_class_entry *clsenA,
-                                                                                  classcache_class_entry *clsenB)
-{
-#ifdef CLASSCACHE_VERBOSE
-       char logbuffer[1024];
-#endif
-       
-       assert(en);
-       assert(clsenA);
-       assert(clsenB);
-       assert(!clsenA->classobj || !clsenB->classobj || clsenA->classobj == clsenB->classobj);
-
-#ifdef CLASSCACHE_VERBOSE
-       sprintf(logbuffer,"classcache_merge_class_entries(%p,%p->%p,%p->%p) ", 
-                       (void*)en,(void*)clsenA,(void*)clsenA->classobj,(void*)clsenB,(void*)clsenB->classobj);
-       if (clsenA->classobj)
-               utf_cat_classname(logbuffer, clsenA->classobj->name);
-       if (clsenB->classobj)
-               utf_cat_classname(logbuffer, clsenB->classobj->name);
-       log_println(logbuffer);
-#endif
-
-       CLASSCACHE_COUNT(stat_merge_class_entries);
-
-       /* clsenB will be merged into clsenA */
-       clsenA->loaders = classcache_merge_loaders(clsenA->loaders, clsenB->loaders);
-       clsenB->loaders = NULL; /* these have been freed or reused */
-
-       clsenA->constraints = classcache_merge_loaders(clsenA->constraints,
-                                                                                                  clsenB->constraints);
-       clsenB->constraints = NULL; /* these have been freed or reused */
-
-       if (!clsenA->classobj)
-               clsenA->classobj = clsenB->classobj;
-
-       /* remove clsenB from the list of class entries */
-       classcache_remove_class_entry(en, clsenB);
-}
-
-
-/* classcache_lookup_name ******************************************************
-   Lookup a name in the first level of the cache
-   (internally used helper function)
-   
-   IN:
-       name.............the name to look up
-  
-   RETURN VALUE:
-       a pointer to the classcache_name_entry for this name, or
-       null if no entry was found.
-          
-*******************************************************************************/
-
-static classcache_name_entry *classcache_lookup_name(utf *name)
-{
-       classcache_name_entry *c;           /* hash table element                 */
-       u4 key;                             /* hashkey computed from classname    */
-       u4 slot;                            /* slot in hashtable                  */
-
-       CLASSCACHE_COUNT(stat_lookup_name);
-
-       key  = CLASSCACHE_HASH(name->text, (u4) name->blength);
-       slot = key & (hashtable_classcache.size - 1);
-       c    = hashtable_classcache.ptr[slot];
-
-       /* search external hash chain for the entry */
-
-       while (c) {
-               /* entry found in hashtable */
-               CLASSCACHE_COUNT(stat_lookup_name_entry);
-
-               if (c->name == name)
-                       return c;
-
-               c = c->hashlink;                    /* next element in external chain */
-       }
-
-       /* not found */
-
-       CLASSCACHE_COUNT(stat_lookup_name_notfound);
-       return NULL;
-}
-
-
-/* classcache_new_name *********************************************************
-   Return a classcache_name_entry for the given name. The entry is created
-   if it is not already in the cache.
-   (internally used helper function)
-   
-   IN:
-       name.............the name to look up / create an entry for
-  
-   RETURN VALUE:
-       a pointer to the classcache_name_entry for this name
-          
-*******************************************************************************/
-
-static classcache_name_entry *classcache_new_name(utf *name)
-{
-       classcache_name_entry *c;       /* hash table element */
-       u4 key;                                         /* hashkey computed from classname */
-       u4 slot;                                        /* slot in hashtable               */
-       u4 i;
-
-       CLASSCACHE_COUNT(stat_lookup_new_name);
-
-       key  = CLASSCACHE_HASH(name->text, (u4) name->blength);
-       slot = key & (hashtable_classcache.size - 1);
-       c    = hashtable_classcache.ptr[slot];
-
-       /* search external hash chain for the entry */
-
-       while (c) {
-               /* entry found in hashtable */
-               CLASSCACHE_COUNT(stat_lookup_new_name_entry);
-
-               if (c->name == name)
-                       return c;
-
-               c = c->hashlink;                    /* next element in external chain */
-       }
-
-       /* location in hashtable found, create new entry */
-
-       c = NEW(classcache_name_entry);
-
-       c->name = name;
-       c->classes = NULL;
-
-       /* insert entry into hashtable */
-       c->hashlink = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-       CLASSCACHE_COUNTIF(c->hashlink,stat_lookup_new_name_collisions);
-       hashtable_classcache.ptr[slot] = c;
-
-       /* update number of hashtable-entries */
-       hashtable_classcache.entries++;
-       CLASSCACHE_COUNT(stat_classnames_stored);
-
-       if ((hashtable_classcache.entries*2) > hashtable_classcache.size) {
-               /* reorganization of hashtable */ 
-
-               classcache_name_entry *c2;
-               hashtable newhash;              /* the new hashtable */
-
-               CLASSCACHE_COUNT(stat_rehash_names);
-
-               /* create new hashtable, double the size */
-
-               hashtable_create(&newhash, hashtable_classcache.size * 2);
-               newhash.entries = hashtable_classcache.entries;
-
-               /* transfer elements to new hashtable */
-
-               for (i = 0; i < hashtable_classcache.size; i++) {
-                       c2 = (classcache_name_entry *) hashtable_classcache.ptr[i];
-                       while (c2) {
-                               classcache_name_entry *nextc = c2->hashlink;
-                               u4 newslot =
-                                       (CLASSCACHE_HASH(c2->name->text, (u4) c2->name->blength)) & (newhash.size - 1);
-
-                               c2->hashlink = (classcache_name_entry *) newhash.ptr[newslot];
-                               CLASSCACHE_COUNTIF(c2->hashlink,stat_rehash_names_collisions);
-                               newhash.ptr[newslot] = c2;
-
-                               c2 = nextc;
-                       }
-               }
-
-               /* dispose old table */
-
-               MFREE(hashtable_classcache.ptr, void *, hashtable_classcache.size);
-               hashtable_classcache = newhash;
-       }
-
-       return c;
-}
-
-
-/* classcache_lookup ***********************************************************
-   Lookup a possibly loaded class
-  
-   IN:
-       initloader.......initiating loader for resolving the class name
-       classname........class name to look up
-  
-   RETURN VALUE:
-       The return value is a pointer to the cached class object,
-       or NULL, if the class is not in the cache.
-
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-classinfo *classcache_lookup(classloader_t *initloader, utf *classname)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-       classcache_loader_entry *lden;
-       classinfo *cls = NULL;
-
-       CLASSCACHE_LOCK();
-
-       CLASSCACHE_COUNT(stat_lookup);
-       en = classcache_lookup_name(classname);
-
-       if (en) {
-               /* iterate over all class entries */
-
-               for (clsen = en->classes; clsen; clsen = clsen->next) {
-                       CLASSCACHE_COUNT(stat_lookup_class_entry_checked);
-                       /* check if this entry has been loaded by initloader */
-
-                       for (lden = clsen->loaders; lden; lden = lden->next) {
-                               CLASSCACHE_COUNT(stat_lookup_loader_checked);
-                               if (lden->loader == initloader) {
-                                       /* found the loaded class entry */
-
-                                       assert(clsen->classobj);
-                                       cls = clsen->classobj;
-                                       goto found;
-                               }
-                       }
-               }
-       }
-
-  found:
-       CLASSCACHE_UNLOCK();
-       return cls;
-}
-
-
-/* classcache_lookup_defined ***************************************************
-   Lookup a class with the given name and defining loader
-  
-   IN:
-       defloader........defining loader
-       classname........class name
-  
-   RETURN VALUE:
-       The return value is a pointer to the cached class object,
-       or NULL, if the class is not in the cache.
-   
-*******************************************************************************/
-
-classinfo *classcache_lookup_defined(classloader_t *defloader, utf *classname)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-       classinfo *cls = NULL;
-
-       CLASSCACHE_LOCK();
-
-       en = classcache_lookup_name(classname);
-
-       if (en) {
-               /* iterate over all class entries */
-               for (clsen = en->classes; clsen; clsen = clsen->next) {
-                       if (!clsen->classobj)
-                               continue;
-
-                       /* check if this entry has been defined by defloader */
-                       if (clsen->classobj->classloader == defloader) {
-                               cls = clsen->classobj;
-                               goto found;
-                       }
-               }
-       }
-
-  found:
-       CLASSCACHE_UNLOCK();
-       return cls;
-}
-
-
-/* classcache_lookup_defined_or_initiated **************************************
-   Lookup a class that has been defined or initiated by the given loader
-  
-   IN:
-       loader...........defining or initiating loader
-       classname........class name to look up
-  
-   RETURN VALUE:
-       The return value is a pointer to the cached class object,
-       or NULL, if the class is not in the cache.
-
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-classinfo *classcache_lookup_defined_or_initiated(classloader_t *loader, 
-                                                                                                 utf *classname)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-       classcache_loader_entry *lden;
-       classinfo *cls = NULL;
-
-       CLASSCACHE_LOCK();
-
-       en = classcache_lookup_name(classname);
-
-       if (en) {
-               /* iterate over all class entries */
-
-               for (clsen = en->classes; clsen; clsen = clsen->next) {
-
-                       /* check if this entry has been defined by loader */
-                       if (clsen->classobj && clsen->classobj->classloader == loader) {
-                               cls = clsen->classobj;
-                               goto found;
-                       }
-                       
-                       /* check if this entry has been initiated by loader */
-                       for (lden = clsen->loaders; lden; lden = lden->next) {
-                               if (lden->loader == loader) {
-                                       /* found the loaded class entry */
-
-                                       assert(clsen->classobj);
-                                       cls = clsen->classobj;
-                                       goto found;
-                               }
-                       }
-               }
-       }
-
-  found:
-       CLASSCACHE_UNLOCK();
-       return cls;
-}
-
-
-/* classcache_store ************************************************************
-   
-   Store a loaded class. If a class of the same name has already been stored
-   with the same initiating loader, then the given class CLS is freed (if
-   possible) and the previously stored class is returned.
-  
-   IN:
-       initloader.......initiating loader used to load the class
-                           (may be NULL indicating the bootstrap loader)
-       cls..............class object to cache
-          mayfree..........true if CLS may be freed in case another class is
-                           returned
-  
-   RETURN VALUE:
-       cls..............everything ok, the class was stored in the cache,
-          other classinfo..another class with the same (initloader,name) has been
-                           stored earlier. CLS has been freed[1] and the earlier
-                                               stored class is returned.
-       NULL.............an exception has been thrown.
-   
-   Note: synchronized with global tablelock
-
-   [1]...in case MAYFREE is true
-   
-*******************************************************************************/
-
-classinfo *classcache_store(classloader_t *initloader, classinfo *cls,
-                                                       bool mayfree)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-       classcache_class_entry *clsenB;
-       classcache_loader_entry *lden;
-#ifdef CLASSCACHE_VERBOSE
-       char logbuffer[1024];
-#endif
-       
-       assert(cls);
-       assert(cls->state & CLASS_LOADED);
-
-       CLASSCACHE_LOCK();
-
-#ifdef CLASSCACHE_VERBOSE
-       sprintf(logbuffer,"classcache_store (%p,%d,%p=", (void*)initloader,mayfree,(void*)cls);
-       utf_cat_classname(logbuffer, cls->name);
-       strcat(logbuffer,")");
-       log_println(logbuffer);
-#endif
-
-       en = classcache_new_name(cls->name);
-
-       assert(en);
-
-       /* iterate over all class entries */
-       for (clsen = en->classes; clsen; clsen = clsen->next) {
-
-               /* check if this entry has already been loaded by initloader */
-               for (lden = clsen->loaders; lden; lden = lden->next) {
-                       if (lden->loader == initloader) {
-                          if (clsen->classobj != cls) {
-                                       /* A class with the same (initloader,name) pair has been stored already. */
-                                       /* We free the given class and return the earlier one.                   */
-#ifdef CLASSCACHE_VERBOSE
-                                       log_println("replacing %p with earlier loaded class %p",cls,clsen->classobj);
-#endif
-                                       assert(clsen->classobj);
-                                       if (mayfree)
-                                               class_free(cls);
-                                       cls = clsen->classobj;
-                          }
-                          goto return_success;
-                       }
-               }
-
-               /* {This entry has not been resolved with initloader} */
-
-               /* check if initloader is constrained to this entry */
-               for (lden = clsen->constraints; lden; lden = lden->next) {
-                       if (lden->loader == initloader) {
-                               /* we have to use this entry. check if it has been resolved */
-                               if (clsen->classobj) {
-                                       /* check if is has already been resolved to another class */
-                                       if (clsen->classobj != cls) {
-                                               /* a loading constraint is violated */
-                                               exceptions_throw_linkageerror("loading constraint violated: ", cls);
-                                               goto return_exception;
-                                       }
-
-                                       /* record initloader as initiating loader */
-                                       clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
-                                       goto return_success;
-                               }
-
-                               /* {this is the first resolution for this entry} */
-                               /* record initloader as initiating loader */
-                               clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
-
-                               /* maybe we can merge this entry with another one */
-                               for (clsenB = en->classes; clsenB; clsenB = clsenB->next) {
-                                       /* we dont want the entry that we have already */
-                                       if (clsenB->classobj == cls) {
-                                               /* this entry has the same classobj. let's merge them */
-                                               classcache_merge_class_entries(en,clsen,clsenB);
-                                               goto return_success;
-                                       }
-                               }
-
-                               /* record the loaded class object */
-                               clsen->classobj = cls;
-                               CLASSCACHE_COUNT(stat_classes_stored);
-
-                               /* done */
-                               goto return_success;
-                       }
-               }
-
-       }
-
-       /* {There is no class entry containing initloader as initiating 
-        *  or constrained loader.} */
-
-       /* we look for a class entry with the same classobj we want to store */
-       for (clsen = en->classes; clsen; clsen = clsen->next) {
-               if (clsen->classobj == cls) {
-                       /* this entry is about the same classobj. let's use it */
-                       /* check if this entry has already been loaded by initloader */
-                       for (lden = clsen->loaders; lden; lden = lden->next) {
-                               if (lden->loader == initloader)
-                                       goto return_success;
-                       }
-                       clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
-                       goto return_success;
-               }
-       }
-
-       /* create a new class entry for this class object with */
-       /* initiating loader initloader                        */
-
-       clsen = NEW(classcache_class_entry);
-       clsen->classobj = cls;
-       clsen->loaders = classcache_new_loader_entry(initloader, NULL);
-       clsen->constraints = NULL;
-
-       clsen->next = en->classes;
-       en->classes = clsen;
-       CLASSCACHE_COUNT(stat_classes_stored);
-
-  return_success:
-#ifdef CLASSCACHE_VERBOSE
-       classcache_debug_dump(stdout,cls->name);
-#endif
-       CLASSCACHE_UNLOCK();
-       return cls;
-
-  return_exception:
-       CLASSCACHE_UNLOCK();
-       return NULL;                            /* exception */
-}
-
-/* classcache_store_unique *****************************************************
-   
-   Store a loaded class as loaded by the bootstrap loader. This is a wrapper 
-   aroung classcache_store that throws an exception if a class with the same 
-   name has already been loaded by the bootstrap loader.
-
-   This function is used to register a few special classes during startup.
-   It should not be used otherwise.
-  
-   IN:
-       cls..............class object to cache
-  
-   RETURN VALUE:
-       true.............everything ok, the class was stored.
-       false............an exception has been thrown.
-   
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-bool classcache_store_unique(classinfo *cls)
-{
-       classinfo *result;
-
-       result = classcache_store(NULL,cls,false);
-       if (result == NULL)
-               return false;
-
-       if (result != cls) {
-               exceptions_throw_internalerror("class already stored in the class cache");
-               return false;
-       }
-
-       return true;
-}
-
-/* classcache_store_defined ****************************************************
-   
-   Store a loaded class after it has been defined. If the class has already
-   been defined by the same defining loader in another thread, free the given
-   class and returned the one which has been defined earlier.
-  
-   IN:
-       cls..............class object to store. classloader must be set
-                           (classloader may be NULL, for bootloader)
-  
-   RETURN VALUE:
-       cls..............everything ok, the class was stored the cache,
-          other classinfo..the class had already been defined, CLS was freed, the
-                           class which was defined earlier is returned,
-       NULL.............an exception has been thrown.
-   
-*******************************************************************************/
-
-classinfo *classcache_store_defined(classinfo *cls)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-#ifdef CLASSCACHE_VERBOSE
-       char logbuffer[1024];
-#endif
-
-       assert(cls);
-       assert(cls->state & CLASS_LOADED);
-
-       CLASSCACHE_LOCK();
-
-#ifdef CLASSCACHE_VERBOSE
-       sprintf(logbuffer,"classcache_store_defined (%p,", (void*)cls->classloader);
-       utf_cat_classname(logbuffer, cls->name);
-       strcat(logbuffer,")");
-       log_println(logbuffer);
-#endif
-
-       en = classcache_new_name(cls->name);
-
-       assert(en);
-
-       /* iterate over all class entries */
-       for (clsen = en->classes; clsen; clsen = clsen->next) {
-               
-               /* check if this class has been defined by the same classloader */
-               if (clsen->classobj && clsen->classobj->classloader == cls->classloader) {
-                       /* we found an earlier definition, delete the newer one */
-                       /* (if it is a different classinfo)                     */
-                       if (clsen->classobj != cls) {
-#ifdef CLASSCACHE_VERBOSE
-                               log_println("replacing %p with earlier defined class %p",cls,clsen->classobj);
-#endif
-                               class_free(cls);
-                               cls = clsen->classobj;
-                       }
-                       goto return_success;
-               }
-       }
-
-       /* create a new class entry for this class object */
-       /* the list of initiating loaders is empty at this point */
-
-       clsen = NEW(classcache_class_entry);
-       clsen->classobj = cls;
-       clsen->loaders = NULL;
-       clsen->constraints = NULL;
-
-       clsen->next = en->classes;
-       en->classes = clsen;
-       CLASSCACHE_COUNT(stat_classes_stored);
-
-return_success:
-#ifdef CLASSCACHE_VERBOSE
-       classcache_debug_dump(stdout,cls->name);
-#endif
-       CLASSCACHE_UNLOCK();
-       return cls;
-}
-
-/* classcache_find_loader ******************************************************
-   Find the class entry loaded by or constrained to a given loader
-   (internally used helper function)
-  
-   IN:
-       entry............the classcache_name_entry
-       loader...........the loader to look for
-  
-   RETURN VALUE:
-       the classcache_class_entry for the given loader, or
-          NULL if no entry was found
-   
-*******************************************************************************/
-
-static classcache_class_entry * classcache_find_loader(
-                                                                       classcache_name_entry * entry,
-                                                                       classloader_t * loader)
-{
-       classcache_class_entry *clsen;
-       classcache_loader_entry *lden;
-
-       assert(entry);
-
-       /* iterate over all class entries */
-       for (clsen = entry->classes; clsen; clsen = clsen->next) {
-
-               /* check if this entry has already been loaded by initloader */
-               for (lden = clsen->loaders; lden; lden = lden->next) {
-                       if (lden->loader == loader)
-                               return clsen;   /* found */
-               }
-
-               /* check if loader is constrained to this entry */
-               for (lden = clsen->constraints; lden; lden = lden->next) {
-                       if (lden->loader == loader)
-                               return clsen;   /* found */
-               }
-       }
-
-       /* not found */
-       return NULL;
-}
-
-/* classcache_free_class_entry *************************************************
-   Free the memory used by a class entry
-  
-   IN:
-       clsen............the classcache_class_entry to free  
-          
-*******************************************************************************/
-
-static void classcache_free_class_entry(classcache_class_entry * clsen)
-{
-       classcache_loader_entry *lden;
-       classcache_loader_entry *next;
-
-       assert(clsen);
-
-       for (lden = clsen->loaders; lden; lden = next) {
-               next = lden->next;
-               FREE(lden, classcache_loader_entry);
-       }
-       for (lden = clsen->constraints; lden; lden = next) {
-               next = lden->next;
-               FREE(lden, classcache_loader_entry);
-       }
-
-       FREE(clsen, classcache_class_entry);
-}
-
-/* classcache_remove_class_entry ***********************************************
-   Remove a classcache_class_entry from the list of possible resolution of
-   a name entry
-   (internally used helper function)
-  
-   IN:
-       entry............the classcache_name_entry
-       clsen............the classcache_class_entry to remove
-  
-*******************************************************************************/
-
-static void classcache_remove_class_entry(classcache_name_entry * entry,
-                                                                                 classcache_class_entry * clsen)
-{
-       classcache_class_entry **chain;
-
-       assert(entry);
-       assert(clsen);
-
-       chain = &(entry->classes);
-       while (*chain) {
-               if (*chain == clsen) {
-                       *chain = clsen->next;
-                       classcache_free_class_entry(clsen);
-                       return;
-               }
-               chain = &((*chain)->next);
-       }
-}
-
-/* classcache_free_name_entry **************************************************
-   Free the memory used by a name entry
-  
-   IN:
-       entry............the classcache_name_entry to free  
-          
-*******************************************************************************/
-
-static void classcache_free_name_entry(classcache_name_entry * entry)
-{
-       classcache_class_entry *clsen;
-       classcache_class_entry *next;
-
-       assert(entry);
-
-       for (clsen = entry->classes; clsen; clsen = next) {
-               next = clsen->next;
-               classcache_free_class_entry(clsen);
-       }
-
-       FREE(entry, classcache_name_entry);
-}
-
-/* classcache_free *************************************************************
-   Free the memory used by the class cache
-
-   NOTE:
-       The class cache may not be used any more after this call, except
-          when it is reinitialized with classcache_init.
-  
-   Note: NOT synchronized!
-  
-*******************************************************************************/
-
-void classcache_free(void)
-{
-       u4 slot;
-       classcache_name_entry *entry;
-       classcache_name_entry *next;
-
-       for (slot = 0; slot < hashtable_classcache.size; ++slot) {
-               for (entry = (classcache_name_entry *) hashtable_classcache.ptr[slot]; entry; entry = next) {
-                       next = entry->hashlink;
-                       classcache_free_name_entry(entry);
-               }
-       }
-
-       MFREE(hashtable_classcache.ptr, voidptr, hashtable_classcache.size);
-       hashtable_classcache.size = 0;
-       hashtable_classcache.entries = 0;
-       hashtable_classcache.ptr = NULL;
-}
-
-/* classcache_add_constraint ***************************************************
-   Add a loading constraint
-  
-   IN:
-       a................first initiating loader
-       b................second initiating loader
-       classname........class name
-  
-   RETURN VALUE:
-       true.............everything ok, the constraint has been added,
-       false............an exception has been thrown.
-   
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool classcache_add_constraint(classloader_t * a,
-                                                          classloader_t * b,
-                                                          utf * classname)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsenA;
-       classcache_class_entry *clsenB;
-
-       assert(classname);
-
-#ifdef CLASSCACHE_VERBOSE
-       log_start();
-       log_print("classcache_add_constraint(%p,%p,", (void *) a, (void *) b);
-       utf_fprint_printable_ascii_classname(stdout, classname);
-       log_print(")\n");
-       log_finish();
-#endif
-
-       /* a constraint with a == b is trivially satisfied */
-       if (a == b) {
-               CLASSCACHE_COUNT(stat_trivial_constraints);
-               return true;
-       }
-
-       CLASSCACHE_LOCK();
-
-       en = classcache_new_name(classname);
-
-       assert(en);
-       CLASSCACHE_COUNT(stat_nontriv_constraints);
-
-       /* find the entry loaded by / constrained to each loader */
-       clsenA = classcache_find_loader(en, a);
-       clsenB = classcache_find_loader(en, b);
-
-       if (clsenA && clsenB) {
-               /* { both loaders have corresponding entries } */
-               CLASSCACHE_COUNT(stat_nontriv_constraints_both);
-
-               /* if the entries are the same, the constraint is already recorded */
-               if (clsenA == clsenB)
-                       goto return_success;
-
-               /* check if the entries can be merged */
-               if (clsenA->classobj && clsenB->classobj
-                       && clsenA->classobj != clsenB->classobj) {
-                       /* no, the constraint is violated */
-                       exceptions_throw_linkageerror("loading constraint violated: ",
-                                                                                 clsenA->classobj);
-                       goto return_exception;
-               }
-
-               /* yes, merge the entries */
-               classcache_merge_class_entries(en,clsenA,clsenB);
-               CLASSCACHE_COUNT(stat_nontriv_constraints_merged);
-       }
-       else {
-               /* { at most one of the loaders has a corresponding entry } */
-
-               /* set clsenA to the single class entry we have */
-               if (!clsenA)
-                       clsenA = clsenB;
-
-               if (!clsenA) {
-                       /* { no loader has a corresponding entry } */
-                       CLASSCACHE_COUNT(stat_nontriv_constraints_none);
-
-                       /* create a new class entry with the constraint (a,b,en->name) */
-                       clsenA = NEW(classcache_class_entry);
-                       clsenA->classobj = NULL;
-                       clsenA->loaders = NULL;
-                       clsenA->constraints = classcache_new_loader_entry(b, NULL);
-                       clsenA->constraints = classcache_new_loader_entry(a, clsenA->constraints);
-
-                       clsenA->next = en->classes;
-                       en->classes = clsenA;
-               }
-               else {
-                       CLASSCACHE_COUNT(stat_nontriv_constraints_one);
-
-                       /* make b the loader that has no corresponding entry */
-                       if (clsenB)
-                               b = a;
-
-                       /* loader b must be added to entry clsenA */
-                       clsenA->constraints = classcache_new_loader_entry(b, clsenA->constraints);
-               }
-       }
-
-  return_success:
-       CLASSCACHE_UNLOCK();
-       return true;
-
-  return_exception:
-       CLASSCACHE_UNLOCK();
-       return false;                           /* exception */
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-/* classcache_add_constraints_for_params ***************************************
-   Add loading constraints for the parameters and return type of 
-   the given method.
-  
-   IN:
-       a................first initiating loader
-       b................second initiating loader
-       m................methodinfo 
-  
-   RETURN VALUE:
-       true.............everything ok, the constraints have been added,
-       false............an exception has been thrown.
-   
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool classcache_add_constraints_for_params(classloader_t * a,
-                                                                                  classloader_t * b,
-                                                                                  methodinfo *m)
-{
-       methoddesc *md;
-       typedesc *td;
-       s4 i;
-
-       /* a constraint with a == b is trivially satisfied */
-
-       if (a == b) {
-               return true;
-       }
-
-       /* get the parsed descriptor */
-
-       assert(m);
-       md = m->parseddesc;
-       assert(md);
-
-       /* constrain the return type */
-
-       if (md->returntype.type == TYPE_ADR) {
-               if (!classcache_add_constraint(a, b, md->returntype.classref->name))
-                       return false; /* exception */
-       }
-
-       /* constrain each reference type used in the parameters */
-
-       td = md->paramtypes;
-       i = md->paramcount;
-       for (; i--; td++) {
-               if (td->type != TYPE_ADR)
-                       continue;
-
-               if (!classcache_add_constraint(a, b, td->classref->name))
-                       return false; /* exception */
-       }
-
-       /* everything ok */
-       return true;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-
-/* classcache_number_of_loaded_classes *****************************************
-
-   Counts the number of loaded classes and returns it.
-
-   Note: This function assumes that the CLASSCACHE_LOCK is held by the
-   caller!
-
-*******************************************************************************/
-
-static s4 classcache_number_of_loaded_classes(void)
-{
-       classcache_name_entry  *en;
-       classcache_class_entry *clsen;
-       s4                      number;
-       s4                      i;
-
-       /* initialize class counter */
-
-       number = 0;
-
-       for (i = 0; i < hashtable_classcache.size; i++) {
-               /* iterate over hashlink */
-
-               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
-                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
-
-                       if (en->name->text[0] == '$')
-                               continue;
-
-                       /* iterate over classes with same name */
-
-                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
-                               /* get only loaded classes */
-
-                               if (clsen->classobj != NULL)
-                                       number++;
-                       }
-               }
-       }
-
-       return number;
-}
-
-
-/* classcache_get_loaded_class_count *******************************************
-
-   Counts the number of loaded classes and returns it.
-
-*******************************************************************************/
-
-s4 classcache_get_loaded_class_count(void)
-{
-       s4 count;
-
-       CLASSCACHE_LOCK();
-
-       count = classcache_number_of_loaded_classes();
-       
-       CLASSCACHE_UNLOCK();
-
-       return count;
-}
-
-
-/* classcache_get_loaded_classes ***********************************************
-
-   Returns an array of all loaded classes as array.  The array is
-   allocaed on the Java heap.
-
-*******************************************************************************/
-
-#if defined(ENABLE_JVMTI)
-void classcache_get_loaded_classes(s4 *class_count_ptr,
-                                                                  classinfo ***classes_ptr)
-{
-       classinfo              **classes;
-       s4                       class_count;
-       classcache_name_entry   *en;
-       classcache_class_entry  *clsen;
-       s4                       i;
-       s4                       j;
-
-       CLASSCACHE_LOCK();
-
-       /* get the number of loaded classes and allocate the array */
-
-       class_count = classcache_number_of_loaded_classes();
-
-       classes = GCMNEW(classinfo*, class_count);
-
-       /* look in every slot of the hashtable */
-
-       for (i = 0, j = 0; i < hashtable_classcache.size; i++) {
-               /* iterate over hashlink */
-
-               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
-                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
-
-                       if (en->name->text[0] == '$')
-                               continue;
-
-                       /* iterate over classes with same name */
-
-                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
-                               /* get only loaded classes */
-
-                               if (clsen->classobj != NULL) {
-                                       classes[j] = clsen->classobj;
-                                       j++;
-                               }
-                       }
-               }
-       }
-
-       /* pass the return values */
-
-       *class_count_ptr = class_count;
-       *classes_ptr     = classes;
-
-       CLASSCACHE_UNLOCK();
-}
-#endif /* defined(ENABLE_JVMTI) */
-
-
-/* classcache_foreach_loaded_class *********************************************
-
-   Calls the given function for each loaded class.
-
-*******************************************************************************/
-
-void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func,
-                                                                        void *data)
-{
-       classcache_name_entry   *en;
-       classcache_class_entry  *clsen;
-       s4                       i;
-
-       CLASSCACHE_LOCK();
-
-       /* look in every slot of the hashtable */
-
-       for (i = 0; i < hashtable_classcache.size; i++) {
-               /* iterate over hashlink */
-
-               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
-                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
-
-                       if (en->name->text[0] == '$')
-                               continue;
-
-                       /* iterate over classes with same name */
-
-                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
-                               /* get only loaded classes */
-
-                               if (clsen->classobj != NULL) {
-                                       (*func)(clsen->classobj, data);
-                               }
-                       }
-               }
-       }
-
-       CLASSCACHE_UNLOCK();
-}
-
-
-/*============================================================================*/
-/* DEBUG DUMPS                                                                */
-/*============================================================================*/
-
-/* classcache_debug_dump *******************************************************
-   Print the contents of the loaded class cache to a stream
-  
-   IN:
-       file.............output stream
-          only.............if != NULL, only print entries for this name
-                           (Currently we print also the rest of the hash chain to
-                                                get a feel for the average length of hash chains.)
-  
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-#ifndef NDEBUG
-void classcache_debug_dump(FILE * file,utf *only)
-{
-       classcache_name_entry *c;
-       classcache_class_entry *clsen;
-       classcache_loader_entry *lden;
-       u4 slot;
-
-       CLASSCACHE_LOCK();
-
-       log_println("=== [loaded class cache] =====================================");
-       log_println("hash size   : %d", (int) hashtable_classcache.size);
-       log_println("hash entries: %d", (int) hashtable_classcache.entries);
-       log_println("");
-
-       if (only) {
-               c = classcache_lookup_name(only);
-               slot = 0; /* avoid compiler warning */
-               goto dump_it;
-       }
-
-       for (slot = 0; slot < hashtable_classcache.size; ++slot) {
-               c = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-
-dump_it:
-               for (; c; c = c->hashlink) {
-                       utf_fprint_printable_ascii_classname(file, c->name);
-                       fprintf(file, "\n");
-
-                       /* iterate over all class entries */
-                       for (clsen = c->classes; clsen; clsen = clsen->next) {
-                               if (clsen->classobj) {
-                                       log_println("    loaded %p", (void *) clsen->classobj);
-                               }
-                               else {
-                                       log_println("    unresolved");
-                               }
-
-                               log_start();
-                               log_print("        loaders: ");
-                               for (lden = clsen->loaders; lden; lden = lden->next) {
-                                       log_print("<%p> %p ", (void *) lden, (void *) lden->loader);
-                               }
-                               log_finish();
-
-                               log_start();
-                               log_print("        constraints: ");
-                               for (lden = clsen->constraints; lden; lden = lden->next) {
-                                       log_print("<%p> %p ", (void *) lden, (void *) lden->loader);
-                               }
-                               log_finish();
-                       }
-               }
-
-               if (only)
-                       break;
-       }
-       fprintf(file, "\n==============================================================\n\n");
-
-       CLASSCACHE_UNLOCK();
-}
-#endif /* 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/vmcore/classcache.h b/src/vmcore/classcache.h
deleted file mode 100644 (file)
index bbdba5c..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/* src/vmcore/classcache.h - loaded class cache and loading constraints
-
-   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 _CLASSCACHE_H
-#define _CLASSCACHE_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include <stdio.h>  /* for FILE */
-
-#if defined(ENABLE_JVMTI)
-# include "native/jni.h"
-#endif
-
-#include "toolbox/hashtable.h"
-
-#include "vm/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/references.h"
-
-
-/* forward declarations *******************************************************/
-
-typedef struct classcache_name_entry classcache_name_entry;
-typedef struct classcache_class_entry classcache_class_entry;
-typedef struct classcache_loader_entry classcache_loader_entry;
-
-/* global variables ***********************************************************/
-
-extern hashtable hashtable_classcache;
-
-
-/* structs ********************************************************************/
-
-/*----------------------------------------------------------------------------*/
-/* The Loaded Class Cache                                                     */
-/*                                                                            */
-/* The loaded class cache is implemented as a two-level data structure.       */
-/*                                                                            */
-/* The first level is a hash table indexed by class names. For each class     */
-/* name in the cache there is a classcache_name_entry, which collects all     */
-/* information about classes with this class name.                            */
-/*                                                                            */
-/* Second level: For each classcache_name_entry there is a list of            */
-/* classcache_class_entry:s representing the possible different resolutions   */
-/* of the class name.                                                         */
-/*                                                                            */
-/* A classcache_class_entry records the following:                            */
-/*                                                                            */
-/* - the loaded class object, if this entry has been resolved, otherwise NULL */
-/* - the list of initiating loaders which have resolved the class name to     */
-/*   this class object                                                        */
-/* - the list of initiating loaders which are constrained to resolve this     */
-/*   class name to this class object in the future                            */
-/*                                                                            */
-/* The classcache_class_entry:s approximate the equivalence classes created   */
-/* by the loading constraints and the equivalence of loaded classes.          */
-/*                                                                            */
-/* When a loading constraint (loaderA,loaderB,NAME) is added, then the        */
-/* classcache_class_entry:s for NAME containing loaderA and loaderB resp.     */
-/* must be merged into one entry. If this is impossible, because the entries  */
-/* have already been resolved to different class objects, then the constraint */
-/* is violated and an expception must be thrown.                              */
-/*----------------------------------------------------------------------------*/
-
-
-/* classcache_name_entry
- *
- * For each classname a classcache_name_entry struct is created.
- */
-
-struct classcache_name_entry
-{
-       utf                     *name;        /* class name                       */
-       classcache_name_entry   *hashlink;    /* link for external chaining       */
-       classcache_class_entry  *classes;     /* equivalence classes for this name*/
-};
-
-struct classcache_class_entry
-{
-       classinfo               *classobj;    /* the loaded class object, or NULL */
-       classcache_loader_entry *loaders;
-       classcache_loader_entry *constraints;
-       classcache_class_entry  *next;        /* next class entry for same name   */
-};
-
-struct classcache_loader_entry
-{
-       classloader_t            *loader;     /* class loader object              */
-       classcache_loader_entry  *next;       /* next loader entry in the list    */
-};
-
-
-/* callback function type for  classcache_foreach_loaded_class */
-
-typedef void (*classcache_foreach_functionptr_t)(classinfo *, void *);
-
-
-/* function prototypes ********************************************************/
-
-/* initialize the loaded class cache */
-bool classcache_init(void);
-void classcache_free(void);
-
-classinfo * classcache_lookup(classloader_t *initloader,utf *classname);
-classinfo * classcache_lookup_defined(classloader_t *defloader,utf *classname);
-classinfo * classcache_lookup_defined_or_initiated(classloader_t *loader,utf *classname);
-
-bool classcache_store_unique(classinfo *cls);
-classinfo * classcache_store(classloader_t *initloader,classinfo *cls,bool mayfree);
-classinfo * classcache_store_defined(classinfo *cls);
-
-#if defined(ENABLE_VERIFIER)
-bool classcache_add_constraint(classloader_t *a,classloader_t *b,utf *classname);
-bool classcache_add_constraints_for_params(classloader_t *a,classloader_t *b,
-                                                                                  methodinfo *m);
-#endif
-
-s4 classcache_get_loaded_class_count(void);
-
-void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func,
-                                                                        void *data);
-
-#if defined(ENABLE_JVMTI)
-void classcache_get_loaded_classes(s4 *class_count_ptr,
-                                                                  classinfo ***classes_ptr);
-#endif
-
-#ifndef NDEBUG
-void classcache_debug_dump(FILE *file,utf *only);
-#endif
-       
-#endif /* _CLASSCACHE_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/vmcore/descriptor.c b/src/vmcore/descriptor.c
deleted file mode 100644 (file)
index f49e050..0000000
+++ /dev/null
@@ -1,1398 +0,0 @@
-/* src/vmcore/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/exceptions.h"
-#include "vm/jit_interface.h"
-#include "vm/primitive.h"
-#include "vm/vm.h"
-
-#include "vmcore/descriptor.h"
-#include "vmcore/options.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->decltype = 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->decltype = PRIMITIVETYPE_BYTE;
-                       td->type = TYPE_INT;
-                       break;
-               case 'C':
-                       td->decltype = PRIMITIVETYPE_CHAR;
-                       td->type = TYPE_INT;
-                       break;
-               case 'S':  
-                       td->decltype = PRIMITIVETYPE_SHORT;
-                       td->type = TYPE_INT;
-                       break;
-               case 'Z':
-                       td->decltype = PRIMITIVETYPE_BOOLEAN;
-                       td->type = TYPE_INT;
-                       break;
-               case 'I':
-                       td->decltype = PRIMITIVETYPE_INT;
-                       td->type = TYPE_INT;
-                       break;
-               case 'D':
-                       td->decltype = PRIMITIVETYPE_DOUBLE;
-                       td->type = TYPE_DBL;
-                       break;
-               case 'F':
-                       td->decltype = PRIMITIVETYPE_FLOAT;
-                       td->type = TYPE_FLT;
-                       break;
-               case 'J':
-                       td->decltype = PRIMITIVETYPE_LONG;
-                       td->type = TYPE_LNG;
-                       break;
-               case 'V':
-                       td->decltype = 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(voidptr,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(voidptr,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->decltype = 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->decltype = 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->decltype) {
-                       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(voidptr)) {
-                               fprintf(file,"    %p\n",*((voidptr*)pos));
-                               pos += sizeof(voidptr);
-                               size -= sizeof(voidptr);
-                       }
-               }
-       }
-
-       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/vmcore/descriptor.h b/src/vmcore/descriptor.h
deleted file mode 100644 (file)
index dae43e7..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/* src/vmcore/descriptor.h - checking and parsing of field / method descriptors
-
-   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
-
-   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/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/references.h"
-#include "vmcore/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                 decltype;   /* (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 decltype field contains the declared type.                       */
-/*       So short is PRIMITIVETYPE_SHORT, char is PRIMITIVETYPE_CHAR.         */
-/*       For non-primitive types decltype 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 ********************************************************/
-
-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) */
-
-#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/vmcore/field.c b/src/vmcore/field.c
deleted file mode 100644 (file)
index 00c0680..0000000
+++ /dev/null
@@ -1,562 +0,0 @@
-/* src/vmcore/field.c - field functions
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "vm/types.h"
-
-#include "vm/array.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/primitive.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/annotation.h"
-#include "vmcore/class.h"
-#include "vmcore/descriptor.h"
-#include "vmcore/field.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/references.h"
-#include "vmcore/suck.h"
-#include "vmcore/utf8.h"
-
-
-/* field_load ******************************************************************
-
-   Load everything about a class field from the class file and fill a
-   fieldinfo structure.
-
-*******************************************************************************/
-
-#define field_load_NOVALUE  0xffffffff /* must be bigger than any u2 value! */
-
-bool field_load(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
-{
-       classinfo *c;
-       u4 attrnum, i;
-       u4 pindex = field_load_NOVALUE;     /* constantvalue_index */
-       utf *u;
-
-       /* Get class. */
-
-       c = cb->clazz;
-
-       f->clazz = c;
-
-       /* Get access flags. */
-
-       if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
-               return false;
-
-       f->flags = suck_u2(cb);
-
-       /* Get name. */
-
-       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-               return false;
-
-       f->name = u;
-
-       /* Get descriptor. */
-
-       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-               return false;
-
-       f->descriptor = u;
-       f->parseddesc = NULL;
-
-       if (!descriptor_pool_add(descpool, u, NULL))
-               return false;
-
-       /* descriptor_pool_add accepts method descriptors, so we have to
-          check against them here before the call of
-          descriptor_to_basic_type below. */
-
-       if (u->text[0] == '(') {
-               exceptions_throw_classformaterror(c, "Method descriptor used for field");
-               return false;
-       }
-
-#ifdef ENABLE_VERIFIER
-       if (opt_verify) {
-               /* check name */
-               if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
-                       exceptions_throw_classformaterror(c,
-                                                                                         "Illegal Field name \"%s\"",
-                                                                                         f->name->text);
-                       return false;
-               }
-
-               /* check flag consistency */
-               i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
-
-               if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
-                       ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
-                       exceptions_throw_classformaterror(c,
-                                                                                         "Illegal field modifiers: 0x%X",
-                                                                                         f->flags);
-                       return false;
-               }
-
-               if (c->flags & ACC_INTERFACE) {
-                       if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
-                               != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
-                               f->flags & ACC_TRANSIENT) {
-                               exceptions_throw_classformaterror(c,
-                                                                                                 "Illegal field modifiers: 0x%X",
-                                                                                                 f->flags);
-                               return false;
-                       }
-               }
-       }
-#endif /* ENABLE_VERIFIER */
-
-       /* data type */
-
-       f->type = descriptor_to_basic_type(f->descriptor);
-
-       /* For static-fields allocate memory for the value and set the
-          value to 0. */
-
-       if (f->flags & ACC_STATIC) {
-               switch (f->type) {
-               case TYPE_INT:
-               case TYPE_LNG:
-               case TYPE_FLT:
-               case TYPE_DBL:
-                       f->value = NEW(imm_union);
-                       break;
-
-               case TYPE_ADR:
-#if !defined(ENABLE_GC_BOEHM)
-                       f->value = NEW(imm_union);
-#else
-                       f->value = GCNEW_UNCOLLECTABLE(imm_union, 1);
-#endif
-                       break;
-
-               default:
-                       vm_abort("field_load: invalid field type %d", f->type);
-               }
-
-               /* Set the field to zero, for float and double fields set the
-                  correct 0.0 value. */
-
-               switch (f->type) {
-               case TYPE_INT:
-               case TYPE_LNG:
-               case TYPE_ADR:
-                       f->value->l = 0;
-                       break;
-
-               case TYPE_FLT:
-                       f->value->f = 0.0;
-                       break;
-
-               case TYPE_DBL:
-                       f->value->d = 0.0;
-                       break;
-               }
-       }
-       else {
-               /* For instance-fields set the offset to 0. */
-
-               f->offset = 0;
-
-               /* For final fields, which are not static, we need a value
-                  structure. */
-
-               if (f->flags & ACC_FINAL) {
-                       f->value = NEW(imm_union);
-                       /* XXX hack */
-                       f->value->l = 0;
-               }
-
-               switch (f->type) {
-               case TYPE_ADR:
-                       c->flags |= ACC_CLASS_HAS_POINTERS;
-                       break;
-               }
-       }
-
-       /* read attributes */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       attrnum = suck_u2(cb);
-
-       for (i = 0; i < attrnum; i++) {
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-                       return false;
-
-               if (u == utf_ConstantValue) {
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* check attribute length */
-
-                       if (suck_u4(cb) != 2) {
-                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-                               return false;
-                       }
-                       
-                       /* constant value attribute */
-
-                       if (pindex != field_load_NOVALUE) {
-                               exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
-                               return false;
-                       }
-                       
-                       /* index of value in constantpool */
-
-                       pindex = suck_u2(cb);
-               
-                       /* initialize field with value from constantpool */             
-
-                       switch (f->type) {
-                       case TYPE_INT: {
-                               constant_integer *ci; 
-
-                               if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
-                                       return false;
-
-                               f->value->i = ci->value;
-                       }
-                       break;
-                                       
-                       case TYPE_LNG: {
-                               constant_long *cl; 
-
-                               if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
-                                       return false;
-
-                               f->value->l = cl->value;
-                       }
-                       break;
-
-                       case TYPE_FLT: {
-                               constant_float *cf;
-
-                               if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
-                                       return false;
-
-                               f->value->f = cf->value;
-                       }
-                       break;
-                                                                                       
-                       case TYPE_DBL: {
-                               constant_double *cd;
-
-                               if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
-                                       return false;
-
-                               f->value->d = cd->value;
-                       }
-                       break;
-                                               
-                       case TYPE_ADR:
-                               if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
-                                       return false;
-
-                               /* Create Java-string from compressed UTF8-string. */
-
-                               f->value->a = literalstring_new(u);
-                               break;
-       
-                       default: 
-                               vm_abort("field_load: invalid field type %d", f->type);
-                       }
-               }
-#if defined(ENABLE_JAVASE)
-               else if (u == utf_Signature) {
-                       /* Signature */
-
-                       if (!loader_load_attribute_signature(cb, &(f->signature)))
-                               return false;
-               }
-
-#if defined(ENABLE_ANNOTATIONS)
-               else if (u == utf_RuntimeVisibleAnnotations) {
-                       /* RuntimeVisibleAnnotations */
-                       if (!annotation_load_field_attribute_runtimevisibleannotations(cb, f))
-                               return false;
-               }
-               else if (u == utf_RuntimeInvisibleAnnotations) {
-                       /* RuntimeInvisibleAnnotations */
-                       if (!annotation_load_field_attribute_runtimeinvisibleannotations(cb, f))
-                               return false;
-               }
-#endif
-#endif
-               else {
-                       /* unknown attribute */
-
-                       if (!loader_skip_attribute_body(cb))
-                               return false;
-               }
-       }
-
-       /* everything was ok */
-
-       return true;
-}
-
-
-/* field_get_type **************************************************************
-
-   Returns the type of the field as class.
-
-*******************************************************************************/
-
-classinfo *field_get_type(fieldinfo *f)
-{
-       typedesc  *td;
-       utf       *u;
-       classinfo *c;
-
-       td = f->parseddesc;
-
-       if (td->type == TYPE_ADR) {
-               assert(td->classref);
-
-               u = td->classref->name;
-
-               /* load the class of the field-type with the field's
-                  classloader */
-
-               c = load_class_from_classloader(u, f->clazz->classloader);
-       }
-       else {
-               c = primitive_class_get_by_type(td->decltype);
-       }
-
-       return c;
-}
-
-
-/* field_free ******************************************************************
-
-   Frees a fields' resources.
-
-*******************************************************************************/
-
-void field_free(fieldinfo *f)
-{
-       /* free memory for fields which have a value */
-
-       if (f->value)
-#if defined(ENABLE_GC_BOEHM)
-               if (f->type != TYPE_ADR)
-#endif
-                       FREE(f->value, imm_union);
-}
-
-
-/* field_get_annotations ******************************************************
-
-   Get a fields' unparsed annotations in a byte array.
-
-   IN:
-       f........the field of which the annotations should be returned
-
-   RETURN VALUE:
-       The unparsed annotations in a byte array (or NULL if there aren't any).
-
-*******************************************************************************/
-
-java_handle_bytearray_t *field_get_annotations(fieldinfo *f)
-{
-#if defined(ENABLE_ANNOTATIONS)
-       classinfo               *c;           /* declaring class           */
-       int                      slot;        /* slot of this field        */
-       java_handle_bytearray_t *annotations; /* unparsed annotations      */
-       java_handle_t           *field_annotations;  /* array of unparsed  */
-                      /* annotations of all fields of the declaring class */
-
-       c           = f->clazz;
-       slot        = f - c->fields;
-       annotations = NULL;
-
-       LLNI_classinfo_field_get(c, field_annotations, field_annotations);
-
-       /* the field_annotations array might be shorter then the field
-        * count if the fields above a certain index have no annotations.
-        */
-       if (field_annotations != NULL &&
-               array_length_get(field_annotations) > slot) {
-               annotations = (java_handle_bytearray_t*)array_objectarray_element_get(
-                               (java_handle_objectarray_t*)field_annotations, slot);
-       }
-       
-       return annotations;
-#else
-       return NULL;
-#endif
-}
-
-
-/* field_printflags ************************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_printflags(fieldinfo *f)
-{
-       if (f == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       if (f->flags & ACC_PUBLIC)       printf(" PUBLIC");
-       if (f->flags & ACC_PRIVATE)      printf(" PRIVATE");
-       if (f->flags & ACC_PROTECTED)    printf(" PROTECTED");
-       if (f->flags & ACC_STATIC)       printf(" STATIC");
-       if (f->flags & ACC_FINAL)        printf(" FINAL");
-       if (f->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
-       if (f->flags & ACC_VOLATILE)     printf(" VOLATILE");
-       if (f->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
-       if (f->flags & ACC_NATIVE)       printf(" NATIVE");
-       if (f->flags & ACC_INTERFACE)    printf(" INTERFACE");
-       if (f->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
-}
-#endif
-
-
-/* field_print *****************************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_print(fieldinfo *f)
-{
-       if (f == NULL) {
-               printf("(fieldinfo*)NULL");
-               return;
-       }
-
-       utf_display_printable_ascii_classname(f->clazz->name);
-       printf(".");
-       utf_display_printable_ascii(f->name);
-       printf(" ");
-       utf_display_printable_ascii(f->descriptor);     
-
-       field_printflags(f);
-
-       if (!(f->flags & ACC_STATIC)) {
-               printf(", offset: %d", f->offset);
-       }
-}
-#endif
-
-
-/* field_println ***************************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_println(fieldinfo *f)
-{
-       field_print(f);
-       printf("\n");
-}
-#endif
-
-/* field_fieldref_print ********************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_fieldref_print(constant_FMIref *fr)
-{
-       if (fr == NULL) {
-               printf("(constant_FMIref *)NULL");
-               return;
-       }
-
-       if (IS_FMIREF_RESOLVED(fr)) {
-               printf("<field> ");
-               field_print(fr->p.field);
-       }
-       else {
-               printf("<fieldref> ");
-               utf_display_printable_ascii_classname(fr->p.classref->name);
-               printf(".");
-               utf_display_printable_ascii(fr->name);
-               printf(" ");
-               utf_display_printable_ascii(fr->descriptor);
-       }
-}
-#endif
-
-/* field_fieldref_println ******************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_fieldref_println(constant_FMIref *fr)
-{
-       field_fieldref_print(fr);
-       printf("\n");
-}
-#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/vmcore/field.h b/src/vmcore/field.h
deleted file mode 100644 (file)
index 32c3871..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/* src/vmcore/field.h - field functions header
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _FIELD_H
-#define _FIELD_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct fieldinfo fieldinfo; 
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "vmcore/descriptor.h"
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/references.h"
-#include "vmcore/utf8.h"
-
-
-/* fieldinfo ******************************************************************/
-
-struct fieldinfo {           /* field of a class                                 */
-
-       /* CAUTION: The first field must be a pointer that is never the same      */
-       /*          value as CLASSREF_PSEUDO_VFTBL! This is used to check whether */
-       /*          a constant_FMIref has been resolved.                          */
-
-       classinfo *clazz;     /* needed by typechecker. Could be optimized        */
-                             /* away by using constant_FMIref instead of         */
-                             /* fieldinfo throughout the compiler.               */
-
-       s4         flags;     /* ACC flags                                        */
-       s4         type;      /* basic data type                                  */
-       utf       *name;      /* name of field                                    */
-       utf       *descriptor;/* JavaVM descriptor string of field                */
-       utf       *signature; /* Signature attribute string                       */
-       typedesc  *parseddesc;/* parsed descriptor                                */
-
-       int32_t    offset;    /* offset from start of object (instance variables) */
-       imm_union *value;     /* storage for static values (class variables)      */
-};
-
-
-/* function prototypes ********************************************************/
-
-bool       field_load(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool);
-classinfo *field_get_type(fieldinfo *f);
-void       field_free(fieldinfo *f);
-
-java_handle_bytearray_t *field_get_annotations(fieldinfo *f);
-
-#if !defined(NDEBUG)
-void field_printflags(fieldinfo *f);
-void field_print(fieldinfo *f);
-void field_println(fieldinfo *f);
-void field_fieldref_print(constant_FMIref *fr);
-void field_fieldref_println(constant_FMIref *fr);
-#endif
-
-#endif /* _FIELD_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/vmcore/linker.c b/src/vmcore/linker.c
deleted file mode 100644 (file)
index cee3866..0000000
+++ /dev/null
@@ -1,1383 +0,0 @@
-/* src/vmcore/linker.c - class linker functions
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/native.h"
-
-#include "threads/lock-common.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/access.h"
-#include "vm/array.h"
-#include "vm/exceptions.h"
-#include "vm/primitive.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit_interface.h"
-
-#include "vmcore/class.h"
-#include "vmcore/classcache.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/rt-timing.h"
-
-
-/* debugging macros ***********************************************************/
-
-#if !defined(NDEBUG)
-# define TRACELINKCLASS(c) \
-    do { \
-        if (opt_TraceLinkClass) { \
-            log_start(); \
-            log_print("[Linking "); \
-            class_print((c)); \
-            log_print("]"); \
-            log_finish(); \
-        } \
-    } while (0)
-#else
-# define TRACELINKCLASS(c)
-#endif
-
-
-/* #include "vm/resolve.h" */
-/* copied prototype to avoid bootstrapping problem: */
-classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#if !defined(NDEBUG) && defined(ENABLE_INLINING)
-#define INLINELOG(code)  do { if (opt_TraceInlining) { code } } while (0)
-#else
-#define INLINELOG(code)
-#endif
-
-
-/* global variables ***********************************************************/
-
-static s4 interfaceindex;       /* sequential numbering of interfaces         */
-static s4 classvalue;
-
-java_object_t *linker_classrenumber_lock;
-
-
-/* private functions **********************************************************/
-
-static classinfo *link_class_intern(classinfo *c);
-static arraydescriptor *link_array(classinfo *c);
-static void linker_compute_class_values(classinfo *c);
-static void linker_compute_subclasses(classinfo *c);
-static bool linker_addinterface(classinfo *c, classinfo *ic);
-static s4 class_highestinterface(classinfo *c);
-
-
-/* dummy structures for alinment checks ***************************************/
-
-typedef struct dummy_alignment_long_t   dummy_alignment_long_t;
-typedef struct dummy_alignment_double_t dummy_alignment_double_t;
-
-struct dummy_alignment_long_t {
-       int32_t i;
-       int64_t l;
-};
-
-struct dummy_alignment_double_t {
-       int32_t i;
-       double  d;
-};
-
-
-/* linker_init *****************************************************************
-
-   Initializes the linker subsystem and links classes required for the
-   primitive table.
-
-*******************************************************************************/
-
-void linker_preinit(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("linker_preinit");
-
-       /* Check for if alignment for long and double matches what we
-          assume for the current architecture. */
-
-#if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
-       /* Define a define here which is later checked when we use this
-          offset. */
-
-# define LINKER_ALIGNMENT_LONG_DOUBLE 4
-
-       if (OFFSET(dummy_alignment_long_t, l) != 4)
-               vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
-                                OFFSET(dummy_alignment_long_t, l), 4);
-
-       if (OFFSET(dummy_alignment_double_t, d) != 4)
-               vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
-                                OFFSET(dummy_alignment_double_t, d), 4);
-#else
-
-# define LINKER_ALIGNMENT_LONG_DOUBLE 8
-
-       if (OFFSET(dummy_alignment_long_t, l) != 8)
-               vm_abort("linker_preinit: long alignment is different from what assumed: %d != %d",
-                                OFFSET(dummy_alignment_long_t, l), 8);
-
-       if (OFFSET(dummy_alignment_double_t, d) != 8)
-               vm_abort("linker_preinit: double alignment is different from what assumed: %d != %d",
-                                OFFSET(dummy_alignment_double_t, d), 8);
-#endif
-
-       /* Reset interface index. */
-
-       interfaceindex = 0;
-
-#if defined(ENABLE_THREADS)
-       /* create the global lock object */
-
-       linker_classrenumber_lock = NEW(java_object_t);
-
-       LOCK_INIT_OBJECT_LOCK(linker_classrenumber_lock);
-#endif
-
-       /* Link the most basic classes. */
-
-       if (!link_class(class_java_lang_Object))
-               vm_abort("linker_preinit: linking java/lang/Object failed");
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_Cloneable))
-               vm_abort("linker_preinit: linking java/lang/Cloneable failed");
-
-       if (!link_class(class_java_io_Serializable))
-               vm_abort("linker_preinit: linking java/io/Serializable failed");
-#endif
-}
-
-
-/* linker_init *****************************************************************
-
-   Links all classes required in the VM.
-
-*******************************************************************************/
-
-void linker_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("linker_init");
-
-       /* Link java.lang.Class as first class of the system, because we
-       need it's vftbl for all other classes so we can use a class as
-       object. */
-
-       if (!link_class(class_java_lang_Class))
-               vm_abort("linker_init: linking java/lang/Class failed");
-
-       /* Now set the header.vftbl of all classes which were created
-       before java.lang.Class was linked. */
-
-       class_postset_header_vftbl();
-
-       /* Link primitive-type wrapping classes. */
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_Void))
-               vm_abort("linker_init: linking failed");
-#endif
-
-       if (!link_class(class_java_lang_Boolean))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Byte))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Character))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Short))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Integer))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Long))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Float))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Double))
-               vm_abort("linker_init: linking failed");
-
-       /* Link important system classes. */
-
-       if (!link_class(class_java_lang_String))
-               vm_abort("linker_init: linking java/lang/String failed");
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_ClassLoader))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_SecurityManager))
-               vm_abort("linker_init: linking failed");
-#endif
-
-       if (!link_class(class_java_lang_System))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Thread))
-               vm_abort("linker_init: linking failed");
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_ThreadGroup))
-               vm_abort("linker_init: linking failed");
-#endif
-
-       if (!link_class(class_java_lang_Throwable))
-               vm_abort("linker_init: linking failed");
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       if (!link_class(class_java_lang_VMSystem))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_VMThread))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_VMThrowable))
-               vm_abort("linker_init: linking failed");
-#endif
-
-       /* Important system exceptions. */
-
-       if (!link_class(class_java_lang_Exception))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_ClassNotFoundException))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_RuntimeException))
-               vm_abort("linker_init: linking failed");
-
-       /* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_StackTraceElement))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_Constructor))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_Field))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_Method))
-               vm_abort("linker_init: linking failed");
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       if (!link_class(class_java_lang_reflect_VMConstructor))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_VMField))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_VMMethod))
-               vm_abort("linker_init: linking failed");
-# endif
-
-       if (!link_class(class_java_security_PrivilegedAction))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_util_Vector))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_util_HashMap))
-               vm_abort("linker_init: linking failed");
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       if (!link_class(class_sun_reflect_MagicAccessorImpl))
-               vm_abort("linker_init: linking failed");
-# endif
-
-       if (!link_class(arrayclass_java_lang_Object))
-               vm_abort("linker_init: linking failed");
-#endif
-
-
-       /* create pseudo classes used by the typechecker */
-
-    /* pseudo class for Arraystubs (extends java.lang.Object) */
-
-       pseudo_class_Arraystub                   =
-               class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
-       pseudo_class_Arraystub->state           |= CLASS_LOADED;
-       pseudo_class_Arraystub->super            = class_java_lang_Object;
-
-#if defined(ENABLE_JAVASE)
-
-       pseudo_class_Arraystub->interfacescount  = 2;
-       pseudo_class_Arraystub->interfaces       = MNEW(classinfo*, 2);
-       pseudo_class_Arraystub->interfaces[0]    = class_java_lang_Cloneable;
-       pseudo_class_Arraystub->interfaces[1]    = class_java_io_Serializable;
-
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-
-       pseudo_class_Arraystub->interfacescount    = 0;
-       pseudo_class_Arraystub->interfaces         = NULL;
-
-#else
-# error unknown Java configuration
-#endif
-
-       if (!classcache_store_unique(pseudo_class_Arraystub))
-               vm_abort("linker_init: could not cache pseudo_class_Arraystub");
-
-       if (!link_class(pseudo_class_Arraystub))
-               vm_abort("linker_init: linking pseudo_class_Arraystub failed");
-
-       /* pseudo class representing the null type */
-
-       pseudo_class_Null         = class_create_classinfo(utf_new_char("$NULL$"));
-       pseudo_class_Null->state |= CLASS_LOADED;
-       pseudo_class_Null->super  = class_java_lang_Object;
-
-       if (!classcache_store_unique(pseudo_class_Null))
-               vm_abort("linker_init: could not cache pseudo_class_Null");
-
-       if (!link_class(pseudo_class_Null))
-               vm_abort("linker_init: linking failed");
-
-       /* pseudo class representing new uninitialized objects */
-    
-       pseudo_class_New         = class_create_classinfo(utf_new_char("$NEW$"));
-       pseudo_class_New->state |= CLASS_LOADED;
-       pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
-       pseudo_class_New->super  = class_java_lang_Object;
-
-       if (!classcache_store_unique(pseudo_class_New))
-               vm_abort("linker_init: could not cache pseudo_class_New");
-
-       /* Correct vftbl-entries (retarded loading and linking of class
-          java/lang/String). */
-
-       stringtable_update();
-}
-
-
-/* link_class ******************************************************************
-
-   Wrapper function for link_class_intern to ease monitor enter/exit
-   and exception handling.
-
-*******************************************************************************/
-
-classinfo *link_class(classinfo *c)
-{
-       classinfo *r;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_end;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       if (c == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       LOCK_MONITOR_ENTER(c);
-
-       /* Maybe the class is currently linking or is already linked.*/
-
-       if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
-               LOCK_MONITOR_EXIT(c);
-
-               return c;
-       }
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getcompilingtime)
-               compilingtime_stop();
-
-       if (opt_getloadingtime)
-               loadingtime_start();
-#endif
-
-       /* call the internal function */
-
-       r = link_class_intern(c);
-
-       /* If return value is NULL, we had a problem and the class is not
-          linked. */
-
-       if (r == NULL)
-               c->state &= ~CLASS_LINKING;
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_stop();
-
-       if (opt_getcompilingtime)
-               compilingtime_start();
-#endif
-
-       LOCK_MONITOR_EXIT(c);
-
-       RT_TIMING_GET_TIME(time_end);
-
-       RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
-
-       return r;
-}
-
-
-/* linker_overwrite_method *****************************************************
-
-   Overwrite a method with another one, update method flags and check
-   assumptions.
-
-   IN:
-      mg................the general method being overwritten
-         ms................the overwriting (more specialized) method
-         wl................worklist where to add invalidated methods
-
-   RETURN VALUE:
-      true..............everything ok
-         false.............an exception has been thrown
-
-*******************************************************************************/
-
-static bool linker_overwrite_method(methodinfo *mg,
-                                                                       methodinfo *ms,
-                                                                       method_worklist **wl)
-{
-       classinfo *cg;
-       classinfo *cs;
-
-       cg = mg->clazz;
-       cs = ms->clazz;
-
-       /* overriding a final method is illegal */
-
-       if (mg->flags & ACC_FINAL) {
-               exceptions_throw_verifyerror(mg, "Overriding final method");
-               return false;
-       }
-
-       /* method ms overwrites method mg */
-
-#if defined(ENABLE_VERIFIER)
-       /* Add loading constraints (for the more general types of method mg). */
-       /* Not for <init>, as it is not invoked virtually.                    */
-
-       if ((ms->name != utf_init)
-                       && !classcache_add_constraints_for_params(
-                               cs->classloader, cg->classloader, mg))
-       {
-               return false;
-       }
-#endif
-
-       /* inherit the vftbl index, and record the overwriting */
-
-       ms->vftblindex = mg->vftblindex;
-       ms->overwrites = mg;
-
-       /* update flags and check assumptions */
-       /* <init> methods are a special case, as they are never dispatched dynamically */
-
-       if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
-               do {
-                       if (mg->flags & ACC_METHOD_IMPLEMENTED) {
-                               /* this adds another implementation */
-
-                               mg->flags &= ~ACC_METHOD_MONOMORPHIC;
-
-                               INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
-
-                               method_break_assumption_monomorphic(mg, wl);
-                       }
-                       else {
-                               /* this is the first implementation */
-
-                               mg->flags |= ACC_METHOD_IMPLEMENTED;
-
-                               INLINELOG( printf("becomes implemented: "); method_println(mg); );
-                       }
-
-                       ms = mg;
-                       mg = mg->overwrites;
-               } while (mg != NULL);
-       }
-
-       return true;
-}
-
-
-/* link_class_intern ***********************************************************
-
-   Tries to link a class. The function calculates the length in bytes
-   that an instance of this class requires as well as the VTBL for
-   methods and interface methods.
-       
-*******************************************************************************/
-
-static classinfo *link_class_intern(classinfo *c)
-{
-       classinfo *super;             /* super class                              */
-       classinfo *tc;                /* temporary class variable                 */
-       s4 supervftbllength;          /* vftbllegnth of super class               */
-       s4 vftbllength;               /* vftbllength of current class             */
-       s4 interfacetablelength;      /* interface table length                   */
-       vftbl_t *v;                   /* vftbl of current class                   */
-       s4 i;                         /* interface/method/field counter           */
-       arraydescriptor *arraydesc;   /* descriptor for array classes             */
-       method_worklist *worklist;    /* worklist for recompilation               */
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_resolving, time_compute_vftbl,
-                                       time_abstract, time_compute_iftbl, time_fill_vftbl,
-                                       time_offsets, time_fill_iftbl, time_finalizer,
-                                       time_subclasses;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       TRACELINKCLASS(c);
-
-       /* the class must be loaded */
-
-       /* XXX should this be a specific exception? */
-       assert(c->state & CLASS_LOADED);
-
-       /* This is check in link_class. */
-
-       assert(!(c->state & CLASS_LINKED));
-
-       /* cache the self-reference of this class                          */
-       /* we do this for cases where the defining loader of the class     */
-       /* has not yet been recorded as an initiating loader for the class */
-       /* this is needed so subsequent code can assume that self-refs     */
-       /* will always resolve lazily                                      */
-       /* No need to do it for the bootloader - it is always registered   */
-       /* as initiating loader for the classes it loads.                  */
-       if (c->classloader)
-               classcache_store(c->classloader,c,false);
-
-       /* this class is currently linking */
-
-       c->state |= CLASS_LINKING;
-
-       arraydesc = NULL;
-       worklist = NULL;
-
-       /* Link the super interfaces. */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               tc = c->interfaces[i];
-
-               if (!(tc->state & CLASS_LINKED))
-                       if (!link_class(tc))
-                               return NULL;
-       }
-       
-       /* check super class */
-
-       super = NULL;
-
-       /* Check for java/lang/Object. */
-
-       if (c->super == NULL) {
-               c->index = 0;
-               c->instancesize = sizeof(java_object_t);
-               
-               vftbllength = supervftbllength = 0;
-
-               c->finalizer = NULL;
-       }
-       else {
-               /* Get super class. */
-
-               super = c->super;
-
-               /* Link the super class if necessary. */
-               
-               if (!(super->state & CLASS_LINKED))
-                       if (!link_class(super))
-                               return NULL;
-
-               /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
-                  flags. */
-
-               c->flags |= (super->flags &
-                                        (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
-
-               /* handle array classes */
-
-               if (c->name->text[0] == '[')
-                       if (!(arraydesc = link_array(c)))
-                               return NULL;
-
-               if (c->flags & ACC_INTERFACE)
-                       c->index = interfaceindex++;
-               else
-                       c->index = super->index + 1;
-               
-               c->instancesize = super->instancesize;
-
-               vftbllength = supervftbllength = super->vftbl->vftbllength;
-               
-               c->finalizer = super->finalizer;
-       }
-       RT_TIMING_GET_TIME(time_resolving);
-
-
-       /* compute vftbl length */
-
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &(c->methods[i]);
-
-               if (!(m->flags & ACC_STATIC)) { /* is instance method */
-                       tc = super;
-
-                       while (tc) {
-                               s4 j;
-
-                               for (j = 0; j < tc->methodscount; j++) {
-                                       if (method_canoverwrite(m, &(tc->methods[j]))) {
-                                               if (tc->methods[j].flags & ACC_PRIVATE)
-                                                       goto notfoundvftblindex;
-
-                                               /* package-private methods in other packages */
-                                               /* must not be overridden                    */
-                                               /* (see Java Language Specification 8.4.8.1) */
-                                               if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
-                                                        && !SAME_PACKAGE(c,tc) ) 
-                                               {
-                                                   goto notfoundvftblindex;
-                                               }
-
-                                               if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
-                                                       return NULL;
-
-                                               goto foundvftblindex;
-                                       }
-                               }
-
-                               tc = tc->super;
-                       }
-
-               notfoundvftblindex:
-                       m->vftblindex = (vftbllength++);
-               foundvftblindex:
-                       ;
-               }
-       }
-       RT_TIMING_GET_TIME(time_compute_vftbl);
-
-
-       /* Check all interfaces of an abstract class (maybe be an
-          interface too) for unimplemented methods.  Such methods are
-          called miranda-methods and are marked with the ACC_MIRANDA
-          flag.  VMClass.getDeclaredMethods does not return such
-          methods. */
-
-       if (c->flags & ACC_ABSTRACT) {
-               classinfo  *ic;
-               methodinfo *im;
-               s4 abstractmethodscount;
-               s4 j;
-               s4 k;
-
-               abstractmethodscount = 0;
-
-               /* check all interfaces of the abstract class */
-
-               for (i = 0; i < c->interfacescount; i++) {
-                       ic = c->interfaces[i];
-
-                       for (j = 0; j < ic->methodscount; j++) {
-                               im = &(ic->methods[j]);
-
-                               /* skip `<clinit>' and `<init>' */
-
-                               if ((im->name == utf_clinit) || (im->name == utf_init))
-                                       continue;
-
-                               for (tc = c; tc != NULL; tc = tc->super) {
-                                       for (k = 0; k < tc->methodscount; k++) {
-                                               if (method_canoverwrite(im, &(tc->methods[k])))
-                                                       goto noabstractmethod;
-                                       }
-                               }
-
-                               abstractmethodscount++;
-
-                       noabstractmethod:
-                               ;
-                       }
-               }
-
-               if (abstractmethodscount > 0) {
-                       methodinfo *am;
-
-                       /* reallocate methods memory */
-
-                       c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
-                                                                 c->methodscount + abstractmethodscount);
-
-                       for (i = 0; i < c->interfacescount; i++) {
-                               ic = c->interfaces[i];
-
-                               for (j = 0; j < ic->methodscount; j++) {
-                                       im = &(ic->methods[j]);
-
-                                       /* skip `<clinit>' and `<init>' */
-
-                                       if ((im->name == utf_clinit) || (im->name == utf_init))
-                                               continue;
-
-                                       for (tc = c; tc != NULL; tc = tc->super) {
-                                               for (k = 0; k < tc->methodscount; k++) {
-                                                       if (method_canoverwrite(im, &(tc->methods[k])))
-                                                               goto noabstractmethod2;
-                                               }
-                                       }
-
-                                       /* Copy the method found into the new c->methods
-                                          array and tag it as miranda-method. */
-
-                                       am = &(c->methods[c->methodscount]);
-                                       c->methodscount++;
-
-                                       MCOPY(am, im, methodinfo, 1);
-
-                                       am->vftblindex  = (vftbllength++);
-                                       am->clazz       = c;
-                                       am->flags      |= ACC_MIRANDA;
-
-                               noabstractmethod2:
-                                       ;
-                               }
-                       }
-               }
-       }
-       RT_TIMING_GET_TIME(time_abstract);
-
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_vftbl_len +=
-                       sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
-#endif
-
-       /* compute interfacetable length */
-
-       interfacetablelength = 0;
-
-       for (tc = c; tc != NULL; tc = tc->super) {
-               for (i = 0; i < tc->interfacescount; i++) {
-                       s4 h = class_highestinterface(tc->interfaces[i]) + 1;
-
-                       if (h > interfacetablelength)
-                               interfacetablelength = h;
-               }
-       }
-       RT_TIMING_GET_TIME(time_compute_iftbl);
-
-       /* allocate virtual function table */
-
-       v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
-                                                         sizeof(methodptr) * (vftbllength - 1) +
-                                                         sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
-       v = (vftbl_t *) (((methodptr *) v) +
-                                        (interfacetablelength - 1) * (interfacetablelength > 1));
-
-       c->vftbl                = v;
-       v->clazz                = c;
-       v->vftbllength          = vftbllength;
-       v->interfacetablelength = interfacetablelength;
-       v->arraydesc            = arraydesc;
-
-       /* store interface index in vftbl */
-
-       if (c->flags & ACC_INTERFACE)
-               v->baseval = -(c->index);
-
-       /* copy virtual function table of super class */
-
-       for (i = 0; i < supervftbllength; i++) 
-               v->table[i] = super->vftbl->table[i];
-
-       /* Fill the remaining vftbl slots with the AbstractMethodError
-          stub (all after the super class slots, because they are already
-          initialized). */
-
-       for (; i < vftbllength; i++) {
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-               if (opt_intrp)
-                       v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-               else
-# endif
-                       v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
-#else
-               v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-#endif
-       }
-
-       /* add method stubs into virtual function table */
-
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &(c->methods[i]);
-
-               assert(m->stubroutine == NULL);
-
-               /* Don't create a compiler stub for abstract methods as they
-                  throw an AbstractMethodError with the default stub in the
-                  vftbl.  This entry is simply copied by sub-classes. */
-
-               if (m->flags & ACC_ABSTRACT)
-                       continue;
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-               if (opt_intrp)
-                       m->stubroutine = intrp_createcompilerstub(m);
-               else
-#endif
-                       m->stubroutine = codegen_generate_stub_compiler(m);
-#else
-               m->stubroutine = intrp_createcompilerstub(m);
-#endif
-
-               /* static methods are not in the vftbl */
-
-               if (m->flags & ACC_STATIC)
-                       continue;
-
-               /* insert the stubroutine into the vftbl */
-
-               v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
-       }
-       RT_TIMING_GET_TIME(time_fill_vftbl);
-
-       /* compute instance size and offset of each field */
-       
-       for (i = 0; i < c->fieldscount; i++) {
-               s4 dsize;
-               fieldinfo *f = &(c->fields[i]);
-               
-               if (!(f->flags & ACC_STATIC)) {
-                       dsize = descriptor_typesize(f->parseddesc);
-
-#if defined(__I386__) || (defined(__ARM__) && !defined(__ARM_EABI__)) || (defined(__POWERPC__) && defined(__DARWIN__)) || defined(__M68K__)
-                       /* On some architectures and configurations we need to
-                          align long (int64_t) and double fields to 4-bytes to
-                          match what GCC does for struct members.  We must do the
-                          same as GCC here because the offsets in native header
-                          structs like java_lang_Double must match the offsets of
-                          the Java fields (eg. java.lang.Double.value). */
-
-# if LINKER_ALIGNMENT_LONG_DOUBLE != 4
-#  error alignment of long and double is not 4
-# endif
-
-                       c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
-#else
-
-# if LINKER_ALIGNMENT_LONG_DOUBLE != 8
-#  error alignment of long and double is not 8
-# endif
-
-                       c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
-#endif
-
-                       f->offset = c->instancesize;
-                       c->instancesize += dsize;
-               }
-       }
-       RT_TIMING_GET_TIME(time_offsets);
-
-       /* initialize interfacetable and interfacevftbllength */
-
-       v->interfacevftbllength = MNEW(s4, interfacetablelength);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
-#endif
-
-       for (i = 0; i < interfacetablelength; i++) {
-               v->interfacevftbllength[i] = 0;
-               v->interfacetable[-i] = NULL;
-       }
-
-       /* add interfaces */
-
-       for (tc = c; tc != NULL; tc = tc->super)
-               for (i = 0; i < tc->interfacescount; i++)
-                       if (!linker_addinterface(c, tc->interfaces[i]))
-                               return NULL;
-
-       RT_TIMING_GET_TIME(time_fill_iftbl);
-
-       /* add finalizer method (not for java.lang.Object) */
-
-       if (super) {
-               methodinfo *fi;
-
-               fi = class_findmethod(c, utf_finalize, utf_void__void);
-
-               if (fi)
-                       if (!(fi->flags & ACC_STATIC))
-                               c->finalizer = fi;
-       }
-       RT_TIMING_GET_TIME(time_finalizer);
-
-       /* final tasks */
-
-       linker_compute_subclasses(c);
-
-       RT_TIMING_GET_TIME(time_subclasses);
-
-       /* revert the linking state and class is linked */
-
-       c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
-
-       /* check worklist */
-
-       /* XXX must this also be done in case of exception? */
-
-       while (worklist != NULL) {
-               method_worklist *wi = worklist;
-
-               worklist = worklist->next;
-
-               INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
-               jit_invalidate_code(wi->m);
-
-               /* XXX put worklist into dump memory? */
-               FREE(wi, method_worklist);
-       }
-
-       RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
-       RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
-       RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
-       RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
-       RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
-       RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
-       RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
-       RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
-       RT_TIMING_TIME_DIFF(time_finalizer    ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
-
-       /* just return c to show that we didn't had a problem */
-
-       return c;
-}
-
-
-/* link_array ******************************************************************
-
-   This function is called by link_class to create the arraydescriptor
-   for an array class.
-
-   This function returns NULL if the array cannot be linked because
-   the component type has not been linked yet.
-
-*******************************************************************************/
-
-static arraydescriptor *link_array(classinfo *c)
-{
-       classinfo       *comp;
-       s4               namelen;
-       arraydescriptor *desc;
-       vftbl_t         *compvftbl;
-       utf             *u;
-
-       comp = NULL;
-       namelen = c->name->blength;
-
-       /* Check the component type */
-
-       switch (c->name->text[1]) {
-       case '[':
-               /* c is an array of arrays. */
-               u = utf_new(c->name->text + 1, namelen - 1);
-               if (!(comp = load_class_from_classloader(u, c->classloader)))
-                       return NULL;
-               break;
-
-       case 'L':
-               /* c is an array of objects. */
-               u = utf_new(c->name->text + 2, namelen - 3);
-               if (!(comp = load_class_from_classloader(u, c->classloader)))
-                       return NULL;
-               break;
-       }
-
-       /* If the component type has not been linked, link it now */
-
-       assert(!comp || (comp->state & CLASS_LOADED));
-
-       if (comp && !(comp->state & CLASS_LINKED))
-               if (!link_class(comp))
-                       return NULL;
-
-       /* Allocate the arraydescriptor */
-
-       desc = NEW(arraydescriptor);
-
-       if (comp) {
-               /* c is an array of references */
-               desc->arraytype = ARRAYTYPE_OBJECT;
-               desc->componentsize = sizeof(void*);
-               desc->dataoffset = OFFSET(java_objectarray_t, data);
-               
-               compvftbl = comp->vftbl;
-
-               if (!compvftbl) {
-                       log_text("Component class has no vftbl");
-                       assert(0);
-               }
-
-               desc->componentvftbl = compvftbl;
-               
-               if (compvftbl->arraydesc) {
-                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
-
-                       if (compvftbl->arraydesc->dimension >= 255) {
-                               log_text("Creating array of dimension >255");
-                               assert(0);
-                       }
-
-                       desc->dimension = compvftbl->arraydesc->dimension + 1;
-                       desc->elementtype = compvftbl->arraydesc->elementtype;
-
-               } else {
-                       desc->elementvftbl = compvftbl;
-                       desc->dimension = 1;
-                       desc->elementtype = ARRAYTYPE_OBJECT;
-               }
-
-       } else {
-               /* c is an array of a primitive type */
-               switch (c->name->text[1]) {
-               case 'Z':
-                       desc->arraytype = ARRAYTYPE_BOOLEAN;
-                       desc->dataoffset = OFFSET(java_booleanarray_t,data);
-                       desc->componentsize = sizeof(u1);
-                       break;
-
-               case 'B':
-                       desc->arraytype = ARRAYTYPE_BYTE;
-                       desc->dataoffset = OFFSET(java_bytearray_t,data);
-                       desc->componentsize = sizeof(u1);
-                       break;
-
-               case 'C':
-                       desc->arraytype = ARRAYTYPE_CHAR;
-                       desc->dataoffset = OFFSET(java_chararray_t,data);
-                       desc->componentsize = sizeof(u2);
-                       break;
-
-               case 'D':
-                       desc->arraytype = ARRAYTYPE_DOUBLE;
-                       desc->dataoffset = OFFSET(java_doublearray_t,data);
-                       desc->componentsize = sizeof(double);
-                       break;
-
-               case 'F':
-                       desc->arraytype = ARRAYTYPE_FLOAT;
-                       desc->dataoffset = OFFSET(java_floatarray_t,data);
-                       desc->componentsize = sizeof(float);
-                       break;
-
-               case 'I':
-                       desc->arraytype = ARRAYTYPE_INT;
-                       desc->dataoffset = OFFSET(java_intarray_t,data);
-                       desc->componentsize = sizeof(s4);
-                       break;
-
-               case 'J':
-                       desc->arraytype = ARRAYTYPE_LONG;
-                       desc->dataoffset = OFFSET(java_longarray_t,data);
-                       desc->componentsize = sizeof(s8);
-                       break;
-
-               case 'S':
-                       desc->arraytype = ARRAYTYPE_SHORT;
-                       desc->dataoffset = OFFSET(java_shortarray_t,data);
-                       desc->componentsize = sizeof(s2);
-                       break;
-
-               default:
-                       exceptions_throw_noclassdeffounderror(c->name);
-                       return NULL;
-               }
-               
-               desc->componentvftbl = NULL;
-               desc->elementvftbl = NULL;
-               desc->dimension = 1;
-               desc->elementtype = desc->arraytype;
-       }
-
-       return desc;
-}
-
-
-/* linker_compute_subclasses ***************************************************
-
-   XXX
-
-   ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
-   This function needs to take the class renumber lock and stop the
-   world during class renumbering. The lock is used in C code which
-   is not that performance critical. Whereas JIT code uses critical
-   sections to atomically access the class values.
-
-*******************************************************************************/
-
-static void linker_compute_subclasses(classinfo *c)
-{
-       LOCK_MONITOR_ENTER(linker_classrenumber_lock);
-
-#if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
-       threads_stopworld();
-#endif
-
-       if (!(c->flags & ACC_INTERFACE)) {
-               c->nextsub = NULL;
-               c->sub     = NULL;
-       }
-
-       if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
-               c->nextsub    = c->super->sub;
-               c->super->sub = c;
-       }
-
-       classvalue = 0;
-
-       /* compute class values */
-
-       linker_compute_class_values(class_java_lang_Object);
-
-       LOCK_MONITOR_EXIT(linker_classrenumber_lock);
-
-#if 0 && defined(ENABLE_THREADS) && !defined(DISABLE_GC)
-       threads_startworld();
-#endif
-}
-
-
-/* linker_compute_class_values *************************************************
-
-   XXX
-
-*******************************************************************************/
-
-static void linker_compute_class_values(classinfo *c)
-{
-       classinfo *subs;
-
-       c->vftbl->baseval = ++classvalue;
-
-       subs = c->sub;
-
-       while (subs) {
-               linker_compute_class_values(subs);
-
-               subs = subs->nextsub;
-       }
-
-       c->vftbl->diffval = classvalue - c->vftbl->baseval;
-}
-
-
-/* linker_addinterface *********************************************************
-
-   Is needed by link_class for adding a VTBL to a class. All
-   interfaces implemented by ic are added as well.
-
-   RETURN VALUE:
-      true.........everything ok
-         false........an exception has been thrown
-
-*******************************************************************************/
-
-static bool linker_addinterface(classinfo *c, classinfo *ic)
-{
-       s4          j, k;
-       vftbl_t    *v;
-       s4          i;
-       classinfo  *sc;
-       methodinfo *m;
-
-       v = c->vftbl;
-       i = ic->index;
-
-       if (i >= v->interfacetablelength)
-               vm_abort("Internal error: interfacetable overflow");
-
-       /* if this interface has already been added, return immediately */
-
-       if (v->interfacetable[-i] != NULL)
-               return true;
-
-       if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
-               v->interfacevftbllength[i] = 1;
-               v->interfacetable[-i]      = MNEW(methodptr, 1);
-               v->interfacetable[-i][0]   = NULL;
-       }
-       else {
-               v->interfacevftbllength[i] = ic->methodscount;
-               v->interfacetable[-i]      = MNEW(methodptr, ic->methodscount);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_vftbl_len += sizeof(methodptr) *
-                               (ic->methodscount + (ic->methodscount == 0));
-#endif
-
-               for (j = 0; j < ic->methodscount; j++) {
-                       for (sc = c; sc != NULL; sc = sc->super) {
-                               for (k = 0; k < sc->methodscount; k++) {
-                                       m = &(sc->methods[k]);
-
-                                       if (method_canoverwrite(m, &(ic->methods[j]))) {
-                                               /* method m overwrites the (abstract) method */
-#if defined(ENABLE_VERIFIER)
-                                               /* Add loading constraints (for the more
-                                                  general types of the method
-                                                  ic->methods[j]).  */
-                                               if (!classcache_add_constraints_for_params(
-                                                                       c->classloader, ic->classloader,
-                                                                       &(ic->methods[j])))
-                                               {
-                                                       return false;
-                                               }
-#endif
-
-                                               /* XXX taken from gcj */
-                                               /* check for ACC_STATIC: IncompatibleClassChangeError */
-
-                                               /* check for !ACC_PUBLIC: IllegalAccessError */
-
-                                               /* check for ACC_ABSTRACT: AbstracMethodError,
-                                                  not sure about that one */
-
-                                               v->interfacetable[-i][j] = v->table[m->vftblindex];
-                                               goto foundmethod;
-                                       }
-                               }
-                       }
-
-                       /* If no method was found, insert the AbstractMethodError
-                          stub. */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-                       if (opt_intrp)
-                               v->interfacetable[-i][j] =
-                                       (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-                       else
-# endif
-                               v->interfacetable[-i][j] =
-                                       (methodptr) (ptrint) &asm_abstractmethoderror;
-#else
-                       v->interfacetable[-i][j] =
-                               (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-#endif
-
-               foundmethod:
-                       ;
-               }
-       }
-
-       /* add superinterfaces of this interface */
-
-       for (j = 0; j < ic->interfacescount; j++)
-               if (!linker_addinterface(c, ic->interfaces[j]))
-                       return false;
-
-       /* everything ok */
-
-       return true;
-}
-
-
-/* class_highestinterface ******************************************************
-
-   Used by the function link_class to determine the amount of memory
-   needed for the interface table.
-
-*******************************************************************************/
-
-static s4 class_highestinterface(classinfo *c)
-{
-       s4 h;
-       s4 h2;
-       s4 i;
-       
-    /* check for ACC_INTERFACE bit already done in link_class_intern */
-
-    h = c->index;
-
-       for (i = 0; i < c->interfacescount; i++) {
-               h2 = class_highestinterface(c->interfaces[i]);
-
-               if (h2 > h)
-                       h = h2;
-       }
-
-       return h;
-}
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/vmcore/linker.h b/src/vmcore/linker.h
deleted file mode 100644 (file)
index ad95bcc..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/* src/vmcore/linker.h - class linker header
-
-   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
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _LINKER_H
-#define _LINKER_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct _vftbl vftbl_t;
-typedef struct arraydescriptor arraydescriptor;
-typedef struct primitivetypeinfo primitivetypeinfo;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vmcore/class.h"
-#include "vmcore/references.h"
-
-
-/* virtual function table ******************************************************
-
-   The vtbl has a bidirectional layout with open ends at both sides.
-   interfacetablelength gives the number of entries of the interface
-   table at the start of the vftbl. The vftbl pointer points to
-   &interfacetable[0].  vftbllength gives the number of entries of
-   table at the end of the vftbl.
-
-   runtime type check (checkcast):
-
-   Different methods are used for runtime type check depending on the
-   argument of checkcast/instanceof.
-       
-   A check against a class is implemented via relative numbering on
-   the class hierachy tree. The tree is numbered in a depth first
-   traversal setting the base field and the diff field. The diff field
-   gets the result of (high - base) so that a range check can be
-   implemented by an unsigned compare. A sub type test is done by
-   checking the inclusion of base of the sub class in the range of the
-   superclass.
-
-   A check against an interface is implemented via the
-   interfacevftbl. If the interfacevftbl contains a nonnull value a
-   class is a subclass of this interface.
-
-   interfacetable:
-
-   Like standard virtual methods interface methods are called using
-   virtual function tables. All interfaces are numbered sequentially
-   (starting with zero). For each class there exist an interface table
-   of virtual function tables for each implemented interface. The
-   length of the interface table is determined by the highest number
-   of an implemented interface.
-
-   The following example assumes a class which implements interface 0 and 3:
-
-   interfacetablelength = 4
-
-                  | ...       |            +----------+
-                  +-----------+            | method 2 |---> method z
-                  | class     |            | method 1 |---> method y
-                  +-----------+            | method 0 |---> method x
-                  | ivftbl  0 |----------> +----------+
-    vftblptr ---> +-----------+
-                  | ivftbl -1 |--> NULL    +----------+
-                  | ivftbl -2 |--> NULL    | method 1 |---> method x
-                  | ivftbl -3 |-----+      | method 0 |---> method a
-                  +-----------+     +----> +----------+
-     
-                              +---------------+
-                              | length 3 = 2  |
-                              | length 2 = 0  |
-                              | length 1 = 0  |
-                              | length 0 = 3  |
-    interfacevftbllength ---> +---------------+
-
-*******************************************************************************/
-
-struct _vftbl {
-       methodptr   *interfacetable[1];    /* interface table (access via macro)  */
-       classinfo   *clazz;                /* class, the vtbl belongs to          */
-       arraydescriptor *arraydesc;        /* for array classes, otherwise NULL   */
-       s4           vftbllength;          /* virtual function table length       */
-       s4           interfacetablelength; /* interface table length              */
-       s4           baseval;              /* base for runtime type check         */
-                                          /* (-index for interfaces)             */
-       s4           diffval;              /* high - base for runtime type check  */
-       s4          *interfacevftbllength; /* length of interface vftbls          */
-       methodptr    table[1];             /* class vftbl                         */
-};
-
-
-/* arraydescriptor *************************************************************
-
-   For every array class an arraydescriptor is allocated which
-   describes the array class. The arraydescriptor is referenced from
-   the vftbl of the array class.
-
-*******************************************************************************/
-
-struct arraydescriptor {
-       vftbl_t *componentvftbl; /* vftbl of the component type, NULL for primit. */
-       vftbl_t *elementvftbl;   /* vftbl of the element type, NULL for primitive */
-       s2       arraytype;      /* ARRAYTYPE_* constant                          */
-       s2       dimension;      /* dimension of the array (always >= 1)          */
-       s4       dataoffset;     /* offset of the array data from object pointer  */
-       s4       componentsize;  /* size of a component in bytes                  */
-       s2       elementtype;    /* ARRAYTYPE_* constant                          */
-};
-
-
-/* global variables ***********************************************************/
-
-/* This lock must be taken while renumbering classes or while atomically      */
-/* accessing classes.                                                         */
-
-extern java_object_t *linker_classrenumber_lock;
-
-
-/* function prototypes ********************************************************/
-
-void       linker_preinit(void);
-void       linker_init(void);
-classinfo *link_class(classinfo *c);
-
-#endif /* _LINKER_H */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
diff --git a/src/vmcore/loader.c b/src/vmcore/loader.c
deleted file mode 100644 (file)
index c303485..0000000
+++ /dev/null
@@ -1,2228 +0,0 @@
-/* src/vmcore/loader.c - class loader 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 <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "threads/lock-common.h"
-
-#include "toolbox/hashtable.h"
-#include "toolbox/logging.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/package.hpp"
-#include "vm/primitive.h"
-#include "vm/resolve.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit_interface.h"
-
-#if defined(ENABLE_JAVASE)
-# include "vmcore/annotation.h"
-# include "vmcore/stackmap.h"
-#endif
-
-#include "vmcore/classcache.h"
-#include "vmcore/field.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/rt-timing.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#include "vmcore/suck.h"
-
-#if defined(ENABLE_ZLIB)
-# include "vmcore/zip.h"
-#endif
-
-#if defined(ENABLE_JVMTI)
-# include "native/jvmti/cacaodbg.h"
-#endif
-
-
-/* global variables ***********************************************************/
-
-static hashtable *hashtable_classloader;
-
-
-/* loader_preinit **************************************************************
-
-   Initializes the classpath list and loads classes required for the
-   primitive table.
-
-   NOTE: Exceptions thrown during VM initialization are caught in the
-         exception functions themselves.
-
-*******************************************************************************/
-void loader_preinit(void)
-{
-#if defined(ENABLE_THREADS)
-       list_classpath_entry *lce;
-#endif
-
-       TRACESUBSYSTEMINITIALIZATION("loader_preinit");
-
-#if defined(ENABLE_THREADS)
-       /* Initialize the monitor pointer for zip/jar file locking. */
-
-       for (lce = list_first(list_classpath_entries); lce != NULL;
-                lce = list_next(list_classpath_entries, lce)) {
-               if (lce->type == CLASSPATH_ARCHIVE)
-                       LOCK_INIT_OBJECT_LOCK(lce);
-       }
-#endif
-
-       /* initialize classloader hashtable, 10 entries should be enough */
-
-       hashtable_classloader = NEW(hashtable);
-       hashtable_create(hashtable_classloader, 10);
-
-       /* Load the most basic classes. */
-
-       assert(vm_initializing == true);
-
-       class_java_lang_Object     = load_class_bootstrap(utf_java_lang_Object);
-
-#if defined(ENABLE_JAVASE)
-       class_java_lang_Cloneable  = load_class_bootstrap(utf_java_lang_Cloneable);
-       class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
-#endif
-}
-
-
-/* loader_init *****************************************************************
-
-   Loads all classes required in the VM.
-
-   NOTE: Exceptions thrown during VM initialization are caught in the
-         exception functions themselves.
-
-*******************************************************************************/
-void loader_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("loader_init");
-
-       /* Load primitive-type wrapping classes. */
-
-       assert(vm_initializing == true);
-
-#if defined(ENABLE_JAVASE)
-       class_java_lang_Void       = load_class_bootstrap(utf_java_lang_Void);
-#endif
-
-       class_java_lang_Boolean    = load_class_bootstrap(utf_java_lang_Boolean);
-       class_java_lang_Byte       = load_class_bootstrap(utf_java_lang_Byte);
-       class_java_lang_Character  = load_class_bootstrap(utf_java_lang_Character);
-       class_java_lang_Short      = load_class_bootstrap(utf_java_lang_Short);
-       class_java_lang_Integer    = load_class_bootstrap(utf_java_lang_Integer);
-       class_java_lang_Long       = load_class_bootstrap(utf_java_lang_Long);
-       class_java_lang_Float      = load_class_bootstrap(utf_java_lang_Float);
-       class_java_lang_Double     = load_class_bootstrap(utf_java_lang_Double);
-
-       /* Load important system classes. */
-
-       class_java_lang_Class      = load_class_bootstrap(utf_java_lang_Class);
-       class_java_lang_String     = load_class_bootstrap(utf_java_lang_String);
-
-#if defined(ENABLE_JAVASE)
-       class_java_lang_ClassLoader =
-               load_class_bootstrap(utf_java_lang_ClassLoader);
-
-       class_java_lang_SecurityManager =
-               load_class_bootstrap(utf_java_lang_SecurityManager);
-#endif
-
-       class_java_lang_System     =
-               load_class_bootstrap(utf_new_char("java/lang/System"));
-
-       class_java_lang_Thread     =
-               load_class_bootstrap(utf_new_char("java/lang/Thread"));
-
-#if defined(ENABLE_JAVASE)
-       class_java_lang_ThreadGroup =
-               load_class_bootstrap(utf_java_lang_ThreadGroup);
-#endif
-
-       class_java_lang_Throwable  = load_class_bootstrap(utf_java_lang_Throwable);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       class_java_lang_VMSystem   =
-               load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
-
-       class_java_lang_VMThread   =
-               load_class_bootstrap(utf_new_char("java/lang/VMThread"));
-
-       class_java_lang_VMThrowable =
-               load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
-#endif
-
-       /* Important system exceptions. */
-
-       class_java_lang_Exception  = load_class_bootstrap(utf_java_lang_Exception);
-
-       class_java_lang_ClassNotFoundException =
-               load_class_bootstrap(utf_java_lang_ClassNotFoundException);
-
-       class_java_lang_RuntimeException =
-               load_class_bootstrap(utf_java_lang_RuntimeException);
-
-       /* Some classes which may be used often. */
-
-#if defined(ENABLE_JAVASE)
-       class_java_lang_StackTraceElement      = load_class_bootstrap(utf_java_lang_StackTraceElement);
-
-       class_java_lang_reflect_Constructor    = load_class_bootstrap(utf_java_lang_reflect_Constructor);
-       class_java_lang_reflect_Field          = load_class_bootstrap(utf_java_lang_reflect_Field);
-       class_java_lang_reflect_Method         = load_class_bootstrap(utf_java_lang_reflect_Method);
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       class_java_lang_reflect_VMConstructor  = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
-       class_java_lang_reflect_VMField        = load_class_bootstrap(utf_java_lang_reflect_VMField);
-       class_java_lang_reflect_VMMethod       = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
-# endif
-
-       class_java_security_PrivilegedAction   = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
-
-       class_java_util_HashMap                = load_class_bootstrap(utf_new_char("java/util/HashMap"));
-       class_java_util_Vector                 = load_class_bootstrap(utf_java_util_Vector);
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       class_sun_reflect_MagicAccessorImpl =
-               load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
-# endif
-
-       arrayclass_java_lang_Object =
-               load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
-
-# if defined(ENABLE_ANNOTATIONS)
-       /* needed by annotation support */
-       class_sun_reflect_ConstantPool =
-               load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
-
-#  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       /* needed by GNU Classpaths annotation support */
-       class_sun_reflect_annotation_AnnotationParser =
-               load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
-#  endif
-# endif
-#endif
-}
-
-
-/* loader_hashtable_classloader_add ********************************************
-
-   Adds an entry to the classloader hashtable.
-
-   REMEMBER: Also use this to register native loaders!
-
-*******************************************************************************/
-
-classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
-{
-       hashtable_classloader_entry *cle;
-       u4   key;
-       u4   slot;
-
-       if (cl == NULL)
-               return NULL;
-
-       LOCK_MONITOR_ENTER(hashtable_classloader->header);
-
-       LLNI_CRITICAL_START;
-
-       /* key for entry is the hashcode of the classloader;
-          aligned to 16-byte boundaries */
-
-       key  = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
-       slot = key & (hashtable_classloader->size - 1);
-       cle  = hashtable_classloader->ptr[slot];
-
-       /* search hashchain for existing entry */
-
-       while (cle) {
-               if (cle->object == LLNI_DIRECT(cl))
-                       break;
-
-               cle = cle->hashlink;
-       }
-
-       LLNI_CRITICAL_END;
-
-       /* if no classloader was found, we create a new entry here */
-
-       if (cle == NULL) {
-               cle = NEW(hashtable_classloader_entry);
-
-#if defined(ENABLE_GC_CACAO)
-               /* register the classloader object with the GC */
-
-               gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
-#endif
-
-               LLNI_CRITICAL_START;
-
-               cle->object = LLNI_DIRECT(cl);
-
-               LLNI_CRITICAL_END;
-
-/*#define LOADER_DEBUG_CLASSLOADER*/
-#ifdef LOADER_DEBUG_CLASSLOADER
-               printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
-               class_print(LLNI_vftbl_direct(cl)->class);
-               printf("\n");
-               fflush(stdout);
-#endif
-
-               /* insert entry into hashtable */
-
-               cle->hashlink = hashtable_classloader->ptr[slot];
-               hashtable_classloader->ptr[slot] = cle;
-
-               /* update number of entries */
-
-               hashtable_classloader->entries++;
-       }
-
-
-       LOCK_MONITOR_EXIT(hashtable_classloader->header);
-
-#if defined(ENABLE_HANDLES)
-       return cle;
-#else
-       return cl;
-#endif
-}
-
-
-/* loader_hashtable_classloader_find *******************************************
-
-   Find an entry in the classloader hashtable.
-
-*******************************************************************************/
-
-classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
-{
-       hashtable_classloader_entry *cle;
-       u4   key;
-       u4   slot;
-
-       if (cl == NULL)
-               return NULL;
-
-       LLNI_CRITICAL_START;
-
-       /* key for entry is the hashcode of the classloader;
-          aligned to 16-byte boundaries */
-
-       key  = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
-       slot = key & (hashtable_classloader->size - 1);
-       cle  = hashtable_classloader->ptr[slot];
-
-       /* search hashchain for existing entry */
-
-       while (cle) {
-               if (cle->object == LLNI_DIRECT(cl))
-                       break;
-
-               cle = cle->hashlink;
-       }
-
-#ifdef LOADER_DEBUG_CLASSLOADER
-       if (cle == NULL) {
-               printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
-               class_print(LLNI_vftbl_direct(cl)->class);
-               printf("\n");
-               fflush(stdout);
-       }
-#endif
-
-       LLNI_CRITICAL_END;
-
-#if defined(ENABLE_HANDLES)
-       return cle;
-#else
-       return cl;
-#endif
-}
-
-
-/* loader_load_all_classes *****************************************************
-
-   Loads all classes specified in the BOOTCLASSPATH.
-
-*******************************************************************************/
-
-void loader_load_all_classes(void)
-{
-       list_classpath_entry    *lce;
-#if defined(ENABLE_ZLIB)
-       hashtable               *ht;
-       s4                       slot;
-       hashtable_zipfile_entry *htzfe;
-       utf                     *u;
-#endif
-
-       for (lce = list_first(list_classpath_entries); lce != NULL;
-                lce = list_next(list_classpath_entries, lce)) {
-#if defined(ENABLE_ZLIB)
-               if (lce->type == CLASSPATH_ARCHIVE) {
-                       /* get the classes hashtable */
-
-                       ht = lce->htclasses;
-
-                       for (slot = 0; slot < ht->size; slot++) {
-                               htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
-
-                               for (; htzfe; htzfe = htzfe->hashlink) {
-                                       u = htzfe->filename;
-
-                                       /* skip all entries in META-INF and .properties,
-                       .png files */
-
-                                       if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
-                                               strstr(u->text, ".properties") ||
-                                               strstr(u->text, ".png"))
-                                               continue;
-
-                                       /* load class from bootstrap classloader */
-
-                                       if (!load_class_bootstrap(u)) {
-                                               fprintf(stderr, "Error loading: ");
-                                               utf_fprint_printable_ascii_classname(stderr, u);
-                                               fprintf(stderr, "\n");
-
-#if !defined(NDEBUG)
-                                               /* print out exception and cause */
-
-                                               exceptions_print_current_exception();
-#endif
-                                       }
-                               }
-                       }
-
-               } else {
-#endif
-#if defined(ENABLE_ZLIB)
-               }
-#endif
-       }
-}
-
-
-/* loader_skip_attribute_body **************************************************
-
-   Skips an attribute the attribute_name_index has already been read.
-       
-   attribute_info {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       u1 info[attribute_length];
-   }
-
-*******************************************************************************/
-
-bool loader_skip_attribute_body(classbuffer *cb)
-{
-       u4 attribute_length;
-
-       if (!suck_check_classbuffer_size(cb, 4))
-               return false;
-
-       attribute_length = suck_u4(cb);
-
-       if (!suck_check_classbuffer_size(cb, attribute_length))
-               return false;
-
-       suck_skip_nbytes(cb, attribute_length);
-
-       return true;
-}
-
-
-/* load_constantpool ***********************************************************
-
-   Loads the constantpool of a class, the entries are transformed into
-   a simpler format by resolving references (a detailed overview of
-   the compact structures can be found in global.h).
-
-*******************************************************************************/
-
-static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
-{
-
-       /* The following structures are used to save information which cannot be 
-          processed during the first pass. After the complete constantpool has 
-          been traversed the references can be resolved. 
-          (only in specific order)                                                */
-       
-       /* CONSTANT_Class entries */
-       typedef struct forward_class {
-               struct forward_class *next;
-               u2 thisindex;
-               u2 name_index;
-       } forward_class;
-
-       /* CONSTANT_String */
-       typedef struct forward_string {
-               struct forward_string *next;
-               u2 thisindex;
-               u2 string_index;
-       } forward_string;
-
-       /* CONSTANT_NameAndType */
-       typedef struct forward_nameandtype {
-               struct forward_nameandtype *next;
-               u2 thisindex;
-               u2 name_index;
-               u2 sig_index;
-       } forward_nameandtype;
-
-       /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
-       typedef struct forward_fieldmethint {
-               struct forward_fieldmethint *next;
-               u2 thisindex;
-               u1 tag;
-               u2 class_index;
-               u2 nameandtype_index;
-       } forward_fieldmethint;
-
-
-       classinfo *c;
-       u4 idx;
-
-       forward_class *forward_classes = NULL;
-       forward_string *forward_strings = NULL;
-       forward_nameandtype *forward_nameandtypes = NULL;
-       forward_fieldmethint *forward_fieldmethints = NULL;
-
-       forward_class *nfc;
-       forward_string *nfs;
-       forward_nameandtype *nfn;
-       forward_fieldmethint *nff;
-
-       u4 cpcount;
-       u1 *cptags;
-       voidptr *cpinfos;
-
-       c = cb->clazz;
-
-       /* number of entries in the constant_pool table plus one */
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       cpcount = c->cpcount = suck_u2(cb);
-
-       /* allocate memory */
-       cptags  = c->cptags  = MNEW(u1, cpcount);
-       cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
-
-       if (cpcount < 1) {
-               exceptions_throw_classformaterror(c, "Illegal constant pool size");
-               return false;
-       }
-       
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
-#endif
-       
-       /* initialize constantpool */
-       for (idx = 0; idx < cpcount; idx++) {
-               cptags[idx] = CONSTANT_UNUSED;
-               cpinfos[idx] = NULL;
-       }
-
-                       
-       /******* first pass *******/
-       /* entries which cannot be resolved now are written into 
-          temporary structures and traversed again later        */
-                  
-       idx = 1;
-       while (idx < cpcount) {
-               u4 t;
-
-               /* get constant type */
-               if (!suck_check_classbuffer_size(cb, 1))
-                       return false;
-
-               t = suck_u1(cb);
-
-               switch (t) {
-               case CONSTANT_Class:
-                       nfc = DNEW(forward_class);
-
-                       nfc->next = forward_classes;
-                       forward_classes = nfc;
-
-                       nfc->thisindex = idx;
-                       /* reference to CONSTANT_NameAndType */
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       nfc->name_index = suck_u2(cb);
-
-                       idx++;
-                       break;
-                       
-               case CONSTANT_String:
-                       nfs = DNEW(forward_string);
-                               
-                       nfs->next = forward_strings;
-                       forward_strings = nfs;
-                               
-                       nfs->thisindex = idx;
-
-                       /* reference to CONSTANT_Utf8_info with string characters */
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       nfs->string_index = suck_u2(cb);
-                               
-                       idx++;
-                       break;
-
-               case CONSTANT_NameAndType:
-                       nfn = DNEW(forward_nameandtype);
-                               
-                       nfn->next = forward_nameandtypes;
-                       forward_nameandtypes = nfn;
-                               
-                       nfn->thisindex = idx;
-
-                       if (!suck_check_classbuffer_size(cb, 2 + 2))
-                               return false;
-
-                       /* reference to CONSTANT_Utf8_info containing simple name */
-                       nfn->name_index = suck_u2(cb);
-
-                       /* reference to CONSTANT_Utf8_info containing field or method
-                          descriptor */
-                       nfn->sig_index = suck_u2(cb);
-                               
-                       idx++;
-                       break;
-
-               case CONSTANT_Fieldref:
-               case CONSTANT_Methodref:
-               case CONSTANT_InterfaceMethodref:
-                       nff = DNEW(forward_fieldmethint);
-                       
-                       nff->next = forward_fieldmethints;
-                       forward_fieldmethints = nff;
-
-                       nff->thisindex = idx;
-                       /* constant type */
-                       nff->tag = t;
-
-                       if (!suck_check_classbuffer_size(cb, 2 + 2))
-                               return false;
-
-                       /* class or interface type that contains the declaration of the
-                          field or method */
-                       nff->class_index = suck_u2(cb);
-
-                       /* name and descriptor of the field or method */
-                       nff->nameandtype_index = suck_u2(cb);
-
-                       idx++;
-                       break;
-                               
-               case CONSTANT_Integer: {
-                       constant_integer *ci = NEW(constant_integer);
-
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_const_pool_len += sizeof(constant_integer);
-#endif
-
-                       if (!suck_check_classbuffer_size(cb, 4))
-                               return false;
-
-                       ci->value = suck_s4(cb);
-                       cptags[idx] = CONSTANT_Integer;
-                       cpinfos[idx] = ci;
-
-                       idx++;
-                       break;
-               }
-                               
-               case CONSTANT_Float: {
-                       constant_float *cf = NEW(constant_float);
-
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_const_pool_len += sizeof(constant_float);
-#endif
-
-                       if (!suck_check_classbuffer_size(cb, 4))
-                               return false;
-
-                       cf->value = suck_float(cb);
-                       cptags[idx] = CONSTANT_Float;
-                       cpinfos[idx] = cf;
-
-                       idx++;
-                       break;
-               }
-                               
-               case CONSTANT_Long: {
-                       constant_long *cl = NEW(constant_long);
-                                       
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_const_pool_len += sizeof(constant_long);
-#endif
-
-                       if (!suck_check_classbuffer_size(cb, 8))
-                               return false;
-
-                       cl->value = suck_s8(cb);
-                       cptags[idx] = CONSTANT_Long;
-                       cpinfos[idx] = cl;
-                       idx += 2;
-                       if (idx > cpcount) {
-                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
-                               return false;
-                       }
-                       break;
-               }
-                       
-               case CONSTANT_Double: {
-                       constant_double *cd = NEW(constant_double);
-                               
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_const_pool_len += sizeof(constant_double);
-#endif
-
-                       if (!suck_check_classbuffer_size(cb, 8))
-                               return false;
-
-                       cd->value = suck_double(cb);
-                       cptags[idx] = CONSTANT_Double;
-                       cpinfos[idx] = cd;
-                       idx += 2;
-                       if (idx > cpcount) {
-                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
-                               return false;
-                       }
-                       break;
-               }
-                               
-               case CONSTANT_Utf8: { 
-                       u4 length;
-
-                       /* number of bytes in the bytes array (not string-length) */
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       length = suck_u2(cb);
-                       cptags[idx] = CONSTANT_Utf8;
-
-                       /* validate the string */
-                       if (!suck_check_classbuffer_size(cb, length))
-                               return false;
-
-#ifdef ENABLE_VERIFIER
-                       if (opt_verify &&
-                               !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
-                       {
-                               exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
-                               return false;
-                       }
-#endif /* ENABLE_VERIFIER */
-                       /* insert utf-string into the utf-symboltable */
-                       cpinfos[idx] = utf_new((char *) cb->pos, length);
-
-                       /* skip bytes of the string (buffer size check above) */
-                       suck_skip_nbytes(cb, length);
-                       idx++;
-                       break;
-               }
-                                                                               
-               default:
-                       exceptions_throw_classformaterror(c, "Illegal constant pool type");
-                       return false;
-               }  /* end switch */
-       } /* end while */
-
-
-       /* resolve entries in temporary structures */
-
-       while (forward_classes) {
-               utf *name =
-                       class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
-               if (!name)
-                       return false;
-
-#ifdef ENABLE_VERIFIER
-               if (opt_verify && !is_valid_name_utf(name)) {
-                       exceptions_throw_classformaterror(c, "Class reference with invalid name");
-                       return false;
-               }
-#endif /* ENABLE_VERIFIER */
-
-               /* add all class references to the descriptor_pool */
-
-               if (!descriptor_pool_add_class(descpool, name))
-                       return false;
-
-               cptags[forward_classes->thisindex] = CONSTANT_Class;
-
-               /* the classref is created later */
-               cpinfos[forward_classes->thisindex] = name;
-
-               nfc = forward_classes;
-               forward_classes = forward_classes->next;
-       }
-
-       while (forward_strings) {
-               utf *text =
-                       class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
-               if (!text)
-                       return false;
-
-               /* resolve utf-string */
-               cptags[forward_strings->thisindex] = CONSTANT_String;
-               cpinfos[forward_strings->thisindex] = text;
-               
-               nfs = forward_strings;
-               forward_strings = forward_strings->next;
-       }
-
-       while (forward_nameandtypes) {
-               constant_nameandtype *cn = NEW(constant_nameandtype);   
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_const_pool_len += sizeof(constant_nameandtype);
-#endif
-
-               /* resolve simple name and descriptor */
-               cn->name = class_getconstant(c,
-                                                                        forward_nameandtypes->name_index,
-                                                                        CONSTANT_Utf8);
-               if (!cn->name)
-                       return false;
-
-               cn->descriptor = class_getconstant(c,
-                                                                                  forward_nameandtypes->sig_index,
-                                                                                  CONSTANT_Utf8);
-               if (!cn->descriptor)
-                       return false;
-
-#ifdef ENABLE_VERIFIER
-               if (opt_verify) {
-                       /* check name */
-                       if (!is_valid_name_utf(cn->name)) {
-                               exceptions_throw_classformaterror(c,
-                                                                                                 "Illegal Field name \"%s\"",
-                                                                                                 cn->name->text);
-
-                               return false;
-                       }
-
-                       /* disallow referencing <clinit> among others */
-                       if (cn->name->text[0] == '<' && cn->name != utf_init) {
-                               exceptions_throw_classformaterror(c, "Illegal reference to special method");
-                               return false;
-                       }
-               }
-#endif /* ENABLE_VERIFIER */
-
-               cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
-               cpinfos[forward_nameandtypes->thisindex] = cn;
-
-               nfn = forward_nameandtypes;
-               forward_nameandtypes = forward_nameandtypes->next;
-       }
-
-       while (forward_fieldmethints) {
-               constant_nameandtype *nat;
-               constant_FMIref *fmi = NEW(constant_FMIref);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_const_pool_len += sizeof(constant_FMIref);
-#endif
-               /* resolve simple name and descriptor */
-
-               nat = class_getconstant(c,
-                                                               forward_fieldmethints->nameandtype_index,
-                                                               CONSTANT_NameAndType);
-               if (!nat)
-                       return false;
-
-               /* add all descriptors in {Field,Method}ref to the descriptor_pool */
-
-               if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
-                       return false;
-
-               /* the classref is created later */
-
-               fmi->p.index = forward_fieldmethints->class_index;
-               fmi->name = nat->name;
-               fmi->descriptor = nat->descriptor;
-
-               cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
-               cpinfos[forward_fieldmethints->thisindex] = fmi;
-       
-               nff = forward_fieldmethints;
-               forward_fieldmethints = forward_fieldmethints->next;
-       }
-
-       /* everything was ok */
-
-       return true;
-}
-
-
-/* loader_load_attribute_signature *********************************************
-
-   Signature_attribute {
-       u2 attribute_name_index;
-          u4 atrribute_length;
-          u2 signature_index;
-   }
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
-{
-       classinfo *c;
-       u4         attribute_length;
-       u2         signature_index;
-
-       /* get classinfo */
-
-       c = cb->clazz;
-
-       /* check remaining bytecode */
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2))
-               return false;
-
-       /* check attribute length */
-
-       attribute_length = suck_u4(cb);
-
-       if (attribute_length != 2) {
-               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-               return false;
-       }
-
-       if (*signature != NULL) {
-               exceptions_throw_classformaterror(c, "Multiple Signature attributes");
-               return false;
-       }
-
-       /* get signature */
-
-       signature_index = suck_u2(cb);
-
-       if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
-               return false;
-
-       return true;
-}
-#endif /* defined(ENABLE_JAVASE) */
-
-
-/* load_class_from_sysloader ***************************************************
-
-   Load the class with the given name using the system class loader
-
-   IN:
-       name.............the classname
-
-   RETURN VALUE:
-       the loaded class, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-classinfo *load_class_from_sysloader(utf *name)
-{
-       methodinfo    *m;
-       java_handle_t *clo;
-       classloader_t *cl;
-       classinfo     *c;
-
-       assert(class_java_lang_Object);
-       assert(class_java_lang_ClassLoader);
-       assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
-       
-       m = class_resolveclassmethod(class_java_lang_ClassLoader,
-                                                                utf_getSystemClassLoader,
-                                                                utf_void__java_lang_ClassLoader,
-                                                                class_java_lang_Object,
-                                                                false);
-
-       if (!m)
-               return false;
-
-       clo = vm_call_method(m, NULL);
-
-       if (!clo)
-               return false;
-
-       cl = loader_hashtable_classloader_add(clo);
-
-       c = load_class_from_classloader(name, cl);
-
-       return c;
-}
-
-
-/* load_class_from_classloader *************************************************
-
-   Load the class with the given name using the given user-defined class loader.
-
-   IN:
-       name.............the classname
-          cl...............user-defined class loader
-          
-   RETURN VALUE:
-       the loaded class, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
-{
-       java_handle_t *o;
-       classinfo     *c;
-       classinfo     *tmpc;
-       java_handle_t *string;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_lookup, time_prepare, time_java, 
-                                       time_cache;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       assert(name);
-
-       /* lookup if this class has already been loaded */
-
-       c = classcache_lookup(cl, name);
-
-       RT_TIMING_GET_TIME(time_lookup);
-       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
-
-       if (c != NULL)
-               return c;
-
-       /* if other class loader than bootstrap, call it */
-
-       if (cl != NULL) {
-               methodinfo *lc;
-               char       *text;
-               s4          namelen;
-
-               text = name->text;
-               namelen = name->blength;
-
-               /* handle array classes */
-               if (text[0] == '[') {
-                       classinfo *comp;
-                       utf       *u;
-
-                       switch (text[1]) {
-                       case 'L':
-                               /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
-                               if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
-                                       exceptions_throw_classnotfoundexception(name);
-                                       return false;
-                               }
-
-                               u = utf_new(text + 2, namelen - 3);
-
-                               if (!(comp = load_class_from_classloader(u, cl)))
-                                       return false;
-
-                               /* create the array class */
-
-                               c = class_array_of(comp, false);
-
-                               tmpc = classcache_store(cl, c, true);
-
-                               if (tmpc == NULL) {
-                                       /* exception, free the loaded class */
-                                       c->state &= ~CLASS_LOADING;
-                                       class_free(c);
-                               }
-
-                               return tmpc;
-
-                       case '[':
-                               /* load the component class */
-
-                               u = utf_new(text + 1, namelen - 1);
-
-                               if (!(comp = load_class_from_classloader(u, cl)))
-                                       return false;
-
-                               /* create the array class */
-
-                               c = class_array_of(comp, false);
-
-                               tmpc = classcache_store(cl, c, true);
-
-                               if (tmpc == NULL) {
-                                       /* exception, free the loaded class */
-                                       c->state &= ~CLASS_LOADING;
-                                       class_free(c);
-                               }
-
-                               return tmpc;
-
-                       default:
-                               /* primitive array classes are loaded by the bootstrap loader */
-
-                               c = load_class_bootstrap(name);
-
-                               return c;
-                       }
-               }
-
-               LLNI_class_get(cl, c);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-               /* OpenJDK uses this internal function because it's
-                  synchronized. */
-
-               lc = class_resolveclassmethod(c,
-                                                                         utf_loadClassInternal,
-                                                                         utf_java_lang_String__java_lang_Class,
-                                                                         NULL,
-                                                                         true);
-#else
-               lc = class_resolveclassmethod(c,
-                                                                         utf_loadClass,
-                                                                         utf_java_lang_String__java_lang_Class,
-                                                                         NULL,
-                                                                         true);
-#endif
-
-               if (lc == NULL)
-                       return false; /* exception */
-
-               /* move return value into `o' and cast it afterwards to a classinfo* */
-
-               string = javastring_new_slash_to_dot(name);
-
-               RT_TIMING_GET_TIME(time_prepare);
-
-               o = vm_call_method(lc, (java_handle_t *) cl, string);
-
-               RT_TIMING_GET_TIME(time_java);
-
-               c = LLNI_classinfo_unwrap(o);
-
-               if (c != NULL) {
-                       /* Store this class in the loaded class cache. If another
-                          class with the same (initloader,name) pair has been
-                          stored earlier it will be returned by classcache_store
-                          In this case classcache_store may not free the class
-                          because it has already been exposed to Java code which
-                          may have kept references to that class. */
-
-                   tmpc = classcache_store(cl, c, false);
-
-                       if (tmpc == NULL) {
-                               /* exception, free the loaded class */
-                               c->state &= ~CLASS_LOADING;
-                               class_free(c);
-                       }
-
-                       c = tmpc;
-               }
-
-               RT_TIMING_GET_TIME(time_cache);
-
-               RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
-               RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
-               RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
-
-               /* SUN compatible -verbose:class output */
-
-               if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
-                       printf("[Loaded ");
-                       utf_display_printable_ascii_classname(name);
-                       printf("]\n");
-               }
-
-#if defined(ENABLE_JVMTI)
-               /* fire Class Load JVMTI event */
-               if (jvmti) jvmti_ClassLoadPrepare(false, c);
-#endif
-
-
-               return c;
-       } 
-
-       c = load_class_bootstrap(name);
-
-       return c;
-}
-
-
-/* load_class_bootstrap ********************************************************
-       
-   Load the class with the given name using the bootstrap class loader.
-
-   IN:
-       name.............the classname
-
-   RETURN VALUE:
-       loaded classinfo, or
-          NULL if an exception has been thrown
-
-   SYNCHRONIZATION:
-       load_class_bootstrap is synchronized. It can be treated as an
-          atomic operation.
-
-*******************************************************************************/
-
-classinfo *load_class_bootstrap(utf *name)
-{
-       classbuffer *cb;
-       classinfo   *c;
-       classinfo   *r;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_lookup, time_array, time_suck, 
-                                       time_load, time_cache;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       /* for debugging */
-
-       assert(name);
-
-       /* lookup if this class has already been loaded */
-
-       r = classcache_lookup(NULL, name);
-
-       if (r != NULL) {
-               RT_TIMING_GET_TIME(time_lookup);
-               RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
-               
-               return r;
-       }
-
-       RT_TIMING_GET_TIME(time_lookup);
-       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
-               
-       /* create the classinfo */
-
-       c = class_create_classinfo(name);
-
-       /* handle array classes */
-
-       if (name->text[0] == '[') {
-               c = load_newly_created_array(c, NULL);
-
-               if (c == NULL)
-                       return NULL;
-
-               assert(c->state & CLASS_LOADED);
-
-               RT_TIMING_GET_TIME(time_array);
-               RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
-               
-               return c;
-       }
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getcompilingtime)
-               compilingtime_stop();
-
-       if (opt_getloadingtime)
-               loadingtime_start();
-#endif
-
-       /* load classdata, throw exception on error */
-
-       cb = suck_start(c);
-
-       if (cb == NULL) {
-               exceptions_throw_classnotfoundexception(name);
-               return NULL;
-       }
-
-       RT_TIMING_GET_TIME(time_suck);
-       
-       /* load the class from the buffer */
-
-       r = load_class_from_classbuffer(cb);
-
-       RT_TIMING_GET_TIME(time_load);
-       
-       if (r == NULL) {
-               /* the class could not be loaded, free the classinfo struct */
-
-               class_free(c);
-       }
-       else {
-               /* Store this class in the loaded class cache this step also
-                  checks the loading constraints. If the class has been
-                  loaded before, the earlier loaded class is returned. */
-
-               classinfo *res = classcache_store(NULL, c, true);
-
-               if (res == NULL) {
-                       /* exception */
-                       class_free(c);
-               }
-               else {
-                       /* Add the package name to the boot packages. */
-
-                       Package_add(c->packagename);
-               }
-
-               r = res;
-       }
-
-       RT_TIMING_GET_TIME(time_cache);
-       
-       /* SUN compatible -verbose:class output */
-
-       if (opt_verboseclass && r) {
-               printf("[Loaded ");
-               utf_display_printable_ascii_classname(name);
-               printf(" from %s]\n", cb->path);
-       }
-
-       /* free memory */
-
-       suck_stop(cb);
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_stop();
-
-       if (opt_getcompilingtime)
-               compilingtime_start();
-#endif
-
-       RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
-       RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
-       RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
-       RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
-
-       return r;
-}
-
-
-/* load_class_from_classbuffer_intern ******************************************
-       
-   Loads a class from a classbuffer into a given classinfo structure.
-   Super-classes are also loaded at this point and some verfication
-   checks are done.
-
-   SYNCHRONIZATION:
-       This function is NOT synchronized!
-   
-*******************************************************************************/
-
-static bool load_class_from_classbuffer_intern(classbuffer *cb)
-{
-       classinfo          *c;
-       classinfo          *tc;
-       utf                *name;
-       utf                *supername;
-       utf               **interfacesnames;
-       utf                *u;
-       constant_classref  *cr;
-       int16_t             index;
-
-       u4 i,j;
-       u4 ma, mi;
-       descriptor_pool *descpool;
-#if defined(ENABLE_STATISTICS)
-       u4 classrefsize;
-       u4 descsize;
-#endif
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_checks, time_ndpool, time_cpool,
-                                       time_setup, time_fields, time_methods, time_classrefs,
-                                       time_descs,     time_setrefs, time_parsefds, time_parsemds,
-                                       time_parsecpool, time_verify, time_attrs;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       /* Get the classbuffer's class. */
-
-       c = cb->clazz;
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
-               return false;
-
-       /* check signature */
-
-       if (suck_u4(cb) != MAGIC) {
-               exceptions_throw_classformaterror(c, "Bad magic number");
-               return false;
-       }
-
-       /* check version */
-
-       mi = suck_u2(cb);
-       ma = suck_u2(cb);
-
-       if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
-               exceptions_throw_unsupportedclassversionerror(c, ma, mi);
-               return false;
-       }
-
-       RT_TIMING_GET_TIME(time_checks);
-
-       /* create a new descriptor pool */
-
-       descpool = descriptor_pool_new(c);
-
-       RT_TIMING_GET_TIME(time_ndpool);
-
-       /* load the constant pool */
-
-       if (!load_constantpool(cb, descpool))
-               return false;
-
-       RT_TIMING_GET_TIME(time_cpool);
-
-       /* ACC flags */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* We OR the flags here, as we set already some flags in
-          class_create_classinfo. */
-
-       c->flags |= suck_u2(cb);
-
-       /* check ACC flags consistency */
-
-       if (c->flags & ACC_INTERFACE) {
-               if (!(c->flags & ACC_ABSTRACT)) {
-                       /* We work around this because interfaces in JDK 1.1 are
-                        * not declared abstract. */
-
-                       c->flags |= ACC_ABSTRACT;
-               }
-
-               if (c->flags & ACC_FINAL) {
-                       exceptions_throw_classformaterror(c,
-                                                                                         "Illegal class modifiers: 0x%X",
-                                                                                         c->flags);
-                       return false;
-               }
-
-               if (c->flags & ACC_SUPER) {
-                       c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
-               }
-       }
-
-       if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
-               exceptions_throw_classformaterror(c,
-                                                                                 "Illegal class modifiers: 0x%X",
-                                                                                 c->flags);
-               return false;
-       }
-
-       if (!suck_check_classbuffer_size(cb, 2 + 2))
-               return false;
-
-       /* This class. */
-
-       index = suck_u2(cb);
-
-       name = (utf *) class_getconstant(c, index, CONSTANT_Class);
-
-       if (name == NULL)
-               return false;
-
-       if (c->name == utf_not_named_yet) {
-               /* we finally have a name for this class */
-               c->name = name;
-               class_set_packagename(c);
-       }
-       else if (name != c->name) {
-               exceptions_throw_noclassdeffounderror_wrong_name(c, name);
-               return false;
-       }
-
-       /* Retrieve superclass. */
-
-       c->super = NULL;
-
-       index = suck_u2(cb);
-
-       if (index == 0) {
-               supername = NULL;
-
-               /* This is only allowed for java.lang.Object. */
-
-               if (c->name != utf_java_lang_Object) {
-                       exceptions_throw_classformaterror(c, "Bad superclass index");
-                       return false;
-               }
-       }
-       else {
-               supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
-
-               if (supername == NULL)
-                       return false;
-
-               /* java.lang.Object may not have a super class. */
-
-               if (c->name == utf_java_lang_Object) {
-                       exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
-                       return false;
-               }
-
-               /* Detect circularity. */
-
-               if (supername == c->name) {
-                       exceptions_throw_classcircularityerror(c);
-                       return false;
-               }
-
-               /* Interfaces must have java.lang.Object as super class. */
-
-               if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
-                       exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
-                       return false;
-               }
-       }
-
-       /* Parse the super interfaces. */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       c->interfacescount = suck_u2(cb);
-
-       if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
-               return false;
-
-       c->interfaces = MNEW(classinfo*, c->interfacescount);
-
-       /* Get the names of the super interfaces. */
-
-       interfacesnames = DMNEW(utf*, c->interfacescount);
-
-       for (i = 0; i < c->interfacescount; i++) {
-               index = suck_u2(cb);
-
-               u = (utf *) class_getconstant(c, index, CONSTANT_Class);
-
-               if (u == NULL)
-                       return false;
-
-               interfacesnames[i] = u;
-       }
-
-       RT_TIMING_GET_TIME(time_setup);
-
-       /* Parse fields. */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       c->fieldscount = suck_u2(cb);
-       c->fields      = MNEW(fieldinfo, c->fieldscount);
-
-       MZERO(c->fields, fieldinfo, c->fieldscount);
-
-       for (i = 0; i < c->fieldscount; i++) {
-               if (!field_load(cb, &(c->fields[i]), descpool))
-                       return false;
-       }
-
-       RT_TIMING_GET_TIME(time_fields);
-
-       /* Parse methods. */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       c->methodscount = suck_u2(cb);
-       c->methods      = MNEW(methodinfo, c->methodscount);
-
-       MZERO(c->methods, methodinfo, c->methodscount);
-       
-       for (i = 0; i < c->methodscount; i++) {
-               if (!method_load(cb, &(c->methods[i]), descpool))
-                       return false;
-       }
-
-       RT_TIMING_GET_TIME(time_methods);
-
-       /* create the class reference table */
-
-       c->classrefs =
-               descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
-
-       RT_TIMING_GET_TIME(time_classrefs);
-
-       /* allocate space for the parsed descriptors */
-
-       descriptor_pool_alloc_parsed_descriptors(descpool);
-       c->parseddescs =
-               descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat) {
-               descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
-               count_classref_len += classrefsize;
-               count_parsed_desc_len += descsize;
-       }
-#endif
-
-       RT_TIMING_GET_TIME(time_descs);
-
-       /* put the classrefs in the constant pool */
-
-       for (i = 0; i < c->cpcount; i++) {
-               if (c->cptags[i] == CONSTANT_Class) {
-                       utf *name = (utf *) c->cpinfos[i];
-                       c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
-               }
-       }
-
-       /* Resolve the super class. */
-
-       if (supername != NULL) {
-               cr = descriptor_pool_lookup_classref(descpool, supername);
-
-               if (cr == NULL)
-                       return false;
-
-               /* XXX This should be done better. */
-               tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
-
-               if (tc == NULL) {
-                       resolve_handle_pending_exception(true);
-                       return false;
-               }
-
-               /* Interfaces are not allowed as super classes. */
-
-               if (tc->flags & ACC_INTERFACE) {
-                       exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
-                       return false;
-               }
-
-               /* Don't allow extending final classes */
-
-               if (tc->flags & ACC_FINAL) {
-                       exceptions_throw_verifyerror(NULL,
-                                                                                "Cannot inherit from final class");
-                       return false;
-               }
-
-               /* Store the super class. */
-
-               c->super = tc;
-       }
-
-       /* Resolve the super interfaces. */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               u  = interfacesnames[i];
-               cr = descriptor_pool_lookup_classref(descpool, u);
-
-               if (cr == NULL)
-                       return false;
-
-               /* XXX This should be done better. */
-               tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
-
-               if (tc == NULL) {
-                       resolve_handle_pending_exception(true);
-                       return false;
-               }
-
-               /* Detect circularity. */
-
-               if (tc == c) {
-                       exceptions_throw_classcircularityerror(c);
-                       return false;
-               }
-
-               if (!(tc->flags & ACC_INTERFACE)) {
-                       exceptions_throw_incompatibleclasschangeerror(tc,
-                                                                                                                 "Implementing class");
-                       return false;
-               }
-
-               /* Store the super interface. */
-
-               c->interfaces[i] = tc;
-       }
-
-       RT_TIMING_GET_TIME(time_setrefs);
-
-       /* Parse the field descriptors. */
-
-       for (i = 0; i < c->fieldscount; i++) {
-               c->fields[i].parseddesc =
-                       descriptor_pool_parse_field_descriptor(descpool,
-                                                                                                  c->fields[i].descriptor);
-               if (!c->fields[i].parseddesc)
-                       return false;
-       }
-
-       RT_TIMING_GET_TIME(time_parsefds);
-
-       /* parse method descriptors */
-
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &c->methods[i];
-               m->parseddesc =
-                       descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
-                                                                                                       m->flags, class_get_self_classref(m->clazz));
-               if (!m->parseddesc)
-                       return false;
-
-               for (j = 0; j < m->rawexceptiontablelength; j++) {
-                       if (!m->rawexceptiontable[j].catchtype.any)
-                               continue;
-
-                       if ((m->rawexceptiontable[j].catchtype.ref =
-                                descriptor_pool_lookup_classref(descpool,
-                                               (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
-                               return false;
-               }
-
-               for (j = 0; j < m->thrownexceptionscount; j++) {
-                       if (!m->thrownexceptions[j].any)
-                               continue;
-
-                       if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
-                                               (utf *) m->thrownexceptions[j].any)) == NULL)
-                               return false;
-               }
-       }
-
-       RT_TIMING_GET_TIME(time_parsemds);
-
-       /* parse the loaded descriptors */
-
-       for (i = 0; i < c->cpcount; i++) {
-               constant_FMIref *fmi;
-               s4               index;
-
-               switch (c->cptags[i]) {
-               case CONSTANT_Fieldref:
-                       fmi = (constant_FMIref *) c->cpinfos[i];
-                       fmi->parseddesc.fd =
-                               descriptor_pool_parse_field_descriptor(descpool,
-                                                                                                          fmi->descriptor);
-                       if (!fmi->parseddesc.fd)
-                               return false;
-
-                       index = fmi->p.index;
-                       fmi->p.classref =
-                               (constant_classref *) class_getconstant(c, index,
-                                                                                                               CONSTANT_Class);
-                       if (!fmi->p.classref)
-                               return false;
-                       break;
-               case CONSTANT_Methodref:
-               case CONSTANT_InterfaceMethodref:
-                       fmi = (constant_FMIref *) c->cpinfos[i];
-                       index = fmi->p.index;
-                       fmi->p.classref =
-                               (constant_classref *) class_getconstant(c, index,
-                                                                                                               CONSTANT_Class);
-                       if (!fmi->p.classref)
-                               return false;
-                       fmi->parseddesc.md =
-                               descriptor_pool_parse_method_descriptor(descpool,
-                                                                                                               fmi->descriptor,
-                                                                                                               ACC_UNDEF,
-                                                                                                               fmi->p.classref);
-                       if (!fmi->parseddesc.md)
-                               return false;
-                       break;
-               }
-       }
-
-       RT_TIMING_GET_TIME(time_parsecpool);
-
-#ifdef ENABLE_VERIFIER
-       /* Check if all fields and methods can be uniquely
-        * identified by (name,descriptor). */
-
-       if (opt_verify) {
-               /* We use a hash table here to avoid making the
-                * average case quadratic in # of methods, fields.
-                */
-               static int shift = 0;
-               u2 *hashtab;
-               u2 *next; /* for chaining colliding hash entries */
-               size_t len;
-               size_t hashlen;
-               u2 index;
-               u2 old;
-
-               /* Allocate hashtable */
-               len = c->methodscount;
-               if (len < c->fieldscount) len = c->fieldscount;
-               hashlen = 5 * len;
-               hashtab = MNEW(u2,(hashlen + len));
-               next = hashtab + hashlen;
-
-               /* Determine bitshift (to get good hash values) */
-               if (!shift) {
-                       len = sizeof(utf);
-                       while (len) {
-                               len >>= 1;
-                               shift++;
-                       }
-               }
-
-               /* Check fields */
-               memset(hashtab, 0, sizeof(u2) * (hashlen + len));
-
-               for (i = 0; i < c->fieldscount; ++i) {
-                       fieldinfo *fi = c->fields + i;
-
-                       /* It's ok if we lose bits here */
-                       index = ((((size_t) fi->name) +
-                                         ((size_t) fi->descriptor)) >> shift) % hashlen;
-
-                       if ((old = hashtab[index])) {
-                               old--;
-                               next[i] = old;
-                               do {
-                                       if (c->fields[old].name == fi->name &&
-                                               c->fields[old].descriptor == fi->descriptor) {
-                                               exceptions_throw_classformaterror(c, "Repetitive field name/signature");
-                                               return false;
-                                       }
-                               } while ((old = next[old]));
-                       }
-                       hashtab[index] = i + 1;
-               }
-
-               /* Check methods */
-               memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
-
-               for (i = 0; i < c->methodscount; ++i) {
-                       methodinfo *mi = c->methods + i;
-
-                       /* It's ok if we lose bits here */
-                       index = ((((size_t) mi->name) +
-                                         ((size_t) mi->descriptor)) >> shift) % hashlen;
-
-                       if ((old = hashtab[index])) {
-                               old--;
-                               next[i] = old;
-                               do {
-                                       if (c->methods[old].name == mi->name &&
-                                               c->methods[old].descriptor == mi->descriptor) {
-                                               exceptions_throw_classformaterror(c, "Repetitive method name/signature");
-                                               return false;
-                                       }
-                               } while ((old = next[old]));
-                       }
-                       hashtab[index] = i + 1;
-               }
-
-               MFREE(hashtab, u2, (hashlen + len));
-       }
-#endif /* ENABLE_VERIFIER */
-
-       RT_TIMING_GET_TIME(time_verify);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat) {
-               size_classinfo  += sizeof(classinfo*) * c->interfacescount;
-               size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
-               size_methodinfo += sizeof(methodinfo) * c->methodscount;
-       }
-#endif
-
-       /* load attribute structures */
-
-       if (!class_load_attributes(cb))
-               return false;
-
-       /* Pre Java 1.5 version don't check this. This implementation is
-          like Java 1.5 do it: for class file version 45.3 we don't check
-          it, older versions are checked. */
-
-       if (((ma == 45) && (mi > 3)) || (ma > 45)) {
-               /* check if all data has been read */
-               s4 classdata_left = ((cb->data + cb->size) - cb->pos);
-
-               if (classdata_left > 0) {
-                       exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
-                       return false;
-               }
-       }
-
-       RT_TIMING_GET_TIME(time_attrs);
-
-       RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
-       RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
-       RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
-       RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
-       RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
-       RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
-       RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
-       RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
-       RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
-       RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
-       RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
-       RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
-       RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
-       RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
-       RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
-
-       return true;
-}
-
-
-/* load_class_from_classbuffer *************************************************
-
-   Convenience wrapper for load_class_from_classbuffer.
-
-   SYNCHRONIZATION:
-       This function is NOT synchronized!
-   
-*******************************************************************************/
-
-classinfo *load_class_from_classbuffer(classbuffer *cb)
-{
-       classinfo *c;
-       bool       result;
-       int32_t    dumpmarker;
-
-       /* Get the classbuffer's class. */
-
-       c = cb->clazz;
-
-       /* Check if the class is already loaded. */
-
-       if (c->state & CLASS_LOADED)
-               return c;
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_class_loads++;
-#endif
-
-#if !defined(NDEBUG)
-       if (loadverbose)
-               log_message_class("Loading class: ", c);
-#endif
-
-       /* Mark start of dump memory area. */
-
-       DMARKER;
-
-       /* Class is currently loading. */
-
-       c->state |= CLASS_LOADING;
-
-       /* Parse the classbuffer. */
-
-       result = load_class_from_classbuffer_intern(cb);
-
-       /* Release dump area. */
-
-       DRELEASE;
-
-       /* An error occurred. */
-
-       if (result == false) {
-               /* Revert loading state. */
-
-               c->state = (c->state & ~CLASS_LOADING);
-
-               return NULL;
-       }
-
-       /* Revert loading state and set loaded. */
-
-       c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
-
-#if defined(ENABLE_JVMTI)
-       /* fire Class Prepare JVMTI event */
-
-       if (jvmti)
-               jvmti_ClassLoadPrepare(true, c);
-#endif
-
-#if !defined(NDEBUG)
-       if (loadverbose)
-               log_message_class("Loading done class: ", c);
-#endif
-
-       return c;
-}
-
-
-/* load_newly_created_array ****************************************************
-
-   Load a newly created array class.
-
-       RETURN VALUE:
-           c....................the array class C has been loaded
-               other classinfo......the array class was found in the class cache, 
-                                    C has been freed
-           NULL.................an exception has been thrown
-
-       Note:
-               This is an internal function. Do not use it unless you know exactly
-               what you are doing!
-
-               Use one of the load_class_... functions for general array class loading.
-
-*******************************************************************************/
-
-classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
-{
-       classinfo         *comp = NULL;
-       methodinfo        *clone;
-       methoddesc        *clonedesc;
-       constant_classref *classrefs;
-       char              *text;
-       s4                 namelen;
-       utf               *u;
-
-       text    = c->name->text;
-       namelen = c->name->blength;
-
-       /* Check array class name */
-
-       if ((namelen < 2) || (text[0] != '[')) {
-               exceptions_throw_classnotfoundexception(c->name);
-               return NULL;
-       }
-
-       /* Check the element type */
-
-       switch (text[1]) {
-       case '[':
-               /* c is an array of arrays. We have to create the component class. */
-
-               u = utf_new(text + 1, namelen - 1);
-
-               comp = load_class_from_classloader(u, loader);
-
-               if (comp == NULL)
-                       return NULL;
-
-               assert(comp->state & CLASS_LOADED);
-
-               /* the array's flags are that of the component class */
-               c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
-               c->classloader = comp->classloader;
-               break;
-
-       case 'L':
-               /* c is an array of objects. */
-
-               /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
-               if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
-                       exceptions_throw_classnotfoundexception(c->name);
-                       return NULL;
-               }
-
-               u = utf_new(text + 2, namelen - 3);
-
-               if (!(comp = load_class_from_classloader(u, loader)))
-                       return NULL;
-
-               assert(comp->state & CLASS_LOADED);
-
-               /* the array's flags are that of the component class */
-               c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
-               c->classloader = comp->classloader;
-               break;
-
-       default:
-               /* c is an array of a primitive type */
-
-               /* check for cases like `[II' and whether the character is a
-                  valid primitive type */
-
-               if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
-                       exceptions_throw_classnotfoundexception(c->name);
-                       return NULL;
-               }
-
-               /* the accessibility of the array class is public (VM Spec 5.3.3) */
-               c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
-               c->classloader = NULL;
-       }
-
-       assert(class_java_lang_Object);
-#if defined(ENABLE_JAVASE)
-       assert(class_java_lang_Cloneable);
-       assert(class_java_io_Serializable);
-#endif
-
-       /* Setup the array class. */
-
-       c->super = class_java_lang_Object;
-
-#if defined(ENABLE_JAVASE)
-
-       c->interfacescount = 2;
-    c->interfaces      = MNEW(classinfo*, 2);
-       c->interfaces[0]   = class_java_lang_Cloneable;
-       c->interfaces[1]   = class_java_io_Serializable;
-
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-
-       c->interfacescount = 0;
-       c->interfaces      = NULL;
-
-#else
-# error unknow Java configuration
-#endif
-
-       c->methodscount = 1;
-       c->methods      = MNEW(methodinfo, c->methodscount);
-
-       MZERO(c->methods, methodinfo, c->methodscount);
-
-       classrefs = MNEW(constant_classref, 2);
-
-       CLASSREF_INIT(classrefs[0], c, c->name);
-       CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
-
-       /* create descriptor for clone method */
-       /* we need one paramslot which is reserved for the 'this' parameter */
-       clonedesc = NEW(methoddesc);
-       clonedesc->returntype.type = TYPE_ADR;
-       clonedesc->returntype.classref = classrefs + 1;
-       clonedesc->returntype.arraydim = 0;
-       /* initialize params to "empty", add real params below in
-          descriptor_params_from_paramtypes */
-       clonedesc->paramcount = 0;
-       clonedesc->paramslots = 0;
-       clonedesc->paramtypes[0].classref = classrefs + 0;
-       clonedesc->params = NULL;
-
-       /* create methodinfo */
-
-       clone = c->methods;
-       MSET(clone, 0, methodinfo, 1);
-
-#if defined(ENABLE_THREADS)
-       lock_init_object_lock(&clone->header);
-#endif
-
-       /* ATTENTION: if you delete the ACC_NATIVE below, set
-          clone->maxlocals=1 (interpreter related) */
-
-       clone->flags      = ACC_PUBLIC | ACC_NATIVE;
-       clone->name       = utf_clone;
-       clone->descriptor = utf_void__java_lang_Object;
-       clone->parseddesc = clonedesc;
-       clone->clazz      = c;
-
-       /* parse the descriptor to get the register allocation */
-
-       if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
-               return false;
-
-       clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
-
-       /* XXX: field: length? */
-
-       /* array classes are not loaded from class files */
-
-       c->state          |= CLASS_LOADED;
-       c->parseddescs    = (u1 *) clonedesc;
-       c->parseddescsize = sizeof(methodinfo);
-       c->classrefs      = classrefs;
-       c->classrefcount  = 1;
-
-       /* insert class into the loaded class cache */
-       /* XXX free classinfo if NULL returned? */
-
-       return classcache_store(loader, c, true);
-}
-
-
-/* loader_close ****************************************************************
-
-   Frees all resources.
-       
-*******************************************************************************/
-
-void loader_close(void)
-{
-       /* empty */
-}
-
-
-/*
- * 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/vmcore/loader.h b/src/vmcore/loader.h
deleted file mode 100644 (file)
index faa9ba5..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* src/vmcore/loader.h - class loader header
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _LOADER_H
-#define _LOADER_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct classbuffer classbuffer;
-
-
-#include "config.h"
-
-#include <stdio.h>
-
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "vmcore/descriptor.h"
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/references.h"
-#include "vmcore/utf8.h"
-
-
-/* constant pool entries *******************************************************
-
-       All constant pool entries need a data structure which contain the entrys
-       value. In some cases this structure exist already, in the remaining cases
-       this structure must be generated:
-
-               kind                      structure                     generated?
-       ----------------------------------------------------------------------
-    CONSTANT_Class               constant_classref                  yes
-    CONSTANT_Fieldref            constant_FMIref                    yes
-    CONSTANT_Methodref           constant_FMIref                    yes
-    CONSTANT_InterfaceMethodref  constant_FMIref                    yes
-    CONSTANT_String              unicode                             no
-    CONSTANT_Integer             constant_integer                   yes
-    CONSTANT_Float               constant_float                     yes
-    CONSTANT_Long                constant_long                      yes
-    CONSTANT_Double              constant_double                    yes
-    CONSTANT_NameAndType         constant_nameandtype               yes
-    CONSTANT_Utf8                unicode                             no
-    CONSTANT_UNUSED              -
-
-*******************************************************************************/
-
-typedef struct {            /* Integer                                        */
-       s4 value;
-} constant_integer;
-
-       
-typedef struct {            /* Float                                          */
-       float value;
-} constant_float;
-
-
-typedef struct {            /* Long                                           */
-       s8 value;
-} constant_long;
-       
-
-typedef struct {            /* Double                                         */
-       double value;
-} constant_double;
-
-
-typedef struct {            /* NameAndType (Field or Method)                  */
-       utf *name;              /* field/method name                              */
-       utf *descriptor;        /* field/method type descriptor string            */
-} constant_nameandtype;
-
-
-/* classbuffer ****************************************************************/
-
-struct classbuffer {
-       classinfo *clazz;                   /* pointer to classinfo structure     */
-       uint8_t   *data;                    /* pointer to byte code               */
-       int32_t    size;                    /* size of the byte code              */
-       uint8_t   *pos;                     /* current read position              */
-       char      *path;                    /* path to file (for debugging)       */
-};
-
-
-/* hashtable_classloader_entry *************************************************
-
-   ATTENTION: The pointer to the classloader object needs to be the
-   first field of the entry, so that it can be used as an indirection
-   cell. This is checked by gc_init() during startup.
-
-*******************************************************************************/
-
-typedef struct hashtable_classloader_entry hashtable_classloader_entry;
-
-struct hashtable_classloader_entry {
-       java_object_t               *object;
-       hashtable_classloader_entry *hashlink;
-};
-
-
-/* classloader *****************************************************************
-
-   [!ENABLE_HANDLES]: The classloader is a Java Object which cannot move.
-   [ENABLE_HANDLES] : The classloader entry itself is a static handle for a
-                      given classloader (use loader_hashtable_classloader_foo).
-
-*******************************************************************************/
-
-#if defined(ENABLE_HANDLES)
-typedef hashtable_classloader_entry classloader_t;
-#else
-typedef java_object_t               classloader_t;
-#endif
-
-
-/* function prototypes ********************************************************/
-
-void loader_preinit(void);
-void loader_init(void);
-
-/* classloader management functions */
-classloader_t *loader_hashtable_classloader_add(java_handle_t *cl);
-classloader_t *loader_hashtable_classloader_find(java_handle_t *cl);
-
-void loader_load_all_classes(void);
-
-bool loader_skip_attribute_body(classbuffer *cb);
-
-#if defined(ENABLE_JAVASE)
-bool loader_load_attribute_signature(classbuffer *cb, utf **signature);
-#endif
-
-/* free resources */
-void loader_close(void);
-
-/* class loading functions */
-classinfo *load_class_from_sysloader(utf *name);
-classinfo *load_class_from_classloader(utf *name, classloader_t *cl);
-classinfo *load_class_bootstrap(utf *name);
-
-/* (don't use the following directly) */
-classinfo *load_class_from_classbuffer(classbuffer *cb);
-classinfo *load_newly_created_array(classinfo *c, classloader_t *loader);
-
-#endif /* _LOADER_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/vmcore/method.c b/src/vmcore/method.c
deleted file mode 100644 (file)
index 393ad44..0000000
+++ /dev/null
@@ -1,1207 +0,0 @@
-/* src/vmcore/method.c - method functions
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "threads/lock-common.h"
-
-#include "vm/array.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/resolve.h"
-#include "vm/vm.h"
-
-#include "vm/jit/code.h"
-#include "vm/jit/methodheader.h"
-
-#include "vm/jit_interface.h"
-
-#include "vmcore/class.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/suck.h"
-#include "vmcore/utf8.h"
-
-
-#if !defined(NDEBUG) && defined(ENABLE_INLINING)
-#define INLINELOG(code)  do { if (opt_TraceInlining) { code } } while (0)
-#else
-#define INLINELOG(code)
-#endif
-
-
-/* global variables ***********************************************************/
-
-methodinfo *method_java_lang_reflect_Method_invoke;
-
-
-/* method_init *****************************************************************
-
-   Initialize method subsystem.
-
-*******************************************************************************/
-
-void method_init(void)
-{
-#if defined(ENABLE_JAVASE)
-       /* Sanity check. */
-
-       if (class_java_lang_reflect_Method == NULL)
-               vm_abort("method_init: class_java_lang_reflect_Method is NULL");
-
-       /* Cache java.lang.reflect.Method.invoke() */
-
-       method_java_lang_reflect_Method_invoke =
-               class_findmethod(class_java_lang_reflect_Method, utf_invoke, NULL);
-
-       if (method_java_lang_reflect_Method_invoke == NULL)
-               vm_abort("method_init: Could not resolve method java.lang.reflect.Method.invoke().");
-#endif
-}
-
-
-/* method_load *****************************************************************
-
-   Loads a method from the class file and fills an existing methodinfo
-   structure.
-
-   method_info {
-       u2 access_flags;
-          u2 name_index;
-          u2 descriptor_index;
-          u2 attributes_count;
-          attribute_info attributes[attribute_count];
-   }
-
-   attribute_info {
-       u2 attribute_name_index;
-          u4 attribute_length;
-          u1 info[attribute_length];
-   }
-
-   LineNumberTable_attribute {
-       u2 attribute_name_index;
-          u4 attribute_length;
-          u2 line_number_table_length;
-          {
-              u2 start_pc;
-                  u2 line_number;
-          } line_number_table[line_number_table_length];
-   }
-
-*******************************************************************************/
-
-bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
-{
-       classinfo *c;
-       int argcount;
-       s4         i, j, k, l;
-       utf       *u;
-       u2         name_index;
-       u2         descriptor_index;
-       u2         attributes_count;
-       u2         attribute_name_index;
-       utf       *attribute_name;
-       u2         code_attributes_count;
-       u2         code_attribute_name_index;
-       utf       *code_attribute_name;
-
-       /* get classinfo */
-
-       c = cb->clazz;
-
-       LOCK_INIT_OBJECT_LOCK(&(m->header));
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_all_methods++;
-#endif
-
-       /* all fields of m have been zeroed in load_class_from_classbuffer */
-
-       m->clazz = c;
-       
-       if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
-               return false;
-
-       /* access flags */
-
-       m->flags = suck_u2(cb);
-
-       /* name */
-
-       name_index = suck_u2(cb);
-
-       if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
-               return false;
-
-       m->name = u;
-
-       /* descriptor */
-
-       descriptor_index = suck_u2(cb);
-
-       if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
-               return false;
-
-       m->descriptor = u;
-
-       if (!descriptor_pool_add(descpool, u, &argcount))
-               return false;
-
-#ifdef ENABLE_VERIFIER
-       if (opt_verify) {
-               if (!is_valid_name_utf(m->name)) {
-                       exceptions_throw_classformaterror(c, "Method with invalid name");
-                       return false;
-               }
-
-               if (m->name->text[0] == '<' &&
-                       m->name != utf_init && m->name != utf_clinit) {
-                       exceptions_throw_classformaterror(c, "Method with invalid special name");
-                       return false;
-               }
-       }
-#endif /* ENABLE_VERIFIER */
-       
-       if (!(m->flags & ACC_STATIC))
-               argcount++; /* count the 'this' argument */
-
-#ifdef ENABLE_VERIFIER
-       if (opt_verify) {
-               if (argcount > 255) {
-                       exceptions_throw_classformaterror(c, "Too many arguments in signature");
-                       return false;
-               }
-
-               /* check flag consistency */
-               if (m->name != utf_clinit) {
-                       i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
-
-                       if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
-                               exceptions_throw_classformaterror(c,
-                                                                                                 "Illegal method modifiers: 0x%X",
-                                                                                                 m->flags);
-                               return false;
-                       }
-
-                       if (m->flags & ACC_ABSTRACT) {
-                               if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
-                                                                ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
-                                       exceptions_throw_classformaterror(c,
-                                                                                                         "Illegal method modifiers: 0x%X",
-                                                                                                         m->flags);
-                                       return false;
-                               }
-                       }
-
-                       if (c->flags & ACC_INTERFACE) {
-                               if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
-                                       exceptions_throw_classformaterror(c,
-                                                                                                         "Illegal method modifiers: 0x%X",
-                                                                                                         m->flags);
-                                       return false;
-                               }
-                       }
-
-                       if (m->name == utf_init) {
-                               if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
-                                                               ACC_NATIVE | ACC_ABSTRACT)) {
-                                       exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
-                                       return false;
-                               }
-                       }
-               }
-       }
-#endif /* ENABLE_VERIFIER */
-
-       /* mark the method as monomorphic until further notice */
-
-       m->flags |= ACC_METHOD_MONOMORPHIC;
-
-       /* non-abstract methods have an implementation in this class */
-
-       if (!(m->flags & ACC_ABSTRACT))
-               m->flags |= ACC_METHOD_IMPLEMENTED;
-               
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* attributes count */
-
-       attributes_count = suck_u2(cb);
-
-       for (i = 0; i < attributes_count; i++) {
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               /* attribute name index */
-
-               attribute_name_index = suck_u2(cb);
-
-               attribute_name =
-                       class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
-
-               if (attribute_name == NULL)
-                       return false;
-
-               if (attribute_name == utf_Code) {
-                       /* Code */
-
-                       if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
-                               exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
-                               return false;
-                       }
-                       
-                       if (m->jcode) {
-                               exceptions_throw_classformaterror(c, "Multiple Code attributes");
-                               return false;
-                       }
-
-                       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
-                               return false;
-
-                       suck_u4(cb);
-                       m->maxstack = suck_u2(cb);
-                       m->maxlocals = suck_u2(cb);
-
-                       if (m->maxlocals < argcount) {
-                               exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
-                               return false;
-                       }
-                       
-                       if (!suck_check_classbuffer_size(cb, 4))
-                               return false;
-
-                       m->jcodelength = suck_u4(cb);
-
-                       if (m->jcodelength == 0) {
-                               exceptions_throw_classformaterror(c, "Code of a method has length 0");
-                               return false;
-                       }
-                       
-                       if (m->jcodelength > 65535) {
-                               exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
-                               return false;
-                       }
-
-                       if (!suck_check_classbuffer_size(cb, m->jcodelength))
-                               return false;
-
-                       m->jcode = MNEW(u1, m->jcodelength);
-                       suck_nbytes(m->jcode, cb, m->jcodelength);
-
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       m->rawexceptiontablelength = suck_u2(cb);
-                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
-                               return false;
-
-                       m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
-
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat) {
-                               count_vmcode_len += m->jcodelength + 18;
-                               count_extable_len +=
-                                       m->rawexceptiontablelength * sizeof(raw_exception_entry);
-                       }
-#endif
-
-                       for (j = 0; j < m->rawexceptiontablelength; j++) {
-                               u4 idx;
-                               m->rawexceptiontable[j].startpc   = suck_u2(cb);
-                               m->rawexceptiontable[j].endpc     = suck_u2(cb);
-                               m->rawexceptiontable[j].handlerpc = suck_u2(cb);
-
-                               idx = suck_u2(cb);
-
-                               if (!idx) {
-                                       m->rawexceptiontable[j].catchtype.any = NULL;
-                               }
-                               else {
-                                       /* the classref is created later */
-                                       if (!(m->rawexceptiontable[j].catchtype.any =
-                                                 (utf *) class_getconstant(c, idx, CONSTANT_Class)))
-                                               return false;
-                               }
-                       }
-
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       /* code attributes count */
-
-                       code_attributes_count = suck_u2(cb);
-
-                       for (k = 0; k < code_attributes_count; k++) {
-                               if (!suck_check_classbuffer_size(cb, 2))
-                                       return false;
-
-                               /* code attribute name index */
-
-                               code_attribute_name_index = suck_u2(cb);
-
-                               code_attribute_name =
-                                       class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8);
-
-                               if (code_attribute_name == NULL)
-                                       return false;
-
-                               /* check which code attribute */
-
-                               if (code_attribute_name == utf_LineNumberTable) {
-                                       /* LineNumberTable */
-
-                                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                                               return false;
-
-                                       /* attribute length */
-
-                                       (void) suck_u4(cb);
-
-                                       /* line number table length */
-
-                                       m->linenumbercount = suck_u2(cb);
-
-                                       if (!suck_check_classbuffer_size(cb,
-                                                                                               (2 + 2) * m->linenumbercount))
-                                               return false;
-
-                                       m->linenumbers = MNEW(lineinfo, m->linenumbercount);
-
-#if defined(ENABLE_STATISTICS)
-                                       if (opt_stat)
-                                               size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
-#endif
-                                       
-                                       for (l = 0; l < m->linenumbercount; l++) {
-                                               m->linenumbers[l].start_pc    = suck_u2(cb);
-                                               m->linenumbers[l].line_number = suck_u2(cb);
-                                       }
-                               }
-#if defined(ENABLE_JAVASE)
-                               else if (code_attribute_name == utf_StackMapTable) {
-                                       /* StackTableMap */
-
-                                       if (!stackmap_load_attribute_stackmaptable(cb, m))
-                                               return false;
-                               }
-#endif
-                               else {
-                                       /* unknown code attribute */
-
-                                       if (!loader_skip_attribute_body(cb))
-                                               return false;
-                               }
-                       }
-               }
-               else if (attribute_name == utf_Exceptions) {
-                       /* Exceptions */
-
-                       if (m->thrownexceptions != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
-                               return false;
-                       }
-
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* attribute length */
-
-                       (void) suck_u4(cb);
-
-                       m->thrownexceptionscount = suck_u2(cb);
-
-                       if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
-                               return false;
-
-                       m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
-
-                       for (j = 0; j < m->thrownexceptionscount; j++) {
-                               /* the classref is created later */
-                               if (!((m->thrownexceptions)[j].any =
-                                         (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
-                                       return false;
-                       }
-               }
-#if defined(ENABLE_JAVASE)
-               else if (attribute_name == utf_Signature) {
-                       /* Signature */
-
-                       if (!loader_load_attribute_signature(cb, &(m->signature)))
-                               return false;
-               }
-
-#if defined(ENABLE_ANNOTATIONS)
-               else if (attribute_name == utf_RuntimeVisibleAnnotations) {
-                       /* RuntimeVisibleAnnotations */
-                       if (!annotation_load_method_attribute_runtimevisibleannotations(cb, m))
-                               return false;
-               }
-               else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
-                       /* RuntimeInvisibleAnnotations */
-                       if (!annotation_load_method_attribute_runtimeinvisibleannotations(cb, m))
-                               return false;
-               }
-               else if (attribute_name == utf_RuntimeVisibleParameterAnnotations) {
-                       /* RuntimeVisibleParameterAnnotations */
-                       if (!annotation_load_method_attribute_runtimevisibleparameterannotations(cb, m))
-                               return false;
-               }
-               else if (attribute_name == utf_RuntimeInvisibleParameterAnnotations) {
-                       /* RuntimeInvisibleParameterAnnotations */
-                       if (!annotation_load_method_attribute_runtimeinvisibleparameterannotations(cb, m))
-                               return false;
-               }
-               else if (attribute_name == utf_AnnotationDefault) {
-                       /* AnnotationDefault */
-                       if (!annotation_load_method_attribute_annotationdefault(cb, m))
-                               return false;
-               }
-#endif
-#endif
-               else {
-                       /* unknown attribute */
-
-                       if (!loader_skip_attribute_body(cb))
-                               return false;
-               }
-       }
-
-       if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
-               exceptions_throw_classformaterror(c, "Missing Code attribute");
-               return false;
-       }
-
-#if defined(ENABLE_REPLACEMENT)
-       /* initialize the hit countdown field */
-
-       m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
-#endif
-
-       /* everything was ok */
-
-       return true;
-}
-
-
-/* method_free *****************************************************************
-
-   Frees all memory that was allocated for this method.
-
-*******************************************************************************/
-
-void method_free(methodinfo *m)
-{
-       if (m->jcode)
-               MFREE(m->jcode, u1, m->jcodelength);
-
-       if (m->rawexceptiontable)
-               MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
-
-       code_free_code_of_method(m);
-
-       if (m->stubroutine) {
-               if (m->flags & ACC_NATIVE) {
-                       removenativestub(m->stubroutine);
-
-               } else {
-                       removecompilerstub(m->stubroutine);
-               }
-       }
-}
-
-
-/* method_canoverwrite *********************************************************
-
-   Check if m and old are identical with respect to type and
-   name. This means that old can be overwritten with m.
-       
-*******************************************************************************/
-
-bool method_canoverwrite(methodinfo *m, methodinfo *old)
-{
-       if (m->name != old->name)
-               return false;
-
-       if (m->descriptor != old->descriptor)
-               return false;
-
-       if (m->flags & ACC_STATIC)
-               return false;
-
-       return true;
-}
-
-
-/* method_new_builtin **********************************************************
-
-   Creates a minimal methodinfo structure for builtins. This comes handy
-   when dealing with builtin stubs or stacktraces.
-
-*******************************************************************************/
-
-methodinfo *method_new_builtin(builtintable_entry *bte)
-{
-       methodinfo *m;
-
-       /* allocate the methodinfo structure */
-
-       m = NEW(methodinfo);
-
-       /* initialize methodinfo structure */
-
-       MZERO(m, methodinfo, 1);
-       LOCK_INIT_OBJECT_LOCK(&(m->header));
-
-       m->flags      = ACC_METHOD_BUILTIN;
-       m->parseddesc = bte->md;
-       m->name       = bte->name;
-       m->descriptor = bte->descriptor;
-
-       /* return the newly created methodinfo */
-
-       return m;
-}
-
-
-/* method_vftbl_lookup *********************************************************
-
-   Does a method lookup in the passed virtual function table.  This
-   function does exactly the same thing as JIT, but additionally
-   relies on the fact, that the methodinfo pointer is at the first
-   data segment slot (even for compiler stubs).
-
-*******************************************************************************/
-
-methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
-{
-       methodptr   mptr;
-       methodptr  *pmptr;
-       methodinfo *resm;                   /* pointer to new resolved method     */
-
-       /* If the method is not an instance method, just return it. */
-
-       if (m->flags & ACC_STATIC)
-               return m;
-
-       assert(vftbl);
-
-       /* Get the method from the virtual function table.  Is this an
-          interface method? */
-
-       if (m->clazz->flags & ACC_INTERFACE) {
-               pmptr = vftbl->interfacetable[-(m->clazz->index)];
-               mptr  = pmptr[(m - m->clazz->methods)];
-       }
-       else {
-               mptr = vftbl->table[m->vftblindex];
-       }
-
-       /* and now get the codeinfo pointer from the first data segment slot */
-
-       resm = code_get_methodinfo_for_pv(mptr);
-
-       return resm;
-}
-
-
-/* method_get_parametercount **************************************************
-
-   Use the descriptor of a method to determine the number of parameters
-   of the method. The this pointer of non-static methods is not counted.
-
-   IN:
-       m........the method of which the parameters should be counted
-
-   RETURN VALUE:
-       The parameter count or -1 on error.
-
-*******************************************************************************/
-
-int32_t method_get_parametercount(methodinfo *m)
-{
-       methoddesc *md;             /* method descriptor of m   */
-       int32_t     paramcount = 0; /* the parameter count of m */
-
-       md = m->parseddesc;
-       
-       /* is the descriptor fully parsed? */
-
-       if (md->params == NULL) {
-               if (!descriptor_params_from_paramtypes(md, m->flags)) {
-                       return -1;
-               }
-       }
-
-       paramcount = md->paramcount;
-
-       /* skip `this' pointer */
-
-       if (!(m->flags & ACC_STATIC)) {
-               --paramcount;
-       }
-
-       return paramcount;
-}
-
-
-/* method_get_parametertypearray ***********************************************
-
-   Use the descriptor of a method to generate a java.lang.Class array
-   which contains the classes of the parametertypes of the method.
-
-   This function is called by java.lang.reflect.{Constructor,Method}.
-
-*******************************************************************************/
-
-java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m)
-{
-       methoddesc                *md;
-       typedesc                  *paramtypes;
-       int32_t                    paramcount;
-       java_handle_objectarray_t *oa;
-       int32_t                    i;
-       classinfo                 *c;
-
-       md = m->parseddesc;
-
-       /* is the descriptor fully parsed? */
-
-       if (m->parseddesc->params == NULL)
-               if (!descriptor_params_from_paramtypes(md, m->flags))
-                       return NULL;
-
-       paramtypes = md->paramtypes;
-       paramcount = md->paramcount;
-
-       /* skip `this' pointer */
-
-       if (!(m->flags & ACC_STATIC)) {
-               paramtypes++;
-               paramcount--;
-       }
-
-       /* create class-array */
-
-       oa = builtin_anewarray(paramcount, class_java_lang_Class);
-
-       if (oa == NULL)
-               return NULL;
-
-    /* get classes */
-
-       for (i = 0; i < paramcount; i++) {
-               if (!resolve_class_from_typedesc(&paramtypes[i], true, false, &c))
-                       return NULL;
-
-               LLNI_array_direct(oa, i) = (java_object_t *) c;
-       }
-
-       return oa;
-}
-
-
-/* method_get_exceptionarray ***************************************************
-
-   Get the exceptions which can be thrown by a method.
-
-*******************************************************************************/
-
-java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m)
-{
-       java_handle_objectarray_t *oa;
-       classinfo                 *c;
-       s4                         i;
-
-       /* create class-array */
-
-       oa = builtin_anewarray(m->thrownexceptionscount, class_java_lang_Class);
-
-       if (oa == NULL)
-               return NULL;
-
-       /* iterate over all exceptions and store the class in the array */
-
-       for (i = 0; i < m->thrownexceptionscount; i++) {
-               c = resolve_classref_or_classinfo_eager(m->thrownexceptions[i], true);
-
-               if (c == NULL)
-                       return NULL;
-
-               LLNI_array_direct(oa, i) = (java_object_t *) c;
-       }
-
-       return oa;
-}
-
-
-/* method_returntype_get *******************************************************
-
-   Get the return type of the method.
-
-*******************************************************************************/
-
-classinfo *method_returntype_get(methodinfo *m)
-{
-       typedesc  *td;
-       classinfo *c;
-
-       td = &(m->parseddesc->returntype);
-
-       if (!resolve_class_from_typedesc(td, true, false, &c))
-               return NULL;
-
-       return c;
-}
-
-
-/* method_count_implementations ************************************************
-
-   Count the implementations of a method in a class cone (a class and all its
-   subclasses.)
-
-   IN:
-       m................the method to count
-          c................class at which to start the counting (this class and
-                           all its subclasses will be searched)
-
-   OUT:
-       *found...........if found != NULL, *found receives the method
-                           implementation that was found. This value is only
-                                               meaningful if the return value is 1.
-
-   RETURN VALUE:
-       the number of implementations found
-
-*******************************************************************************/
-
-s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
-{
-       s4          count;
-       methodinfo *mp;
-       methodinfo *mend;
-       classinfo  *child;
-
-       count = 0;
-
-       mp = c->methods;
-       mend = mp + c->methodscount;
-
-       for (; mp < mend; ++mp) {
-               if (method_canoverwrite(mp, m)) {
-                       if (found)
-                               *found = mp;
-                       count++;
-                       break;
-               }
-       }
-
-       for (child = c->sub; child != NULL; child = child->nextsub) {
-               count += method_count_implementations(m, child, found);
-       }
-
-       return count;
-}
-
-
-/* method_get_annotations ******************************************************
-
-   Get a methods' unparsed annotations in a byte array.
-
-   IN:
-       m........the method of which the annotations should be returned
-
-   RETURN VALUE:
-       The unparsed annotations in a byte array (or NULL if there aren't any).
-
-*******************************************************************************/
-
-java_handle_bytearray_t *method_get_annotations(methodinfo *m)
-{
-#if defined(ENABLE_ANNOTATIONS)
-       classinfo     *c;                  /* methods' declaring class          */
-       int            slot;               /* methods' slot                     */
-       java_handle_t *annotations;        /* methods' unparsed annotations     */
-       java_handle_t *method_annotations; /* all methods' unparsed annotations */
-                                          /* of the declaring class            */
-
-       c           = m->clazz;
-       slot        = m - c->methods;
-       annotations = NULL;
-
-       LLNI_classinfo_field_get(c, method_annotations, method_annotations);
-
-       /* the method_annotations array might be shorter then the method
-        * count if the methods above a certain index have no annotations.
-        */     
-       if (method_annotations != NULL &&
-               array_length_get(method_annotations) > slot) {
-               annotations = array_objectarray_element_get(
-                       (java_handle_objectarray_t*)method_annotations, slot);
-       }
-       
-       return (java_handle_bytearray_t*)annotations;
-#else
-       return NULL;
-#endif
-}
-
-
-/* method_get_parameterannotations ********************************************
-
-   Get a methods' unparsed parameter annotations in an array of byte
-   arrays.
-
-   IN:
-       m........the method of which the parameter annotations should be
-                   returned
-
-   RETURN VALUE:
-       The unparsed parameter annotations in a byte array (or NULL if
-          there aren't any).
-
-*******************************************************************************/
-
-java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
-{
-#if defined(ENABLE_ANNOTATIONS)
-       classinfo     *c;                           /* methods' declaring class */
-       int            slot;                        /* methods' slot            */
-       java_handle_t *parameterAnnotations;        /* methods' unparsed        */
-                                                   /* parameter annotations    */
-       java_handle_t *method_parameterannotations; /* all methods' unparsed    */
-                                                   /* parameter annotations of */
-                                                   /* the declaring class      */
-
-       c                    = m->clazz;
-       slot                 = m - c->methods;
-       parameterAnnotations = NULL;
-
-       LLNI_classinfo_field_get(
-               c, method_parameterannotations, method_parameterannotations);
-
-       /* the method_annotations array might be shorter then the method
-        * count if the methods above a certain index have no annotations.
-        */     
-       if (method_parameterannotations != NULL &&
-               array_length_get(method_parameterannotations) > slot) {
-               parameterAnnotations = array_objectarray_element_get(
-                               (java_handle_objectarray_t*)method_parameterannotations,
-                               slot);
-       }
-       
-       return (java_handle_bytearray_t*)parameterAnnotations;
-#else
-       return NULL;
-#endif
-}
-
-
-/* method_get_annotationdefault ***********************************************
-
-   Get a methods' unparsed annotation default value in a byte array.
-   
-   IN:
-       m........the method of which the annotation default value should be
-                   returned
-
-   RETURN VALUE:
-       The unparsed annotation default value in a byte array (or NULL if
-          there isn't one).
-
-*******************************************************************************/
-
-java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
-{
-#if defined(ENABLE_ANNOTATIONS)
-       classinfo     *c;                         /* methods' declaring class     */
-       int            slot;                      /* methods' slot                */
-       java_handle_t *annotationDefault;         /* methods' unparsed            */
-                                                 /* annotation default value     */
-       java_handle_t *method_annotationdefaults; /* all methods' unparsed        */
-                                                 /* annotation default values of */
-                                                 /* the declaring class          */
-
-       c                 = m->clazz;
-       slot              = m - c->methods;
-       annotationDefault = NULL;
-
-       LLNI_classinfo_field_get(
-               c, method_annotationdefaults, method_annotationdefaults);
-
-       /* the method_annotations array might be shorter then the method
-        * count if the methods above a certain index have no annotations.
-        */     
-       if (method_annotationdefaults != NULL &&
-               array_length_get(method_annotationdefaults) > slot) {
-               annotationDefault = array_objectarray_element_get(
-                               (java_handle_objectarray_t*)method_annotationdefaults, slot);
-       }
-       
-       return (java_handle_bytearray_t*)annotationDefault;
-#else
-       return NULL;
-#endif
-}
-
-
-/* method_add_to_worklist ******************************************************
-
-   Add the method to the given worklist. If the method already occurs in
-   the worklist, the worklist remains unchanged.
-
-*******************************************************************************/
-
-static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
-{
-       method_worklist *wi;
-
-       for (wi = *wl; wi != NULL; wi = wi->next)
-               if (wi->m == m)
-                       return;
-
-       wi = NEW(method_worklist);
-       wi->next = *wl;
-       wi->m = m;
-
-       *wl = wi;
-}
-
-
-/* method_add_assumption_monomorphic *******************************************
-
-   Record the assumption that the method is monomorphic.
-
-   IN:
-      m.................the method
-         caller............the caller making the assumption
-
-*******************************************************************************/
-
-void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
-{
-       method_assumption *as;
-
-       /* XXX LOCKING FOR THIS FUNCTION? */
-
-       /* check if we already have registered this assumption */
-
-       for (as = m->assumptions; as != NULL; as = as->next) {
-               if (as->context == caller)
-                       return;
-       }
-
-       /* register the assumption */
-
-       as = NEW(method_assumption);
-       as->next = m->assumptions;
-       as->context = caller;
-
-       m->assumptions = as;
-}
-
-
-/* method_break_assumption_monomorphic *****************************************
-
-   Break the assumption that this method is monomorphic. All callers that
-   have registered this assumption are added to the worklist.
-
-   IN:
-      m.................the method
-         wl................worklist where to add invalidated callers
-
-*******************************************************************************/
-
-void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
-{
-       method_assumption *as;
-
-       /* XXX LOCKING FOR THIS FUNCTION? */
-
-       for (as = m->assumptions; as != NULL; as = as->next) {
-               INLINELOG(
-                       printf("ASSUMPTION BROKEN (monomorphism): ");
-                       method_print(m);
-                       printf(" in ");
-                       method_println(as->context);
-               );
-
-               method_add_to_worklist(as->context, wl);
-       }
-}
-
-
-/* method_printflags ***********************************************************
-
-   Prints the flags of a method to stdout like.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_printflags(methodinfo *m)
-{
-       if (m == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       if (m->flags & ACC_PUBLIC)             printf(" PUBLIC");
-       if (m->flags & ACC_PRIVATE)            printf(" PRIVATE");
-       if (m->flags & ACC_PROTECTED)          printf(" PROTECTED");
-       if (m->flags & ACC_STATIC)             printf(" STATIC");
-       if (m->flags & ACC_FINAL)              printf(" FINAL");
-       if (m->flags & ACC_SYNCHRONIZED)       printf(" SYNCHRONIZED");
-       if (m->flags & ACC_VOLATILE)           printf(" VOLATILE");
-       if (m->flags & ACC_TRANSIENT)          printf(" TRANSIENT");
-       if (m->flags & ACC_NATIVE)             printf(" NATIVE");
-       if (m->flags & ACC_INTERFACE)          printf(" INTERFACE");
-       if (m->flags & ACC_ABSTRACT)           printf(" ABSTRACT");
-       if (m->flags & ACC_METHOD_BUILTIN)     printf(" (builtin)");
-       if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
-       if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* method_print ****************************************************************
-
-   Prints a method to stdout like:
-
-   java.lang.Object.<init>()V
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_print(methodinfo *m)
-{
-       if (m == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       if (m->clazz != NULL)
-               utf_display_printable_ascii_classname(m->clazz->name);
-       else
-               printf("NULL");
-       printf(".");
-       utf_display_printable_ascii(m->name);
-       utf_display_printable_ascii(m->descriptor);
-
-       method_printflags(m);
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* method_println **************************************************************
-
-   Prints a method plus new line to stdout like:
-
-   java.lang.Object.<init>()V
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_println(methodinfo *m)
-{
-       if (opt_debugcolor) printf("\033[31m"); /* red */
-       method_print(m);
-       if (opt_debugcolor) printf("\033[m");   
-       printf("\n");
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* method_methodref_print ******************************************************
-
-   Prints a method reference to stdout.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_methodref_print(constant_FMIref *mr)
-{
-       if (!mr) {
-               printf("(constant_FMIref *)NULL");
-               return;
-       }
-
-       if (IS_FMIREF_RESOLVED(mr)) {
-               printf("<method> ");
-               method_print(mr->p.method);
-       }
-       else {
-               printf("<methodref> ");
-               utf_display_printable_ascii_classname(mr->p.classref->name);
-               printf(".");
-               utf_display_printable_ascii(mr->name);
-               utf_display_printable_ascii(mr->descriptor);
-       }
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* method_methodref_println ****************************************************
-
-   Prints a method reference to stdout, followed by a newline.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_methodref_println(constant_FMIref *mr)
-{
-       method_methodref_print(mr);
-       printf("\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/vmcore/method.h b/src/vmcore/method.h
deleted file mode 100644 (file)
index ff28286..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/* src/vmcore/method.h - method functions header
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _METHOD_H
-#define _METHOD_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct methodinfo          methodinfo; 
-typedef struct raw_exception_entry raw_exception_entry;
-typedef struct lineinfo            lineinfo; 
-typedef struct method_assumption   method_assumption;
-typedef struct method_worklist     method_worklist;
-typedef struct codeinfo            codeinfo;
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/builtin.h"
-#include "vm/global.h"
-
-#include "vmcore/descriptor.h"
-#include "vmcore/references.h"
-#include "vmcore/linker.h"
-#include "vmcore/loader.h"
-
-#if defined(ENABLE_JAVASE)
-# include "vmcore/stackmap.h"
-#endif
-
-#include "vmcore/utf8.h"
-
-
-#if defined(ENABLE_REPLACEMENT)
-/* Initial value for the hit countdown field of each method. */
-#define METHOD_INITIAL_HIT_COUNTDOWN  1000
-#endif
-
-
-/* methodinfo *****************************************************************/
-
-struct methodinfo {                 /* method structure                       */
-       java_object_t header;           /* we need this in jit's monitorenter     */
-       s4            flags;            /* ACC flags                              */
-       utf          *name;             /* name of method                         */
-       utf          *descriptor;       /* JavaVM descriptor string of method     */
-#if defined(ENABLE_JAVASE)
-       utf          *signature;        /* Signature attribute                    */
-       stack_map_t  *stack_map;        /* StackMapTable attribute                */
-#endif
-
-       methoddesc   *parseddesc;       /* parsed descriptor                      */
-                            
-       classinfo    *clazz;            /* class, the method belongs to           */
-       s4            vftblindex;       /* index of method in virtual function    */
-                                       /* table (if it is a virtual method)      */
-       s4            maxstack;         /* maximum stack depth of method          */
-       s4            maxlocals;        /* maximum number of local variables      */
-       s4            jcodelength;      /* length of JavaVM code                  */
-       u1           *jcode;            /* pointer to JavaVM code                 */
-
-       s4            rawexceptiontablelength;  /* exceptiontable length          */
-       raw_exception_entry *rawexceptiontable; /* the exceptiontable             */
-
-       u2            thrownexceptionscount; /* number of exceptions attribute    */
-       classref_or_classinfo *thrownexceptions; /* except. a method may throw    */
-
-       u2            linenumbercount;  /* number of linenumber attributes        */
-       lineinfo     *linenumbers;      /* array of lineinfo items                */
-
-       u1           *stubroutine;      /* stub for compiling or calling natives  */
-       codeinfo     *code;             /* current code of this method            */
-
-#if defined(ENABLE_LSRA)
-       s4            maxlifetimes;     /* helper for lsra                        */
-#endif
-
-       methodinfo   *overwrites;       /* method that is directly overwritten    */
-       method_assumption *assumptions; /* list of assumptions about this method  */
-
-#if defined(ENABLE_REPLACEMENT)
-       s4            hitcountdown;     /* decreased for each hit                 */
-#endif
-
-#if defined(ENABLE_DEBUG_FILTER)
-       u1            filtermatches;    /* flags indicating which filters the method matches */
-#endif
-
-#if defined(ENABLE_ESCAPE)
-       u1           *paramescape;
-#endif
-};
-
-/* method_assumption ***********************************************************
-
-   This struct is used for registering assumptions about methods.
-
-*******************************************************************************/
-
-struct method_assumption {
-       method_assumption *next;
-       methodinfo        *context;
-};
-
-
-/* method_worklist *************************************************************
-
-   List node used for method worklists.
-
-*******************************************************************************/
-
-struct method_worklist {
-       method_worklist *next;
-       methodinfo      *m;
-};
-
-
-/* raw_exception_entry ********************************************************/
-
-/* exception table entry read by the loader */
-
-struct raw_exception_entry {    /* exceptiontable entry in a method           */
-       classref_or_classinfo catchtype; /* catchtype of exc. (0 == catchall)     */
-       u2              startpc;    /* start pc of guarded area (inclusive)       */
-       u2              endpc;      /* end pc of guarded area (exklusive)         */
-       u2              handlerpc;  /* pc of exception handler                    */
-};
-
-
-/* lineinfo *******************************************************************/
-
-struct lineinfo {
-       u2 start_pc;
-       u2 line_number;
-};
-
-
-/* global variables ***********************************************************/
-
-extern methodinfo *method_java_lang_reflect_Method_invoke;
-
-
-/* inline functions ***********************************************************/
-
-inline static bool method_is_builtin(methodinfo* m)
-{
-       return m->flags & ACC_METHOD_BUILTIN;
-}
-
-
-/* function prototypes ********************************************************/
-
-void method_init(void);
-
-bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool);
-void method_free(methodinfo *m);
-bool method_canoverwrite(methodinfo *m, methodinfo *old);
-
-methodinfo *method_new_builtin(builtintable_entry *bte);
-
-methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m);
-
-int32_t                    method_get_parametercount(methodinfo *m);
-java_handle_objectarray_t *method_get_parametertypearray(methodinfo *m);
-java_handle_objectarray_t *method_get_exceptionarray(methodinfo *m);
-classinfo                 *method_returntype_get(methodinfo *m);
-
-void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller);
-void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl);
-
-s4   method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found);
-
-java_handle_bytearray_t *method_get_annotations(methodinfo *m);
-java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m);
-java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m);
-
-#if !defined(NDEBUG)
-void method_printflags(methodinfo *m);
-void method_print(methodinfo *m);
-void method_println(methodinfo *m);
-void method_methodref_print(constant_FMIref *mr);
-void method_methodref_println(constant_FMIref *mr);
-#endif
-
-#endif /* _METHOD_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/vmcore/options.c b/src/vmcore/options.c
deleted file mode 100644 (file)
index a5494ba..0000000
+++ /dev/null
@@ -1,855 +0,0 @@
-/* src/vmcore/options.c - contains global options
-
-   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 <limits.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "mm/memory.h"
-
-#include "native/jni.h"
-
-#include "vm/vm.h"
-
-#include "vmcore/options.h"
-#include "vmcore/system.h"
-
-
-/* command line option ********************************************************/
-
-s4    opt_index = 0;            /* index of processed arguments               */
-char *opt_arg;                  /* this one exports the option argument       */
-
-bool opt_foo = false;           /* option for development                     */
-
-bool opt_jar = false;
-
-#if defined(ENABLE_JIT)
-bool opt_jit = true;            /* JIT mode execution (default)               */
-bool opt_intrp = false;         /* interpreter mode execution                 */
-#else
-bool opt_jit = false;           /* JIT mode execution                         */
-bool opt_intrp = true;          /* interpreter mode execution (default)       */
-#endif
-
-bool opt_run = true;
-
-s4   opt_heapmaxsize   = 0;     /* maximum heap size                          */
-s4   opt_heapstartsize = 0;     /* initial heap size                          */
-s4   opt_stacksize     = 0;     /* thread stack size                          */
-
-bool opt_verbose = false;
-bool opt_debugcolor = false;   /* use ANSI terminal sequences                */
-bool compileall = false;
-
-bool loadverbose = false;
-bool initverbose = false;
-
-bool opt_verboseclass     = false;
-bool opt_verbosegc        = false;
-bool opt_verbosejni       = false;
-bool opt_verbosecall      = false;      /* trace all method invocation        */
-
-bool showmethods = false;
-bool showconstantpool = false;
-bool showutf = false;
-
-char *opt_method = NULL;
-char *opt_signature = NULL;
-
-bool compileverbose =  false;           /* trace compiler actions             */
-bool showstack = false;
-
-bool opt_showdisassemble    = false;    /* generate disassembler listing      */
-bool opt_shownops           = false;
-bool opt_showddatasegment   = false;    /* generate data segment listing      */
-bool opt_showintermediate   = false;    /* generate intermediate code listing */
-
-bool checkbounds = true;       /* check array bounds                         */
-bool opt_noieee = false;       /* don't implement ieee compliant floats      */
-bool checksync = true;         /* do synchronization                         */
-#if defined(ENABLE_LOOP)
-bool opt_loops = false;        /* optimize array accesses in loops           */
-#endif
-
-bool makeinitializations = true;
-
-#if defined(ENABLE_STATISTICS)
-bool opt_stat    = false;
-bool opt_getloadingtime = false;   /* to measure the runtime                 */
-bool opt_getcompilingtime = false; /* compute compile time                   */
-#endif
-#if defined(ENABLE_VERIFIER)
-bool opt_verify  = true;       /* true if classfiles should be verified      */
-#endif
-
-#if defined(ENABLE_PROFILING)
-bool opt_prof    = false;
-bool opt_prof_bb = false;
-#endif
-
-#if defined(ENABLE_JITCACHE)
-bool opt_jitcache = false;
-bool opt_jitcache_details = false;
-#endif
-
-/* optimization options *******************************************************/
-
-#if defined(ENABLE_IFCONV)
-bool opt_ifconv = false;
-#endif
-
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
-bool opt_lsra = false;
-#endif
-#if defined(ENABLE_SSA)
-bool opt_ssa_dce = false;          /* enable dead code elemination */
-bool opt_ssa_cp = false;           /* enable copy propagation      */
-#endif
-
-
-/* interpreter options ********************************************************/
-
-#if defined(ENABLE_INTRP)
-bool opt_no_dynamic = false;            /* suppress dynamic superinstructions */
-bool opt_no_replication = false;        /* don't use replication in intrp     */
-bool opt_no_quicksuper = false;         /* instructions for quickening cannot be
-                                                                                  part of dynamic superinstructions */
-
-s4   opt_static_supers = 0x7fffffff;
-bool vm_debug = false;          /* XXX this should be called `opt_trace'      */
-#endif
-
-#if defined(ENABLE_DEBUG_FILTER)
-const char *opt_filter_verbosecall_include = 0;
-const char *opt_filter_verbosecall_exclude = 0;
-const char *opt_filter_show_method = 0;
-#endif
-
-
-/* -XX options ****************************************************************/
-
-/* NOTE: For better readability keep these alpha-sorted. */
-
-/* Options which must always be available (production options in
-   HotSpot). */
-
-int64_t  opt_MaxDirectMemorySize          = -1;
-int      opt_MaxPermSize                  = 0;
-int      opt_PermSize                     = 0;
-int      opt_ThreadStackSize              = 0;
-
-/* Debugging options which can be turned off. */
-
-int      opt_DebugExceptions              = 0;
-int      opt_DebugFinalizer               = 0;
-#if defined(ENABLE_JITCACHE)
-int   opt_DebugJitCache                = 0;
-#endif
-int      opt_DebugLocalReferences         = 0;
-int      opt_DebugLocks                   = 0;
-int      opt_DebugPackage                 = 0;
-int      opt_DebugPatcher                 = 0;
-int      opt_DebugProperties              = 0;
-int      opt_DebugStackFrameInfo          = 0;
-int      opt_DebugStackTrace              = 0;
-int      opt_DebugThreads                 = 0;
-#if defined(ENABLE_DISASSEMBLER)
-int      opt_DisassembleStubs             = 0;
-#endif
-#if defined(ENABLE_GC_CACAO)
-int      opt_GCDebugRootSet               = 0;
-int      opt_GCStress                     = 0;
-#endif
-#if defined(ENABLE_INLINING)
-int      opt_Inline                       = 0;
-#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-int      opt_InlineAll                    = 0;
-int      opt_InlineCount                  = INT_MAX;
-int      opt_InlineMaxSize                = INT_MAX;
-int      opt_InlineMinSize                = 0;
-#endif
-#endif
-int      opt_PrintConfig                  = 0;
-int      opt_ProfileGCMemoryUsage         = 0;
-int      opt_ProfileMemoryUsage           = 0;
-FILE    *opt_ProfileMemoryUsageGNUPlot    = NULL;
-#if defined(ENABLE_REPLACEMENT)
-int      opt_TestReplacement              = 0;
-#endif
-int      opt_TraceCompilerCalls           = 0;
-int      opt_TraceExceptions              = 0;
-int      opt_TraceHPI                     = 0;
-#if defined(ENABLE_INLINING) && !defined(NDEBUG)
-int      opt_TraceInlining                = 0;
-#endif
-int      opt_TraceJavaCalls               = 0;
-int      opt_TraceJNICalls                = 0;
-int      opt_TraceJVMCalls                = 0;
-int      opt_TraceJVMCallsVerbose         = 0;
-int      opt_TraceLinkClass               = 0;
-#if defined(ENABLE_REPLACEMENT)
-int      opt_TraceReplacement             = 0;
-#endif
-int      opt_TraceSubsystemInitialization = 0;
-int      opt_TraceTraps                   = 0;
-
-
-enum {
-       OPT_TYPE_BOOLEAN,
-       OPT_TYPE_VALUE
-};
-
-enum {
-       /* Options which must always be available (production options in
-          HotSpot). */
-
-       OPT_MaxDirectMemorySize,
-       OPT_MaxPermSize,
-       OPT_PermSize,
-       OPT_ThreadStackSize,
-
-       /* Debugging options which can be turned off. */
-
-       OPT_DebugExceptions,
-       OPT_DebugFinalizer,
-       OPT_DebugJitCache,
-       OPT_DebugLocalReferences,
-       OPT_DebugLocks,
-       OPT_DebugPackage,
-       OPT_DebugPatcher,
-       OPT_DebugProperties,
-       OPT_DebugStackFrameInfo,
-       OPT_DebugStackTrace,
-       OPT_DebugThreads,
-       OPT_DisassembleStubs,
-       OPT_GCDebugRootSet,
-       OPT_GCStress,
-       OPT_Inline,
-       OPT_InlineAll,
-       OPT_InlineCount,
-       OPT_InlineMaxSize,
-       OPT_InlineMinSize,
-       OPT_PrintConfig,
-       OPT_ProfileGCMemoryUsage,
-       OPT_ProfileMemoryUsage,
-       OPT_ProfileMemoryUsageGNUPlot,
-       OPT_TestReplacement,
-       OPT_TraceCompilerCalls,
-       OPT_TraceExceptions,
-       OPT_TraceHPI,
-       OPT_TraceInlining,
-       OPT_TraceJavaCalls,
-       OPT_TraceJNICalls,
-       OPT_TraceJVMCalls,
-       OPT_TraceJVMCallsVerbose,
-       OPT_TraceLinkClass,
-       OPT_TraceReplacement,
-       OPT_TraceSubsystemInitialization,
-       OPT_TraceTraps,
-       OPT_Vmlog,
-       OPT_VmlogStrings,
-       OPT_VmlogIgnore
-};
-
-
-option_t options_XX[] = {
-       /* Options which must always be available (production options in
-          HotSpot). */
-
-       { "MaxDirectMemorySize",          OPT_MaxDirectMemorySize,          OPT_TYPE_VALUE,   "Maximum total size of NIO direct-buffer allocations" },
-       { "MaxPermSize",                  OPT_MaxPermSize,                  OPT_TYPE_VALUE,   "not implemented" },
-       { "PermSize",                     OPT_PermSize,                     OPT_TYPE_VALUE,   "not implemented" },
-       { "ThreadStackSize",              OPT_ThreadStackSize,              OPT_TYPE_VALUE,   "TODO" },
-
-       /* Debugging options which can be turned off. */
-
-       { "DebugExceptions",              OPT_DebugExceptions,              OPT_TYPE_BOOLEAN, "debug exceptions" },
-       { "DebugFinalizer",               OPT_DebugFinalizer,               OPT_TYPE_BOOLEAN, "debug finalizer thread" },
-#if defined (ENABLE_JITCACHE)
-       { "DebugJitCache",                OPT_DebugJitCache,                OPT_TYPE_BOOLEAN, "debug JIT cache actions" },
-#endif
-       { "DebugLocalReferences",         OPT_DebugLocalReferences,         OPT_TYPE_BOOLEAN, "print debug information for local reference tables" },
-       { "DebugLocks",                   OPT_DebugLocks,                   OPT_TYPE_BOOLEAN, "print debug information for locks" },
-       { "DebugPackage",                 OPT_DebugPackage,                 OPT_TYPE_BOOLEAN, "debug Java boot-packages" },
-       { "DebugPatcher",                 OPT_DebugPatcher,                 OPT_TYPE_BOOLEAN, "debug JIT code patching" },
-       { "DebugProperties",              OPT_DebugProperties,              OPT_TYPE_BOOLEAN, "print debug information for properties" },
-       { "DebugStackFrameInfo",          OPT_DebugStackFrameInfo,          OPT_TYPE_BOOLEAN, "TODO" },
-       { "DebugStackTrace",              OPT_DebugStackTrace,              OPT_TYPE_BOOLEAN, "debug stacktrace creation" },
-       { "DebugThreads",                 OPT_DebugThreads,                 OPT_TYPE_BOOLEAN, "print debug information for threads" },
-#if defined(ENABLE_DISASSEMBLER)
-       { "DisassembleStubs",             OPT_DisassembleStubs,             OPT_TYPE_BOOLEAN, "disassemble builtin and native stubs when generated" },
-#endif
-#if defined(ENABLE_GC_CACAO)
-       { "GCDebugRootSet",               OPT_GCDebugRootSet,               OPT_TYPE_BOOLEAN, "GC: print root-set at collection" },
-       { "GCStress",                     OPT_GCStress,                     OPT_TYPE_BOOLEAN, "GC: forced collection at every allocation" },
-#endif
-#if defined(ENABLE_INLINING)
-       { "Inline",                       OPT_Inline,                       OPT_TYPE_BOOLEAN, "enable method inlining" },
-#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-       { "InlineAll",                    OPT_InlineAll,                    OPT_TYPE_BOOLEAN, "use inlining in all compilations" },
-       { "InlineCount",                  OPT_InlineCount,                  OPT_TYPE_VALUE,   "stop inlining after the given number of roots" },
-       { "InlineMaxSize",                OPT_InlineMaxSize,                OPT_TYPE_VALUE,   "maximum size for inlined result" },
-       { "InlineMinSize",                OPT_InlineMinSize,                OPT_TYPE_VALUE,   "minimum size for inlined result" },
-#endif
-#endif
-       { "PrintConfig",                  OPT_PrintConfig,                  OPT_TYPE_BOOLEAN, "print VM configuration" },
-       { "ProfileGCMemoryUsage",         OPT_ProfileGCMemoryUsage,         OPT_TYPE_VALUE,   "profiles GC memory usage in the given interval, <value> is in seconds (default: 5)" },
-       { "ProfileMemoryUsage",           OPT_ProfileMemoryUsage,           OPT_TYPE_VALUE,   "TODO" },
-       { "ProfileMemoryUsageGNUPlot",    OPT_ProfileMemoryUsageGNUPlot,    OPT_TYPE_VALUE,   "TODO" },
-#if defined(ENABLE_REPLACEMENT)
-       { "TestReplacement",              OPT_TestReplacement,              OPT_TYPE_BOOLEAN, "activate all replacement points during code generation" },
-#endif
-       { "TraceCompilerCalls",           OPT_TraceCompilerCalls,           OPT_TYPE_BOOLEAN, "trace JIT compiler calls" },
-       { "TraceExceptions",              OPT_TraceExceptions,              OPT_TYPE_BOOLEAN, "trace Exception throwing" },
-       { "TraceHPI",                     OPT_TraceHPI,                     OPT_TYPE_BOOLEAN, "Trace Host Porting Interface (HPI)" },
-#if defined(ENABLE_INLINING) && !defined(NDEBUG)
-       { "TraceInlining",                OPT_TraceInlining,                OPT_TYPE_VALUE,   "trace method inlining with the given verbosity level (default: 1)" },
-#endif
-#if !defined(ENABLE_VMLOG)
-       { "TraceJavaCalls",               OPT_TraceJavaCalls,               OPT_TYPE_BOOLEAN, "trace Java method calls" },
-#endif
-       { "TraceJNICalls",                OPT_TraceJNICalls,                OPT_TYPE_BOOLEAN, "trace JNI method calls" },
-       { "TraceJVMCalls",                OPT_TraceJVMCalls,                OPT_TYPE_BOOLEAN, "trace JVM method calls but omit very frequent ones" },
-       { "TraceJVMCallsVerbose",         OPT_TraceJVMCallsVerbose,         OPT_TYPE_BOOLEAN, "trace all JVM method calls" },
-       { "TraceLinkClass",               OPT_TraceLinkClass,               OPT_TYPE_BOOLEAN, "trace class linking" },
-#if defined(ENABLE_REPLACEMENT)
-       { "TraceReplacement",             OPT_TraceReplacement,             OPT_TYPE_VALUE,   "trace on-stack replacement with the given verbosity level (default: 1)" },
-#endif
-       { "TraceSubsystemInitialization", OPT_TraceSubsystemInitialization, OPT_TYPE_BOOLEAN, "trace initialization of subsystems" },
-       { "TraceTraps",                   OPT_TraceTraps,                   OPT_TYPE_BOOLEAN, "trace traps generated by JIT code" },
-#if defined(ENABLE_VMLOG)
-       { "Vmlog",                        OPT_Vmlog,                        OPT_TYPE_VALUE,   "prefix for vmlog trace files (enables vmlog)" },
-       { "VmlogStrings",                 OPT_VmlogStrings,                 OPT_TYPE_VALUE,   "prefix of vmlog string file to load" },
-       { "VmlogIgnore",                  OPT_VmlogIgnore,                  OPT_TYPE_VALUE,   "prefix of vmlog ignore file to load" },
-#endif
-
-       /* end marker */
-
-       { NULL,                           -1,                               -1,               NULL }
-};
-
-
-/* options_get *****************************************************************
-
-   DOCUMENT ME!!!
-
-*******************************************************************************/
-
-int options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
-{
-       char *option;
-       int   i;
-
-       if (opt_index >= vm_args->nOptions)
-               return OPT_DONE;
-
-       /* get the current option */
-
-       option = vm_args->options[opt_index].optionString;
-
-       if ((option == NULL) || (option[0] != '-'))
-               return OPT_DONE;
-
-       for (i = 0; opts[i].name; i++) {
-               if (!opts[i].arg) {
-                       /* boolean option found */
-
-                       if (strcmp(option + 1, opts[i].name) == 0) {
-                               opt_index++;
-                               return opts[i].value;
-                       }
-
-               } else {
-                       /* parameter option found */
-
-                       /* with a space between */
-
-                       if (strcmp(option + 1, opts[i].name) == 0) {
-                               opt_index++;
-
-                               if (opt_index < vm_args->nOptions) {
-                                       opt_arg = system_strdup(vm_args->options[opt_index].optionString);
-                                       opt_index++;
-                                       return opts[i].value;
-                               }
-
-                               return OPT_ERROR;
-
-                       } else {
-                               /* parameter and option have no space between */
-
-                               /* FIXME: this assumption is plain wrong, hits you if there is a
-                                * parameter with no argument starting with same letter as param with argument
-                                * but named after that one, ouch! */
-
-                               size_t l = system_strlen(opts[i].name);
-
-                               if (system_strlen(option + 1) > l) {
-                                       if (memcmp(option + 1, opts[i].name, l) == 0) {
-                                               opt_index++;
-                                               opt_arg = system_strdup(option + 1 + l);
-                                               return opts[i].value;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       return OPT_ERROR;
-}
-
-
-/* options_xxusage *************************************************************
-
-   Print usage message for debugging options.
-
-*******************************************************************************/
-
-static void options_xxusage(void)
-{
-       option_t *opt;
-       int       length;
-       int       i;
-       char     *c;
-
-       /* Prevent compiler warning. */
-
-       length = 0;
-
-       for (opt = options_XX; opt->name != NULL; opt++) {
-               printf("    -XX:");
-
-               switch (opt->type) {
-               case OPT_TYPE_BOOLEAN:
-                       printf("+%s", opt->name);
-                       length = system_strlen("    -XX:+") + system_strlen(opt->name);
-                       break;
-
-               case OPT_TYPE_VALUE:
-                       printf("%s=<value>", opt->name);
-                       length = system_strlen("    -XX:") + system_strlen(opt->name) +
-                               system_strlen("=<value>");
-                       break;
-
-               default:
-                       vm_abort("options_xxusage: unkown option type %d", opt->type);
-               }
-
-               /* Check if the help fits into one 80-column line.
-                  Documentation starts at column 29. */
-
-               if (length < (29 - 1)) {
-                       /* Print missing spaces up to column 29. */
-
-                       for (i = length; i < 29; i++)
-                               printf(" ");
-               }
-               else {
-                       printf("\n");
-                       printf("                             "); /* 29 spaces */
-               }
-
-               /* Check documentation length. */
-
-               length = system_strlen(opt->doc);
-
-               if (length < (80 - 29)) {
-                       printf("%s", opt->doc);
-               }
-               else {
-                       for (c = opt->doc, i = 29; *c != 0; c++, i++) {
-                               /* If we are at the end of the line, break it. */
-
-                               if (i == 80) {
-                                       printf("\n");
-                                       printf("                             "); /* 29 spaces */
-                                       i = 29;
-                               }
-
-                               printf("%c", *c);
-                       }
-               }
-
-               printf("\n");
-       }
-
-       /* exit with error code */
-
-       exit(1);
-}
-
-
-/* options_xx ******************************************************************
-
-   Handle -XX: options.
-
-*******************************************************************************/
-
-void options_xx(JavaVMInitArgs *vm_args)
-{
-       const char *name;
-       const char *start;
-       char       *end;
-       int         length;
-       int         enable;
-       char       *value;
-       option_t   *opt;
-       char       *filename;
-       FILE       *file;
-       int         i;
-
-       /* Iterate over all passed options. */
-
-       for (i = 0; i < vm_args->nOptions; i++) {
-               /* Get the current option. */
-
-               name = vm_args->options[i].optionString;
-
-               /* Check for help (-XX). */
-
-               if (strcmp(name, "-XX") == 0)
-                       options_xxusage();
-
-               /* Check if the option start with -XX. */
-
-               start = strstr(name, "-XX:");
-
-               if ((start == NULL) || (start != name))
-                       continue;
-
-               /* Check if the option is a boolean option. */
-
-               if (name[4] == '+') {
-                       start  = name + 4 + 1;
-                       enable = 1;
-               }
-               else if (name[4] == '-') {
-                       start  = name + 4 + 1;
-                       enable = 0;
-               }
-               else {
-                       start  = name + 4;
-                       enable = -1;
-               }
-
-               /* Search for a '=' in the option name and get the option name
-                  length and the value of the option. */
-
-               end = strchr(start, '=');
-
-               if (end == NULL) {
-                       length = system_strlen(start);
-                       value  = NULL;
-               }
-               else {
-                       length = end - start;
-                       value  = end + 1;
-               }
-
-               /* Search the option in the option array. */
-
-               for (opt = options_XX; opt->name != NULL; opt++) {
-                       if (strncmp(opt->name, start, length) == 0) {
-                               /* Check if the options passed fits to the type. */
-
-                               switch (opt->type) {
-                               case OPT_TYPE_BOOLEAN:
-                                       if ((enable == -1) || (value != NULL))
-                                               options_xxusage();
-                                       break;
-                               case OPT_TYPE_VALUE:
-                                       if ((enable != -1) || (value == NULL))
-                                               options_xxusage();
-                                       break;
-                               default:
-                                       vm_abort("options_xx: unknown option type %d for option %s",
-                                                        opt->type, opt->name);
-                               }
-
-                               break;
-                       }
-               }
-
-               /* Process the option. */
-
-               switch (opt->value) {
-
-               /* Options which must always be available (production options
-                  in HotSpot). */
-
-               case OPT_MaxDirectMemorySize:
-                       opt_MaxDirectMemorySize = system_atoi(value);
-                       break;
-
-               case OPT_MaxPermSize:
-                       /* Currently ignored. */
-                       break;
-
-               case OPT_PermSize:
-                       /* Currently ignored. */
-                       break;
-
-               case OPT_ThreadStackSize:
-                       /* currently ignored */
-                       break;
-
-               /* Debugging options which can be turned off. */
-
-               case OPT_DebugExceptions:
-                       opt_DebugExceptions = enable;
-                       break;
-
-               case OPT_DebugFinalizer:
-                       opt_DebugFinalizer = enable;
-                       break;
-
-#if defined(ENABLE_JITCACHE)
-               case OPT_DebugJitCache:
-                       opt_DebugJitCache = enable;
-                       break;
-#endif
-
-               case OPT_DebugLocalReferences:
-                       opt_DebugLocalReferences = enable;
-                       break;
-
-               case OPT_DebugLocks:
-                       opt_DebugLocks = enable;
-                       break;
-
-               case OPT_DebugPackage:
-                       opt_DebugPackage = enable;
-                       break;
-
-               case OPT_DebugPatcher:
-                       opt_DebugPatcher = enable;
-                       break;
-
-               case OPT_DebugProperties:
-                       opt_DebugProperties = enable;
-                       break;
-
-               case OPT_DebugStackFrameInfo:
-                       opt_DebugStackFrameInfo = enable;
-                       break;
-
-               case OPT_DebugStackTrace:
-                       opt_DebugStackTrace = enable;
-                       break;
-
-               case OPT_DebugThreads:
-                       opt_DebugThreads = enable;
-                       break;
-
-#if defined(ENABLE_DISASSEMBLER)
-               case OPT_DisassembleStubs:
-                       opt_DisassembleStubs = enable;
-                       break;
-#endif
-
-#if defined(ENABLE_GC_CACAO)
-               case OPT_GCDebugRootSet:
-                       opt_GCDebugRootSet = enable;
-                       break;
-
-               case OPT_GCStress:
-                       opt_GCStress = enable;
-                       break;
-#endif
-
-#if defined(ENABLE_INLINING)
-               case OPT_Inline:
-                       opt_Inline = enable;
-                       break;
-#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-               case OPT_InlineAll:
-                       opt_InlineAll = enable;
-                       break;
-
-               case OPT_InlineCount:
-                       if (value != NULL)
-                               opt_InlineCount = system_atoi(value);
-                       break;
-
-               case OPT_InlineMaxSize:
-                       if (value != NULL)
-                               opt_InlineMaxSize = system_atoi(value);
-                       break;
-
-               case OPT_InlineMinSize:
-                       if (value != NULL)
-                               opt_InlineMinSize = system_atoi(value);
-                       break;
-#endif
-#endif
-
-               case OPT_PrintConfig:
-                       opt_PrintConfig = enable;
-                       break;
-
-               case OPT_ProfileGCMemoryUsage:
-                       if (value == NULL)
-                               opt_ProfileGCMemoryUsage = 5;
-                       else
-                               opt_ProfileGCMemoryUsage = system_atoi(value);
-                       break;
-
-               case OPT_ProfileMemoryUsage:
-                       if (value == NULL)
-                               opt_ProfileMemoryUsage = 5;
-                       else
-                               opt_ProfileMemoryUsage = system_atoi(value);
-
-# if defined(ENABLE_STATISTICS)
-                       /* we also need statistics */
-
-                       opt_stat = true;
-# endif
-                       break;
-
-               case OPT_ProfileMemoryUsageGNUPlot:
-                       if (value == NULL)
-                               filename = "profile.dat";
-                       else
-                               filename = value;
-
-                       file = fopen(filename, "w");
-
-                       if (file == NULL)
-                               vm_abort_errno("options_xx: fopen failed");
-
-                       opt_ProfileMemoryUsageGNUPlot = file;
-                       break;
-
-#if defined(ENABLE_REPLACEMENT)
-               case OPT_TestReplacement:
-                       opt_TestReplacement = enable;
-                       break;
-#endif
-
-               case OPT_TraceCompilerCalls:
-                       opt_TraceCompilerCalls = enable;
-                       break;
-
-               case OPT_TraceExceptions:
-                       opt_TraceExceptions = enable;
-                       break;
-
-               case OPT_TraceHPI:
-                       opt_TraceHPI = enable;
-                       break;
-
-#if defined(ENABLE_INLINING) && !defined(NDEBUG)
-               case OPT_TraceInlining:
-                       if (value == NULL)
-                               opt_TraceInlining = 1;
-                       else
-                               opt_TraceInlining = system_atoi(value);
-                       break;
-#endif
-
-               case OPT_TraceJavaCalls:
-                       opt_verbosecall = enable;
-                       opt_TraceJavaCalls = enable;
-                       break;
-
-               case OPT_TraceJNICalls:
-                       opt_TraceJNICalls = enable;
-                       break;
-
-               case OPT_TraceJVMCalls:
-                       opt_TraceJVMCalls = enable;
-                       break;
-
-               case OPT_TraceJVMCallsVerbose:
-                       opt_TraceJVMCallsVerbose = enable;
-                       break;
-
-               case OPT_TraceLinkClass:
-                       opt_TraceLinkClass = enable;
-                       break;
-
-#if defined(ENABLE_REPLACEMENT)
-               case OPT_TraceReplacement:
-                       if (value == NULL)
-                               opt_TraceReplacement = 1;
-                       else
-                               opt_TraceReplacement = system_atoi(value);
-                       break;
-#endif
-
-               case OPT_TraceSubsystemInitialization:
-                       opt_TraceSubsystemInitialization = enable;
-                       break;
-
-               case OPT_TraceTraps:
-                       opt_TraceTraps = enable;
-                       break;
-
-#if defined(ENABLE_VMLOG)
-               case OPT_Vmlog:
-                       if (value == NULL)
-                               vmlog_cacao_set_prefix("vmlog");
-                       else
-                               vmlog_cacao_set_prefix(value);
-                       opt_verbosecall = 1;
-                       opt_TraceJavaCalls = 1;
-                       break;
-
-               case OPT_VmlogStrings:
-                       if (value != NULL)
-                               vmlog_cacao_set_stringprefix(value);
-                       break;
-
-               case OPT_VmlogIgnore:
-                       if (value != NULL)
-                               vmlog_cacao_set_ignoreprefix(value);
-                       break;
-#endif
-
-               default:
-                       printf("Unknown -XX option: %s\n", name);
-                       break;
-               }
-       }
-}
-
-
-/*
- * 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/vmcore/options.h b/src/vmcore/options.h
deleted file mode 100644 (file)
index 6bc04c8..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/* src/vmcore/options.h - define global options extern
-
-   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 _OPTIONS_H
-#define _OPTIONS_H
-
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "native/jni.h"
-
-#include "vm/global.h"
-
-
-/* reserved option numbers ****************************************************/
-
-/* define these negative since the other options are an enum */
-
-#define OPT_DONE       -1
-#define OPT_ERROR      -2
-#define OPT_IGNORE     -3
-
-
-typedef struct opt_struct opt_struct;
-
-struct opt_struct {
-       char *name;
-       bool  arg;
-       int   value;
-};
-
-
-typedef struct option_t option_t;
-
-struct option_t {
-       char *name;
-       int   value;
-       int   type;
-       char *doc;
-};
-
-
-/* global variables ***********************************************************/
-
-extern s4    opt_index;
-extern char *opt_arg;
-
-extern bool opt_foo;
-
-extern bool opt_jit;
-extern bool opt_intrp;
-
-extern bool opt_jar;
-extern bool opt_run;
-
-extern s4   opt_heapmaxsize;
-extern s4   opt_heapstartsize;
-extern s4   opt_stacksize;
-
-extern bool opt_verbose;
-extern bool opt_debugcolor;
-extern bool compileall;
-
-extern bool loadverbose;         /* Print debug messages during loading */
-extern bool initverbose;         /* Log class initialization */ 
-
-extern bool opt_verboseclass;
-extern bool opt_verbosegc;
-extern bool opt_verbosejni;
-extern bool opt_verbosecall;
-
-extern bool showmethods;
-extern bool showconstantpool;
-extern bool showutf;
-
-extern char *opt_method;
-extern char *opt_signature;
-
-extern bool compileverbose;
-extern bool showstack;
-
-extern bool opt_showdisassemble;
-extern bool opt_shownops;
-extern bool opt_showddatasegment;
-extern bool opt_showintermediate;
-
-extern bool checkbounds;
-extern bool opt_noieee;
-extern bool checksync;
-#if defined(ENABLE_LOOP)
-extern bool opt_loops;
-#endif
-
-extern bool makeinitializations;
-
-#if defined(ENABLE_STATISTICS)
-extern bool opt_stat;
-extern bool opt_getloadingtime;
-extern bool opt_getcompilingtime;
-#endif
-#if defined(ENABLE_VERIFIER)
-extern bool opt_verify;
-#endif
-
-#if defined(ENABLE_PROFILING)
-extern bool opt_prof;
-extern bool opt_prof_bb;
-#endif
-
-/* optimization options *******************************************************/
-
-#if defined(ENABLE_IFCONV)
-extern bool opt_ifconv;
-#endif
-
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
-extern bool opt_lsra;
-#endif
-#if defined(ENABLE_SSA)
-extern bool opt_ssa_dce;          /* enable dead code elemination */
-extern bool opt_ssa_cp;           /* enable copy propagation      */
-#endif
-
-/* interpreter options ********************************************************/
-
-#if defined(ENABLE_INTRP)
-extern bool opt_no_dynamic;
-extern bool opt_no_replication;
-extern bool opt_no_quicksuper;
-
-extern s4   opt_static_supers;
-extern bool vm_debug;
-#endif
-
-/* debug output filtering options *********************************************/
-
-#if defined(ENABLE_DEBUG_FILTER)
-extern const char *opt_filter_verbosecall_include;
-extern const char *opt_filter_verbosecall_exclude;
-extern const char *opt_filter_show_method;
-#endif
-
-
-/* -XX options ****************************************************************/
-
-/* NOTE: For better readability keep these alpha-sorted. */
-
-/* Options which must always be available (production options in
-   HotSpot). */
-
-extern int64_t  opt_MaxDirectMemorySize;
-extern int      opt_MaxPermSize;
-extern int      opt_PermSize;
-extern int      opt_ThreadStackSize;
-
-/* Debugging options which can be turned off. */
-
-extern int      opt_DebugExceptions;
-extern int      opt_DebugFinalizer;
-#if defined(ENABLE_JITCACHE)
-extern int   opt_DebugJitCache;
-#endif
-extern int      opt_DebugLocalReferences;
-extern int      opt_DebugLocks;
-extern int      opt_DebugPatcher;
-extern int      opt_DebugPackage;
-extern int      opt_DebugProperties;
-extern int      opt_DebugStackFrameInfo;
-extern int      opt_DebugStackTrace;
-extern int      opt_DebugThreads;
-#if defined(ENABLE_DISASSEMBLER)
-extern int      opt_DisassembleStubs;
-#endif
-#if defined(ENABLE_GC_CACAO)
-extern int      opt_GCDebugRootSet;
-extern int      opt_GCStress;
-#endif
-#if defined(ENABLE_INLINING)
-extern int      opt_Inline;
-#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-extern int      opt_InlineAll;
-extern int      opt_InlineCount;
-extern int      opt_InlineMaxSize;
-extern int      opt_InlineMinSize;
-#endif
-#endif
-extern int      opt_PrintConfig;
-extern int      opt_ProfileGCMemoryUsage;
-extern int      opt_ProfileMemoryUsage;
-extern FILE    *opt_ProfileMemoryUsageGNUPlot;
-#if defined(ENABLE_REPLACEMENT)
-extern int      opt_TestReplacement;
-#endif
-extern int      opt_TraceCompilerCalls;
-extern int      opt_TraceExceptions;
-extern int      opt_TraceHPI;
-#if defined(ENABLE_INLINING) && !defined(NDEBUG)
-extern int      opt_TraceInlining;
-#endif
-extern int      opt_TraceJavaCalls;
-extern int      opt_TraceJNICalls;
-extern int      opt_TraceJVMCalls;
-extern int      opt_TraceJVMCallsVerbose;
-extern int      opt_TraceLinkClass;
-#if defined(ENABLE_REPLACEMENT)
-extern int      opt_TraceReplacement;
-#endif
-extern int      opt_TraceSubsystemInitialization;
-extern int      opt_TraceTraps;
-
-
-/* function prototypes ********************************************************/
-
-int  options_get(opt_struct *opts, JavaVMInitArgs *vm_args);
-void options_xx(JavaVMInitArgs *vm_args);
-
-
-/* debug **********************************************************************/
-
-#if !defined(NDEBUG)
-# define TRACESUBSYSTEMINITIALIZATION(text)                                            \
-    do {                                                                                                               \
-        if (opt_TraceSubsystemInitialization) {                                        \
-            log_println("[Initializing subsystem: %s]", text); \
-        }                                                                                                              \
-    } while (0)
-#else
-# define TRACESUBSYSTEMINITIALIZATION(text)
-#endif
-
-#endif /* _OPTIONS_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/vmcore/primitivecore.c b/src/vmcore/primitivecore.c
deleted file mode 100644 (file)
index d55da76..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/* src/vmcore/primitivecore.c - core functions for primitive types
-
-   Copyright (C) 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "vm/global.h"
-#include "vm/primitive.h"
-#include "vm/vm.h"
-
-#include "vmcore/class.h"
-#include "vmcore/options.h"
-#include "vmcore/utf8.h"
-
-
-/* primitivetype_table *********************************************************
-
-   Structure for primitive classes: contains the class for wrapping
-   the primitive type, the primitive class, the name of the class for
-   wrapping, the one character type signature and the name of the
-   primitive class.
-   CAUTION: Don't change the order of the types. This table is indexed
-   by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
-
-*******************************************************************************/
-
-primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
-       { "int"     , NULL, NULL, NULL, "java/lang/Integer",   'I', "[I", NULL },
-       { "long"    , NULL, NULL, NULL, "java/lang/Long",      'J', "[J", NULL },
-       { "float"   , NULL, NULL, NULL, "java/lang/Float",     'F', "[F", NULL },
-       { "double"  , NULL, NULL, NULL, "java/lang/Double",    'D', "[D", NULL },
-       { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
-       { "byte"    , NULL, NULL, NULL, "java/lang/Byte",      'B', "[B", NULL },
-       { "char"    , NULL, NULL, NULL, "java/lang/Character", 'C', "[C", NULL },
-       { "short"   , NULL, NULL, NULL, "java/lang/Short",     'S', "[S", NULL },
-       { "boolean" , NULL, NULL, NULL, "java/lang/Boolean",   'Z', "[Z", NULL },
-       { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
-#if defined(ENABLE_JAVASE)
-       { "void"    , NULL, NULL, NULL, "java/lang/Void",      'V', NULL, NULL }
-#else
-       { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
-#endif
-};
-
-
-/* primitive_init **************************************************************
-
-   Fill the primitive type table with the primitive-type classes,
-   array-classes and wrapper classes.  This is important in the VM
-   startup.
-
-   We split this primitive-type table initialization because of
-   annotations in the bootstrap classes.
-
-   But we may get a problem if we have annotations in:
-
-   java/lang/Object
-   java/lang/Cloneable
-   java/io/Serializable
-
-   Also see: loader_preinit and linker_preinit.
-
-*******************************************************************************/
-
-void primitive_init(void)
-{  
-       utf       *name;
-       classinfo *c;
-       utf       *u;
-       classinfo *ac;
-       int        i;
-
-       TRACESUBSYSTEMINITIALIZATION("primitive_init");
-
-       /* Load and link primitive-type classes and array-classes. */
-
-       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
-               /* Skip dummy entries. */
-
-               if (primitivetype_table[i].cname == NULL)
-                       continue;
-
-               /* create UTF-8 name */
-
-               name = utf_new_char(primitivetype_table[i].cname);
-
-               primitivetype_table[i].name = name;
-
-               /* create primitive class */
-
-               c = class_create_classinfo(name);
-
-               /* Primitive type classes don't have a super class. */
-
-               c->super = NULL;
-
-               /* set flags and mark it as primitive class */
-
-               c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT | ACC_CLASS_PRIMITIVE;
-               
-               /* prevent loader from loading primitive class */
-
-               c->state |= CLASS_LOADED;
-
-               /* INFO: don't put primitive classes into the classcache */
-
-               if (!link_class(c))
-                       vm_abort("linker_init: linking failed");
-
-               /* Just to be sure. */
-
-               assert(c->state & CLASS_LOADED);
-               assert(c->state & CLASS_LINKED);
-
-               primitivetype_table[i].class_primitive = c;
-
-               /* Create primitive array class. */
-
-               if (primitivetype_table[i].arrayname != NULL) {
-                       u  = utf_new_char(primitivetype_table[i].arrayname);
-                       ac = class_create_classinfo(u);
-                       ac = load_newly_created_array(ac, NULL);
-
-                       if (ac == NULL)
-                               vm_abort("primitive_init: loading failed");
-
-                       assert(ac->state & CLASS_LOADED);
-
-                       if (!link_class(ac))
-                               vm_abort("primitive_init: linking failed");
-
-                       /* Just to be sure. */
-
-                       assert(ac->state & CLASS_LOADED);
-                       assert(ac->state & CLASS_LINKED);
-
-                       primitivetype_table[i].arrayclass = ac;
-               }
-       }
-
-       /* We use two for-loops to have the array-classes already in the
-          primitive-type table (hint: annotations in wrapper-classes). */
-
-       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
-               /* Skip dummy entries. */
-
-               if (primitivetype_table[i].cname == NULL)
-                       continue;
-
-               /* Create class for wrapping the primitive type. */
-
-               u = utf_new_char(primitivetype_table[i].wrapname);
-               c = load_class_bootstrap(u);
-
-               if (c == NULL)
-                       vm_abort("primitive_init: loading failed");
-
-               if (!link_class(c))
-                       vm_abort("primitive_init: linking failed");
-
-               /* Just to be sure. */
-
-               assert(c->state & CLASS_LOADED);
-               assert(c->state & CLASS_LINKED);
-
-               primitivetype_table[i].class_wrap = c;
-       }
-}
-
-
-/* primitive_postinit **********************************************************
-
-   Finish the primitive-type table initialization.  In this step we
-   set the vftbl of the primitive-type classes.
-
-   This is necessary because java/lang/Class is loaded and linked
-   after the primitive types have been linked.
-
-   We have to do that in an extra function, as the primitive types are
-   not stored in the classcache.
-
-*******************************************************************************/
-
-void primitive_postinit(void)
-{
-       classinfo *c;
-       int        i;
-
-       TRACESUBSYSTEMINITIALIZATION("primitive_postinit");
-
-       assert(class_java_lang_Class);
-       assert(class_java_lang_Class->vftbl);
-
-       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
-               /* Skip dummy entries. */
-
-               if (primitivetype_table[i].cname == NULL)
-                       continue;
-
-               c = primitivetype_table[i].class_primitive;
-
-               c->object.header.vftbl = class_java_lang_Class->vftbl;
-       }
-}
-
-
-/*
- * 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/vmcore/references.h b/src/vmcore/references.h
deleted file mode 100644 (file)
index 9fa790c..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/* src/vmcore/references.h - references to classes/fields/methods
-
-   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 _REFERENCES_H_
-#define _REFERENCES_H_
-
-/* forward typedefs ***********************************************************/
-
-typedef struct constant_classref constant_classref;
-typedef struct constant_FMIref   constant_FMIref;
-
-
-/* constant_classref **********************************************************/
-
-struct constant_classref {
-       void             *pseudo_vftbl; /* for distinguishing it from classinfo   */
-       struct classinfo *referer;    /* class containing the reference           */
-       struct utf       *name;       /* name of the class refered to             */
-};
-
-
-/* classref_or_classinfo ******************************************************/
-
-typedef union classref_or_classinfo {
-       constant_classref *ref;       /* a symbolic class reference               */
-       struct classinfo  *cls;       /* an already loaded class                  */
-       void              *any;       /* used for general access (x != NULL,...)  */
-} classref_or_classinfo;
-
-
-/* parseddesc_t ***************************************************************/
-
-typedef union parseddesc {
-       struct typedesc   *fd;        /* parsed field descriptor                  */
-       struct methoddesc *md;        /* parsed method descriptor                 */
-       void              *any;       /* used for simple test against NULL        */
-} parseddesc_t;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/descriptor.h"
-#include "vmcore/field.h"
-#include "vmcore/method.h"
-#include "vmcore/utf8.h"
-
-
-/*----------------------------------------------------------------------------*/
-/* References                                                                 */
-/*                                                                            */
-/* This header files defines the following types used for references to       */
-/* classes/methods/fields and descriptors:                                    */
-/*                                                                            */
-/*     classinfo *                a loaded class                              */
-/*     constant_classref          a symbolic reference                        */
-/*     classref_or_classinfo      a loaded class or a symbolic reference      */
-/*                                                                            */
-/*     constant_FMIref            a symb. ref. to a field/method/intf.method  */
-/*                                                                            */
-/*     typedesc *                 describes a field type                      */
-/*     methoddesc *               descrives a method type                     */
-/*     parseddesc                 describes a field type or a method type     */
-/*----------------------------------------------------------------------------*/
-
-/* structs ********************************************************************/
-
-/* constant_FMIref ************************************************************/
-
-struct constant_FMIref{      /* Fieldref, Methodref and InterfaceMethodref    */
-       union {
-               s4                 index;     /* used only within the loader          */
-               constant_classref *classref;  /* class having this field/meth./intfm. */
-               fieldinfo         *field;     /* resolved field                       */
-               methodinfo        *method;    /* resolved method                      */
-       } p;
-       utf         *name;       /* field/method/interfacemethod name             */
-       utf         *descriptor; /* field/method/intfmeth. type descriptor string */
-       parseddesc_t parseddesc; /* parsed descriptor                             */
-};
-
-
-/* macros *********************************************************************/
-
-/* a value that never occurrs in classinfo.header.vftbl                       */
-#define CLASSREF_PSEUDO_VFTBL ((void *) 1)
-
-/* macro for testing if a classref_or_classinfo is a classref                 */
-/* `reforinfo` is only evaluated once                                         */
-#define IS_CLASSREF(reforinfo)  \
-       ((reforinfo).ref->pseudo_vftbl == CLASSREF_PSEUDO_VFTBL)
-
-/* macro for testing if a constant_FMIref has been resolved                   */
-/* `fmiref` is only evaluated once                                            */
-#define IS_FMIREF_RESOLVED(fmiref)  \
-       ((fmiref)->p.classref->pseudo_vftbl != CLASSREF_PSEUDO_VFTBL)
-
-/* the same as IS_CLASSREF, but also check against NULL */
-#define IS_XCLASSREF(reforinfo)  \
-       ((reforinfo).any && IS_CLASSREF(reforinfo))
-
-/* macro for casting a classref/classinfo * to a classref_or_classinfo        */
-#define CLASSREF_OR_CLASSINFO(value) \
-       (*((classref_or_classinfo *)(&(value))))
-
-/* macro for accessing the name of a classref/classinfo                       */
-#define CLASSREF_OR_CLASSINFO_NAME(value) \
-       (IS_CLASSREF(value) ? (value).ref->name : (value).cls->name)
-
-/* macro for accessing the class name of a method reference                   */
-#define METHODREF_CLASSNAME(fmiref) \
-       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.method->clazz->name \
-                                                               : (fmiref)->p.classref->name)
-
-/* macro for accessing the class name of a field reference                   */
-#define FIELDREF_CLASSNAME(fmiref) \
-       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.field->clazz->name \
-                                                               : (fmiref)->p.classref->name)
-
-/* initialize a constant_classref with referer `ref` and name `classname`     */
-
-#define CLASSREF_INIT(c,ref,classname) \
-    do { \
-        (c).pseudo_vftbl = CLASSREF_PSEUDO_VFTBL; \
-        (c).referer = (ref); \
-        (c).name = (classname); \
-    } while (0)
-
-#endif /* _REFERENCES_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/vmcore/rt-timing.c b/src/vmcore/rt-timing.c
deleted file mode 100644 (file)
index 7e535be..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* src/vmcore/rt-timing.c - POSIX real-time timing utilities
-
-   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
-
-   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 <errno.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "vm/global.h"
-
-#include "vmcore/rt-timing.h"
-
-
-struct rt_timing_stat {
-       int index;
-       int totalindex;
-       const char *name;
-};
-
-static struct rt_timing_stat rt_timing_stat_defs[] = {
-    { RT_TIMING_JIT_CHECKS      ,RT_TIMING_JIT_TOTAL , "checks at beginning" },
-    { RT_TIMING_JIT_PARSE       ,RT_TIMING_JIT_TOTAL , "parse" },
-    { RT_TIMING_JIT_STACK       ,RT_TIMING_JIT_TOTAL , "analyse_stack" },
-    { RT_TIMING_JIT_TYPECHECK   ,RT_TIMING_JIT_TOTAL , "typecheck" },
-    { RT_TIMING_JIT_LOOP        ,RT_TIMING_JIT_TOTAL , "loop" },
-    { RT_TIMING_JIT_IFCONV      ,RT_TIMING_JIT_TOTAL , "if conversion" },
-    { RT_TIMING_JIT_ALLOC       ,RT_TIMING_JIT_TOTAL , "register allocation" },
-    { RT_TIMING_JIT_RPLPOINTS   ,RT_TIMING_JIT_TOTAL , "replacement point generation" },
-    { RT_TIMING_JIT_CODEGEN     ,RT_TIMING_JIT_TOTAL , "codegen" },
-    { RT_TIMING_JIT_TOTAL       ,-1                  , "total compile time" },
-    { -1                        ,-1                  , "" },
-
-    { RT_TIMING_LINK_RESOLVE    ,RT_TIMING_LINK_TOTAL, "link: resolve superclass/superinterfaces"},
-    { RT_TIMING_LINK_C_VFTBL    ,RT_TIMING_LINK_TOTAL, "link: compute vftbl length"},
-    { RT_TIMING_LINK_ABSTRACT   ,RT_TIMING_LINK_TOTAL, "link: handle abstract methods"},
-    { RT_TIMING_LINK_C_IFTBL    ,RT_TIMING_LINK_TOTAL, "link: compute interface table"},
-    { RT_TIMING_LINK_F_VFTBL    ,RT_TIMING_LINK_TOTAL, "link: fill vftbl"},
-    { RT_TIMING_LINK_OFFSETS    ,RT_TIMING_LINK_TOTAL, "link: set offsets"},
-    { RT_TIMING_LINK_F_IFTBL    ,RT_TIMING_LINK_TOTAL, "link: fill interface table"},
-    { RT_TIMING_LINK_FINALIZER  ,RT_TIMING_LINK_TOTAL, "link: set finalizer"},
-    { RT_TIMING_LINK_EXCEPTS    ,RT_TIMING_LINK_TOTAL, "link: resolve exception classes"},
-    { RT_TIMING_LINK_SUBCLASS   ,RT_TIMING_LINK_TOTAL, "link: re-calculate subclass indices"},
-    { RT_TIMING_LINK_TOTAL      ,-1                  , "total link time" },
-    { -1                        ,-1                  , "" },
-       
-       { RT_TIMING_LOAD_CHECKS     ,RT_TIMING_LOAD_TOTAL, "load: initial checks"},
-       { RT_TIMING_LOAD_NDPOOL     ,RT_TIMING_LOAD_TOTAL, "load: new descriptor pool"},
-       { RT_TIMING_LOAD_CPOOL      ,RT_TIMING_LOAD_TOTAL, "load: load constant pool"},
-       { RT_TIMING_LOAD_SETUP      ,RT_TIMING_LOAD_TOTAL, "load: class setup"},
-       { RT_TIMING_LOAD_FIELDS     ,RT_TIMING_LOAD_TOTAL, "load: load fields"},
-       { RT_TIMING_LOAD_METHODS    ,RT_TIMING_LOAD_TOTAL, "load: load methods"},
-       { RT_TIMING_LOAD_CLASSREFS  ,RT_TIMING_LOAD_TOTAL, "load: create classrefs"},
-       { RT_TIMING_LOAD_DESCS      ,RT_TIMING_LOAD_TOTAL, "load: allocate descriptors"},
-       { RT_TIMING_LOAD_SETREFS    ,RT_TIMING_LOAD_TOTAL, "load: set classrefs"},
-       { RT_TIMING_LOAD_PARSEFDS   ,RT_TIMING_LOAD_TOTAL, "load: parse field descriptors"},
-       { RT_TIMING_LOAD_PARSEMDS   ,RT_TIMING_LOAD_TOTAL, "load: parse method descriptors"},
-       { RT_TIMING_LOAD_PARSECP    ,RT_TIMING_LOAD_TOTAL, "load: parse descriptors in constant pool"},
-       { RT_TIMING_LOAD_VERIFY     ,RT_TIMING_LOAD_TOTAL, "load: verifier checks"},
-       { RT_TIMING_LOAD_ATTRS      ,RT_TIMING_LOAD_TOTAL, "load: load attributes"},
-       { RT_TIMING_LOAD_TOTAL      ,-1                  , "total load time (from classbuffer)"},
-    { -1                        ,-1                  , "" },
-
-       { RT_TIMING_LOAD_BOOT_LOOKUP,-1                       , "boot: lookup in classcache"},
-       { RT_TIMING_LOAD_BOOT_ARRAY ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: load array classes"},
-       { RT_TIMING_LOAD_BOOT_SUCK  ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: suck class files"},
-       { RT_TIMING_LOAD_BOOT_LOAD  ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: load from class buffer"},
-       { RT_TIMING_LOAD_BOOT_CACHE ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: store in classcache"},
-       { RT_TIMING_LOAD_BOOT_TOTAL ,-1                       , "total bootstrap loader time"},
-    { -1                        ,-1                       , "" },
-
-       { RT_TIMING_LOAD_CL_LOOKUP  ,-1                       , "classloader: lookup in classcache" },
-       { RT_TIMING_LOAD_CL_PREPARE ,-1                       , "classloader: prepare loader call" },
-       { RT_TIMING_LOAD_CL_JAVA    ,-1                       , "classloader: loader Java code" },
-       { RT_TIMING_LOAD_CL_CACHE   ,-1                       , "classloader: store in classcache" },
-    { -1                        ,-1                       , "" },
-
-       { RT_TIMING_NEW_OBJECT      ,-1                       , "builtin_new time" },
-       { RT_TIMING_NEW_ARRAY       ,-1                       , "builtin_newarray time" },
-    { -1                        ,-1                       , "" },
-
-       { RT_TIMING_GC_ALLOC        ,-1                       , "heap allocation time" },
-#if defined(ENABLE_GC_CACAO)
-       { RT_TIMING_GC_SUSPEND      ,RT_TIMING_GC_TOTAL       , "gc: suspending threads" },
-       { RT_TIMING_GC_ROOTSET1     ,RT_TIMING_GC_TOTAL       , "gc: rootset finding" },
-       { RT_TIMING_GC_MARK         ,RT_TIMING_GC_TOTAL       , "gc: marking phase" },
-       { RT_TIMING_GC_COMPACT      ,RT_TIMING_GC_TOTAL       , "gc: compaction phase" },
-       { RT_TIMING_GC_ROOTSET2     ,RT_TIMING_GC_TOTAL       , "gc: rootset writeback" },
-       { RT_TIMING_GC_TOTAL        ,-1                       , "total garbage collection time" },
-       { -1                        ,-1                       , "" },
-#endif
-
-    { 0                         ,-1                       , NULL }
-};
-
-static long long rt_timing_sum[RT_TIMING_N] = { 0 };
-
-void rt_timing_gettime(struct timespec *ts)
-{
-       if (clock_gettime(CLOCK_THREAD_CPUTIME_ID,ts) != 0) {
-               fprintf(stderr,"could not get time by clock_gettime: %s\n",strerror(errno));
-               abort();
-       }
-}
-
-long rt_timing_diff_usec(struct timespec *a,struct timespec *b)
-{
-       long diff;
-       time_t atime;
-
-       diff = (b->tv_nsec - a->tv_nsec) / 1000;
-       atime = a->tv_sec;
-       while (atime < b->tv_sec) {
-               atime++;
-               diff += 1000000;
-       }
-       return diff;
-}
-
-void rt_timing_time_diff(struct timespec *a,struct timespec *b,int index)
-{
-       long diff;
-
-       diff = rt_timing_diff_usec(a,b);
-       rt_timing_sum[index] += diff;
-}
-
-void rt_timing_print_time_stats(FILE *file)
-{
-       struct rt_timing_stat *stats;
-       double total;
-
-       for (stats = rt_timing_stat_defs; stats->name; ++stats) {
-               if (stats->index < 0) {
-                       fprintf(file,"%s\n",stats->name);
-                       continue;
-               }
-               
-               if (stats->totalindex >= 0) {
-                       total = rt_timing_sum[stats->totalindex];
-                       fprintf(file,"%12lld usec %3.0f%% %s\n",
-                                       rt_timing_sum[stats->index],
-                                       (total != 0.0) ? rt_timing_sum[stats->index] / total * 100.0 : 0.0,
-                                       stats->name);
-               }
-               else {
-                       fprintf(file,"%12lld usec      %s\n",
-                                       rt_timing_sum[stats->index],
-                                       stats->name);
-               }
-       }
-}
-
-/*
- * 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/vmcore/rt-timing.h b/src/vmcore/rt-timing.h
deleted file mode 100644 (file)
index d78e8c9..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/* src/vmcore/rt-timing.h - POSIX real-time timing utilities
-
-   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
-
-   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 _RT_TIMING_H
-#define _RT_TIMING_H
-
-#include "config.h"
-
-#if defined(ENABLE_RT_TIMING)
-
-#include <time.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "vm/global.h"
-
-
-#define RT_TIMING_GET_TIME(ts) \
-       rt_timing_gettime(&(ts));
-
-#define RT_TIMING_TIME_DIFF(a,b,index) \
-       rt_timing_time_diff(&(a),&(b),(index));
-
-#define RT_TIMING_JIT_CHECKS       0
-#define RT_TIMING_JIT_PARSE        1
-#define RT_TIMING_JIT_STACK        2
-#define RT_TIMING_JIT_TYPECHECK    3
-#define RT_TIMING_JIT_LOOP         4
-#define RT_TIMING_JIT_IFCONV       5
-#define RT_TIMING_JIT_ALLOC        6
-#define RT_TIMING_JIT_RPLPOINTS    7
-#define RT_TIMING_JIT_CODEGEN      8
-#define RT_TIMING_JIT_TOTAL        9
-
-#define RT_TIMING_LINK_RESOLVE     10
-#define RT_TIMING_LINK_C_VFTBL     11
-#define RT_TIMING_LINK_ABSTRACT    12
-#define RT_TIMING_LINK_C_IFTBL     13
-#define RT_TIMING_LINK_F_VFTBL     14
-#define RT_TIMING_LINK_OFFSETS     15
-#define RT_TIMING_LINK_F_IFTBL     16
-#define RT_TIMING_LINK_FINALIZER   17
-#define RT_TIMING_LINK_EXCEPTS     18
-#define RT_TIMING_LINK_SUBCLASS    19
-#define RT_TIMING_LINK_TOTAL       20
-
-#define RT_TIMING_LOAD_CHECKS      21
-#define RT_TIMING_LOAD_NDPOOL      22
-#define RT_TIMING_LOAD_CPOOL       23
-#define RT_TIMING_LOAD_SETUP       24
-#define RT_TIMING_LOAD_FIELDS      25
-#define RT_TIMING_LOAD_METHODS     26
-#define RT_TIMING_LOAD_CLASSREFS   27
-#define RT_TIMING_LOAD_DESCS       28
-#define RT_TIMING_LOAD_SETREFS     29
-#define RT_TIMING_LOAD_PARSEFDS    30
-#define RT_TIMING_LOAD_PARSEMDS    31
-#define RT_TIMING_LOAD_PARSECP     32
-#define RT_TIMING_LOAD_VERIFY      33
-#define RT_TIMING_LOAD_ATTRS       34
-#define RT_TIMING_LOAD_TOTAL       35
-
-#define RT_TIMING_LOAD_BOOT_LOOKUP 36
-#define RT_TIMING_LOAD_BOOT_ARRAY  37
-#define RT_TIMING_LOAD_BOOT_SUCK   38
-#define RT_TIMING_LOAD_BOOT_LOAD   39
-#define RT_TIMING_LOAD_BOOT_CACHE  40
-#define RT_TIMING_LOAD_BOOT_TOTAL  41
-
-#define RT_TIMING_LOAD_CL_LOOKUP   42
-#define RT_TIMING_LOAD_CL_PREPARE  43
-#define RT_TIMING_LOAD_CL_JAVA     44
-#define RT_TIMING_LOAD_CL_CACHE    45
-
-#define RT_TIMING_NEW_OBJECT       46
-#define RT_TIMING_NEW_ARRAY        47
-
-#define RT_TIMING_GC_ALLOC         48
-#define RT_TIMING_GC_SUSPEND       49
-#define RT_TIMING_GC_ROOTSET1      50
-#define RT_TIMING_GC_MARK          51
-#define RT_TIMING_GC_COMPACT       52
-#define RT_TIMING_GC_ROOTSET2      53
-#define RT_TIMING_GC_TOTAL         54
-
-#define RT_TIMING_N                55
-
-void rt_timing_gettime(struct timespec *ts);
-
-void rt_timing_time_diff(struct timespec *a,struct timespec *b,int index);
-
-long rt_timing_diff_usec(struct timespec *a,struct timespec *b);
-
-void rt_timing_print_time_stats(FILE *file);
-
-#else /* !defined(ENABLE_RT_TIMING) */
-
-#define RT_TIMING_GET_TIME(ts)
-#define RT_TIMING_TIME_DIFF(a,b,index)
-
-#endif /* defined(ENABLE_RT_TIMING) */
-
-#endif /* _RT_TIMING_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/vmcore/stackmap.c b/src/vmcore/stackmap.c
deleted file mode 100644 (file)
index 40ee97e..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-/* src/vmcore/stackmap.c - class attribute StackMapTable
-
-   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 "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "vm/exceptions.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/stackmap.h"
-#include "vmcore/statistics.h"
-#include "vmcore/suck.h"
-
-
-/* stackmap_get_verification_type_info *****************************************
-
-   union verification_type_info {
-       Top_variable_info;
-          Integer_variable_info;
-          Float_variable_info;
-          Long_variable_info;
-          Double_variable_info;
-          Null_variable_info;
-          UninitializedThis_variable_info;
-          Object_variable_info;
-          Uninitialized_variable_info;
-   }
-
-   Top_variable_info {
-       u1 tag = ITEM_Top;  // 0
-   }
-
-   Integer_variable_info {
-       u1 tag = ITEM_Integer;  // 1
-   }
-
-   Float_variable_info {
-       u1 tag = ITEM_Float;  // 2
-   }
-
-   Long_variable_info {
-       u1 tag = ITEM_Long;  // 4
-   }
-
-   Double_variable_info {
-       u1 tag = ITEM_Double;  // 3
-   }
-
-   Null_variable_info {
-       u1 tag = ITEM_Null;  // 5
-   }
-
-   UninitializedThis_variable_info {
-       u1 tag = ITEM_UninitializedThis;  // 6
-   }
-
-   Object_variable_info {
-       u1 tag = ITEM_Object;  // 7
-          u2 cpool_index;
-   }
-
-   Uninitialized_variable_info {
-       u1 tag = ITEM_Uninitialized;  // 8
-          u2 offset;
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_verification_type_info(classbuffer *cb, verification_type_info_t *verification_type_info)
-{
-       /* get verification type */
-
-       if (!suck_check_classbuffer_size(cb, 1))
-               return false;
-
-       verification_type_info->tag = suck_u1(cb);
-
-       /* process the tag */
-
-       switch (verification_type_info->tag) {
-       case ITEM_Top:
-       case ITEM_Integer:
-       case ITEM_Float:
-       case ITEM_Long:
-       case ITEM_Double:
-       case ITEM_Null:
-       case ITEM_UninitializedThis:
-               break;
-
-       case ITEM_Object:
-               /* get constant pool index */
-
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               verification_type_info->Object_variable_info.cpool_index = suck_u2(cb);
-               break;
-
-       case ITEM_Uninitialized:
-               /* get offset */
-
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               verification_type_info->Uninitialized_variable_info.offset = suck_u2(cb);
-               break;
-       }
-
-       return true;
-}
-
-
-/* stackmap_get_same_locals_1_stack_item_frame *********************************
-
-   same_locals_1_stack_item_frame {
-       u1 frame_type = SAME_LOCALS_1_STACK_ITEM;  // 64-127
-          verification_type_info stack[1];
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_same_locals_1_stack_item_frame(classbuffer *cb, stack_map_frame_t *stack_map_frame)
-{
-       same_locals_1_stack_item_frame_t *same_locals_1_stack_item_frame;
-
-       /* for convenience */
-
-       same_locals_1_stack_item_frame =
-               &(stack_map_frame->same_locals_1_stack_item_frame);
-
-       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame->stack[0])))
-               return false;
-
-       return true;
-}
-
-
-/* stackmap_get_same_locals_1_stack_item_frame_extended ************************
-
-   same_locals_1_stack_item_frame_extended {
-       u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED;  // 247
-          u2 offset_delta;
-          verification_type_info stack[1];
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_same_locals_1_stack_item_frame_extended(classbuffer *cb, stack_map_frame_t *stack_map_frame)
-{
-       same_locals_1_stack_item_frame_extended_t *same_locals_1_stack_item_frame_extended;
-
-       /* for convenience */
-
-       same_locals_1_stack_item_frame_extended =
-               &(stack_map_frame->same_locals_1_stack_item_frame_extended);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* get offset delta */
-
-       same_locals_1_stack_item_frame_extended->offset_delta = suck_u2(cb);
-
-       /* process stack */
-
-       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame_extended->stack[0])))
-               return false;
-
-       return true;
-}
-
-
-/* stackmap_get_chop_frame *****************************************************
-
-   chop_frame {
-       u1 frame_type = CHOP_FRAME;  // 248-250
-          u2 offset_delta;
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_chop_frame(classbuffer *cb,
-                                                                       stack_map_frame_t *stack_map_frame)
-{
-       chop_frame_t *chop_frame;
-
-       /* for convenience */
-
-       chop_frame = &(stack_map_frame->chop_frame);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* get offset delta */
-
-       chop_frame->offset_delta = suck_u2(cb);
-
-       return true;
-}
-
-
-/* stackmap_get_same_frame_extended ********************************************
-
-   same_frame_extended {
-       u1 frame_type = SAME_FRAME_EXTENDED;  // 251
-          u2 offset_delta;
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_same_frame_extended(classbuffer *cb,
-                                                                                        stack_map_frame_t *stack_map_frame)
-{
-       same_frame_extended_t *same_frame_extended;
-
-       /* for convenience */
-
-       same_frame_extended = &(stack_map_frame->same_frame_extended);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* get offset delta */
-
-       same_frame_extended->offset_delta = suck_u2(cb);
-
-       return true;
-}
-
-
-/* stackmap_get_append_frame ***************************************************
-
-   append_frame {
-       u1 frame_type = APPEND_FRAME;  // 252-254
-          u2 offset_delta;
-          verification_type_info locals[frame_Type - 251];
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_append_frame(classbuffer *cb,
-                                                                         stack_map_frame_t *stack_map_frame)
-{
-       append_frame_t *append_frame;
-       s4              number_of_locals;
-       s4              i;
-
-       /* for convenience */
-
-       append_frame = &(stack_map_frame->append_frame);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* get offset delta */
-
-       append_frame->offset_delta = suck_u2(cb);
-
-       /* allocate locals array */
-
-       number_of_locals = append_frame->frame_type - 251;
-
-       append_frame->locals = DMNEW(verification_type_info_t, number_of_locals);
-
-       /* process all locals */
-
-       for (i = 0; i < number_of_locals; i++)
-               if (!stackmap_get_verification_type_info(cb, &(append_frame->locals[i])))
-                       return false;
-
-       return true;
-}
-
-
-/* stackmap_get_full_frame *****************************************************
-
-   full_frame {
-       u1 frame_type = FULL_FRAME;
-          u2 offset_delta;
-          u2 number_of_locals;
-          verification_type_info locals[number_of_locals];
-          u2 number_of_stack_items;
-          verification_type_info stack[number_of_stack_items];
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_full_frame(classbuffer *cb,
-                                                                       stack_map_frame_t *stack_map_frame)
-{
-       full_frame_t *full_frame;
-       s4 i;
-
-       /* for convenience */
-
-       full_frame = &(stack_map_frame->full_frame);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2 + 2))
-               return false;
-
-       /*  get offset delta */
-
-       stack_map_frame->full_frame.offset_delta = suck_u2(cb);
-
-       /* get number of locals */
-
-       full_frame->number_of_locals = suck_u2(cb);
-
-       /* allocate locals array */
-
-       full_frame->locals =
-               DMNEW(verification_type_info_t, full_frame->number_of_locals);
-
-       /* process all locals */
-
-       for (i = 0; i < full_frame->number_of_locals; i++)
-               if (!stackmap_get_verification_type_info(cb, &(full_frame->locals[i])))
-                       return false;
-
-       /* get number of stack items */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       full_frame->number_of_stack_items = suck_u2(cb);
-
-       /* allocate stack array */
-
-       full_frame->stack =
-               DMNEW(verification_type_info_t, full_frame->number_of_stack_items);
-
-       /* process all stack items */
-
-       for (i = 0; i < full_frame->number_of_stack_items; i++)
-               if (!stackmap_get_verification_type_info(cb, &(full_frame->stack[i])))
-                       return false;
-
-       return true;
-}
-
-
-/* stackmap_load_attribute_stackmaptable ***************************************
-
-   stack_map {
-          u2 attribute_name_index;
-          u4 attribute_length;
-          u2 number_of_entries;
-          stack_map_frame entries[number_of_entries];
-   }
-
-   union stack_map_frame {
-       same_frame;
-          same_locals_1_stack_item_frame;
-          same_locals_1_stack_item_frame_extended;
-          chop_frame;
-          same_frame_extended;
-          append_frame;
-          full_frame;
-   }
-
-   same_frame {
-       u1 frame_type = SAME;  // 0-63
-   }
-
-*******************************************************************************/
-
-bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m)
-{
-       classinfo       *c;
-       stack_map_t     *stack_map;
-       s4               i;
-       u1               frame_type;
-
-       /* get classinfo */
-
-       c = cb->clazz;
-
-       /* allocate stack map structure */
-
-       stack_map = DNEW(stack_map_t);
-
-       STATISTICS(size_stack_map += sizeof(stack_map_t));
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2))
-               return false;
-
-       /* attribute_length */
-
-       stack_map->attribute_length = suck_u4(cb);
-
-       if (!suck_check_classbuffer_size(cb, stack_map->attribute_length))
-               return false;
-
-       /* get number of entries */
-
-       stack_map->number_of_entries = suck_u2(cb);
-
-       /* process all entries */
-
-       stack_map->entries = DMNEW(stack_map_frame_t, stack_map->number_of_entries);
-
-       for (i = 0; i < stack_map->number_of_entries; i++) {
-               /* get the frame type */
-
-               frame_type = suck_u1(cb);
-
-               stack_map->entries[i].frame_type = frame_type;
-
-               /* process frame */
-
-               if (frame_type <= FRAME_TYPE_SAME) {
-                       /* same_frame */
-               }
-               else if (frame_type <= FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM) {
-                       /* same_locals_1_stack_item_frame */
-
-                       if (!stackmap_get_same_locals_1_stack_item_frame(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type <= FRAME_TYPE_RESERVED) {
-                       /* reserved */
-
-                       exceptions_throw_classformaterror(c, "reserved frame type");
-                       return false;
-               }
-               else if (frame_type == FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
-                       /* same_locals_1_stack_item_frame_extended */
-
-                       if (!stackmap_get_same_locals_1_stack_item_frame_extended(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type <= FRAME_TYPE_CHOP) {
-                       /* chop_frame */
-
-                       if (!stackmap_get_chop_frame(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type == FRAME_TYPE_SAME_FRAME_EXTENDED) {
-                       /* same_frame_extended */
-
-                       if (!stackmap_get_same_frame_extended(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type <= FRAME_TYPE_APPEND) {
-                       /* append_frame */
-
-                       if (!stackmap_get_append_frame(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type == FRAME_TYPE_FULL_FRAME) {
-                       /* full_frame */
-
-                       if (!stackmap_get_full_frame(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-       }
-
-       /* store stack map in method structure */
-
-#if 0
-       /* currently not used */
-
-       m->stack_map = stack_map;
-#endif
-
-       return true;
-}
-
-
-/*
- * 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/vmcore/stackmap.h b/src/vmcore/stackmap.h
deleted file mode 100644 (file)
index 973941a..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/* src/vmcore/stackmap.h - class attribute StackMapTable
-
-   Copyright (C) 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
-
-   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 _STACKMAP_H
-#define _STACKMAP_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct stack_map_t                       stack_map_t;
-typedef union  stack_map_frame_t                 stack_map_frame_t;
-typedef struct same_locals_1_stack_item_frame_t  same_locals_1_stack_item_frame_t;
-typedef struct same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended_t;
-typedef struct chop_frame_t                      chop_frame_t;
-typedef struct same_frame_extended_t             same_frame_extended_t;
-typedef struct append_frame_t                    append_frame_t;
-typedef struct full_frame_t                      full_frame_t;
-
-typedef union  verification_type_info_t          verification_type_info_t;
-typedef struct Top_variable_info_t                  Top_variable_info_t;
-typedef struct Integer_variable_info_t           Integer_variable_info_t;
-typedef struct Float_variable_info_t             Float_variable_info_t;
-typedef struct Long_variable_info_t              Long_variable_info_t;
-typedef struct Double_variable_info_t            Double_variable_info_t;
-typedef struct Null_variable_info_t              Null_variable_info_t;
-typedef struct UninitializedThis_variable_info_t UninitializedThis_variable_info_t;
-typedef struct Object_variable_info_t            Object_variable_info_t;
-typedef struct Uninitialized_variable_info_t     Uninitialized_variable_info_t;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "vmcore/loader.h"
-#include "vmcore/method.h"
-
-
-/* verification_type_info *****************************************************/
-
-#define ITEM_Top                  0
-#define ITEM_Integer              1
-#define ITEM_Float                2
-#define ITEM_Double               3
-#define ITEM_Long                 4
-#define ITEM_Null                 5
-#define ITEM_UninitializedThis    6
-#define ITEM_Object               7
-#define ITEM_Uninitialized        8
-
-struct Top_variable_info_t {
-       u1 tag;
-};
-
-struct Integer_variable_info_t {
-       u1 tag;
-};
-
-struct Float_variable_info_t {
-       u1 tag;
-};
-
-struct Long_variable_info_t {
-       u1 tag;
-};
-
-struct Double_variable_info_t {
-       u1 tag;
-};
-
-struct Null_variable_info_t {
-       u1 tag;
-};
-
-struct UninitializedThis_variable_info_t {
-       u1 tag;
-};
-
-struct Object_variable_info_t {
-       u1 tag;
-       u2 cpool_index;
-};
-
-struct Uninitialized_variable_info_t {
-       u1 tag;
-       u2 offset;
-};
-
-union verification_type_info_t {
-       u1 tag;
-       Top_variable_info_t                   Top_variable_info;
-       Integer_variable_info_t           Integer_variable_info;
-       Float_variable_info_t             Float_variable_info;
-       Long_variable_info_t              Long_variable_info;
-       Double_variable_info_t            Double_variable_info;
-       Null_variable_info_t              Null_variable_info;
-       UninitializedThis_variable_info_t UninitializedThis_variable_info;
-       Object_variable_info_t            Object_variable_info;
-       Uninitialized_variable_info_t     Uninitialized_variable_info;
-};
-
-
-/* stack_map_t ****************************************************************/
-
-struct stack_map_t {
-       u2                 attribute_name_index;
-       u4                 attribute_length;
-       u2                 number_of_entries;
-       stack_map_frame_t *entries;
-};
-
-
-/* same_locals_1_stack_item_frame_t *******************************************/
-
-struct same_locals_1_stack_item_frame_t {
-       u1                       frame_type;
-       verification_type_info_t stack[1];
-};
-
-
-/* same_locals_1_stack_item_frame_extended_t **********************************/
-
-struct same_locals_1_stack_item_frame_extended_t {
-       u1                       frame_type;
-       u2                       offset_delta;
-       verification_type_info_t stack[1];
-};
-
-
-/* chop_frame_t ***************************************************************/
-
-struct chop_frame_t {
-       u1 frame_type;
-       u2 offset_delta;
-};
-
-
-/* same_frame_extended_t ******************************************************/
-
-struct same_frame_extended_t {
-       u1 frame_type;
-       u2 offset_delta;
-};
-
-
-/* append_frame_t *************************************************************/
-
-struct append_frame_t {
-       u1                        frame_type;
-       u2                        offset_delta;
-       verification_type_info_t *locals;
-};
-
-
-/* full_frame_t ***************************************************************/
-
-struct full_frame_t {
-       u1                        frame_type;
-       u2                        offset_delta;
-       u2                        number_of_locals;
-       verification_type_info_t *locals;
-       u2                        number_of_stack_items;
-       verification_type_info_t *stack;
-};
-
-
-/* stack_map_frame_t **********************************************************/
-
-#define FRAME_TYPE_SAME                                 63   /* 0-63          */
-#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM             127  /* 0-127         */
-#define FRAME_TYPE_RESERVED                             246  /* 128-246       */
-#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED    247  /* 247           */
-#define FRAME_TYPE_CHOP                                 250  /* 248-250       */
-#define FRAME_TYPE_SAME_FRAME_EXTENDED                  251  /* 251           */
-#define FRAME_TYPE_APPEND                               254  /* 252-254       */
-#define FRAME_TYPE_FULL_FRAME                           255  /* 255           */
-
-union stack_map_frame_t {
-       u1                                        frame_type;
-       same_locals_1_stack_item_frame_t          same_locals_1_stack_item_frame;
-       same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended;
-       chop_frame_t                              chop_frame;
-       same_frame_extended_t                     same_frame_extended;
-       append_frame_t                            append_frame;
-       full_frame_t                              full_frame;
-};
-
-
-/* function prototypes ********************************************************/
-
-bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m);
-
-#endif /* _STACKMAP_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/vmcore/statistics.c b/src/vmcore/statistics.c
deleted file mode 100644 (file)
index dbffc11..0000000
+++ /dev/null
@@ -1,825 +0,0 @@
-/* src/vmcore/statistics.c - global varables for statistics
-
-   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
-
-   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 <stdint.h>
-#include <string.h> 
-
-#if defined(HAVE_TIME_H)
-# include <time.h>
-#endif
-
-#if defined(HAVE_SYS_TIME_H)
-# include <sys/time.h>
-#endif
-
-#if defined(HAVE_SYS_RESOURCE_H)
-# include <sys/resource.h>
-#endif
-
-#include "vm/types.h"
-
-#include "mm/gc-common.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/global.h"
-
-#include "vm/jit/code.h"
-
-#include "vmcore/class.h"
-#include "vmcore/field.h"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
-
-/* global variables ***********************************************************/
-
-static s8 loadingtime = 0;              /* accumulated loading time           */
-static s8 loadingstarttime = 0;
-static s8 loadingstoptime = 0;
-static s4 loadingtime_recursion = 0;
-
-static s8 compilingtime = 0;            /* accumulated compile time           */
-static s8 compilingstarttime = 0;
-static s8 compilingstoptime = 0;
-static s4 compilingtime_recursion = 0;
-
-s4 codememusage = 0;
-s4 maxcodememusage = 0;
-
-s4 memoryusage = 0;
-s4 maxmemusage = 0;
-
-s4 maxdumpsize = 0;
-
-s4 globalallocateddumpsize = 0;
-s4 globaluseddumpsize = 0;
-
-
-/* variables for measurements *************************************************/
-
-s4 size_classinfo        = 0;
-s4 size_fieldinfo        = 0;
-s4 size_methodinfo       = 0;
-s4 size_lineinfo         = 0;
-s4 size_codeinfo         = 0;
-
-s4 size_stub_native      = 0;
-
-s4 size_stack_map        = 0;
-s4 size_string           = 0;
-
-s4 size_threadobject     = 0;
-int32_t size_thread_index_t = 0;
-int32_t size_stacksize      = 0;
-
-s4 size_lock_record      = 0;
-s4 size_lock_hashtable   = 0;
-s4 size_lock_waiter      = 0;
-
-int32_t count_linenumbertable = 0;
-int32_t size_linenumbertable  = 0;
-
-s4 size_patchref         = 0;
-
-s4 size_cachedref           = 0;
-
-u8 count_calls_java_to_native = 0;
-u8 count_calls_native_to_java = 0;
-
-int count_const_pool_len = 0;
-int count_classref_len = 0;
-int count_parsed_desc_len = 0;
-int count_vftbl_len = 0;
-int count_all_methods = 0;
-int count_methods_marked_used = 0;  /* RTA */
-
-int count_vmcode_len = 0;
-int count_extable_len = 0;
-int count_class_loads = 0;
-int count_class_inits = 0;
-
-int count_utf_len = 0;                  /* size of utf hash                   */
-int count_utf_new = 0;                  /* calls of utf_new                   */
-int count_utf_new_found  = 0;           /* calls of utf_new with fast return  */
-
-int count_locals_conflicts = 0;         /* register allocator statistics */
-int count_locals_spilled = 0;
-int count_locals_register = 0;
-int count_ss_spilled = 0;
-int count_ss_register = 0;
-int count_methods_allocated_by_lsra = 0;
-int count_mem_move_bb = 0;
-int count_interface_size = 0;
-int count_argument_mem_ss = 0;
-int count_argument_reg_ss = 0;
-int count_method_in_register = 0;
-int count_mov_reg_reg = 0;
-int count_mov_mem_reg = 0;
-int count_mov_reg_mem = 0;
-int count_mov_mem_mem = 0;
-
-int count_jit_calls = 0;
-int count_methods = 0;
-int count_spills_read_ila = 0;
-int count_spills_read_flt = 0;
-int count_spills_read_dbl = 0;
-int count_spills_write_ila = 0;
-int count_spills_write_flt = 0;
-int count_spills_write_dbl = 0;
-int count_pcmd_activ = 0;
-int count_pcmd_drop = 0;
-int count_pcmd_zero = 0;
-int count_pcmd_const_store = 0;
-int count_pcmd_const_alu = 0;
-int count_pcmd_const_bra = 0;
-int count_pcmd_load = 0;
-int count_pcmd_move = 0;
-int count_load_instruction = 0;
-int count_pcmd_store = 0;
-int count_pcmd_store_comb = 0;
-int count_dup_instruction = 0;
-int count_pcmd_op = 0;
-int count_pcmd_mem = 0;
-int count_pcmd_met = 0;
-int count_pcmd_bra = 0;
-int count_pcmd_table = 0;
-int count_pcmd_return = 0;
-int count_pcmd_returnx = 0;
-int count_check_null = 0;
-int count_check_bound = 0;
-int count_max_basic_blocks = 0;
-int count_basic_blocks = 0;
-int count_javainstr = 0;
-int count_max_javainstr = 0;
-int count_javacodesize = 0;
-int count_javaexcsize = 0;
-int count_calls = 0;
-int count_tryblocks = 0;
-int count_code_len = 0;
-int count_data_len = 0;
-int count_cstub_len = 0;
-int count_max_new_stack = 0;
-int count_upper_bound_new_stack = 0;
-
-int count_emit_branch = 0;
-int count_emit_branch_8bit = 0;
-int count_emit_branch_16bit = 0;
-int count_emit_branch_32bit = 0;
-int count_emit_branch_64bit = 0;
-
-s4 count_branches_resolved   = 0;
-s4 count_branches_unresolved = 0;
-
-u8 count_jni_callXmethod_calls=0;
-u8 count_jni_calls=0;
-
-
-static int count_block_stack_init[11] = {
-       0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 
-       0
-};
-int *count_block_stack = count_block_stack_init;
-static int count_analyse_iterations_init[5] = {
-       0, 0, 0, 0, 0
-};
-int *count_analyse_iterations = count_analyse_iterations_init;
-static int count_method_bb_distribution_init[9] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0
-};
-int *count_method_bb_distribution = count_method_bb_distribution_init;
-static int count_block_size_distribution_init[18] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0
-};
-int *count_block_size_distribution = count_block_size_distribution_init;
-static int count_store_length_init[21] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0
-};
-int *count_store_length = count_store_length_init;
-static int count_store_depth_init[11] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0
-};
-int *count_store_depth = count_store_depth_init;
-
-
-/* instruction scheduler statistics *******************************************/
-
-s4 count_schedule_basic_blocks = 0;
-s4 count_schedule_nodes = 0;
-s4 count_schedule_leaders = 0;
-s4 count_schedule_max_leaders = 0;
-s4 count_schedule_critical_path = 0;
-
-
-/* jnicallXmethodinvokation ***************************************************
-
-   increments the jni CallXMethod invokation count by one
-       
-*******************************************************************************/
-
-void jnicallXmethodnvokation(void)
-{
-       /* XXX do locking here */
-       count_jni_callXmethod_calls++;
-}
-
-
-/* jniinvokation *************************************************************
-
-   increments the jni overall  invokation count by one
-       
-*******************************************************************************/
-
-void jniinvokation(void)
-{
-       /* XXX do locking here */
-       count_jni_calls++;
-}
-
-
-/* getcputime *********************************** ******************************
-
-   Returns the used CPU time in microseconds
-       
-*******************************************************************************/
-
-s8 getcputime(void)
-{
-#if defined(HAVE_GETRUSAGE)
-       struct rusage ru;
-       int sec, usec;
-
-       getrusage(RUSAGE_SELF, &ru);
-
-       sec  = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
-       usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec;
-
-       return sec * 1000000 + usec;
-#else
-       /* If we don't have getrusage, simply return 0. */
-
-       return 0;
-#endif
-}
-
-
-/* loadingtime_stop ************************************************************
-
-   XXX
-
-*******************************************************************************/
-
-void loadingtime_start(void)
-{
-       loadingtime_recursion++;
-
-       if (loadingtime_recursion == 1)
-               loadingstarttime = getcputime();
-}
-
-
-/* loadingtime_stop ************************************************************
-
-   XXX
-
-*******************************************************************************/
-
-void loadingtime_stop(void)
-{
-       if (loadingtime_recursion == 1) {
-               loadingstoptime = getcputime();
-               loadingtime += (loadingstoptime - loadingstarttime);
-       }
-
-       loadingtime_recursion--;
-}
-
-
-/* compilingtime_stop **********************************************************
-
-   XXX
-
-*******************************************************************************/
-
-void compilingtime_start(void)
-{
-       compilingtime_recursion++;
-
-       if (compilingtime_recursion == 1)
-               compilingstarttime = getcputime();
-}
-
-
-/* compilingtime_stop **********************************************************
-
-   XXX
-
-*******************************************************************************/
-
-void compilingtime_stop(void)
-{
-       if (compilingtime_recursion == 1) {
-               compilingstoptime = getcputime();
-               compilingtime += (compilingstoptime - compilingstarttime);
-       }
-
-       compilingtime_recursion--;
-}
-
-
-/* print_times *****************************************************************
-
-   Prints a summary of CPU time usage.
-
-*******************************************************************************/
-
-void print_times(void)
-{
-       s8 totaltime;
-       s8 runtime;
-
-       totaltime = getcputime();
-       runtime = totaltime - loadingtime - compilingtime;
-
-#if SIZEOF_VOID_P == 8
-       dolog("Time for loading classes: %6ld ms", loadingtime / 1000);
-       dolog("Time for compiling code:  %6ld ms", compilingtime / 1000);
-       dolog("Time for running program: %6ld ms", runtime / 1000);
-       dolog("Total time:               %6ld ms", totaltime / 1000);
-#else
-       dolog("Time for loading classes: %6lld ms", loadingtime / 1000);
-       dolog("Time for compiling code:  %6lld ms", compilingtime / 1000);
-       dolog("Time for running program: %6lld ms", runtime / 1000);
-       dolog("Total time:               %6lld ms", totaltime / 1000);
-#endif
-}
-
-
-/* print_stats *****************************************************************
-
-   outputs detailed compiler statistics
-
-*******************************************************************************/
-
-void print_stats(void)
-{
-       s4    i;
-       float f;
-       s4    sum;
-
-
-       dolog("Number of JIT compiler calls: %6d", count_jit_calls);
-       dolog("Number of compiled methods:   %6d", count_methods);
-
-       dolog("Number of compiled basic blocks:               %6d",
-                 count_basic_blocks);
-       dolog("Number of max. basic blocks per method:        %6d",
-                 count_max_basic_blocks);
-
-       dolog("Number of compiled JavaVM instructions:        %6d",
-                 count_javainstr);
-       dolog("Number of max. JavaVM instructions per method: %6d",
-                 count_max_javainstr);
-       dolog("Size of compiled JavaVM instructions:          %6d(%d)",
-                 count_javacodesize, count_javacodesize - count_methods * 18);
-
-       dolog("Size of compiled Exception Tables:      %d", count_javaexcsize);
-       dolog("Number of Machine-Instructions: %d", count_code_len >> 2);
-       dolog("Number of Spills (write to memory) <all [i/l/a|flt|dbl]>: %d [%d|%d|%d]",
-               count_spills_write_ila + count_spills_write_flt + count_spills_write_dbl,
-               count_spills_write_ila, count_spills_write_flt, count_spills_write_dbl);
-       dolog("Number of Spills (read from memory) <all [i/l/a|flt|dbl]>: %d [%d|%d|%d]",
-               count_spills_read_ila + count_spills_read_flt + count_spills_read_dbl,
-               count_spills_read_ila, count_spills_read_flt, count_spills_read_dbl);
-       dolog("Number of Activ    Pseudocommands: %6d", count_pcmd_activ);
-       dolog("Number of Drop     Pseudocommands: %6d", count_pcmd_drop);
-       dolog("Number of Const    Pseudocommands: %6d (zero:%5d)",
-                 count_pcmd_load, count_pcmd_zero);
-       dolog("Number of ConstAlu Pseudocommands: %6d (cmp: %5d, store:%5d)",
-                 count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
-       dolog("Number of Move     Pseudocommands: %6d", count_pcmd_move);
-       dolog("Number of Load     Pseudocommands: %6d", count_load_instruction);
-       dolog("Number of Store    Pseudocommands: %6d (combined: %5d)",
-                 count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
-       dolog("Number of OP       Pseudocommands: %6d", count_pcmd_op);
-       dolog("Number of DUP      Pseudocommands: %6d", count_dup_instruction);
-       dolog("Number of Mem      Pseudocommands: %6d", count_pcmd_mem);
-       dolog("Number of Method   Pseudocommands: %6d", count_pcmd_met);
-       dolog("Number of Branch   Pseudocommands: %6d (rets:%5d, Xrets: %5d)",
-                 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
-       log_println("                resolved branches: %6d", count_branches_resolved);
-       log_println("              unresolved branches: %6d", count_branches_unresolved);
-       dolog("Number of Table    Pseudocommands: %6d", count_pcmd_table);
-       dolog("Number of Useful   Pseudocommands: %6d", count_pcmd_table +
-                 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
-       dolog("Number of Null Pointer Checks:     %6d", count_check_null);
-       dolog("Number of Array Bound Checks:      %6d", count_check_bound);
-       dolog("Number of Try-Blocks: %d", count_tryblocks);
-
-       dolog("Number of branch_emit (total, 8bit/16bit/32bit/64bit offset): %d, %d/%d/%d/%d",
-               count_emit_branch,  count_emit_branch_8bit,  count_emit_branch_16bit, 
-                                                       count_emit_branch_32bit, count_emit_branch_64bit);
-
-       dolog("Maximal count of stack elements:   %d", count_max_new_stack);
-       dolog("Upper bound of max stack elements: %d", count_upper_bound_new_stack);
-       dolog("Distribution of stack sizes at block boundary");
-       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
-       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
-                 count_block_stack[0], count_block_stack[1], count_block_stack[2],
-                 count_block_stack[3], count_block_stack[4], count_block_stack[5],
-                 count_block_stack[6], count_block_stack[7], count_block_stack[8],
-                 count_block_stack[9], count_block_stack[10]);
-       dolog("Distribution of store stack depth");
-       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
-       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
-                 count_store_depth[0], count_store_depth[1], count_store_depth[2],
-                 count_store_depth[3], count_store_depth[4], count_store_depth[5],
-                 count_store_depth[6], count_store_depth[7], count_store_depth[8],
-                 count_store_depth[9], count_store_depth[10]);
-       dolog("Distribution of store creator chains first part");
-       dolog("     0     1     2     3     4     5     6     7     8     9");
-       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
-                 count_store_length[0], count_store_length[1], count_store_length[2],
-                 count_store_length[3], count_store_length[4], count_store_length[5],
-                 count_store_length[6], count_store_length[7], count_store_length[8],
-                 count_store_length[9]);
-       dolog("Distribution of store creator chains second part");
-       dolog("    10    11    12    13    14    15    16    17    18    19  >=20");
-       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
-                 count_store_length[10], count_store_length[11],
-                 count_store_length[12], count_store_length[13],
-                 count_store_length[14], count_store_length[15],
-                 count_store_length[16], count_store_length[17],
-                 count_store_length[18], count_store_length[19],
-                 count_store_length[20]);
-       dolog("Distribution of analysis iterations");
-       dolog("     1     2     3     4   >=5");
-       dolog("%6d%6d%6d%6d%6d",
-                 count_analyse_iterations[0], count_analyse_iterations[1],
-                 count_analyse_iterations[2], count_analyse_iterations[3],
-                 count_analyse_iterations[4]);
-
-
-       /* Distribution of basic blocks per method ********************************/
-
-       log_println("Distribution of basic blocks per method:");
-       log_println("   <=5  <=10  <=15  <=20  <=30  <=40  <=50  <=75   >75");
-
-       log_start();
-       for (i = 0; i <= 8; i++)
-               log_print("%6d", count_method_bb_distribution[i]);
-       log_finish();
-
-       /* print ratio */
-
-       f = (float) count_methods;
-
-       log_start();
-       for (i = 0; i <= 8; i++)
-               log_print("%6.2f", (float) count_method_bb_distribution[i] / f);
-       log_finish();
-
-       /* print cumulated ratio */
-
-       log_start();
-       for (i = 0, sum = 0; i <= 8; i++) {
-               sum += count_method_bb_distribution[i];
-               log_print("%6.2f", (float) sum / f);
-       }
-       log_finish();
-
-
-       /* Distribution of basic block sizes **************************************/
-
-       log_println("Distribution of basic block sizes:");
-       log_println("     0     1     2     3     4     5     6     7     8     9   <13   <15   <17   <19   <21   <26   <31   >30");
-
-       /* print block sizes */
-
-       log_start();
-       for (i = 0; i <= 17; i++)
-               log_print("%6d", count_block_size_distribution[i]);
-       log_finish();
-
-       /* print ratio */
-
-       f = (float) count_basic_blocks;
-
-       log_start();
-       for (i = 0; i <= 17; i++)
-               log_print("%6.2f", (float) count_block_size_distribution[i] / f);
-       log_finish();
-
-       /* print cumulated ratio */
-
-       log_start();
-       for (i = 0, sum = 0; i <= 17; i++) {
-               sum += count_block_size_distribution[i];
-               log_print("%6.2f", (float) sum / f);
-       }
-       log_finish();
-
-       statistics_print_memory_usage();
-
-       dolog("Number of class loads:    %6d", count_class_loads);
-       dolog("Number of class inits:    %6d", count_class_inits);
-       dolog("Number of loaded Methods: %6d\n", count_all_methods);
-
-       dolog("Calls of utf_new:                 %6d", count_utf_new);
-       dolog("Calls of utf_new (element found): %6d\n", count_utf_new_found);
-
-
-       /* LSRA statistics ********************************************************/
-
-       dolog("Moves reg -> reg:     %6d", count_mov_reg_reg);
-       dolog("Moves mem -> reg:     %6d", count_mov_mem_reg);
-       dolog("Moves reg -> mem:     %6d", count_mov_reg_mem);
-       dolog("Moves mem -> mem:     %6d", count_mov_mem_mem);
-
-       dolog("Methods allocated by LSRA:         %6d",
-                 count_methods_allocated_by_lsra);
-       dolog("Conflicts between local Variables: %6d", count_locals_conflicts);
-       dolog("Local Variables held in Memory:    %6d", count_locals_spilled);
-       dolog("Local Variables held in Registers: %6d", count_locals_register);
-       dolog("Stackslots held in Memory:         %6d", count_ss_spilled);
-       dolog("Stackslots held in Registers:      %6d", count_ss_register);
-       dolog("Memory moves at BB Boundaries:     %6d", count_mem_move_bb);
-       dolog("Number of interface slots:         %6d\n", count_interface_size);
-       dolog("Number of Argument stack slots in register:  %6d",
-                 count_argument_reg_ss);
-       dolog("Number of Argument stack slots in memory:    %6d\n",
-                 count_argument_mem_ss);
-       dolog("Number of Methods kept in registers:         %6d\n",
-                 count_method_in_register);
-
-
-       /* instruction scheduler statistics ***************************************/
-
-#if defined(USE_SCHEDULER)
-       dolog("Instruction scheduler statistics:");
-       dolog("Number of basic blocks:       %7d", count_schedule_basic_blocks);
-       dolog("Number of nodes:              %7d", count_schedule_nodes);
-       dolog("Number of leaders nodes:      %7d", count_schedule_leaders);
-       dolog("Number of max. leaders nodes: %7d", count_schedule_max_leaders);
-       dolog("Length of critical path:      %7d\n", count_schedule_critical_path);
-#endif
-
-
-       /* call statistics ********************************************************/
-
-       dolog("Function call statistics:");
-       dolog("Number of jni->CallXMethod function invokations: %ld",
-                 count_jni_callXmethod_calls);
-       dolog("Overall number of jni invokations:               %ld",
-                 count_jni_calls);
-
-       log_println("java-to-native calls:   %10ld", count_calls_java_to_native);
-       log_println("native-to-java calls:   %10ld", count_calls_native_to_java);
-
-
-       /* now print other statistics ********************************************/
-
-#if defined(ENABLE_INTRP)
-       print_dynamic_super_statistics();
-#endif
-}
-
-
-/* statistics_print_date *******************************************************
-
-   Print current date and time.
-
-*******************************************************************************/
-
-void statistics_print_date(void)
-{
-  time_t t;
-  struct tm tm;
-
-#if defined(HAVE_TIME)
-  time(&t);
-#else
-# error !HAVE_TIME
-#endif
-
-#if defined(HAVE_LOCALTIME_R)
-  localtime_r(&t, &tm);
-#else
-# error !HAVE_LOCALTIME_R
-#endif
-
-  log_println("%d-%02d-%02d %02d:%02d:%02d",
-                         1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
-                         tm.tm_hour, tm.tm_min, tm.tm_sec);
-}
-
-
-/* statistics_print_memory_usage ***********************************************
-
-   Print current memory usage.
-
-*******************************************************************************/
-
-void statistics_print_memory_usage(void)
-{
-       s4 sum;
-
-       log_println("memory usage ----------------------");
-       log_println("");
-       log_println("code:                      %10d", count_code_len);
-       log_println("data:                      %10d", count_data_len);
-       log_println("                            ----------");
-
-       sum =
-               count_code_len +
-               count_data_len;
-
-       log_println("                           %10d", sum);
-
-       log_println("");
-
-       log_println("classinfo  (%3d B):        %10d", (int) sizeof(classinfo), size_classinfo);
-       log_println("fieldinfo  (%3d B):        %10d", (int) sizeof(fieldinfo), size_fieldinfo);
-       log_println("methodinfo (%3d B):        %10d", (int) sizeof(methodinfo), size_methodinfo);
-       log_println("lineinfo   (%3d B):        %10d", (int) sizeof(lineinfo), size_lineinfo);
-       log_println("codeinfo   (%3d B):        %10d", (int) sizeof(codeinfo), size_codeinfo);
-       log_println("                            ----------");
-
-       sum =
-               size_classinfo +
-               size_fieldinfo +
-               size_methodinfo +
-               size_lineinfo +
-               size_codeinfo;
-
-       log_println("                           %10d", sum);
-
-       log_println("");
-
-       log_println("linenumber tables (%5d): %10d", count_linenumbertable, size_linenumbertable);
-       log_println("exception tables:          %10d", count_extable_len);
-       log_println("patcher references:        %10d", size_patchref);
-       log_println("cached references:         %10d", size_cachedref);
-       log_println("                            ----------");
-
-       sum =
-               size_linenumbertable +
-               count_extable_len +
-               size_patchref +
-               size_cachedref;
-
-       log_println("                           %10d", sum);
-
-       log_println("");
-
-       log_println("constant pool:             %10d", count_const_pool_len);
-       log_println("classref:                  %10d", count_classref_len);
-       log_println("parsed descriptors:        %10d", count_parsed_desc_len);
-       log_println("vftbl:                     %10d", count_vftbl_len);
-       log_println("compiler stubs:            %10d", count_cstub_len);
-       log_println("native stubs:              %10d", size_stub_native);
-       log_println("utf:                       %10d", count_utf_len);
-       log_println("vmcode:                    %10d", count_vmcode_len);
-       log_println("stack map:                 %10d", size_stack_map);
-       log_println("string:                    %10d", size_string);
-       log_println("threadobject:              %10d", size_threadobject);
-       log_println("thread index:              %10d", size_thread_index_t);
-       log_println("stack size:                %10d", size_stacksize);
-       log_println("lock record:               %10d", size_lock_record);
-       log_println("lock hashtable:            %10d", size_lock_hashtable);
-       log_println("lock waiter:               %10d", size_lock_waiter);
-       log_println("                            ----------");
-
-       sum =
-               count_const_pool_len +
-               count_classref_len +
-               count_parsed_desc_len + 
-               count_vftbl_len +
-               count_cstub_len +
-               size_stub_native +
-               count_utf_len +
-               count_vmcode_len +
-               size_stack_map +
-               size_string +
-               size_threadobject +
-               size_thread_index_t +
-               size_stacksize +
-               size_lock_record +
-               size_lock_hashtable +
-               size_lock_waiter;
-
-       log_println("                           %10d", sum);
-
-       log_println("");
-
-       log_println("max. code memory:          %10d", maxcodememusage);
-       log_println("max. heap memory:          %10d", maxmemusage);
-       log_println("max. dump memory:          %10d", maxdumpsize);
-       log_println("");
-       log_println("heap memory not freed:     %10d", (int32_t) memoryusage);
-       log_println("dump memory not freed:     %10d", (int32_t) globalallocateddumpsize);
-
-       log_println("");
-}
-
-
-/* statistics_print_gc_memory_usage ********************************************
-
-   Print current GC memory usage.
-
-*******************************************************************************/
-
-void statistics_print_gc_memory_usage(void)
-{
-       static int64_t count = 0;
-       int64_t max;
-       int64_t size;
-       int64_t free;
-       int64_t used;
-       int64_t total;
-
-       count++;
-
-       max   = gc_get_max_heap_size();
-       size  = gc_get_heap_size();
-       free  = gc_get_free_bytes();
-       used  = size - free;
-       total = gc_get_total_bytes();
-
-       if (opt_ProfileMemoryUsageGNUPlot) {
-               if (count == 1)
-                       fprintf(opt_ProfileMemoryUsageGNUPlot, "plot \"profile.dat\" using 1:2 with lines title \"max. Java heap size\", \"profile.dat\" using 1:3 with lines title \"Java heap size\", \"profile.dat\" using 1:4 with lines title \"used\", \"profile.dat\" using 1:5 with lines title \"free\"\n");
-
-#if SIZEOF_VOID_P == 8
-               fprintf(opt_ProfileMemoryUsageGNUPlot, "%ld %ld %ld %ld %ld\n", count, max, size, used, free);
-#else
-               fprintf(opt_ProfileMemoryUsageGNUPlot, "%lld %lld %lld %lld %lld\n", count, max, size, used, free);
-#endif
-
-               fflush(opt_ProfileMemoryUsageGNUPlot);
-       }
-       else {
-               log_println("GC memory usage -------------------");
-               log_println("");
-               log_println("max. Java heap size: %10lld", max);
-               log_println("");
-               log_println("Java heap size:      %10lld", size);
-               log_println("used:                %10lld", used);
-               log_println("free:                %10lld", free);
-               log_println("totally used:        %10lld", total);
-               log_println("");
-       }
-}
-
-
-/*
- * 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/vmcore/statistics.h b/src/vmcore/statistics.h
deleted file mode 100644 (file)
index 3bae33b..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-/* src/vmcore/statistics.h - exports global varables for statistics
-
-   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
-
-   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 _STATISTICS_H
-#define _STATISTICS_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-
-/* statistic macros ***********************************************************/
-
-#if defined(ENABLE_STATISTICS)
-#define STATISTICS(x) \
-    do { \
-        if (opt_stat) { \
-            x; \
-        } \
-    } while (0)
-#else
-#define STATISTICS(x)    /* nothing */
-#endif
-
-/* in_  inline statistics */
-
-#define IN_MAX                  9
-#define IN_UNIQUEVIRT           0x0000 
-#define IN_UNIQUE_INTERFACE     0x0001
-#define IN_OUTSIDERS            0x0004
-#define IN_MAXDEPTH             0x0008
-#define IN_MAXCODE              0x0010
-#define IN_JCODELENGTH          0x0020
-#define IN_EXCEPTION            0x0040
-#define IN_NOT_UNIQUE_VIRT      0x0080
-#define IN_NOT_UNIQUE_INTERFACE 0x0100
-
-#define N_UNIQUEVIRT            0
-#define N_UNIQUE_INTERFACE      1
-#define N_OUTSIDERS             2
-#define N_MAXDEPTH             3       
-#define N_MAXCODE               4 
-#define N_JCODELENGTH           5 
-#define N_EXCEPTION            6 
-#define N_NOT_UNIQUE_VIRT       7 
-#define N_NOT_UNIQUE_INTERFACE  8 
-
-
-/* global variables ***********************************************************/
-
-extern s4 codememusage;
-extern s4 maxcodememusage;
-
-extern s4 memoryusage;
-extern s4 maxmemusage;
-
-extern s4 maxdumpsize;
-
-extern s4 globalallocateddumpsize;
-extern s4 globaluseddumpsize;
-
-
-/* variables for measurements *************************************************/
-
-extern s4 size_classinfo;
-extern s4 size_fieldinfo;
-extern s4 size_methodinfo;
-extern s4 size_lineinfo;
-extern s4 size_codeinfo;
-
-extern s4 size_stub_native;
-
-extern s4 size_stack_map;
-extern s4 size_string;
-
-extern s4 size_threadobject;
-extern int32_t size_thread_index_t;
-extern int32_t size_stacksize;
-
-extern s4 size_lock_record;
-extern s4 size_lock_hashtable;
-extern s4 size_lock_waiter;
-
-extern int32_t count_linenumbertable;
-extern int32_t size_linenumbertable;
-
-extern s4 size_patchref;
-
-extern s4 size_cachedref;
-
-extern u8 count_calls_java_to_native;
-extern u8 count_calls_native_to_java;
-
-extern int count_const_pool_len;
-extern int count_classref_len;
-extern int count_parsed_desc_len;
-extern int count_vftbl_len;
-extern int count_all_methods;
-extern int count_methods_marked_used;  /*RTA*/
-extern int count_vmcode_len;
-extern int count_extable_len;
-extern int count_class_loads;
-extern int count_class_inits;
-
-extern int count_utf_len;               /* size of utf hash                   */
-extern int count_utf_new;
-extern int count_utf_new_found;
-
-extern int count_locals_conflicts;
-extern int count_locals_spilled;
-extern int count_locals_register;
-extern int count_ss_spilled;
-extern int count_ss_register;
-extern int count_methods_allocated_by_lsra;
-extern int count_mem_move_bb;
-extern int count_interface_size;
-extern int count_argument_mem_ss;
-extern int count_argument_reg_ss;
-extern int count_method_in_register;
-extern int count_mov_reg_reg;
-extern int count_mov_mem_reg;
-extern int count_mov_reg_mem;
-extern int count_mov_mem_mem;
-
-extern int count_jit_calls;
-extern int count_methods;
-extern int count_spills_read_ila;
-extern int count_spills_read_flt;
-extern int count_spills_read_dbl;
-extern int count_spills_write_ila;
-extern int count_spills_write_flt;
-extern int count_spills_write_dbl;
-extern int count_pcmd_activ;
-extern int count_pcmd_drop;
-extern int count_pcmd_zero;
-extern int count_pcmd_const_store;
-extern int count_pcmd_const_alu;
-extern int count_pcmd_const_bra;
-extern int count_pcmd_load;
-extern int count_pcmd_move;
-extern int count_load_instruction;
-extern int count_pcmd_store;
-extern int count_pcmd_store_comb;
-extern int count_dup_instruction;
-extern int count_pcmd_op;
-extern int count_pcmd_mem;
-extern int count_pcmd_met;
-extern int count_pcmd_bra;
-extern int count_pcmd_table;
-extern int count_pcmd_return;
-extern int count_pcmd_returnx;
-extern int count_check_null;
-extern int count_check_bound;
-extern int count_max_basic_blocks;
-extern int count_basic_blocks;
-extern int count_max_javainstr;
-extern int count_javainstr;
-extern int count_javacodesize;
-extern int count_javaexcsize;
-extern int count_calls;
-extern int count_tryblocks;
-extern int count_code_len;
-extern int count_data_len;
-extern int count_cstub_len;
-extern int count_max_new_stack;
-extern int count_upper_bound_new_stack;
-
-extern int count_emit_branch;
-extern int count_emit_branch_8bit;
-extern int count_emit_branch_16bit;
-extern int count_emit_branch_32bit;
-extern int count_emit_branch_64bit;
-
-extern s4 count_branches_resolved;
-extern s4 count_branches_unresolved;
-
-extern int *count_block_stack;
-extern int *count_analyse_iterations;
-extern int *count_method_bb_distribution;
-extern int *count_block_size_distribution;
-extern int *count_store_length;
-extern int *count_store_depth;
-                                /* in_  inline statistics */
-extern int count_in;
-extern int count_in_uniqVirt;
-extern int count_in_uniqIntf;
-extern int count_in_rejected;
-extern int count_in_rejected_mult;
-extern int count_in_outsiders;
-extern int count_in_uniqueVirt_not_inlined;
-extern int count_in_uniqueInterface_not_inlined;
-extern int count_in_maxDepth;
-extern int count_in_maxMethods;
-
-extern u2 count_in_not   [512];
-
-/* instruction scheduler statistics *******************************************/
-
-extern s4 count_schedule_basic_blocks;
-extern s4 count_schedule_nodes;
-extern s4 count_schedule_leaders;
-extern s4 count_schedule_max_leaders;
-extern s4 count_schedule_critical_path;
-
-
-/* function prototypes ********************************************************/
-
-s8 getcputime(void);
-
-void loadingtime_start(void);
-void loadingtime_stop(void);
-void compilingtime_start(void);
-void compilingtime_stop(void);
-
-void print_times(void);
-void print_stats(void);
-
-void statistics_print_date(void);
-void statistics_print_memory_usage(void);
-void statistics_print_gc_memory_usage(void);
-
-void mem_usagelog(bool givewarnings);
-
-void compiledinvokation(void);
-void jnicallXmethodnvokation(void);
-void jniinvokation(void);
-
-#endif /* _STATISTICS_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/vmcore/suck.c b/src/vmcore/suck.c
deleted file mode 100644 (file)
index 933ceab..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-/* src/vmcore/suck.c - functions to read LE ordered types from a buffer
-
-   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 <stdlib.h>
-
-#include "vm/types.h"
-
-#include "arch.h"
-
-#include "mm/memory.h"
-
-#include "threads/lock-common.h"
-
-#include "toolbox/list.h"
-#include "toolbox/logging.h"
-#include "toolbox/util.h"
-
-#include "vm/exceptions.h"
-#include "vm/properties.h"
-#include "vm/vm.h"
-
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/suck.h"
-#include "vmcore/system.h"
-#include "vmcore/zip.h"
-
-
-/* global variables ***********************************************************/
-
-list_t *list_classpath_entries;
-
-
-/* suck_init *******************************************************************
-
-   Initializes the suck subsystem like initializing the classpath
-   entries list.
-
-*******************************************************************************/
-
-bool suck_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("suck_init");
-
-       list_classpath_entries = list_create(OFFSET(list_classpath_entry, linkage));
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* scandir_filter **************************************************************
-
-   Filters for zip/jar files.
-
-*******************************************************************************/
-
-#if defined(__LINUX__)
-static int scandir_filter(const struct dirent *a)
-#else
-static int scandir_filter(struct dirent *a)
-#endif
-{
-       s4 namlen;
-
-#if defined(_DIRENT_HAVE_D_NAMLEN)
-       namlen = a->d_namlen;
-#else
-       namlen = strlen(a->d_name);
-#endif
-
-       if ((strncasecmp(a->d_name + namlen - 4, ".zip", 4) == 0) ||
-               (strncasecmp(a->d_name + namlen - 4, ".jar", 4) == 0))
-               return 1;
-
-       return 0;
-}
-
-
-/* suck_add ********************************************************************
-
-   Adds a classpath to the global classpath entries list.
-
-*******************************************************************************/
-
-void suck_add(char *classpath)
-{
-       list_classpath_entry *lce;
-       char                 *start;
-       char                 *end;
-       char                 *filename;
-       s4                    filenamelen;
-       bool                  is_zip;
-       char                 *cwd;
-       s4                    cwdlen;
-#if defined(ENABLE_ZLIB)
-       hashtable            *ht;
-#endif
-
-       /* parse the classpath string */
-
-       for (start = classpath; (*start) != '\0'; ) {
-
-               /* search for ':' delimiter to get the end of the current entry */
-               for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
-
-               if (start != end) {
-                       is_zip = false;
-                       filenamelen = end - start;
-
-                       if (filenamelen > 4) {
-                               if ((strncasecmp(end - 4, ".zip", 4) == 0) ||
-                                       (strncasecmp(end - 4, ".jar", 4) == 0)) {
-                                       is_zip = true;
-                               }
-                       }
-
-                       /* save classpath entries as absolute pathnames */
-
-                       cwd = NULL;
-                       cwdlen = 0;
-
-                       if (*start != '/') {                      /* XXX fix me for win32 */
-                               cwd = _Jv_getcwd();
-                               cwdlen = strlen(cwd) + strlen("/");
-                       }
-
-                       /* allocate memory for filename and fill it */
-
-                       filename = MNEW(char, filenamelen + cwdlen + strlen("/") +
-                                                       strlen("0"));
-
-                       if (cwd) {
-                               strcpy(filename, cwd);
-                               strcat(filename, "/");
-                               strncat(filename, start, filenamelen);
-
-                               /* add cwd length to file length */
-                               filenamelen += cwdlen;
-
-                       } else {
-                               strncpy(filename, start, filenamelen);
-                               filename[filenamelen] = '\0';
-                       }
-
-                       lce = NULL;
-
-                       if (is_zip) {
-#if defined(ENABLE_ZLIB)
-                               ht = zip_open(filename);
-
-                               if (ht != NULL) {
-                                       lce = NEW(list_classpath_entry);
-
-                                       lce->type      = CLASSPATH_ARCHIVE;
-                                       lce->htclasses = ht;
-                                       lce->path      = filename;
-                                       lce->pathlen   = filenamelen;
-
-                                       /* SUN compatible -verbose:class output */
-
-                                       if (opt_verboseclass)
-                                               printf("[Opened %s]\n", filename);
-                               }
-
-#else
-                               vm_abort("suck_add: zip/jar files not supported");
-#endif
-                       }
-                       else {
-                               if (filename[filenamelen - 1] != '/') {/* XXX fixme for win32 */
-                                       filename[filenamelen] = '/';
-                                       filename[filenamelen + 1] = '\0';
-                                       filenamelen++;
-                               }
-
-                               lce = NEW(list_classpath_entry);
-
-                               lce->type    = CLASSPATH_PATH;
-                               lce->path    = filename;
-                               lce->pathlen = filenamelen;
-                       }
-
-                       /* add current classpath entry, if no error */
-
-                       if (lce != NULL)
-                               list_add_last(list_classpath_entries, lce);
-               }
-
-               /* goto next classpath entry, skip ':' delimiter */
-
-               if ((*end) == ':')
-                       start = end + 1;
-               else
-                       start = end;
-       }
-}
-
-
-/* suck_add_from_property ******************************************************
-
-   Adds a classpath form a property entry to the global classpath
-   entries list.
-
-*******************************************************************************/
-
-void suck_add_from_property(char *key)
-{
-       char           *value;
-       char           *start;
-       char           *end;
-       char           *path;
-       s4              pathlen;
-       struct dirent **namelist;
-       s4              n;
-       s4              i;
-       s4              namlen;
-       char           *boot_class_path;
-       char           *p;
-
-       /* get the property value */
-
-       value = properties_get(key);
-
-       if (value == NULL)
-               return;
-
-       /* get the directory entries of the property */
-
-       for (start = value; (*start) != '\0'; ) {
-
-               /* search for ':' delimiter to get the end of the current entry */
-
-               for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
-
-               /* found an entry */
-
-               if (start != end) {
-                       /* allocate memory for the path entry */
-
-                       pathlen = end - start;
-                       path = MNEW(char, pathlen + strlen("0"));
-
-                       /* copy and terminate the string */
-
-                       strncpy(path, start, pathlen);
-                       path[pathlen] = '\0';
-
-                       /* Reset namelist to NULL for the freeing in an error case
-                          (see below). */
-
-                       namelist = NULL;
-
-                       /* scan the directory found for zip/jar files */
-
-                       n = system_scandir(path, &namelist, scandir_filter, alphasort);
-
-                       /* On error, just continue, this should be ok. */
-
-                       if (n > 0) {
-                               for (i = 0; i < n; i++) {
-#if defined(_DIRENT_HAVE_D_NAMLEN)
-                                       namlen = namelist[i]->d_namlen;
-#else
-                                       namlen = strlen(namelist[i]->d_name);
-#endif
-
-                                       /* Allocate memory for bootclasspath. */
-
-                                       boot_class_path = properties_get("sun.boot.class.path");
-
-                                       p = MNEW(char,
-                                                        pathlen + strlen("/") + namlen +
-                                                        strlen(":") +
-                                                        strlen(boot_class_path) +
-                                                        strlen("0"));
-
-                                       /* Prepend the file found to the bootclasspath. */
-
-                                       strcpy(p, path);
-                                       strcat(p, "/");
-                                       strcat(p, namelist[i]->d_name);
-                                       strcat(p, ":");
-                                       strcat(p, boot_class_path);
-
-                                       properties_add("sun.boot.class.path", p);
-                                       properties_add("java.boot.class.path", p);
-
-                                       MFREE(boot_class_path, char, strlen(boot_class_path));
-
-                                       /* free the memory allocated by scandir */
-                                       /* (We use `free` as the memory came from the C library.) */
-
-                                       free(namelist[i]);
-                               }
-                       }
-
-                       /* On some systems (like Linux) when n == 0, then namelist
-                          returned from scnadir is NULL, thus we don't have to
-                          free it.
-                          (Use `free` as the memory came from the C library.) */
-
-                       if (namelist != NULL)
-                               free(namelist);
-
-                       MFREE(path, char, pathlen + strlen("0"));
-               }
-
-               /* goto next entry, skip ':' delimiter */
-
-               if ((*end) == ':')
-                       start = end + 1;
-               else
-                       start = end;
-       }
-}
-
-
-/* suck_check_classbuffer_size *************************************************
-
-   Assert that at least <len> bytes are left to read <len> is limited
-   to the range of non-negative s4 values.
-
-*******************************************************************************/
-
-bool suck_check_classbuffer_size(classbuffer *cb, s4 len)
-{
-#ifdef ENABLE_VERIFIER
-       if (len < 0 || ((cb->data + cb->size) - cb->pos) < len) {
-               exceptions_throw_classformaterror(cb->clazz, "Truncated class file");
-               return false;
-       }
-#endif /* ENABLE_VERIFIER */
-
-       return true;
-}
-
-
-u1 suck_u1(classbuffer *cb)
-{
-       u1 a;
-
-       a = SUCK_BE_U1(cb->pos);
-       cb->pos++;
-
-       return a;
-}
-
-
-u2 suck_u2(classbuffer *cb)
-{
-       u2 a;
-
-       a = SUCK_BE_U2(cb->pos);
-       cb->pos += 2;
-
-       return a;
-}
-
-
-u4 suck_u4(classbuffer *cb)
-{
-       u4 a;
-
-       a = SUCK_BE_U4(cb->pos);
-       cb->pos += 4;
-
-       return a;
-}
-
-
-u8 suck_u8(classbuffer *cb)
-{
-#if U8_AVAILABLE == 1
-       u8 a;
-
-       a = SUCK_BE_U8(cb->pos);
-       cb->pos += 8;
-
-       return a;
-#else
-       u8 v;
-
-       v.high = suck_u4(cb);
-       v.low = suck_u4(cb);
-
-       return v;
-#endif
-}
-
-
-float suck_float(classbuffer *cb)
-{
-       float f;
-
-#if WORDS_BIGENDIAN == 0
-       u1 buffer[4];
-       u2 i;
-
-       for (i = 0; i < 4; i++)
-               buffer[3 - i] = suck_u1(cb);
-
-       MCOPY((u1 *) (&f), buffer, u1, 4);
-#else
-       suck_nbytes((u1*) (&f), cb, 4);
-#endif
-
-       assert(sizeof(float) == 4);
-       
-       return f;
-}
-
-
-double suck_double(classbuffer *cb)
-{
-       double d;
-
-#if WORDS_BIGENDIAN == 0
-       u1 buffer[8];
-       u2 i;   
-
-# if defined(__ARM__) && defined(__ARMEL__) && !defined(__VFP_FP__)
-       /*
-        * On little endian ARM processors when using FPA, word order
-        * of doubles is still big endian. So take that into account
-        * here. When using VFP, word order of doubles follows byte
-        * order. (michi 2005/07/24)
-        */
-       for (i = 0; i < 4; i++)
-               buffer[3 - i] = suck_u1(cb);
-       for (i = 0; i < 4; i++)
-               buffer[7 - i] = suck_u1(cb);
-# else
-       for (i = 0; i < 8; i++)
-               buffer[7 - i] = suck_u1(cb);
-# endif /* defined(__ARM__) && ... */
-
-       MCOPY((u1 *) (&d), buffer, u1, 8);
-#else 
-       suck_nbytes((u1*) (&d), cb, 8);
-#endif
-
-       assert(sizeof(double) == 8);
-       
-       return d;
-}
-
-
-/* suck_nbytes *****************************************************************
-
-   Transfer block of classfile data into a buffer.
-
-*******************************************************************************/
-
-void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
-{
-       MCOPY(buffer, cb->pos, u1, len);
-       cb->pos += len;
-}
-
-
-/* suck_skip_nbytes ************************************************************
-
-   Skip block of classfile data.
-
-*******************************************************************************/
-
-void suck_skip_nbytes(classbuffer *cb, s4 len)
-{
-       cb->pos += len;
-}
-
-
-/* suck_start ******************************************************************
-
-   Returns true if classbuffer is already loaded or a file for the
-   specified class has succussfully been read in. All directories of
-   the searchpath are used to find the classfile (<classname>.class).
-   Returns NULL if no classfile is found and writes an error message.
-       
-*******************************************************************************/
-
-classbuffer *suck_start(classinfo *c)
-{
-       list_classpath_entry *lce;
-       char                 *filename;
-       s4                    filenamelen;
-       char                 *path;
-       FILE                 *classfile;
-       s4                    len;
-       struct stat           buffer;
-       classbuffer          *cb;
-
-       /* initialize return value */
-
-       cb = NULL;
-
-       /* get the classname as char string (do it here for the warning at
-       the end of the function) */
-
-       filenamelen = utf_bytes(c->name) + strlen(".class") + strlen("0");
-       filename = MNEW(char, filenamelen);
-
-       utf_copy(filename, c->name);
-       strcat(filename, ".class");
-
-       /* walk through all classpath entries */
-
-       for (lce = list_first(list_classpath_entries); lce != NULL && cb == NULL;
-                lce = list_next(list_classpath_entries, lce)) {
-#if defined(ENABLE_ZLIB)
-               if (lce->type == CLASSPATH_ARCHIVE) {
-
-                       /* enter a monitor on zip/jar archives */
-
-                       LOCK_MONITOR_ENTER(lce);
-
-                       /* try to get the file in current archive */
-
-                       cb = zip_get(lce, c);
-
-                       /* leave the monitor */
-
-                       LOCK_MONITOR_EXIT(lce);
-
-               } else {
-#endif /* defined(ENABLE_ZLIB) */
-                       path = MNEW(char, lce->pathlen + filenamelen);
-                       strcpy(path, lce->path);
-                       strcat(path, filename);
-
-                       classfile = system_fopen(path, "r");
-
-                       if (classfile) {                                   /* file exists */
-                               if (!system_stat(path, &buffer)) {     /* read classfile data */
-                                       cb = NEW(classbuffer);
-                                       cb->clazz = c;
-                                       cb->size  = buffer.st_size;
-                                       cb->data  = MNEW(u1, cb->size);
-                                       cb->pos   = cb->data;
-                                       cb->path  = lce->path;
-
-                                       /* read class data */
-
-                                       len = system_fread((void *) cb->data, 1, cb->size,
-                                                                          classfile);
-
-                                       if (len != buffer.st_size) {
-                                               suck_stop(cb);
-/*                                             if (ferror(classfile)) { */
-/*                                             } */
-                                       }
-
-                                       /* close the class file */
-
-                                       system_fclose(classfile);
-                               }
-                       }
-
-                       MFREE(path, char, lce->pathlen + filenamelen);
-#if defined(ENABLE_ZLIB)
-               }
-#endif
-       }
-
-       if (opt_verbose)
-               if (cb == NULL)
-                       dolog("Warning: Can not open class file '%s'", filename);
-
-       MFREE(filename, char, filenamelen);
-
-       return cb;
-}
-
-
-/* suck_stop *******************************************************************
-
-   Frees memory for buffer with classfile data.
-
-   CAUTION: This function may only be called if buffer has been
-   allocated by suck_start with reading a file.
-       
-*******************************************************************************/
-
-void suck_stop(classbuffer *cb)
-{
-       /* free memory */
-
-       MFREE(cb->data, u1, cb->size);
-       FREE(cb, classbuffer);
-}
-
-
-/*
- * 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/vmcore/suck.h b/src/vmcore/suck.h
deleted file mode 100644 (file)
index cc29e06..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/* src/vmcore/suck.h - functions to read LE ordered types from a buffer
-
-   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
-
-   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 _SUCK_H
-#define _SUCK_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "toolbox/hashtable.h"
-#include "toolbox/list.h"
-
-#include "vm/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-
-
-/* list_classpath_entry *******************************************************/
-
-enum {
-       CLASSPATH_PATH,
-       CLASSPATH_ARCHIVE
-};
-
-typedef struct list_classpath_entry list_classpath_entry;
-
-struct list_classpath_entry {
-#if defined(ENABLE_THREADS)
-       java_object_t      header;              /* monitor locking on zip/jar files   */
-#endif
-       s4                 type;
-       char              *path;
-       s4                 pathlen;
-#if defined(ENABLE_ZLIB)
-       hashtable         *htclasses;
-#endif
-       listnode_t         linkage;
-};
-
-
-/* macros to read LE and BE types from a buffer ********************************
-
-   BE macros are for Java class file loading.
-   LE macros are for ZIP file loading.
-
-*******************************************************************************/
-
-/* LE macros (for ZIP files ) *************************************************/
-
-#if defined(__I386__) || defined(__X86_64__)
-
-/* we can optimize the LE access on little endian machines without alignment */
-
-#define SUCK_LE_U1(p)    *((u1 *) (p))
-#define SUCK_LE_U2(p)    *((u2 *) (p))
-#define SUCK_LE_U4(p)    *((u4 *) (p))
-
-#if U8_AVAILABLE == 1
-#define SUCK_LE_U8(p)    *((u8 *) (p))
-#endif
-
-#else /* defined(__I386__) || defined(__X86_64__) */
-
-#define SUCK_LE_U1(p) \
-      ((u1) (p)[0])
-
-#define SUCK_LE_U2(p) \
-    ((((u2) (p)[1]) << 8) + \
-      ((u2) (p)[0]))
-
-#define SUCK_LE_U4(p) \
-    ((((u4) (p)[3]) << 24) + \
-     (((u4) (p)[2]) << 16) + \
-     (((u4) (p)[1]) << 8) + \
-      ((u4) (p)[0]))
-
-#if U8_AVAILABLE == 1
-#define SUCK_LE_U8(p) \
-    ((((u8) (p)[7]) << 56) + \
-     (((u8) (p)[6]) << 48) + \
-     (((u8) (p)[5]) << 40) + \
-     (((u8) (p)[4]) << 32) + \
-     (((u8) (p)[3]) << 24) + \
-     (((u8) (p)[2]) << 16) + \
-     (((u8) (p)[1]) << 8) + \
-      ((u8) (p)[0]))
-#endif
-
-#endif /* defined(__I386__) || defined(__X86_64__) */
-
-
-/* BE macros (for Java class files ) ******************************************/
-
-#define SUCK_BE_U1(p) \
-      ((u1) (p)[0])
-
-#define SUCK_BE_U2(p) \
-    ((((u2) (p)[0]) << 8) + \
-      ((u2) (p)[1]))
-
-#define SUCK_BE_U4(p) \
-    ((((u4) (p)[0]) << 24) + \
-     (((u4) (p)[1]) << 16) + \
-     (((u4) (p)[2]) << 8) + \
-      ((u4) (p)[3]))
-
-#if U8_AVAILABLE == 1
-#define SUCK_BE_U8(p) \
-    ((((u8) (p)[0]) << 56) + \
-     (((u8) (p)[1]) << 48) + \
-     (((u8) (p)[2]) << 40) + \
-     (((u8) (p)[3]) << 32) + \
-     (((u8) (p)[4]) << 24) + \
-     (((u8) (p)[5]) << 16) + \
-     (((u8) (p)[6]) << 8) + \
-      ((u8) (p)[7]))
-#endif
-
-
-#define SUCK_BE_S1(p)    (s1) SUCK_BE_U1(p)
-#define SUCK_BE_S2(p)    (s2) SUCK_BE_U2(p)
-#define SUCK_BE_S4(p)    (s4) SUCK_BE_U4(p)
-#define SUCK_BE_S8(p)    (s8) SUCK_BE_U8(p)
-
-
-/* signed suck defines ********************************************************/
-
-#define suck_s1(a)    (s1) suck_u1((a))
-#define suck_s2(a)    (s2) suck_u2((a))
-#define suck_s4(a)    (s4) suck_u4((a))
-#define suck_s8(a)    (s8) suck_u8((a))
-
-
-/* export variables ***********************************************************/
-
-extern list_t *list_classpath_entries;
-
-
-/* function prototypes ********************************************************/
-
-bool suck_init(void);
-
-void suck_add(char *classpath);
-void suck_add_from_property(char *key);
-
-bool suck_check_classbuffer_size(classbuffer *cb, s4 len);
-
-u1 suck_u1(classbuffer *cb);
-u2 suck_u2(classbuffer *cb);
-u4 suck_u4(classbuffer *cb);
-u8 suck_u8(classbuffer *cb);
-
-float suck_float(classbuffer *cb);
-double suck_double(classbuffer *cb);
-
-void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len);
-void suck_skip_nbytes(classbuffer *cb, s4 len);
-
-classbuffer *suck_start(classinfo *c);
-
-void suck_stop(classbuffer *cb);
-
-#endif /* _SUCK_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/vmcore/system.c b/src/vmcore/system.c
deleted file mode 100644 (file)
index be474a9..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* src/vmcore/system.c - system (OS) functions
-
-   Copyright (C) 2007
-   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"
-
-/* NOTE: In this file we check for all system headers, because we wrap
-   all system calls into functions for better portability. */
-
-#if defined(HAVE_ERRNO_H)
-# include <errno.h>
-#endif
-
-#if defined(HAVE_STDINT_H)
-# include <stdint.h>
-#endif
-
-#if defined(HAVE_STRING_H)
-# include <string.h>
-#endif
-
-#if defined(HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
-
-#if defined(HAVE_SYS_MMAN_H)
-# include <sys/mman.h>
-#endif
-
-#if defined(__DARWIN__)
-# include <mach/mach.h>
-# include <mach/mach_host.h>
-# include <mach/host_info.h>
-#endif
-
-/* this should work on BSD */
-/* #include <sys/sysctl.h> */
-
-#include "vm/vm.h"
-
-
-/* system_mmap_anonymous *******************************************************
-
-   Maps anonymous memory, even on systems not defining
-   MAP_ANON(YMOUS).
-
-*******************************************************************************/
-
-void *system_mmap_anonymous(void *addr, size_t len, int prot, int flags)
-{
-       void *p;
-
-#if defined(MAP_ANON) || defined(MAP_ANONYMOUS)
-       p = mmap(addr, len, prot,
-# if defined(MAP_ANON)
-                        MAP_ANON | flags,
-# else
-                        MAP_ANONYMOUS | flags,
-# endif
-                        -1, 0);
-#else
-       int fd;
-
-       fd = open("/dev/zero", O_RDONLY, 0);
-
-       if (fd == -1)
-               vm_abort("system_mmap_anonymous: open failed: %s", strerror(errno));
-
-       p = mmap(addr, len, prot, flags, fd, 0);
-#endif
-
-#if defined(MAP_FAILED)
-       if (p == MAP_FAILED)
-#else
-       if (p == (void *) -1)
-#endif
-               vm_abort("system_mmap_anonymous: mmap failed: %s", strerror(errno));
-
-       return p;
-}
-
-
-/* system_processors_online ****************************************************
-
-   Returns the number of online processors in the system.
-
-   RETURN:
-       online processor count
-
-*******************************************************************************/
-
-int system_processors_online(void)
-{
-#if defined(_SC_NPROC_ONLN)
-
-       return (int) sysconf(_SC_NPROC_ONLN);
-
-#elif defined(_SC_NPROCESSORS_ONLN)
-
-       return (int) sysconf(_SC_NPROCESSORS_ONLN);
-
-#elif defined(__DARWIN__)
-
-       host_basic_info_data_t hinfo;
-       mach_msg_type_number_t hinfo_count = HOST_BASIC_INFO_COUNT;
-       kern_return_t rc;
-
-       rc = host_info(mach_host_self(), HOST_BASIC_INFO,
-                                  (host_info_t) &hinfo, &hinfo_count);
-       if (rc != KERN_SUCCESS) {
-               return -1;
-       }
-
-       /* XXX michi: according to my infos this should be
-          hinfo.max_cpus, can someone please confirm or deny that? */
-       return (int) hinfo.avail_cpus;
-
-#elif defined(__FREEBSD__)
-# error IMPLEMENT ME!
-
-       /* this should work in BSD */
-       /*
-       int ncpu, mib[2], rc;
-       size_t len;
-
-       mib[0] = CTL_HW;
-       mib[1] = HW_NCPU;
-       len = sizeof(ncpu);
-       rc = sysctl(mib, 2, &ncpu, &len, NULL, 0);
-
-       return (int32_t) ncpu;
-       */
-
-#else
-
-       return 1;
-
-#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/vmcore/system.h b/src/vmcore/system.h
deleted file mode 100644 (file)
index 8a052ae..0000000
+++ /dev/null
@@ -1,507 +0,0 @@
-/* src/vmcore/system.h - system (OS) functions
-
-   Copyright (C) 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 _VMCORE_SYSTEM_H
-#define _VMCORE_SYSTEM_H
-
-#include "config.h"
-
-/* NOTE: In this file we check for all system headers, because we wrap
-   all system calls into inline functions for better portability. */
-
-#if defined(HAVE_DIRENT_H)
-# include <dirent.h>
-#endif
-
-#if defined(HAVE_DLFCN_H)
-# include <dlfcn.h>
-#endif
-
-#if defined(HAVE_FCNTL_H)
-# include <fcntl.h>
-#endif
-
-#if defined(ENABLE_JRE_LAYOUT)
-# if defined(HAVE_LIBGEN_H)
-#  include <libgen.h>
-# endif
-#endif
-
-#if defined(HAVE_STDINT_H)
-# include <stdint.h>
-#endif
-
-#if defined(HAVE_STDIO_H)
-# include <stdio.h>
-#endif
-
-#if defined(HAVE_STDLIB_H)
-# include <stdlib.h>
-#endif
-
-#if defined(HAVE_STRING_H)
-# include <string.h>
-#endif
-
-#if defined(HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
-
-#if defined(HAVE_SYS_MMAN_H)
-# include <sys/mman.h>
-#endif
-
-#if defined(HAVE_SYS_SOCKET_H)
-# include <sys/socket.h>
-#endif
-
-#if defined(HAVE_SYS_STAT_H)
-# include <sys/stat.h>
-#endif
-
-#if defined(HAVE_SYS_TYPES_H)
-# include <sys/types.h>
-#endif
-
-
-/* inline functions ***********************************************************/
-
-inline static void system_abort(void)
-{
-#if defined(HAVE_ABORT)
-       abort();
-#else
-# error abort not available
-#endif
-}
-
-inline static int system_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
-{
-#if defined(HAVE_ACCEPT)
-       return accept(sockfd, addr, addrlen);
-#else
-# error accept not available
-#endif
-}
-
-inline static int system_access(const char *pathname, int mode)
-{
-#if defined(HAVE_ACCESS)
-       return access(pathname, mode);
-#else
-# error access not available
-#endif
-}
-
-inline static int system_atoi(const char *nptr)
-{
-#if defined(HAVE_ATOI)
-       return atoi(nptr);
-#else
-# error atoi not available
-#endif
-}
-
-inline static void *system_calloc(size_t nmemb, size_t size)
-{
-#if defined(HAVE_CALLOC)
-       return calloc(nmemb, size);
-#else
-# error calloc not available
-#endif
-}
-
-inline static int system_close(int fd)
-{
-#if defined(HAVE_CLOSE)
-       return close(fd);
-#else
-# error close not available
-#endif
-}
-
-inline static int system_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
-{
-#if defined(HAVE_CONNECT)
-       return connect(sockfd, serv_addr, addrlen);
-#else
-# error connect not available
-#endif
-}
-
-#if defined(ENABLE_JRE_LAYOUT)
-inline static char *system_dirname(char *path)
-{
-#if defined(HAVE_DIRNAME)
-       return dirname(path);
-#else
-# error dirname not available
-#endif
-}
-#endif
-
-inline static int system_dlclose(void* handle)
-{
-#if defined(HAVE_DLCLOSE)
-       return dlclose(handle);
-#else
-# error dlclose not available
-#endif
-}
-
-inline static char* system_dlerror(void)
-{
-#if defined(HAVE_DLERROR)
-       return dlerror();
-#else
-# error dlerror not available
-#endif
-}
-
-inline static void* system_dlopen(const char* filename, int flag)
-{
-#if defined(HAVE_DLOPEN)
-       return dlopen(filename, flag);
-#else
-# error dlopen not available
-#endif
-}
-
-inline static void* system_dlsym(void* handle, const char* symbol)
-{
-#if defined(HAVE_DLSYM)
-       return dlsym(handle, symbol);
-#else
-# error dlsym not available
-#endif
-}
-
-inline static FILE *system_fopen(const char *path, const char *mode)
-{
-#if defined(HAVE_FOPEN)
-       return fopen(path, mode);
-#else
-# error fopen not available
-#endif
-}
-
-inline static int system_fclose(FILE *fp)
-{
-#if defined(HAVE_FCLOSE)
-       return fclose(fp);
-#else
-# error fclose not available
-#endif
-}
-
-inline static size_t system_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
-#if defined(HAVE_FREAD)
-       return fread(ptr, size, nmemb, stream);
-#else
-# error fread not available
-#endif
-}
-
-inline static int system_fseek(FILE *stream, off_t offset, int whence)
-{
-#if defined(HAVE_FSEEK)
-       return fseek(stream, offset, whence);
-#else
-# error fseek not available
-#endif
-}
-
-inline static void system_free(void *ptr)
-{
-#if defined(HAVE_FREE)
-       free(ptr);
-#else
-# error free not available
-#endif
-}
-
-inline static int system_fsync(int fd)
-{
-#if defined(HAVE_FSYNC)
-       return fsync(fd);
-#else
-# error fsync not available
-#endif
-}
-
-inline static int system_ftruncate(int fd, off_t length)
-{
-#if defined(HAVE_FTRUNCATE)
-       return ftruncate(fd, length);
-#else
-# error ftruncate not available
-#endif
-}
-
-inline static int system_gethostname(char *name, size_t len)
-{
-#if defined(HAVE_GETHOSTNAME)
-       return gethostname(name, len);
-#else
-# error gethostname not available
-#endif
-}
-
-inline static int system_getpagesize(void)
-{
-#if defined(HAVE_GETPAGESIZE)
-       return getpagesize();
-#else
-# error getpagesize not available
-#endif
-}
-
-inline static int system_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
-{
-#if defined(HAVE_GETSOCKNAME)
-       return getsockname(s, name, namelen);
-#else
-# error getsockname not available
-#endif
-}
-
-inline static int system_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
-{
-#if defined(HAVE_GETSOCKOPT)
-       return getsockopt(s, level, optname, optval, optlen);
-#else
-# error getsockopt not available
-#endif
-}
-
-inline static int system_listen(int sockfd, int backlog)
-{
-#if defined(HAVE_LISTEN)
-       return listen(sockfd, backlog);
-#else
-# error listen not available
-#endif
-}
-
-inline static off_t system_lseek(int fildes, off_t offset, int whence)
-{
-#if defined(HAVE_LSEEK)
-       return lseek(fildes, offset, whence);
-#else
-# error lseek not available
-#endif
-}
-
-inline static void *system_malloc(size_t size)
-{
-#if defined(HAVE_MALLOC)
-       return malloc(size);
-#else
-# error malloc not available
-#endif
-}
-
-inline static void *system_memcpy(void *dest, const void *src, size_t n)
-{
-#if defined(HAVE_MEMCPY)
-       return memcpy(dest, src, n);
-#else
-# error memcpy not available
-#endif
-}
-
-inline static void *system_memset(void *s, int c, size_t n)
-{
-#if defined(HAVE_MEMSET)
-       return memset(s, c, n);
-#else
-# error memset not available
-#endif
-}
-
-inline static int system_mprotect(void *addr, size_t len, int prot)
-{
-#if defined(HAVE_MPROTECT)
-       return mprotect(addr, len, prot);
-#else
-# error mprotect not available
-#endif
-}
-
-inline static int system_open(const char *pathname, int flags, mode_t mode)
-{
-#if defined(HAVE_OPEN)
-       return open(pathname, flags, mode);
-#else
-# error open not available
-#endif
-}
-
-inline static ssize_t system_read(int fd, void *buf, size_t count)
-{
-#if defined(HAVE_READ)
-       return read(fd, buf, count);
-#else
-# error read not available
-#endif
-}
-
-inline static void *system_realloc(void *ptr, size_t size)
-{
-#if defined(HAVE_REALLOC)
-       return realloc(ptr, size);
-#else
-# error realloc not available
-#endif
-}
-
-#if defined(__LINUX__)
-inline static int system_scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
-#elif defined(__IRIX__)
-inline static int system_scandir(const char *dir, struct dirent ***namelist, int(*filter)(dirent_t *), int(*compar)(dirent_t **, dirent_t **))
-#else
-inline static int system_scandir(const char *dir, struct dirent ***namelist, int(*filter)(struct dirent *), int(*compar)(const void *, const void *))
-#endif
-{
-#if defined(HAVE_SCANDIR)
-       return scandir(dir, namelist, filter, compar);
-#else
-# error scandir not available
-#endif
-}
-
-inline static int system_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
-{
-#if defined(HAVE_SETSOCKOPT)
-       return setsockopt(s, level, optname, optval, optlen);
-#else
-# error setsockopt not available
-#endif
-}
-
-inline static int system_shutdown(int s, int how)
-{
-#if defined(HAVE_SHUTDOWN)
-       return shutdown(s, how);
-#else
-# error shutdown not available
-#endif
-}
-
-inline static int system_socket(int domain, int type, int protocol)
-{
-#if defined(HAVE_SOCKET)
-       return socket(domain, type, protocol);
-#else
-# error socket not available
-#endif
-}
-
-inline static int system_stat(const char *path, struct stat *buf)
-{
-#if defined(HAVE_STAT)
-       return stat(path, buf);
-#else
-# error stat not available
-#endif
-}
-
-inline static char *system_strcat(char *dest, const char *src)
-{
-#if defined(HAVE_STRCAT)
-       return strcat(dest, src);
-#else
-# error strcat not available
-#endif
-}
-
-inline static char *system_strcpy(char *dest, const char *src)
-{
-#if defined(HAVE_STRCPY)
-       return strcpy(dest, src);
-#else
-# error strcpy not available
-#endif
-}
-
-inline static char *system_strdup(const char *s)
-{
-#if defined(HAVE_STRDUP)
-       return strdup(s);
-#else
-# error strdup not available
-#endif
-}
-
-inline static char *system_strerror(int errnum)
-{
-#if defined(HAVE_STRERROR)
-       return strerror(errnum);
-#else
-# error strerror not available
-#endif
-}
-
-inline static size_t system_strlen(const char *s)
-{
-#if defined(HAVE_STRLEN)
-       return strlen(s);
-#else
-# error strlen not available
-#endif
-}
-
-inline static ssize_t system_write(int fd, const void *buf, size_t count)
-{
-#if defined(HAVE_WRITE)
-       return write(fd, buf, count);
-#else
-# error write not available
-#endif
-}
-
-
-/* function prototypes ********************************************************/
-
-void *system_mmap_anonymous(void *addr, size_t len, int prot, int flags);
-int   system_processors_online(void);
-
-#endif /* _VMCORE_SYSTEM_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/vmcore/utf8.c b/src/vmcore/utf8.c
deleted file mode 100644 (file)
index b292d95..0000000
+++ /dev/null
@@ -1,1933 +0,0 @@
-/* src/vmcore/utf8.c - utf8 string 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 <string.h>
-#include <assert.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "threads/lock-common.h"
-
-#include "toolbox/hashtable.h"
-
-#include "vm/exceptions.h"
-
-#include "vmcore/options.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#include "vmcore/utf8.h"
-
-
-/* global variables ***********************************************************/
-
-/* hashsize must be power of 2 */
-
-#define HASHTABLE_UTF_SIZE    16384     /* initial size of utf-hash           */
-
-hashtable *hashtable_utf;               /* hashtable for utf8-symbols         */
-
-
-/* utf-symbols for pointer comparison of frequently used strings **************/
-
-utf *utf_java_lang_Object;
-
-utf *utf_java_lang_Class;
-utf *utf_java_lang_ClassLoader;
-utf *utf_java_lang_Cloneable;
-utf *utf_java_lang_SecurityManager;
-utf *utf_java_lang_String;
-utf *utf_java_lang_ThreadGroup;
-utf *utf_java_lang_ref_SoftReference;
-utf *utf_java_lang_ref_WeakReference;
-utf *utf_java_lang_ref_PhantomReference;
-utf *utf_java_io_Serializable;
-
-utf *utf_java_lang_Throwable;
-utf *utf_java_lang_Error;
-
-utf *utf_java_lang_AbstractMethodError;
-utf *utf_java_lang_ClassCircularityError;
-utf *utf_java_lang_ClassFormatError;
-utf *utf_java_lang_ExceptionInInitializerError;
-utf *utf_java_lang_IncompatibleClassChangeError;
-utf *utf_java_lang_InstantiationError;
-utf *utf_java_lang_InternalError;
-utf *utf_java_lang_LinkageError;
-utf *utf_java_lang_NoClassDefFoundError;
-utf *utf_java_lang_NoSuchFieldError;
-utf *utf_java_lang_NoSuchMethodError;
-utf *utf_java_lang_OutOfMemoryError;
-utf *utf_java_lang_UnsatisfiedLinkError;
-utf *utf_java_lang_UnsupportedClassVersionError;
-utf *utf_java_lang_VerifyError;
-utf *utf_java_lang_VirtualMachineError;
-
-utf *utf_java_lang_Exception;
-
-utf *utf_java_lang_ArithmeticException;
-utf *utf_java_lang_ArrayIndexOutOfBoundsException;
-utf *utf_java_lang_ArrayStoreException;
-utf *utf_java_lang_ClassCastException;
-utf *utf_java_lang_ClassNotFoundException;
-utf *utf_java_lang_CloneNotSupportedException;
-utf *utf_java_lang_IllegalAccessException;
-utf *utf_java_lang_IllegalArgumentException;
-utf *utf_java_lang_IllegalMonitorStateException;
-utf *utf_java_lang_InstantiationException;
-utf *utf_java_lang_InterruptedException;
-utf *utf_java_lang_NegativeArraySizeException;
-utf *utf_java_lang_NullPointerException;
-utf *utf_java_lang_RuntimeException;
-utf *utf_java_lang_StringIndexOutOfBoundsException;
-
-utf *utf_java_lang_reflect_InvocationTargetException;
-
-utf *utf_java_security_PrivilegedActionException;
-
-#if defined(ENABLE_JAVASE)
-utf* utf_java_lang_Void;
-#endif
-
-utf* utf_java_lang_Boolean;
-utf* utf_java_lang_Byte;
-utf* utf_java_lang_Character;
-utf* utf_java_lang_Short;
-utf* utf_java_lang_Integer;
-utf* utf_java_lang_Long;
-utf* utf_java_lang_Float;
-utf* utf_java_lang_Double;
-
-#if defined(ENABLE_JAVASE)
-utf *utf_java_lang_StackTraceElement;
-utf *utf_java_lang_reflect_Constructor;
-utf *utf_java_lang_reflect_Field;
-utf *utf_java_lang_reflect_Method;
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-utf *utf_java_lang_reflect_VMConstructor;
-utf *utf_java_lang_reflect_VMField;
-utf *utf_java_lang_reflect_VMMethod;
-# endif
-
-utf *utf_java_util_Vector;
-#endif
-
-utf *utf_InnerClasses;                  /* InnerClasses                       */
-utf *utf_ConstantValue;                 /* ConstantValue                      */
-utf *utf_Code;                          /* Code                               */
-utf *utf_Exceptions;                    /* Exceptions                         */
-utf *utf_LineNumberTable;               /* LineNumberTable                    */
-utf *utf_SourceFile;                    /* SourceFile                         */
-
-#if defined(ENABLE_JAVASE)
-utf *utf_EnclosingMethod;
-utf *utf_Signature;
-utf *utf_StackMapTable;
-
-#if defined(ENABLE_ANNOTATIONS)
-utf *utf_RuntimeVisibleAnnotations;            /* RuntimeVisibleAnnotations            */
-utf *utf_RuntimeInvisibleAnnotations;          /* RuntimeInvisibleAnnotations          */
-utf *utf_RuntimeVisibleParameterAnnotations;   /* RuntimeVisibleParameterAnnotations   */
-utf *utf_RuntimeInvisibleParameterAnnotations; /* RuntimeInvisibleParameterAnnotations */
-utf *utf_AnnotationDefault;                    /* AnnotationDefault                    */
-#endif
-#endif
-
-utf *utf_init;                          /* <init>                             */
-utf *utf_clinit;                        /* <clinit>                           */
-utf *utf_clone;                         /* clone                              */
-utf *utf_finalize;                      /* finalize                           */
-utf *utf_invoke;
-utf *utf_main;
-utf *utf_run;                           /* run                                */
-
-utf *utf_add;
-utf *utf_remove;
-utf *utf_addThread;
-utf *utf_removeThread;
-utf *utf_put;
-utf *utf_get;
-utf *utf_uncaughtException;
-utf *utf_value;
-
-utf *utf_fillInStackTrace;
-utf *utf_findNative;
-utf *utf_getSystemClassLoader;
-utf *utf_initCause;
-utf *utf_loadClass;
-utf *utf_loadClassInternal;
-utf *utf_printStackTrace;
-
-utf *utf_division_by_zero;
-
-utf *utf_Z;                             /* Z                                  */
-utf *utf_B;                             /* B                                  */
-utf *utf_C;                             /* C                                  */
-utf *utf_S;                             /* S                                  */
-utf *utf_I;                             /* I                                  */
-utf *utf_J;                             /* J                                  */
-utf *utf_F;                             /* F                                  */
-utf *utf_D;                             /* D                                  */
-
-utf *utf_void__void;                    /* ()V                                */
-utf *utf_boolean__void;                 /* (Z)V                               */
-utf *utf_byte__void;                    /* (B)V                               */
-utf *utf_char__void;                    /* (C)V                               */
-utf *utf_short__void;                   /* (S)V                               */
-utf *utf_int__void;                     /* (I)V                               */
-utf *utf_long__void;                    /* (J)V                               */
-utf *utf_float__void;                   /* (F)V                               */
-utf *utf_double__void;                  /* (D)V                               */
-
-utf *utf_void__java_lang_ClassLoader;   /* ()Ljava/lang/ClassLoader;          */
-utf *utf_void__java_lang_Object;        /* ()Ljava/lang/Object;               */
-utf *utf_void__java_lang_Throwable;     /* ()Ljava/lang/Throwable;            */
-utf *utf_java_lang_ClassLoader_java_lang_String__J;
-utf *utf_java_lang_Exception__V;        /* (Ljava/lang/Exception;)V           */
-utf *utf_java_lang_Object__java_lang_Object;
-utf *utf_java_lang_String__void;        /* (Ljava/lang/String;)V              */
-utf *utf_java_lang_String__java_lang_Class;
-utf *utf_java_lang_Thread__V;           /* (Ljava/lang/Thread;)V              */
-utf *utf_java_lang_Thread_java_lang_Throwable__V;
-utf *utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V;
-utf *utf_java_lang_Throwable__void;     /* (Ljava/lang/Throwable;)V           */
-utf *utf_java_lang_Throwable__java_lang_Throwable;
-
-utf *utf_not_named_yet;                 /* special name for unnamed classes   */
-utf *utf_null;
-utf *array_packagename;
-
-
-/* utf_init ********************************************************************
-
-   Initializes the utf8 subsystem.
-
-*******************************************************************************/
-
-void utf8_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("utf8_init");
-
-       /* create utf8 hashtable */
-
-       hashtable_utf = NEW(hashtable);
-
-       hashtable_create(hashtable_utf, HASHTABLE_UTF_SIZE);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_utf_len += sizeof(utf*) * hashtable_utf->size;
-#endif
-
-       /* create utf-symbols for pointer comparison of frequently used strings */
-
-       utf_java_lang_Object           = utf_new_char("java/lang/Object");
-
-       utf_java_lang_Class            = utf_new_char("java/lang/Class");
-       utf_java_lang_ClassLoader      = utf_new_char("java/lang/ClassLoader");
-       utf_java_lang_Cloneable        = utf_new_char("java/lang/Cloneable");
-       utf_java_lang_SecurityManager  = utf_new_char("java/lang/SecurityManager");
-       utf_java_lang_String           = utf_new_char("java/lang/String");
-       utf_java_lang_ThreadGroup      = utf_new_char("java/lang/ThreadGroup");
-
-       utf_java_lang_ref_SoftReference =
-               utf_new_char("java/lang/ref/SoftReference");
-
-       utf_java_lang_ref_WeakReference =
-               utf_new_char("java/lang/ref/WeakReference");
-
-       utf_java_lang_ref_PhantomReference =
-               utf_new_char("java/lang/ref/PhantomReference");
-
-       utf_java_io_Serializable       = utf_new_char("java/io/Serializable");
-
-       utf_java_lang_Throwable        = utf_new_char("java/lang/Throwable");
-       utf_java_lang_Error            = utf_new_char("java/lang/Error");
-
-       utf_java_lang_ClassCircularityError =
-               utf_new_char("java/lang/ClassCircularityError");
-
-       utf_java_lang_ClassFormatError = utf_new_char("java/lang/ClassFormatError");
-
-       utf_java_lang_ExceptionInInitializerError =
-               utf_new_char("java/lang/ExceptionInInitializerError");
-
-       utf_java_lang_IncompatibleClassChangeError =
-               utf_new_char("java/lang/IncompatibleClassChangeError");
-
-       utf_java_lang_InstantiationError =
-               utf_new_char("java/lang/InstantiationError");
-
-       utf_java_lang_InternalError    = utf_new_char("java/lang/InternalError");
-       utf_java_lang_LinkageError     = utf_new_char("java/lang/LinkageError");
-
-       utf_java_lang_NoClassDefFoundError =
-               utf_new_char("java/lang/NoClassDefFoundError");
-
-       utf_java_lang_OutOfMemoryError = utf_new_char("java/lang/OutOfMemoryError");
-
-       utf_java_lang_UnsatisfiedLinkError =
-               utf_new_char("java/lang/UnsatisfiedLinkError");
-
-       utf_java_lang_UnsupportedClassVersionError =
-               utf_new_char("java/lang/UnsupportedClassVersionError");
-
-       utf_java_lang_VerifyError      = utf_new_char("java/lang/VerifyError");
-
-       utf_java_lang_VirtualMachineError =
-               utf_new_char("java/lang/VirtualMachineError");
-
-#if defined(ENABLE_JAVASE)
-       utf_java_lang_AbstractMethodError =
-               utf_new_char("java/lang/AbstractMethodError");
-
-       utf_java_lang_NoSuchFieldError =
-               utf_new_char("java/lang/NoSuchFieldError");
-
-       utf_java_lang_NoSuchMethodError =
-               utf_new_char("java/lang/NoSuchMethodError");
-#endif
-
-       utf_java_lang_Exception        = utf_new_char("java/lang/Exception");
-
-       utf_java_lang_ArithmeticException =
-               utf_new_char("java/lang/ArithmeticException");
-
-       utf_java_lang_ArrayIndexOutOfBoundsException =
-               utf_new_char("java/lang/ArrayIndexOutOfBoundsException");
-
-       utf_java_lang_ArrayStoreException =
-               utf_new_char("java/lang/ArrayStoreException");
-
-       utf_java_lang_ClassCastException =
-               utf_new_char("java/lang/ClassCastException");
-
-       utf_java_lang_ClassNotFoundException =
-               utf_new_char("java/lang/ClassNotFoundException");
-
-       utf_java_lang_CloneNotSupportedException =
-               utf_new_char("java/lang/CloneNotSupportedException");
-
-       utf_java_lang_IllegalAccessException =
-               utf_new_char("java/lang/IllegalAccessException");
-
-       utf_java_lang_IllegalArgumentException =
-               utf_new_char("java/lang/IllegalArgumentException");
-
-       utf_java_lang_IllegalMonitorStateException =
-               utf_new_char("java/lang/IllegalMonitorStateException");
-
-       utf_java_lang_InstantiationException =
-               utf_new_char("java/lang/InstantiationException");
-
-       utf_java_lang_InterruptedException =
-               utf_new_char("java/lang/InterruptedException");
-
-       utf_java_lang_NegativeArraySizeException =
-               utf_new_char("java/lang/NegativeArraySizeException");
-
-       utf_java_lang_NullPointerException =
-               utf_new_char("java/lang/NullPointerException");
-
-       utf_java_lang_RuntimeException =
-               utf_new_char("java/lang/RuntimeException");
-
-       utf_java_lang_StringIndexOutOfBoundsException =
-               utf_new_char("java/lang/StringIndexOutOfBoundsException");
-
-       utf_java_lang_reflect_InvocationTargetException =
-               utf_new_char("java/lang/reflect/InvocationTargetException");
-
-       utf_java_security_PrivilegedActionException =
-               utf_new_char("java/security/PrivilegedActionException");
-#if defined(ENABLE_JAVASE)
-       utf_java_lang_Void             = utf_new_char("java/lang/Void");
-#endif
-
-       utf_java_lang_Boolean          = utf_new_char("java/lang/Boolean");
-       utf_java_lang_Byte             = utf_new_char("java/lang/Byte");
-       utf_java_lang_Character        = utf_new_char("java/lang/Character");
-       utf_java_lang_Short            = utf_new_char("java/lang/Short");
-       utf_java_lang_Integer          = utf_new_char("java/lang/Integer");
-       utf_java_lang_Long             = utf_new_char("java/lang/Long");
-       utf_java_lang_Float            = utf_new_char("java/lang/Float");
-       utf_java_lang_Double           = utf_new_char("java/lang/Double");
-
-#if defined(ENABLE_JAVASE)
-       utf_java_lang_StackTraceElement =
-               utf_new_char("java/lang/StackTraceElement");
-
-       utf_java_lang_reflect_Constructor =
-               utf_new_char("java/lang/reflect/Constructor");
-
-       utf_java_lang_reflect_Field    = utf_new_char("java/lang/reflect/Field");
-       utf_java_lang_reflect_Method   = utf_new_char("java/lang/reflect/Method");
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       utf_java_lang_reflect_VMConstructor = utf_new_char("java/lang/reflect/VMConstructor");
-       utf_java_lang_reflect_VMField       = utf_new_char("java/lang/reflect/VMField");
-       utf_java_lang_reflect_VMMethod      = utf_new_char("java/lang/reflect/VMMethod");
-# endif
-
-       utf_java_util_Vector           = utf_new_char("java/util/Vector");
-#endif
-
-       utf_InnerClasses               = utf_new_char("InnerClasses");
-       utf_ConstantValue              = utf_new_char("ConstantValue");
-       utf_Code                       = utf_new_char("Code");
-       utf_Exceptions                 = utf_new_char("Exceptions");
-       utf_LineNumberTable            = utf_new_char("LineNumberTable");
-       utf_SourceFile                 = utf_new_char("SourceFile");
-
-#if defined(ENABLE_JAVASE)
-       utf_EnclosingMethod            = utf_new_char("EnclosingMethod");
-       utf_Signature                  = utf_new_char("Signature");
-       utf_StackMapTable              = utf_new_char("StackMapTable");
-
-# if defined(ENABLE_ANNOTATIONS)
-       utf_RuntimeVisibleAnnotations            = utf_new_char("RuntimeVisibleAnnotations");
-       utf_RuntimeInvisibleAnnotations          = utf_new_char("RuntimeInvisibleAnnotations");
-       utf_RuntimeVisibleParameterAnnotations   = utf_new_char("RuntimeVisibleParameterAnnotations");
-       utf_RuntimeInvisibleParameterAnnotations = utf_new_char("RuntimeInvisibleParameterAnnotations");
-       utf_AnnotationDefault                    = utf_new_char("AnnotationDefault");
-# endif
-#endif
-
-       utf_init                           = utf_new_char("<init>");
-       utf_clinit                         = utf_new_char("<clinit>");
-       utf_clone                      = utf_new_char("clone");
-       utf_finalize                   = utf_new_char("finalize");
-       utf_invoke                     = utf_new_char("invoke");
-       utf_main                       = utf_new_char("main");
-       utf_run                        = utf_new_char("run");
-
-       utf_add                        = utf_new_char("add");
-       utf_remove                     = utf_new_char("remove");
-       utf_addThread                  = utf_new_char("addThread");
-       utf_removeThread               = utf_new_char("removeThread");
-       utf_put                        = utf_new_char("put");
-       utf_get                        = utf_new_char("get");
-       utf_uncaughtException          = utf_new_char("uncaughtException");
-       utf_value                      = utf_new_char("value");
-
-       utf_fillInStackTrace           = utf_new_char("fillInStackTrace");
-       utf_findNative                 = utf_new_char("findNative");
-       utf_getSystemClassLoader       = utf_new_char("getSystemClassLoader");
-       utf_initCause                  = utf_new_char("initCause");
-       utf_loadClass                  = utf_new_char("loadClass");
-       utf_loadClassInternal          = utf_new_char("loadClassInternal");
-       utf_printStackTrace            = utf_new_char("printStackTrace");
-
-       utf_division_by_zero           = utf_new_char("/ by zero");
-
-       utf_Z                          = utf_new_char("Z");
-       utf_B                          = utf_new_char("B");
-       utf_C                          = utf_new_char("C");
-       utf_S                          = utf_new_char("S");
-       utf_I                          = utf_new_char("I");
-       utf_J                          = utf_new_char("J");
-       utf_F                          = utf_new_char("F");
-       utf_D                          = utf_new_char("D");
-
-       utf_void__void                 = utf_new_char("()V");
-       utf_boolean__void              = utf_new_char("(Z)V");
-       utf_byte__void                 = utf_new_char("(B)V");
-       utf_char__void                 = utf_new_char("(C)V");
-       utf_short__void                = utf_new_char("(S)V");
-       utf_int__void                  = utf_new_char("(I)V");
-       utf_long__void                 = utf_new_char("(J)V");
-       utf_float__void                = utf_new_char("(F)V");
-       utf_double__void               = utf_new_char("(D)V");
-       utf_void__java_lang_Object     = utf_new_char("()Ljava/lang/Object;");
-       utf_void__java_lang_Throwable  = utf_new_char("()Ljava/lang/Throwable;");
-
-       utf_void__java_lang_ClassLoader =
-               utf_new_char("()Ljava/lang/ClassLoader;");
-
-       utf_java_lang_ClassLoader_java_lang_String__J =
-               utf_new_char("(Ljava/lang/ClassLoader;Ljava/lang/String;)J");
-
-       utf_java_lang_Exception__V     = utf_new_char("(Ljava/lang/Exception;)V");
-
-       utf_java_lang_Object__java_lang_Object =
-               utf_new_char("(Ljava/lang/Object;)Ljava/lang/Object;");
-
-       utf_java_lang_String__void     = utf_new_char("(Ljava/lang/String;)V");
-
-       utf_java_lang_String__java_lang_Class =
-               utf_new_char("(Ljava/lang/String;)Ljava/lang/Class;");
-
-       utf_java_lang_Thread__V        = utf_new_char("(Ljava/lang/Thread;)V");
-
-       utf_java_lang_Thread_java_lang_Throwable__V =
-               utf_new_char("(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
-
-       utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V =
-               utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
-
-       utf_java_lang_Throwable__void  = utf_new_char("(Ljava/lang/Throwable;)V");
-
-       utf_java_lang_Throwable__java_lang_Throwable =
-               utf_new_char("(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
-
-       utf_null                       = utf_new_char("null");
-       utf_not_named_yet              = utf_new_char("\t<not_named_yet>");
-       array_packagename              = utf_new_char("\t<the array package>");
-}
-
-
-/* utf_hashkey *****************************************************************
-
-   The hashkey is computed from the utf-text by using up to 8
-   characters.  For utf-symbols longer than 15 characters 3 characters
-   are taken from the beginning and the end, 2 characters are taken
-   from the middle.
-
-*******************************************************************************/
-
-#define nbs(val) ((u4) *(++text) << val) /* get next byte, left shift by val  */
-#define fbs(val) ((u4) *(  text) << val) /* get first byte, left shift by val */
-
-u4 utf_hashkey(const char *text, u4 length)
-{
-       const char *start_pos = text;       /* pointer to utf text                */
-       u4 a;
-
-       switch (length) {
-       case 0: /* empty string */
-               return 0;
-
-       case 1: return fbs(0);
-       case 2: return fbs(0) ^ nbs(3);
-       case 3: return fbs(0) ^ nbs(3) ^ nbs(5);
-       case 4: return fbs(0) ^ nbs(2) ^ nbs(4) ^ nbs(6);
-       case 5: return fbs(0) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(6);
-       case 6: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(5) ^ nbs(6);
-       case 7: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(5) ^ nbs(6);
-       case 8: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(5) ^ nbs(6) ^ nbs(7);
-
-       case 9:
-               a = fbs(0);
-               a ^= nbs(1);
-               a ^= nbs(2);
-               text++;
-               return a ^ nbs(4) ^ nbs(5) ^ nbs(6) ^ nbs(7) ^ nbs(8);
-
-       case 10:
-               a = fbs(0);
-               text++;
-               a ^= nbs(2);
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text++;
-               return a ^ nbs(6) ^ nbs(7) ^ nbs(8) ^ nbs(9);
-
-       case 11:
-               a = fbs(0);
-               text++;
-               a ^= nbs(2);
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text++;
-               return a ^ nbs(6) ^ nbs(7) ^ nbs(8) ^ nbs(9) ^ nbs(10);
-
-       case 12:
-               a = fbs(0);
-               text += 2;
-               a ^= nbs(2);
-               a ^= nbs(3);
-               text++;
-               a ^= nbs(5);
-               a ^= nbs(6);
-               a ^= nbs(7);
-               text++;
-               return a ^ nbs(9) ^ nbs(10);
-
-       case 13:
-               a = fbs(0);
-               a ^= nbs(1);
-               text++;
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text += 2;      
-               a ^= nbs(7);
-               a ^= nbs(8);
-               text += 2;
-               return a ^ nbs(9) ^ nbs(10);
-
-       case 14:
-               a = fbs(0);
-               text += 2;      
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text += 2;      
-               a ^= nbs(7);
-               a ^= nbs(8);
-               text += 2;
-               return a ^ nbs(9) ^ nbs(10) ^ nbs(11);
-
-       case 15:
-               a = fbs(0);
-               text += 2;      
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text += 2;      
-               a ^= nbs(7);
-               a ^= nbs(8);
-               text += 2;
-               return a ^ nbs(9) ^ nbs(10) ^ nbs(11);
-
-       default:  /* 3 characters from beginning */
-               a = fbs(0);
-               text += 2;
-               a ^= nbs(3);
-               a ^= nbs(4);
-
-               /* 2 characters from middle */
-               text = start_pos + (length / 2);
-               a ^= fbs(5);
-               text += 2;
-               a ^= nbs(6);    
-
-               /* 3 characters from end */
-               text = start_pos + length - 4;
-
-               a ^= fbs(7);
-               text++;
-
-               return a ^ nbs(10) ^ nbs(11);
-    }
-}
-
-/* utf_full_hashkey ************************************************************
-
-   This function computes a hash value using all bytes in the string.
-
-   The algorithm is the "One-at-a-time" algorithm as published
-   by Bob Jenkins on http://burtleburtle.net/bob/hash/doobs.html.
-
-*******************************************************************************/
-
-u4 utf_full_hashkey(const char *text, u4 length)
-{
-       register const unsigned char *p = (const unsigned char *) text;
-       register u4 hash;
-       register u4 i;
-
-       hash = 0;
-       for (i=length; i--;)
-       {
-           hash += *p++;
-           hash += (hash << 10);
-           hash ^= (hash >> 6);
-       }
-       hash += (hash << 3);
-       hash ^= (hash >> 11);
-       hash += (hash << 15);
-
-       return hash;
-}
-
-/* unicode_hashkey *************************************************************
-
-   Compute the hashkey of a unicode string.
-
-*******************************************************************************/
-
-u4 unicode_hashkey(u2 *text, u2 len)
-{
-       return utf_hashkey((char *) text, len);
-}
-
-
-/* utf_new *********************************************************************
-
-   Creates a new utf-symbol, the text of the symbol is passed as a
-   u1-array. The function searches the utf-hashtable for a utf-symbol
-   with this text. On success the element returned, otherwise a new
-   hashtable element is created.
-
-   If the number of entries in the hashtable exceeds twice the size of
-   the hashtable slots a reorganization of the hashtable is done and
-   the utf symbols are copied to a new hashtable with doubled size.
-
-*******************************************************************************/
-
-utf *utf_new(const char *text, u2 length)
-{
-       u4 key;                             /* hashkey computed from utf-text     */
-       u4 slot;                            /* slot in hashtable                  */
-       utf *u;                             /* hashtable element                  */
-       u2 i;
-
-       LOCK_MONITOR_ENTER(hashtable_utf->header);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_utf_new++;
-#endif
-
-       key  = utf_hashkey(text, length);
-       slot = key & (hashtable_utf->size - 1);
-       u    = hashtable_utf->ptr[slot];
-
-       /* search external hash chain for utf-symbol */
-
-       while (u) {
-               if (u->blength == length) {
-                       /* compare text of hashtable elements */
-
-                       for (i = 0; i < length; i++)
-                               if (text[i] != u->text[i])
-                                       goto nomatch;
-                       
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_utf_new_found++;
-#endif
-
-                       /* symbol found in hashtable */
-
-                       LOCK_MONITOR_EXIT(hashtable_utf->header);
-
-                       return u;
-               }
-
-       nomatch:
-               u = u->hashlink; /* next element in external chain */
-       }
-
-       /* location in hashtable found, create new utf element */
-
-       u = NEW(utf);
-
-       u->blength  = length;               /* length in bytes of utfstring       */
-       u->hashlink = hashtable_utf->ptr[slot]; /* link in external hashchain     */
-       u->text     = mem_alloc(length + 1);/* allocate memory for utf-text       */
-
-       memcpy(u->text, text, length);      /* copy utf-text                      */
-       u->text[length] = '\0';
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_utf_len += sizeof(utf) + length + 1;
-#endif
-
-       hashtable_utf->ptr[slot] = u;       /* insert symbol into table           */
-       hashtable_utf->entries++;           /* update number of entries           */
-
-       if (hashtable_utf->entries > (hashtable_utf->size * 2)) {
-
-        /* reorganization of hashtable, average length of the external
-           chains is approx. 2 */
-
-               hashtable *newhash;                              /* the new hashtable */
-               u4         i;
-               utf       *u;
-               utf       *nextu;
-               u4         slot;
-
-               /* create new hashtable, double the size */
-
-               newhash = hashtable_resize(hashtable_utf, hashtable_utf->size * 2);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_utf_len += sizeof(utf*) * hashtable_utf->size;
-#endif
-
-               /* transfer elements to new hashtable */
-
-               for (i = 0; i < hashtable_utf->size; i++) {
-                       u = hashtable_utf->ptr[i];
-
-                       while (u) {
-                               nextu = u->hashlink;
-                               slot  = utf_hashkey(u->text, u->blength) & (newhash->size - 1);
-                                               
-                               u->hashlink = (utf *) newhash->ptr[slot];
-                               newhash->ptr[slot] = u;
-
-                               /* follow link in external hash chain */
-
-                               u = nextu;
-                       }
-               }
-       
-               /* dispose old table */
-
-               hashtable_free(hashtable_utf);
-
-               hashtable_utf = newhash;
-       }
-
-       LOCK_MONITOR_EXIT(hashtable_utf->header);
-
-       return u;
-}
-
-
-/* utf_new_u2 ******************************************************************
-
-   Make utf symbol from u2 array, if isclassname is true '.' is
-   replaced by '/'.
-
-*******************************************************************************/
-
-utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
-{
-       char *buffer;                   /* memory buffer for  unicode characters  */
-       char *pos;                      /* pointer to current position in buffer  */
-       u4 left;                        /* unicode characters left                */
-       u4 buflength;                   /* utf length in bytes of the u2 array    */
-       utf *result;                    /* resulting utf-string                   */
-       int i;          
-
-       /* determine utf length in bytes and allocate memory */
-
-       buflength = u2_utflength(unicode_pos, unicode_length); 
-       buffer    = MNEW(char, buflength);
-       left = buflength;
-       pos  = buffer;
-
-       for (i = 0; i++ < unicode_length; unicode_pos++) {
-               /* next unicode character */
-               u2 c = *unicode_pos;
-               
-               if ((c != 0) && (c < 0x80)) {
-                       /* 1 character */       
-                       left--;
-               if ((int) left < 0) break;
-                       /* convert classname */
-                       if (isclassname && c == '.')
-                               *pos++ = '/';
-                       else
-                               *pos++ = (char) c;
-
-               } else if (c < 0x800) {             
-                       /* 2 characters */                              
-               unsigned char high = c >> 6;
-               unsigned char low  = c & 0x3F;
-                       left = left - 2;
-               if ((int) left < 0) break;
-               *pos++ = high | 0xC0; 
-               *pos++ = low  | 0x80;     
-
-               } else {         
-               /* 3 characters */                              
-               char low  = c & 0x3f;
-               char mid  = (c >> 6) & 0x3F;
-               char high = c >> 12;
-                       left = left - 3;
-               if ((int) left < 0) break;
-               *pos++ = high | 0xE0; 
-               *pos++ = mid  | 0x80;  
-               *pos++ = low  | 0x80;   
-               }
-       }
-       
-       /* insert utf-string into symbol-table */
-       result = utf_new(buffer,buflength);
-
-       MFREE(buffer, char, buflength);
-
-       return result;
-}
-
-
-/* utf_new_char ****************************************************************
-
-   Creates a new utf symbol, the text for this symbol is passed as a
-   c-string ( = char* ).
-
-*******************************************************************************/
-
-utf *utf_new_char(const char *text)
-{
-       return utf_new(text, strlen(text));
-}
-
-
-/* utf_new_char_classname ******************************************************
-
-   Creates a new utf symbol, the text for this symbol is passed as a
-   c-string ( = char* ) "." characters are going to be replaced by
-   "/". Since the above function is used often, this is a separte
-   function, instead of an if.
-
-*******************************************************************************/
-
-utf *utf_new_char_classname(const char *text)
-{
-       if (strchr(text, '.')) {
-               char *txt = strdup(text);
-               char *end = txt + strlen(txt);
-               char *c;
-               utf *tmpRes;
-
-               for (c = txt; c < end; c++)
-                       if (*c == '.') *c = '/';
-
-               tmpRes = utf_new(txt, strlen(txt));
-               FREE(txt, 0);
-
-               return tmpRes;
-
-       } else
-               return utf_new(text, strlen(text));
-}
-
-
-/* utf_nextu2 ******************************************************************
-
-   Read the next unicode character from the utf string and increment
-   the utf-string pointer accordingly.
-
-   CAUTION: This function is unsafe for input that was not checked 
-            by is_valid_utf!
-
-*******************************************************************************/
-
-u2 utf_nextu2(char **utf_ptr)
-{
-    /* uncompressed unicode character */
-    u2 unicode_char = 0;
-    /* current position in utf text */ 
-    unsigned char *utf = (unsigned char *) (*utf_ptr);
-    /* bytes representing the unicode character */
-    unsigned char ch1, ch2, ch3;
-    /* number of bytes used to represent the unicode character */
-    int len = 0;
-       
-    switch ((ch1 = utf[0]) >> 4) {
-       default: /* 1 byte */
-               (*utf_ptr)++;
-               return (u2) ch1;
-       case 0xC: 
-       case 0xD: /* 2 bytes */
-               if (((ch2 = utf[1]) & 0xC0) == 0x80) {
-                       unsigned char high = ch1 & 0x1F;
-                       unsigned char low  = ch2 & 0x3F;
-                       unicode_char = (high << 6) + low;
-                       len = 2;
-               }
-               break;
-
-       case 0xE: /* 2 or 3 bytes */
-               if (((ch2 = utf[1]) & 0xC0) == 0x80) {
-                       if (((ch3 = utf[2]) & 0xC0) == 0x80) {
-                               unsigned char low  = ch3 & 0x3f;
-                               unsigned char mid  = ch2 & 0x3f;
-                               unsigned char high = ch1 & 0x0f;
-                               unicode_char = (((high << 6) + mid) << 6) + low;
-                               len = 3;
-                       } else
-                               len = 2;                                           
-               }
-               break;
-    }
-
-    /* update position in utf-text */
-    *utf_ptr = (char *) (utf + len);
-
-    return unicode_char;
-}
-
-
-/* utf_bytes *******************************************************************
-
-   Determine number of bytes (aka. octets) in the utf string.
-
-   IN:
-      u............utf string
-
-   OUT:
-      The number of octets of this utf string.
-         There is _no_ terminating zero included in this count.
-
-*******************************************************************************/
-
-u4 utf_bytes(utf *u)
-{
-       return u->blength;
-}
-
-
-/* utf_get_number_of_u2s_for_buffer ********************************************
-
-   Determine number of UTF-16 u2s in the given UTF-8 buffer
-
-   CAUTION: This function is unsafe for input that was not checked 
-            by is_valid_utf!
-
-   CAUTION: Use this function *only* when you want to convert an UTF-8 buffer
-   to an array of u2s (UTF-16) and want to know how many of them you will get.
-   All other uses of this function are probably wrong.
-
-   IN:
-      buffer........points to first char in buffer
-         blength.......number of _bytes_ in the buffer
-
-   OUT:
-      the number of u2s needed to hold this string in UTF-16 encoding.
-         There is _no_ terminating zero included in this count.
-
-   NOTE: Unlike utf_get_number_of_u2s, this function never throws an
-   exception.
-
-*******************************************************************************/
-
-u4 utf_get_number_of_u2s_for_buffer(const char *buffer, u4 blength)
-{
-       const char *endpos;                 /* points behind utf string           */
-       const char *utf_ptr;                /* current position in utf text       */
-       u4 len = 0;                         /* number of unicode characters       */
-
-       utf_ptr = buffer;
-       endpos = utf_ptr + blength;
-
-       while (utf_ptr < endpos) {
-               len++;
-               /* next unicode character */
-               utf_nextu2((char **)&utf_ptr);
-       }
-
-       assert(utf_ptr == endpos);
-
-       return len;
-}
-
-
-/* utf_get_number_of_u2s *******************************************************
-
-   Determine number of UTF-16 u2s in the utf string.
-
-   CAUTION: This function is unsafe for input that was not checked 
-            by is_valid_utf!
-
-   CAUTION: Use this function *only* when you want to convert a utf string
-   to an array of u2s and want to know how many of them you will get.
-   All other uses of this function are probably wrong.
-
-   IN:
-      u............utf string
-
-   OUT:
-      the number of u2s needed to hold this string in UTF-16 encoding.
-         There is _no_ terminating zero included in this count.
-         XXX 0 if a NullPointerException has been thrown (see below)
-
-*******************************************************************************/
-
-u4 utf_get_number_of_u2s(utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-       u4 len = 0;                         /* number of unicode characters       */
-
-       /* XXX this is probably not checked by most callers! Review this after */
-       /* the invalid uses of this function have been eliminated */
-       if (u == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) {
-               len++;
-               /* next unicode character */
-               utf_nextu2(&utf_ptr);
-       }
-
-       if (utf_ptr != endpos) {
-               /* string ended abruptly */
-               exceptions_throw_internalerror("Illegal utf8 string");
-               return 0;
-       }
-
-       return len;
-}
-
-
-/* utf8_safe_number_of_u2s *****************************************************
-
-   Determine number of UTF-16 u2s needed for decoding the given UTF-8 string.
-   (For invalid UTF-8 the U+fffd replacement character will be counted.)
-
-   This function is safe even for invalid UTF-8 strings.
-
-   IN:
-      text..........zero-terminated(!) UTF-8 string (may be invalid)
-                       must NOT be NULL
-         nbytes........strlen(text). (This is needed to completely emulate
-                       the RI).
-
-   OUT:
-      the number of u2s needed to hold this string in UTF-16 encoding.
-         There is _no_ terminating zero included in this count.
-
-*******************************************************************************/
-
-s4 utf8_safe_number_of_u2s(const char *text, s4 nbytes) {
-       register const unsigned char *t;
-       register s4 byte;
-       register s4 len;
-       register const unsigned char *tlimit;
-       s4 byte1;
-       s4 byte2;
-       s4 byte3;
-       s4 value;
-       s4 skip;
-
-       assert(text);
-       assert(nbytes >= 0);
-
-       len = 0;
-       t = (const unsigned char *) text;
-       tlimit = t + nbytes;
-
-       /* CAUTION: Keep this code in sync with utf8_safe_convert_to_u2s! */
-
-       while (1) {
-               byte = *t++;
-
-               if (byte & 0x80) {
-                       /* highest bit set, non-ASCII character */
-
-                       if ((byte & 0xe0) == 0xc0) {
-                               /* 2-byte: should be 110..... 10...... ? */
-
-                               if ((*t++ & 0xc0) == 0x80)
-                                       ; /* valid 2-byte */
-                               else
-                                       t--; /* invalid */
-                       }
-                       else if ((byte & 0xf0) == 0xe0) {
-                               /* 3-byte: should be 1110.... 10...... 10...... */
-                               /*                            ^t                */
-
-                               if (t + 2 > tlimit)
-                                       return len + 1; /* invalid, stop here */
-
-                               if ((*t++ & 0xc0) == 0x80) {
-                                       if ((*t++ & 0xc0) == 0x80)
-                                               ; /* valid 3-byte */
-                                       else
-                                               t--; /* invalid */
-                               }
-                               else
-                                       t--; /* invalid */
-                       }
-                       else if ((byte & 0xf8) == 0xf0) {
-                               /* 4-byte: should be 11110... 10...... 10...... 10...... */
-                               /*                            ^t                         */
-
-                               if (t + 3 > tlimit)
-                                       return len + 1; /* invalid, stop here */
-
-                               if (((byte1 = *t++) & 0xc0) == 0x80) {
-                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
-                                               if (((byte3 = *t++) & 0xc0) == 0x80) {
-                                                       /* valid 4-byte UTF-8? */
-                                                       value = ((byte  & 0x07) << 18)
-                                                                 | ((byte1 & 0x3f) << 12)
-                                                                 | ((byte2 & 0x3f) <<  6)
-                                                                 | ((byte3 & 0x3f)      );
-
-                                                       if (value > 0x10FFFF)
-                                                               ; /* invalid */
-                                                       else if (value > 0xFFFF)
-                                                               len += 1; /* we need surrogates */
-                                                       else
-                                                               ; /* 16bit suffice */
-                                               }
-                                               else
-                                                       t--; /* invalid */
-                                       }
-                                       else
-                                               t--; /* invalid */
-                               }
-                               else
-                                       t--; /* invalid */
-                       }
-                       else if ((byte & 0xfc) == 0xf8) {
-                               /* invalid 5-byte */
-                               if (t + 4 > tlimit)
-                                       return len + 1; /* invalid, stop here */
-
-                               skip = 4;
-                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
-                                       t++;
-                       }
-                       else if ((byte & 0xfe) == 0xfc) {
-                               /* invalid 6-byte */
-                               if (t + 5 > tlimit)
-                                       return len + 1; /* invalid, stop here */
-
-                               skip = 5;
-                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
-                                       t++;
-                       }
-                       else
-                               ; /* invalid */
-               }
-               else {
-                       /* NUL */
-
-                       if (byte == 0)
-                               break;
-
-                       /* ASCII character, common case */
-               }
-
-               len++;
-       }
-
-       return len;
-}
-
-
-/* utf8_safe_convert_to_u2s ****************************************************
-
-   Convert the given UTF-8 string to UTF-16 into a pre-allocated buffer.
-   (Invalid UTF-8 will be replaced with the U+fffd replacement character.)
-   Use utf8_safe_number_of_u2s to determine the number of u2s to allocate.
-
-   This function is safe even for invalid UTF-8 strings.
-
-   IN:
-      text..........zero-terminated(!) UTF-8 string (may be invalid)
-                       must NOT be NULL
-         nbytes........strlen(text). (This is needed to completely emulate
-                                       the RI).
-         buffer........a preallocated array of u2s to receive the decoded
-                       string. Use utf8_safe_number_of_u2s to get the
-                                       required number of u2s for allocating this.
-
-*******************************************************************************/
-
-#define UNICODE_REPLACEMENT  0xfffd
-
-void utf8_safe_convert_to_u2s(const char *text, s4 nbytes, u2 *buffer) {
-       register const unsigned char *t;
-       register s4 byte;
-       register const unsigned char *tlimit;
-       s4 byte1;
-       s4 byte2;
-       s4 byte3;
-       s4 value;
-       s4 skip;
-
-       assert(text);
-       assert(nbytes >= 0);
-
-       t = (const unsigned char *) text;
-       tlimit = t + nbytes;
-
-       /* CAUTION: Keep this code in sync with utf8_safe_number_of_u2s! */
-
-       while (1) {
-               byte = *t++;
-
-               if (byte & 0x80) {
-                       /* highest bit set, non-ASCII character */
-
-                       if ((byte & 0xe0) == 0xc0) {
-                               /* 2-byte: should be 110..... 10...... */
-
-                               if (((byte1 = *t++) & 0xc0) == 0x80) {
-                                       /* valid 2-byte UTF-8 */
-                                       *buffer++ = ((byte  & 0x1f) << 6)
-                                                         | ((byte1 & 0x3f)     );
-                               }
-                               else {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       t--;
-                               }
-                       }
-                       else if ((byte & 0xf0) == 0xe0) {
-                               /* 3-byte: should be 1110.... 10...... 10...... */
-
-                               if (t + 2 > tlimit) {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       return;
-                               }
-
-                               if (((byte1 = *t++) & 0xc0) == 0x80) {
-                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
-                                               /* valid 3-byte UTF-8 */
-                                               *buffer++ = ((byte  & 0x0f) << 12)
-                                                                 | ((byte1 & 0x3f) <<  6)
-                                                                 | ((byte2 & 0x3f)      );
-                                       }
-                                       else {
-                                               *buffer++ = UNICODE_REPLACEMENT;
-                                               t--;
-                                       }
-                               }
-                               else {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       t--;
-                               }
-                       }
-                       else if ((byte & 0xf8) == 0xf0) {
-                               /* 4-byte: should be 11110... 10...... 10...... 10...... */
-
-                               if (t + 3 > tlimit) {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       return;
-                               }
-
-                               if (((byte1 = *t++) & 0xc0) == 0x80) {
-                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
-                                               if (((byte3 = *t++) & 0xc0) == 0x80) {
-                                                       /* valid 4-byte UTF-8? */
-                                                       value = ((byte  & 0x07) << 18)
-                                                                 | ((byte1 & 0x3f) << 12)
-                                                                 | ((byte2 & 0x3f) <<  6)
-                                                                 | ((byte3 & 0x3f)      );
-
-                                                       if (value > 0x10FFFF) {
-                                                               *buffer++ = UNICODE_REPLACEMENT;
-                                                       }
-                                                       else if (value > 0xFFFF) {
-                                                               /* we need surrogates */
-                                                               *buffer++ = 0xd800 | ((value >> 10) - 0x40);
-                                                               *buffer++ = 0xdc00 | (value & 0x03ff);
-                                                       }
-                                                       else
-                                                               *buffer++ = value; /* 16bit suffice */
-                                               }
-                                               else {
-                                                       *buffer++ = UNICODE_REPLACEMENT;
-                                                       t--;
-                                               }
-                                       }
-                                       else {
-                                               *buffer++ = UNICODE_REPLACEMENT;
-                                               t--;
-                                       }
-                               }
-                               else {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       t--;
-                               }
-                       }
-                       else if ((byte & 0xfc) == 0xf8) {
-                               if (t + 4 > tlimit) {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       return;
-                               }
-
-                               skip = 4;
-                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
-                                       t++;
-                               *buffer++ = UNICODE_REPLACEMENT;
-                       }
-                       else if ((byte & 0xfe) == 0xfc) {
-                               if (t + 5 > tlimit) {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       return;
-                               }
-
-                               skip = 5;
-                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
-                                       t++;
-                               *buffer++ = UNICODE_REPLACEMENT;
-                       }
-                       else
-                               *buffer++ = UNICODE_REPLACEMENT;
-               }
-               else {
-                       /* NUL */
-
-                       if (byte == 0)
-                               break;
-
-                       /* ASCII character, common case */
-
-                       *buffer++ = byte;
-               }
-       }
-}
-
-
-/* u2_utflength ****************************************************************
-
-   Returns the utf length in bytes of a u2 array.
-
-*******************************************************************************/
-
-u4 u2_utflength(u2 *text, u4 u2_length)
-{
-       u4 result_len = 0;                  /* utf length in bytes                */
-       u2 ch;                              /* current unicode character          */
-       u4 len;
-       
-       for (len = 0; len < u2_length; len++) {
-               /* next unicode character */
-               ch = *text++;
-         
-               /* determine bytes required to store unicode character as utf */
-               if (ch && (ch < 0x80)) 
-                       result_len++;
-               else if (ch < 0x800)
-                       result_len += 2;        
-               else 
-                       result_len += 3;        
-       }
-
-    return result_len;
-}
-
-
-/* utf_copy ********************************************************************
-
-   Copy the given utf string byte-for-byte to a buffer.
-
-   IN:
-      buffer.......the buffer
-         u............the utf string
-
-*******************************************************************************/
-
-void utf_copy(char *buffer, utf *u)
-{
-       /* our utf strings are zero-terminated (done by utf_new) */
-       MCOPY(buffer, u->text, char, u->blength + 1);
-}
-
-
-/* utf_cat *********************************************************************
-
-   Append the given utf string byte-for-byte to a buffer.
-
-   IN:
-      buffer.......the buffer
-         u............the utf string
-
-*******************************************************************************/
-
-void utf_cat(char *buffer, utf *u)
-{
-       /* our utf strings are zero-terminated (done by utf_new) */
-       MCOPY(buffer + strlen(buffer), u->text, char, u->blength + 1);
-}
-
-
-/* utf_copy_classname **********************************************************
-
-   Copy the given utf classname byte-for-byte to a buffer.
-   '/' is replaced by '.'
-
-   IN:
-      buffer.......the buffer
-         u............the utf string
-
-*******************************************************************************/
-
-void utf_copy_classname(char *buffer, utf *u)
-{
-       char *bufptr;
-       char *srcptr;
-       char *endptr;
-       char ch;
-
-       bufptr = buffer;
-       srcptr = u->text;
-       endptr = UTF_END(u) + 1; /* utfs are zero-terminared by utf_new */
-
-       while (srcptr != endptr) {
-               ch = *srcptr++;
-               if (ch == '/')
-                       ch = '.';
-               *bufptr++ = ch;
-       }
-}
-
-
-/* utf_cat *********************************************************************
-
-   Append the given utf classname byte-for-byte to a buffer.
-   '/' is replaced by '.'
-
-   IN:
-      buffer.......the buffer
-         u............the utf string
-
-*******************************************************************************/
-
-void utf_cat_classname(char *buffer, utf *u)
-{
-       utf_copy_classname(buffer + strlen(buffer), u);
-}
-
-/* utf_display_printable_ascii *************************************************
-
-   Write utf symbol to stdout (for debugging purposes).
-   Non-printable and non-ASCII characters are printed as '?'.
-
-*******************************************************************************/
-
-void utf_display_printable_ascii(utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-
-       if (u == NULL) {
-               printf("NULL");
-               fflush(stdout);
-               return;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) {
-               /* read next unicode character */
-
-               u2 c = utf_nextu2(&utf_ptr);
-
-               if ((c >= 32) && (c <= 127))
-                       printf("%c", c);
-               else
-                       printf("?");
-       }
-
-       fflush(stdout);
-}
-
-
-/* utf_display_printable_ascii_classname ***************************************
-
-   Write utf symbol to stdout with `/' converted to `.' (for debugging
-   purposes).
-   Non-printable and non-ASCII characters are printed as '?'.
-
-*******************************************************************************/
-
-void utf_display_printable_ascii_classname(utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-
-       if (u == NULL) {
-               printf("NULL");
-               fflush(stdout);
-               return;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) {
-               /* read next unicode character */
-
-               u2 c = utf_nextu2(&utf_ptr);
-
-               if (c == '/')
-                       c = '.';
-
-               if ((c >= 32) && (c <= 127))
-                       printf("%c", c);
-               else
-                       printf("?");
-       }
-
-       fflush(stdout);
-}
-
-
-/* utf_sprint_convert_to_latin1 ************************************************
-       
-   Write utf symbol into c-string (for debugging purposes).
-   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
-   invalid results.
-
-*******************************************************************************/
-
-void utf_sprint_convert_to_latin1(char *buffer, utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-       u2 pos = 0;                         /* position in c-string               */
-
-       if (!u) {
-               strcpy(buffer, "NULL");
-               return;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) 
-               /* copy next unicode character */       
-               buffer[pos++] = utf_nextu2(&utf_ptr);
-
-       /* terminate string */
-       buffer[pos] = '\0';
-}
-
-
-/* utf_sprint_convert_to_latin1_classname **************************************
-       
-   Write utf symbol into c-string with `/' converted to `.' (for debugging
-   purposes).
-   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
-   invalid results.
-
-*******************************************************************************/
-
-void utf_sprint_convert_to_latin1_classname(char *buffer, utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-       u2 pos = 0;                         /* position in c-string               */
-
-       if (!u) {
-               strcpy(buffer, "NULL");
-               return;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) {
-               /* copy next unicode character */       
-               u2 c = utf_nextu2(&utf_ptr);
-               if (c == '/') c = '.';
-               buffer[pos++] = c;
-       }
-
-       /* terminate string */
-       buffer[pos] = '\0';
-}
-
-
-/* utf_strcat_convert_to_latin1 ************************************************
-       
-   Like libc strcat, but uses an utf8 string.
-   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
-   invalid results.
-
-*******************************************************************************/
-
-void utf_strcat_convert_to_latin1(char *buffer, utf *u)
-{
-       utf_sprint_convert_to_latin1(buffer + strlen(buffer), u);
-}
-
-
-/* utf_strcat_convert_to_latin1_classname **************************************
-       
-   Like libc strcat, but uses an utf8 string.
-   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
-   invalid results.
-
-*******************************************************************************/
-
-void utf_strcat_convert_to_latin1_classname(char *buffer, utf *u)
-{
-       utf_sprint_convert_to_latin1_classname(buffer + strlen(buffer), u);
-}
-
-
-/* utf_fprint_printable_ascii **************************************************
-       
-   Write utf symbol into file.
-   Non-printable and non-ASCII characters are printed as '?'.
-
-*******************************************************************************/
-
-void utf_fprint_printable_ascii(FILE *file, utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-
-       if (!u)
-               return;
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) { 
-               /* read next unicode character */                
-               u2 c = utf_nextu2(&utf_ptr);                            
-
-               if (c >= 32 && c <= 127) fprintf(file, "%c", c);
-               else fprintf(file, "?");
-       }
-}
-
-
-/* utf_fprint_printable_ascii_classname ****************************************
-       
-   Write utf symbol into file with `/' converted to `.'.
-   Non-printable and non-ASCII characters are printed as '?'.
-
-*******************************************************************************/
-
-void utf_fprint_printable_ascii_classname(FILE *file, utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-
-    if (!u)
-               return;
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) { 
-               /* read next unicode character */                
-               u2 c = utf_nextu2(&utf_ptr);                            
-               if (c == '/') c = '.';
-
-               if (c >= 32 && c <= 127) fprintf(file, "%c", c);
-               else fprintf(file, "?");
-       }
-}
-
-
-/* is_valid_utf ****************************************************************
-
-   Return true if the given string is a valid UTF-8 string.
-
-   utf_ptr...points to first character
-   end_pos...points after last character
-
-*******************************************************************************/
-
-/*  static unsigned long min_codepoint[6] = {0,1L<<7,1L<<11,1L<<16,1L<<21,1L<<26}; */
-
-bool is_valid_utf(char *utf_ptr, char *end_pos)
-{
-       int bytes;
-       int len,i;
-       char c;
-       unsigned long v;
-
-       if (end_pos < utf_ptr) return false;
-       bytes = end_pos - utf_ptr;
-       while (bytes--) {
-               c = *utf_ptr++;
-
-               if (!c) return false;                     /* 0x00 is not allowed */
-               if ((c & 0x80) == 0) continue;            /* ASCII */
-
-               if      ((c & 0xe0) == 0xc0) len = 1;     /* 110x xxxx */
-               else if ((c & 0xf0) == 0xe0) len = 2;     /* 1110 xxxx */
-               else if ((c & 0xf8) == 0xf0) len = 3;     /* 1111 0xxx */
-               else if ((c & 0xfc) == 0xf8) len = 4;     /* 1111 10xx */
-               else if ((c & 0xfe) == 0xfc) len = 5;     /* 1111 110x */
-               else return false;                        /* invalid leading byte */
-
-               if (len > 2) return false;                /* Java limitation */
-
-               v = (unsigned long)c & (0x3f >> len);
-               
-               if ((bytes -= len) < 0) return false;     /* missing bytes */
-
-               for (i = len; i--; ) {
-                       c = *utf_ptr++;
-                       if ((c & 0xc0) != 0x80)               /* 10xx xxxx */
-                               return false;
-                       v = (v << 6) | (c & 0x3f);
-               }
-
-               if (v == 0) {
-                       if (len != 1) return false;           /* Java special */
-
-               } else {
-                       /* Sun Java seems to allow overlong UTF-8 encodings */
-                       
-                       /* if (v < min_codepoint[len]) */
-                               /* XXX throw exception? */
-               }
-
-               /* surrogates in UTF-8 seem to be allowed in Java classfiles */
-               /* if (v >= 0xd800 && v <= 0xdfff) return false; */ /* surrogates */
-
-               /* even these seem to be allowed */
-               /* if (v == 0xfffe || v == 0xffff) return false; */ /* invalid codepoints */
-       }
-
-       return true;
-}
-
-
-/* is_valid_name ***************************************************************
-
-   Return true if the given string may be used as a class/field/method
-   name. (Currently this only disallows empty strings and control
-   characters.)
-
-   NOTE: The string is assumed to have passed is_valid_utf!
-
-   utf_ptr...points to first character
-   end_pos...points after last character
-
-*******************************************************************************/
-
-bool is_valid_name(char *utf_ptr, char *end_pos)
-{
-       if (end_pos <= utf_ptr) return false; /* disallow empty names */
-
-       while (utf_ptr < end_pos) {
-               unsigned char c = *utf_ptr++;
-
-               if (c < 0x20) return false; /* disallow control characters */
-               if (c == 0xc0 && (unsigned char) *utf_ptr == 0x80)  /* disallow zero */
-                       return false;
-       }
-
-       return true;
-}
-
-bool is_valid_name_utf(utf *u)
-{
-       return is_valid_name(u->text, UTF_END(u));
-}
-
-
-/* utf_show ********************************************************************
-
-   Writes the utf symbols in the utfhash to stdout and displays the
-   number of external hash chains grouped according to the chainlength
-   (for debugging purposes).
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void utf_show(void)
-{
-
-#define CHAIN_LIMIT 20               /* limit for seperated enumeration */
-
-       u4 chain_count[CHAIN_LIMIT]; /* numbers of chains */
-       u4 max_chainlength = 0;      /* maximum length of the chains */
-       u4 sum_chainlength = 0;      /* sum of the chainlengths */
-       u4 beyond_limit = 0;         /* number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */
-       u4 i;
-
-       printf("UTF-HASH:\n");
-
-       /* show element of utf-hashtable */
-
-       for (i = 0; i < hashtable_utf->size; i++) {
-               utf *u = hashtable_utf->ptr[i];
-
-               if (u) {
-                       printf("SLOT %d: ", (int) i);
-
-                       while (u) {
-                               printf("'");
-                               utf_display_printable_ascii(u);
-                               printf("' ");
-                               u = u->hashlink;
-                       }       
-                       printf("\n");
-               }
-       }
-
-       printf("UTF-HASH: %d slots for %d entries\n", 
-                  (int) hashtable_utf->size, (int) hashtable_utf->entries );
-
-       if (hashtable_utf->entries == 0)
-               return;
-
-       printf("chains:\n  chainlength    number of chains    %% of utfstrings\n");
-
-       for (i=0;i<CHAIN_LIMIT;i++)
-               chain_count[i]=0;
-
-       /* count numbers of hashchains according to their length */
-       for (i=0; i<hashtable_utf->size; i++) {
-                 
-               utf *u = (utf*) hashtable_utf->ptr[i];
-               u4 chain_length = 0;
-
-               /* determine chainlength */
-               while (u) {
-                       u = u->hashlink;
-                       chain_length++;
-               }
-
-               /* update sum of all chainlengths */
-               sum_chainlength+=chain_length;
-
-               /* determine the maximum length of the chains */
-               if (chain_length>max_chainlength)
-                       max_chainlength = chain_length;
-
-               /* update number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */
-               if (chain_length>=CHAIN_LIMIT) {
-                       beyond_limit+=chain_length;
-                       chain_length=CHAIN_LIMIT-1;
-               }
-
-               /* update number of hashchains of current length */
-               chain_count[chain_length]++;
-       }
-
-       /* display results */  
-       for (i=1;i<CHAIN_LIMIT-1;i++) 
-               printf("       %2d %17d %18.2f%%\n",i,chain_count[i],(((float) chain_count[i]*i*100)/hashtable_utf->entries));
-         
-       printf("     >=%2d %17d %18.2f%%\n",CHAIN_LIMIT-1,chain_count[CHAIN_LIMIT-1],((float) beyond_limit*100)/hashtable_utf->entries);
-
-
-       printf("max. chainlength:%5d\n",max_chainlength);
-
-       /* avg. chainlength = sum of chainlengths / number of chains */
-       printf("avg. chainlength:%5.2f\n",(float) sum_chainlength / (hashtable_utf->size-chain_count[0]));
-}
-#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/vmcore/utf8.h b/src/vmcore/utf8.h
deleted file mode 100644 (file)
index 6f76610..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/* src/vmcore/utf8.h - utf8 string 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 _UTF_H
-#define _UTF_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct utf utf;
-
-#include "config.h"
-
-#include <stdio.h>
-
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-
-/* data structure for utf8 symbols ********************************************/
-
-struct utf {
-       utf  *hashlink;                     /* link for external hash chain       */
-       s4    blength;                      /* text length in bytes               */
-       char *text;                         /* pointer to text                    */
-};
-
-/* to determine the end of utf strings */
-
-#define UTF_END(u)    ((char *) u->text + u->blength)
-
-
-/* utf-symbols for pointer comparison of frequently used strings **************/
-
-extern utf *utf_java_lang_Object;
-
-extern utf *utf_java_lang_Class;
-extern utf *utf_java_lang_ClassLoader;
-extern utf *utf_java_lang_Cloneable;
-extern utf *utf_java_lang_SecurityManager;
-extern utf *utf_java_lang_String;
-extern utf *utf_java_lang_ThreadGroup;
-extern utf *utf_java_lang_ref_SoftReference;
-extern utf *utf_java_lang_ref_WeakReference;
-extern utf *utf_java_lang_ref_PhantomReference;
-extern utf *utf_java_io_Serializable;
-
-extern utf *utf_java_lang_Throwable;
-extern utf *utf_java_lang_Error;
-
-extern utf *utf_java_lang_AbstractMethodError;
-extern utf *utf_java_lang_ClassCircularityError;
-extern utf *utf_java_lang_ClassFormatError;
-extern utf *utf_java_lang_ExceptionInInitializerError;
-extern utf *utf_java_lang_IncompatibleClassChangeError;
-extern utf *utf_java_lang_InstantiationError;
-extern utf *utf_java_lang_InternalError;
-extern utf *utf_java_lang_LinkageError;
-extern utf *utf_java_lang_NoClassDefFoundError;
-extern utf *utf_java_lang_NoSuchFieldError;
-extern utf *utf_java_lang_NoSuchMethodError;
-extern utf *utf_java_lang_OutOfMemoryError;
-extern utf *utf_java_lang_UnsatisfiedLinkError;
-extern utf *utf_java_lang_UnsupportedClassVersionError;
-extern utf *utf_java_lang_VerifyError;
-extern utf *utf_java_lang_VirtualMachineError;
-
-extern utf *utf_java_lang_Exception;
-
-extern utf *utf_java_lang_ArithmeticException;
-extern utf *utf_java_lang_ArrayIndexOutOfBoundsException;
-extern utf *utf_java_lang_ArrayStoreException;
-extern utf *utf_java_lang_ClassCastException;
-extern utf *utf_java_lang_ClassNotFoundException;
-extern utf *utf_java_lang_CloneNotSupportedException;
-extern utf *utf_java_lang_IllegalAccessException;
-extern utf *utf_java_lang_IllegalArgumentException;
-extern utf *utf_java_lang_IllegalMonitorStateException;
-extern utf *utf_java_lang_InstantiationException;
-extern utf *utf_java_lang_InterruptedException;
-extern utf *utf_java_lang_NegativeArraySizeException;
-extern utf *utf_java_lang_NullPointerException;
-extern utf *utf_java_lang_RuntimeException;
-extern utf *utf_java_lang_StringIndexOutOfBoundsException;
-
-extern utf *utf_java_lang_reflect_InvocationTargetException;
-
-extern utf *utf_java_security_PrivilegedActionException;
-
-#if defined(ENABLE_JAVASE)
-extern utf* utf_java_lang_Void;
-#endif
-
-extern utf* utf_java_lang_Boolean;
-extern utf* utf_java_lang_Byte;
-extern utf* utf_java_lang_Character;
-extern utf* utf_java_lang_Short;
-extern utf* utf_java_lang_Integer;
-extern utf* utf_java_lang_Long;
-extern utf* utf_java_lang_Float;
-extern utf* utf_java_lang_Double;
-
-#if defined(ENABLE_JAVASE)
-extern utf *utf_java_lang_StackTraceElement;
-extern utf *utf_java_lang_reflect_Constructor;
-extern utf *utf_java_lang_reflect_Field;
-extern utf *utf_java_lang_reflect_Method;
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-extern utf *utf_java_lang_reflect_VMConstructor;
-extern utf *utf_java_lang_reflect_VMField;
-extern utf *utf_java_lang_reflect_VMMethod;
-# endif
-
-extern utf *utf_java_util_Vector;
-#endif
-
-extern utf *utf_InnerClasses;
-extern utf *utf_ConstantValue;
-extern utf *utf_Code;
-extern utf *utf_Exceptions;
-extern utf *utf_LineNumberTable;
-extern utf *utf_SourceFile;
-
-#if defined(ENABLE_JAVASE)
-extern utf *utf_EnclosingMethod;
-extern utf *utf_Signature;
-extern utf *utf_StackMapTable;
-
-#if defined(ENABLE_ANNOTATIONS)
-extern utf *utf_RuntimeVisibleAnnotations;
-extern utf *utf_RuntimeInvisibleAnnotations;
-extern utf *utf_RuntimeVisibleParameterAnnotations;
-extern utf *utf_RuntimeInvisibleParameterAnnotations;
-extern utf *utf_AnnotationDefault;
-#endif
-#endif
-
-extern utf *utf_init;
-extern utf *utf_clinit;
-extern utf *utf_clone;
-extern utf *utf_finalize;
-extern utf *utf_invoke;
-extern utf *utf_main;
-extern utf *utf_run;
-
-extern utf *utf_add;
-extern utf *utf_remove;
-extern utf *utf_addThread;
-extern utf *utf_removeThread;
-extern utf *utf_put;
-extern utf *utf_get;
-extern utf *utf_uncaughtException;
-extern utf *utf_value;
-
-extern utf *utf_fillInStackTrace;
-extern utf *utf_findNative;
-extern utf *utf_getSystemClassLoader;
-extern utf *utf_initCause;
-extern utf *utf_loadClass;
-extern utf *utf_loadClassInternal;
-extern utf *utf_printStackTrace;
-
-extern utf *utf_division_by_zero;
-
-extern utf *utf_Z;
-extern utf *utf_B;
-extern utf *utf_C;
-extern utf *utf_S;
-extern utf *utf_I;
-extern utf *utf_J;
-extern utf *utf_F;
-extern utf *utf_D;
-
-extern utf *utf_void__void;
-extern utf *utf_boolean__void;
-extern utf *utf_byte__void;
-extern utf *utf_char__void;
-extern utf *utf_short__void;
-extern utf *utf_int__void;
-extern utf *utf_long__void;
-extern utf *utf_float__void;
-extern utf *utf_double__void;
-
-extern utf *utf_void__java_lang_ClassLoader;
-extern utf *utf_void__java_lang_Object;
-extern utf *utf_void__java_lang_Throwable;
-extern utf *utf_java_lang_ClassLoader_java_lang_String__J;
-extern utf *utf_java_lang_Exception__V;
-extern utf *utf_java_lang_Object__java_lang_Object;
-extern utf *utf_java_lang_String__void;
-extern utf *utf_java_lang_String__java_lang_Class;
-extern utf *utf_java_lang_Thread__V;
-extern utf *utf_java_lang_Thread_java_lang_Throwable__V;
-extern utf *utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V;
-extern utf *utf_java_lang_Throwable__void;
-extern utf *utf_java_lang_Throwable__java_lang_Throwable;
-
-extern utf *utf_not_named_yet;
-extern utf *utf_null;
-extern utf *array_packagename;
-
-
-/* function prototypes ********************************************************/
-
-/* initialize the utf8 subsystem */
-void utf8_init(void);
-
-u4 utf_hashkey(const char *text, u4 length);
-u4 utf_full_hashkey(const char *text, u4 length);
-
-/* determine hashkey of a unicode-symbol */
-u4 unicode_hashkey(u2 *text, u2 length);
-
-/* create new utf-symbol */
-utf *utf_new(const char *text, u2 length);
-
-/* make utf symbol from u2 array */
-utf *utf_new_u2(u2 *unicodedata, u4 unicodelength, bool isclassname);
-
-utf *utf_new_char(const char *text);
-utf *utf_new_char_classname(const char *text);
-
-/* get number of bytes */
-u4 utf_bytes(utf *u);
-
-/* get next unicode character of a utf-string */
-u2 utf_nextu2(char **utf);
-
-/* get (number of) unicode characters of a utf string (safe) */
-s4 utf8_safe_number_of_u2s(const char *text, s4 nbytes);
-void utf8_safe_convert_to_u2s(const char *text, s4 nbytes, u2 *buffer);
-
-/* get (number of) unicode characters of a utf string (UNSAFE!) */
-u4 utf_get_number_of_u2s(utf *u);
-u4 utf_get_number_of_u2s_for_buffer(const char *buffer, u4 blength);
-
-/* determine utf length in bytes of a u2 array */
-u4 u2_utflength(u2 *text, u4 u2_length);
-
-void utf_copy(char *buffer, utf *u);
-void utf_cat(char *buffer, utf *u);
-void utf_copy_classname(char *buffer, utf *u);
-void utf_cat_classname(char *buffer, utf *u);
-
-/* write utf symbol to file/buffer */
-void utf_display_printable_ascii(utf *u);
-void utf_display_printable_ascii_classname(utf *u);
-
-void utf_sprint_convert_to_latin1(char *buffer, utf *u);
-void utf_sprint_convert_to_latin1_classname(char *buffer, utf *u);
-
-void utf_strcat_convert_to_latin1(char *buffer, utf *u);
-void utf_strcat_convert_to_latin1_classname(char *buffer, utf *u);
-
-void utf_fprint_printable_ascii(FILE *file, utf *u);
-void utf_fprint_printable_ascii_classname(FILE *file, utf *u);
-
-/* check if a UTF-8 string is valid */
-bool is_valid_utf(char *utf_ptr, char *end_pos);
-
-/* check if a UTF-8 string may be used as a class/field/method name */
-bool is_valid_name(char *utf_ptr, char *end_pos);
-bool is_valid_name_utf(utf *u);
-
-/* show utf-table */
-void utf_show(void);
-
-#endif /* _UTF_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/vmcore/zip.c b/src/vmcore/zip.c
deleted file mode 100644 (file)
index c3644e2..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-/* src/vmcore/zip.c - ZIP file handling for bootstrap classloader
-
-   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 <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <zlib.h>
-#include <sys/mman.h>
-
-#include "vm/types.h"
-
-#include "toolbox/hashtable.h"
-
-#include "mm/memory.h"
-
-#include "vm/global.h"
-#include "vm/vm.h"
-
-#include "vmcore/suck.h"
-#include "vmcore/utf8.h"
-#include "vmcore/zip.h"
-
-
-/* start size for classes hashtable *******************************************/
-
-#define HASHTABLE_CLASSES_SIZE    (1 << 10)
-
-
-/* info taken from:
-   http://www.pkware.com/business_and_developers/developer/popups/appnote.txt
-*/
-
-/* all signatures in the ZIP file have a length of 4 bytes ********************/
-
-#define SIGNATURE_LENGTH    4
-
-/* Central directory structure *************************************************
-
-   [file header 1]
-   .
-   .
-   . 
-   [file header n]
-   [digital signature] 
-   
-   File header:
-   
-     central file header signature   4 bytes  (0x02014b50)
-     version made by                 2 bytes
-     version needed to extract       2 bytes
-     general purpose bit flag        2 bytes
-     compression method              2 bytes
-     last mod file time              2 bytes
-     last mod file date              2 bytes
-     crc-32                          4 bytes
-     compressed size                 4 bytes
-     uncompressed size               4 bytes
-     file name length                2 bytes
-     extra field length              2 bytes
-     file comment length             2 bytes
-     disk number start               2 bytes
-     internal file attributes        2 bytes
-     external file attributes        4 bytes
-     relative offset of local header 4 bytes
-   
-     file name (variable size)
-     extra field (variable size)
-     file comment (variable size)
-
-   Digital signature:
-   
-     header signature                4 bytes  (0x05054b50)
-     size of data                    2 bytes
-     signature data (variable size)
-
-*******************************************************************************/
-
-#define CDSFH_HEADER_SIZE            46
-
-#define CDSFH_SIGNATURE              0x02014b50
-#define CDSFH_COMPRESSION_METHOD     10
-#define CDSFH_COMPRESSED_SIZE        20
-#define CDSFH_UNCOMPRESSED_SIZE      24
-#define CDSFH_FILE_NAME_LENGTH       28
-#define CDSFH_EXTRA_FIELD_LENGTH     30
-#define CDSFH_FILE_COMMENT_LENGTH    32
-#define CDSFH_RELATIVE_OFFSET        42
-#define CDSFH_FILENAME               46
-
-typedef struct cdsfh cdsfh;
-
-struct cdsfh {
-       u2 compressionmethod;
-       u4 compressedsize;
-       u4 uncompressedsize;
-       u2 filenamelength;
-       u2 extrafieldlength;
-       u2 filecommentlength;
-       u4 relativeoffset;
-};
-
-
-/* End of central directory record *********************************************
-
-   end of central dir signature    4 bytes  (0x06054b50)
-   number of this disk             2 bytes
-   number of the disk with the
-   start of the central directory  2 bytes
-   total number of entries in the
-   central directory on this disk  2 bytes
-   total number of entries in
-   the central directory           2 bytes
-   size of the central directory   4 bytes
-   offset of start of central
-   directory with respect to
-   the starting disk number        4 bytes
-   .ZIP file comment length        2 bytes
-   .ZIP file comment       (variable size)
-
-*******************************************************************************/
-
-#define EOCDR_SIGNATURE              0x06054b50
-#define EOCDR_ENTRIES                10
-#define EOCDR_OFFSET                 16
-
-typedef struct eocdr eocdr;
-
-struct eocdr {
-       u2 entries;
-       u4 offset;
-};
-
-
-/* zip_open ********************************************************************
-
-   XXX
-
-*******************************************************************************/
-
-hashtable *zip_open(char *path)
-{
-       hashtable               *ht;
-       hashtable_zipfile_entry *htzfe;
-       int                      fd;
-       u1                       lfh_signature[SIGNATURE_LENGTH];
-       off_t                    len;
-       u1                      *filep;
-       s4                       i;
-       u1                      *p;
-       eocdr                    eocdr;
-       cdsfh                    cdsfh;
-       const char              *filename;
-       const char              *classext;
-       utf                     *u;
-       u4                       key;       /* hashkey computed from utf-text     */
-       u4                       slot;      /* slot in hashtable                  */
-
-       /* first of all, open the file */
-
-       if ((fd = open(path, O_RDONLY)) == -1)
-               return NULL;
-
-       /* check for signature in first local file header */
-
-       if (read(fd, lfh_signature, SIGNATURE_LENGTH) != SIGNATURE_LENGTH)
-               return NULL;
-
-       if (SUCK_LE_U4(lfh_signature) != LFH_SIGNATURE)
-               return NULL;
-
-       /* get the file length */
-
-       if ((len = lseek(fd, 0, SEEK_END)) == -1)
-               return NULL;
-
-       /* we better mmap the file */
-
-       filep = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
-
-       /* some older compilers, like DEC OSF cc, don't like comparisons
-       on void* types */
-
-       if ((ptrint) filep == (ptrint) MAP_FAILED)
-               return NULL;
-
-       /* find end of central directory record */
-
-       for (p = filep + len; p >= filep; p--)
-               if (SUCK_LE_U4(p) == EOCDR_SIGNATURE)
-                       break;
-
-       /* get number of entries in central directory */
-
-       eocdr.entries = SUCK_LE_U2(p + EOCDR_ENTRIES);
-       eocdr.offset  = SUCK_LE_U4(p + EOCDR_OFFSET);
-
-       /* create hashtable for filenames */
-
-       ht = NEW(hashtable);
-
-       hashtable_create(ht, HASHTABLE_CLASSES_SIZE);
-
-       /* add all file entries into the hashtable */
-
-       for (i = 0, p = filep + eocdr.offset; i < eocdr.entries; i++) {
-               /* check file header signature */
-
-               if (SUCK_LE_U4(p) != CDSFH_SIGNATURE)
-                       return NULL;
-
-               /* we found an entry */
-
-               cdsfh.compressionmethod = SUCK_LE_U2(p + CDSFH_COMPRESSION_METHOD);
-               cdsfh.compressedsize    = SUCK_LE_U4(p + CDSFH_COMPRESSED_SIZE);
-               cdsfh.uncompressedsize  = SUCK_LE_U4(p + CDSFH_UNCOMPRESSED_SIZE);
-               cdsfh.filenamelength    = SUCK_LE_U2(p + CDSFH_FILE_NAME_LENGTH);
-               cdsfh.extrafieldlength  = SUCK_LE_U2(p + CDSFH_EXTRA_FIELD_LENGTH);
-               cdsfh.filecommentlength = SUCK_LE_U2(p + CDSFH_FILE_COMMENT_LENGTH);
-               cdsfh.relativeoffset    = SUCK_LE_U4(p + CDSFH_RELATIVE_OFFSET);
-
-               /* create utf8 string of filename, strip .class from classes */
-
-               filename = (const char *) (p + CDSFH_FILENAME);
-               classext = filename + cdsfh.filenamelength - strlen(".class");
-
-               /* skip directory entries */
-
-               if (filename[cdsfh.filenamelength - 1] != '/') {
-                       if (strncmp(classext, ".class", strlen(".class")) == 0)
-                               u = utf_new(filename, cdsfh.filenamelength - strlen(".class"));
-                       else
-                               u = utf_new(filename, cdsfh.filenamelength);
-
-                       /* insert class into hashtable */
-
-                       htzfe = NEW(hashtable_zipfile_entry);
-
-                       htzfe->filename          = u;
-                       htzfe->compressionmethod = cdsfh.compressionmethod;
-                       htzfe->compressedsize    = cdsfh.compressedsize;
-                       htzfe->uncompressedsize  = cdsfh.uncompressedsize;
-                       htzfe->data              = filep + cdsfh.relativeoffset;
-
-                       /* get hashtable slot */
-
-                       key  = utf_hashkey(u->text, u->blength);
-                       slot = key & (ht->size - 1);
-
-                       /* insert into external chain */
-
-                       htzfe->hashlink = ht->ptr[slot];
-
-                       /* insert hashtable zipfile entry */
-
-                       ht->ptr[slot] = htzfe;
-                       ht->entries++;
-               }
-
-               /* move to next central directory structure file header */
-
-               p = p +
-                       CDSFH_HEADER_SIZE +
-                       cdsfh.filenamelength +
-                       cdsfh.extrafieldlength +
-                       cdsfh.filecommentlength;
-       }
-
-       /* return pointer to hashtable */
-
-       return ht;
-}
-
-
-/* zip_find ********************************************************************
-
-   Search for the given filename in the classpath entries of a zip file.
-
-   NOTE: The '.class' extension is stripped when reading a zip file, so if
-   you want to find a .class file, you must search for its name _without_
-   the '.class' extension. 
-   XXX I dont like that, it makes foo and foo.class ambiguous. -Edwin
-
-   IN:
-      lce..........the classpath entries for the zip file
-         u............the filename to look for
-
-   RETURN VALUE:
-      hashtable_zipfile_entry * of the entry if found, or
-         NULL if not found
-
-*******************************************************************************/
-
-hashtable_zipfile_entry *zip_find(list_classpath_entry *lce, utf *u)
-{
-       hashtable               *ht;
-       u4                       key;       /* hashkey computed from utf-text     */
-       u4                       slot;      /* slot in hashtable                  */
-       hashtable_zipfile_entry *htzfe;     /* hashtable element                  */
-
-       /* get classes hashtable from the classpath entry */
-
-       ht = lce->htclasses;
-
-       /* get the hashtable slot of the name searched */
-
-       key   = utf_hashkey(u->text, u->blength);
-       slot  = key & (ht->size - 1);
-       htzfe = ht->ptr[slot];
-
-       /* search external hash chain for utf-symbol */
-
-       while (htzfe) {
-               if (htzfe->filename == u)
-                       return htzfe;
-
-               /* next element in external chain */
-
-               htzfe = htzfe->hashlink;
-       }
-
-       /* file not found in this archive */
-
-       return NULL;
-}
-
-
-/* zip_get ********************************************************************
-
-   XXX
-
-*******************************************************************************/
-
-classbuffer *zip_get(list_classpath_entry *lce, classinfo *c)
-{
-       hashtable_zipfile_entry *htzfe;
-       lfh                      lfh;
-       u1                      *indata;
-       u1                      *outdata;
-       z_stream                 zs;
-       int                      err;
-       classbuffer             *cb;
-
-       /* try to find the class in the current archive */
-
-       htzfe = zip_find(lce, c->name);
-
-       if (htzfe == NULL)
-               return NULL;
-
-       /* read stuff from local file header */
-
-       lfh.filenamelength   = SUCK_LE_U2(htzfe->data + LFH_FILE_NAME_LENGTH);
-       lfh.extrafieldlength = SUCK_LE_U2(htzfe->data + LFH_EXTRA_FIELD_LENGTH);
-
-       indata = htzfe->data +
-               LFH_HEADER_SIZE +
-               lfh.filenamelength +
-               lfh.extrafieldlength;
-
-       /* allocate buffer for uncompressed data */
-
-       outdata = MNEW(u1, htzfe->uncompressedsize);
-
-       /* how is the file stored? */
-
-       switch (htzfe->compressionmethod) {
-       case Z_DEFLATED:
-               /* fill z_stream structure */
-
-               zs.next_in   = indata;
-               zs.avail_in  = htzfe->compressedsize;
-               zs.next_out  = outdata;
-               zs.avail_out = htzfe->uncompressedsize;
-
-               zs.zalloc = Z_NULL;
-               zs.zfree  = Z_NULL;
-               zs.opaque = Z_NULL;
-
-               /* initialize this inflate run */
-
-               if (inflateInit2(&zs, -MAX_WBITS) != Z_OK)
-                       vm_abort("zip_get: inflateInit2 failed: %s", strerror(errno));
-
-               /* decompress the file into buffer */
-
-               err = inflate(&zs, Z_SYNC_FLUSH);
-
-               if ((err != Z_STREAM_END) && (err != Z_OK))
-                       vm_abort("zip_get: inflate failed: %s", strerror(errno));
-
-               /* finish this inflate run */
-
-               if (inflateEnd(&zs) != Z_OK)
-                       vm_abort("zip_get: inflateEnd failed: %s", strerror(errno));
-               break;
-
-       case 0:
-               /* uncompressed file, just copy the data */
-               MCOPY(outdata, indata, u1, htzfe->compressedsize);
-               break;
-
-       default:
-               vm_abort("zip_get: unknown compression method %d",
-                                htzfe->compressionmethod);
-       }
-       
-       /* allocate classbuffer */
-
-       cb = NEW(classbuffer);
-
-       cb->clazz = c;
-       cb->size  = htzfe->uncompressedsize;
-       cb->data  = outdata;
-       cb->pos   = outdata;
-       cb->path  = lce->path;
-
-       /* return the filled classbuffer structure */
-
-       return 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/vmcore/zip.h b/src/vmcore/zip.h
deleted file mode 100644 (file)
index 0d09aa5..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/* src/vmcore/zip.c - ZIP file handling for bootstrap classloader
-
-   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
-
-   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 _ZIP_H
-#define _ZIP_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "toolbox/hashtable.h"
-
-#include "vm/global.h"
-
-#include "vmcore/class.h"
-#include "vmcore/loader.h"
-#include "vmcore/suck.h"
-#include "vmcore/utf8.h"
-
-
-/* Local file header ***********************************************************
-
-   local file header signature     4 bytes  (0x04034b50)
-   version needed to extract       2 bytes
-   general purpose bit flag        2 bytes
-   compression method              2 bytes
-   last mod file time              2 bytes
-   last mod file date              2 bytes
-   crc-32                          4 bytes
-   compressed size                 4 bytes
-   uncompressed size               4 bytes
-   file name length                2 bytes
-   extra field length              2 bytes
-
-   file name (variable size)
-   extra field (variable size)
-
-*******************************************************************************/
-
-#define LFH_HEADER_SIZE              30
-
-#define LFH_SIGNATURE                0x04034b50
-#define LFH_FILE_NAME_LENGTH         26
-#define LFH_EXTRA_FIELD_LENGTH       28
-
-typedef struct lfh lfh;
-
-struct lfh {
-       u2 compressionmethod;
-       u4 compressedsize;
-       u4 uncompressedsize;
-       u2 filenamelength;
-       u2 extrafieldlength;
-};
-
-/* hashtable_zipfile_entry ****************************************************/
-
-typedef struct hashtable_zipfile_entry hashtable_zipfile_entry;
-
-struct hashtable_zipfile_entry {
-       utf                     *filename;
-       u2                       compressionmethod;
-       u4                       compressedsize;
-       u4                       uncompressedsize;
-       u1                      *data;
-       hashtable_zipfile_entry *hashlink;
-};
-
-
-/* function prototypes ********************************************************/
-
-hashtable *zip_open(char *path);
-hashtable_zipfile_entry *zip_find(list_classpath_entry *lce, utf *u);
-classbuffer *zip_get(list_classpath_entry *lce, classinfo *c);
-
-#endif /* _ZIP_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 e10629c11822e6267f590511606a46c27b40ddb3..94e7d3d33c0fecd07b11cc7ec6d6b87605235627 100644 (file)
@@ -33,7 +33,8 @@ PR52.class,
 PR57.class,
 PR58.class,
 PR65.class,
-PR80.class
+PR80.class,
+PR89.class
 })
 
 public class All {
diff --git a/tests/regression/bugzilla/PR89.java b/tests/regression/bugzilla/PR89.java
new file mode 100644 (file)
index 0000000..506ac21
--- /dev/null
@@ -0,0 +1,62 @@
+/* tests/regression/bugzilla/PR89.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 PR89 {
+    final static float  f = 123.456f;
+    final static double d = 789.012;
+
+    @Test
+    public void testFloat() throws Exception {
+        FloatReflect floatReflect = new FloatReflect();
+        Method m = FloatReflect.class.getMethod("returnFloat", null);
+        Float ret = (Float) m.invoke(floatReflect, null);
+        assertEquals(f, ret, 0.0);
+    }
+
+    @Test
+    public void testDouble() throws Exception {
+        DoubleReflect doubleReflect = new DoubleReflect();
+        Method m = DoubleReflect.class.getMethod("returnDouble", null);
+        Double ret = (Double) m.invoke(doubleReflect, null);
+        assertEquals(d, ret, 0.0);
+    }
+
+    class FloatReflect {
+        public float returnFloat() {
+            return f;
+        }
+    }
+
+    class DoubleReflect {
+        public double returnDouble() {
+            return d;
+        }
+    }
+}