Merged with tip.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Mon, 5 May 2008 13:02:09 +0000 (15:02 +0200)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Mon, 5 May 2008 13:02:09 +0000 (15:02 +0200)
554 files changed:
.hgignore
Makefile.am
NEWS
autogen.sh
configure.ac
contrib/Makefile.am
contrib/setenvinstalled.in
contrib/setenvsource.in
contrib/vmlog/vmlog.c
contrib/vmlog/vmlog.h
contrib/vmlog/vmlog_cacao.c
contrib/vmlog/vmlog_cacao.h
doc/Makefile.am
doc/assertions.tex [new file with mode: 0644]
doc/doxygen/Doxyfile [new file with mode: 0644]
doc/doxygen/Makefile.am [new file with mode: 0644]
doc/handbook/cacao.tex
doc/handbook/java.bib
doc/handbook/s390.tex [new file with mode: 0644]
m4/ac_prog_javac.m4
m4/annotations.m4
m4/assertion.m4
m4/az_python.m4 [new file with mode: 0644]
m4/classpath.m4
m4/debug.m4
m4/dump.m4
m4/hpi.m4 [new file with mode: 0644]
m4/jit.m4
m4/jni.m4
m4/jre-layout.m4
m4/libjvm.m4
m4/ltdl.m4
m4/zlib.m4
man/Makefile.am
src/Makefile.am
src/cacao/Makefile.am
src/cacao/cacao.c
src/cacaoh/Makefile.am
src/cacaoh/cacaoh.c
src/cacaoh/dummy.c
src/cacaoh/headers.c
src/classes/Makefile.am [new file with mode: 0644]
src/classes/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java [new file with mode: 0644]
src/classes/gnu/gnu/classpath/VMStackWalker.java [new file with mode: 0644]
src/classes/gnu/gnu/classpath/VMSystemProperties.java [new file with mode: 0644]
src/classes/gnu/gnu/java/lang/CPStringBuilder.java [new file with mode: 0644]
src/classes/gnu/gnu/java/lang/VMCPStringBuilder.java [new file with mode: 0644]
src/classes/gnu/gnu/java/lang/management/VMMemoryMXBeanImpl.java [new file with mode: 0644]
src/classes/gnu/gnu/java/lang/management/VMRuntimeMXBeanImpl.java [new file with mode: 0644]
src/classes/gnu/java/lang/VMClassLoader.java [new file with mode: 0644]
src/classes/gnu/java/lang/VMString.java [new file with mode: 0644]
src/classes/gnu/java/lang/VMThread.java [new file with mode: 0644]
src/classes/gnu/java/lang/reflect/Constructor.java [new file with mode: 0644]
src/classes/gnu/java/lang/reflect/Field.java [new file with mode: 0644]
src/classes/gnu/java/lang/reflect/Method.java [new file with mode: 0644]
src/classes/gnu/java/lang/reflect/Modifier.java [new file with mode: 0644]
src/classes/gnu/java/lang/reflect/VMConstructor.java [new file with mode: 0644]
src/classes/gnu/java/lang/reflect/VMField.java [new file with mode: 0644]
src/classes/gnu/java/lang/reflect/VMMethod.java [new file with mode: 0644]
src/classes/gnu/java/security/VMAccessController.java [new file with mode: 0644]
src/classes/gnu/sun/misc/Unsafe.java [new file with mode: 0644]
src/classes/gnu/sun/reflect/ConstantPool.java [new file with mode: 0644]
src/classes/gnu/sun/reflect/annotation/AnnotationParser.java [new file with mode: 0644]
src/classes/gnu/sun/reflect/annotation/AnnotationType.java [new file with mode: 0644]
src/classes/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java [new file with mode: 0644]
src/classes/gnu/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java [new file with mode: 0644]
src/classes/gnu/sun/reflect/annotation/ExceptionProxy.java [new file with mode: 0644]
src/classes/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java [new file with mode: 0644]
src/lib/Makefile.am [deleted file]
src/lib/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java [deleted file]
src/lib/gnu/gnu/classpath/VMStackWalker.java [deleted file]
src/lib/gnu/gnu/classpath/VMSystemProperties.java [deleted file]
src/lib/gnu/gnu/java/lang/management/VMMemoryMXBeanImpl.java [deleted file]
src/lib/gnu/gnu/java/lang/management/VMRuntimeMXBeanImpl.java [deleted file]
src/lib/gnu/java/lang/VMClassLoader.java [deleted file]
src/lib/gnu/java/lang/VMString.java [deleted file]
src/lib/gnu/java/lang/VMThread.java [deleted file]
src/lib/gnu/java/lang/VMThrowable.java [deleted file]
src/lib/gnu/java/lang/reflect/Constructor.java [deleted file]
src/lib/gnu/java/lang/reflect/Field.java [deleted file]
src/lib/gnu/java/lang/reflect/Method.java [deleted file]
src/lib/gnu/java/security/VMAccessController.java [deleted file]
src/lib/gnu/sun/misc/Unsafe.java [deleted file]
src/lib/gnu/sun/reflect/ConstantPool.java [deleted file]
src/lib/gnu/sun/reflect/annotation/AnnotationParser.java [deleted file]
src/lib/gnu/sun/reflect/annotation/AnnotationType.java [deleted file]
src/lib/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java [deleted file]
src/lib/gnu/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java [deleted file]
src/lib/gnu/sun/reflect/annotation/ExceptionProxy.java [deleted file]
src/lib/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java [deleted file]
src/mm/Makefile.am
src/mm/boehm-gc/BCC_MAKEFILE
src/mm/boehm-gc/digimars.mak
src/mm/boehm.c
src/mm/cacao-gc/gc.c
src/mm/cacao-gc/gc.h
src/mm/cacao-gc/mark.c
src/mm/cacao-gc/rootset.c
src/mm/cacao-gc/rootset.h
src/mm/codememory.c [new file with mode: 0644]
src/mm/codememory.h [new file with mode: 0644]
src/mm/dumpmemory.c [new file with mode: 0644]
src/mm/dumpmemory.h [new file with mode: 0644]
src/mm/gc-common.h
src/mm/memory.c
src/mm/memory.h
src/native/include/Makefile.am
src/native/jni.c
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/native.c
src/native/native.h
src/native/vm/Makefile.am
src/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.c
src/native/vm/cldc1.1/java_lang_Class.c
src/native/vm/cldc1.1/java_lang_Runtime.c
src/native/vm/cldc1.1/java_lang_Thread.c
src/native/vm/cldc1.1/java_lang_Throwable.c
src/native/vm/gnu/Makefile.am
src/native/vm/gnu/gnu_classpath_VMStackWalker.c
src/native/vm/gnu/gnu_classpath_VMSystemProperties.c
src/native/vm/gnu/gnu_classpath_jdwp_VMFrame.c
src/native/vm/gnu/gnu_classpath_jdwp_VMMethod.c
src/native/vm/gnu/gnu_classpath_jdwp_VMVirtualMachine.c
src/native/vm/gnu/gnu_java_lang_VMCPStringBuilder.c [new file with mode: 0644]
src/native/vm/gnu/gnu_java_lang_management_VMMemoryMXBeanImpl.c
src/native/vm/gnu/java_lang_VMClass.c
src/native/vm/gnu/java_lang_VMClassLoader.c
src/native/vm/gnu/java_lang_VMRuntime.c
src/native/vm/gnu/java_lang_VMSystem.c
src/native/vm/gnu/java_lang_VMThread.c
src/native/vm/gnu/java_lang_VMThrowable.c
src/native/vm/gnu/java_lang_reflect_Constructor.c [deleted file]
src/native/vm/gnu/java_lang_reflect_Field.c [deleted file]
src/native/vm/gnu/java_lang_reflect_Method.c [deleted file]
src/native/vm/gnu/java_lang_reflect_VMConstructor.c [new file with mode: 0644]
src/native/vm/gnu/java_lang_reflect_VMField.c [new file with mode: 0644]
src/native/vm/gnu/java_lang_reflect_VMMethod.c [new file with mode: 0644]
src/native/vm/java_lang_Class.c [deleted file]
src/native/vm/java_lang_Class.h [deleted file]
src/native/vm/java_lang_ClassLoader.c [deleted file]
src/native/vm/java_lang_ClassLoader.h [deleted file]
src/native/vm/java_lang_Runtime.c [deleted file]
src/native/vm/java_lang_Runtime.h [deleted file]
src/native/vm/java_lang_Thread.c [deleted file]
src/native/vm/java_lang_Thread.h [deleted file]
src/native/vm/java_lang_reflect_Constructor.c [deleted file]
src/native/vm/java_lang_reflect_Constructor.h [deleted file]
src/native/vm/java_lang_reflect_Method.c [deleted file]
src/native/vm/java_lang_reflect_Method.h [deleted file]
src/native/vm/nativevm.c
src/native/vm/nativevm.h
src/native/vm/reflect.c
src/native/vm/reflect.h
src/native/vm/sun/Makefile.am
src/native/vm/sun/hpi.c [new file with mode: 0644]
src/native/vm/sun/hpi.h [new file with mode: 0644]
src/native/vm/sun/jvm.c
src/native/vm/sun_misc_Unsafe.c
src/threads/Makefile.am
src/threads/critical.h
src/threads/lock-common.h
src/threads/mutex.h [new file with mode: 0644]
src/threads/native/Makefile.am [deleted file]
src/threads/native/generic-primitives.h [deleted file]
src/threads/native/lock.c [deleted file]
src/threads/native/lock.h [deleted file]
src/threads/native/threads.c [deleted file]
src/threads/native/threads.h [deleted file]
src/threads/none/Makefile.am
src/threads/none/thread-none.c [new file with mode: 0644]
src/threads/none/thread-none.h [new file with mode: 0644]
src/threads/none/threads.h [deleted file]
src/threads/posix/Makefile.am [new file with mode: 0644]
src/threads/posix/generic-primitives.h [new file with mode: 0644]
src/threads/posix/lock.c [new file with mode: 0644]
src/threads/posix/lock.h [new file with mode: 0644]
src/threads/posix/mutex-posix.h [new file with mode: 0644]
src/threads/posix/thread-posix.c [new file with mode: 0644]
src/threads/posix/thread-posix.h [new file with mode: 0644]
src/threads/thread.c [new file with mode: 0644]
src/threads/thread.h [new file with mode: 0644]
src/threads/threadlist.c [new file with mode: 0644]
src/threads/threadlist.h [new file with mode: 0644]
src/threads/threads-common.c [deleted file]
src/threads/threads-common.h [deleted file]
src/toolbox/Makefile.am
src/toolbox/bitvector.h
src/toolbox/list.c
src/toolbox/list.h
src/toolbox/logging.c
src/toolbox/set.c [new file with mode: 0644]
src/toolbox/set.h [new file with mode: 0644]
src/vm/access.c
src/vm/access.h
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/exceptions.c
src/vm/exceptions.h
src/vm/finalizer.c
src/vm/global.h
src/vm/initialize.c
src/vm/initialize.h
src/vm/jit/Makefile.am
src/vm/jit/abi.h
src/vm/jit/allocator/liveness.c
src/vm/jit/allocator/lsra.c
src/vm/jit/allocator/lsra.h
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/linux/md-os.c
src/vm/jit/alpha/machine-instr.h
src/vm/jit/alpha/md-abi.c
src/vm/jit/alpha/md-trap.h [new file with mode: 0644]
src/vm/jit/alpha/md.c
src/vm/jit/alpha/patcher.c
src/vm/jit/arm/Makefile.am
src/vm/jit/arm/asmpart.S
src/vm/jit/arm/codegen.c
src/vm/jit/arm/codegen.h
src/vm/jit/arm/emit.c
src/vm/jit/arm/linux/md-os.c
src/vm/jit/arm/machine-instr.h
src/vm/jit/arm/md-abi.c
src/vm/jit/arm/md-trap.h [new file with mode: 0644]
src/vm/jit/arm/md.c
src/vm/jit/arm/patcher.c
src/vm/jit/cfg.c
src/vm/jit/cfg.h
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/emit-common.c
src/vm/jit/exceptiontable.c
src/vm/jit/exceptiontable.h
src/vm/jit/executionstate.c [new file with mode: 0644]
src/vm/jit/executionstate.h [new file with mode: 0644]
src/vm/jit/i386/Makefile.am
src/vm/jit/i386/asmpart.S
src/vm/jit/i386/codegen.c
src/vm/jit/i386/cygwin/md-asm.h
src/vm/jit/i386/darwin/md-asm.h
src/vm/jit/i386/darwin/md-os.c
src/vm/jit/i386/emit.c
src/vm/jit/i386/linux/md-os.c
src/vm/jit/i386/machine-instr.h
src/vm/jit/i386/md-abi.c
src/vm/jit/i386/md-trap.h [new file with mode: 0644]
src/vm/jit/i386/md.h
src/vm/jit/i386/patcher.c
src/vm/jit/inline/inline.c
src/vm/jit/inline/inline_debug.inc
src/vm/jit/intrp/Makefile.am
src/vm/jit/intrp/asmpart.c
src/vm/jit/intrp/codegen.c
src/vm/jit/intrp/disass.c
src/vm/jit/intrp/dynamic-super.c
src/vm/jit/intrp/engine.c
src/vm/jit/intrp/patcher.c
src/vm/jit/ir/Makefile.am [new file with mode: 0644]
src/vm/jit/ir/bytecode.c [new file with mode: 0644]
src/vm/jit/ir/bytecode.h [new file with mode: 0644]
src/vm/jit/jit.c
src/vm/jit/jit.h
src/vm/jit/linenumbertable.c
src/vm/jit/linenumbertable.h
src/vm/jit/loop/analyze.c
src/vm/jit/m68k/Makefile.am
src/vm/jit/m68k/arch.h
src/vm/jit/m68k/asmpart.S
src/vm/jit/m68k/codegen.c
src/vm/jit/m68k/codegen.h
src/vm/jit/m68k/emit.c
src/vm/jit/m68k/linux/Makefile.am
src/vm/jit/m68k/linux/md-abi.c
src/vm/jit/m68k/linux/md-os.c
src/vm/jit/m68k/linux/md-os.h [deleted file]
src/vm/jit/m68k/machine-instr.h
src/vm/jit/m68k/md-trap.h [new file with mode: 0644]
src/vm/jit/m68k/md.c
src/vm/jit/m68k/md.h
src/vm/jit/m68k/patcher.c
src/vm/jit/methodtree.c [new file with mode: 0644]
src/vm/jit/methodtree.h [new file with mode: 0644]
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/linux/md-os.c
src/vm/jit/mips/machine-instr.h
src/vm/jit/mips/md-abi.c
src/vm/jit/mips/md-trap.h [new file with mode: 0644]
src/vm/jit/mips/patcher.c
src/vm/jit/optimizing/Makefile.am
src/vm/jit/optimizing/dominators.c
src/vm/jit/optimizing/dominators.h
src/vm/jit/optimizing/graph.c
src/vm/jit/optimizing/lifetimes.c
src/vm/jit/optimizing/lifetimes.h
src/vm/jit/optimizing/lsra.c
src/vm/jit/optimizing/lsra.h
src/vm/jit/optimizing/profile.c
src/vm/jit/optimizing/recompile.c
src/vm/jit/optimizing/ssa.c
src/vm/jit/optimizing/ssa.h
src/vm/jit/optimizing/ssa2.c [new file with mode: 0644]
src/vm/jit/optimizing/ssa3.c [new file with mode: 0644]
src/vm/jit/optimizing/ssa_phi.c [new file with mode: 0644]
src/vm/jit/optimizing/ssa_phi.h [new file with mode: 0644]
src/vm/jit/optimizing/ssa_rename.c [new file with mode: 0644]
src/vm/jit/optimizing/ssa_rename.h [new file with mode: 0644]
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/codegen.c
src/vm/jit/powerpc/codegen.h
src/vm/jit/powerpc/darwin/md-abi.c
src/vm/jit/powerpc/darwin/md-os.c
src/vm/jit/powerpc/disass.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
src/vm/jit/powerpc/md-trap.h [new file with mode: 0644]
src/vm/jit/powerpc/netbsd/md-abi.c
src/vm/jit/powerpc/patcher.c
src/vm/jit/powerpc64/Makefile.am
src/vm/jit/powerpc64/arch.h
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
src/vm/jit/powerpc64/md-trap.h [new file with mode: 0644]
src/vm/jit/powerpc64/md.c
src/vm/jit/powerpc64/patcher.c
src/vm/jit/python.c [new file with mode: 0644]
src/vm/jit/python.h [new file with mode: 0644]
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/arch.h
src/vm/jit/s390/asmpart.S
src/vm/jit/s390/codegen.c
src/vm/jit/s390/emit.c
src/vm/jit/s390/machine-instr.h
src/vm/jit/s390/md-abi.c
src/vm/jit/s390/md-trap.h [new file with mode: 0644]
src/vm/jit/s390/md.c
src/vm/jit/s390/md.h
src/vm/jit/s390/patcher.c
src/vm/jit/show.c
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
src/vm/jit/sparc64/md-abi.c
src/vm/jit/sparc64/md-trap.h [new file with mode: 0644]
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
src/vm/jit/stacktrace.h
src/vm/jit/trace.c
src/vm/jit/trap.c [new file with mode: 0644]
src/vm/jit/trap.h [new file with mode: 0644]
src/vm/jit/verify/icmds.c
src/vm/jit/verify/typecheck-builtins.inc
src/vm/jit/verify/typecheck-common.c
src/vm/jit/verify/typecheck-common.h
src/vm/jit/verify/typecheck-fields.inc
src/vm/jit/verify/typecheck-invoke.inc
src/vm/jit/verify/typecheck-stackbased-gen.inc
src/vm/jit/verify/typecheck-stackbased.c
src/vm/jit/verify/typecheck-typeinferer-gen.inc
src/vm/jit/verify/typecheck-variablesbased-gen.inc
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
src/vm/jit/x86_64/md-abi.c
src/vm/jit/x86_64/md-trap.h [new file with mode: 0644]
src/vm/jit/x86_64/md.h
src/vm/jit/x86_64/patcher.c
src/vm/jit_interface.h
src/vm/package.c
src/vm/primitive.c
src/vm/properties.c
src/vm/resolve.c
src/vm/resolve.h
src/vm/signal.c
src/vm/signallocal.h
src/vm/string.c
src/vm/stringlocal.h
src/vm/vm.c
src/vm/vm.h
src/vmcore/annotation.c
src/vmcore/class.c
src/vmcore/class.h
src/vmcore/classcache.c
src/vmcore/classcache.h
src/vmcore/descriptor.c
src/vmcore/field.c
src/vmcore/field.h
src/vmcore/linker.c
src/vmcore/linker.h
src/vmcore/loader.c
src/vmcore/loader.h
src/vmcore/method.c
src/vmcore/method.h
src/vmcore/options.c
src/vmcore/options.h
src/vmcore/primitivecore.c
src/vmcore/references.h
src/vmcore/stackmap.c
src/vmcore/suck.c
src/vmcore/system.c
src/vmcore/system.h
src/vmcore/utf8.c
src/vmcore/utf8.h
src/vmcore/zip.c
tests/A2.java [deleted file]
tests/AA.java [deleted file]
tests/AA1.java [deleted file]
tests/AA2.java [deleted file]
tests/BB.java [deleted file]
tests/C.java [deleted file]
tests/C2.java [deleted file]
tests/C3.java [deleted file]
tests/CC.java [deleted file]
tests/D.java [deleted file]
tests/DD.java [deleted file]
tests/EE.java [deleted file]
tests/GG.java [deleted file]
tests/HI2.java [deleted file]
tests/II.java [deleted file]
tests/IIAA.java [deleted file]
tests/IIBB.java [deleted file]
tests/IICC.java [deleted file]
tests/IIexample.java [deleted file]
tests/Makefile.am
tests/n.java [deleted file]
tests/regression/HelloWorld.java [deleted file]
tests/regression/Makefile.am
tests/regression/TestAnnotations.java
tests/regression/assertion/Makefile.am [new file with mode: 0644]
tests/regression/assertion/Test.sh [new file with mode: 0644]
tests/regression/assertion/disabled.output [new file with mode: 0644]
tests/regression/assertion/enabled.output [new file with mode: 0644]
tests/regression/assertion/packagetest/testassertions.java [new file with mode: 0644]
tests/regression/assertion/testassertions.java [new file with mode: 0644]
tests/regression/bugzilla/All.java [new file with mode: 0644]
tests/regression/bugzilla/Makefile.am [new file with mode: 0644]
tests/regression/bugzilla/PR52.java [new file with mode: 0644]
tests/regression/bugzilla/PR57.java [new file with mode: 0644]
tests/regression/bugzilla/PR58.java [new file with mode: 0644]
tests/regression/bugzilla/PR65.java [new file with mode: 0644]
tests/regression/clinitexception.2output [deleted file]
tests/regression/clinitexception.java [deleted file]
tests/regression/codepatching/Makefile.am [deleted file]
tests/regression/codepatching/aastoreconstClass.java [deleted file]
tests/regression/codepatching/checkcastC.java [deleted file]
tests/regression/codepatching/checkcastI.java [deleted file]
tests/regression/codepatching/getfieldD.java [deleted file]
tests/regression/codepatching/getfieldF.java [deleted file]
tests/regression/codepatching/getfieldI.java [deleted file]
tests/regression/codepatching/getfieldJ.java [deleted file]
tests/regression/codepatching/getfieldL.java [deleted file]
tests/regression/codepatching/getstaticD.java [deleted file]
tests/regression/codepatching/getstaticF.java [deleted file]
tests/regression/codepatching/getstaticI.java [deleted file]
tests/regression/codepatching/getstaticJ.java [deleted file]
tests/regression/codepatching/getstaticL.java [deleted file]
tests/regression/codepatching/instanceofC.java [deleted file]
tests/regression/codepatching/instanceofI.java [deleted file]
tests/regression/codepatching/invokespecial.java [deleted file]
tests/regression/codepatching/invokestatic.java [deleted file]
tests/regression/codepatching/multianewarray.java [deleted file]
tests/regression/codepatching/newarray.java [deleted file]
tests/regression/codepatching/putfieldD.java [deleted file]
tests/regression/codepatching/putfieldF.java [deleted file]
tests/regression/codepatching/putfieldI.java [deleted file]
tests/regression/codepatching/putfieldJ.java [deleted file]
tests/regression/codepatching/putfieldL.java [deleted file]
tests/regression/codepatching/putfieldconstC.java [deleted file]
tests/regression/codepatching/putfieldconstD.java [deleted file]
tests/regression/codepatching/putfieldconstF.java [deleted file]
tests/regression/codepatching/putfieldconstI.java [deleted file]
tests/regression/codepatching/putfieldconstJ.java [deleted file]
tests/regression/codepatching/putfieldconstL.java [deleted file]
tests/regression/codepatching/putstaticD.java [deleted file]
tests/regression/codepatching/putstaticF.java [deleted file]
tests/regression/codepatching/putstaticI.java [deleted file]
tests/regression/codepatching/putstaticJ.java [deleted file]
tests/regression/codepatching/putstaticL.java [deleted file]
tests/regression/codepatching/putstaticconstC.java [deleted file]
tests/regression/codepatching/putstaticconstD.java [deleted file]
tests/regression/codepatching/putstaticconstF.java [deleted file]
tests/regression/codepatching/putstaticconstI.java [deleted file]
tests/regression/codepatching/putstaticconstJ.java [deleted file]
tests/regression/codepatching/putstaticconstL.java [deleted file]
tests/regression/codepatching/test.java [deleted file]
tests/regression/jasmin/Makefile.am
tests/regression/jasmin/runtest
tests/regression/jasmin/test_load_store_conflict_different_types.j [new file with mode: 0644]
tests/regression/jasmin/test_verify_fail_jsr_multiple_returns.j [deleted file]
tests/regression/jasmin/test_verify_fail_jsr_multiple_returns.j-no [new file with mode: 0644]
tests/regression/jasmin/test_verify_fail_jsr_recursion.j [deleted file]
tests/regression/jasmin/test_verify_fail_jsr_recursion.j-no [new file with mode: 0644]
tests/regression/jasmin/test_verify_fail_jsr_recursion_terminates.j [deleted file]
tests/regression/jasmin/test_verify_fail_jsr_recursion_terminates.j-no [new file with mode: 0644]
tests/regression/junit/All.java [new file with mode: 0644]
tests/regression/junit/Makefile.am [new file with mode: 0644]
tests/regression/junit/TestExceptionInStaticClassInitializer.java [new file with mode: 0644]
tests/regression/junit/TestPatcher.java [new file with mode: 0644]
tests/regression/native/Makefile.am
tests/regression/resolving/Makefile.am
tests/regression/resolving/TestController.java
tests/regression/resolving/test_instance_subtype_violated.java
tests/regression/resolving/test_param_loading_constraint_violated.java
tests/regression/resolving/test_param_loading_constraint_violated_derived.java
tests/regression/resolving/test_param_subtype_violated.java
tests/regression/resolving/test_return_subtype_ok.java
tests/regression/resolving/test_return_subtype_violated.java
tests/regression/resolving/test_retval_loading_constraint_violated.java
tests/regression/resolving/test_simple_lazy_load.java
tests/scribble.java [deleted file]
tests/threads/threadInterrupt.java [new file with mode: 0644]
tests/threads/waitAndInterrupt.java [new file with mode: 0644]
tests/weakref.java [new file with mode: 0644]

index df61478144eba52905f8c47c5a5546971027ba15..3155a5228c6930e2060ba0412a968318162bd090 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -6,6 +6,12 @@ syntax: glob
 *.lo
 *.a
 *.o
+*.aux
+*.ids
+*.idx
+*.log
+*.out
+*.toc
 Makefile
 Makefile.in
 TAGS
@@ -27,16 +33,26 @@ ltmain.sh
 missing
 contrib/setenvinstalled
 contrib/setenvsource
+doc/doxygen/html
+doc/doxygen/latex
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
 src/cacao/cacao
 src/cacaoh/cacaoh
-src/lib/classes/
-src/lib/vm.zip
+src/classes/classes/
+src/classes/vm.zip
 src/native/include/*.h
 src/scripts/java
 tests/*.class
 tests/regression/*.class
-tests/regression/codepatching/*.class
+tests/regression/assertion/*.class
+tests/regression/assertion/packagetest/*.class
+tests/regression/bugzilla/*.class
 tests/regression/jasmin/*.class
+tests/regression/junit/*.class
 tests/regression/native/*.class
 tests/regression/native/*.h
 tests/regression/native/*.so
@@ -44,3 +60,4 @@ tests/regression/resolving/*.class
 tests/regression/resolving/classes1/*.class
 tests/regression/resolving/classes2/*.class
 tests/regression/resolving/classes3/*.class
+tests/threads/*.class
index e3acb1c61ad1668e5f1ed9dc642ebce805767b99..e451bb5a5888a841377bb2dbcfd5c6fb3d460bbb 100644 (file)
@@ -1,9 +1,7 @@
 ## Makefile.am
 ##
-## 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.
 ##
 ## along with this program; if not, write to the Free Software
 ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 ## 02111-1307, USA.
-##
-## Contact: cacao@cacaojvm.org
-##
-## Authors: Christian Thalinger
-##
-## Changes:
 
 
 ACLOCAL_AMFLAGS = -I m4
diff --git a/NEWS b/NEWS
index 137b44178a7537a14368a3e9d0991abf6705d597..973a7bd67f277fc43049111cbb335101a82995e0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-New in release 0.99 (August x, 2007)
+New in release 0.99 (March x, 2008)
 
   * Initial support to use OpenJDK as Java core library.
   * Fixed memory leak in Boehm-GC.
@@ -7,6 +7,12 @@ New in release 0.99 (August x, 2007)
   * Removed genoffsets, cross-compilation is now much easier.
   * Implemented Class.isAnonymousClass(), isLocalClass() and
     isMemberClass() for GNU Classpath.
+  * Annotation support.
+  * Assertion support.
+  * Linenumber table code rewritten.
+  * Exception table code rewritten.
+  * Replaced --with-classpath-includedir with --with-jni_h and
+    --with-jni_md_h to better support OpenJDK/IcedTea build.s
 
 
 New in release 0.98 (June 6, 2007)
index 58160c6f57b30c6e49d0ee1759d82917a7edde96..1c6c633c87997a93f81cd87d36be0ff21aa67ddc 100755 (executable)
@@ -9,7 +9,7 @@ for CACAO_LIBTOOLIZE in libtoolize libtoolize15 glibtoolize; do
         CACAO_LIBTOOLIZE_VERSION=`${CACAO_LIBTOOLIZE} --version | sed 's/^.*[^0-9.]\([0-9]\{1,\}\.[0-9.]\{1,\}\).*/\1/'`
 #        echo ${CACAO_LIBTOOLIZE_VERSION}
         case ${CACAO_LIBTOOLIZE_VERSION} in
-            1.5* )
+            1.5* | 2.* )
                 CACAO_HAVE_LIBTOOLIZE=true
                 break;
                 ;;
@@ -19,7 +19,7 @@ done
 
 if test ${CACAO_HAVE_LIBTOOLIZE} = false; then
     echo "No proper libtoolize was found."
-    echo "You must have libtool 1.5 installed."
+    echo "You must have libtool 1.5 or later installed."
     exit 1
 fi
 
index e3d14074a25d8fc61de8d186c74c02f469f33041..2fe112d523ca10280aa83f6f83c4d5d0478037b6 100644 (file)
@@ -1,9 +1,7 @@
 dnl configure.ac
 dnl
-dnl Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-dnl C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-dnl E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-dnl J. Wenninger, Institut f. Computersprachen - TU Wien
+dnl Copyright (C) 1996-2005, 2006, 2007, 2008
+dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 dnl 
 dnl This file is part of CACAO.
 dnl 
@@ -25,7 +23,7 @@ dnl 02110-1301, USA.
 dnl Process this file with autoconf to produce a configure script.
 
 
-AC_INIT(cacao, 0.98+svn, cacao@cacaojvm.org)
+AC_INIT(cacao, 0.99rc3, cacao@cacaojvm.org)
 AC_CONFIG_SRCDIR(src/cacao/cacao.c)
 AC_CANONICAL_HOST
 AC_PREREQ(2.59)
@@ -197,12 +195,6 @@ CFLAGS="$ARCH_CFLAGS $OPT_CFLAGS"
 dnl set interpreter flags
 AC_SUBST(INTRP_CFLAGS)
 
-dnl define some stuff required for --fullversion
-AC_DEFINE_UNQUOTED(VERSION_CONFIGURE_ARGS, "$ac_configure_args", [configure arguments])
-AC_DEFINE_UNQUOTED(VERSION_CC, "$CC", [CC used])
-AC_DEFINE_UNQUOTED(VERSION_CFLAGS, "$OPT_CFLAGS $ARCH_CFLAGS", [CFLAGS used])
-
-
 dnl define and substitute some architecture specific variables
 AC_DEFINE_UNQUOTED([ARCH_DIR], "${ARCH_DIR}", [architecture directory])
 AC_DEFINE_UNQUOTED([JAVA_ARCH], "${JAVA_ARCH}", [Java architecture name])
@@ -231,6 +223,8 @@ AC_CHECK_HEADERS([errno.h])
 AC_CHECK_HEADERS([fcntl.h])
 AC_CHECK_HEADERS([libgen.h])
 AC_CHECK_HEADERS([netdb.h])
+AC_CHECK_HEADERS([stdint.h])
+AC_CHECK_HEADERS([stdio.h])
 AC_CHECK_HEADERS([stdlib.h])
 AC_CHECK_HEADERS([string.h])
 AC_CHECK_HEADERS([time.h])
@@ -246,7 +240,6 @@ AC_CHECK_HEADERS([sys/time.h])
 AC_CHECK_HEADERS([sys/types.h])
 
 dnl this is for fdlibm
-AC_CHECK_HEADERS([stdint.h])
 AC_CHECK_HEADERS([inttypes.h])
 AC_CHECK_HEADERS([sys/config.h])
 AC_CHECK_HEADERS([sys/types.h])
@@ -275,6 +268,7 @@ AC_FUNC_MEMCMP
 AC_FUNC_MMAP
 
 dnl keep them alpha-sorted!
+AC_CHECK_FUNCS([abort])
 AC_CHECK_FUNCS([accept])
 AC_CHECK_FUNCS([access])
 AC_CHECK_FUNCS([atoi])
@@ -284,9 +278,11 @@ AC_CHECK_FUNCS([close])
 AC_CHECK_FUNCS([confstr])
 AC_CHECK_FUNCS([connect])
 AC_CHECK_FUNCS([dirname])
+AC_CHECK_FUNCS([fclose])
 AC_CHECK_FUNCS([fflush])
 AC_CHECK_FUNCS([fopen])
 AC_CHECK_FUNCS([fprintf])
+AC_CHECK_FUNCS([fread])
 AC_CHECK_FUNCS([free])
 AC_CHECK_FUNCS([fstat])
 AC_CHECK_FUNCS([fsync])
@@ -312,6 +308,7 @@ AC_CHECK_FUNCS([memset])
 AC_CHECK_FUNCS([mmap])
 AC_CHECK_FUNCS([mprotect])
 AC_CHECK_FUNCS([open])
+AC_CHECK_FUNCS([read])
 AC_CHECK_FUNCS([readlink])
 AC_CHECK_FUNCS([realloc])
 AC_CHECK_FUNCS([recv])
@@ -321,12 +318,17 @@ AC_CHECK_FUNCS([send])
 AC_CHECK_FUNCS([setsockopt])
 AC_CHECK_FUNCS([shutdown])
 AC_CHECK_FUNCS([socket])
+AC_CHECK_FUNCS([stat])
+AC_CHECK_FUNCS([strcat])
 AC_CHECK_FUNCS([strchr])
+AC_CHECK_FUNCS([strcpy])
 AC_CHECK_FUNCS([strdup])
 AC_CHECK_FUNCS([strerror])
+AC_CHECK_FUNCS([strlen])
 AC_CHECK_FUNCS([strncmp])
 AC_CHECK_FUNCS([strstr])
 AC_CHECK_FUNCS([time])
+AC_CHECK_FUNCS([write])
 
 
 dnl Checks for libraries.
@@ -500,7 +502,7 @@ fi
 dnl check for verifier
 AC_MSG_CHECKING(whether classfile verification should be enabled)
 AC_ARG_ENABLE([verifier],
-              [AS_HELP_STRING(--disable-verifier,disable classfile verification [[default=yes]])],
+              [AS_HELP_STRING(--disable-verifier,disable classfile verification [[default=enabled]])],
               [case "${enableval}" in
                    no) ENABLE_VERIFIER=no;;
                    *) ENABLE_VERIFIER=yes;;
@@ -571,7 +573,7 @@ AC_CHECK_ENABLE_THREADS
 dnl check if if-conversion should be supported
 AC_MSG_CHECKING(whether if-conversion should be supported)
 AC_ARG_ENABLE([ifconv],
-              [AS_HELP_STRING(--disable-ifconv,disable if-conversion [[default=yes]])],
+              [AS_HELP_STRING(--disable-ifconv,disable if-conversion [[default=enabled]])],
               [case "${enableval}" in
                    no) ENABLE_IFCONV=no;;
                    *) ENABLE_IFCONV=yes;;
@@ -656,7 +658,7 @@ fi
 dnl check if linear scan register allocator(lsra) with SSA should be used
 AC_MSG_CHECKING(whether lsra with ssa should be supported)
 AC_ARG_ENABLE([ssa],
-              [AS_HELP_STRING(--disable-ssa,disable ssa [[default=no]])],
+              [AS_HELP_STRING(--disable-ssa,disable ssa [[default=disabled]])],
               [case "${enableval}" in
                    no) ENABLE_SSA=no;;
                    *) ENABLE_SSA=yes;;
@@ -763,12 +765,31 @@ AC_SUBST(CACAO_VM_ZIP)
 
 AC_CHECK_WITH_CACAOH
 AC_CHECK_WITH_CLASSPATH
+
+dnl Now we check for jre-layout so we can skip some checks that are
+dnl not required.
+AC_CHECK_ENABLE_JRE_LAYOUT
+
 AC_CHECK_WITH_CLASSPATH_PREFIX
 AC_CHECK_WITH_CLASSPATH_CLASSES
-AC_CHECK_WITH_CLASSPATH_LIBDIR
-AC_CHECK_WITH_CLASSPATH_INCLUDEDIR
-AC_CHECK_WITH_JRE_LAYOUT
 
+if test x"${ENABLE_JRE_LAYOUT}" = "xno"; then
+   AC_CHECK_WITH_CLASSPATH_LIBDIR
+fi
+
+dnl The check for jni_md.h must be before jni.h.
+AC_CHECK_WITH_JNI_MD_H
+AC_CHECK_WITH_JNI_H
+
+dnl HPI is only required for OpenJDK
+case "${WITH_CLASSPATH}" in
+    sun)
+        AC_CHECK_WITH_HPI_MD_H
+        AC_CHECK_WITH_HPI_H
+        ;;
+    *)
+        ;;
+esac
 
 dnl check for some programs we need
 
@@ -800,10 +821,28 @@ AC_CHECK_HEADERS(
        ]
 )
 
+dnl python
+
+AZ_PYTHON_DEFAULT
+AZ_PYTHON_ENABLE
+AZ_PYTHON_WITH
+AZ_PYTHON_VERSION_ENSURE( [2.4] )
+AZ_PYTHON_CSPEC
+AZ_PYTHON_LSPEC
+
+
+dnl define some stuff required for --fullversion
+AC_DEFINE_UNQUOTED(VERSION_CONFIGURE_ARGS, "$ac_configure_args", [configure arguments])
+AC_DEFINE_UNQUOTED(VERSION_CC, "$CC", [CC used])
+AC_DEFINE_UNQUOTED(VERSION_CFLAGS, "$OPT_CFLAGS $ARCH_CFLAGS $CPPFLAGS", [CFLAGS used])
+
+
 dnl finally pass CFLAGS to Makefiles via AM_CFLAGS
-CFLAGS=$OPT_CFLAGS
+CFLAGS="$OPT_CFLAGS"
 AM_CFLAGS=$ARCH_CFLAGS
+AM_CPPFLAGS="$CPPFLAGS"
 AC_SUBST(AM_CFLAGS)
+AC_SUBST(AM_CPPFLAGS)
 
 
 AC_CONFIG_FILES([Makefile]
@@ -813,13 +852,14 @@ AC_CONFIG_FILES([Makefile]
                [contrib/vmlog/Makefile]
                [contrib/vmlog/t/Makefile]
                [doc/Makefile]
+               [doc/doxygen/Makefile]
                [doc/handbook/Makefile]
                [man/Makefile]
                [src/Makefile]
                [src/cacao/Makefile]
                [src/cacaoh/Makefile]
+               [src/classes/Makefile]
                [src/fdlibm/Makefile]
-               [src/lib/Makefile]
                [src/mm/Makefile]
                [src/mm/cacao-gc/Makefile]
                [src/native/Makefile]
@@ -832,8 +872,8 @@ AC_CONFIG_FILES([Makefile]
                [src/scripts/Makefile]
                [src/scripts/java]
                [src/threads/Makefile]
-               [src/threads/native/Makefile]
                [src/threads/none/Makefile]
+               [src/threads/posix/Makefile]
                [src/toolbox/Makefile]
                [src/vm/Makefile]
                [src/vm/jit/Makefile]
@@ -850,6 +890,7 @@ AC_CONFIG_FILES([Makefile]
                [src/vm/jit/i386/linux/Makefile]
                [src/vm/jit/intrp/Makefile]
                [src/vm/jit/inline/Makefile]
+               [src/vm/jit/ir/Makefile]
                [src/vm/jit/loop/Makefile]
                [src/vm/jit/m68k/Makefile]
                [src/vm/jit/m68k/linux/Makefile]
@@ -878,8 +919,10 @@ AC_CONFIG_FILES([Makefile]
                [src/vmcore/Makefile]
                [tests/Makefile]
                [tests/regression/Makefile]
-               [tests/regression/codepatching/Makefile]
+               [tests/regression/bugzilla/Makefile]
+               [tests/regression/assertion/Makefile]
                [tests/regression/jasmin/Makefile]
+               [tests/regression/junit/Makefile]
                [tests/regression/native/Makefile]
                [tests/regression/resolving/Makefile]
                [tests/regression/resolving/classes1/Makefile]
index bc7f7372ade15eeffb22948ed8a163c4a8c85733..57803bd3abcf54f218d30329498d71a3eb02d316 100644 (file)
@@ -1,9 +1,7 @@
 ## contrib/Makefile.am
 ##
-## 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.
 ##
 ## 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
-##
-## Changes:
 
-## Process this file with automake to produce Makefile.in
 
 SUBDIRS = vmlog
 
index d9abeb3ac824e0beb70f78fece2a667c85b535d8..580d7cf6f69cf10a9e4f443d4b958a883402725e 100644 (file)
@@ -1,6 +1,6 @@
-# sets the environment variables when GNU classpath is installed, but
-# CACAO not
+# Sets the environment variables properly when GNU Classpath is
+# installed, but CACAO is not.
 
 export PATH=$PWD/src/cacao:$PATH
 export LD_LIBRARY_PATH=$PWD/src/cacao/.libs
-export BOOTCLASSPATH=$PWD/src/lib/vm.zip:@CLASSPATH_CLASSES@
+export BOOTCLASSPATH=$PWD/src/classes/vm.zip:@CLASSPATH_CLASSES@
index 4b9e4d9c638b6124e80bba3b943dbfe014c234ce..b260cb655672936726530d3e97da7ea9907543cd 100644 (file)
@@ -1,5 +1,5 @@
-# sets the environment variables when GNU classpath and CACAO are not
-# installed
+# Sets the environment variables properly when GNU Classpath and CACAO
+# are not installed.
 
 export PATH=$PWD/src/cacao:$PATH
 
@@ -14,4 +14,4 @@ $PWD/src/cacao/.libs:\
 @CLASSPATH_PREFIX@/native/jni/java-util/.libs:\
 $LD_LIBRARY_PATH
 
-export BOOTCLASSPATH=$PWD/src/lib/vm.zip:@CLASSPATH_CLASSES@
+export BOOTCLASSPATH=$PWD/src/classes/vm.zip:@CLASSPATH_CLASSES@
index 8cfa0bc8cce9e39b0d87836792725b137ee20408..d3f4d2f03f2bd132021b2dd2a1215ed8f5cc65b6 100644 (file)
@@ -1714,6 +1714,15 @@ vmlog_log_entry * vmlog_ringbuf_prev(vmlog_ringbuf *ring,int prefetch)
 
 /*** option parsing **************************************************/
 
+vmlog_options *vmlog_opt_new(void)
+{
+       vmlog_options *opts;
+
+       VMLOG_XZNEW(opts,vmlog_options);
+
+       return opts;
+}
+
 int vmlog_opt_parse_seq(const char *arg,int len,vmlog_seq_t *seq)
 {
        char *buf;
@@ -1768,6 +1777,21 @@ int vmlog_opt_parse_range(const char *arg,vmlog_seq_t *start,vmlog_seq_t *end)
        return 1;
 }
 
+void vmlog_opt_set_prefix(vmlog_options *opts, const char *arg)
+{
+       opts->prefix = vmlog_strdup(arg,strlen(arg));
+}
+
+void vmlog_opt_set_stringprefix(vmlog_options *opts, const char *arg)
+{
+       opts->stringprefix = vmlog_strdup(arg,strlen(arg));
+}
+
+void vmlog_opt_set_ignoreprefix(vmlog_options *opts, const char *arg)
+{
+       opts->ignoreprefix = vmlog_strdup(arg,strlen(arg));
+}
+
 static int vmlog_opt_parse_one_option(vmlog_options *opts, const char *arg, const char *nextarg)
 {
        int eat;
@@ -1782,19 +1806,19 @@ static int vmlog_opt_parse_one_option(vmlog_options *opts, const char *arg, cons
        if (strcmp(arg,"-vmlog:prefix") == 0) {
                if (!nextarg)
                        vmlog_die("expected a prefix after -vmlog:prefix");
-               opts->prefix = vmlog_strdup(nextarg,strlen(nextarg));
+               vmlog_opt_set_prefix(opts,nextarg);
                eat++;
        }
        else if (strcmp(arg,"-vmlog:strings") == 0) {
                if (!nextarg)
                        vmlog_die("expected a prefix after -vmlog:strings");
-               opts->stringprefix = vmlog_strdup(nextarg,strlen(nextarg));
+               vmlog_opt_set_stringprefix(opts,nextarg);
                eat++;
        }
        else if (strcmp(arg,"-vmlog:ignore") == 0) {
                if (!nextarg)
                        vmlog_die("expected a prefix after -vmlog:ignore");
-               opts->ignoreprefix = vmlog_strdup(nextarg,strlen(nextarg));
+               vmlog_opt_set_ignoreprefix(opts,nextarg);
                eat++;
        }
        else {
@@ -1814,7 +1838,7 @@ vmlog_options *vmlog_opt_parse_cmd_line(int *pargc,char **argv)
 
        assert(pargc);
 
-       VMLOG_XZNEW(opts,vmlog_options);
+       opts = vmlog_opt_new();
 
        if (*pargc && argv[0])
                opts->progname = vmlog_strdup(argv[0],strlen(argv[0]));
@@ -1851,7 +1875,7 @@ vmlog_options *vmlog_opt_parse_vmargs(JavaVMInitArgs *vmargs)
 
        assert(vmargs);
 
-       VMLOG_XZNEW(opts,vmlog_options);
+       opts = vmlog_opt_new();
 
        i = 0;
        while (i < vmargs->nOptions) {
index 478717eb7453ba3cb5925198df2d61e5966e8076..ee90081bb08fc5f6b7e565d42daa21cd679b8095 100644 (file)
@@ -257,6 +257,10 @@ vmlog_log_entry * vmlog_ringbuf_next(vmlog_ringbuf *ring,int prefetch);
 vmlog_log_entry * vmlog_ringbuf_prev(vmlog_ringbuf *ring,int prefetch);
 
 /* option parsing */
+vmlog_options *vmlog_opt_new(void);
+void vmlog_opt_set_prefix(vmlog_options *opts, const char *arg);
+void vmlog_opt_set_stringprefix(vmlog_options *opts, const char *arg);
+void vmlog_opt_set_ignoreprefix(vmlog_options *opts, const char *arg);
 int vmlog_opt_parse_seq(const char *arg,int len,vmlog_seq_t *seq);
 int vmlog_opt_parse_range(const char *arg,vmlog_seq_t *start,vmlog_seq_t *end);
 vmlog_options *vmlog_opt_parse_cmd_line(int *pargc,char **argv);
index 04b9e8f251da5055ea31809985c62f329609843c..618153716c27f60875ea08ada493cd67504f14e2 100644 (file)
 /*** global variables ************************************************/
 
 static vmlog_log *vmlog_global_log = NULL;
-static java_objectheader vmlog_global_lock;
+static java_object_t *vmlog_global_lock = NULL;
+static vmlog_options *vmlog_cacao_options = NULL;
 
 /*** locking *********************************************************/
 
-#define VMLOG_LOCK(vml)    lock_monitor_enter(&vmlog_global_lock)
-#define VMLOG_UNLOCK(vml)  lock_monitor_exit(&vmlog_global_lock)
+#define VMLOG_LOCK(vml)    lock_monitor_enter(vmlog_global_lock)
+#define VMLOG_UNLOCK(vml)  lock_monitor_exit(vmlog_global_lock)
 
 /*** include the vmlog code ******************************************/
 
@@ -39,33 +40,31 @@ static java_objectheader vmlog_global_lock;
 
 /*** internal functions **********************************************/
 
-void vmlog_cacao_init(JavaVMInitArgs *vmargs)
+void vmlog_cacao_init()
 {
-       vmlog_options *opts;
-
-       opts = vmlog_opt_parse_vmargs(vmargs);
-       
-       if (!opts->prefix)
+       if (!vmlog_cacao_options->prefix)
                return;
 
-       vmlog_global_log = vmlog_log_new(opts->prefix,1);
+       vmlog_global_log = vmlog_log_new(vmlog_cacao_options->prefix,1);
 
-       if (opts->ignoreprefix) {
+       if (vmlog_cacao_options->ignoreprefix) {
                vmlog_log_load_ignorelist(vmlog_global_log,
-                               opts->ignoreprefix);
+                               vmlog_cacao_options->ignoreprefix);
        }
 
-       if (opts->stringprefix) {
+       if (vmlog_cacao_options->stringprefix) {
                vmlog_load_stringhash(vmlog_global_log,
-                               opts->stringprefix);
+                               vmlog_cacao_options->stringprefix);
        }
 
-       vmlog_opt_free(opts);
+       vmlog_opt_free(vmlog_cacao_options);
+       vmlog_cacao_options = NULL;
 }
 
 void vmlog_cacao_init_lock(void)
 {
-       lock_init_object_lock(&vmlog_global_lock);
+       vmlog_global_lock = NEW(java_object_t);
+       lock_init_object_lock(vmlog_global_lock);
 }
 
 static void vmlog_cacao_do_log(vmlog_log_function fun,
@@ -73,13 +72,24 @@ static void vmlog_cacao_do_log(vmlog_log_function fun,
 {
        char *name;
        int namelen;
+       char *cname;
+       int cnamelen;
 
        assert(m);
 
        if (!vmlog_global_log)
                return;
 
-       name = vmlog_concat4len(m->class->name->text,m->class->name->blength,
+       if (m->class) {
+               cname = m->class->name->text;
+               cnamelen = m->class->name->blength;
+       }
+       else {
+               cname = "<NULL>";
+               cnamelen = 6;
+       }
+
+       name = vmlog_concat4len(cname,cnamelen,
                                ".",1,
                                m->name->text,m->name->blength,
                                m->descriptor->text,m->descriptor->blength,
@@ -117,7 +127,7 @@ void vmlog_cacao_unwnd_method(methodinfo *m)
        vmlog_cacao_do_log(vmlog_log_unwnd,m);
 }
 
-void vmlog_cacao_throw(java_objectheader *xptr)
+void vmlog_cacao_throw(java_object_t *xptr)
 {
        classinfo *c;
        
@@ -135,7 +145,7 @@ void vmlog_cacao_throw(java_objectheader *xptr)
        }
 }
 
-void vmlog_cacao_catch(java_objectheader *xptr)
+void vmlog_cacao_catch(java_object_t *xptr)
 {
        classinfo *c;
        
@@ -162,6 +172,39 @@ void vmlog_cacao_signl(const char *name)
                        name, strlen(name));
 }
 
+void vmlog_cacao_signl_type(int type)
+{
+       char message[20];
+
+       if (!vmlog_global_log)
+               return;
+
+       sprintf(message, "EXC %d", type);
+
+       vmlog_log_signl(vmlog_global_log,(void*) THREADOBJECT,
+                       message, strlen(message));
+}
+
+void vmlog_cacao_init_options(void)
+{
+       vmlog_cacao_options = vmlog_opt_new();
+}
+
+void vmlog_cacao_set_prefix(const char *arg)
+{
+       vmlog_opt_set_prefix(vmlog_cacao_options, arg);
+}
+
+void vmlog_cacao_set_stringprefix(const char *arg)
+{
+       vmlog_opt_set_stringprefix(vmlog_cacao_options, arg);
+}
+
+void vmlog_cacao_set_ignoreprefix(const char *arg)
+{
+       vmlog_opt_set_ignoreprefix(vmlog_cacao_options, arg);
+}
+
 /* vim: noet ts=8 sw=8
  */
 
index c67cca8c1562ba1e770fa8164f26a0f7645e6fb8..ebe1c85b8399e59ca3cb89ad28705db33d13dc7c 100644 (file)
 #ifndef _VMLOG_CACAO_H_
 #define _VMLOG_CACAO_H_
 
-#include <threads/native/threads.h>
+void vmlog_cacao_init_options(void);
 
-void vmlog_cacao_init(JavaVMInitArgs *vmargs);
+void vmlog_cacao_set_prefix(const char *arg);
+void vmlog_cacao_set_stringprefix(const char *arg);
+void vmlog_cacao_set_ignoreprefix(const char *arg);
+
+void vmlog_cacao_init(void);
 
 void vmlog_cacao_init_lock(void);
 
@@ -31,9 +35,10 @@ void vmlog_cacao_unwnd_method(methodinfo *m);
 void vmlog_cacao_unrol_method(methodinfo *m);
 void vmlog_cacao_rerol_method(methodinfo *m);
 
-void vmlog_cacao_throw(java_objectheader *xptr);
-void vmlog_cacao_catch(java_objectheader *xptr);
+void vmlog_cacao_throw(java_object_t *xptr);
+void vmlog_cacao_catch(java_object_t *xptr);
 void vmlog_cacao_signl(const char *name);
+void vmlog_cacao_signl_type(int type);
 
 #endif
 
index 327d68f77bbb1ab350296865db3eb1849cb35818..7e878e2b03b7795fe12f0dacb112a98337190284 100644 (file)
@@ -1,9 +1,7 @@
 ## doc/Makefile.am
 ##
-## 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.
 ##
 ## 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
-##
-## Changes:
 
-## Process this file with automake to produce Makefile.in
 
-SUBDIRS = handbook
+SUBDIRS = \
+       doxygen \
+       handbook
 
-dist_noinst_DATA = annotations.tex jsr.bib
+dist_noinst_DATA = \
+       assertions.tex \
+       annotations.tex \
+       jsr.bib
 
-EXTRA_DIST = inlining_stacktrace.txt native_threads.txt stack.txt
+EXTRA_DIST = \
+       inlining_stacktrace.txt \
+       native_threads.txt \
+       stack.txt
 
 CLEANFILES = \
        annotations.aux \
@@ -47,7 +46,11 @@ CLEANFILES = \
        annotations.toc \
        annotations.idx \
        annotations.out \
-       annotations.tex~
+       annotations.tex~ \
+       assertions.aux \
+       assertions.dvi \
+       assertions.log \
+       assertions.toc
 
 annotations:
        latex annotations
@@ -55,6 +58,10 @@ annotations:
        latex annotations
        latex annotations
 
+assertions:
+       latex assertions
+       latex assertions
+
 ## Local variables:
 ## mode: Makefile
 ## indent-tabs-mode: t
diff --git a/doc/assertions.tex b/doc/assertions.tex
new file mode 100644 (file)
index 0000000..4ee56ea
--- /dev/null
@@ -0,0 +1,418 @@
+\documentclass{article}%
+\usepackage{amsmath}
+\usepackage{amsfonts}
+\usepackage{amssymb}
+\usepackage{graphicx}
+\usepackage{listings}
+\lstloadlanguages{Java,C}
+\lstset{basicstyle=\scriptsize, numbers=left, tabsize=4, frame=none, breaklines=true}
+%-------------------------------------------
+\newtheorem{theorem}{Theorem}
+\newtheorem{acknowledgement}[theorem]{Acknowledgement}
+\newtheorem{algorithm}[theorem]{Algorithm}
+\newtheorem{axiom}[theorem]{Axiom}
+\newtheorem{case}[theorem]{Case}
+\newtheorem{claim}[theorem]{Claim}
+\newtheorem{conclusion}[theorem]{Conclusion}
+\newtheorem{condition}[theorem]{Condition}
+\newtheorem{conjecture}[theorem]{Conjecture}
+\newtheorem{corollary}[theorem]{Corollary}
+\newtheorem{criterion}[theorem]{Criterion}
+\newtheorem{definition}[theorem]{Definition}
+\newtheorem{example}[theorem]{Example}
+\newtheorem{exercise}[theorem]{Exercise}
+\newtheorem{lemma}[theorem]{Lemma}
+\newtheorem{notation}[theorem]{Notation}
+\newtheorem{problem}[theorem]{Problem}
+\newtheorem{proposition}[theorem]{Proposition}
+\newtheorem{remark}[theorem]{Remark}
+\newtheorem{solution}[theorem]{Solution}
+\newtheorem{summary}[theorem]{Summary}
+\newenvironment{proof}[1][Proof]{\textbf{#1.} }{\ \rule{0.5em}{0.5em}}
+
+\begin{document}
+
+\title{Assertion support \\for the CACAO Virtual Machine}
+\author{{Gregor Kaufmann}
+\\0247381 033 534
+\\gregor@complang.tuwien.ac.at}
+\date{January 1, 2008}
+\maketitle
+\pagebreak
+
+\tableofcontents
+\pagebreak
+
+
+\section{Introduction to assertions in Java}
+\subsection{General Introduction}
+The assertion keyword in Java allows to assert the correctness of assumptions made in a program. It was first introdcuded in JDK 1.2 (see JSR41\footnote{http://jcp.org/aboutJava/communityprocess/review/jsr041/publicDraft.html}). An assertion works on an expression, evaluating to a boolean type, that must be true during the execution of a program (or else the execution halts and an exception gets thrown). Short example: a function that calculates from celsius to kelvin. This function might use an assertion to assure that the calculated value is not below 0.
+
+An assertion statement comes in two forms:
+\begin{itemize}
+\item \verb'assert BooleanExpression ;'
+\item \verb'assert BooleanExpression : ValueExpression ;'
+\end{itemize}
+The "BooleanExpression" can be any java expression resulting in a boolean value. If this "BoolenExpression" evalutes to false an (unnamed) AssertionError gets thrown. The second form of the assertion statement is used to generate detailed error messages: the value of "ValueExpression" gets passed to the constructor of the thrown AssertionError exception, building a more detailed error message. An assertion statement is equal to: if (BooleanExpression == false) throw new AssertionError(ValueExpression); (without the possibility to easily turn on/off this code at runtime).
+Examples:
+\begin{itemize}
+\item \verb'assert val < 10;'
+\item \verb'assert val > 99: val;'
+\item \verb'assert isValid(val): val;'
+\item \verb'assert val.isEnabled(): val.getStatus();'
+\end{itemize}
+
+\pagebreak
+\subsection{Interpreter options}
+Assertions can be turned on or off at runtime (turned off by default). The following options for the interpreter are available (\verb'>'JDK1.2 and \verb'>'CACAO-0.98):
+\begin{itemize}
+\item \verb'-ea[:<packagename>...|:<classname>]'
+\item \verb'-enableassertions[:<packagename>...|:<classname>]'
+\item \verb'-da[:<packagename>...|:<classname>]'
+\item \verb'-disableassertions[:<packagename>...|:<classname>]'
+\item \verb'-esa | -enablesystemassertions'
+\item \verb'-dsa | -disablesystemassertions}' 
+\end{itemize}
+Detailed explanation of the available options:
+\begin{itemize}
+\item{\verb'-enableassertions/-ea' -- \tiny{Turns on assertions for all non-system/user classes}}
+\item{\verb'-disableassertions/-da' -- \tiny{Turns off assertions for all non-system/user classes}}
+\item{\verb'-enablesystemassertions/-esa' -- \tiny{Turns on assertions for all system/non-user classes}}
+\item{\verb'-disablesystemassertions/-dsa' -- \tiny{Turns off assertions for all system/non-user classes}}
+\item{\verb'-enableassertions/-ea:my.package...' -- \tiny{Turns on assertions for all classes in the "my.package" package (and all subpackages)}}
+\item{\verb'-disableassertions/-da:my.package...' -- \tiny{Turns off assertions for all classes in the "my.package" package (and all subpackages)}}
+\item{\verb'-enableassertions/-ea:Myclass' -- \tiny{Turns on assertions a class named "Myclass"}}
+\item{\verb'-disableassertions/-da:Myclass' -- \tiny{Turns off assertions a class named "Myclass"}}
+\end{itemize}
+Note 1: Specifing multiple class/package names is possible.
+\\
+\\
+Note 2: The assertion switches -ea/-da/-esa/-dsa are currently not implemented correctly in cacao+classpath (use cacao+openjdk or a patched classpath [see section \ref{see1}]).
+\pagebreak
+\subsection{Bytecode of an assertion statement} \label{bytecode}
+The following example shows how an assertion statement is translated into bytecode.
+\\
+\\
+I've compiled the following class with JDK-6.0 (other compilers produce slightly different bytecode).
+\begin{lstlisting}[language=Java]
+public class Test {
+    public static void main(String[] args) {
+        int x = 1;
+        assert x == 2 : x;
+    }
+}
+\end{lstlisting}
+The following bytecode gets produced:
+\\
+\begin{lstlisting}[language=Java]
+static {};
+  Code:
+   0:   ldc\_w   #5; //class Test
+   3:   invokevirtual   #6; //Method java/lang/Class.desiredAssertionStatus:()Z
+   6:   ifne    13
+   9:   iconst\_1
+   10:  goto    14
+   13:  iconst\_0
+   14:  putstatic       #2; //Field \$assertionsDisabled:Z
+   17:  return
+\end{lstlisting}
+A static block is used to iniatilizes the boolean variable describing the assertion status of the class "Test".
+The assertion status, as set by the user/vm for, gets loaded (lines 3,4), and saved into constant\_pool[2] (line 9).
+\\
+\begin{lstlisting}[language=Java]
+public static void main(java.lang.String[]);
+  Code:
+   0:   iconst\_1
+   1:   istore\_1
+   2:   getstatic       #2; //Field \$assertionsDisabled:Z
+   5:   ifne    22
+   8:   iload\_1
+   9:   iconst\_2
+   10:  if\_icmpeq       22
+   13:  new     #3; //class java/lang/AssertionError
+   16:  dup
+   17:  iload\_1
+   18:  invokespecial   #4; //Method java/lang/AssertionError."<init>":(I)V
+   21:  athrow
+   22:  return
+\end{lstlisting}
+The assertion status gets loaded from constant\_pool[2] (line 5), if assertions are disabled the function returns immediatly (lines 6,15). Otherwise, the assertion statement gets evaluated and an AssertionError exception gets thrown (lines 6-15).
+
+\pagebreak
+\section{Implementation of java assertions in CACAO}
+
+When I started working on the assertion support for cacao, a basic functionality to toggle assertions on and off was already implemented. It was possible to toggle assertions on and off at a systemwide level, but this only worked when cacao was used together with the GNU classpath classes. Because at least something was already implemented, I decided to start my work on cacao+classpath.
+\\
+\\
+Each class implements a method called desiredAssertionStatus that returns the desired assertion status of a class, see section \ref{bytecode} on how this is used by an assertion statement.
+\\
+\\
+The desiredAssertionStatus method in java.lang.Class of classpath looks like this:
+\begin{lstlisting}[language=Java,firstnumber=1216]
+  public boolean desiredAssertionStatus()
+  {
+    ClassLoader c = getClassLoader();
+    Object status;
+    if (c == null)
+      return VMClassLoader.defaultAssertionStatus();
+    if (c.classAssertionStatus != null)
+      synchronized (c)
+        {
+          status = c.classAssertionStatus.get(getName());
+          if (status != null)
+            return status.equals(Boolean.TRUE);
+        }
+    else
+      {
+        status = ClassLoader.StaticData.
+                    systemClassAssertionStatus.get(getName());
+        if (status != null)
+          return status.equals(Boolean.TRUE);
+      }
+    if (c.packageAssertionStatus != null)
+      synchronized (c)
+        {
+          String name = getPackagePortion(getName());
+          if ("".equals(name))
+            status = c.packageAssertionStatus.get(null);
+          else
+            do
+              {
+                status = c.packageAssertionStatus.get(name);
+                name = getPackagePortion(name);
+              }
+            while (! "".equals(name) && status == null);
+          if (status != null)
+            return status.equals(Boolean.TRUE);
+        }
+    else
+      {
+        String name = getPackagePortion(getName());
+        if ("".equals(name))
+          status = ClassLoader.StaticData.
+                    systemPackageAssertionStatus.get(null);
+        else
+          do
+            {
+              status = ClassLoader.StaticData.
+                        systemPackageAssertionStatus.get(name);
+              name = getPackagePortion(name);
+            }
+          while (! "".equals(name) && status == null);
+        if (status != null)
+          return status.equals(Boolean.TRUE);
+      }
+    return c.defaultAssertionStatus;
+  }
+\end{lstlisting}
+The ClassLoader class stores the global assertion status for user classes and the individual status for classes and packages:
+\begin{itemize}
+\item{\verb'boolean defaultAssertionStatus'}
+\item{\verb'Map<String, Boolean> systemPackageAssertionStatus'}
+\item{\verb'Map<String, Boolean> systemClassAssertionStatus'}
+\end{itemize}
+
+\noindent The VMClassLoader class is a special class that needs to implemented by virtual machines that use the classpath classes.
+The following methods are used by the ClassLoader to initialize the variables above (in the same order):
+\begin{itemize}
+\item{\verb'boolean defaultUserAssertionStatus()'}
+\item{\verb'Map<String, Boolean> packageAssertionStatus()'}
+\item{\verb'Map<String, Boolean> classAssertionStatus()'}
+\end{itemize}
+See: java.lang.Class\footnote{http://cvs.savannah.gnu.org/viewvc/classpath/java/lang/Class.java?revision=1.54\&root=classpath\&view=markup}, java.lang.ClassLoader\footnote{http://cvs.savannah.gnu.org/viewvc/classpath/java/lang/ClassLoader.java?revision=1.62\&root=classpath\&view=markup}, java.lang.VMClassLoader\footnote{http://cvs.savannah.gnu.org/viewvc/classpath/vm/reference/java/lang/VMClassLoader.java?revision=1.16.2.18\&root=classpath\&view=markup}
+\\
+\\
+What had to be done:
+\begin{itemize}
+\item{Implement the methods: defaultUserAssertionStatus, packageAssertionStatus, classAssertionStatus}
+\item{Write a function to parse the commandline options}
+\end{itemize}
+See: src/lib/gnu/java/lang/VMClassLoader.java (section \ref{see1}), src/native/vm/gnu/java\_lang\_VMClassLoader.c (section \ref{see2}), src/vm/assertion.c (section \ref{see3}) and src/vm/assertion.c (section \ref{see4})
+\\\\
+For cacao+openjdk I could reuse most of the code I wrote for cacao+classpath:
+\\\\
+The desiredAssertionStatus method in java.lang.Class of openjdk looks like this:
+\begin{lstlisting}[language=Java, firstnumber=2849]
+public boolean desiredAssertionStatus() {
+    ClassLoader loader = getClassLoader();
+    // If the loader is null this is a system class, so ask the VM
+    if (loader == null)
+        return desiredAssertionStatus0(this);
+
+    synchronized(loader) {
+        // If the classloader has been initialized with
+        // the assertion directives, ask it. Otherwise,
+        // ask the VM.
+        return (loader.classAssertionStatus == null ?
+                desiredAssertionStatus0(this) :
+                loader.desiredAssertionStatus(getName()));
+    }
+}
+
+\end{lstlisting}
+The native function called by desiredAssertionStatus0 is JVM\_DesiredAssertionStatus, and that's the only function that had to be implemented by me to make assertions work with cacao+openjdk. I've also corrected the implementation of the JVM\_AssertionStatusDirectives function, which is used by java.lang.ClassLoader.
+\\
+\\
+See: src/native/vm/sun/jvm.c (section \ref{see5})
+
+\pagebreak
+\section{Patch overview}
+\subsection{Changed/New files}
+\begin{itemize}
+\item{\verb'configure.ac'}
+\item{\verb'm4/assertion.m4'}
+\item{\verb'src/lib/gnu/java/lang/VMClassLoader.java'}
+\item{\verb'src/native/include/Makefile.am'}
+\item{\verb'src/native/jni.h'}
+\item{\verb'src/native/vm/gnu/java_lang_VMClassLoader.c'}
+\item{\verb'src/native/vm/sun/jvm.c'}
+\item{\verb'src/vm/Makefile.am'}
+\item{\verb'src/vm/assertion.c'}
+\item{\verb'src/vm/assertion.h'}
+\item{\verb'src/vm/vm.c'}
+\item{\verb'src/vmcore/class.c'}
+\item{\verb'src/vmcore/class.h'}
+\item{\verb'src/vmcore/linker.c'}
+\item{\verb'src/vmcore/loader.c'}
+\item{\verb'configure.ac'}
+\end{itemize}
+
+\subsection{configure.ac}
+Added configure option "--enable-assertion" (turned on by default).
+\\
+Most of the assertion code will be turned off if this switch is disabled.
+\\\\
+Actual configure logic is in m4/assertion.m4.
+
+\subsection{m4/assertion.m4}
+Added autoconf logic to enable/disable building of assertion support.
+
+\subsection{src/lib/gnu/java/lang/VMClassLoader.java}
+\label{see1}
+Replaced the dummy implementations of:
+\begin{itemize}
+\item{\verb'defaultAssertionStatus'}
+\item{\verb'packageAssertionStatus'}
+\item{\verb'classAssertionStatus'}
+\end{itemize}
+
+Added:
+\begin{itemize}
+\item{\verb'defaultUserAssertionStatus'}
+\end{itemize}
+
+\noindent This function returns the user assertion status. Due to incorrect handling of user/system assertion status in GNU classpath\footnote{http://www.gnu.org/software/classpath/}, enabling (default) system assertions will also enable assertions in all user classes (a patch\footnote{http://www.mail-archive.com/classpath-patches@gnu.org/msg10400/assertion\_cp.patch} to fix this behaviour was submitted in August 07).
+\\\\
+Actual implementations now call into native code to get status.
+
+\subsection{src/native/include/Makefile.am}
+Added:
+\begin{itemize}
+\item{\verb'java_util_HashMap.h'}
+\item{\verb'java_util_Map.h'}
+\end{itemize}
+\noindent Headers needed to allow construction of Map/HashMap in native code.
+
+\subsection{src/native/jni.h}
+Removed:
+\begin{itemize}
+\item{\verb'_Jv_JavaVM->Java_java_lang_VMClassLoader_defaultAssertionStatus'}
+\end{itemize}
+\noindent This variable was used to hold the system's assertion status and was replaced by assertion\_user\_enabled and assertion\_system\_enabled.
+
+\subsection{src/native/vm/gnu/java\_lang\_VMClassLoader.c}
+\label{see2}
+This file holds native implementations of the VMClassLoader for GNU classpath.
+\\\\
+The following functions were added/replaced:
+\begin{itemize}
+\item{\verb'Java_java_lang_VMClassLoader_defaultUserAssertionStatus'}
+\end{itemize}
+\noindent Native implementation of VMClassLoader.defaultUserAssertionStatus. This function returns the default user assertion status of the system (user\_assertion\_status). Returns false if ENABLE\_ASSERTION is not defined (--enable-assertions=no).
+\begin{itemize}
+\item{\verb'Java_java_lang_VMClassLoader_defaultAssertionStatus'}
+\end{itemize}
+\noindent Previous implemention was replaced. Native implementation of VMClassLoader.defaultAssertionStatus. This function returns the default assertion status of the system (system\_assertion\_status). Returns false if ENABLE\_ASSERTION is not defined (--enable-assertions=no).
+\begin{itemize}
+\item{\verb'Java_java_lang_VMClassLoader_packageAssertionStatus0'}
+\end{itemize}
+\noindent Native implementation of VMClassLoader.packageAssertionStatus. Builds and returns a HashMap containing key and value pairs of packagenames and their assertion status (as expected by the ClassLoader). Returns an empty HashMap if ENABLE\_ASSERTION is not defined (--enable-assertions=no).
+\begin{itemize}
+\item{\verb'Java_java_lang_VMClassLoader_classAssertionStatus0'}
+\end{itemize}
+\noindent Native implementation of VMClassLoader.classAssertionStatus. Builds and returns a HashMap containing key and value pairs of classnames and their assertion status (as expected by the ClassLoader). Returns an empty HashMap if ENABLE\_ASSERTION is not defined (--enable-assertions=no).
+
+\subsection{src/native/jni.h}
+Removed:
+\begin{itemize}
+\item{\verb'_Jv_JavaVM->Java_java_lang_VMClassLoader_defaultAssertionStatus'}
+\end{itemize}
+\noindent This variable was used to hold the system's assertion status and was replaced by assertion\_user\_enabled and assertion\_system\_enabled.
+
+\subsection{src/native/vm/sun/jvm.c}
+\label{see5}
+This file holds various native implementations needed by OpenJDK\footnote{http://openjdk.java.net/}.
+\\\\
+The following functions were added/replaced:
+\begin{itemize}
+\item{\verb'JVM_DesiredAssertionStatus'}
+\end{itemize}
+\noindent Dummy implementation was replaced. Returns the desired assertion status for a given class. Returns false if ENABLE\_ASSERTION is not defined (--enable-assertions=no).
+\begin{itemize}
+\item{\verb'JVM_AssertionStatusDirectives'}
+\end{itemize}
+\noindent Previous implementation was incomplete. Builds and returns an AssertionStatusDirectives object. This object contains the names of all packages and classes and their assertion status.
+
+\subsection{src/vm/Makefile.am}
+Added (optional) building of the assertion module (assertion.c/assertion.h). Will only be built if ENABLE\_ASSERTION is defined (--enable-assertions=yes).
+
+\subsection{src/vm/assertion.c}
+\label{see3}
+This file handles the various assertion commandline options (-ea/-da/-esa/-dsa).
+
+\subsection{src/vm/assertion.h}
+\label{see4}
+Defines the following global variables:
+\begin{lstlisting}[language=C,firstnumber=46]
+extern list\_t  *list\_assertion\_names;
+\end{lstlisting}
+This variable stores class/package names and their assertion status.
+\begin{lstlisting}[language=C,firstnumber=47]
+extern int32\_t  assertion\_class\_count;
+\end{lstlisting}
+This variable stores the amount of classnames specified on the commandline.
+\begin{lstlisting}[language=C,firstnumber=48]
+extern int32\_t  assertion\_package\_count;
+\end{lstlisting}
+This variable stores the amount of packagenames specified on the commandline.
+\begin{lstlisting}[language=C,firstnumber=49]
+extern bool     assertion\_user\_enabled;
+\end{lstlisting}
+This variable stores the systemwide user default assertion status.
+\begin{lstlisting}[language=C,firstnumber=50]
+extern bool     assertion_system_enabled;
+\end{lstlisting}
+This variable stores the systemwide default assertion status.
+\\\\
+Defines the following functions:
+\begin{lstlisting}[language=C,firstnumber=54]
+void assertion\_ea\_da(const char *name, bool enabled);
+\end{lstlisting}
+This function is used to initialize the variables described aboved.
+
+\subsection{src/vm/vm.c}
+Handling of assertion commandline options was added/changed. Package and classname parsing is handled by src/vm/assertion.c (assertion\_ea\_da function).
+
+\subsection{src/vmcore/class.c}
+Added class\_java\_util\_HashMap
+
+\subsection{src/vmcore/class.h}
+Added class\_java\_util\_HashMap.
+
+\subsection{src/vmcore/linker.c}
+Added linking of class\_java\_util\_HashMap.
+
+\subsection{src/vmcore/loader.c}
+Added loading of class\_java\_util\_HashMap.
+
+\end{document}
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
new file mode 100644 (file)
index 0000000..924220e
--- /dev/null
@@ -0,0 +1,1356 @@
+# Doxyfile 1.5.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = CACAO 
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = 
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, 
+# and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ../../src
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = ../../src/classes ../../src/fdlibm ../../src/mm/boehm-gc ../../src/native/include
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = NO
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is enabled by default, which results in a transparent 
+# background. Warning: Depending on the platform used, enabling this option 
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they 
+# become hard to read).
+
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/doc/doxygen/Makefile.am b/doc/doxygen/Makefile.am
new file mode 100644 (file)
index 0000000..c75bf12
--- /dev/null
@@ -0,0 +1,40 @@
+## doc/doxygen/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.
+
+
+dist_noinst_DATA = \
+       Doxyfile
+
+doxygen:
+       doxygen
+
+clean-local:
+       -rm -rf html latex
+
+
+## Local variables:
+## mode: Makefile
+## indent-tabs-mode: t
+## c-basic-offset: 4
+## tab-width: 8
+## compile-command: "automake --add-missing"
+## End:
index 1c1db18ae34de71d123adc4e61c4ffc5915a6388..9fe29bde9b2d8f50436d3c47dee2e832a53151f9 100644 (file)
@@ -58,6 +58,7 @@
     \include{arm}
     \include{mips}
     \include{powerpc}
+    \include{s390}
     \include{x86}
     \include{x86_64}
 
@@ -66,7 +67,7 @@
 \include{jvmti}
 
 %\include{}
-\bibliography{java}
 \bibliographystyle{alpha}
+\bibliography{java}
 
 \end{document} 
index 7572ec63d38bfb7188074d9afb6dca4d56d846e2..f34a37995c9744af5bbb5ecfbbab7b2be8260425 100644 (file)
@@ -1793,3 +1793,24 @@ Nasr},
   HOWPUBLISHED = {{\tt http://www.gnu.org/software/gdb/}}
 }
 
+@MISC{s390:bib:principles,
+       KEY = {PRINCIPLES},
+       TITLE = {Enterprise Systems Architecture/390, Principles of Operation, Seventh Edition},
+       YEAR = 1999,
+       ORGANIZATION = {International Business Machines Corporation}
+}
+
+@MISC{s390:bib:gcc,
+       KEY = {GCC},
+       TITLE = {Porting GCC to the IBM S/390 platform},
+       AUTHOR = {Hartmut Penner, Ulrich Weigand},
+       ORGANIZATION = {IBM Deutschland Entwicklung GmbH},
+}
+
+@MISC{s390:bib:abi,
+       KEY = {ABI},
+       TITLE = {LINUX for S/390, ELF Application Binary Interface Supplement},
+       YEAR = 2001,
+       ORGANIZATION = {International Business Machines Corporation}
+}
+
diff --git a/doc/handbook/s390.tex b/doc/handbook/s390.tex
new file mode 100644 (file)
index 0000000..dd653f2
--- /dev/null
@@ -0,0 +1,575 @@
+%\newcommand{\code}{\texttt}
+
+%\chapter{The Just-In-Time Compiler}
+
+\section{ESA/390 code generator}
+
+\subsection{About s390 Architecture}
+
+IBM's mainframe architecture s390 is the living architecture with the longest heritage, defined in a time where assembler programming was predominant and compilers where in their childhood. This fact made already porting of the GNU Compiler Collection a difficult task, as reported by the developers in \cite{s390:bib:gcc}. However the existence of a paper describing the experiences and difficulties encountered while porting an existing C compiler to the s390 architecture made the task of porting CACAO a little easier.
+
+s390 being a CISC architecture provides an extensive instruction set defined in \cite{s390:bib:principles}. There is a wide range of I/O related instructions and control instructions used by the operating system. For the CACAO port, only a small subset of instructions is from interest. \cite{s390:bib:principles} categorises them into into three sections: general instructions, floating point instructions and binary floating point instructions. 
+
+The architecture defines 16 general purpose registers and 16 floating point registers. Instructions have variable length, which always is a multiple of 2 bytes. There are 2, 4 and 6 bytes long instructions and more than 30 \cite{s390:bib:gcc} instruction formats defined. Most instructions take 2 operands: the first operand being also the destination one of the operation. Most arithmetic instructions exist in two flavours: in the RR format they take two register operands, while in the RX format they take one register and one memory operand. There is also the RI format taking one register and one signed 16 bit immediate operand.
+
+For conditional execution, there exists a 2 bit condition code. A lot of instructions set this condition code depending on their result to a value defined for each instruction individually. The \emph{branch on condition} and \emph{branch relative on condition} instructions take a 4 bit bitmask, containing one bit for each possible condition code value. The branch is taken if the bit corresponding the the current condition code value is set. To branch unconditionnaly, one sets all bits in the bitmask. A \emph{branch on condition} instruction with all bits cleared in the bitmask is a nop instruction.
+
+\subsection{The ELF ABI}
+
+The \emph{application binary interface} (ABI) for GNU/Linux, the target operating system of the s390 CACAO port is defined in \cite{s390:bib:abi} and referred to as \emph{ELF ABI}.
+
+The \emph{ELF ABI} defines a system interface for compiled application programs with the purpose of establishing a standard binary interface for application programs on Linux for s390~\cite{s390:bib:abi}. The part of interest for this work is the function calling sequence, that defines register usage, stack layout and the way function parameters are passed. These are summarised in the following tables: table~\ref{s390:tbl:elf:intreg} for the general purpose register usage, table~\ref{s390:tbl:elf:fpreg} for the floating point register usage and table~\ref{s390:tbl:elf:stack} for the layout of a stack frame. To illustrate the typical function prologue, epilogue and calling conventions, figure~\ref{s390:fig:elf:hello} lists the assembly code of a simple function printing the string ``Hello world''.
+
+\begin{table}
+\centering
+\begin{tabular}{|l|l|l|}
+\hline
+Register      & Usage                                                  & Call effect \\
+\hline
+\%r0, \%r1    & General purpose                                        & Volatile \\
+\%r2, \%r3    & Parameter passing and return values                    & Volatile \\
+\%r4, \%r5    & Parameter passing                                      & Volatile \\
+\%r6          & Parameter passing                                      & Saved \\
+\%r7 - \%r11  & Local variables                                        & Saved \\
+\%r12         & Local variable, commonly used as GOT pointer           & Saved \\
+\%r13         & Local variable, commonly used as Literal Pool pointer  & Saved \\
+\%r14         & Return address                                         & Volatile \\
+\%r15         & Stack pointer                                          & Saved \\
+\hline
+\end{tabular}
+\caption{General purpose register usage in the \emph{ELF ABI}}
+\label{s390:tbl:elf:intreg}
+\end{table}
+
+\begin{table}
+\centering
+\begin{tabular}{|l|l|l|}
+\hline
+Register                       & Usage                                  & Call effect \\
+\hline
+\%f0, \%f2                     & Parameter passing and return values    & Volatile \\
+\%f4, \%f6                     & General purpose                        & Saved \\
+\%f1, \%f3, \%f5, \%f7 â€“ \%f15 & General purpose                        & Volatile \\
+\hline
+\end{tabular}
+\caption{Floating point register usage in the \emph{ELF ABI}}
+\label{s390:tbl:elf:fpreg}
+\end{table}
+
+\begin{table}
+\centering
+\begin{tabular}{|l|l|l|}
+\hline
+Use & Size & Offset \\
+\hline
+Local and spill variable area of calling function & Varies & Varies \\
+On stack parameters passed to called function & Varies & 96 \\
+Register save area for called function use & 88 & 8 \\
+Reserved for compiler use & 4 & 4 \\
+Back chain (optional pointer to previous frame) & 4 & 0, 8 byte aligned \\
+\hline
+\end{tabular}
+\caption{Stackframe layout in the \emph{ELF ABI}}
+\label{s390:tbl:elf:stack}
+\end{table}
+
+\begin{figure}
+\begin{verbatim}
+.data
+L_data_hello:
+    .asciz "Hello world\n"
+.text
+
+.globl hello
+
+hello:
+    ; Store callee saved registers in register save area.
+    ; The ELF ABI requires the registers to be stored at particular offsets.
+    ; %r14 is not callee saved, but contains the return address.
+    stm     %r11, %r15, 44(%r15)
+    ; Setup literal pool pointer in %r13 and jump over literal pool.
+    bras    %r13, L_literal_pool_end
+
+       ; Literal pool.
+L_literal_pool:
+L_hello:
+    .long  L_data_hello
+L_printf:
+    .long  printf
+L_literal_pool_end:
+
+    ; Allocate mandatory register save area for callee.
+    ahi    %r15, -96
+    ; Load pointer to string as argument from literal pool.
+    l      %r2, L_hello - L_literal_pool(%r13)
+    ; Load address of printf function from literal pool.
+    l      %r1, L_printf - L_literal_pool(%r13)
+    ; Save program counter of next instruction in %r14 and jump to address in %r1
+    basr   %r14, %r1
+
+    ; Restore callee saved registers from stack.
+    ; Restore return address as well
+    lm     %r11, %r15, 96 + 44(%r15)
+    ; Branch to return address
+    br     %r14
+\end{verbatim}
+\caption{Function that prints the string ``Hello world'' using the \emph{ELF ABI}}
+\label{s390:fig:elf:hello}
+\end{figure}
+
+\subsection{The JIT ABI}
+\label{s390:sec:jitabi}
+
+In just-in-time compiled Java code we try to stay as close as possible to the requirements of the \emph{ELF ABI}. However, some conventions of the \emph{ELF ABI} are violated for various reasons and an alternate ABI, the \emph{JIT ABI} was defined.
+
+Tables~\ref{s390:tbl:jit:intreg} and~\ref{s390:tbl:jit:fpreg} show the general purpose register and floating point register usage in the \emph{JIT ABI} respectively. The stack frame layout in the \emph{JIT ABI} is shown in table~\ref{s390:tbl:jit:stack}.
+
+\begin{table}[H]
+       \centering
+       \begin{tabular}{|c|c|c|}
+       \hline
+       Register & Use & CACAO mnemonic \\
+       \hline
+       \%r0 & Scratch register & ITMP3, ITMP3\_XPTR \\
+       \%r1 & Scratch register & ITMP1, ITMP1\_XPC, METHODPTR \\
+       \%r2 & Parameter passing, return value & RESULT \\
+       \%r3 & Parameter passing, return value & RESULT2 \\
+       \%r4 - \%r6 & Parameter passing & - \\
+       \%r7 - \%r12 & Callee saved & - \\
+       \%r13 & Procedure vector & PV \\
+       \%r14 & Return address, scratch register & RA, ITMP2 \\
+       \%r15 & Stack pointer & SP \\
+       \hline
+       \end{tabular}
+       \caption{General purpose register usage in the \emph{JIT ABI}}
+       \label{s390:tbl:jit:intreg}
+\end{table}
+
+\begin{table}[H]
+       \centering
+       \begin{tabular}{|c|c|c|}
+       \hline
+       Register & Use & CACAO mnemonic \\
+       \hline
+       \%f0 & Parameter passing, return value & FRESULT \\
+       \%f2 & Parameter passing & - \\
+       \%f4 & Scratch register & FTMP1 \\
+       \%f6 & Scratch register & FTMP2 \\
+       \%f3, \%f5, \%f7 - \%f15 & Caller saved & - \\
+       \hline
+       \end{tabular}
+       \caption{Floating point register usage in the \emph{JIT ABI}}
+       \label{s390:tbl:jit:fpreg}
+\end{table}
+
+\begin{table}[H]
+       \centering
+       \begin{tabular}{|c|c|c|}
+       \hline
+       Use & Size & Offset \\
+       \hline
+       Return address & 1 slot & Stackframesize - 8 \\
+       Callee saved integer registers & 0 - 5 slots & \\
+       Callee saved floating point registers & Currently there are none & \\
+       Temporary slot & 1 slot & \\
+       \code{monitorenter} argument & 1 slot & \\
+       Local variables & 0 to n slots & 0 \\
+       \hline
+       \end{tabular}
+       \caption{Stackframe layout in the \emph{JIT ABI}}
+       \label{s390:tbl:jit:stack}
+\end{table}
+
+Register \code{\%r0} is treated by some instructions in a special way. The \emph{branch and save operation} for example takes two registers as operands. The second operand is used as branch address. If however register \code{\%r0} is passed as second operand, the operation is performed without branching. But the most notable special treatment is that \code{\%r0} can't be used as base or index register for storage operands. 
+
+To make the \emph{JIT} and \emph{ELF ABI}s compatible, there were two options for the use of the limited \code{\%r0} register: use it as scratch register or as caller saved temporary register. It was first used as caller saved register, what turned out to be a mistake. The final version of the \emph{JIT ABI} uses it as scratch register for the following reasons:
+
+\begin{itemize}
+       \item For some instructions it is handy to have a consecutive \emph{even-odd pair} of scratch registers.
+       \item Using \code{\%r0} as general purpose register leads to a lot of corner cases in the code generation algorithm.
+       \item Among all scratch registers, \code{REG\_ITMP3} is by convention the one used the least likely. So the best allocation for a register with limited usability is \code{REG\_ITMP3}.
+\end{itemize}
+
+To illustrate the typical prologue, epilogue and calling conventions in just-in-time code, consider the typical \emph{Hello world} program as shown in figure~\ref{s390:fig:jit:helloj}. The assembly code it is translated into is listed in figure~\ref{s390:fig:jit:hellojdis}.
+
+\begin{figure}
+\begin{verbatim}
+class Hello {
+    public static void main(String[] args) {
+        System.out.println("Hello world");
+    }
+}    
+\end{verbatim}
+
+\caption{Source code of Java program printing the string ``Hello world''}
+\label{s390:fig:jit:helloj}
+\end{figure}
+
+\begin{figure}
+\begin{verbatim}
+ahi    %r13,-4092       ; Offset procedure vector
+ahi    %r15,-16         ; Allocate stack frame
+st     %r14,12(%r15)    ; Store return address
+l      %r1,4052(%r13)   ; Get java.lang.System.out into argument register #1
+l      %r2,0(%r1)
+l      %r3,4048(%r13)   ; Load "Hello world" from data segment into argument register #2
+l      %r12,0(%r2)      ; Load virtual function table pointer of java.lang.System.out
+l      %r13,192(%r12)   ; Load method address from virtual function table
+basr   %r14,%r13        ; Call method
+basr   %r13,%r0         ; Restore procedure vector
+ahi    %r13,-4128
+l      %r14,12(%r15)    ; Load return address
+ahi    %r15,16          ; Remove stack frame
+br     %r14             ; Return
+bc     0,0              ; NOP
+\end{verbatim}
+\caption{Disassembly of translated java program printing the string ``Hello world''}
+\label{s390:fig:jit:hellojdis}
+\end{figure}
+
+\subsection{Register allocation}
+
+For s390 the \emph{simplereg} register allocator was not changed at all and worked out of the box. But as described in section~\ref{s390:sec:long}, there is still potential for optimising long arithmetics by tuning the register allocator for s390.
+
+\subsection{Address constants}
+
+On s390, while registers are 32 bit wide, the width of addresses is 31 bit. If the CPU uses addresses given as 32 bit values, it always ignores the most significant bit of the value. This showed to be a problem in the machine independent part of the code base that uses addresses as lookup keys, like the AVL tree of all methods, because each memory location can be address using two different 32 bit pointers. This code had to be extended to always clear the most significant bit of the passed pointers, if compiled for s390.
+
+A statistical analysis of the static instruction frequency shows that 8\% of all generated intermediate instructions are \code{ACONST}. An \code{ACONST} loads an address literal into the destination operated. As 8\% is fairly a lot, two approaches were considered to implement this instruction:
+\begin{itemize}
+       \item Put the address constant on the data segment and implement \code{ACONST} as a load from the data segment.
+       \item Load the address using two immediate 16 bit loads and one 16 bit left shift.
+\end{itemize}
+
+When running the benchmarks, no considerable difference could be observed. Because of the jitter in the benchmark run times, none of the two approaches took the lead. So we decided to always load address constants from the data segment, with the exception of the \code{null} pointer, that can be satisfied with a single immediate load. The GNU C Compiler loads address constants from the literal pool too.
+
+\subsection{Integer arithmetics}
+
+s390 provides native instructions for 32 bit arithmetics. These include addition, substraction, multiplication, division, reminder, bitwise logical operations, arithmetic and logical shift. Most of the instructions can handle either two register operands, or one register and one memory operand. So all 32 bit arithmetics could be implemented inline. 
+
+Java's 8 bit signed integer type \code{byte} and 16 bit unsigned integer type \code{char} are both handled through 32 bit arithmetics. Internally they are always represented as 32 bit values in both storage and registers. The only exception are arrays of those types. Here the array loads must sign extend the loaded values, and the array stores must store only the respective number of bytes into memory.
+
+\subsection{Long arithmetics}
+\label{s390:sec:long}
+
+Java's 64 bit integer type \code{long} is stored either as 64 bit value in storage or in two 32 bit registers. Almost all long instructions are inline except \code{LMUL}, \code{LDIV} and \code{LREM} that are delegated to builtins. Addition is performed as one 32 bit addition followed by a second 32 bit addition with carry, substraction works in a similar way. s390 provides 64 bit shift instructions that are used to implement the \code{I2L} intermediate instruction and long shift operations. Those shift instructions always operate on an \emph{even-odd pair of registers}. If not already in such a register pair, the value has to be copied into \code{REG\_ITMP31\_PACKED}. This is actually always the case with the current register allocator, because it allocates the least significant half of the 64 bit value to the lower register of the pair. This could however be simply improved by making the register allocator always prefer an \emph{even-odd pair of registers} for the allocation of 64 bit variables.
+
+\subsection{Floating point arithmetics}
+
+s390 defines 16 64 bit wide floating point registers, that can hold single or double precision IEEE floating point values. Two of those registers can be combined to hold an extended precision IEEE floating value, but this feature is not needed for CACAO. Note that not all 16 registers must be available: registers \code{\%f0}, \code{\%f2}, \code{\%f4}, \code{\%f6} are available on all ESA/390 models. The remaining registers are referred to as additional \emph{floating-point registers} (AFR) and they are present only if the \emph{basic-floating-point-extensions facility} is installed. The current code base blindly assumes that all 16 registers are available. We took care to allocate the AFRs only as temporary registers, thus in future releases we can easily support models without AFRs by simply marking the respective registers as reserved in the register descriptor arrays (\code{nregdescfloat}) and by not storing and restoring them at \emph{ELF ABI} - \emph{CACAO ABI} boundaries.
+
+Java floating point semantics require a IEEE 754 \emph{round to nearest mode}. The rounding mode is controlled via the floating point control register \code{fpc}. On Linux/s390 the \code{fpc} register of newly started processes is always initialised to 0, meaning \emph{round to nearest} \cite{s390:bib:abi}, so no extra effort needs to be made here.
+
+\subsection{Machine code generation}
+
+The usual way to generate machine code in CACAO is to use code generation macros defined in the architecture dependent header file \code{codegen.h}. For example on alpha, to generate machine code equivalent to the following assembly code:
+
+\begin{verbatim}
+ild  16(%r9), %r10
+\end{verbatim}
+
+one would place the following macro into the code generation algorithm:
+
+\begin{verbatim}
+M_ILD(R9, 16, R10)
+\end{verbatim}
+
+On s390, the equivalent instruction in assembly language would be:
+
+\begin{verbatim}
+l    %r10, 16(%r9)
+\end{verbatim}
+
+and would lead to definition of the following macro:
+
+\begin{verbatim}
+M_L(R10, 16, 0, R9)
+\end{verbatim}
+
+For ease of maintenance there is an effort to keep all code generators as similar as possible. The proffered signature of the code generation macros is the one used in the alpha code generator. To honour this requirement but keep the possibility of using special s390 instructions not available in the alpha instruction set, the code generation macros were defined in two layers:
+
+The instructions prefixed with the prefix \code{N\_} follow exactly to the s390 naming and conventions as defined in~\cite{s390:bib:principles}.
+
+\begin{verbatim}
+N_L(dest, disp, index, base)
+\end{verbatim}
+
+The widely used code generation macros prefixed with an \code{M\_} are an alpha compatibility layer. They define alpha-like code generation macros in terms of \code{N\_} prefixed code generation macros.
+
+\begin{verbatim}
+#define M_ALD(base, disp, dest) N_L(dest, disp, 0, base)
+\end{verbatim}
+
+To prevent subtle errors, if CACAO is compiled in debug mode, all code generation macros validate the passed parameters. In release mode, no run-time checks are performed. 
+
+As already mentioned in section~\ref{s390:sec:jitabi}, some instructions don't accept register \code{\%r0} as operand, but rather treat it as \emph{optional operand not given}. Again, to prevent subtle errors, if CACAO is compiled in debug mode, the corresponding code generation macros don't accept \code{\%r0} as operand. Instead a special value, \code{RN}, meaning \emph{register none} must be given. In release mode, \code{RN} just expands to \code{\%r0} and no run-time checks are performed.
+
+\subsection{Exception handling}
+
+In contrast to other ports, in the s390 one we try to perform most of exception handling in C code. A port is required to implement an \code{asm\_handle\_exception} function in assembly language that is called only from JIT code with special conventions: register \code{xptr} contains the exception object and register \code{xpc} contains the program counter of the failing instruction, which can be mapped to a java byte code index. All other registers are required to be left unchanged. The s390 version is a thin wrapper around a C function \code{md\_handle\_exception} and does the following:
+
+\begin{itemize}
+       \item Allocates 3 arrays on the stack: \code{regs[16]}, \code{fregs[16]}, \code{out[3]}.
+       \item Stores special, temporary and argument integer registers into \code{regs}.
+       \item Stores temporary and argument floating point registers into \code{fregs}.
+       \item Calls \code{md\_handle\_exception} with the 3 arrays as arguments.
+       \item \code{md\_handle\_exception} while handling the exception computes new values for registers and puts them into the respective arrays. This eventually includes a new stack pointer, a new procedure vector, new values for callee saved registers and a new program counter.
+       \item Restores registers from the respective arrays.
+       \item Jumps to the address contained in register \code{xpc}.
+\end{itemize}
+
+\subsection{Exception raising}
+
+Currently there are two approaches to raise an exception in JIT code:
+
+\begin{itemize}
+       \item A call to \code{asm\_handle\_exception}.
+       \item Make the JIT code produce a hardware exception, and call \code{asm\_handle\_exception} from a signal handler.
+\end{itemize}
+
+The first approach requires special stub code to be generated for the call while the second requires generation of very little code: a single instruction or even none at all. Handling of hardware exceptions on the other side involves the kernel and a context switch and can therefore be a costy operation. But because of the fundamental property of exceptions being rare, we prefer to reduce the code size at the price of occasional performance penalty. 
+
+Consider for example the assembly code corresponding to the load an object's field in figure~\ref{s390:fig:exceptionrise}. If the value in \code{\%r10} points to a valid java object, the field value is loaded. If however the value in \code{\%r10} is a \code{null} pointer, the process receives a \code{SIGSEGV} signal and the operating system passes control to a function \code{md\_handle\_sigsegv}, the registered handler for this signal. This signal handler has access to all registers and the faulting program counter as well. It examines the opcode of the faulting instruction to see whether it corresponds to the use of a \code{null} pointer. If so, an exception object is allocated and put into the \code{xpc} register, \code{xptr} is set to the faulting address and program flow is resumed at \code{asm\_handle\_exception}. 
+
+\begin{figure}[H]
+\begin{verbatim}
+l %r9, 36(%r10)
+\end{verbatim}
+\caption{Load of an object's field with the potential of rising a \code{NullPointerException}.}
+\label{s390:fig:exceptionrise}
+\end{figure}
+
+For explicit exception raising, we have defined the \code{ill} pseudo instruction in RR format. Its mnemonic is defined if figure~\ref{s390:fig:ill} and its machine code format in table~\ref{s390:tbl:ill}.
+
+\begin{figure}
+\centering
+\begin{verbatim}
+ill register, exception_number
+\end{verbatim}
+\caption{Mnemonic of the \code{ill} pseudo instruction}
+\label{s390:fig:ill}
+\end{figure}
+
+\begin{table}
+\centering
+\begin{tabular}{|c|c|c|c|}
+       \hline
+       Bits & 0 - 7 & 8 - 11 & 12 - 15 \\
+       \hline
+       Contents & 0x02 & register & exception number \\
+       \hline
+\end{tabular}
+\caption{Machine code for the \code{ill} pseudo instruction}
+\label{s390:tbl:ill}
+\end{table}
+
+As the opcode \code{0x02} is no valid opcode according to~\cite{s390:bib:principles} , once that instruction is reached, it will lead to an illegal instruction exception. The operating system delivers a \code{SIGILL} signal to the process and control is passed to the registered signal handler. This signal handler then examines the opcode of the instruction at the faulting address. In case it corresponds to the \code{ill} pseudo-instruction, the second register field is interpreted as exception number. The corresponding exception object is then instantiated and control passed to \code{asm\_handle\_exception}.
+
+Signal handling can be used to support corner cases of arithmetics that can't be handled by the architecture natively. Consider for example the special case of the division of \code{0x80000000} (\code{Integer.MIN}) by \code{0xFFFFFFFF} (-1) that raises a fixed-point divide exception which is signalled to the process by a \code{SIGFPE} signal. If the signal handler determines that the faulting operation was an integer division with those special values as operands, the destination operand is set to the expected result (-1) and normal program flow is resumed.
+
+Table~\ref{s390:tbl:signals} contains an overview of signals used in CACAO JIT code.
+
+\begin{table}
+\centering
+\begin{tabular}{|c|c|c|}
+\hline
+Signal & Faulting instruction & Thrown runtime exception \\
+\hline
+\code{SIGSEGV} & \code{L} & \code{EXCEPTION\_HARDWARE\_NULLPOINTER} \\
+\code{SIGSEGV} & \code{ST} & \code{EXCEPTION\_HARDWARE\_NULLPOINTER} \\
+\code{SIGSEGV} & \code{CL} & \code{EXCEPTION\_HARDWARE\_NULLPOINTER} \\
+\code{SIGILL} & \code{ILL} & \code{EXCEPTION\_HARDWARE\_ARITHMETIC} \\
+\code{SIGILL} & \code{ILL} & \code{EXCEPTION\_HARDWARE\_ARRAYINDEXOUTOFBOUNDS} \\
+\code{SIGILL} & \code{ILL} & \code{EXCEPTION\_HARDWARE\_CLASSCAST} \\
+\code{SIGILL} & \code{ILL} & \code{EXCEPTION\_HARDWARE\_PATCHER} \\
+\code{SIGFPE} & \code{DR} & \code{EXCEPTION\_HARDWARE\_ARITHMETIC} \\
+\code{SIGFPE} & \code{DR} & \code{EXCEPTION\_HARDWARE\_ARITHMETIC} \\
+\hline
+\end{tabular}
+\caption{Overview of signals used by JIT code in Cacao}
+\label{s390:tbl:signals}
+\end{table}
+
+\subsection{Code patching}
+
+Not all the information needed for program execution is available at compile time. Therefore some parts of the JIT-code need to be \emph{patched} at runtime. A trap instruction is placed at the beginning of the code in question. Further, a \emph{patcher reference} is created. This is a tiny data structure associated with the patched position encapsulating metadata about the information to be patched. The trap instruction used is the \code{ill} pseudo-instruction with a exception number of \code{EXCEPTION\_HADRWARE\_PATCHER}.
+
+Once the patched position is reached and the trap instruction executed the operating system passes control the the \code{md\_signal\_handler\_sigill} function. This function inspects the faulting instruction and then passes control to the machine independent \code{signal\_handle} function, which in turn invokes the machine independent entry into the patching subsystem: \code{patcher\_handler}. Here the faulting program counter is used to look up the associated \emph{patcher reference}. The address of the machine dependent patcher function is extracted from the \emph{patcher reference} and the patcher is invoked with the \emph{patcher reference} as argument. After the patcher function has finished, and the signal handler exits, program flow is resumed at the now reconstructed patched position. The anatomy of a patcher function is the following:
+
+\begin{itemize}
+       \item Examine the patcher reference to determine what information needs to be retrieved.
+       \item Retrieve required information.
+       \item Overwrite the trap instruction at the patched position with the original machine code.
+       \item Patch required information. This is usually done in one of the following ways:
+       \begin{itemize}
+               \item Modify a value on the data segment. The offset of the value is extracted from the \emph{patcher reference}.
+               \item Modify machine code near the patched position.
+       \end{itemize}
+\end{itemize}
+
+Consider the example of calling an object's virtual method in figure~\ref{s390:fig:patch1}. At the time the code for the call is assembled, the called method's class may not have been loaded and thus the offset in the virtual function table may not yet be known. The code generator simply generates the second load with a displacement of 0. It then replaces the machine code at the current location with a trap instruction and creates a \emph{patcher reference} (figure~\ref{s390:fig:patch2}). In the case of a virtual function call it contains an \code{unresolved\_method *}, a data structure encapsulating information needed to resolve the method. Once the trap instruction is reached, the responsible patcher, \code{patcher\_invokevirtual} will be invoked by the patcher subsystem. It resolves the method, then removes the trap instruction and finally, modifies the displacement of the second load, to reflect the offset in the virtual function table (figure~\ref{s390:fig:patch3}).
+
+\begin{figure}
+\begin{verbatim}
+l mptr, offset_vftbl_ptr(a0) ; Load the object's VFTBL pointer
+l pv, offset_method(mptr)    ; Load pointer to method from VFTBL
+\end{verbatim}
+\caption{Machine code for normal virtual function call}
+\label{s390:fig:patch1}
+\end{figure}
+
+\begin{figure}
+\begin{verbatim}
+; Machine code replaced with trap instruction
+; Patcher reference created for this program counter
+ill EXCEPTION_HARDWARE_PATCHER
+l pv, 0(mptr)
+\end{verbatim}
+\caption{Machine code for virtual function call before being patched}
+\label{s390:fig:patch2}
+\end{figure}
+
+\begin{figure}
+\begin{verbatim}
+; Trap instruction removed and original machine code restored
+l mptr, offset_vftbl_pointer(a0)
+; Load instruction patched
+l pv, 16(mptr)
+\end{verbatim}
+\caption{Machine code for virtual function call after being patched}
+\label{s390:fig:patch3}
+\end{figure}
+
+The above example shows, that patchers that modify machine code are tightly coupled with the code used for its generation. Here, given the program counter of the patched position, the patcher is expected to exactly determine the load instruction to patch. On one hand, its easy, because it's simply the next instruction after the trap. On the other hand, care must be taken when modifying the code generation portion to not forget keep the patchers up to date.
+
+\subsection{Data segment access}
+
+One speciality of s390 compared with other architectures is the format of memory addresses in instructions. This can be given as \code{displacement(base)} or \code{displacement(index, base)} where \code{displacement} is an unsigned 12 bit value while \code{base} and \code{index} designate registers. The resulting memory address is calculated as the sum of the displacement and the values in the registers. The conventional way to address a value on the data segment is to use a negative displacement with the procedure vector register. As this obviously can't be done on s390 a workaround was needed. \\
+
+We decided to add a negative constant \code{N\_PV\_OFFSET} to the procedure vector in each java methods prologue. This way, a load of the form as in figure~\ref{s390:fig:dsegload1} turns into a load of the form as in figure~\ref{s390:fig:dsegload2} with a non-negative displacement for the first 4 kB of the data segment. For data segment access beyond that barrier, special code has to be generated. Most of those accesses can be fullfitted by first loading the negative displacement as 16 bit signed immediate value into the destination register and then using that register as an index register for the actual load as in figure~\ref{s390:fig:dsegload3}. Note however, that the code does not work if the destination register is \code{\%r0}, because \code{\%r0} can't be used as index register.
+
+\begin{figure}[H]
+\begin{verbatim}
+    l      reg, negative_displacement(pv)
+\end{verbatim}
+\caption{Usual way to load a value from the data segment}
+\label{s390:fig:dsegload1}
+\end{figure}
+
+\begin{figure}[H]
+\begin{verbatim}
+    l      reg, negative_displacement - N_PV_OFFSET(pv)
+\end{verbatim}
+\caption{Load from data segment with non-negative displacement}
+\label{s390:fig:dsegload2}
+\end{figure}
+
+\begin{figure}[H]
+\begin{verbatim}
+    lhi reg, negative_displacement
+    l   reg, 0(reg, pv)
+\end{verbatim}
+\caption{Load from data segment for large displacements}
+\label{s390:fig:dsegload3}
+\end{figure}
+
+In very rare cases, where the data can't be addressed using a signed 16 bit offset, we place the negative displacement into the instruction flow and load it in a PC relative fashion, as seen in figure~\ref{s390:fig:dsegload4}.
+
+\begin{figure}[H]
+\begin{verbatim}
+    bras reg, L_bras     ; Branch over constant dseg offset in instruction stream 
+                         ; and store current PC of next instruction in reg     
+    .long negative_displacement
+L_bras:
+    l    reg, 0(reg)     ; Load constant dseg offset into reg
+    l    reg, 0(reg, pv) ; Address dseg using two registers
+\end{verbatim}
+\caption{Load from data segment for very large displacements}
+\label{s390:fig:dsegload4}
+\end{figure}
+
+The fact, that in JIT code the procedure vector is always set off must be kept in mind when passing its value to architecture independent code, for example the patcher subsystem, that expects it to point to the methods entry point. \code{N\_PV\_OFFSET} must first be substracted from the procedure vector value.
+
+\subsection{Recalculation of the procedure vector}
+
+Because the procedure vector is a caller saved register in the \emph{JIT ABI}, but a callee saved register in the \emph{ELF ABI}, the procedure vector has to be recalculated after each Java-to-Java call. This is done by the snippet of assembly code seen in figure~\ref{s390:fig:pvrestore1}
+
+\begin{figure}[H]
+\begin{verbatim}
+    ; get program counter into pv
+    basr     pv, 0 
+L_basr:
+    ; substract offset to start of method
+    ahi      pv, -(L_basr - L_mcodebase) + N_PV_OFFSET
+\end{verbatim}
+\caption{Assembly code for the recalculation of the procedure vector}
+\label{s390:fig:pvrestore1}
+\end{figure}
+
+Although rare, it happens for large methods that the that the immediate operand to \code{ahi} does not fit into the range of valid immediates. Care has to be taken to still generate correct code as seen in the assembly code in figure~\ref{s390:fig:pvrestore2}.
+
+\begin{figure}[H]
+\begin{verbatim}
+    ; Jump over (big) constant in instruction flow and
+    ; get program counter of next instruction into PV.
+    bras    pv, L_bras
+    ; offset to start of method is placed in instruction flow
+    .long   -(L_bras - L_mcodebase) + N_PV_OFFSET
+L_bras:
+    ; Add offset to program counter retrieved above.
+    a       pv, 0(pv)
+\end{verbatim}
+\caption{Assembly code for the recalculation of the procedure vector for large methods}
+\label{s390:fig:pvrestore2}
+\end{figure}
+
+\subsection{Long branches}
+
+For program counter relative branches, that are used for inter-method branching, the offset is specified as signed 17 bit integer. The size of most methods does not exceed 64kB. But occasionally, there are large methods that require a branch with a offset not fitting into this range. We call this kind of branches \emph{long branches}. If a backward \emph{long branch} is generated, this does not cause further troubles. The problem are forward branches: branches to not yet generated code. In such cases, instead of generating a branch, we reserve exactly the size of a branch instruction. This space will be filled with a (short) branch as soon as the referenced code gets generated. This is obviously a problem if the branch generated later shows to be a \emph{long branch}, because the code generated for a \emph{long branch} does not fit into the reserved space.
+
+This condition is detected in \code{emit\_branch} by checking the passed displacement to fit into the 17 bit signed range. If this condition does not hold and the flag \code{CODEGENDATA\_FLAG\_LONGBRANCHES} is not set, then both flags \code{CODEGENDATA\_FLAG\_ERROR} and \code{CODEGENDATA\_FLAG\_LONGBRANCHES} are set and no branch is generated. After \code{codegen\_emit} returns, \code{codegen\_generate} checks for those two flags. If they are both set, the method is recompiled, with only the \code{CODEGENDATA\_FLAG\_LONGBRANCHES} flags set. 
+
+This causes that more space is reserved for forward branches: enough to patch either a (short) branch or a \emph{long branch}.
+
+A long branch is implemented by storing the long displacement in the data segment. The generated code loads the displacement from the data segment, combines it with the procedure vector and then jumps to the resulting address.
+
+\subsection{The development environment}
+
+Most of the development has been done on a Debian GNU/Linux system running on the Hercules emulator. Installing the system on the emulator can be tricky and needs several hours to complete. It is not recommended to setup such a system from scratch, but rather use the disk image floating around at the complang group.
+
+As the emulator showed to be slow for native compiling, a cross compiler was used instead. To eliminate the need of cross compiling all dependencies of CACAO on the development system, the following approach was chosen instead:
+
+\begin{itemize}
+       \item The root of the target system was mounted via NFS on the development system.
+       \item The cross compiler was set up to use the mounted NFS root as sysroot.
+\end{itemize}
+
+The procedure of building the cross compiler in practice is shown in figure~\ref{s390:fig:crosgcc}.
+
+\begin{figure}
+\begin{verbatim}
+$ mount s390-system:/ /foo
+$ cd binutils-2.17
+$ ./configure \
+    --target=s390-ibm-linux-gnu \
+    --with-build-sysroot=/foo \
+    --with-sysroot=/foo
+$ make install
+$ cd gcc-4.1.1
+$ ./configure \
+    --target=s390-ibm-linux-gnu \
+    --prefix=/usr/local \
+    --with-sysroot=/foo \
+    --enable-languages=c
+$ make install
+\end{verbatim}
+\caption{Building an s390 cross compiler with the sysroot feature}
+\label{s390:fig:crosgcc}
+\end{figure}
+
+In the final phase of development, we got a free account at the \emph{IBM community development system} for three months. This account provided us with root access to a ESA/390 virtual machine with 256MB of RAM preinstalled with a GNU/Linux system. Development on that system worked perfectly and it had a more reasonable performance than the emulated system.
+
+
+
+
index caa71e53ac0d6e48f8530efaaae6ea8a91fc3faf..977c6bf2f4df425ea56600bffeaae85c0921b918 100644 (file)
@@ -37,9 +37,9 @@ dnl @license GPLWithACException
 AC_DEFUN([AC_PROG_JAVAC],[
 AC_REQUIRE([AC_EXEEXT])dnl
 if test "x$JAVAPREFIX" = x; then
-        test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, "javac$EXEEXT -bootclasspath ${CLASSPATH_CLASSES}" "ecj$EXEEXT -bootclasspath ${CLASSPATH_CLASSES}" "gcj$EXEEXT -C -bootclasspath ${CLASSPATH_CLASSES}" "jikes$EXEEXT -bootclasspath ${CLASSPATH_CLASSES}")
+        test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, "javac$EXEEXT" "ecj$EXEEXT" "gcj$EXEEXT -C")
 else
-        test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, "javac$EXEEXT -bootclasspath ${CLASSPATH_CLASSES}" "ecj$EXEEXT -bootclasspath ${CLASSPATH_CLASSES}" "gcj$EXEEXT -C -bootclasspath ${CLASSPATH_CLASSES}" "jikes$EXEEXT -bootclasspath ${CLASSPATH_CLASSES}", $JAVAPREFIX)
+        test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, "javac$EXEEXT" "ecj$EXEEXT" "gcj$EXEEXT -C", $JAVAPREFIX)
 fi
 test "x$JAVAC" = x && AC_MSG_ERROR([no acceptable Java compiler found in \$PATH])
 AC_PROG_JAVAC_WORKS
index 7560c30c86301a341c458c6f2408d6a65951412f..23045535e8552a1f34d7324d450708f096473e9e 100644 (file)
@@ -1,9 +1,7 @@
 dnl m4/annotations.m4
 dnl
-dnl Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
-dnl C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-dnl E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-dnl J. Wenninger, Institut f. Computersprachen - TU Wien
+dnl Copyright (C) 2007, 2008
+dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 dnl 
 dnl This file is part of CACAO.
 dnl 
@@ -28,16 +26,19 @@ dnl check if annotations support should be built
 AC_DEFUN([AC_CHECK_ENABLE_ANNOTATIONS],[
 AC_MSG_CHECKING(wether to build annotations support)
 AC_ARG_ENABLE([annotations],
-              [AS_HELP_STRING(--enable-annotations,build annotations support [[default=no]])],
+              [AS_HELP_STRING(--enable-annotations,build annotations support [[default=(cldc1.1:no,javase:yes]])],
               [case "${enableval}" in
                    yes)
                        ENABLE_ANNOTATIONS=yes
                        ;;
-                   *)
+                   no)
                        ENABLE_ANNOTATIONS=no
                        ;;
+                   *)
+                       AC_CHECK_ENABLE_ANNOTATIONS_DEFAULT
+                       ;;
                esac],
-              [ENABLE_ANNOTATIONS=no])
+              [AC_CHECK_ENABLE_ANNOTATIONS_DEFAULT])
 AC_MSG_RESULT(${ENABLE_ANNOTATIONS})
 AM_CONDITIONAL([ENABLE_ANNOTATIONS], test x"${ENABLE_ANNOTATIONS}" = "xyes")
    
@@ -45,3 +46,14 @@ if test x"${ENABLE_ANNOTATIONS}" = "xyes"; then
     AC_DEFINE([ENABLE_ANNOTATIONS], 1, [enable annotations])
 fi
 ])
+
+
+dnl check for the default value for --enable-annotations
+
+AC_DEFUN([AC_CHECK_ENABLE_ANNOTATIONS_DEFAULT],[
+if test x"${ENABLE_JAVAME_CLDC1_1}" = "xyes"; then
+    ENABLE_ANNOTATIONS=no
+else
+    ENABLE_ANNOTATIONS=yes
+fi
+])
index e83ea19258fe6bde75703f9d24460d3f5bb73bc4..0652fbdcbefd24fbd57c8e53e905822ad8df0072 100644 (file)
@@ -1,7 +1,7 @@
 dnl m4/assertion.m4
 dnl
 dnl Copyright (C) 2007
-dnl CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 dnl 
 dnl This file is part of CACAO.
 dnl 
diff --git a/m4/az_python.m4 b/m4/az_python.m4
new file mode 100644 (file)
index 0000000..4b082de
--- /dev/null
@@ -0,0 +1,518 @@
+##### http://autoconf-archive.cryp.to/az_python.html
+#
+# SYNOPSIS
+#
+#   AZ_PYTHON_DEFAULT
+#   AZ_PYTHON_ENABLE
+#   AZ_PYTHON_WITH
+#   AZ_PYTHON_PATH
+#   AZ_PYTHON_VERSION_ENSURE( [2.2] )
+#   AZ_PYTHON_CSPEC
+#   AZ_PYTHON_LSPEC
+#
+# DESCRIPTION
+#
+#   This file provides autoconf support for those applications that
+#   want to embed python. It supports all pythons >= 2.2 which is the
+#   first official release containing distutils. Version 2.2 of python
+#   was released December 21, 2001. Since it actually executes the
+#   python, cross platform configuration will probably not work. Also,
+#   most of the platforms supported are consistent until you look into
+#   MacOSX. The python included with it is installed as a framework
+#   which is a very different environment to set up the normal tools
+#   such as gcc and libtool to deal with. Therefore, once we establish
+#   which python that we are going to use, we use its distutils to
+#   actually compile and link our modules or applications.
+#
+#   At this time, it does NOT support linking with Python statically.
+#   It does support dynamic linking.
+#
+#   This set of macros help define $PYTHON, $ENABLE_PYTHON, $PYTHON_CSPEC
+#   and $PYTHON_LSPEC. $PYTHON defines the full executable path for the
+#   Python being linked to and is used within these macros to determine
+#   if that has been specified or found. These macros do execute this
+#   python version so it must be present on the system at configure
+#   time.
+#
+#   $ENABLE_PYTHON is an automake variable that defines whether Python
+#   support should be included or not in your application.
+#   $PYTHON_CSPEC is a variable that supplies additional CFLAGS for the
+#   compilation of the application/shared library. $PYTHON_LSPEC is a
+#   variable that supplies additional LDFLAGS for linking the
+#   application/shared library.
+#
+#   The following is an example of how to set up for python usage
+#   within your application in your configure.in:
+#
+#     AZ_PYTHON_DEFAULT( )
+#     AZ_PYTHON_ENABLE( )             # Optional
+#     AZ_PYTHON_WITH( )               # Optional
+#     AZ_PYTHON_PATH( )               # or AZ_PYTHON_INSIST( )
+#     # if $PYTHON is not defined, then the following do nothing.
+#     AZ_PYTHON_VERSION_ENSURE( [2.2] )
+#     AZ_PYTHON_CSPEC
+#     AZ_PYTHON_LSPEC
+#
+#   The AZ_PYTHON_DEFAULT sets the $ENABLE_PYTHON to false. Thereby,
+#   excluding it if it was optional.
+#
+#   The AZ_PYTHON_ENABLE looks for the optional configure parameters of
+#   --enable-python/--disable-python and establishes the $PYTHON and
+#   $ENABLE_PYTHON variables accordingly.
+#
+#   The AZ_PYTHON_WITH looks for the optional configure parameters of
+#   --with-python/--without-python and establishes the $PYTHON and
+#   $ENABLE_PYTHON variables accordingly.
+#
+#   The AZ_PYTHON_PATH looks for python assuming that none has been
+#   previously found or defined and issues an error if it does not find
+#   it. If it does find it, it establishes the $PYTHON and $ENABLE_PYTHON
+#   variables accordingly. AZ_PYTHON_INSIST could be used here instead
+#   if you want to insist that Python support be included using the
+#   --enable-python or --with-python checks previously done.
+#
+#   The AZ_PYTHON_VERSION_ENSURE issues an error if the Python
+#   previously found is not of version 2.2 or greater.
+#
+#   Once that these macros have be run, we can use ENABLE_PYTHON within
+#   the makefile.am file to conditionally add the Python support such
+#   as:
+#
+#   Makefile.am example showing optional inclusion of directories:
+#
+#    if ENABLE_PYTHON
+#    plugins = plugins
+#    src = src
+#    else
+#    plugins =
+#    src =
+#    endif
+#
+#    SUBDIRS = . $(plugins) $(src)
+#
+#   Makefile.am example showing optional shared library build:
+#
+#    if ENABLE_PYTHON
+#    lib_LTLIBRARIES        = libElemList.la
+#    libElemList_la_SOURCES = libElemList.c
+#    libElemList_la_CFLAGS  = @PYTHON_CSPEC@
+#    libElemList_la_LDFLAGS = @PYTHON_LSPEC@
+#    endif
+#
+#   Makefile.am example showing optional program build:
+#
+#    if ENABLE_PYTHON
+#    bin_PROGRAMS    = runFunc
+#    runFunc_SOURCES = runFunc.c
+#    runFunc_CFLAGS  = @PYTHON_CSPEC@
+#    runFunc_LDFLAGS = @PYTHON_LSPEC@
+#    endif
+#
+#   The above compiles the modules only if ENABLE_PYTHON was specified as
+#   true. Also, the else portion of the if was optional.
+#
+# LAST MODIFICATION
+#
+#   2007-08-04
+#
+# COPYLEFT
+#
+#   Copyright (c) 2007 Robert White <kranki@mac.com>
+#   Copyright (c) 2007 Dustin J. Mitchell <dustin@cs.uchicago.edu>
+#
+#   Copying and distribution of this file, with or without
+#   modification, are permitted in any medium without royalty provided
+#   the copyright notice and this notice are preserved.
+
+# AZ_PYTHON_DEFAULT( )
+# -----------------
+# Sets the default to not include Python support.
+
+AC_DEFUN([AZ_PYTHON_DEFAULT],
+[
+    az_python_use=false
+    AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+])
+
+
+
+# AZ_PYTHON_ENABLE( [path] )
+# -----------------------------------------------------------------
+# Handles the various --enable-python commands.
+# Input:
+#   $1 is the optional search path for the python executable if needed
+# Ouput:
+#   ENABLE_PYTHON (AM_CONDITIONAL) is true if python executable found
+#   and --enable-python was requested; otherwise false.
+#   $PYTHON contains the full executable path to python if PYTHON_ENABLE_USE
+#   is true.
+#
+# Example:
+#   AZ_PYTHON_ENABLE( )
+#   or
+#   AZ_PYTHON_ENABLE( "/usr/bin" )
+
+AC_DEFUN([AZ_PYTHON_ENABLE],
+[
+    AC_ARG_VAR([PYTHON],[Python Executable Path])
+
+    # unless PYTHON was supplied to us (as a precious variable),
+    # see if --enable-python[=PythonExecutablePath], --enable-python,
+    # --disable-python or --enable-python=no was given.
+    if test -z "$PYTHON"
+    then
+        AC_MSG_CHECKING(for --enable-python)
+        AC_ARG_ENABLE(
+            python,
+            AC_HELP_STRING([--enable-python@<:@=PYTHON@:>@],
+                [absolute path name of Python executable]
+            ),
+            [
+                if test "$enableval" = "yes"
+                then
+                    # "yes" was specified, but we don't have a path
+                    # for the executable.
+                    # So, let's searth the PATH Environment Variable.
+                    AC_MSG_RESULT(yes)
+                    AC_PATH_PROG(
+                        [PYTHON],
+                        python,
+                        [],
+                        $1
+                    )
+                    if test -z "$PYTHON"
+                    then
+                        AC_MSG_ERROR(no path to python found)
+                    fi
+                    az_python_use=true
+                    AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+                    AZ_PYTHON_PREFIX( )
+                elif test "$enableval" = "no"
+                then
+                    AC_MSG_RESULT(no)
+                    az_python_use=false
+                    AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+                else
+                    # $enableval must be the executable path then.
+                    AC_SUBST([PYTHON], ["${enableval}"])
+                    AC_MSG_RESULT($withval)
+                    az_python_use=true
+                    AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+                    AZ_PYTHON_PREFIX( )
+                fi
+            ],
+            [
+                # --with-python was not specified.
+                AC_MSG_RESULT(no)
+                az_python_use=false
+                AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+            ]
+        )
+    fi
+])
+
+
+
+# AZ_PYTHON_CSPEC( )
+# -----------------
+# Set up the c compiler options to compile Python
+# embedded programs/libraries in $PYTHON_CSPEC if
+# $PYTHON has been defined.
+
+AC_DEFUN([AZ_PYTHON_CSPEC],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+        az_python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
+        if test -z "$az_python_prefix"
+        then
+            AC_MSG_ERROR([Python Prefix is not known])
+        fi
+        az_python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
+        az_python_version=`$PYTHON -c "import sys; print sys.version[[:3]]"`
+        az_python_includespec="-I${az_python_prefix}/include/python${az_python_version}"
+        if test x"$python_prefix" != x"$python_execprefix"; then
+            az_python_execspec="-I${az_python_execprefix}/include/python${az_python_version}"
+            az_python_includespec="${az_python_includespec} $az_python_execspec"
+        fi
+        az_python_ccshared=`${PYTHON} -c "import distutils.sysconfig; print distutils.sysconfig.get_config_var('CFLAGSFORSHARED')"`
+        az_python_cspec="${az_python_ccshared} ${az_python_includespec}"
+        AC_SUBST([PYTHON_CSPEC], [${az_python_cspec}])
+        AC_MSG_NOTICE([PYTHON_CSPEC=${az_python_cspec}])
+               AC_DEFINE(ENABLE_PYTHON, 1, [enabled python pass])
+    fi
+])
+
+
+
+# AZ_PYTHON_INSIST( )
+# -----------------
+# Look for Python and set the output variable 'PYTHON'
+# to 'python' if found, empty otherwise.
+
+AC_DEFUN([AZ_PYTHON_PATH],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    fi
+])
+
+
+
+# AZ_PYTHON_LSPEC( )
+# -----------------
+# Set up the linker options to link Python embedded
+# programs/libraries in $PYTHON_LSPEC if $PYTHON
+# has been defined.
+
+AC_DEFUN([AZ_PYTHON_LSPEC],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+        AZ_PYTHON_RUN([
+import sys
+import distutils.sysconfig
+strUseFrameWork = "--enable-framework"
+dictConfig = distutils.sysconfig.get_config_vars( )
+strConfigArgs = dictConfig.get("CONFIG_ARGS")
+strLinkSpec =  dictConfig.get('LDFLAGS')
+if -1 ==  strConfigArgs.find(strUseFrameWork):
+    strLibPL = dictConfig.get("LIBPL")
+    if strLibPL and (strLibPL != ""):
+        strLinkSpec += " -L%s" % (strLibPL)
+    strSys = dictConfig.get("SYSLIBS")
+    if strSys and (strSys != ""):
+        strLinkSpec += " %s" % (strSys)
+    strSHL = dictConfig.get("SHLIBS")
+    if strSHL and (strSHL != ""):
+        strLinkSpec += " %s" % (strSHL)
+    # Construct the Python Library Name.
+    strTmplte = " -lpython%d.%d"
+    if (sys.platform == "win32") or (sys.platform == "os2emx"):
+        strTmplte = " -lpython%d%d"
+    strWrk = strTmplte % ( (sys.hexversion >> 24),
+                            ((sys.hexversion >> 16) & 0xff))
+    strLinkSpec += strWrk
+else:
+    # This is not ideal since it changes the search path
+    # for Frameworks which could have side-effects on
+    # other included Frameworks.  However, it is necessary
+    # where someone has installed more than one frameworked
+    # Python.  Frameworks are really only used in MacOSX.
+    strLibFW = dictConfig.get("PYTHONFRAMEWORKPREFIX")
+    if strLibFW and (strLibFW != ""):
+        strLinkSpec += " -F%s" % (strLibFW)
+strLinkSpec += " %s" % (dictConfig.get('LINKFORSHARED'))
+print strLinkSpec
+        ])
+        AC_SUBST([PYTHON_LSPEC], [${az_python_output}])
+        AC_MSG_NOTICE([PYTHON_LSPEC=${az_python_output}])
+    fi
+])
+
+
+
+# AZ_PYTHON_PATH( )
+# -----------------
+# Look for Python and set the output variable 'PYTHON'
+# to 'python' if found, empty otherwise.
+
+AC_DEFUN([AZ_PYTHON_PATH],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    AC_PATH_PROG( PYTHON, python, [], $1 )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    else
+        az_python_use=true
+    fi
+    AM_CONDITIONAL(ENABLE_PYTHON, test "$az_python_use" = "true")
+])
+
+
+
+# AZ_PYTHON_PREFIX( )
+# -------------------
+# Use the values of $prefix and $exec_prefix for the corresponding
+# values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX.
+
+AC_DEFUN([AZ_PYTHON_PREFIX],
+[
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable Path is not known])
+    fi
+    ax_python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
+    ax_python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
+    AC_SUBST([PYTHON_PREFIX], ["${ax_python_prefix}"])
+    AC_SUBST([PYTHON_EXECPREFIX], ["${ax_python_execprefix}"])
+])
+
+
+
+# AZ_PYTHON_RUN( PYTHON_PROGRAM )
+# -----------------
+# Run a Python Test Program saving its output
+# in az_python_output and its condition code
+# in az_python_cc.
+
+AC_DEFUN([AZ_PYTHON_RUN],
+[
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -z "$PYTHON"
+    then
+        AC_MSG_ERROR([Python Executable not found])
+    else
+        cat >conftest.py <<_ACEOF
+$1
+_ACEOF
+        az_python_output=`$PYTHON conftest.py`
+        az_python_cc=$?
+        rm conftest.py
+        if test -f "conftest.pyc"
+        then
+            rm conftest.pyc
+        fi
+    fi
+])
+
+
+
+# AZ_PYTHON_VERSION_CHECK( VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE] )
+# -----------------------------------------------------------------------------
+# Run ACTION-IF-TRUE if the Python interpreter has version >= VERSION.
+# Run ACTION-IF-FALSE otherwise.
+# This test uses sys.hexversion instead of the string equivalant (first
+# word of sys.version), in order to cope with versions such as 2.2c1.
+# hexversion has been introduced in Python 1.5.2; it's probably not
+# worth to support older versions (1.5.1 was released on October 31, 1998).
+
+AC_DEFUN([AZ_PYTHON_VERSION_CHECK],
+ [
+    AC_ARG_VAR( [PYTHON], [Python Executable Path] )
+    if test -n "$PYTHON"
+    then
+        AC_MSG_CHECKING([whether $PYTHON version >= $1])
+        AZ_PYTHON_RUN([
+import sys, string
+# split strings by '.' and convert to numeric.  Append some zeros
+# because we need at least 4 digits for the hex conversion.
+minver = map(int, string.split('$1', '.')) + [[0, 0, 0]]
+minverhex = 0
+for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[[i]]
+if sys.hexversion >= minverhex:
+    sys.exit( 0 )
+else:
+    sys.exit( 1 )
+        ])
+        if test $az_python_cc -eq 0
+        then
+            $2
+        m4_ifvaln(
+            [$3],
+            [else $3]
+        )
+        fi
+    fi
+])
+
+
+
+# AZ_PYTHON_VERSION_ENSURE( VERSION )
+# -----------------
+# Insure that the Python Interpreter Version
+# is greater than or equal to the VERSION
+# parameter.
+
+AC_DEFUN([AZ_PYTHON_VERSION_ENSURE],
+[
+    AZ_PYTHON_VERSION_CHECK(
+        [$1],
+        [AC_MSG_RESULT(yes)],
+        [AC_MSG_ERROR(too old)]
+    )
+])
+
+
+
+# AZ_PYTHON_WITH( [path] )
+# -----------------------------------------------------------------
+# Handles the various --with-python commands.
+# Input:
+#   $1 is the optional search path for the python executable if needed
+# Ouput:
+#   ENABLE_PYTHON (AM_CONDITIONAL) is true if python executable found
+#   and --with-python was requested; otherwise false.
+#   $PYTHON contains the full executable path to python if ENABLE_PYTHON
+#   is true.
+#
+# Example:
+#   AZ_PYTHON_WITH( )
+#   or
+#   AZ_PYTHON_WITH("/usr/bin")
+
+AC_DEFUN([AZ_PYTHON_WITH],
+[
+    AC_ARG_VAR([PYTHON],[Python Executable Path])
+
+    # unless PYTHON was supplied to us (as a precious variable),
+    # see if --with-python[=PythonExecutablePath], --with-python,
+    # --without-python or --with-python=no was given.
+    if test -z "$PYTHON"
+    then
+        AC_MSG_CHECKING(for --with-python)
+        AC_ARG_WITH(
+            python,
+            AC_HELP_STRING([--with-python@<:@=PYTHON@:>@],
+                [absolute path name of Python executable]
+            ),
+            [
+                if test "$withval" = "yes"
+                then
+                    # "yes" was specified, but we don't have a path
+                    # for the executable.
+                    # So, let's searth the PATH Environment Variable.
+                    AC_MSG_RESULT(yes)
+                    AC_PATH_PROG(
+                        [PYTHON],
+                        python,
+                        [],
+                        $1
+                    )
+                    if test -z "$PYTHON"
+                    then
+                        AC_MSG_ERROR(no path to python found)
+                    fi
+                    az_python_use=true
+                    AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+                    AZ_PYTHON_PREFIX( )
+                elif test "$withval" = "no"
+                then
+                    AC_MSG_RESULT(no)
+                    az_python_use=false
+                    AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+                else
+                    # $withval must be the executable path then.
+                    AC_SUBST([PYTHON], ["${withval}"])
+                    AC_MSG_RESULT($withval)
+                    az_python_use=true
+                    AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+                    AZ_PYTHON_PREFIX( )
+                fi
+            ],
+            [
+                # --with-python was not specified.
+                AC_MSG_RESULT(no)
+                az_python_use=false
+                AM_CONDITIONAL(ENABLE_PYTHON, test x"$az_python_use" = x"true")
+            ]
+        )
+    fi
+
+])
+
index 3e873ed1db0f6e830a20cf724cf354c3c7c825bb..1a65af749b434d2b7c934b39e3d10fb043d2115e 100644 (file)
@@ -1,28 +1,24 @@
 dnl m4/classpath.m4
 dnl
-dnl Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
-dnl C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-dnl E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-dnl J. Wenninger, Institut f. Computersprachen - TU Wien
-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
 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
 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
 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 
-dnl $Id: classpath.m4 8398 2007-08-22 16:56:45Z twisti $
 
 
 dnl which Java core library should we use
@@ -80,14 +76,14 @@ dnl where are Java core library classes installed
 AC_DEFUN([AC_CHECK_WITH_CLASSPATH_CLASSES],[
 AC_MSG_CHECKING(where Java core library classes are installed)
 AC_ARG_WITH([classpath-classes],
-            [AS_HELP_STRING(--with-classpath-classes=<path>,path to Java core library classes (includes the name of the file and may be flat) [[default=CLASSPATH_PREFIX/{share/classpath/glibj.zip,classes}]])],
+            [AS_HELP_STRING(--with-classpath-classes=<path>,path to Java core library classes (includes the name of the file and may be flat) [[default=(gnu:${CLASSPATH_PREFIX}/share/classpath/glibj.zip,sun:${CLASSPATH_PREFIX}/control/build/${OS_DIR}-${JAVA_ARCH}/classes,*:${CLASSPATH_PREFIX})]])],
             [CLASSPATH_CLASSES=${withval}],
             [case "${WITH_CLASSPATH}" in
                  gnu)
                      CLASSPATH_CLASSES=${CLASSPATH_PREFIX}/share/classpath/glibj.zip
                      ;;
                  sun)
-                     CLASSPATH_CLASSES=${CLASSPATH_PREFIX}/classes
+                     CLASSPATH_CLASSES=${CLASSPATH_PREFIX}/control/build/${OS_DIR}-${JAVA_ARCH}/classes
                      ;;
                  *)
                      CLASSPATH_CLASSES=${CLASSPATH_PREFIX}
@@ -96,6 +92,17 @@ AC_ARG_WITH([classpath-classes],
 AC_MSG_RESULT(${CLASSPATH_CLASSES})
 AC_DEFINE_UNQUOTED([CLASSPATH_CLASSES], "${CLASSPATH_CLASSES}", [Java core library classes])
 AC_SUBST(CLASSPATH_CLASSES)
+
+dnl define BOOTCLASSPATH for Makefiles
+case "${WITH_CLASSPATH}" in
+    cldc1.1 | gnu)
+        BOOTCLASSPATH="\$(top_builddir)/src/classes/classes:\$(CLASSPATH_CLASSES)"
+        ;;
+    *)
+        BOOTCLASSPATH="\$(CLASSPATH_CLASSES)"
+        ;;
+esac
+AC_SUBST(BOOTCLASSPATH)
 ])
 
 
@@ -104,14 +111,14 @@ dnl where are Java core library native libraries installed
 AC_DEFUN([AC_CHECK_WITH_CLASSPATH_LIBDIR],[
 AC_MSG_CHECKING(where Java core library native libraries are installed)
 AC_ARG_WITH([classpath-libdir],
-            [AS_HELP_STRING(--with-classpath-libdir=<dir>,installation directory of Java core library native libraries [[default=CLASSPATH_PREFIX/{lib,lib/${JAVA_ARCH}]])],
+            [AS_HELP_STRING(--with-classpath-libdir=<dir>,installation directory of Java core library native libraries [[default=(gnu:${CLASSPATH_PREFIX}/lib,sun:${CLASSPATH_PREFIX}/control/build/${OS_DIR}-${JAVA_ARCH}/lib/${JAVA_ARCH},*:${CLASSPATH_PREFIX})]])],
             [CLASSPATH_LIBDIR=${withval}],
             [case "${WITH_CLASSPATH}" in
                  gnu)
                      CLASSPATH_LIBDIR=${CLASSPATH_PREFIX}/lib
                      ;;
                  sun)
-                     CLASSPATH_LIBDIR=${CLASSPATH_PREFIX}/lib/${JAVA_ARCH}
+                     CLASSPATH_LIBDIR=${CLASSPATH_PREFIX}/control/build/${OS_DIR}-${JAVA_ARCH}/lib/${JAVA_ARCH}
                      ;;
                  *)
                      CLASSPATH_LIBDIR=${CLASSPATH_PREFIX}
@@ -126,29 +133,54 @@ AC_SUBST(CLASSPATH_LIBDIR)
 ])
 
 
-dnl where are Java core library headers installed
-
-AC_DEFUN([AC_CHECK_WITH_CLASSPATH_INCLUDEDIR],[
-AC_MSG_CHECKING(where Java core library headers are installed)
-AC_ARG_WITH([classpath-includedir],
-            [AS_HELP_STRING(--with-classpath-includedir=<dir>,installation directory of Java core library headers [[default=/usr/local/classpath/include]])],
-            [CLASSPATH_INCLUDEDIR=${withval}],
-            [CLASSPATH_INCLUDEDIR=${CLASSPATH_PREFIX}/include])
-AC_MSG_RESULT(${CLASSPATH_INCLUDEDIR})
-
-if test x"${WITH_CLASSPATH}" = "xsun"; then
-    AC_CHECK_HEADER([${CLASSPATH_INCLUDEDIR}/${OS_DIR}/jni_md.h],
-                    [AC_DEFINE_UNQUOTED([CLASSPATH_JNI_MD_H], "${CLASSPATH_INCLUDEDIR}/${OS_DIR}/jni_md.h", [Java core library jni_md.h header])],
-                    [AC_MSG_ERROR(cannot find jni_md.h)])
-else
-    AC_CHECK_HEADER([${CLASSPATH_INCLUDEDIR}/jni_md.h],
-                    [AC_DEFINE_UNQUOTED([CLASSPATH_JNI_MD_H], "${CLASSPATH_INCLUDEDIR}/jni_md.h", [Java core library jni_md.h header])],
-                    [AC_MSG_ERROR(cannot find jni_md.h)])
-fi
-
-AC_CHECK_HEADER([${CLASSPATH_INCLUDEDIR}/jni.h],
-                [AC_DEFINE_UNQUOTED([CLASSPATH_JNI_H], "${CLASSPATH_INCLUDEDIR}/jni.h", [Java core library jni.h header])],
+dnl where jni_md.h is installed
+
+AC_DEFUN([AC_CHECK_WITH_JNI_MD_H],[
+AC_MSG_CHECKING(where jni_md.h is installed)
+AC_ARG_WITH([jni_md_h],
+            [AS_HELP_STRING(--with-jni_md_h=<dir>,path to jni_md.h [[default=(sun:${CLASSPATH_PREFIX}/jdk/src/solaris/javavm/export,*:${CLASSPATH_PREFIX}/include)]])],
+            [WITH_JNI_MD_H=${withval}],
+            [case "${WITH_CLASSPATH}" in
+                 sun)
+                     WITH_JNI_MD_H=${CLASSPATH_PREFIX}/jdk/src/solaris/javavm/export
+                     ;;
+                 *)
+                     WITH_JNI_MD_H=${CLASSPATH_PREFIX}/include
+                     ;;
+            esac])
+AC_MSG_RESULT(${WITH_JNI_MD_H})
+
+dnl We use CPPFLAGS so jni.h can find jni_md.h
+CPPFLAGS="${CPPFLAGS} -I${WITH_JNI_MD_H}"
+
+AC_CHECK_HEADER([${WITH_JNI_MD_H}/jni_md.h],
+                [AC_DEFINE_UNQUOTED([INCLUDE_JNI_MD_H], "${WITH_JNI_MD_H}/jni_md.h", [Java core library jni_md.h header])],
+                [AC_MSG_ERROR(cannot find jni_md.h)])
+])
+
+
+dnl where jni.h is installed
+
+AC_DEFUN([AC_CHECK_WITH_JNI_H],[
+AC_MSG_CHECKING(where jni.h is installed)
+AC_ARG_WITH([jni_h],
+            [AS_HELP_STRING(--with-jni_h=<dir>,path to jni.h [[default=(sun:${CLASSPATH_PREFIX}/jdk/src/share/javavm/export,*:${CLASSPATH_PREFIX}/include)]])],
+            [WITH_JNI_H=${withval}],
+            [case "${WITH_CLASSPATH}" in
+                 sun)
+                     WITH_JNI_H=${CLASSPATH_PREFIX}/jdk/src/share/javavm/export
+                     ;;
+                 *)
+                     WITH_JNI_H=${CLASSPATH_PREFIX}/include
+                     ;;
+            esac])
+AC_MSG_RESULT(${WITH_JNI_H})
+
+dnl We use CPPFLAGS so jni.h can find jni_md.h
+CPPFLAGS="${CPPFLAGS} -I${WITH_JNI_H}"
+
+AC_CHECK_HEADER([${WITH_JNI_H}/jni.h],
+                [AC_DEFINE_UNQUOTED([INCLUDE_JNI_H], "${WITH_JNI_H}/jni.h", [Java core library jni.h header])],
                 [AC_MSG_ERROR(cannot find jni.h)],
-                [#define __GCJ_JNI_MD_H__
-                 #include CLASSPATH_JNI_MD_H])
+                [#include INCLUDE_JNI_MD_H])
 ])
index 0a3fdacf4bf9374e6aa3c9a02839dc4e46a04010..29b468c446ba55ddcada529bc7665c10176aca54 100644 (file)
@@ -28,7 +28,7 @@ dnl check for debug
 AC_DEFUN([AC_CHECK_ENABLE_DEBUG],[
 AC_MSG_CHECKING(whether debug code generation should be enabled)
 AC_ARG_ENABLE([debug],
-              [AS_HELP_STRING(--disable-debug,disable debug code generation [[default=yes]])],
+              [AS_HELP_STRING(--disable-debug,disable debug code generation [[default=enabled]])],
               [case "${enableval}" in
                    no)
                        NDEBUG=yes
index fc003fe63992571219ce43937b8a3d91c4d6ea53..77a7c51858692c3b40a6d9d1b4a03679a10f4a36 100644 (file)
@@ -1,9 +1,7 @@
 dnl m4/dump.m4
 dnl
-dnl Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
-dnl C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-dnl E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-dnl J. Wenninger, Institut f. Computersprachen - TU Wien
+dnl Copyright (C) 2007, 2008
+dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 dnl 
 dnl This file is part of CACAO.
 dnl 
@@ -28,14 +26,17 @@ dnl check for dump memory usage
 AC_DEFUN([AC_CHECK_ENABLE_DUMP],[
 AC_MSG_CHECKING(whether dump memory should be disabled)
 AC_ARG_ENABLE([dump],
-              [AS_HELP_STRING(--disable-dump,disable dump memory (for debugging only!) [[default=yes]])],
+              [AS_HELP_STRING(--disable-dump,disable dump memory (for debugging only!) [[default=enabled]])],
               [case "${enableval}" in
                    no)
                        DISABLE_DUMP=yes
                        AC_DEFINE([DISABLE_DUMP], 1, [disable dump memory])
                        ;;
-                   *) DISABLE_DUMP=no;;
+                   *)
+                       DISABLE_DUMP=no
+                       ;;
                esac],
                [DISABLE_DUMP=no])
 AC_MSG_RESULT(${DISABLE_DUMP})
+AM_CONDITIONAL([DISABLE_DUMP], test x"${DISABLE_DUMP}" = "xno")
 ])
diff --git a/m4/hpi.m4 b/m4/hpi.m4
new file mode 100644 (file)
index 0000000..9166e56
--- /dev/null
+++ b/m4/hpi.m4
@@ -0,0 +1,66 @@
+dnl m4/hpi.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 where hpi_md.h is installed
+
+AC_DEFUN([AC_CHECK_WITH_HPI_MD_H],[
+AC_MSG_CHECKING(where hpi_md.h is installed)
+AC_ARG_WITH([hpi_md_h],
+            [AS_HELP_STRING(--with-hpi_md_h=<dir>,path to hpi_md.h (only with --with-classpath=sun) [[default=${CLASSPATH_PREFIX}/jdk/src/solaris/hpi/export]])],
+            [WITH_HPI_MD_H=${withval}],
+            [case "${WITH_CLASSPATH}" in
+                 sun)
+                     WITH_HPI_MD_H=${CLASSPATH_PREFIX}/jdk/src/solaris/hpi/export
+                     ;;
+                 *)
+                     ;;
+            esac])
+AC_MSG_RESULT(${WITH_HPI_MD_H})
+
+dnl We use CPPFLAGS so hpi.h can find hpi_md.h
+CPPFLAGS="${CPPFLAGS} -I${WITH_HPI_MD_H}"
+
+AC_CHECK_HEADER([${WITH_HPI_MD_H}/hpi_md.h],
+                [AC_DEFINE_UNQUOTED([INCLUDE_HPI_MD_H], "${WITH_HPI_MD_H}/hpi_md.h", [Java core library hpi_md.h header])],
+                [AC_MSG_ERROR(cannot find hpi_md.h)])
+])
+
+
+dnl where hpi.h is installed
+
+AC_DEFUN([AC_CHECK_WITH_HPI_H],[
+AC_MSG_CHECKING(where hpi.h is installed)
+AC_ARG_WITH([hpi_h],
+            [AS_HELP_STRING(--with-hpi_h=<dir>,path to hpi.h (only with --with-classpath=sun) [[default=${CLASSPATH_PREFIX}/jdk/src/share/hpi/export]])],
+            [WITH_HPI_H=${withval}],
+            [WITH_HPI_H=${CLASSPATH_PREFIX}/jdk/src/share/hpi/export])
+AC_MSG_RESULT(${WITH_HPI_H})
+
+dnl We use CPPFLAGS so hpi.h can find hpi_md.h
+CPPFLAGS="${CPPFLAGS} -I${WITH_HPI_H}"
+
+AC_CHECK_HEADER([${WITH_HPI_H}/hpi.h],
+                [AC_DEFINE_UNQUOTED([INCLUDE_HPI_H], "${WITH_HPI_H}/hpi.h", [Java core library hpi.h header])],
+                [AC_MSG_ERROR(cannot find hpi.h)],
+                [#include INCLUDE_HPI_MD_H])
+])
index 5f42f34cbd1ec52e32407761a8aec95198f13d46..3cd8dc0d06ca0acd724ee81710b9f658ba7a9295 100644 (file)
--- a/m4/jit.m4
+++ b/m4/jit.m4
@@ -28,7 +28,7 @@ dnl check for JIT compiler
 AC_DEFUN([AC_CHECK_ENABLE_JIT],[
 AC_MSG_CHECKING(whether JIT compiler should be compiled)
 AC_ARG_ENABLE([jit],
-              [AS_HELP_STRING(--disable-jit,disable JIT compiler [[default=yes]])],
+              [AS_HELP_STRING(--disable-jit,disable JIT compiler [[default=enabled]])],
               [case "${enableval}" in
                    no)
                        ENABLE_JIT=no
index 6dd13439e1bdd4599ace147a512bc9cf8b2c17e9..e5399555c50e2ad26ad4d499135026bac248f9a0 100644 (file)
--- a/m4/jni.m4
+++ b/m4/jni.m4
@@ -1,9 +1,7 @@
 dnl m4/jni.m4
 dnl
-dnl Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
-dnl C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-dnl E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-dnl J. Wenninger, Institut f. Computersprachen - TU Wien
+dnl Copyright (C) 2007, 2008
+dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 dnl 
 dnl This file is part of CACAO.
 dnl 
@@ -28,7 +26,7 @@ dnl check if JNI should be enabled
 AC_DEFUN([AC_CHECK_ENABLE_JNI],[
 AC_MSG_CHECKING(whether JNI should be enabled)
 AC_ARG_ENABLE([jni],
-              [AS_HELP_STRING(--enable-jni,enable JNI [[default=yes]])],
+              [AS_HELP_STRING(--enable-jni,enable JNI [[default=(cldc1.1:no,javase:yes)]])],
               [case "${enableval}" in
                   yes)
                       ENABLE_JNI=yes
index 1f563e85630f2541f0dc329aeaa672a470df389a..29184d56140d06cbc2f939e2005dbc9291860cb7 100644 (file)
@@ -1,9 +1,7 @@
 dnl m4/jre-layout.m4
 dnl
-dnl Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
-dnl C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-dnl E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-dnl J. Wenninger, Institut f. Computersprachen - TU Wien
+dnl Copyright (C) 2007, 2008
+dnl CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 dnl 
 dnl This file is part of CACAO.
 dnl 
@@ -25,19 +23,19 @@ dnl 02110-1301, USA.
 
 dnl if we compile for a JRE-style directory layout
 
-AC_DEFUN([AC_CHECK_WITH_JRE_LAYOUT],[
+AC_DEFUN([AC_CHECK_ENABLE_JRE_LAYOUT],[
 AC_MSG_CHECKING(if we compile for a JRE-style directory layout)
-AC_ARG_WITH([jre-layout],
-            [AS_HELP_STRING(--with-jre-layout,compile for JRE-style directory layout [[default=no]])],
-            [case "${enableval}" in
-                yes)
-                    WITH_JRE_LAYOUT=yes
-                    AC_DEFINE([WITH_JRE_LAYOUT], 1, [with JRE layout])
-                    ;;
-                *)
-                    WITH_JRE_LAYOUT=no
-                    ;;
-             esac],
-            [WITH_JRE_LAYOUT=no])
-AC_MSG_RESULT(${WITH_JRE_LAYOUT})
+AC_ARG_ENABLE([jre-layout],
+              [AS_HELP_STRING(--enable-jre-layout,compile for JRE-style directory layout [[default=disabled]])],
+              [case "${enableval}" in
+                  yes)
+                      ENABLE_JRE_LAYOUT=yes
+                      AC_DEFINE([ENABLE_JRE_LAYOUT], 1, [enable JRE layout])
+                      ;;
+                  *)
+                      ENABLE_JRE_LAYOUT=no
+                      ;;
+               esac],
+              [ENABLE_JRE_LAYOUT=no])
+AC_MSG_RESULT(${ENABLE_JRE_LAYOUT})
 ])
index e40144f5c4758576b9711a83fc3b9c72540ee6f0..77e87a778623aea06aab2fd6e8f20a2041d00776 100644 (file)
@@ -28,7 +28,7 @@ dnl check if a libjvm.so should be built
 AC_DEFUN([AC_CHECK_ENABLE_LIBJVM],[
 AC_MSG_CHECKING(whether to build a libjvm.so)
 AC_ARG_ENABLE([libjvm],
-              [AS_HELP_STRING(--disable-libjvm,build a libjvm.so [[default=yes]])],
+              [AS_HELP_STRING(--disable-libjvm,build a libjvm.so [[default=enabled]])],
               [case "${enableval}" in
                   no)
                       ENABLE_LIBJVM=no
index 6e68960a97c86464a200ad0978d7364dbe30170a..6a7b174ca88aaca0af3e0546bb3f8b6ce72e28bf 100644 (file)
@@ -28,7 +28,7 @@ dnl check if ltdl should be used
 AC_DEFUN([AC_CHECK_ENABLE_LTDL],[
 AC_MSG_CHECKING(whether ltdl should be used)
 AC_ARG_ENABLE([ltdl],
-              [AS_HELP_STRING(--disable-ltdl,disable ltdl support [[default=yes]])],
+              [AS_HELP_STRING(--disable-ltdl,disable ltdl support [[default=enabled]])],
               [case "${enableval}" in
                   no)
                       ENABLE_LTDL=no
index 42a83ac49313704c4ebc06daf6674f6486be406d..28c204442ee521b09554d72f3a6ec1028d128fda 100644 (file)
@@ -28,7 +28,7 @@ dnl check if zlib should be used
 AC_DEFUN([AC_CHECK_ENABLE_ZLIB],[
 AC_MSG_CHECKING(whether ZIP/JAR archives should be supported)
 AC_ARG_ENABLE([zlib],
-              [AS_HELP_STRING(--disable-zlib,disable ZIP/JAR archive support (needs zlib) [[default=yes]])],
+              [AS_HELP_STRING(--disable-zlib,disable ZIP/JAR archive support (needs zlib) [[default=enabled]])],
               [case "${enableval}" in
                   no) ENABLE_ZLIB=no;;
                   *) ENABLE_ZLIB=yes;;
index 8e93d07171a91791cd4eb94556c316b2af8918f5..329088b65e68ea2a4b45f0ecfe464faddcc6bdc9 100644 (file)
@@ -1,9 +1,7 @@
 ## man/Makefile.am
 ##
-## 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.
 ##
 ## 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
-##
-## Changes:
 
-## Process this file with automake to produce Makefile.in
 
 man_MANS = cacao.1
 
-EXTRA_DIST = $(man_MANS)
+EXTRA_DIST = \
+       $(man_MANS)
 
 
 ## Local variables:
index b1c82505acbbe59212e51ea6cb518c6afcf7b754..19bd98346f808df7f1476451d60b8aebde798d6b 100644 (file)
@@ -1,9 +1,7 @@
 ## src/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.
 ##
@@ -26,8 +24,8 @@
 DIST_SUBDIRS = \
        cacao \
        cacaoh \
+       classes \
        fdlibm \
-       lib \
        mm \
        native \
        scripts \
@@ -36,11 +34,6 @@ DIST_SUBDIRS = \
        vm \
        vmcore
 
-if ENABLE_THREADS
-THREADS_DIR = \
-       threads
-endif
-
 if ENABLE_CACAOH
 CACAOH_DIR = \
        cacaoh 
@@ -52,11 +45,11 @@ SUBDIRS = \
        toolbox \
        vmcore \
        $(CACAOH_DIR) \
-       lib \
+       classes \
        native \
        fdlibm \
        mm \
-       $(THREADS_DIR) \
+       threads \
        vm \
        cacao \
        scripts
index 16529cdceba3c2d99abd757a7e83f6adb2e9be1b..c823692e9e9f4242ab4b4055f5d65c79242005cd 100644 (file)
@@ -1,9 +1,7 @@
 ## src/cacao/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.
 ##
 ## 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
 
-## Process this file with automake to produce Makefile.in
 
 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_THREADS
-THREAD_LIB = \
-       $(top_builddir)/src/threads/libthreads.la
-endif
-
 if ENABLE_STATICVM
 cacao_LDFLAGS = \
        -all-static
@@ -45,7 +35,7 @@ lib_LTLIBRARIES = \
        libjvm.la
 
 libjvm_la_LDFLAGS = \
-       -release $(PACKAGE_VERSION)
+       -version-info 1:0:0
 
 if WITH_CLASSPATH_SUN
 libjvm_la_LDFLAGS += \
@@ -71,17 +61,22 @@ if ENABLE_RT_TIMING
 cacao_LDFLAGS += -lrt
 endif
 
+if ENABLE_PYTHON
+cacao_LDFLAGS += \
+    @PYTHON_LSPEC@
+endif
+
 libjvm_la_SOURCES =
 
 libjvm_la_LIBADD = \
        $(top_builddir)/src/fdlibm/libfdlibm.la \
        $(top_builddir)/src/mm/libmm.la \
        $(top_builddir)/src/native/libnative.la \
+       $(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) \
-       $(THREAD_LIB)
+       $(GC_LIB)
 
 bin_PROGRAMS = \
        cacao
index 8ab94aaedf97396bfe5a04fd18b4478cd337ebf5..1f19362584b7ec0df5c8f1f8a09ec52562828e5c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/cacao/cacao.c - contains main() of cacao
 
-   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.
 
@@ -33,7 +31,7 @@
 # include <ltdl.h>
 #endif
 
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
 # include <errno.h>
 # include <libgen.h>
 # include <unistd.h>
@@ -49,6 +47,7 @@
 #if defined(ENABLE_JVMTI)
 # include "native/jvmti/jvmti.h"
 # include "native/jvmti/cacaodbg.h"
+# include "threads/mutex.h"
 #endif
 
 #include "vm/vm.h"
@@ -93,7 +92,7 @@ int main(int argc, char **argv)
        /* load and initialize a Java VM, return a JNI interface pointer in env */
 
 #if defined(ENABLE_LIBJVM)
-# if defined(WITH_JRE_LAYOUT)
+# if defined(ENABLE_JRE_LAYOUT)
        /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
 
        path = malloc(sizeof(char) * 4096);
@@ -162,7 +161,7 @@ int main(int argc, char **argv)
        (void) vm_createjvm(&vm, (void *) &env, vm_args);
 
 #if defined(ENABLE_JVMTI)
-       pthread_mutex_init(&dbgcomlock,NULL);
+       mutex_init(&dbgcomlock);
        if (jvmti) jvmti_set_phase(JVMTI_PHASE_START);
 #endif
 
index 07e80cdf2ecbe9b13c0fa4023aef22edc19afcfe..7ab1d640554796ce9a8505973057c970db3f519f 100644 (file)
@@ -1,9 +1,7 @@
 ## src/cacaoh/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.
 ##
index 91177b244e28f822f038e7e21d7fc2c7aa551bea..09aab9cba11affc0b6b8edc50ab357a7a0145a33 100644 (file)
@@ -261,11 +261,7 @@ int main(int argc, char **argv)
                log_println("Java - header-generator started"); 
        }
 
-       /* initialize the utf8 hashtable stuff: lock, often used utf8 strings
-          (must be done _after_ threads_preinit) */
-
-       if (!utf8_init())
-               vm_abort("utf8_init failed\n");
+       utf8_init();
 
        /* initialize the classcache hashtable stuff: lock, hashtable
           (must be done _after_ threads_preinit) */
index eb0b68d9277ac51c9a570e0cf312a694e4f51d38..82c994a2eab6e89703e6e074617bc811ca44475b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/cacaoh/dummy.c - dummy functions for cacaoh
 
-   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 "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/method.h"
-#include "vmcore/utf8.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 ***********************************************************/
@@ -146,37 +151,30 @@ void intrp_asm_abstractmethoderror(void)
        abort();
 }
 
-void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out)
-{
-       abort();
-}
-
-void intrp_asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out)
-{
-       abort();
-}
-
 
 /* builtin ********************************************************************/
 
 java_handle_t *builtin_clone(void *env, java_handle_t *o)
 {
-       abort();
-
+       vm_abort("builtin_clone: Not implemented.");
        return NULL;
 }
 
-int32_t builtin_isanysubclass(classinfo *sub, classinfo *super)
+bool builtin_isanysubclass(classinfo *sub, classinfo *super)
 {
-       abort();
+       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)
 {
-       abort();
-
+       vm_abort("builtin_new: Not implemented.");
        return NULL;
 }
 
@@ -216,7 +214,7 @@ void code_free_code_of_method(methodinfo *m)
 }
 
 
-methodinfo *code_get_methodinfo_for_pv(u1 *pv)
+methodinfo *code_get_methodinfo_for_pv(void *pv)
 {
        return NULL;
 }
@@ -296,7 +294,7 @@ void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
        abort();
 }
 
-void exceptions_throw_incompatibleclasschangeerror(classinfo *c)
+void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
 {
        fprintf(stderr, "java.lang.IncompatibleClassChangeError: ");
 
@@ -353,7 +351,7 @@ void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
        abort();
 }
 
-void exceptions_throw_verifyerror(methodinfo *m, const char *message)
+void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
 {
        fprintf(stderr, "java.lang.VerifyError: ");
        utf_fprint_printable_ascii(stderr, m->name);
@@ -385,21 +383,11 @@ void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
        abort();
 }
 
-void exceptions_throw_unsupportedclassversionerror(classinfo *c,
-                                                                                                  const char *message, ...)
+void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
 {
-       va_list ap;
-
        fprintf(stderr, "java.lang.UnsupportedClassVersionError: " );
-
        utf_display_printable_ascii(c->name);
-       fprintf(stderr, ": ");
-
-       va_start(ap, message);
-       vfprintf(stderr, message, ap);
-       va_end(ap);
-
-       fputc('\n', stderr);
+       fprintf(stderr, " (Unsupported major.minor version %d.%d)\n", ma, mi);
 
        abort();
 }
@@ -464,7 +452,7 @@ int64_t gc_get_max_heap_size(void)
 
 /* heap ***********************************************************************/
 
-void *heap_alloc_uncollectable(uint32_t bytelength)
+void *heap_alloc_uncollectable(size_t bytelength)
 {
        return calloc(bytelength, 1);
 }
@@ -557,18 +545,18 @@ void mem_free(void *m, int32_t size)
        free(m);
 }
 
-void *dump_alloc(int32_t size)
+void *dumpmemory_get(size_t size)
 {
        return malloc(size);
 }
 
-void dump_release(int32_t size)
+int32_t dumpmemory_marker(void)
 {
+       return 0;
 }
 
-int32_t dump_size(void)
+void dumpmemory_release(int32_t size)
 {
-       return 0;
 }
 
 
@@ -613,8 +601,34 @@ char *properties_get(char *key)
 }
 
 
+/* 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();
@@ -746,15 +760,36 @@ void vm_abort(const char *text, ...)
 {
        va_list ap;
 
-       /* print the log message */
-
        va_start(ap, text);
        vfprintf(stderr, text, ap);
        va_end(ap);
 
-       /* now abort the VM */
+       system_abort();
+}
 
-       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, ...)
@@ -783,6 +818,21 @@ 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
index d3b080f26ce40db038b70464f1c479bfeaaf0939..8d9c42fc921bfb6e9b2870e412b1f931b9dd7cf0 100644 (file)
@@ -1,9 +1,7 @@
 /* src/cacaoh/headers.c - 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -285,7 +283,7 @@ void printmethod(methodinfo *m)
 
        /* create remarks */
        fprintf(file, "\n/*\n * Class:     ");
-       utf_fprint_printable_ascii(file, m->class->name);
+       utf_fprint_printable_ascii(file, m->clazz->name);
        fprintf(file, "\n * Method:    ");
        utf_fprint_printable_ascii(file, m->name);
        fprintf(file, "\n * Signature: ");
@@ -296,7 +294,7 @@ void printmethod(methodinfo *m)
        fprintf(file, "JNIEXPORT ");
        printtype(utf_ptr, "", "_handle");
        fprintf(file, " JNICALL Java_");
-       printID(m->class->name);
+       printID(m->clazz->name);
 
        chain_addlast(ident_chain, m->name);
 
@@ -314,7 +312,7 @@ void printmethod(methodinfo *m)
                        
        if (!(m->flags & ACC_STATIC)) {
                fprintf(file, ", struct ");
-               printID(m->class->name);
+               printID(m->clazz->name);
                fprintf(file, "* this");
 
        } else {
diff --git a/src/classes/Makefile.am b/src/classes/Makefile.am
new file mode 100644 (file)
index 0000000..72c9027
--- /dev/null
@@ -0,0 +1,124 @@
+## src/lib/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.
+
+
+EXTRA_DIST = \
+       $(VM_JAVA_FILES_GNU) \
+       $(VM_JAVA_FILES_GNU_ANNOTATIONS) \
+       $(VM_JAVA_FILES_CLDC1_1)
+
+CLEANFILES = vm.zip
+
+VM_JAVA_FILES_GNU = \
+       $(top_srcdir)/src/classes/gnu/gnu/classpath/VMStackWalker.java \
+       $(top_srcdir)/src/classes/gnu/gnu/classpath/VMSystemProperties.java \
+       $(top_srcdir)/src/classes/gnu/gnu/java/lang/VMCPStringBuilder.java \
+       $(top_srcdir)/src/classes/gnu/gnu/java/lang/management/VMMemoryMXBeanImpl.java \
+       $(top_srcdir)/src/classes/gnu/gnu/java/lang/management/VMRuntimeMXBeanImpl.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/VMClassLoader.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/VMString.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/VMThread.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/reflect/VMConstructor.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/reflect/VMField.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/reflect/VMMethod.java \
+       $(top_srcdir)/src/classes/gnu/java/security/VMAccessController.java \
+       $(top_srcdir)/src/classes/gnu/sun/misc/Unsafe.java
+
+# Remove these files when a new GNU Classpath release (> 0.97.1) is
+# available.
+
+VM_JAVA_FILES_GNU += \
+       $(top_srcdir)/src/classes/gnu/java/lang/reflect/Constructor.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/reflect/Field.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/reflect/Method.java \
+       $(top_srcdir)/src/classes/gnu/java/lang/reflect/Modifier.java \
+       $(top_srcdir)/src/classes/gnu/gnu/java/lang/CPStringBuilder.java
+
+VM_JAVA_FILES_GNU_ANNOTATIONS = \
+       $(top_srcdir)/src/classes/gnu/sun/reflect/ConstantPool.java \
+       $(top_srcdir)/src/classes/gnu/sun/reflect/annotation/ExceptionProxy.java \
+       $(top_srcdir)/src/classes/gnu/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java \
+       $(top_srcdir)/src/classes/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java \
+       $(top_srcdir)/src/classes/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java \
+       $(top_srcdir)/src/classes/gnu/sun/reflect/annotation/AnnotationType.java \
+       $(top_srcdir)/src/classes/gnu/sun/reflect/annotation/AnnotationParser.java
+
+VM_JAVA_FILES_CLDC1_1 = \
+       $(top_srcdir)/src/classes/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java
+
+BOOTCLASSPATH = $(top_builddir)/src/classes/classes:$(CLASSPATH_CLASSES)
+
+if WITH_CLASSPATH_GNU
+VM_JAVA_FILES = \
+       $(VM_JAVA_FILES_GNU)
+
+if ENABLE_ANNOTATIONS
+VM_JAVA_FILES += \
+       $(VM_JAVA_FILES_GNU_ANNOTATIONS)
+endif
+
+if ENABLE_ZLIB
+pkgdata_DATA = vm.zip
+else
+pkgdata_DATA = nozip
+endif
+endif
+
+if WITH_CLASSPATH_CLDC1_1
+VM_JAVA_FILES = \
+       $(VM_JAVA_FILES_CLDC1_1)
+
+if ENABLE_ZLIB
+pkgdata_DATA = vm.zip
+else
+pkgdata_DATA = nozip
+endif
+endif
+
+if ENABLE_ZLIB
+VM_ZIP = ../vm.zip
+
+vm.zip: $(VM_JAVA_FILES)
+       $(mkdir_p) classes
+       $(JAVAC) -bootclasspath $(BOOTCLASSPATH) -source 1.5 -target 1.5 -d classes $(VM_JAVA_FILES)
+       @if test "$(JAR)" = "zip" -o "$(JAR)" = "zip.exe"; then \
+           cd classes && $(JAR) -r -D $(VM_ZIP) .; \
+       else \
+           cd classes && $(JAR) cvf $(VM_ZIP) .; \
+       fi
+else
+nozip: $(VM_JAVA_FILES)
+       $(mkdir_p) classes
+       $(JAVAC) -bootclasspath $(BOOTCLASSPATH) -source 1.5 -target 1.5 -d classes $(VM_JAVA_FILES)
+endif
+
+clean-local:
+       -rm -rf classes
+
+
+## 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/classes/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java b/src/classes/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java
new file mode 100644 (file)
index 0000000..42aeb40
--- /dev/null
@@ -0,0 +1,33 @@
+/* src/lib/com/sun/cldchi/jvm/FileDescriptor.java
+
+   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.
+
+*/
+
+package com.sun.cldchi.jvm;
+
+class FileDescriptor {
+    long pointer;
+    int position;
+    int length;
+}
diff --git a/src/classes/gnu/gnu/classpath/VMStackWalker.java b/src/classes/gnu/gnu/classpath/VMStackWalker.java
new file mode 100644 (file)
index 0000000..434edd2
--- /dev/null
@@ -0,0 +1,135 @@
+/* VMStackWalker.java -- Reference implementation of VM hooks for stack access
+   Copyright (C) 2005 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.classpath;
+
+/**
+ * This class provides access to the classes on the Java stack
+ * for reflection and security purposes.
+ *
+ * <p>
+ * This class is only available to privileged code (i.e., code loaded
+ * by the bootstrap loader).
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Archie Cobbs
+ */
+public final class VMStackWalker
+{
+  /**
+   * Get a list of all the classes currently executing methods on the
+   * Java stack. <code>getClassContext()[0]</code> is the class associated
+   * with the currently executing method, i.e., the method that called
+   * <code>VMStackWalker.getClassContext()</code> (possibly through
+   * reflection). So you may need to pop off these stack frames from
+   * the top of the stack:
+   * <ul>
+   * <li><code>VMStackWalker.getClassContext()</code>
+   * <li><code>Method.invoke()</code>
+   * </ul>
+   *
+   * @return an array of the declaring classes of each stack frame
+   */
+  public static native Class[] getClassContext();
+
+  /**
+   * Get the class associated with the method invoking the method
+   * invoking this method, or <code>null</code> if the stack is not
+   * that deep (e.g., invoked via JNI invocation API). This method
+   * is an optimization for the expression <code>getClassContext()[1]</code>
+   * and should return the same result.
+   *
+   * <p>
+   * VM implementers are encouraged to provide a more efficient
+   * version of this method.
+   */
+//    public static Class getCallingClass()
+//    {
+//      Class[] ctx = getClassContext();
+//      if (ctx.length < 3)
+//        return null;
+//      return ctx[2];
+//    }
+  public static native Class getCallingClass();
+
+  /**
+   * Get the class loader associated with the Class returned by
+   * <code>getCallingClass()</code>, or <code>null</code> if no such class
+   * exists or it is the boot loader. This method is an optimization for the
+   * expression <code>VMStackWalker.getClassLoader(getClassContext()[1])</code>
+   * and should return the same result.
+   *
+   * <p>
+   * VM implementers are encouraged to provide a more efficient
+   * version of this method.
+   */
+//    public static ClassLoader getCallingClassLoader()
+//    {
+//      Class[] ctx = getClassContext();
+//      if (ctx.length < 3)
+//        return null;
+//      return getClassLoader(ctx[2]);
+//    }
+  public static native ClassLoader getCallingClassLoader();
+
+
+  /**
+   * Retrieve the class's ClassLoader, or <code>null</code> if loaded
+   * by the bootstrap loader. I.e., this should return the same thing
+   * as {@link java.lang.VMClass#getClassLoader}. This duplicate version
+   * is here to work around access permissions.
+   */
+//    public static native ClassLoader getClassLoader(Class cl);
+
+  /**
+   * Walk up the stack and return the first non-null class loader.
+   * If there aren't any non-null class loaders on the stack, return null.
+   */
+//   public static ClassLoader firstNonNullClassLoader()
+//   {
+//     Class[] stack = getClassContext();
+//     for (int i = 0; i < stack.length; i++)
+//       {
+//         ClassLoader loader = getClassLoader(stack[i]);
+//         if (loader != null)
+//           return loader;
+//       }
+//     return null;
+//   }
+    public static native ClassLoader firstNonNullClassLoader();
+}
diff --git a/src/classes/gnu/gnu/classpath/VMSystemProperties.java b/src/classes/gnu/gnu/classpath/VMSystemProperties.java
new file mode 100644 (file)
index 0000000..287a933
--- /dev/null
@@ -0,0 +1,98 @@
+/* VMSystemProperties.java -- Allow the VM to set System properties.
+   Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.classpath;
+
+import java.util.Properties;
+
+class VMSystemProperties
+{
+    /**
+     * Get the system properties. This is done here, instead of in System,
+     * because of the bootstrap sequence. Note that the native code should
+     * not try to use the Java I/O classes yet, as they rely on the properties
+     * already existing. The only safe method to use to insert these default
+     * system properties is {@link Properties#setProperty(String, String)}.
+     *
+     * <p>These properties MUST include:
+     * <dl>
+     * <dt>java.version         <dd>Java version number
+     * <dt>java.vendor          <dd>Java vendor specific string
+     * <dt>java.vendor.url      <dd>Java vendor URL
+     * <dt>java.home            <dd>Java installation directory
+     * <dt>java.vm.specification.version <dd>VM Spec version
+     * <dt>java.vm.specification.vendor  <dd>VM Spec vendor
+     * <dt>java.vm.specification.name    <dd>VM Spec name
+     * <dt>java.vm.version      <dd>VM implementation version
+     * <dt>java.vm.vendor       <dd>VM implementation vendor
+     * <dt>java.vm.name         <dd>VM implementation name
+     * <dt>java.specification.version    <dd>Java Runtime Environment version
+     * <dt>java.specification.vendor     <dd>Java Runtime Environment vendor
+     * <dt>java.specification.name       <dd>Java Runtime Environment name
+     * <dt>java.class.version   <dd>Java class version number
+     * <dt>java.class.path      <dd>Java classpath
+     * <dt>java.library.path    <dd>Path for finding Java libraries
+     * <dt>java.io.tmpdir       <dd>Default temp file path
+     * <dt>java.compiler        <dd>Name of JIT to use
+     * <dt>java.ext.dirs        <dd>Java extension path
+     * <dt>os.name              <dd>Operating System Name
+     * <dt>os.arch              <dd>Operating System Architecture
+     * <dt>os.version           <dd>Operating System Version
+     * <dt>file.separator       <dd>File separator ("/" on Unix)
+     * <dt>path.separator       <dd>Path separator (":" on Unix)
+     * <dt>line.separator       <dd>Line separator ("\n" on Unix)
+     * <dt>user.name            <dd>User account name
+     * <dt>user.home            <dd>User home directory
+     * <dt>user.dir             <dd>User's current working directory
+     * <dt>gnu.cpu.endian       <dd>"big" or "little"
+     * </dl>
+     *
+     * @param properties the Properties object to insert the system properties into
+     */
+    static native void preInit(Properties properties);
+
+    /**
+     * Here you get a chance to overwrite some of the properties set by
+     * the common SystemProperties code. For example, it might be
+     * a good idea to process the properties specified on the command
+     * line here.
+     */
+//     static void postInit(Properties properties)
+//     {
+//     }
+    static native void postInit(Properties properties);
+}
diff --git a/src/classes/gnu/gnu/java/lang/CPStringBuilder.java b/src/classes/gnu/gnu/java/lang/CPStringBuilder.java
new file mode 100644 (file)
index 0000000..978a204
--- /dev/null
@@ -0,0 +1,1084 @@
+/* ClasspathStringBuffer.java -- Growable strings without locking or copying
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang;
+
+import java.io.Serializable;
+
+/**
+ * This class is based on java.lang.AbstractStringBuffer but
+ * without the copying of the string by toString.
+ * If you modify this, please consider also modifying that code.
+ * This code is not thread-safe; limit its use to internal use within
+ * methods.
+ */
+public final class CPStringBuilder
+  implements Serializable, CharSequence, Appendable
+{
+
+  /**
+   * Index of next available character (and thus the size of the current
+   * string contents).  Note that this has permissions set this way so that
+   * String can get the value.
+   *
+   * @serial the number of characters in the buffer
+   */
+  int count;
+
+  /**
+   * The buffer.  Note that this has permissions set this way so that String
+   * can get the value.
+   *
+   * @serial the buffer
+   */
+  char[] value;
+
+  /**
+   * The default capacity of a buffer.
+   */
+  private static final int DEFAULT_CAPACITY = 16;
+
+  /**
+   * Create a new CPStringBuilder with default capacity 16.
+   */
+  public CPStringBuilder()
+  {
+    this(DEFAULT_CAPACITY);
+  }
+
+  /**
+   * Create an empty <code>StringBuffer</code> with the specified initial
+   * capacity.
+   *
+   * @param capacity the initial capacity
+   * @throws NegativeArraySizeException if capacity is negative
+   */
+  public CPStringBuilder(int capacity)
+  {
+    value = new char[capacity];
+  }
+
+  /**
+   * Create a new <code>StringBuffer</code> with the characters in the
+   * specified <code>String</code>. Initial capacity will be the size of the
+   * String plus 16.
+   *
+   * @param str the <code>String</code> to convert
+   * @throws NullPointerException if str is null
+   */
+  public CPStringBuilder(String str)
+  {
+    count = str.length();
+    value = new char[count + DEFAULT_CAPACITY];
+    str.getChars(0, count, value, 0);
+  }
+
+  /**
+   * Create a new <code>StringBuffer</code> with the characters in the
+   * specified <code>CharSequence</code>. Initial capacity will be the
+   * length of the sequence plus 16; if the sequence reports a length
+   * less than or equal to 0, then the initial capacity will be 16.
+   *
+   * @param seq the initializing <code>CharSequence</code>
+   * @throws NullPointerException if str is null
+   * @since 1.5
+   */
+  public CPStringBuilder(CharSequence seq)
+  {
+    int len = seq.length();
+    count = len <= 0 ? 0 : len;
+    value = new char[count + DEFAULT_CAPACITY];
+    for (int i = 0; i < len; ++i)
+      value[i] = seq.charAt(i);
+  }
+
+  /**
+   * Increase the capacity of this <code>StringBuffer</code>. This will
+   * ensure that an expensive growing operation will not occur until
+   * <code>minimumCapacity</code> is reached. The buffer is grown to the
+   * larger of <code>minimumCapacity</code> and
+   * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+   *
+   * @param minimumCapacity the new capacity
+   * @see #capacity()
+   */
+  public void ensureCapacity(int minimumCapacity)
+  {
+    ensureCapacity_unsynchronized(minimumCapacity);
+  }
+
+  /**
+   * Set the length of this StringBuffer. If the new length is greater than
+   * the current length, all the new characters are set to '\0'. If the new
+   * length is less than the current length, the first <code>newLength</code>
+   * characters of the old array will be preserved, and the remaining
+   * characters are truncated.
+   *
+   * @param newLength the new length
+   * @throws IndexOutOfBoundsException if the new length is negative
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   * @see #length()
+   */
+  public void setLength(int newLength)
+  {
+    if (newLength < 0)
+      throw new StringIndexOutOfBoundsException(newLength);
+
+    int valueLength = value.length;
+
+    /* Always call ensureCapacity_unsynchronized in order to preserve
+       copy-on-write semantics.  */
+    ensureCapacity_unsynchronized(newLength);
+
+    if (newLength < valueLength)
+      {
+        /* If the StringBuffer's value just grew, then we know that
+           value is newly allocated and the region between count and
+           newLength is filled with '\0'.  */
+       count = newLength;
+      }
+    else
+      {
+       /* The StringBuffer's value doesn't need to grow.  However,
+          we should clear out any cruft that may exist.  */
+       while (count < newLength)
+          value[count++] = '\0';
+      }
+  }
+
+  /**
+   * Get the character at the specified index.
+   *
+   * @param index the index of the character to get, starting at 0
+   * @return the character at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public char charAt(int index)
+  {
+    if (index < 0 || index >= count)
+      throw new StringIndexOutOfBoundsException(index);
+    return value[index];
+  }
+
+  /**
+   * Get the code point at the specified index.  This is like #charAt(int),
+   * but if the character is the start of a surrogate pair, and the
+   * following character completes the pair, then the corresponding
+   * supplementary code point is returned.
+   * @param index the index of the codepoint to get, starting at 0
+   * @return the codepoint at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+   * @since 1.5
+   */
+  public int codePointAt(int index)
+  {
+    return Character.codePointAt(value, index, count);
+  }
+
+  /**
+   * Get the code point before the specified index.  This is like
+   * #codePointAt(int), but checks the characters at <code>index-1</code> and
+   * <code>index-2</code> to see if they form a supplementary code point.
+   * @param index the index just past the codepoint to get, starting at 0
+   * @return the codepoint at the specified index
+   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+   * @since 1.5
+   */
+  public int codePointBefore(int index)
+  {
+    // Character.codePointBefore() doesn't perform this check.  We
+    // could use the CharSequence overload, but this is just as easy.
+    if (index >= count)
+      throw new IndexOutOfBoundsException();
+    return Character.codePointBefore(value, index, 1);
+  }
+
+  /**
+   * Get the specified array of characters. <code>srcOffset - srcEnd</code>
+   * characters will be copied into the array you pass in.
+   *
+   * @param srcOffset the index to start copying from (inclusive)
+   * @param srcEnd the index to stop copying from (exclusive)
+   * @param dst the array to copy into
+   * @param dstOffset the index to start copying into
+   * @throws NullPointerException if dst is null
+   * @throws IndexOutOfBoundsException if any source or target indices are
+   *         out of range (while unspecified, source problems cause a
+   *         StringIndexOutOfBoundsException, and dest problems cause an
+   *         ArrayIndexOutOfBoundsException)
+   * @see System#arraycopy(Object, int, Object, int, int)
+   */
+  public void getChars(int srcOffset, int srcEnd,
+                      char[] dst, int dstOffset)
+  {
+    if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
+      throw new StringIndexOutOfBoundsException();
+    System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
+  }
+
+  /**
+   * Set the character at the specified index.
+   *
+   * @param index the index of the character to set starting at 0
+   * @param ch the value to set that character to
+   * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public void setCharAt(int index, char ch)
+  {
+    if (index < 0 || index >= count)
+      throw new StringIndexOutOfBoundsException(index);
+    // Call ensureCapacity to enforce copy-on-write.
+    ensureCapacity_unsynchronized(count);
+    value[index] = ch;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param obj the <code>Object</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(Object)
+   * @see #append(String)
+   */
+  public CPStringBuilder append(Object obj)
+  {
+    return append(String.valueOf(obj));
+  }
+
+  /**
+   * Append the <code>String</code> to this <code>StringBuffer</code>. If
+   * str is null, the String "null" is appended.
+   *
+   * @param str the <code>String</code> to append
+   * @return this <code>StringBuffer</code>
+   */
+  public CPStringBuilder append(String str)
+  {
+    if (str == null)
+      str = "null";
+    int len = str.length();
+    ensureCapacity_unsynchronized(count + len);
+    str.getChars(0, len, value, count);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Append the <code>StringBuilder</code> value of the argument to this
+   * <code>StringBuilder</code>. This behaves the same as
+   * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+   *
+   * @param stringBuffer the <code>StringBuilder</code> to convert and append
+   * @return this <code>StringBuilder</code>
+   * @see #append(Object)
+   */
+  public CPStringBuilder append(StringBuffer stringBuffer)
+  {
+    if (stringBuffer == null)
+      return append("null");
+    synchronized (stringBuffer)
+      {
+       int len = stringBuffer.length();
+       ensureCapacity(count + len);
+       stringBuffer.getChars(0, len, value, count);
+       count += len;
+      }
+    return this;
+  }
+
+  /**
+   * Append the <code>char</code> array to this <code>StringBuffer</code>.
+   * This is similar (but more efficient) than
+   * <code>append(new String(data))</code>, except in the case of null.
+   *
+   * @param data the <code>char[]</code> to append
+   * @return this <code>StringBuffer</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @see #append(char[], int, int)
+   */
+  public CPStringBuilder append(char[] data)
+  {
+    return append(data, 0, data.length);
+  }
+
+  /**
+   * Append part of the <code>char</code> array to this
+   * <code>StringBuffer</code>. This is similar (but more efficient) than
+   * <code>append(new String(data, offset, count))</code>, except in the case
+   * of null.
+   *
+   * @param data the <code>char[]</code> to append
+   * @param offset the start location in <code>str</code>
+   * @param count the number of characters to get from <code>str</code>
+   * @return this <code>StringBuffer</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @throws IndexOutOfBoundsException if offset or count is out of range
+   *         (while unspecified, this is a StringIndexOutOfBoundsException)
+   */
+  public CPStringBuilder append(char[] data, int offset, int count)
+  {
+    if (offset < 0 || count < 0 || offset > data.length - count)
+      throw new StringIndexOutOfBoundsException();
+    ensureCapacity_unsynchronized(this.count + count);
+    System.arraycopy(data, offset, value, this.count, count);
+    this.count += count;
+    return this;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param bool the <code>boolean</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(boolean)
+   */
+  public CPStringBuilder append(boolean bool)
+  {
+    return append(bool ? "true" : "false");
+  }
+
+  /**
+   * Append the <code>char</code> to this <code>StringBuffer</code>.
+   *
+   * @param ch the <code>char</code> to append
+   * @return this <code>StringBuffer</code>
+   */
+  public CPStringBuilder append(char ch)
+  {
+    ensureCapacity_unsynchronized(count + 1);
+    value[count++] = ch;
+    return this;
+  }
+
+  /**
+   * Append the characters in the <code>CharSequence</code> to this
+   * buffer.
+   *
+   * @param seq the <code>CharSequence</code> providing the characters
+   * @return this <code>StringBuffer</code>
+   * @since 1.5
+   */
+  public CPStringBuilder append(CharSequence seq)
+  {
+    return append(seq, 0, seq.length());
+  }
+
+  /**
+   * Append some characters from the <code>CharSequence</code> to this
+   * buffer.  If the argument is null, the four characters "null" are
+   * appended.
+   *
+   * @param seq the <code>CharSequence</code> providing the characters
+   * @param start the starting index
+   * @param end one past the final index
+   * @return this <code>StringBuffer</code>
+   * @since 1.5
+   */
+  public CPStringBuilder append(CharSequence seq, int start, int end)
+  {
+    if (seq == null)
+      return append("null");
+    if (end - start > 0)
+      {
+       ensureCapacity_unsynchronized(count + end - start);
+       for (; start < end; ++start)
+         value[count++] = seq.charAt(start);
+      }
+    return this;
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param inum the <code>int</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(int)
+   */
+  // This is native in libgcj, for efficiency.
+  public CPStringBuilder append(int inum)
+  {
+    return append(String.valueOf(inum));
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param lnum the <code>long</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(long)
+   */
+  public CPStringBuilder append(long lnum)
+  {
+    return append(Long.toString(lnum, 10));
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param fnum the <code>float</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(float)
+   */
+  public CPStringBuilder append(float fnum)
+  {
+    return append(Float.toString(fnum));
+  }
+
+  /**
+   * Append the <code>String</code> value of the argument to this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param dnum the <code>double</code> to convert and append
+   * @return this <code>StringBuffer</code>
+   * @see String#valueOf(double)
+   */
+  public CPStringBuilder append(double dnum)
+  {
+    return append(Double.toString(dnum));
+  }
+
+  /**
+   * Append the code point to this <code>StringBuffer</code>.
+   * This is like #append(char), but will append two characters
+   * if a supplementary code point is given.
+   *
+   * @param code the code point to append
+   * @return this <code>StringBuffer</code>
+   * @see Character#toChars(int, char[], int)
+   * @since 1.5
+   */
+  public CPStringBuilder appendCodePoint(int code)
+  {
+    int len = Character.charCount(code);
+    ensureCapacity_unsynchronized(count + len);
+    Character.toChars(code, value, count);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Delete characters from this <code>StringBuffer</code>.
+   * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+   * harmless for end to be larger than length().
+   *
+   * @param start the first character to delete
+   * @param end the index after the last character to delete
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+   * @since 1.2
+   */
+  public CPStringBuilder delete(int start, int end)
+  {
+    if (start < 0 || start > count || start > end)
+      throw new StringIndexOutOfBoundsException(start);
+    if (end > count)
+      end = count;
+    ensureCapacity_unsynchronized(count);
+    if (count - end != 0)
+      System.arraycopy(value, end, value, start, count - end);
+    count -= end - start;
+    return this;
+  }
+
+  /**
+   * Delete a character from this <code>StringBuffer</code>.
+   *
+   * @param index the index of the character to delete
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if index is out of bounds
+   * @since 1.2
+   */
+  public CPStringBuilder deleteCharAt(int index)
+  {
+    return delete(index, index + 1);
+  }
+
+  /**
+   * Replace characters between index <code>start</code> (inclusive) and
+   * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+   * is larger than the size of this StringBuffer, all characters after
+   * <code>start</code> are replaced.
+   *
+   * @param start the beginning index of characters to delete (inclusive)
+   * @param end the ending index of characters to delete (exclusive)
+   * @param str the new <code>String</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+   * @throws NullPointerException if str is null
+   * @since 1.2
+   */
+  public CPStringBuilder replace(int start, int end, String str)
+  {
+    if (start < 0 || start > count || start > end)
+      throw new StringIndexOutOfBoundsException(start);
+
+    int len = str.length();
+    // Calculate the difference in 'count' after the replace.
+    int delta = len - (end > count ? count : end) + start;
+    ensureCapacity_unsynchronized(count + delta);
+
+    if (delta != 0 && end < count)
+      System.arraycopy(value, end, value, end + delta, count - end);
+
+    str.getChars(0, len, value, start);
+    count += delta;
+    return this;
+  }
+
+  /**
+   * Insert a subarray of the <code>char[]</code> argument into this
+   * <code>StringBuffer</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param str the <code>char[]</code> to insert
+   * @param str_offset the index in <code>str</code> to start inserting from
+   * @param len the number of characters to insert
+   * @return this <code>StringBuffer</code>
+   * @throws NullPointerException if <code>str</code> is <code>null</code>
+   * @throws StringIndexOutOfBoundsException if any index is out of bounds
+   * @since 1.2
+   */
+  public CPStringBuilder insert(int offset, char[] str, int str_offset, int len)
+  {
+    if (offset < 0 || offset > count || len < 0
+        || str_offset < 0 || str_offset > str.length - len)
+      throw new StringIndexOutOfBoundsException();
+    ensureCapacity_unsynchronized(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    System.arraycopy(str, str_offset, value, offset, len);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param obj the <code>Object</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @exception StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(Object)
+   */
+  public CPStringBuilder insert(int offset, Object obj)
+  {
+    return insert(offset, obj == null ? "null" : obj.toString());
+  }
+
+  /**
+   * Insert the <code>String</code> argument into this
+   * <code>StringBuffer</code>. If str is null, the String "null" is used
+   * instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param str the <code>String</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   */
+  public CPStringBuilder insert(int offset, String str)
+  {
+    if (offset < 0 || offset > count)
+      throw new StringIndexOutOfBoundsException(offset);
+    if (str == null)
+      str = "null";
+    int len = str.length();
+    ensureCapacity_unsynchronized(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    str.getChars(0, len, value, offset);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>CharSequence</code> argument into this
+   * <code>StringBuffer</code>.  If the sequence is null, the String
+   * "null" is used instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param sequence the <code>CharSequence</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws IndexOutOfBoundsException if offset is out of bounds
+   * @since 1.5
+   */
+  public CPStringBuilder insert(int offset, CharSequence sequence)
+  {
+    if (sequence == null)
+      sequence = "null";
+    return insert(offset, sequence, 0, sequence.length());
+  }
+
+  /**
+   * Insert a subsequence of the <code>CharSequence</code> argument into this
+   * <code>StringBuffer</code>.  If the sequence is null, the String
+   * "null" is used instead.
+   *
+   * @param offset the place to insert in this buffer
+   * @param sequence the <code>CharSequence</code> to insert
+   * @param start the starting index of the subsequence
+   * @param end one past the ending index of the subsequence
+   * @return this <code>StringBuffer</code>
+   * @throws IndexOutOfBoundsException if offset, start,
+   * or end are out of bounds
+   * @since 1.5
+   */
+  public CPStringBuilder insert(int offset, CharSequence sequence, int start, int end)
+  {
+    if (sequence == null)
+      sequence = "null";
+    if (start < 0 || end < 0 || start > end || end > sequence.length())
+      throw new IndexOutOfBoundsException();
+    int len = end - start;
+    ensureCapacity_unsynchronized(count + len);
+    System.arraycopy(value, offset, value, offset + len, count - offset);
+    for (int i = start; i < end; ++i)
+      value[offset++] = sequence.charAt(i);
+    count += len;
+    return this;
+  }
+
+  /**
+   * Insert the <code>char[]</code> argument into this
+   * <code>StringBuffer</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param data the <code>char[]</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws NullPointerException if <code>data</code> is <code>null</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see #insert(int, char[], int, int)
+   */
+  public CPStringBuilder insert(int offset, char[] data)
+  {
+    return insert(offset, data, 0, data.length);
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param bool the <code>boolean</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(boolean)
+   */
+  public CPStringBuilder insert(int offset, boolean bool)
+  {
+    return insert(offset, bool ? "true" : "false");
+  }
+
+  /**
+   * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param ch the <code>char</code> to insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   */
+  public CPStringBuilder insert(int offset, char ch)
+  {
+    if (offset < 0 || offset > count)
+      throw new StringIndexOutOfBoundsException(offset);
+    ensureCapacity_unsynchronized(count + 1);
+    System.arraycopy(value, offset, value, offset + 1, count - offset);
+    value[offset] = ch;
+    count++;
+    return this;
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param inum the <code>int</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(int)
+   */
+  public CPStringBuilder insert(int offset, int inum)
+  {
+    return insert(offset, String.valueOf(inum));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param lnum the <code>long</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(long)
+   */
+  public CPStringBuilder insert(int offset, long lnum)
+  {
+    return insert(offset, Long.toString(lnum, 10));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param fnum the <code>float</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(float)
+   */
+  public CPStringBuilder insert(int offset, float fnum)
+  {
+    return insert(offset, Float.toString(fnum));
+  }
+
+  /**
+   * Insert the <code>String</code> value of the argument into this
+   * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+   * to <code>String</code>.
+   *
+   * @param offset the place to insert in this buffer
+   * @param dnum the <code>double</code> to convert and insert
+   * @return this <code>StringBuffer</code>
+   * @throws StringIndexOutOfBoundsException if offset is out of bounds
+   * @see String#valueOf(double)
+   */
+  public CPStringBuilder insert(int offset, double dnum)
+  {
+    return insert(offset, Double.toString(dnum));
+  }
+
+  /**
+   * Finds the first instance of a substring in this StringBuilder.
+   *
+   * @param str String to find
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @see #indexOf(String, int)
+   */
+  public int indexOf(String str)
+  {
+    return indexOf(str, 0);
+  }
+
+  /**
+   * Finds the first instance of a String in this StringBuffer, starting at
+   * a given index.  If starting index is less than 0, the search starts at
+   * the beginning of this String.  If the starting index is greater than the
+   * length of this String, or the substring is not found, -1 is returned.
+   *
+   * @param str String to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @since 1.4
+   */
+  public int indexOf(String str, int fromIndex)
+  {
+    if (fromIndex < 0)
+      fromIndex = 0;
+    int olength = str.length();
+    int limit = count - olength;
+    String s = VMCPStringBuilder.toString(value, 0, count);
+    for (; fromIndex <= limit; ++fromIndex)
+      if (s.regionMatches(fromIndex, str, 0, olength))
+        return fromIndex;
+    return -1;
+  }
+
+  /**
+   * Finds the last instance of a substring in this StringBuffer.
+   *
+   * @param str String to find
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @see #lastIndexOf(String, int)
+   * @since 1.4
+   */
+  public int lastIndexOf(String str)
+  {
+    return lastIndexOf(str, count - str.length());
+  }
+
+  /**
+   * Finds the last instance of a String in this StringBuffer, starting at a
+   * given index.  If starting index is greater than the maximum valid index,
+   * then the search begins at the end of this String.  If the starting index
+   * is less than zero, or the substring is not found, -1 is returned.
+   *
+   * @param str String to find
+   * @param fromIndex index to start the search
+   * @return location (base 0) of the String, or -1 if not found
+   * @throws NullPointerException if str is null
+   * @since 1.4
+   */
+  public int lastIndexOf(String str, int fromIndex)
+  {
+    fromIndex = Math.min(fromIndex, count - str.length());
+    String s = VMCPStringBuilder.toString(value, 0, count);
+    int olength = str.length();
+    for ( ; fromIndex >= 0; fromIndex--)
+      if (s.regionMatches(fromIndex, str, 0, olength))
+        return fromIndex;
+    return -1;
+  }
+
+  /**
+   * Reverse the characters in this StringBuffer. The same sequence of
+   * characters exists, but in the reverse index ordering.
+   *
+   * @return this <code>StringBuffer</code>
+   */
+  public CPStringBuilder reverse()
+  {
+    // Call ensureCapacity to enforce copy-on-write.
+    ensureCapacity_unsynchronized(count);
+    for (int i = count >> 1, j = count - i; --i >= 0; ++j)
+      {
+        char c = value[i];
+        value[i] = value[j];
+        value[j] = c;
+      }
+    return this;
+  }
+
+  /**
+   * This may reduce the amount of memory used by the StringBuffer,
+   * by resizing the internal array to remove unused space.  However,
+   * this method is not required to resize, so this behavior cannot
+   * be relied upon.
+   * @since 1.5
+   */
+  public void trimToSize()
+  {
+    int wouldSave = value.length - count;
+    // Some random heuristics: if we save less than 20 characters, who
+    // cares.
+    if (wouldSave < 20)
+      return;
+    // If we save more than 200 characters, shrink.
+    // If we save more than 1/4 of the buffer, shrink.
+    if (wouldSave > 200 || wouldSave * 4 > value.length)
+      {
+       char[] newValue = new char[count];
+       System.arraycopy(value, 0, newValue, 0, count);
+       value = newValue;
+      }
+  }
+
+  /**
+   * Return the number of code points between two indices in the
+   * <code>StringBuffer</code>.  An unpaired surrogate counts as a
+   * code point for this purpose.  Characters outside the indicated
+   * range are not examined, even if the range ends in the middle of a
+   * surrogate pair.
+   *
+   * @param start the starting index
+   * @param end one past the ending index
+   * @return the number of code points
+   * @since 1.5
+   */
+  public int codePointCount(int start, int end)
+  {
+    if (start < 0 || end >= count || start > end)
+      throw new StringIndexOutOfBoundsException();
+
+    int count = 0;
+    while (start < end)
+      {
+       char base = value[start];
+       if (base < Character.MIN_HIGH_SURROGATE
+           || base > Character.MAX_HIGH_SURROGATE
+           || start == end
+           || start == count
+           || value[start + 1] < Character.MIN_LOW_SURROGATE
+           || value[start + 1] > Character.MAX_LOW_SURROGATE)
+         {
+           // Nothing.
+         }
+       else
+         {
+           // Surrogate pair.
+           ++start;
+         }
+       ++start;
+       ++count;
+      }
+    return count;
+  }
+
+  /**
+   * Starting at the given index, this counts forward by the indicated
+   * number of code points, and then returns the resulting index.  An
+   * unpaired surrogate counts as a single code point for this
+   * purpose.
+   *
+   * @param start the starting index
+   * @param codePoints the number of code points
+   * @return the resulting index
+   * @since 1.5
+   */
+  public int offsetByCodePoints(int start, int codePoints)
+  {
+    while (codePoints > 0)
+      {
+       char base = value[start];
+       if (base < Character.MIN_HIGH_SURROGATE
+           || base > Character.MAX_HIGH_SURROGATE
+           || start == count
+           || value[start + 1] < Character.MIN_LOW_SURROGATE
+           || value[start + 1] > Character.MAX_LOW_SURROGATE)
+         {
+           // Nothing.
+         }
+       else
+         {
+           // Surrogate pair.
+           ++start;
+         }
+       ++start;
+       --codePoints;
+      }
+    return start;
+  }
+
+  /**
+   * Increase the capacity of this <code>StringBuilder</code>. This will
+   * ensure that an expensive growing operation will not occur until
+   * <code>minimumCapacity</code> is reached. The buffer is grown to the
+   * larger of <code>minimumCapacity</code> and
+   * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+   *
+   * @param minimumCapacity the new capacity
+   * @see #capacity()
+   */
+  protected void ensureCapacity_unsynchronized(int minimumCapacity)
+  {
+    if (minimumCapacity > value.length)
+      {
+        int max = value.length * 2 + 2;
+        minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+        char[] nb = new char[minimumCapacity];
+        System.arraycopy(value, 0, nb, 0, count);
+        value = nb;
+      }
+  }
+
+  /**
+   * Get the length of the <code>String</code> this <code>StringBuilder</code>
+   * would create. Not to be confused with the <em>capacity</em> of the
+   * <code>StringBuilder</code>.
+   *
+   * @return the length of this <code>StringBuilder</code>
+   * @see #capacity()
+   * @see #setLength(int)
+   */
+  public int length()
+  {
+    return count;
+  }
+
+  /**
+   * Creates a substring of this StringBuilder, starting at a specified index
+   * and ending at one character before a specified index. This is implemented
+   * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
+   * the CharSequence interface.
+   *
+   * @param beginIndex index to start at (inclusive, base 0)
+   * @param endIndex index to end at (exclusive)
+   * @return new String which is a substring of this StringBuilder
+   * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
+   *         bounds
+   * @see #substring(int, int)
+   */
+  public CharSequence subSequence(int beginIndex, int endIndex)
+  {
+    return substring(beginIndex, endIndex);
+  }
+
+  /**
+   * Creates a substring of this StringBuilder, starting at a specified index
+   * and ending at one character before a specified index.
+   *
+   * @param beginIndex index to start at (inclusive, base 0)
+   * @param endIndex index to end at (exclusive)
+   * @return new String which is a substring of this StringBuilder
+   * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
+   *         of bounds
+   */
+  public String substring(int beginIndex, int endIndex)
+  {
+    if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
+      throw new StringIndexOutOfBoundsException();
+    int len = endIndex - beginIndex;
+    if (len == 0)
+      return "";
+    return VMCPStringBuilder.toString(value, beginIndex, len);
+  }
+
+  /**
+   * Convert this <code>StringBuilder</code> to a <code>String</code>. The
+   * String is composed of the characters currently in this StringBuilder. Note
+   * that the result is not a copy, so future modifications to this buffer
+   * do affect the String.
+   *
+   * @return the characters in this StringBuilder
+   */
+  public String toString()
+  {
+    return VMCPStringBuilder.toString(value, 0, count);
+  }
+
+}
diff --git a/src/classes/gnu/gnu/java/lang/VMCPStringBuilder.java b/src/classes/gnu/gnu/java/lang/VMCPStringBuilder.java
new file mode 100644 (file)
index 0000000..ca1c39d
--- /dev/null
@@ -0,0 +1,108 @@
+/* VMCPStringBuilder.java -- Growable strings without locking or copying
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * This class provides VM support for CPStringBuilder
+ * by allowing the package-private constructor
+ * of java.lang.String to be invoked.  The default
+ * implementation uses reflection.  VMs may replace
+ * this class with a more efficient version.
+ */
+final class VMCPStringBuilder
+{
+
+  /**
+   * The package-private constructor for String objects without copying.
+   */
+//   private static final Constructor<String> cons;
+
+//   static
+//   {
+//     try
+//       {
+//     cons = String.class.getDeclaredConstructor(char[].class, Integer.TYPE,
+//                                                Integer.TYPE, Boolean.TYPE);
+//     cons.setAccessible(true);
+//       }
+//     catch (NoSuchMethodException e)
+//       {
+//     throw (Error) 
+//       new InternalError("Could not get no-copy String constructor").initCause(e);
+//       }
+//   }
+
+  /**
+   * Convert this <code>StringBuilder</code> to a <code>String</code>. The
+   * String is composed of the characters currently in this StringBuilder. Note
+   * that the result is not a copy, so future modifications to this buffer
+   * do affect the String.
+   *
+   * @param value the buffered characters.
+   * @param startIndex the index at which to start taking characters from the buffer.
+   * @param count the number of characters used in the buffer.
+   * @return the characters in this StringBuilder
+   */
+//   public static String toString(char[] value, int startIndex, int count)
+//   {
+//     try
+//       {
+//     return cons.newInstance(value, startIndex, count, true);
+//       }
+//     catch (InstantiationException e)
+//       {
+//     throw (Error) 
+//       new InternalError("Could not instantiate no-copy String constructor").initCause(e);
+//       }
+//     catch (IllegalAccessException e)
+//       {
+//     throw (Error) 
+//       new InternalError("Could not access no-copy String constructor").initCause(e);
+//       }
+//     catch (InvocationTargetException e)
+//       {
+//     throw (Error) 
+//       new InternalError("Error calling no-copy String constructor").initCause(e);
+//       }
+//   }
+  public static native String toString(char[] value, int startIndex, int count);
+
+}
diff --git a/src/classes/gnu/gnu/java/lang/management/VMMemoryMXBeanImpl.java b/src/classes/gnu/gnu/java/lang/management/VMMemoryMXBeanImpl.java
new file mode 100644 (file)
index 0000000..d71a06d
--- /dev/null
@@ -0,0 +1,110 @@
+/* VMMemoryMXBeanImpl.java - VM impl. of a memory bean
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.MemoryUsage;
+
+/**
+ * Provides access to information about the memory
+ * management of the current invocation of the virtual
+ * machine.  Instances of this bean are obtained by calling
+ * {@link ManagementFactory#getMemoryMXBean()}.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMMemoryMXBeanImpl
+{
+
+  /**
+   * Returns an instance of {@link java.lang.management.MemoryUsage}
+   * with appropriate initial, used, committed and maximum values
+   * for the heap.  By default, this uses the methods of
+   * {@link java.lang.Runtime} to provide some of the values.
+   *
+   * @return an {@link java.lang.management.MemoryUsage} instance
+   *         for the heap.
+   */
+//   static MemoryUsage getHeapMemoryUsage()
+//   {
+//     Runtime runtime = Runtime.getRuntime();
+//     long totalMem = runtime.totalMemory();
+//     return new MemoryUsage(-1, totalMem - runtime.freeMemory(),
+//                        totalMem, runtime.maxMemory());
+//   }
+  static native MemoryUsage getHeapMemoryUsage();
+
+  /**
+   * Returns an instance of {@link java.lang.management.MemoryUsage}
+   * with appropriate initial, used, committed and maximum values
+   * for non-heap memory.
+   *
+   * @return an {@link java.lang.management.MemoryUsage} instance
+   *         for non-heap memory.
+   */
+  static native MemoryUsage getNonHeapMemoryUsage();
+
+  /**
+   * Returns the number of objects ready to be garbage collected.
+   *
+   * @return the number of finalizable objects.
+   */
+  static native int getObjectPendingFinalizationCount();
+
+  /**
+   * Returns true if the virtual machine will emit additional
+   * information when memory is allocated and deallocated.  The
+   * format of the output is left up to the virtual machine.
+   *
+   * @return true if verbose class loading output is on.
+   */
+  static native boolean isVerbose();
+
+  /**
+   * Turns on or off the emission of additional information
+   * when memory is allocated and deallocated.  The format of the
+   * output is left up to the virtual machine.  This method
+   * may be called by multiple threads concurrently, but there
+   * is only one global setting of verbosity that is affected.
+   *
+   * @param verbose the new setting for verbose class loading
+   *                output.
+   */
+  static native void setVerbose(boolean verbose);
+
+}
diff --git a/src/classes/gnu/gnu/java/lang/management/VMRuntimeMXBeanImpl.java b/src/classes/gnu/gnu/java/lang/management/VMRuntimeMXBeanImpl.java
new file mode 100644 (file)
index 0000000..32a8660
--- /dev/null
@@ -0,0 +1,89 @@
+/* VMRuntimeMXBeanImpl.java - VM implementation of an runtime bean
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import gnu.classpath.SystemProperties;
+
+/**
+ * Provides access to information about the virtual machine.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMRuntimeMXBeanImpl
+{
+
+  /**
+   * Returns the command-line arguments supplied
+   * to the virtual machine, excluding those supplied
+   * to <code>main()</code>.
+   *
+   * @return the command-line arguments.
+   */
+  static native String[] getInputArguments();
+
+  /**
+   * Returns a developer-chosen name for the virtual
+   * machine, which may differ over different running
+   * instances of the same virtual machine binary.
+   * For example, this may include the particular
+   * process identifier used by this instance or
+   * the host name of the machine on which it is
+   * running.  The intention is that this name refers
+   * to the precise entity that the other data supplied
+   * by the bean refers to, rather than the VM in general.
+   *
+   * @return the custom name of the VM.
+   */
+  static String getName()
+  {
+    return SystemProperties.getProperty("java.vm.name") + " " +
+      SystemProperties.getProperty("java.vm.version");
+  }
+
+  /**
+   * The time in milliseconds at which the virtual
+   * machine was started.  This method is only executed
+   * once (for efficency), as the value is not expected
+   * to change.
+   *
+   * @return the VM start time.
+   */
+  static native long getStartTime();
+
+}
diff --git a/src/classes/gnu/java/lang/VMClassLoader.java b/src/classes/gnu/java/lang/VMClassLoader.java
new file mode 100644 (file)
index 0000000..f09838b
--- /dev/null
@@ -0,0 +1,457 @@
+/* VMClassLoader.java -- Reference implementation of native interface
+   required by ClassLoader
+   Copyright (C) 1998, 2001, 2002, 2004, 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang;
+
+import gnu.classpath.Configuration;
+import gnu.classpath.SystemProperties;
+import gnu.java.lang.InstrumentationImpl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.instrument.Instrumentation;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.zip.ZipFile;
+import java.util.Collections;
+import java.lang.Boolean;
+
+/**
+ * java.lang.VMClassLoader is a package-private helper for VMs to implement
+ * on behalf of java.lang.ClassLoader.
+ *
+ * @author John Keiser
+ * @author Mark Wielaard (mark@klomp.org)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ */
+final class VMClassLoader
+{
+
+
+  /** packages loaded by the bootstrap class loader */
+  static final HashMap definedPackages = new HashMap();
+
+  /** jars from property java.boot.class.path */
+  static final HashMap bootjars = new HashMap();
+  
+
+  /**
+   * Converts the array string of native package names to
+   * Packages. The packages are then put into the
+   * definedPackages hashMap
+   */
+  static
+  {
+    String[] packages = getBootPackages();
+    
+    if( packages != null)
+      {
+        String specName = 
+              SystemProperties.getProperty("java.specification.name");
+        String vendor =
+              SystemProperties.getProperty("java.specification.vendor");
+        String version =
+              SystemProperties.getProperty("java.specification.version");
+        
+        Package p;
+              
+        for(int i = 0; i < packages.length; i++)
+          {
+            p = new Package(packages[i],
+                  specName,
+                  vendor,
+                  version,
+                  "GNU Classpath",
+                  "GNU",
+                  Configuration.CLASSPATH_VERSION,
+                  null,
+                  null);
+
+            definedPackages.put(packages[i], p);
+          }
+      }
+  }
+
+  
+  /**
+   * Helper to define a class using a string of bytes. This assumes that
+   * the security checks have already been performed, if necessary.
+   *
+   * Implementations of this method are advised to consider the
+   * situation where user code modifies the byte array after it has
+   * been passed to defineClass.  This can be handled by making a
+   * private copy of the array, or arranging to only read any given
+   * byte a single time.
+   *
+   * @param name the name to give the class, or null if unknown
+   * @param data the data representing the classfile, in classfile format
+   * @param offset the offset into the data where the classfile starts
+   * @param len the length of the classfile data in the array
+   * @param pd the protection domain
+   * @return the class that was defined
+   * @throws ClassFormatError if data is not in proper classfile format
+   */
+  static final native Class defineClass(ClassLoader cl, String name,
+                                 byte[] data, int offset, int len,
+                                 ProtectionDomain pd)
+    throws ClassFormatError;
+
+  /**
+   * Helper to resolve all references to other classes from this class.
+   *
+   * @param c the class to resolve
+   */
+  static final native void resolveClass(Class c);
+
+  /**
+   * Helper to load a class from the bootstrap class loader.
+   *
+   * @param name the class name to load
+   * @param resolve whether to resolve it
+   * @return the class, loaded by the bootstrap classloader or null
+   * if the class wasn't found. Returning null is equivalent to throwing
+   * a ClassNotFoundException (but a possible performance optimization).
+   */
+  static final native Class loadClass(String name, boolean resolve)
+    throws ClassNotFoundException;
+
+  /**
+   * Helper to load a resource from the bootstrap class loader.
+   *
+   * @param name the resource to find
+   * @return the URL to the resource
+   */
+  static URL getResource(String name)
+  {
+    Enumeration e = getResources(name);
+    if (e.hasMoreElements())
+      return (URL)e.nextElement();
+    return null;
+  }
+  /**
+   * Helper to get a list of resources from the bootstrap class loader.
+   *
+   * @param name the resource to find
+   * @return an enumeration of resources
+   */
+  static Enumeration getResources(String name)
+  {
+//     StringTokenizer st = new StringTokenizer(
+//       SystemProperties.getProperty("java.boot.class.path", "."),
+//       File.pathSeparator);
+//     Vector v = new Vector();
+//     while (st.hasMoreTokens())
+//       {
+//     File file = new File(st.nextToken());
+//     if (file.isDirectory())
+//       {
+//         try
+//           {
+//                 File f = new File(file, name);
+//                 if (!f.exists()) continue;
+//                 v.add(new URL("file://" + f.getAbsolutePath()));
+//           }
+//         catch (MalformedURLException e)
+//           {
+//             throw new Error(e);
+//           }
+//       }
+//     else if (file.isFile())
+//       {
+//         ZipFile zip;
+//             synchronized(bootjars)
+//               {
+//                 zip = (ZipFile) bootjars.get(file.getName());
+//               }
+//             if(zip == null)
+//               {
+//                 try
+//               {
+//                     zip = new ZipFile(file);
+//                     synchronized(bootjars)
+//                       {
+//                         bootjars.put(file.getName(), zip);
+//                       }
+//               }
+//             catch (IOException e)
+//               {
+//                 continue;
+//               }
+//               }
+//         String zname = name.startsWith("/") ? name.substring(1) : name;
+//         if (zip.getEntry(zname) == null)
+//           continue;
+//         try
+//           {
+//             v.add(new URL("jar:file://"
+//               + file.getAbsolutePath() + "!/" + zname));
+//           }
+//         catch (MalformedURLException e)
+//           {
+//             throw new Error(e);
+//           }
+//       }
+//       }
+//     return v.elements();
+//   }
+    Vector urls = nativeGetResources(name);
+    Vector v = new Vector();
+    for (Enumeration en = urls.elements(); en.hasMoreElements();)
+      {
+       try
+         {
+           v.add(new URL((String) en.nextElement()));
+         }
+       catch (MalformedURLException e)
+         {
+           throw new Error(e);
+         }
+      }
+    return v.elements();
+  }
+
+  private native static final Vector nativeGetResources(String name);
+
+
+  /**
+   * Returns a String[] of native package names. The default
+   * implementation tries to load a list of package from
+   * the META-INF/INDEX.LIST file in the boot jar file.
+   * If not found or if any exception is raised, it returns
+   * an empty array. You may decide this needs native help.
+   */
+  private static String[] getBootPackages()
+  {
+    try
+      {
+        Enumeration indexListEnumeration = getResources("META-INF/INDEX.LIST");
+        Set packageSet = new HashSet();
+
+        while (indexListEnumeration.hasMoreElements())
+          {
+            try
+              {
+                String line;
+                int lineToSkip = 3;
+                BufferedReader reader = new BufferedReader(
+                                                           new InputStreamReader(
+                                                                                 ((URL) indexListEnumeration.nextElement()).openStream()));
+                while ((line = reader.readLine()) != null)
+                  {
+                    if (lineToSkip == 0)
+                      {
+                        if (line.length() == 0)
+                          lineToSkip = 1;
+                        else
+                          packageSet.add(line.replace('/', '.'));
+                      }
+                    else
+                      lineToSkip--;
+                  }
+                reader.close();
+              }
+            catch (IOException e)
+              {
+                // Empty catch block on purpose
+              }
+          }
+        return (String[]) packageSet.toArray(new String[packageSet.size()]);
+      }
+    catch (Exception e)
+      {
+        return new String[0];
+      }
+  }
+
+
+  /**
+   * Helper to get a package from the bootstrap class loader.
+   *
+   * @param name the name to find
+   * @return the named package, if it exists
+   */
+  static Package getPackage(String name)
+  {
+    return (Package)definedPackages.get(name);
+  }
+
+
+  
+  /**
+   * Helper to get all packages from the bootstrap class loader.  
+   *
+   * @return all named packages, if any exist
+   */
+  static Package[] getPackages()
+  {
+    Package[] packages = new Package[definedPackages.size()];
+    definedPackages.values().toArray(packages);
+    return packages;
+  }
+
+  /**
+   * Helper for java.lang.Integer, Byte, etc to get the TYPE class
+   * at initialization time. The type code is one of the chars that
+   * represents the primitive type as in JNI.
+   *
+   * <ul>
+   * <li>'Z' - boolean</li>
+   * <li>'B' - byte</li>
+   * <li>'C' - char</li>
+   * <li>'D' - double</li>
+   * <li>'F' - float</li>
+   * <li>'I' - int</li>
+   * <li>'J' - long</li>
+   * <li>'S' - short</li>
+   * <li>'V' - void</li>
+   * </ul>
+   *
+   * @param type the primitive type
+   * @return a "bogus" class representing the primitive type
+   */
+  static final native Class getPrimitiveClass(char type);
+
+  /**
+   * The system default for assertion status. This is used for all system
+   * classes (those with a null ClassLoader), as well as the initial value for
+   * every ClassLoader's default assertion status.
+   *
+   * @return the system-wide default assertion status
+   */
+  static native final boolean defaultAssertionStatus();
+
+  static native final boolean defaultUserAssertionStatus();
+
+
+  static final Map packageAssertionMap = 
+    Collections.unmodifiableMap(packageAssertionStatus0(Boolean.TRUE, Boolean.FALSE));
+  
+  static native final Map packageAssertionStatus0(Boolean jtrue, Boolean jfalse);
+  /**
+   * The system default for package assertion status. This is used for all
+   * ClassLoader's packageAssertionStatus defaults. It must be a map of
+   * package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package
+   * represented as a null key.
+   *
+   * @return a (read-only) map for the default packageAssertionStatus
+   */
+   
+  static final Map packageAssertionStatus() {
+    return packageAssertionMap;
+  }
+
+  static final Map classAssertionMap = 
+    Collections.unmodifiableMap(classAssertionStatus0(Boolean.TRUE, Boolean.FALSE));
+  
+  static native final Map classAssertionStatus0(Boolean jtrue, Boolean jfalse);
+
+  /**
+   * The system default for class assertion status. This is used for all
+   * ClassLoader's classAssertionStatus defaults. It must be a map of
+   * class names to Boolean.TRUE or Boolean.FALSE
+   *
+   * @return a (read-only) map for the default classAssertionStatus
+   */
+  static final Map classAssertionStatus() {
+    return classAssertionMap;
+  }
+  
+  static ClassLoader getSystemClassLoader()
+  {
+    return ClassLoader.defaultGetSystemClassLoader();
+  }
+
+  /**
+   * Find the class if this class loader previously defined this class
+   * or if this class loader has been recorded as the initiating class loader
+   * for this class.
+   */
+  static native Class findLoadedClass(ClassLoader cl, String name);
+
+  /**
+   * The Instrumentation object created by the vm when agents are defined.
+   */
+  static final Instrumentation instrumenter = null;
+
+  /**
+   * Call the transformers of the possible Instrumentation object. This
+   * implementation assumes the instrumenter is a
+   * <code>InstrumentationImpl</code> object. VM implementors would
+   * have to redefine this method if they provide their own implementation
+   * of the <code>Instrumentation</code> interface.
+   *
+   * @param loader the initiating loader
+   * @param name the name of the class
+   * @param data the data representing the classfile, in classfile format
+   * @param offset the offset into the data where the classfile starts
+   * @param len the length of the classfile data in the array
+   * @param pd the protection domain
+   * @return the new data representing the classfile
+   */
+  static final Class defineClassWithTransformers(ClassLoader loader,
+      String name, byte[] data, int offset, int len, ProtectionDomain pd)
+  {
+    
+    if (instrumenter != null)
+      {
+        byte[] modifiedData = new byte[len];
+        System.arraycopy(data, offset, modifiedData, 0, len);
+        modifiedData =
+          ((InstrumentationImpl)instrumenter).callTransformers(loader, name,
+            null, pd, modifiedData);
+        
+        return defineClass(loader, name, modifiedData, 0, modifiedData.length,
+            pd);
+      }
+    else
+      {
+        return defineClass(loader, name, data, offset, len, pd);
+      }
+  }
+}
diff --git a/src/classes/gnu/java/lang/VMString.java b/src/classes/gnu/java/lang/VMString.java
new file mode 100644 (file)
index 0000000..57e4423
--- /dev/null
@@ -0,0 +1,96 @@
+/* VMString.java -- VM Specific String methods
+   Copyright (C) 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.lang.ref.WeakReference;
+import java.util.WeakHashMap;
+
+/*
+ * This class is a reference version, mainly for compiling a class library
+ * jar.  It is likely that VM implementers replace this with their own
+ * version that can communicate effectively with the VM.
+ */
+
+/**
+ * Code relocated from java.lang.String by 
+ * @author Dave Grove <groved@us.ibm.com>
+ */
+final class VMString
+{
+
+  /**
+   * Holds the references for each intern()'d String. If all references to
+   * the string disappear, and the VM properly supports weak references,
+   * the String will be GC'd.
+   */
+//    private static final WeakHashMap internTable = new WeakHashMap();
+
+  /**
+   * Fetches this String from the intern hashtable. If two Strings are
+   * considered equal, by the equals() method, then intern() will return the
+   * same String instance. ie. if (s1.equals(s2)) then
+   * (s1.intern() == s2.intern()). All string literals and string-valued
+   * constant expressions are already interned.
+   *
+   * @param str the String to intern
+   * @return the interned String
+   */
+//    static String intern(String str)
+//    {
+//      synchronized (internTable)
+//        {
+//          WeakReference ref = (WeakReference) internTable.get(str);
+//          if (ref != null)
+//            {
+//              String s = (String) ref.get();
+//              // If s is null, then no strong references exist to the String;
+//              // the weak hash map will soon delete the key.
+//              if (s != null)
+//                return s;
+//            }
+//          internTable.put(str, new WeakReference(str));
+//        }
+//      return str;
+//    }
+
+  /**
+   * this one is native in CACAO
+   */
+  static native String intern(String str);
+
+} // class VMString
diff --git a/src/classes/gnu/java/lang/VMThread.java b/src/classes/gnu/java/lang/VMThread.java
new file mode 100644 (file)
index 0000000..a511f3c
--- /dev/null
@@ -0,0 +1,462 @@
+/* VMThread -- VM interface for Thread of executable code
+   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+/**
+ * VM interface for Thread of executable code. Holds VM dependent state.
+ * It is deliberately package local and final and should only be accessed
+ * by the Thread class.
+ * <p>
+ * This is the GNU Classpath reference implementation, it should be adapted
+ * for a specific VM.
+ * <p>
+ * The following methods must be implemented:
+ * <ul>
+ * <li>native void start(long stacksize);
+ * <li>native void interrupt();
+ * <li>native boolean isInterrupted();
+ * <li>native void suspend();
+ * <li>native void resume();
+ * <li>native void nativeSetPriority(int priority);
+ * <li>native void nativeStop(Throwable t);
+ * <li>native static Thread currentThread();
+ * <li>static native void yield();
+ * <li>static native boolean interrupted();
+ * </ul>
+ * All other methods may be implemented to make Thread handling more efficient
+ * or to implement some optional (and sometimes deprecated) behaviour. Default
+ * implementations are provided but it is highly recommended to optimize them
+ * for a specific VM.
+ * 
+ * @author Jeroen Frijters (jeroen@frijters.net)
+ * @author Dalibor Topic (robilad@kaffe.org)
+ */
+final class VMThread
+{
+    /**
+     * The Thread object that this VM state belongs to.
+     * Used in currentThread() and start().
+     * Note: when this thread dies, this reference is *not* cleared
+     */
+    volatile Thread thread;
+
+    /**
+     * Flag that is set when the thread runs, used by stop() to protect against
+     * stop's getting lost.
+     */
+    private volatile boolean running;
+
+    /**
+     * VM private data.
+     */
+    private transient Object vmdata;
+
+    /**
+     * Private constructor, create VMThreads with the static create method.
+     *
+     * @param thread The Thread object that was just created.
+     */
+    private VMThread(Thread thread)
+    {
+       this.thread = thread;
+    }
+
+    /**
+     * This method is the initial Java code that gets executed when a native
+     * thread starts. It's job is to coordinate with the rest of the VMThread
+     * logic and to start executing user code and afterwards handle clean up.
+     */
+    private void run()
+    {
+       try
+       {
+           try
+           {
+               running = true;
+               synchronized(thread)
+               {
+                   Throwable t = thread.stillborn;
+                   if(t != null)
+                   {
+                       thread.stillborn = null;
+                       throw t;
+                   }
+               }
+               thread.run();
+           }
+           catch(Throwable t)
+           {
+               try
+               {
+                 Thread.UncaughtExceptionHandler handler;
+                 handler = thread.getUncaughtExceptionHandler();
+                 handler.uncaughtException(thread, t);
+               }
+               catch(Throwable ignore)
+               {
+               }
+           }
+       }
+       finally
+       {
+           // Setting runnable to false is partial protection against stop
+           // being called while we're cleaning up. To be safe all code in
+           // VMThread be unstoppable.
+           running = false;
+           thread.die();
+           synchronized(this)
+           {
+               // release the threads waiting to join us
+               notifyAll();
+           }
+       }
+    }
+
+    /**
+     * Creates a native Thread. This is called from the start method of Thread.
+     * The Thread is started.
+     *
+     * @param thread The newly created Thread object
+     * @param stacksize Indicates the requested stacksize. Normally zero,
+     * non-zero values indicate requested stack size in bytes but it is up
+     * to the specific VM implementation to interpret them and may be ignored.
+     */
+    static void create(Thread thread, long stacksize)
+    {
+       VMThread vmThread = new VMThread(thread);
+       thread.vmThread = vmThread;
+       vmThread.start(stacksize);
+    }
+
+    /**
+     * Gets the name of the thread. Usually this is the name field of the
+     * associated Thread object, but some implementation might choose to
+     * return the name of the underlying platform thread.
+     */
+    String getName()
+    {
+       return thread.name;
+    }
+
+    /**
+     * Set the name of the thread. Usually this sets the name field of the
+     * associated Thread object, but some implementations might choose to
+     * set the name of the underlying platform thread.
+     * @param name The new name
+     */
+    void setName(String name)
+    {
+       thread.name = name;
+    }
+
+    /**
+     * Set the thread priority field in the associated Thread object and
+     * calls the native method to set the priority of the underlying
+     * platform thread.
+     * @param priority The new priority
+     */
+    void setPriority(int priority)
+    {
+       thread.priority = priority;
+       nativeSetPriority(priority);
+    }
+
+    /**
+     * Returns the priority. Usually this is the priority field from the
+     * associated Thread object, but some implementation might choose to
+     * return the priority of the underlying platform thread.
+     * @return this Thread's priority
+     */
+    int getPriority()
+    {
+        return thread.priority;
+    }
+
+    /**
+     * Returns true if the thread is a daemon thread. Usually this is the
+     * daemon field from the associated Thread object, but some
+     * implementation might choose to return the daemon state of the underlying
+     * platform thread.
+     * @return whether this is a daemon Thread or not
+     */
+    boolean isDaemon()
+    {
+        return thread.daemon;
+    }
+
+    /**
+     * Returns the number of stack frames in this Thread.
+     * Will only be called when when a previous call to suspend() returned true.
+     *
+     * @deprecated unsafe operation
+     */
+    native int countStackFrames();
+
+    /**
+     * Wait the specified amount of time for the Thread in question to die.
+     *
+     * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
+     * not offer that fine a grain of timing resolution. Besides, there is
+     * no guarantee that this thread can start up immediately when time expires,
+     * because some other thread may be active.  So don't expect real-time
+     * performance.
+     *
+     * @param ms the number of milliseconds to wait, or 0 for forever
+     * @param ns the number of extra nanoseconds to sleep (0-999999)
+     * @throws InterruptedException if the Thread is interrupted; it's
+     *         <i>interrupted status</i> will be cleared
+     */
+    synchronized void join(long ms, int ns) throws InterruptedException
+    {
+       // Round up
+       ms += (ns != 0) ? 1 : 0;
+
+       // 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.
+       while(thread.vmThread != null)
+       {
+           // We use the VMThread object to wait on, because this is a private
+           // object, so client code cannot call notify on us.
+           wait(ms);
+           if(ms != 0)
+           {
+               now = System.currentTimeMillis();
+               ms = end - now;
+               if(ms <= 0)
+               {
+                   break;
+               }
+           }
+       }
+    }
+
+    /**
+     * Cause this Thread to stop abnormally and throw the specified exception.
+     * If you stop a Thread that has not yet started, the stop is ignored
+     * (contrary to what the JDK documentation says).
+     * <b>WARNING</b>This bypasses Java security, and can throw a checked
+     * exception which the call stack is unprepared to handle. Do not abuse 
+     * this power.
+     *
+     * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
+     * leave data in bad states.
+     *
+     * <p><b>NOTE</b> stop() should take care not to stop a thread if it is
+     * executing code in this class.
+     *
+     * @param t the Throwable to throw when the Thread dies
+     * @deprecated unsafe operation, try not to use
+     */
+    void stop(Throwable t)
+    {
+       // Note: we assume that we own the lock on thread
+       // (i.e. that Thread.stop() is synchronized)
+       if(running)
+           nativeStop(t);
+       else
+           thread.stillborn = t;
+    }
+
+    /**
+     * Create a native thread on the underlying platform and start it executing
+     * on the run method of this object.
+     * @param stacksize the requested size of the native thread stack
+     */
+    native void start(long stacksize);
+
+    /**
+     * Interrupt this thread.
+     */
+    native void interrupt();
+
+    /**
+     * Determine whether this Thread has been interrupted, but leave
+     * the <i>interrupted status</i> alone in the process.
+     *
+     * @return whether the Thread has been interrupted
+     */
+    native boolean isInterrupted();
+
+    /**
+     * Suspend this Thread.  It will not come back, ever, unless it is resumed.
+     */
+    native void suspend();
+
+    /**
+     * Resume this Thread.  If the thread is not suspended, this method does
+     * nothing.
+     */
+    native void resume();
+
+    /**
+     * Set the priority of the underlying platform thread.
+     *
+     * @param priority the new priority
+     */
+    native void nativeSetPriority(int priority);
+
+    /**
+     * Asynchronously throw the specified throwable in this Thread.
+     *
+     * @param t the exception to throw
+     */
+    native void nativeStop(Throwable t);
+
+    /**
+     * Return the Thread object associated with the currently executing
+     * thread.
+     *
+     * @return the currently executing Thread
+     */
+    static native Thread currentThread();
+
+    /**
+     * Yield to another thread. The Thread will not lose any locks it holds
+     * during this time. There are no guarantees which thread will be
+     * next to run, and it could even be this one, but most VMs will choose
+     * the highest priority thread that has been waiting longest.
+     */
+    static native void yield();
+
+    /**
+     * Suspend the current Thread's execution for the specified amount of
+     * time. The Thread will not lose any locks it has during this time. There
+     * are no guarantees which thread will be next to run, but most VMs will
+     * choose the highest priority thread that has been waiting longest.
+     *
+     * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
+     * not offer that fine a grain of timing resolution. Besides, there is
+     * no guarantee that this thread can start up immediately when time expires,
+     * because some other thread may be active.  So don't expect real-time
+     * performance.
+     *
+     * @param ms the number of milliseconds to sleep.
+     * @param ns the number of extra nanoseconds to sleep (0-999999)
+     * @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;
+       }
+
+      // 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;
+           }
+       }
+    }
+
+    /**
+     * Determine whether the current Thread has been interrupted, and clear
+     * the <i>interrupted status</i> in the process.
+     *
+     * @return whether the current Thread has been interrupted
+     */
+    static native boolean interrupted();
+
+    /**
+     * Checks whether the current thread holds the monitor on a given object.
+     * This allows you to do <code>assert Thread.holdsLock(obj)</code>.
+     *
+     * @param obj the object to check
+     * @return true if the current thread is currently synchronized on obj
+     * @throws NullPointerException if obj is null
+     */
+//     static boolean holdsLock(Object obj) 
+//     {
+//       /* Use obj.notify to check if the current thread holds
+//        * the monitor of the object.
+//        * If it doesn't, notify will throw an exception.
+//        */
+//       try 
+//     {
+//       obj.notify();
+//       // okay, current thread holds lock
+//       return true;
+//     }
+//       catch (IllegalMonitorStateException e)
+//     {
+//       // it doesn't hold the lock
+//       return false;
+//     }
+//     }
+    static native boolean holdsLock(Object obj);
+
+  /**
+   * Returns the current state of the thread.
+   * The value must be one of "BLOCKED", "NEW",
+   * "RUNNABLE", "TERMINATED", "TIMED_WAITING" or
+   * "WAITING".
+   *
+   * @return a string corresponding to one of the 
+   *         thread enumeration states specified above.
+   */
+  native String getState();
+
+}
diff --git a/src/classes/gnu/java/lang/reflect/Constructor.java b/src/classes/gnu/java/lang/reflect/Constructor.java
new file mode 100644 (file)
index 0000000..55b82e8
--- /dev/null
@@ -0,0 +1,449 @@
+/* java.lang.reflect.Constructor - reflection of Java constructors
+   Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Constructor class represents a constructor of a class. It also allows
+ * dynamic creation of an object, via reflection. Invocation on Constructor
+ * objects knows how to do widening conversions, but throws
+ * {@link IllegalArgumentException} if a narrowing conversion would be
+ * necessary. You can query for information on this Constructor regardless
+ * of location, but construction access may be limited by Java language
+ * access controls. If you can't do it in the compiler, you can't normally
+ * do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructor(Class[])
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getDeclaredConstructors()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Constructor<T>
+  extends AccessibleObject
+  implements GenericDeclaration, Member
+{  
+  private static final int CONSTRUCTOR_MODIFIERS
+    = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
+  private MethodSignatureParser p;
+
+  VMConstructor cons;
+
+  /**
+   * This class is uninstantiable outside this package.
+   */
+  Constructor(VMConstructor cons)
+  {
+    this.cons = cons;
+    cons.cons = this;
+  }
+
+  private Constructor()
+  {
+  }
+
+  /**
+   * Gets the class that declared this constructor.
+   * @return the class that declared this member
+   */
+  @SuppressWarnings("unchecked")
+  public Class<T> getDeclaringClass()
+  {
+    return (Class<T>) cons.getDeclaringClass();
+  }
+
+  /**
+   * Gets the name of this constructor (the non-qualified name of the class
+   * it was declared in).
+   * @return the name of this constructor
+   */
+  public String getName()
+  {
+    return cons.getDeclaringClass().getName();
+  }
+
+  /**
+   * Gets the modifiers this constructor uses.  Use the <code>Modifier</code>
+   * class to interpret the values. A constructor can only have a subset of the
+   * following modifiers: public, private, protected.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public int getModifiers()
+  {
+    return cons.getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
+  }
+
+  /**
+   * Return true if this constructor is synthetic, false otherwise.
+   * A synthetic member is one which is created by the compiler,
+   * and which does not appear in the user's source code.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (cons.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this is a varargs constructor, that is if
+   * the constructor takes a variable number of arguments.
+   * @since 1.5
+   */
+  public boolean isVarArgs()
+  {
+    return (cons.getModifiersInternal() & Modifier.VARARGS) != 0;
+  }
+
+  /**
+   * Get the parameter list for this constructor, in declaration order. If the
+   * constructor takes no parameters, returns a 0-length array (not null).
+   *
+   * @return a list of the types of the constructor's parameters
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?>[] getParameterTypes()
+  {
+    return (Class<?>[]) cons.getParameterTypes();
+  }
+
+  /**
+   * Get the exception types this constructor says it throws, in no particular
+   * order. If the constructor has no throws clause, returns a 0-length array
+   * (not null).
+   *
+   * @return a list of the types in the constructor's throws clause
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?>[] getExceptionTypes()
+  {
+    return (Class<?>[]) cons.getExceptionTypes();
+  }
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Constructors are semantically equivalent if they have the same
+   * declaring class and the same parameter list.  This ignores different
+   * exception clauses, but since you can't create a Method except through the
+   * VM, this is just the == relation.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not.
+   */
+  public boolean equals(Object o)
+  {
+    return cons.equals(o);
+  }
+
+  /**
+   * Get the hash code for the Constructor. The Constructor hash code is the
+   * hash code of the declaring class's name.
+   *
+   * @return the hash code for the object
+   */
+  public int hashCode()
+  {
+    return getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Constructor. A Constructor's String
+   * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
+   * throws &lt;exceptions&gt;", where everything after ')' is omitted if
+   * there are no exceptions.<br> Example:
+   * <code>public java.io.FileInputStream(java.lang.Runnable)
+   * throws java.io.FileNotFoundException</code>
+   *
+   * @return the String representation of the Constructor
+   */
+  public String toString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    CPStringBuilder sb = new CPStringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(getDeclaringClass().getName()).append('(');
+    Class[] c = getParameterTypes();
+    if (c.length > 0)
+      {
+        sb.append(ClassHelper.getUserName(c[0]));
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(ClassHelper.getUserName(c[i]));
+      }
+    sb.append(')');
+    c = getExceptionTypes();
+    if (c.length > 0)
+      {
+        sb.append(" throws ").append(c[0].getName());
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(c[i].getName());
+      }
+    return sb.toString();
+  }
+
+  static <X extends GenericDeclaration>
+  void addTypeParameters(CPStringBuilder sb, TypeVariable<X>[] typeArgs)
+  {
+    if (typeArgs.length == 0)
+      return;
+    sb.append('<');
+    for (int i = 0; i < typeArgs.length; ++i)
+      {
+        if (i > 0)
+          sb.append(',');
+        sb.append(typeArgs[i]);
+      }
+    sb.append("> ");
+  }
+
+  public String toGenericString()
+  {
+    CPStringBuilder sb = new CPStringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    addTypeParameters(sb, getTypeParameters());
+    sb.append(getDeclaringClass().getName()).append('(');
+    Type[] types = getGenericParameterTypes();
+    if (types.length > 0)
+      {
+        sb.append(types[0]);
+        for (int i = 1; i < types.length; ++i)
+          sb.append(',').append(types[i]);
+      }
+    sb.append(')');
+    types = getGenericExceptionTypes();
+    if (types.length > 0)
+      {
+        sb.append(" throws ").append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    return sb.toString();
+  }
+
+  /**
+   * Create a new instance by invoking the constructor. Arguments are
+   * automatically unwrapped and widened, if needed.<p>
+   *
+   * If this class is abstract, you will get an
+   * <code>InstantiationException</code>. If the constructor takes 0
+   * arguments, you may use null or a 0-length array for <code>args</code>.<p>
+   *
+   * If this Constructor enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not create this object in similar compiled code. If the class
+   * is uninitialized, you trigger class initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Then, the constructor is invoked. If it completes normally, the return
+   * value will be the new object. If it completes abruptly, the exception is
+   * wrapped in an <code>InvocationTargetException</code>.
+   *
+   * @param args the arguments to the constructor
+   * @return the newly created object
+   * @throws IllegalAccessException if the constructor could not normally be
+   *         called by the Java code (i.e. it is not public)
+   * @throws IllegalArgumentException if the number of arguments is incorrect;
+   *         or if the arguments types are wrong even with a widening
+   *         conversion
+   * @throws InstantiationException if the class is abstract
+   * @throws InvocationTargetException if the constructor throws an exception
+   * @throws ExceptionInInitializerError if construction triggered class
+   *         initialization, which then failed
+   */
+  @SuppressWarnings("unchecked")
+  public T newInstance(Object... args)
+    throws InstantiationException, IllegalAccessException,
+           InvocationTargetException
+  {
+    return (T) cons.construct(args);
+  }
+
+  /**
+   * Returns an array of <code>TypeVariable</code> objects that represents
+   * the type variables declared by this constructor, in declaration order.
+   * An array of size zero is returned if this constructor has no type
+   * variables.
+   *
+   * @return the type variables associated with this constructor.
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public TypeVariable<Constructor<T>>[] getTypeParameters()
+  {
+    if (p == null)
+      {
+       String sig = cons.getSignature();
+       if (sig == null)
+         return new TypeVariable[0];
+       p = new MethodSignatureParser(this, sig);
+      }
+    return p.getTypeParameters();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the exception types declared by this constructor, in declaration order.
+   * An array of size zero is returned if this constructor declares no
+   * exceptions.
+   *
+   * @return the exception types declared by this constructor. 
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericExceptionTypes()
+  {
+    if (p == null)
+      {
+       String sig = cons.getSignature();
+       if (sig == null)
+         return getExceptionTypes();
+       p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericExceptionTypes();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the parameter list for this constructor, in declaration order.
+   * An array of size zero is returned if this constructor takes no
+   * parameters.
+   *
+   * @return a list of the types of the constructor's parameters
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericParameterTypes()
+  {
+    if (p == null)
+      {
+       String sig = cons.getSignature();
+       if (sig == null)
+         return getParameterTypes();
+       p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericParameterTypes();
+  }
+
+  /**
+   * <p>
+   * Return an array of arrays representing the annotations on each
+   * of the constructor's parameters.  The outer array is aligned against
+   * the parameters of the constructors and is thus equal in length to
+   * the number of parameters (thus having a length zero if there are none).
+   * Each array element in the outer array contains an inner array which
+   * holds the annotations.  This array has a length of zero if the parameter
+   * has no annotations.
+   * </p>
+   * <p>
+   * The returned annotations are serialized.  Changing the annotations has
+   * no affect on the return value of future calls to this method.
+   * </p>
+   * 
+   * @return an array of arrays which represents the annotations used on the
+   *         parameters of this constructor.  The order of the array elements
+   *         matches the declaration order of the parameters.
+   * @since 1.5
+   */
+  public Annotation[][] getParameterAnnotations()
+  {
+    return cons.getParameterAnnotations();
+  }
+
+  /**
+   * Returns the element's annotation for the specified annotation type,
+   * or <code>null</code> if no such annotation exists.
+   *
+   * @param annotationClass the type of annotation to look for.
+   * @return this element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+  @SuppressWarnings("unchecked")
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+  {
+    return (T) cons.getAnnotation(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, then a zero-length
+   * array will be returned.  The returned array may be modified by the client
+   * code, but this will have no effect on the annotation content of this
+   * class, and hence no effect on the return value of this method for
+   * future callers.
+   *
+   * @return the annotations directly defined by the element.
+   * @since 1.5
+   */
+  public Annotation[] getDeclaredAnnotations()
+  {
+    return cons.getDeclaredAnnotations();
+  }
+
+}
diff --git a/src/classes/gnu/java/lang/reflect/Field.java b/src/classes/gnu/java/lang/reflect/Field.java
new file mode 100644 (file)
index 0000000..4c2c183
--- /dev/null
@@ -0,0 +1,735 @@
+/* java.lang.reflect.Field - reflection of Java fields
+   Copyright (C) 1998, 2001, 2005, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Field class represents a member variable of a class. It also allows
+ * dynamic access to a member, via reflection. This works for both
+ * static and instance fields. Operations on Field objects know how to
+ * do widening conversions, but throw {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Field regardless of location, but get and set access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see Class#getField(String)
+ * @see Class#getDeclaredField(String)
+ * @see Class#getFields()
+ * @see Class#getDeclaredFields()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Field
+extends AccessibleObject implements Member
+{
+  static final int FIELD_MODIFIERS
+    = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+      | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+      | Modifier.VOLATILE;
+
+  private FieldSignatureParser p;
+
+  VMField f;
+
+  /**
+   * This class is uninstantiable outside the package.
+   */
+  Field(VMField f)
+  {
+    this.f = f;
+    f.f = this;
+  }
+
+  /**
+   * Gets the class that declared this field, or the class where this field
+   * is a non-inherited member.
+   * @return the class that declared this member
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?> getDeclaringClass()
+  {
+    return (Class<?>) f.getDeclaringClass();
+  }
+
+  /**
+   * Gets the name of this field.
+   * @return the name of this field
+   */
+  public String getName()
+  {
+    return f.getName();
+  }
+
+  /**
+   * Gets the modifiers this field uses.  Use the <code>Modifier</code>
+   * class to interpret the values.  A field can only have a subset of the
+   * following modifiers: public, private, protected, static, final,
+   * transient, and volatile.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public int getModifiers()
+  {
+    return f.getModifiersInternal() & FIELD_MODIFIERS;
+  }
+
+  /**
+   * Return true if this field is synthetic, false otherwise.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (f.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this field represents an enum constant,
+   * false otherwise.
+   * @since 1.5
+   */
+  public boolean isEnumConstant()
+  {
+    return (f.getModifiersInternal() & Modifier.ENUM) != 0;
+  }
+
+  /**
+   * Gets the type of this field.
+   * @return the type of this field
+   */
+  public Class<?> getType()
+  {
+    return f.getType();
+  }
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Fields are semantically equivalent if they have the same declaring
+   * class, name, and type. Since you can't creat a Field except through
+   * the VM, this is just the == relation.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not
+   */
+  public boolean equals(Object o)
+  {
+    return f.equals(o);
+  }
+
+  /**
+   * Get the hash code for the Field. The Field hash code is the hash code
+   * of its name XOR'd with the hash code of its class name.
+   *
+   * @return the hash code for the object.
+   */
+  public int hashCode()
+  {
+    return f.getDeclaringClass().getName().hashCode() ^ f.getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Field. A Field's String
+   * representation is "&lt;modifiers&gt; &lt;type&gt;
+   * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
+   * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
+   *
+   * @return the String representation of the Field
+   */
+  public String toString()
+  {
+    // 64 is a reasonable buffer initial size for field
+    CPStringBuilder sb = new CPStringBuilder(64);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(ClassHelper.getUserName(getType())).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName());
+    return sb.toString();
+  }
+
+  public String toGenericString()
+  {
+    CPStringBuilder sb = new CPStringBuilder(64);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(getGenericType()).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName());
+    return sb.toString();
+  }
+
+  /**
+   * Get the value of this Field.  If it is primitive, it will be wrapped
+   * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
+   *
+   * If the field is static, <code>o</code> will be ignored. Otherwise, if
+   * <code>o</code> is null, you get a <code>NullPointerException</code>,
+   * and if it is incompatible with the declaring class of the field, you
+   * get an <code>IllegalArgumentException</code>.<p>
+   *
+   * Next, if this Field enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not access this field in similar compiled code. If the field
+   * is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the field is accessed, and primitives are wrapped (but not
+   * necessarily in new objects). This method accesses the field of the
+   * declaring class, even if the instance passed in belongs to a subclass
+   * which declares another field to hide this one.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if <code>o</code> is not an instance of
+   *         the class or interface declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #getBoolean(Object)
+   * @see #getByte(Object)
+   * @see #getChar(Object)
+   * @see #getShort(Object)
+   * @see #getInt(Object)
+   * @see #getLong(Object)
+   * @see #getFloat(Object)
+   * @see #getDouble(Object)
+   */
+  public Object get(Object o)
+    throws IllegalAccessException
+  {
+    return f.get(o);
+  }
+
+  /**
+   * Get the value of this boolean Field. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a boolean field of
+   *         <code>o</code>, or if <code>o</code> is not an instance of the
+   *         declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public boolean getBoolean(Object o)
+    throws IllegalAccessException
+  {
+    return f.getBoolean(o);
+  }
+
+  /**
+   * Get the value of this byte Field. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte field of
+   *         <code>o</code>, or if <code>o</code> is not an instance of the
+   *         declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public byte getByte(Object o)
+    throws IllegalAccessException
+  {
+    return f.getByte(o);
+  }
+
+  /**
+   * Get the value of this Field as a char. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a char field of
+   *         <code>o</code>, or if <code>o</code> is not an instance
+   *         of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public char getChar(Object o)
+    throws IllegalAccessException
+  {
+    return f.getChar(o);
+  }
+
+  /**
+   * Get the value of this Field as a short. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte or short
+   *         field of <code>o</code>, or if <code>o</code> is not an instance
+   *         of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public short getShort(Object o)
+    throws IllegalAccessException
+  {
+    return f.getShort(o);
+  }
+
+  /**
+   * Get the value of this Field as an int. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, or
+   *         int field of <code>o</code>, or if <code>o</code> is not an
+   *         instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public int getInt(Object o)
+    throws IllegalAccessException
+  {
+    return f.getInt(o);
+  }
+
+  /**
+   * Get the value of this Field as a long. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         or long field of <code>o</code>, or if <code>o</code> is not an
+   *         instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public long getLong(Object o)
+    throws IllegalAccessException
+  {
+    return f.getLong(o);
+  }
+
+  /**
+   * Get the value of this Field as a float. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         long, or float field of <code>o</code>, or if <code>o</code> is
+   *         not an instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public float getFloat(Object o)
+    throws IllegalAccessException
+  {
+    return f.getFloat(o);
+  }
+
+  /**
+   * Get the value of this Field as a double. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         long, float, or double field of <code>o</code>, or if
+   *         <code>o</code> is not an instance of the declaring class of this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public double getDouble(Object o)
+    throws IllegalAccessException
+  {
+    return f.getDouble(o);
+  }
+
+  /**
+   * Set the value of this Field.  If it is a primitive field, the value
+   * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
+   *
+   * If the field is static, <code>o</code> will be ignored. Otherwise, if
+   * <code>o</code> is null, you get a <code>NullPointerException</code>,
+   * and if it is incompatible with the declaring class of the field, you
+   * get an <code>IllegalArgumentException</code>.<p>
+   *
+   * Next, if this Field enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not access this field in similar compiled code. This also
+   * occurs whether or not there is access control if the field is final.
+   * If the field is primitive, and unwrapping your argument fails, you will
+   * get an <code>IllegalArgumentException</code>; likewise, this error
+   * happens if <code>value</code> cannot be cast to the correct object type.
+   * If the field is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the field is set with the widened value. This method accesses
+   * the field of the declaring class, even if the instance passed in belongs
+   * to a subclass which declares another field to hide this one.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if <code>value</code> cannot be
+   *         converted by a widening conversion to the underlying type of
+   *         the Field, or if <code>o</code> is not an instance of the class
+   *         declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #setBoolean(Object, boolean)
+   * @see #setByte(Object, byte)
+   * @see #setChar(Object, char)
+   * @see #setShort(Object, short)
+   * @see #setInt(Object, int)
+   * @see #setLong(Object, long)
+   * @see #setFloat(Object, float)
+   * @see #setDouble(Object, double)
+   */
+  public void set(Object o, Object value)
+    throws IllegalAccessException
+  {
+    f.set(o, value);
+  }
+
+  /**
+   * Set this boolean Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a boolean field, or if
+   *         <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setBoolean(Object o, boolean value)
+    throws IllegalAccessException
+  {
+    f.setBoolean(o, value);
+  }
+
+  /**
+   * Set this byte Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setByte(Object o, byte value)
+    throws IllegalAccessException
+  {
+    f.setByte(o, value);
+  }
+
+  /**
+   * Set this char Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a char, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setChar(Object o, char value)
+    throws IllegalAccessException
+  {
+    f.setChar(o, value);
+  }
+
+  /**
+   * Set this short Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a short, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setShort(Object o, short value)
+    throws IllegalAccessException
+  {
+    f.setShort(o, value);
+  }
+
+  /**
+   * Set this int Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not an int, long, float, or
+   *         double field, or if <code>o</code> is not an instance of the
+   *         class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setInt(Object o, int value)
+    throws IllegalAccessException
+  {
+    f.setInt(o, value);
+  }
+
+  /**
+   * Set this long Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a long, float, or double
+   *         field, or if <code>o</code> is not an instance of the class
+   *         declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setLong(Object o, long value)
+    throws IllegalAccessException
+  {
+    f.setLong(o, value);
+  }
+
+  /**
+   * Set this float Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a float or long field, or
+   *         if <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setFloat(Object o, float value)
+    throws IllegalAccessException
+  {
+    f.setFloat(o, value);
+  }
+
+  /**
+   * Set this double Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a double field, or if
+   *         <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setDouble(Object o, double value)
+    throws IllegalAccessException
+  {
+    f.setDouble(o, value);
+  }
+
+  /**
+   * Return the generic type of the field. If the field type is not a generic
+   * type, the method returns the same as <code>getType()</code>.
+   *
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type getGenericType()
+  {
+    if (p == null)
+      {
+       String signature = f.getSignature();
+       if (signature == null)
+         return getType();
+       p = new FieldSignatureParser(getDeclaringClass(),
+                                    signature);
+      }
+    return p.getFieldType();
+  }
+
+  /**
+   * Returns the element's annotation for the specified annotation type,
+   * or <code>null</code> if no such annotation exists.
+   *
+   * @param annotationClass the type of annotation to look for.
+   * @return this element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+  @SuppressWarnings("unchecked")
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+  {
+    return (T) f.getAnnotation(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, then a zero-length
+   * array will be returned.  The returned array may be modified by the client
+   * code, but this will have no effect on the annotation content of this
+   * class, and hence no effect on the return value of this method for
+   * future callers.
+   *
+   * @return the annotations directly defined by the element.
+   * @since 1.5
+   */
+  public Annotation[] getDeclaredAnnotations()
+  {
+    return f.getDeclaredAnnotations();
+  }
+
+}
diff --git a/src/classes/gnu/java/lang/reflect/Method.java b/src/classes/gnu/java/lang/reflect/Method.java
new file mode 100644 (file)
index 0000000..e787fb3
--- /dev/null
@@ -0,0 +1,499 @@
+/* java.lang.reflect.Method - reflection of Java methods
+   Copyright (C) 1998, 2001, 2002, 2005, 2007, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Method class represents a member method of a class. It also allows
+ * dynamic invocation, via reflection. This works for both static and
+ * instance methods. Invocation on Method objects knows how to do
+ * widening conversions, but throws {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Method regardless of location, but invocation access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getMethod(String,Class[])
+ * @see java.lang.Class#getDeclaredMethod(String,Class[])
+ * @see java.lang.Class#getMethods()
+ * @see java.lang.Class#getDeclaredMethods()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Method
+extends AccessibleObject implements Member, GenericDeclaration
+{
+  private static final int METHOD_MODIFIERS
+    = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
+      | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
+      | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+
+  private MethodSignatureParser p;
+
+  VMMethod m;
+
+  /**
+   * This class is uninstantiable outside this package.
+   */
+  Method(VMMethod m)
+  {
+    this.m = m;
+    m.m = this;
+  }
+
+  /**
+   * Gets the class that declared this method, or the class where this method
+   * is a non-inherited member.
+   * @return the class that declared this member
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?> getDeclaringClass()
+  {
+    return (Class<?>) m.getDeclaringClass();
+  }
+
+  /**
+   * Gets the name of this method.
+   * @return the name of this method
+   */
+  public String getName()
+  {
+    return m.getName();
+  }
+
+  /**
+   * Gets the modifiers this method uses.  Use the <code>Modifier</code>
+   * class to interpret the values.  A method can only have a subset of the
+   * following modifiers: public, private, protected, abstract, static,
+   * final, synchronized, native, and strictfp.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public int getModifiers()
+  {
+    return m.getModifiersInternal() & METHOD_MODIFIERS;
+  }
+
+  /**
+   * Return true if this method is a bridge method.  A bridge method
+   * is generated by the compiler in some situations involving
+   * generics and inheritance.
+   * @since 1.5
+   */
+  public boolean isBridge()
+  {
+    return (m.getModifiersInternal() & Modifier.BRIDGE) != 0;
+  }
+
+  /**
+   * Return true if this method is synthetic, false otherwise.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (m.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this is a varargs method, that is if
+   * the method takes a variable number of arguments.
+   * @since 1.5
+   */
+  public boolean isVarArgs()
+  {
+    return (m.getModifiersInternal() & Modifier.VARARGS) != 0;
+  }
+
+  /**
+   * Gets the return type of this method.
+   * @return the type of this method
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?> getReturnType()
+  {
+    return (Class<?>) m.getReturnType();
+  }
+
+  /**
+   * Get the parameter list for this method, in declaration order. If the
+   * method takes no parameters, returns a 0-length array (not null).
+   *
+   * @return a list of the types of the method's parameters
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?>[] getParameterTypes()
+  {
+    return (Class<?>[]) m.getParameterTypes();
+  }
+
+  /**
+   * Get the exception types this method says it throws, in no particular
+   * order. If the method has no throws clause, returns a 0-length array
+   * (not null).
+   *
+   * @return a list of the types in the method's throws clause
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?>[] getExceptionTypes()
+  {
+    return (Class<?>[]) m.getExceptionTypes();
+  }
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Methods are semantically equivalent if they have the same declaring
+   * class, name, parameter list, and return type.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not
+   */
+  public boolean equals(Object o)
+  {
+    return m.equals(o);
+  }
+
+  /**
+   * Get the hash code for the Method. The Method hash code is the hash code
+   * of its name XOR'd with the hash code of its class name.
+   *
+   * @return the hash code for the object
+   */
+  public int hashCode()
+  {
+    return m.getDeclaringClass().getName().hashCode() ^ m.getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Method. A Method's String
+   * representation is "&lt;modifiers&gt; &lt;returntype&gt;
+   * &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
+   * everything after ')' is omitted if there are no exceptions.<br> Example:
+   * <code>public static int run(java.lang.Runnable,int)</code>
+   *
+   * @return the String representation of the Method
+   */
+  public String toString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    CPStringBuilder sb = new CPStringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(ClassHelper.getUserName(getReturnType())).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName()).append('(');
+    Class[] c = getParameterTypes();
+    if (c.length > 0)
+      {
+        sb.append(ClassHelper.getUserName(c[0]));
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(ClassHelper.getUserName(c[i]));
+      }
+    sb.append(')');
+    c = getExceptionTypes();
+    if (c.length > 0)
+      {
+        sb.append(" throws ").append(c[0].getName());
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(c[i].getName());
+      }
+    return sb.toString();
+  }
+
+  public String toGenericString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    CPStringBuilder sb = new CPStringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    Constructor.addTypeParameters(sb, getTypeParameters());
+    sb.append(getGenericReturnType()).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName()).append('(');
+    Type[] types = getGenericParameterTypes();
+    if (types.length > 0)
+      {
+        sb.append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    sb.append(')');
+    types = getGenericExceptionTypes();
+    if (types.length > 0)
+      {
+        sb.append(" throws ").append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    return sb.toString();
+  }
+
+  /**
+   * Invoke the method. Arguments are automatically unwrapped and widened,
+   * and the result is automatically wrapped, if needed.<p>
+   *
+   * If the method is static, <code>o</code> will be ignored. Otherwise,
+   * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
+   * mimic the behavior of nonvirtual lookup (as in super.foo()). This means
+   * you will get a <code>NullPointerException</code> if <code>o</code> is
+   * null, and an <code>IllegalArgumentException</code> if it is incompatible
+   * with the declaring class of the method. If the method takes 0 arguments,
+   * you may use null or a 0-length array for <code>args</code>.<p>
+   *
+   * Next, if this Method enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not acces this method in similar compiled code. If the method
+   * is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the method is invoked. If it completes normally, the return value
+   * will be null for a void method, a wrapped object for a primitive return
+   * method, or the actual return of an Object method. If it completes
+   * abruptly, the exception is wrapped in an
+   * <code>InvocationTargetException</code>.
+   *
+   * @param o the object to invoke the method on
+   * @param args the arguments to the method
+   * @return the return value of the method, wrapped in the appropriate
+   *         wrapper if it is primitive
+   * @throws IllegalAccessException if the method could not normally be called
+   *         by the Java code (i.e. it is not public)
+   * @throws IllegalArgumentException if the number of arguments is incorrect;
+   *         if the arguments types are wrong even with a widening conversion;
+   *         or if <code>o</code> is not an instance of the class or interface
+   *         declaring this method
+   * @throws InvocationTargetException if the method throws an exception
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static method triggered
+   *         class initialization, which then failed
+   */
+  public Object invoke(Object o, Object... args)
+    throws IllegalAccessException, InvocationTargetException
+  {
+    return m.invoke(o, args);
+  }
+
+  /**
+   * Returns an array of <code>TypeVariable</code> objects that represents
+   * the type variables declared by this constructor, in declaration order.
+   * An array of size zero is returned if this class has no type
+   * variables.
+   *
+   * @return the type variables associated with this class. 
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public TypeVariable<Method>[] getTypeParameters()
+  {
+    if (p == null)
+      {
+       String sig = m.getSignature();
+       if (sig == null)
+         return (TypeVariable<Method>[]) new TypeVariable[0];
+       p = new MethodSignatureParser(this, sig);
+      }
+    return p.getTypeParameters();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the exception types declared by this method, in declaration order.
+   * An array of size zero is returned if this method declares no
+   * exceptions.
+   *
+   * @return the exception types declared by this method. 
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericExceptionTypes()
+  {
+    if (p == null)
+      {
+       String sig = m.getSignature();
+       if (sig == null)
+         return getExceptionTypes();
+       p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericExceptionTypes();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the parameter list for this method, in declaration order.
+   * An array of size zero is returned if this method takes no
+   * parameters.
+   *
+   * @return a list of the types of the method's parameters
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericParameterTypes()
+  {
+    if (p == null)
+      {
+       String sig = m.getSignature();
+       if (sig == null)
+         return getParameterTypes();
+       p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericParameterTypes();
+  }
+
+  /**
+   * Returns the return type of this method.
+   *
+   * @return the return type of this method
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type getGenericReturnType()
+  {
+    if (p == null)
+      {
+       String sig = m.getSignature();
+       if (sig == null)
+         return getReturnType();
+       p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericReturnType();
+  }
+
+  /**
+   * If this method is an annotation method, returns the default
+   * value for the method.  If there is no default value, or if the
+   * method is not a member of an annotation type, returns null.
+   * Primitive types are wrapped.
+   *
+   * @throws TypeNotPresentException if the method returns a Class,
+   * and the class cannot be found
+   *
+   * @since 1.5
+   */
+  public Object getDefaultValue()
+  {
+    return m.getDefaultValue();
+  }
+
+  /**
+   * <p>
+   * Return an array of arrays representing the annotations on each
+   * of the method's parameters.  The outer array is aligned against
+   * the parameters of the method and is thus equal in length to
+   * the number of parameters (thus having a length zero if there are none).
+   * Each array element in the outer array contains an inner array which
+   * holds the annotations.  This array has a length of zero if the parameter
+   * has no annotations.
+   * </p>
+   * <p>
+   * The returned annotations are serialized.  Changing the annotations has
+   * no affect on the return value of future calls to this method.
+   * </p>
+   * 
+   * @return an array of arrays which represents the annotations used on the
+   *         parameters of this method.  The order of the array elements
+   *         matches the declaration order of the parameters.
+   * @since 1.5
+   */
+  public Annotation[][] getParameterAnnotations()
+  {
+    return m.getParameterAnnotations();
+  }
+
+  /**
+   * Returns the element's annotation for the specified annotation type,
+   * or <code>null</code> if no such annotation exists.
+   *
+   * @param annotationClass the type of annotation to look for.
+   * @return this element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+  @SuppressWarnings("unchecked")
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+  {
+    return (T) m.getAnnotation(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, then a zero-length
+   * array will be returned.  The returned array may be modified by the client
+   * code, but this will have no effect on the annotation content of this
+   * class, and hence no effect on the return value of this method for
+   * future callers.
+   *
+   * @return the annotations directly defined by the element.
+   * @since 1.5
+   */
+  public Annotation[] getDeclaredAnnotations()
+  {
+    return m.getDeclaredAnnotations();
+  }
+
+}
diff --git a/src/classes/gnu/java/lang/reflect/Modifier.java b/src/classes/gnu/java/lang/reflect/Modifier.java
new file mode 100644 (file)
index 0000000..45d9b51
--- /dev/null
@@ -0,0 +1,354 @@
+/* java.lang.reflect.Modifier
+   Copyright (C) 1998, 1999, 2001, 2002, 2005, 2008  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.CPStringBuilder;
+
+/**
+ * Modifier is a helper class with static methods to determine whether an
+ * int returned from getModifiers() represents static, public, protected,
+ * native, final, etc... and provides an additional method to print
+ * out all of the modifiers in an int in order.
+ * <p>
+ * The methods in this class use the bitmask values in the VM spec to
+ * determine the modifiers of an int. This means that a VM must return a
+ * standard mask, conformant with the VM spec.  I don't know if this is how
+ * Sun does it, but I'm willing to bet money that it is.
+ *
+ * @author John Keiser
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Member#getModifiers()
+ * @see Method#getModifiers()
+ * @see Field#getModifiers()
+ * @see Constructor#getModifiers()
+ * @see Class#getModifiers()
+ * @since 1.1
+ */
+public class Modifier
+{
+  /** <STRONG>This constructor really shouldn't be here ... there are no
+   * instance methods or variables of this class, so instantiation is
+   * worthless.  However, this function is in the 1.1 spec, so it is added
+   * for completeness.</STRONG>
+   */
+  public Modifier()
+  {
+  }
+
+  /**
+   * Public: accessible from any other class.
+   */
+  public static final int PUBLIC = 0x0001;
+
+  /**
+   * Private: accessible only from the same enclosing class.
+   */
+  public static final int PRIVATE = 0x0002;
+
+  /**
+   * Protected: accessible only to subclasses, or within the package.
+   */
+  public static final int PROTECTED = 0x0004;
+
+  /**
+   * Static:<br><ul>
+   * <li>Class: no enclosing instance for nested class.</li>
+   * <li>Field or Method: can be accessed or invoked without an
+   *     instance of the declaring class.</li>
+   * </ul>
+   */
+  public static final int STATIC = 0x0008;
+
+  /**
+   * Final:<br><ul>
+   * <li>Class: no subclasses allowed.</li>
+   * <li>Field: cannot be changed.</li>
+   * <li>Method: cannot be overriden.</li>
+   * </ul>
+   */
+  public static final int FINAL = 0x0010;
+
+  /**
+   * Synchronized: Method: lock the class while calling this method.
+   */
+  public static final int SYNCHRONIZED = 0x0020;
+
+  /**
+   * Volatile: Field: cannot be cached.
+   */
+  public static final int VOLATILE = 0x0040;
+
+  /**
+   * Transient: Field: not serialized or deserialized.
+   */
+  public static final int TRANSIENT = 0x0080;
+
+  /**
+   * Native: Method: use JNI to call this method.
+   */
+  public static final int NATIVE = 0x0100;
+
+  /**
+   * Interface: Class: is an interface.
+   */
+  public static final int INTERFACE = 0x0200;
+
+  /**
+   * Abstract:<br><ul>
+   * <li>Class: may not be instantiated.</li>
+   * <li>Method: may not be called.</li>
+   * </ul>
+   */
+  public static final int ABSTRACT = 0x0400;
+
+  /**
+   * Strictfp: Method: expressions are FP-strict.<p>
+   * Also used as a modifier for classes, to mean that all initializers
+   * and constructors are FP-strict, but does not show up in
+   * Class.getModifiers.
+   */
+  public static final int STRICT = 0x0800;
+
+
+  /**
+   * Super - treat invokespecial as polymorphic so that super.foo() works
+   * according to the JLS. This is a reuse of the synchronized constant
+   * to patch a hole in JDK 1.0. *shudder*.
+   */
+  static final int SUPER = 0x0020;
+
+  /**
+   * All the flags, only used by code in this package.
+   */
+  static final int ALL_FLAGS = 0xfff;
+
+  /**
+   * Flag indicating a bridge method.
+   */
+  static final int BRIDGE = 0x40;
+
+  /**
+   * Flag indicating a varargs method.
+   */
+  static final int VARARGS = 0x80;
+
+  /**
+   * Flag indicating a synthetic member.
+   */
+  static final int SYNTHETIC = 0x1000;
+
+  /**
+   * Flag indicating an enum constant or an enum class.
+   */
+  static final int ENUM = 0x4000;
+
+  /**
+   * Check whether the given modifier is abstract.
+   * @param mod the modifier.
+   * @return <code>true</code> if abstract, <code>false</code> otherwise.
+   */
+  public static boolean isAbstract(int mod)
+  {
+    return (mod & ABSTRACT) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is final.
+   * @param mod the modifier.
+   * @return <code>true</code> if final, <code>false</code> otherwise.
+   */
+  public static boolean isFinal(int mod)
+  {
+    return (mod & FINAL) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is an interface.
+   * @param mod the modifier.
+   * @return <code>true</code> if an interface, <code>false</code> otherwise.
+   */
+  public static boolean isInterface(int mod)
+  {
+    return (mod & INTERFACE) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is native.
+   * @param mod the modifier.
+   * @return <code>true</code> if native, <code>false</code> otherwise.
+   */
+  public static boolean isNative(int mod)
+  {
+    return (mod & NATIVE) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is private.
+   * @param mod the modifier.
+   * @return <code>true</code> if private, <code>false</code> otherwise.
+   */
+  public static boolean isPrivate(int mod)
+  {
+    return (mod & PRIVATE) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is protected.
+   * @param mod the modifier.
+   * @return <code>true</code> if protected, <code>false</code> otherwise.
+   */
+  public static boolean isProtected(int mod)
+  {
+    return (mod & PROTECTED) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is public.
+   * @param mod the modifier.
+   * @return <code>true</code> if public, <code>false</code> otherwise.
+   */
+  public static boolean isPublic(int mod)
+  {
+    return (mod & PUBLIC) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is static.
+   * @param mod the modifier.
+   * @return <code>true</code> if static, <code>false</code> otherwise.
+   */
+  public static boolean isStatic(int mod)
+  {
+    return (mod & STATIC) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is strictfp.
+   * @param mod the modifier.
+   * @return <code>true</code> if strictfp, <code>false</code> otherwise.
+   */
+  public static boolean isStrict(int mod)
+  {
+    return (mod & STRICT) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is synchronized.
+   * @param mod the modifier.
+   * @return <code>true</code> if synchronized, <code>false</code> otherwise.
+   */
+  public static boolean isSynchronized(int mod)
+  {
+    return (mod & SYNCHRONIZED) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is transient.
+   * @param mod the modifier.
+   * @return <code>true</code> if transient, <code>false</code> otherwise.
+   */
+  public static boolean isTransient(int mod)
+  {
+    return (mod & TRANSIENT) != 0;
+  }
+
+  /**
+   * Check whether the given modifier is volatile.
+   * @param mod the modifier.
+   * @return <code>true</code> if volatile, <code>false</code> otherwise.
+   */
+  public static boolean isVolatile(int mod)
+  {
+    return (mod & VOLATILE) != 0;
+  }
+
+  /**
+   * Get a string representation of all the modifiers represented by the
+   * given int. The keywords are printed in this order:
+   * <code>&lt;public|protected|private&gt; abstract static final transient
+   * volatile synchronized native strictfp interface</code>.
+   *
+   * @param mod the modifier.
+   * @return the String representing the modifiers.
+   */
+  public static String toString(int mod)
+  {
+    return toString(mod, new CPStringBuilder()).toString();
+  }
+
+  /**
+   * Package helper method that can take a CPStringBuilder.
+   * @param mod the modifier
+   * @param r the CPStringBuilder to which the String representation is appended
+   * @return r, with information appended
+   */
+  static CPStringBuilder toString(int mod, CPStringBuilder r)
+  {
+    if (isPublic(mod))
+      r.append("public ");
+    if (isProtected(mod))
+      r.append("protected ");
+    if (isPrivate(mod))
+      r.append("private ");
+    if (isAbstract(mod))
+      r.append("abstract ");
+    if (isStatic(mod))
+      r.append("static ");
+    if (isFinal(mod))
+      r.append("final ");
+    if (isTransient(mod))
+      r.append("transient ");
+    if (isVolatile(mod))
+      r.append("volatile ");
+    if (isSynchronized(mod))
+      r.append("synchronized ");
+    if (isNative(mod))
+      r.append("native ");
+    if (isStrict(mod))
+      r.append("strictfp ");
+    if (isInterface(mod))
+      r.append("interface ");
+    
+    // Trim trailing space.
+    if ((mod & ALL_FLAGS) != 0)
+      r.setLength(r.length() - 1);
+    return r;
+  }
+}
diff --git a/src/classes/gnu/java/lang/reflect/VMConstructor.java b/src/classes/gnu/java/lang/reflect/VMConstructor.java
new file mode 100644 (file)
index 0000000..6a94711
--- /dev/null
@@ -0,0 +1,207 @@
+/* java.lang.reflect.VMConstructor - VM interface for reflection of Java constructors
+   Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+import java.util.Arrays;
+import java.util.Map;
+
+final class VMConstructor
+{
+  Class clazz;
+  int slot;
+
+  /**
+   * Unparsed annotations.
+   */
+  private byte[] annotations = null;
+
+  /**
+   * Unparsed parameter annotations.
+   */
+  private byte[] parameterAnnotations = null;
+
+  /**
+   * Annotations get parsed the first time they are
+   * accessed and are then cached it this map.
+   */
+  private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations = null;
+
+  /**
+   * Helper array for creating a new array from a java.util.Container.
+   */
+  private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
+    new Annotation[0];
+
+  /** 
+   * This field allows us to refer back to the main constructor instance.
+   *  It is set by the constructor of Constructor.
+   */
+  Constructor cons;
+
+  VMConstructor(Class clazz, int slot)
+  {
+    this.clazz = clazz;
+    this.slot = slot;
+  }
+
+  public Class getDeclaringClass()
+  {
+    return clazz;
+  }
+
+  /**
+   * Return the raw modifiers for this constructor.  In particular
+   * this will include the synthetic and varargs bits.
+   * @return the constructor's modifiers
+   */
+  native int getModifiersInternal();
+
+  /**
+   * Get the parameter list for this constructor, in declaration order. If the
+   * constructor takes no parameters, returns a 0-length array (not null).
+   *
+   * @return a list of the types of the constructor's parameters
+   */
+  native Class[] getParameterTypes();
+
+  /**
+   * Get the exception types this constructor says it throws, in no particular
+   * order. If the constructor has no throws clause, returns a 0-length array
+   * (not null).
+   *
+   * @return a list of the types in the constructor's throws clause
+   */
+  native Class[] getExceptionTypes();
+
+  native Object construct(Object[] args)
+    throws InstantiationException, IllegalAccessException,
+    InvocationTargetException;
+
+  /**
+   * Return the String in the Signature attribute for this constructor. If there
+   * is no Signature attribute, return null.
+   */
+  native String getSignature();
+  
+  /**
+   * <p>
+   * Return an array of arrays representing the annotations on each
+   * of the constructor's parameters.  The outer array is aligned against
+   * the parameters of the constructors and is thus equal in length to
+   * the number of parameters (thus having a length zero if there are none).
+   * Each array element in the outer array contains an inner array which
+   * holds the annotations.  This array has a length of zero if the parameter
+   * has no annotations.
+   * </p>
+   * <p>
+   * The returned annotations are serialized.  Changing the annotations has
+   * no affect on the return value of future calls to this method.
+   * </p>
+   * 
+   * @return an array of arrays which represents the annotations used on the
+   *         parameters of this constructor.  The order of the array elements
+   *         matches the declaration order of the parameters.
+   * @since 1.5
+   */
+  native Annotation[][] getParameterAnnotations();
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Constructors are semantically equivalent if they have the same
+   * declaring class and the same parameter list.  This ignores different
+   * exception clauses, but since you can't create a Method except through the
+   * VM, this is just the == relation.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not.
+   */
+  public boolean equals(Object o)
+  {
+    if (!(o instanceof Constructor))
+      return false;
+    Constructor that = (Constructor)o; 
+    if (clazz != that.getDeclaringClass())
+      return false;
+    if (!Arrays.equals(getParameterTypes(), that.getParameterTypes()))
+      return false;
+    return true;
+  }
+
+  /**
+   * Returns the element's annotation for the specified annotation type,
+   * or <code>null</code> if no such annotation exists.
+   *
+   * @param annotationClass the type of annotation to look for.
+   * @return this element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+//   native Annotation getAnnotation(Class annotationClass);
+  Annotation getAnnotation(Class annotationClass) {
+    if (annotationClass == null)
+      throw new NullPointerException();
+
+    return declaredAnnotations().get(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, then a zero-length
+   * array will be returned.  The returned array may be modified by the client
+   * code, but this will have no effect on the annotation content of this
+   * class, and hence no effect on the return value of this method for
+   * future callers.
+   *
+   * @return the annotations directly defined by the element.
+   * @since 1.5
+   */
+//   native Annotation[] getDeclaredAnnotations();
+  Annotation[] getDeclaredAnnotations() {
+    return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
+  }
+
+  /**
+   * Parses the annotations if they aren't parsed yet and stores them into
+   * the declaredAnnotations map and return this map.
+   */
+  private synchronized native Map<Class<? extends Annotation>, Annotation> declaredAnnotations();
+
+}
diff --git a/src/classes/gnu/java/lang/reflect/VMField.java b/src/classes/gnu/java/lang/reflect/VMField.java
new file mode 100644 (file)
index 0000000..eeb30a8
--- /dev/null
@@ -0,0 +1,583 @@
+/* java.lang.reflect.Field - VM interface for reflection of Java fields
+   Copyright (C) 1998, 2001, 2005, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+import java.util.Map;
+
+final class VMField
+{
+  Class clazz;
+  String name;
+  int slot;
+  
+  /**
+   * Unparsed annotations.
+   */
+  private byte[] annotations = null;
+
+  /**
+   * Annotations get parsed the first time they are
+   * accessed and are then cached it this map.
+   */
+  private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations = null;
+
+  /**
+   * Helper array for creating a new array from a java.util.Container.
+   */
+  private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
+    new Annotation[0];
+
+  /** 
+   * This field allows us to refer back to the main constructor instance.
+   *  It is set by the constructor of Field.
+   */
+  Field f;
+
+  VMField(Class clazz, String name, int slot)
+  {
+    this.clazz = clazz;
+    this.name = name;
+    this.slot = slot;
+  }
+
+  public Class getDeclaringClass()
+  {
+    return clazz;
+  }
+
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Return the raw modifiers for this field.
+   * @return the field's modifiers
+   */
+  native int getModifiersInternal();
+
+  /**
+   * Gets the type of this field.
+   * @return the type of this field
+   */
+  native Class getType();
+
+  /**
+   * Get the value of this Field.  If it is primitive, it will be wrapped
+   * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
+   *
+   * If the field is static, <code>o</code> will be ignored. Otherwise, if
+   * <code>o</code> is null, you get a <code>NullPointerException</code>,
+   * and if it is incompatible with the declaring class of the field, you
+   * get an <code>IllegalArgumentException</code>.<p>
+   *
+   * Next, if this Field enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not access this field in similar compiled code. If the field
+   * is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the field is accessed, and primitives are wrapped (but not
+   * necessarily in new objects). This method accesses the field of the
+   * declaring class, even if the instance passed in belongs to a subclass
+   * which declares another field to hide this one.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if <code>o</code> is not an instance of
+   *         the class or interface declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #getBoolean(Object)
+   * @see #getByte(Object)
+   * @see #getChar(Object)
+   * @see #getShort(Object)
+   * @see #getInt(Object)
+   * @see #getLong(Object)
+   * @see #getFloat(Object)
+   * @see #getDouble(Object)
+   */
+  native Object get(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Get the value of this boolean Field. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a boolean field of
+   *         <code>o</code>, or if <code>o</code> is not an instance of the
+   *         declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  native boolean getBoolean(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Get the value of this byte Field. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte field of
+   *         <code>o</code>, or if <code>o</code> is not an instance of the
+   *         declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  native byte getByte(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Get the value of this Field as a char. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a char field of
+   *         <code>o</code>, or if <code>o</code> is not an instance
+   *         of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  native char getChar(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Get the value of this Field as a short. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte or short
+   *         field of <code>o</code>, or if <code>o</code> is not an instance
+   *         of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  native short getShort(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Get the value of this Field as an int. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, or
+   *         int field of <code>o</code>, or if <code>o</code> is not an
+   *         instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  native int getInt(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Get the value of this Field as a long. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         or long field of <code>o</code>, or if <code>o</code> is not an
+   *         instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  native long getLong(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Get the value of this Field as a float. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         long, or float field of <code>o</code>, or if <code>o</code> is
+   *         not an instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  native float getFloat(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Get the value of this Field as a double. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         long, float, or double field of <code>o</code>, or if
+   *         <code>o</code> is not an instance of the declaring class of this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  native double getDouble(Object o)
+    throws IllegalAccessException;
+
+  /**
+   * Set the value of this Field.  If it is a primitive field, the value
+   * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
+   *
+   * If the field is static, <code>o</code> will be ignored. Otherwise, if
+   * <code>o</code> is null, you get a <code>NullPointerException</code>,
+   * and if it is incompatible with the declaring class of the field, you
+   * get an <code>IllegalArgumentException</code>.<p>
+   *
+   * Next, if this Field enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not access this field in similar compiled code. This also
+   * occurs whether or not there is access control if the field is final.
+   * If the field is primitive, and unwrapping your argument fails, you will
+   * get an <code>IllegalArgumentException</code>; likewise, this error
+   * happens if <code>value</code> cannot be cast to the correct object type.
+   * If the field is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the field is set with the widened value. This method accesses
+   * the field of the declaring class, even if the instance passed in belongs
+   * to a subclass which declares another field to hide this one.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if <code>value</code> cannot be
+   *         converted by a widening conversion to the underlying type of
+   *         the Field, or if <code>o</code> is not an instance of the class
+   *         declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #setBoolean(Object, boolean)
+   * @see #setByte(Object, byte)
+   * @see #setChar(Object, char)
+   * @see #setShort(Object, short)
+   * @see #setInt(Object, int)
+   * @see #setLong(Object, long)
+   * @see #setFloat(Object, float)
+   * @see #setDouble(Object, double)
+   */
+  native void set(Object o, Object value)
+    throws IllegalAccessException;
+
+  /**
+   * Set this boolean Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a boolean field, or if
+   *         <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  native void setBoolean(Object o, boolean value)
+    throws IllegalAccessException;
+
+  /**
+   * Set this byte Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  native void setByte(Object o, byte value)
+    throws IllegalAccessException;
+
+  /**
+   * Set this char Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a char, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  native void setChar(Object o, char value)
+    throws IllegalAccessException;
+
+  /**
+   * Set this short Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a short, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  native void setShort(Object o, short value)
+    throws IllegalAccessException;
+
+  /**
+   * Set this int Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not an int, long, float, or
+   *         double field, or if <code>o</code> is not an instance of the
+   *         class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  native void setInt(Object o, int value)
+    throws IllegalAccessException;
+
+  /**
+   * Set this long Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a long, float, or double
+   *         field, or if <code>o</code> is not an instance of the class
+   *         declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  native void setLong(Object o, long value)
+    throws IllegalAccessException;
+
+  /**
+   * Set this float Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a float or long field, or
+   *         if <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  native void setFloat(Object o, float value)
+    throws IllegalAccessException;
+
+  /**
+   * Set this double Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a double field, or if
+   *         <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  native void setDouble(Object o, double value)
+    throws IllegalAccessException;
+
+  /**
+   * Return the String in the Signature attribute for this field. If there
+   * is no Signature attribute, return null.
+   *
+   */
+  native String getSignature();
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Fields are semantically equivalent if they have the same declaring
+   * class, name, and type. Since you can't create a Field except through
+   * the VM, this is just the == relation.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not
+   */
+  public boolean equals(Object o)
+  {
+    if (!(o instanceof Field))
+      return false;
+    Field that = (Field)o; 
+    if (clazz != that.getDeclaringClass())
+      return false;
+    if (!name.equals(that.getName()))
+      return false;
+    if (getType() != that.getType())
+      return false;
+    return true;
+  }
+
+  /**
+   * Returns the element's annotation for the specified annotation type,
+   * or <code>null</code> if no such annotation exists.
+   *
+   * @param annotationClass the type of annotation to look for.
+   * @return this element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+//   native Annotation getAnnotation(Class annotationClass);
+  Annotation getAnnotation(Class annotationClass){
+    if (annotationClass == null)
+      throw new NullPointerException();
+
+    return declaredAnnotations().get(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, then a zero-length
+   * array will be returned.  The returned array may be modified by the client
+   * code, but this will have no effect on the annotation content of this
+   * class, and hence no effect on the return value of this method for
+   * future callers.
+   *
+   * @return the annotations directly defined by the element.
+   * @since 1.5
+   */
+//   native Annotation[] getDeclaredAnnotations();
+  Annotation[] getDeclaredAnnotations() {
+    return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
+  }
+
+  /**
+   * Parses the annotations if they aren't parsed yet and stores them into
+   * the declaredAnnotations map and return this map.
+   */
+  private synchronized native Map<Class<? extends Annotation>, Annotation> declaredAnnotations();
+
+}
diff --git a/src/classes/gnu/java/lang/reflect/VMMethod.java b/src/classes/gnu/java/lang/reflect/VMMethod.java
new file mode 100644 (file)
index 0000000..ad556f2
--- /dev/null
@@ -0,0 +1,252 @@
+/* java.lang.reflect.VMMethod - VM interface for reflection of Java methods
+   Copyright (C) 1998, 2001, 2002, 2005, 2007, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+import java.util.Arrays;
+import java.util.Map;
+
+final class VMMethod
+{
+  Class clazz;
+  String name;
+  int slot;
+
+  /**
+   * Unparsed annotations.
+   */
+  private byte[] annotations          = null;
+
+  /**
+   * Unparsed parameter annotations.
+   */
+  private byte[] parameterAnnotations = null;
+  
+  /**
+   * Unparsed annotation default value.
+   */
+  private byte[] annotationDefault    = null;
+
+  /**
+   * Annotations get parsed the first time they are
+   * accessed and are then cached it this map.
+   */
+  private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations = null;
+
+  /**
+   * Helper array for creating a new array from a java.util.Container.
+   */
+  private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
+    new Annotation[0];
+
+  /** 
+   * This field allows us to refer back to the main constructor instance.
+   *  It is set by the constructor of Field.
+   */
+  Method m;
+
+  public Class getDeclaringClass()
+  {
+    return clazz;
+  }
+
+  public String getName()
+  {
+    return name;
+  }
+
+  /**
+   * Return the raw modifiers for this method.
+   * @return the method's modifiers
+   */
+  native int getModifiersInternal();
+
+  /**
+   * Gets the return type of this method.
+   * @return the type of this method
+   */
+  native Class getReturnType();
+
+  /**
+   * Get the parameter list for this method, in declaration order. If the
+   * method takes no parameters, returns a 0-length array (not null).
+   *
+   * @return a list of the types of the method's parameters
+   */
+  native Class[] getParameterTypes();
+
+  /**
+   * Get the exception types this method says it throws, in no particular
+   * order. If the method has no throws clause, returns a 0-length array
+   * (not null).
+   *
+   * @return a list of the types in the method's throws clause
+   */
+  native Class[] getExceptionTypes();
+
+  native Object invoke(Object o, Object[] args)
+    throws IllegalAccessException, InvocationTargetException;
+
+  /**
+   * Return the String in the Signature attribute for this method. If there
+   * is no Signature attribute, return null.
+   */
+  native String getSignature();
+
+  /**
+   * If this method is an annotation method, returns the default
+   * value for the method.  If there is no default value, or if the
+   * method is not a member of an annotation type, returns null.
+   * Primitive types are wrapped.
+   *
+   * @throws TypeNotPresentException if the method returns a Class,
+   * and the class cannot be found
+   *
+   * @since 1.5
+   */
+  native Object getDefaultValue();
+
+  /**
+   * <p>
+   * Return an array of arrays representing the annotations on each
+   * of the method's parameters.  The outer array is aligned against
+   * the parameters of the method and is thus equal in length to
+   * the number of parameters (thus having a length zero if there are none).
+   * Each array element in the outer array contains an inner array which
+   * holds the annotations.  This array has a length of zero if the parameter
+   * has no annotations.
+   * </p>
+   * <p>
+   * The returned annotations are serialized.  Changing the annotations has
+   * no affect on the return value of future calls to this method.
+   * </p>
+   * 
+   * @return an array of arrays which represents the annotations used on the
+   *         parameters of this method.  The order of the array elements
+   *         matches the declaration order of the parameters.
+   * @since 1.5
+   */
+  native Annotation[][] getParameterAnnotations();
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Methods are semantically equivalent if they have the same declaring
+   * class, name, parameter list, and return type.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not
+   */
+  public boolean equals(Object o)
+  {
+      // Implementation note:
+      // The following is a correct but possibly slow implementation.
+      //
+      // This class has a private field 'slot' that could be used by
+      // the VM implementation to "link" a particular method to a Class.
+      // In that case equals could be simply implemented as:
+      //
+      // if (o instanceof Method)
+      // {
+      //    Method m = (Method)o;
+      //    return m.declaringClass == this.declaringClass
+      //           && m.slot == this.slot;
+      // }
+      // return false;
+      //
+      // If a VM uses the Method class as their native/internal representation
+      // then just using the following would be optimal:
+      //
+      // return this == o;
+      //
+    if (!(o instanceof Method))
+      return false;
+    Method that = (Method)o;
+    if (clazz != that.getDeclaringClass())
+      return false;
+    if (!name.equals(that.getName()))
+      return false;
+    if (getReturnType() != that.getReturnType())
+      return false;
+    if (!Arrays.equals(getParameterTypes(), that.getParameterTypes()))
+      return false;
+    return true;
+  }
+
+  /**
+   * Returns the element's annotation for the specified annotation type,
+   * or <code>null</code> if no such annotation exists.
+   *
+   * @param annotationClass the type of annotation to look for.
+   * @return this element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+//   native Annotation getAnnotation(Class annotationClass);
+  Annotation getAnnotation(Class annotationClass) {
+    if (annotationClass == null)
+      throw new NullPointerException();
+
+    return declaredAnnotations().get(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, then a zero-length
+   * array will be returned.  The returned array may be modified by the client
+   * code, but this will have no effect on the annotation content of this
+   * class, and hence no effect on the return value of this method for
+   * future callers.
+   *
+   * @return the annotations directly defined by the element.
+   * @since 1.5
+   */
+//   native Annotation[] getDeclaredAnnotations();
+  Annotation[] getDeclaredAnnotations() {
+    return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
+  }
+
+  /**
+   * Parses the annotations if they aren't parsed yet and stores them into
+   * the declaredAnnotations map and return this map.
+   */
+  private synchronized native Map<Class<? extends Annotation>, Annotation> declaredAnnotations();
+
+}
+
diff --git a/src/classes/gnu/java/security/VMAccessController.java b/src/classes/gnu/java/security/VMAccessController.java
new file mode 100644 (file)
index 0000000..160df10
--- /dev/null
@@ -0,0 +1,281 @@
+/* VMAccessController.java -- VM-specific access controller methods.
+   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.security;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+
+final class VMAccessController
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /**
+   * This is a per-thread stack of AccessControlContext objects (which can
+   * be null) for each call to AccessController.doPrivileged in each thread's
+   * call stack. We use this to remember which context object corresponds to
+   * which call.
+   */
+  private static final ThreadLocal contexts = new ThreadLocal();
+
+  /**
+   * This is a Boolean that, if set, tells getContext that it has already
+   * been called once, allowing us to handle recursive permission checks
+   * caused by methods getContext calls.
+   */
+  private static final ThreadLocal inGetContext = new ThreadLocal();
+
+  /**
+   * And we return this all-permissive context to ensure that privileged
+   * methods called from getContext succeed.
+   */
+  private static final AccessControlContext DEFAULT_CONTEXT;
+  static
+  {
+    CodeSource source = new CodeSource(null, null);
+    Permissions permissions = new Permissions();
+    permissions.add(new AllPermission());
+    ProtectionDomain[] domain = new ProtectionDomain[] {
+      new ProtectionDomain(source, permissions)
+    };
+    DEFAULT_CONTEXT = new AccessControlContext(domain);
+  }
+
+  private static final boolean DEBUG = gnu.classpath.Configuration.DEBUG;
+  private static void debug(String msg)
+  {
+    System.err.print(">>> VMAccessController: ");
+    System.err.println(msg);
+  }
+
+  // Constructors.
+  // -------------------------------------------------------------------------
+
+  private VMAccessController() { }
+
+  // Class methods.
+  // -------------------------------------------------------------------------
+
+  /**
+   * Relate a class (which should be an instance of {@link PrivilegedAction}
+   * with an access control context. This method is used by {@link
+   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
+   * to set up the context that will be returned by {@link #getContext()}.
+   * This method relates the class to the current thread, so contexts
+   * pushed from one thread will not be available to another.
+   *
+   * @param acc The access control context.
+   */
+  static void pushContext (AccessControlContext acc)
+  {
+    if (DEBUG)
+      debug("pushing " + acc);
+    LinkedList stack = (LinkedList) contexts.get();
+    if (stack == null)
+      {
+         if (DEBUG)
+           debug("no stack... creating ");
+        stack = new LinkedList();
+        contexts.set(stack);
+      }
+    stack.addFirst(acc);
+  }
+
+  /**
+   * Removes the relation of a class to an {@link AccessControlContext}.
+   * This method is used by {@link AccessController} when exiting from a
+   * call to {@link
+   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
+   */
+  static void popContext()
+  {
+    if (DEBUG)
+      debug("popping context");
+
+    // Stack should never be null, nor should it be empty, if this method
+    // and its counterpart has been called properly.
+    LinkedList stack = (LinkedList) contexts.get();
+    if (stack != null)
+      {
+        stack.removeFirst();
+        if (stack.isEmpty())
+          contexts.set(null);
+      }
+    else if (DEBUG)
+      {
+        debug("no stack during pop?????");
+      }
+  }
+
+  /**
+   * Examine the method stack of the currently running thread, and create
+   * an {@link AccessControlContext} filled in with the appropriate {@link
+   * ProtectionDomain} objects given this stack.
+   *
+   * @return The context.
+   */
+  static AccessControlContext getContext()
+  {
+    // If we are already in getContext, but called a method that needs
+    // a permission check, return the all-permissive context so methods
+    // called from here succeed.
+    //
+    // XXX is this necessary? We should verify if there are any calls in
+    // the stack below this method that require permission checks.
+    Boolean inCall = (Boolean) inGetContext.get();
+    if (inCall != null && inCall.booleanValue())
+      {
+        if (DEBUG)
+          debug("already in getContext");
+        return DEFAULT_CONTEXT;
+      }
+
+    inGetContext.set(Boolean.TRUE);
+
+    Object[][] stack = getStack();
+    Class[] classes = (Class[]) stack[0];
+    String[] methods = (String[]) stack[1];
+
+    if (DEBUG)
+      debug("got trace of length " + classes.length);
+
+    HashSet domains = new HashSet();
+    HashSet seenDomains = new HashSet();
+    AccessControlContext context = null;
+    int privileged = 0;
+
+    // We walk down the stack, adding each ProtectionDomain for each
+    // class in the call stack. If we reach a call to doPrivileged,
+    // we don't add any more stack frames. We skip the first three stack
+    // frames, since they comprise the calls to getStack, getContext,
+    // and AccessController.getContext.
+    for (int i = 3; i < classes.length && privileged < 2; i++)
+      {
+        Class clazz = classes[i];
+        String method = methods[i];
+
+        if (DEBUG)
+          {
+            debug("checking " + clazz + "." + method);
+            // subject to getClassLoader RuntimePermission
+            debug("loader = " + clazz.getClassLoader());
+          }
+
+        // If the previous frame was a call to doPrivileged, then this is
+        // the last frame we look at.
+        if (privileged == 1)
+          privileged = 2;
+
+        if (clazz.equals (AccessController.class)
+            && method.equals ("doPrivileged"))
+          {
+            // If there was a call to doPrivileged with a supplied context,
+            // return that context. If using JAAS doAs*, it should be 
+           // a context with a SubjectDomainCombiner
+            LinkedList l = (LinkedList) contexts.get();
+            if (l != null)
+              context = (AccessControlContext) l.getFirst();
+            privileged = 1;
+          }
+
+        // subject to getProtectionDomain RuntimePermission
+       ProtectionDomain domain = clazz.getProtectionDomain();
+
+        if (domain == null)
+          continue;
+        if (seenDomains.contains(domain))
+          continue;
+        seenDomains.add(domain);
+
+        // Create a static snapshot of this domain, which may change over time
+        // if the current policy changes.
+        domains.add(new ProtectionDomain(domain.getCodeSource(),
+                                         domain.getPermissions()));
+      }
+
+    if (DEBUG)
+      debug("created domains: " + domains);
+
+    ProtectionDomain[] result = (ProtectionDomain[])
+      domains.toArray(new ProtectionDomain[domains.size()]);
+
+    if (context != null)
+      {
+        DomainCombiner dc = context.getDomainCombiner ();
+        // If the supplied context had no explicit DomainCombiner, use
+        // our private version, which computes the intersection of the
+        // context's domains with the derived set.
+        if (dc == null)
+          context = new AccessControlContext
+            (IntersectingDomainCombiner.SINGLETON.combine
+             (result, context.getProtectionDomains ()));
+        // Use the supplied DomainCombiner. This should be secure,
+        // because only trusted code may create an
+        // AccessControlContext with a custom DomainCombiner.
+        else
+          context = new AccessControlContext (result, context, dc);
+      }
+    // No context was supplied. Return the derived one.
+    else
+      context = new AccessControlContext (result);
+
+    inGetContext.set(Boolean.FALSE);
+    return context;
+  }
+
+  /**
+   * Returns a snapshot of the current call stack as a pair of arrays:
+   * the first an array of classes in the call stack, the second an array
+   * of strings containing the method names in the call stack. The two
+   * arrays match up, meaning that method <i>i</i> is declared in class
+   * <i>i</i>. The arrays are clean; it will only contain Java methods,
+   * and no element of the list should be null.
+   *
+   * <p>The default implementation returns an empty stack, which will be
+   * interpreted as having no permissions whatsoever.
+   *
+   * @return A pair of arrays describing the current call stack. The first
+   *    element is an array of Class objects, and the second is an array
+   *    of Strings comprising the method names.
+   */
+//    private static Object[][] getStack()
+//    {
+//      return new Object[][] { new Class[0], new String[0] };
+//    }
+  private native static Object[][] getStack();
+}
diff --git a/src/classes/gnu/sun/misc/Unsafe.java b/src/classes/gnu/sun/misc/Unsafe.java
new file mode 100644 (file)
index 0000000..2577488
--- /dev/null
@@ -0,0 +1,861 @@
+/*
+ * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.misc;
+
+import java.security.*;
+import java.lang.reflect.*;
+
+
+/**
+ * A collection of methods for performing low-level, unsafe operations.
+ * Although the class and all methods are public, use of this class is
+ * limited because only trusted code can obtain instances of it.
+ *
+ * @author John R. Rose
+ * @see #getUnsafe
+ */
+
+public final class Unsafe {
+
+    private static native void registerNatives();
+    static {
+        registerNatives();
+//        sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
+    }
+
+    private Unsafe() {}
+
+    private static final Unsafe theUnsafe = new Unsafe();
+
+    /**
+     * Provides the caller with the capability of performing unsafe
+     * operations.
+     *
+     * <p> The returned <code>Unsafe</code> object should be carefully guarded
+     * by the caller, since it can be used to read and write data at arbitrary
+     * memory addresses.  It must never be passed to untrusted code.
+     *
+     * <p> Most methods in this class are very low-level, and correspond to a
+     * small number of hardware instructions (on typical machines).  Compilers
+     * are encouraged to optimize these methods accordingly.
+     *
+     * <p> Here is a suggested idiom for using unsafe operations:
+     *
+     * <blockquote><pre>
+     * class MyTrustedClass {
+     *   private static final Unsafe unsafe = Unsafe.getUnsafe();
+     *   ...
+     *   private long myCountAddress = ...;
+     *   public int getCount() { return unsafe.getByte(myCountAddress); }
+     * }
+     * </pre></blockquote>
+     *
+     * (It may assist compilers to make the local variable be
+     * <code>final</code>.)
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     *             <code>checkPropertiesAccess</code> method doesn't allow
+     *             access to the system properties.
+     */
+    public static Unsafe getUnsafe() {
+        Class cc = sun.reflect.Reflection.getCallerClass(2);
+        if (cc.getClassLoader() != null)
+            throw new SecurityException("Unsafe");
+        return theUnsafe;
+    }
+
+    /// peek and poke operations
+    /// (compilers should optimize these to memory ops)
+
+    // These work on object fields in the Java heap.
+    // They will not work on elements of packed arrays.
+
+    /**
+     * Fetches a value from a given Java variable.
+     * More specifically, fetches a field or array element within the given
+     * object <code>o</code> at the given offset, or (if <code>o</code> is
+     * null) from the memory address whose numerical value is the given
+     * offset.
+     * <p>
+     * The results are undefined unless one of the following cases is true:
+     * <ul>
+     * <li>The offset was obtained from {@link #objectFieldOffset} on
+     * the {@link java.lang.reflect.Field} of some Java field and the object
+     * referred to by <code>o</code> is of a class compatible with that
+     * field's class.
+     *
+     * <li>The offset and object reference <code>o</code> (either null or
+     * non-null) were both obtained via {@link #staticFieldOffset}
+     * and {@link #staticFieldBase} (respectively) from the
+     * reflective {@link Field} representation of some Java field.
+     *
+     * <li>The object referred to by <code>o</code> is an array, and the offset
+     * is an integer of the form <code>B+N*S</code>, where <code>N</code> is
+     * a valid index into the array, and <code>B</code> and <code>S</code> are
+     * the values obtained by {@link #arrayBaseOffset} and {@link
+     * #arrayIndexScale} (respectively) from the array's class.  The value
+     * referred to is the <code>N</code><em>th</em> element of the array.
+     *
+     * </ul>
+     * <p>
+     * If one of the above cases is true, the call references a specific Java
+     * variable (field or array element).  However, the results are undefined
+     * if that variable is not in fact of the type returned by this method.
+     * <p>
+     * This method refers to a variable by means of two parameters, and so
+     * it provides (in effect) a <em>double-register</em> addressing mode
+     * for Java variables.  When the object reference is null, this method
+     * uses its offset as an absolute address.  This is similar in operation
+     * to methods such as {@link #getInt(long)}, which provide (in effect) a
+     * <em>single-register</em> addressing mode for non-Java variables.
+     * However, because Java variables may have a different layout in memory
+     * from non-Java variables, programmers should not assume that these
+     * two addressing modes are ever equivalent.  Also, programmers should
+     * remember that offsets from the double-register addressing mode cannot
+     * be portably confused with longs used in the single-register addressing
+     * mode.
+     *
+     * @param o Java heap object in which the variable resides, if any, else
+     *        null
+     * @param offset indication of where the variable resides in a Java heap
+     *        object, if any, else a memory address locating the variable
+     *        statically
+     * @return the value fetched from the indicated Java variable
+     * @throws RuntimeException No defined exceptions are thrown, not even
+     *         {@link NullPointerException}
+     */
+    public native int getInt(Object o, long offset);
+
+    /**
+     * Stores a value into a given Java variable.
+     * <p>
+     * The first two parameters are interpreted exactly as with
+     * {@link #getInt(Object, long)} to refer to a specific
+     * Java variable (field or array element).  The given value
+     * is stored into that variable.
+     * <p>
+     * The variable must be of the same type as the method
+     * parameter <code>x</code>.
+     *
+     * @param o Java heap object in which the variable resides, if any, else
+     *        null
+     * @param offset indication of where the variable resides in a Java heap
+     *        object, if any, else a memory address locating the variable
+     *        statically
+     * @param x the value to store into the indicated Java variable
+     * @throws RuntimeException No defined exceptions are thrown, not even
+     *         {@link NullPointerException}
+     */
+    public native void putInt(Object o, long offset, int x);
+
+    /**
+     * Fetches a reference value from a given Java variable.
+     * @see #getInt(Object, long)
+     */
+    public native Object getObject(Object o, long offset);
+
+    /**
+     * Stores a reference value into a given Java variable.
+     * <p>
+     * Unless the reference <code>x</code> being stored is either null
+     * or matches the field type, the results are undefined.
+     * If the reference <code>o</code> is non-null, car marks or
+     * other store barriers for that object (if the VM requires them)
+     * are updated.
+     * @see #putInt(Object, int, int)
+     */
+    public native void putObject(Object o, long offset, Object x);
+
+    /** @see #getInt(Object, long) */
+    public native boolean getBoolean(Object o, long offset);
+    /** @see #putInt(Object, int, int) */
+    public native void    putBoolean(Object o, long offset, boolean x);
+    /** @see #getInt(Object, long) */
+    public native byte    getByte(Object o, long offset);
+    /** @see #putInt(Object, int, int) */
+    public native void    putByte(Object o, long offset, byte x);
+    /** @see #getInt(Object, long) */
+    public native short   getShort(Object o, long offset);
+    /** @see #putInt(Object, int, int) */
+    public native void    putShort(Object o, long offset, short x);
+    /** @see #getInt(Object, long) */
+    public native char    getChar(Object o, long offset);
+    /** @see #putInt(Object, int, int) */
+    public native void    putChar(Object o, long offset, char x);
+    /** @see #getInt(Object, long) */
+    public native long    getLong(Object o, long offset);
+    /** @see #putInt(Object, int, int) */
+    public native void    putLong(Object o, long offset, long x);
+    /** @see #getInt(Object, long) */
+    public native float   getFloat(Object o, long offset);
+    /** @see #putInt(Object, int, int) */
+    public native void    putFloat(Object o, long offset, float x);
+    /** @see #getInt(Object, long) */
+    public native double  getDouble(Object o, long offset);
+    /** @see #putInt(Object, int, int) */
+    public native void    putDouble(Object o, long offset, double x);
+
+    /**
+     * This method, like all others with 32-bit offsets, was native
+     * in a previous release but is now a wrapper which simply casts
+     * the offset to a long value.  It provides backward compatibility
+     * with bytecodes compiled against 1.4.
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public int getInt(Object o, int offset) {
+        return getInt(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putInt(Object o, int offset, int x) {
+        putInt(o, (long)offset, x);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public Object getObject(Object o, int offset) {
+        return getObject(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putObject(Object o, int offset, Object x) {
+        putObject(o, (long)offset, x);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public boolean getBoolean(Object o, int offset) {
+        return getBoolean(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putBoolean(Object o, int offset, boolean x) {
+        putBoolean(o, (long)offset, x);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public byte getByte(Object o, int offset) {
+        return getByte(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putByte(Object o, int offset, byte x) {
+        putByte(o, (long)offset, x);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public short getShort(Object o, int offset) {
+        return getShort(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putShort(Object o, int offset, short x) {
+        putShort(o, (long)offset, x);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public char getChar(Object o, int offset) {
+        return getChar(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putChar(Object o, int offset, char x) {
+        putChar(o, (long)offset, x);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public long getLong(Object o, int offset) {
+        return getLong(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putLong(Object o, int offset, long x) {
+        putLong(o, (long)offset, x);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public float getFloat(Object o, int offset) {
+        return getFloat(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putFloat(Object o, int offset, float x) {
+        putFloat(o, (long)offset, x);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public double getDouble(Object o, int offset) {
+        return getDouble(o, (long)offset);
+    }
+
+    /**
+     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
+     * See {@link #staticFieldOffset}.
+     */
+    @Deprecated
+    public void putDouble(Object o, int offset, double x) {
+        putDouble(o, (long)offset, x);
+    }
+
+    // These work on values in the C heap.
+
+    /**
+     * Fetches a value from a given memory address.  If the address is zero, or
+     * does not point into a block obtained from {@link #allocateMemory}, the
+     * results are undefined.
+     *
+     * @see #allocateMemory
+     */
+    public native byte    getByte(long address);
+
+    /**
+     * Stores a value into a given memory address.  If the address is zero, or
+     * does not point into a block obtained from {@link #allocateMemory}, the
+     * results are undefined.
+     *
+     * @see #getByte(long)
+     */
+    public native void    putByte(long address, byte x);
+
+    /** @see #getByte(long) */
+    public native short   getShort(long address);
+    /** @see #putByte(long, byte) */
+    public native void    putShort(long address, short x);
+    /** @see #getByte(long) */
+    public native char    getChar(long address);
+    /** @see #putByte(long, byte) */
+    public native void    putChar(long address, char x);
+    /** @see #getByte(long) */
+    public native int     getInt(long address);
+    /** @see #putByte(long, byte) */
+    public native void    putInt(long address, int x);
+    /** @see #getByte(long) */
+    public native long    getLong(long address);
+    /** @see #putByte(long, byte) */
+    public native void    putLong(long address, long x);
+    /** @see #getByte(long) */
+    public native float   getFloat(long address);
+    /** @see #putByte(long, byte) */
+    public native void    putFloat(long address, float x);
+    /** @see #getByte(long) */
+    public native double  getDouble(long address);
+    /** @see #putByte(long, byte) */
+    public native void    putDouble(long address, double x);
+
+    /**
+     * Fetches a native pointer from a given memory address.  If the address is
+     * zero, or does not point into a block obtained from {@link
+     * #allocateMemory}, the results are undefined.
+     *
+     * <p> If the native pointer is less than 64 bits wide, it is extended as
+     * an unsigned number to a Java long.  The pointer may be indexed by any
+     * given byte offset, simply by adding that offset (as a simple integer) to
+     * the long representing the pointer.  The number of bytes actually read
+     * from the target address maybe determined by consulting {@link
+     * #addressSize}.
+     *
+     * @see #allocateMemory
+     */
+    public native long getAddress(long address);
+
+    /**
+     * Stores a native pointer into a given memory address.  If the address is
+     * zero, or does not point into a block obtained from {@link
+     * #allocateMemory}, the results are undefined.
+     *
+     * <p> The number of bytes actually written at the target address maybe
+     * determined by consulting {@link #addressSize}.
+     *
+     * @see #getAddress(long)
+     */
+    public native void putAddress(long address, long x);
+
+    /// wrappers for malloc, realloc, free:
+
+    /**
+     * Allocates a new block of native memory, of the given size in bytes.  The
+     * contents of the memory are uninitialized; they will generally be
+     * garbage.  The resulting native pointer will never be zero, and will be
+     * aligned for all value types.  Dispose of this memory by calling {@link
+     * #freeMemory}, or resize it with {@link #reallocateMemory}.
+     *
+     * @throws IllegalArgumentException if the size is negative or too large
+     *         for the native size_t type
+     *
+     * @throws OutOfMemoryError if the allocation is refused by the system
+     *
+     * @see #getByte(long)
+     * @see #putByte(long, byte)
+     */
+    public native long allocateMemory(long bytes);
+
+    /**
+     * Resizes a new block of native memory, to the given size in bytes.  The
+     * contents of the new block past the size of the old block are
+     * uninitialized; they will generally be garbage.  The resulting native
+     * pointer will be zero if and only if the requested size is zero.  The
+     * resulting native pointer will be aligned for all value types.  Dispose
+     * of this memory by calling {@link #freeMemory}, or resize it with {@link
+     * #reallocateMemory}.  The address passed to this method may be null, in
+     * which case an allocation will be performed.
+     *
+     * @throws IllegalArgumentException if the size is negative or too large
+     *         for the native size_t type
+     *
+     * @throws OutOfMemoryError if the allocation is refused by the system
+     *
+     * @see #allocateMemory
+     */
+    public native long reallocateMemory(long address, long bytes);
+
+    /**
+     * Sets all bytes in a given block of memory to a fixed value
+     * (usually zero).
+     */
+    public native void setMemory(long address, long bytes, byte value);
+
+    /**
+     * Sets all bytes in a given block of memory to a copy of another
+     * block.
+     */
+    public native void copyMemory(long srcAddress, long destAddress,
+                                  long bytes);
+
+    /**
+     * Disposes of a block of native memory, as obtained from {@link
+     * #allocateMemory} or {@link #reallocateMemory}.  The address passed to
+     * this method may be null, in which case no action is taken.
+     *
+     * @see #allocateMemory
+     */
+    public native void freeMemory(long address);
+
+    /// random queries
+
+    /**
+     * This constant differs from all results that will ever be returned from
+     * {@link #staticFieldOffset}, {@link #objectFieldOffset},
+     * or {@link #arrayBaseOffset}.
+     */
+    public static final int INVALID_FIELD_OFFSET   = -1;
+
+    /**
+     * Returns the offset of a field, truncated to 32 bits.
+     * This method is implemented as follows:
+     * <blockquote><pre>
+     * public int fieldOffset(Field f) {
+     *     if (Modifier.isStatic(f.getModifiers()))
+     *         return (int) staticFieldOffset(f);
+     *     else
+     *         return (int) objectFieldOffset(f);
+     * }
+     * </pre></blockquote>
+     * @deprecated As of 1.4.1, use {@link #staticFieldOffset} for static
+     * fields and {@link #objectFieldOffset} for non-static fields.
+     */
+    @Deprecated
+    public int fieldOffset(Field f) {
+        if (Modifier.isStatic(f.getModifiers()))
+            return (int) staticFieldOffset(f);
+        else
+            return (int) objectFieldOffset(f);
+    }
+
+    /**
+     * Returns the base address for accessing some static field
+     * in the given class.  This method is implemented as follows:
+     * <blockquote><pre>
+     * public Object staticFieldBase(Class c) {
+     *     Field[] fields = c.getDeclaredFields();
+     *     for (int i = 0; i < fields.length; i++) {
+     *         if (Modifier.isStatic(fields[i].getModifiers())) {
+     *             return staticFieldBase(fields[i]);
+     *         }
+     *     }
+     *     return null;
+     * }
+     * </pre></blockquote>
+     * @deprecated As of 1.4.1, use {@link #staticFieldBase(Field)}
+     * to obtain the base pertaining to a specific {@link Field}.
+     * This method works only for JVMs which store all statics
+     * for a given class in one place.
+     */
+    @Deprecated
+    public Object staticFieldBase(Class c) {
+        Field[] fields = c.getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            if (Modifier.isStatic(fields[i].getModifiers())) {
+                return staticFieldBase(fields[i]);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Report the location of a given field in the storage allocation of its
+     * class.  Do not expect to perform any sort of arithmetic on this offset;
+     * it is just a cookie which is passed to the unsafe heap memory accessors.
+     *
+     * <p>Any given field will always have the same offset and base, and no
+     * two distinct fields of the same class will ever have the same offset
+     * and base.
+     *
+     * <p>As of 1.4.1, offsets for fields are represented as long values,
+     * although the Sun JVM does not use the most significant 32 bits.
+     * However, JVM implementations which store static fields at absolute
+     * addresses can use long offsets and null base pointers to express
+     * the field locations in a form usable by {@link #getInt(Object,long)}.
+     * Therefore, code which will be ported to such JVMs on 64-bit platforms
+     * must preserve all bits of static field offsets.
+     * @see #getInt(Object, long)
+     */
+    public native long staticFieldOffset(Field f);
+
+    /**
+     * Report the location of a given static field, in conjunction with {@link
+     * #staticFieldBase}.
+     * <p>Do not expect to perform any sort of arithmetic on this offset;
+     * it is just a cookie which is passed to the unsafe heap memory accessors.
+     *
+     * <p>Any given field will always have the same offset, and no two distinct
+     * fields of the same class will ever have the same offset.
+     *
+     * <p>As of 1.4.1, offsets for fields are represented as long values,
+     * although the Sun JVM does not use the most significant 32 bits.
+     * It is hard to imagine a JVM technology which needs more than
+     * a few bits to encode an offset within a non-array object,
+     * However, for consistency with other methods in this class,
+     * this method reports its result as a long value.
+     * @see #getInt(Object, long)
+     */
+    public native long objectFieldOffset(Field f);
+
+    /**
+     * Report the location of a given static field, in conjunction with {@link
+     * #staticFieldOffset}.
+     * <p>Fetch the base "Object", if any, with which static fields of the
+     * given class can be accessed via methods like {@link #getInt(Object,
+     * long)}.  This value may be null.  This value may refer to an object
+     * which is a "cookie", not guaranteed to be a real Object, and it should
+     * not be used in any way except as argument to the get and put routines in
+     * this class.
+     */
+    public native Object staticFieldBase(Field f);
+
+    /**
+     * Ensure the given class has been initialized. This is often
+     * needed in conjunction with obtaining the static field base of a
+     * class.
+     */
+    public native void ensureClassInitialized(Class c);
+
+    /**
+     * Report the offset of the first element in the storage allocation of a
+     * given array class.  If {@link #arrayIndexScale} returns a non-zero value
+     * for the same class, you may use that scale factor, together with this
+     * base offset, to form new offsets to access elements of arrays of the
+     * given class.
+     *
+     * @see #getInt(Object, long)
+     * @see #putInt(Object, long, int)
+     */
+    public native int arrayBaseOffset(Class arrayClass);
+
+    /**
+     * Report the scale factor for addressing elements in the storage
+     * allocation of a given array class.  However, arrays of "narrow" types
+     * will generally not work properly with accessors like {@link
+     * #getByte(Object, int)}, so the scale factor for such classes is reported
+     * as zero.
+     *
+     * @see #arrayBaseOffset
+     * @see #getInt(Object, long)
+     * @see #putInt(Object, long, int)
+     */
+    public native int arrayIndexScale(Class arrayClass);
+
+    /**
+     * Report the size in bytes of a native pointer, as stored via {@link
+     * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
+     * other primitive types (as stored in native memory blocks) is determined
+     * fully by their information content.
+     */
+    public native int addressSize();
+
+    /**
+     * Report the size in bytes of a native memory page (whatever that is).
+     * This value will always be a power of two.
+     */
+    public native int pageSize();
+
+
+    /// random trusted operations from JNI:
+
+    /**
+     * Tell the VM to define a class, without security checks.  By default, the
+     * class loader and protection domain come from the caller's class.
+     */
+    public native Class defineClass(String name, byte[] b, int off, int len,
+                                    ClassLoader loader,
+                                    ProtectionDomain protectionDomain);
+
+    public native Class defineClass(String name, byte[] b, int off, int len);
+
+    /** Allocate an instance but do not run any constructor.
+        Initializes the class if it has not yet been. */
+    public native Object allocateInstance(Class cls)
+        throws InstantiationException;
+
+    /** Lock the object.  It must get unlocked via {@link #monitorExit}. */
+    public native void monitorEnter(Object o);
+
+    /**
+     * Unlock the object.  It must have been locked via {@link
+     * #monitorEnter}.
+     */
+    public native void monitorExit(Object o);
+
+    /**
+     * Tries to lock the object.  Returns true or false to indicate
+     * whether the lock succeeded.  If it did, the object must be
+     * unlocked via {@link #monitorExit}.
+     */
+    public native boolean tryMonitorEnter(Object o);
+
+    /** Throw the exception without telling the verifier. */
+    public native void throwException(Throwable ee);
+
+
+    /**
+     * Atomically update Java variable to <tt>x</tt> if it is currently
+     * holding <tt>expected</tt>.
+     * @return <tt>true</tt> if successful
+     */
+    public final native boolean compareAndSwapObject(Object o, long offset,
+                                                     Object expected,
+                                                     Object x);
+
+    /**
+     * Atomically update Java variable to <tt>x</tt> if it is currently
+     * holding <tt>expected</tt>.
+     * @return <tt>true</tt> if successful
+     */
+    public final native boolean compareAndSwapInt(Object o, long offset,
+                                                  int expected,
+                                                  int x);
+
+    /**
+     * Atomically update Java variable to <tt>x</tt> if it is currently
+     * holding <tt>expected</tt>.
+     * @return <tt>true</tt> if successful
+     */
+    public final native boolean compareAndSwapLong(Object o, long offset,
+                                                   long expected,
+                                                   long x);
+
+    /**
+     * Fetches a reference value from a given Java variable, with volatile
+     * load semantics. Otherwise identical to {@link #getObject(Object, long)}
+     */
+    public native Object getObjectVolatile(Object o, long offset);
+
+    /**
+     * Stores a reference value into a given Java variable, with
+     * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)}
+     */
+    public native void    putObjectVolatile(Object o, long offset, Object x);
+
+    /** Volatile version of {@link #getInt(Object, long)}  */
+    public native int     getIntVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putInt(Object, long, int)}  */
+    public native void    putIntVolatile(Object o, long offset, int x);
+
+    /** Volatile version of {@link #getBoolean(Object, long)}  */
+    public native boolean getBooleanVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putBoolean(Object, long, boolean)}  */
+    public native void    putBooleanVolatile(Object o, long offset, boolean x);
+
+    /** Volatile version of {@link #getByte(Object, long)}  */
+    public native byte    getByteVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putByte(Object, long, byte)}  */
+    public native void    putByteVolatile(Object o, long offset, byte x);
+
+    /** Volatile version of {@link #getShort(Object, long)}  */
+    public native short   getShortVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putShort(Object, long, short)}  */
+    public native void    putShortVolatile(Object o, long offset, short x);
+
+    /** Volatile version of {@link #getChar(Object, long)}  */
+    public native char    getCharVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putChar(Object, long, char)}  */
+    public native void    putCharVolatile(Object o, long offset, char x);
+
+    /** Volatile version of {@link #getLong(Object, long)}  */
+    public native long    getLongVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putLong(Object, long, long)}  */
+    public native void    putLongVolatile(Object o, long offset, long x);
+
+    /** Volatile version of {@link #getFloat(Object, long)}  */
+    public native float   getFloatVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putFloat(Object, long, float)}  */
+    public native void    putFloatVolatile(Object o, long offset, float x);
+
+    /** Volatile version of {@link #getDouble(Object, long)}  */
+    public native double  getDoubleVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putDouble(Object, long, double)}  */
+    public native void    putDoubleVolatile(Object o, long offset, double x);
+
+    /**
+     * Version of {@link #putObjectVolatile(Object, long, Object)}
+     * that does not guarantee immediate visibility of the store to
+     * other threads. This method is generally only useful if the
+     * underlying field is a Java volatile (or if an array cell, one
+     * that is otherwise only accessed using volatile accesses).
+     */
+    public native void    putOrderedObject(Object o, long offset, Object x);
+
+    /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)}  */
+    public native void    putOrderedInt(Object o, long offset, int x);
+
+    /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
+    public native void    putOrderedLong(Object o, long offset, long x);
+
+    /**
+     * Unblock the given thread blocked on <tt>park</tt>, or, if it is
+     * not blocked, cause the subsequent call to <tt>park</tt> not to
+     * block.  Note: this operation is "unsafe" solely because the
+     * caller must somehow ensure that the thread has not been
+     * destroyed. Nothing special is usually required to ensure this
+     * when called from Java (in which there will ordinarily be a live
+     * reference to the thread) but this is not nearly-automatically
+     * so when calling from native code.
+     * @param thread the thread to unpark.
+     *
+     */
+    public native void unpark(Object thread);
+
+    /**
+     * Block current thread, returning when a balancing
+     * <tt>unpark</tt> occurs, or a balancing <tt>unpark</tt> has
+     * already occurred, or the thread is interrupted, or, if not
+     * absolute and time is not zero, the given time nanoseconds have
+     * elapsed, or if absolute, the given deadline in milliseconds
+     * since Epoch has passed, or spuriously (i.e., returning for no
+     * "reason"). Note: This operation is in the Unsafe class only
+     * because <tt>unpark</tt> is, so it would be strange to place it
+     * elsewhere.
+     */
+    public native void park(boolean isAbsolute, long time);
+
+    /**
+     * Gets the load average in the system run queue assigned
+     * to the available processors averaged over various periods of time.
+     * This method retrieves the given <tt>nelem</tt> samples and
+     * assigns to the elements of the given <tt>loadavg</tt> array.
+     * The system imposes a maximum of 3 samples, representing
+     * averages over the last 1,  5,  and  15 minutes, respectively.
+     *
+     * @params loadavg an array of double of size nelems
+     * @params nelems the number of samples to be retrieved and
+     *         must be 1 to 3.
+     *
+     * @return the number of samples actually retrieved; or -1
+     *         if the load average is unobtainable.
+     */
+    public native int getLoadAverage(double[] loadavg, int nelems);
+}
diff --git a/src/classes/gnu/sun/reflect/ConstantPool.java b/src/classes/gnu/sun/reflect/ConstantPool.java
new file mode 100644 (file)
index 0000000..b24d28e
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.reflect;
+
+import java.lang.reflect.*;
+
+/** Provides reflective access to the constant pools of classes.
+    Currently this is needed to provide reflective access to annotations
+    but may be used by other internal subsystems in the future. */
+
+public class ConstantPool {
+  // Number of entries in this constant pool (= maximum valid constant pool index)
+  public int      getSize()                      { return getSize0            (constantPoolOop);        }
+  public Class    getClassAt         (int index) { return getClassAt0         (constantPoolOop, index); }
+  public Class    getClassAtIfLoaded (int index) { return getClassAtIfLoaded0 (constantPoolOop, index); }
+  // Returns either a Method or Constructor.
+  // Static initializers are returned as Method objects.
+  public Member   getMethodAt        (int index) { return getMethodAt0        (constantPoolOop, index); }
+  public Member   getMethodAtIfLoaded(int index) { return getMethodAtIfLoaded0(constantPoolOop, index); }
+  public Field    getFieldAt         (int index) { return getFieldAt0         (constantPoolOop, index); }
+  public Field    getFieldAtIfLoaded (int index) { return getFieldAtIfLoaded0 (constantPoolOop, index); }
+  // Fetches the class name, member (field, method or interface
+  // method) name, and type descriptor as an array of three Strings
+  public String[] getMemberRefInfoAt (int index) { return getMemberRefInfoAt0 (constantPoolOop, index); }
+  public int      getIntAt           (int index) { return getIntAt0           (constantPoolOop, index); }
+  public long     getLongAt          (int index) { return getLongAt0          (constantPoolOop, index); }
+  public float    getFloatAt         (int index) { return getFloatAt0         (constantPoolOop, index); }
+  public double   getDoubleAt        (int index) { return getDoubleAt0        (constantPoolOop, index); }
+  public String   getStringAt        (int index) { return getStringAt0        (constantPoolOop, index); }
+  public String   getUTF8At          (int index) { return getUTF8At0          (constantPoolOop, index); }
+
+  //---------------------------------------------------------------------------
+  // Internals only below this point
+  //
+/* This hides this member from being visible through the reflection API in OpenJDK
+ * TODO: find out how to do this with GNU Classpath (if it's realy neccesary).
+
+  static {
+      Reflection.registerFieldsToFilter(ConstantPool.class, new String[] { "constantPoolOop" });
+  }
+*/
+  // HotSpot-internal constant pool object (set by the VM, name known to the VM)
+  private Object constantPoolOop;
+
+  private native int      getSize0            (Object constantPoolOop);
+  private native Class    getClassAt0         (Object constantPoolOop, int index);
+  private native Class    getClassAtIfLoaded0 (Object constantPoolOop, int index);
+  private native Member   getMethodAt0        (Object constantPoolOop, int index);
+  private native Member   getMethodAtIfLoaded0(Object constantPoolOop, int index);
+  private native Field    getFieldAt0         (Object constantPoolOop, int index);
+  private native Field    getFieldAtIfLoaded0 (Object constantPoolOop, int index);
+  private native String[] getMemberRefInfoAt0 (Object constantPoolOop, int index);
+  private native int      getIntAt0           (Object constantPoolOop, int index);
+  private native long     getLongAt0          (Object constantPoolOop, int index);
+  private native float    getFloatAt0         (Object constantPoolOop, int index);
+  private native double   getDoubleAt0        (Object constantPoolOop, int index);
+  private native String   getStringAt0        (Object constantPoolOop, int index);
+  private native String   getUTF8At0          (Object constantPoolOop, int index);
+}
diff --git a/src/classes/gnu/sun/reflect/annotation/AnnotationParser.java b/src/classes/gnu/sun/reflect/annotation/AnnotationParser.java
new file mode 100644 (file)
index 0000000..8c5aca3
--- /dev/null
@@ -0,0 +1,873 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.reflect.annotation;
+
+import java.lang.annotation.*;
+import java.util.*;
+import java.nio.ByteBuffer;
+import java.nio.BufferUnderflowException;
+import java.lang.reflect.*;
+import sun.reflect.ConstantPool;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+
+
+/**
+ * Parser for Java programming language annotations.  Translates
+ * annotation byte streams emitted by compiler into annotation objects.
+ *
+ * @author  Josh Bloch
+ * @since   1.5
+ */
+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
+     * 
+     * @param rawAnnotations are the unparsed annotations
+     * @param constPool is the constant pool of the declaring class
+     * @param container is the containing class
+     * @return the parsed annotations in an array
+     * @throws AnnotationFormatError if an annotation is found to be
+     *         malformed.
+     */
+    public static Annotation[] parseAnnotationsIntoArray(
+                byte[] rawAnnotations,
+                ConstantPool constPool,
+                Class container) {
+        Map<Class, Annotation> annotations = parseAnnotations(rawAnnotations, constPool, container);
+        return annotations.values().toArray(EMPTY_ANNOTATIONS_ARRAY);
+    }
+
+    /**
+     * Parses parameter annotations.
+     * 
+     * @author Mathias Panzenböck
+     * 
+     * @param parameterAnnotations are the unparsed parameter annotations
+     * @param constPool is the constant pool of the declaring class
+     * @param container is the containing class
+     * @return the parsed parameter annotations in an array 2 dimensional array
+     * @throws AnnotationFormatError if an annotation is found to be
+     *         malformed.
+     */
+    public static Annotation[][] parseParameterAnnotations(
+                    byte[] parameterAnnotations,
+                    ConstantPool constPool,
+                    Class container,
+                    int numParameters) {
+        if (parameterAnnotations == null)
+            return new Annotation[numParameters][0];
+
+        Annotation[][] result = parseParameterAnnotations(
+            parameterAnnotations, constPool, container); 
+
+        if (result.length != numParameters)
+            throw new AnnotationFormatError(
+                "Parameter annotations don't match number of parameters (count was " +
+               result.length + " but should be " + numParameters + ").");
+        return result;
+    }
+
+    /**
+     * Parses the annotation default value of the supplied method.
+     * This method is basically copied from OpenJDKs
+     * java.lang.reflect.Method.getAnnotationDefault()
+     * 
+     * @author Mathias Panzenböck
+     *
+     * @param method represents the method for which the annotation default value has to be parsed
+     * @param annotationDefault is the unparsed annotation default value
+     * @param constPool is the constant pool of the declaring class
+     * @return the parsed annotation default value (boxed, if it's a primitive type)
+     * @throws AnnotationFormatError if an annotation is found to be
+     *         malformed.
+     */
+    public static Object parseAnnotationDefault(Method method,
+                                                byte[] annotationDefault,
+                                                ConstantPool constPool) {
+        if  (annotationDefault == null)
+            return null;
+        
+       Class memberType = AnnotationType.invocationHandlerReturnType(
+            method.getReturnType());
+        
+       Object result = AnnotationParser.parseMemberValue(
+            memberType, ByteBuffer.wrap(annotationDefault),
+            constPool, method.getDeclaringClass());
+
+        if (result instanceof sun.reflect.annotation.ExceptionProxy)
+            throw new AnnotationFormatError("Invalid default: " + method);
+        
+       return result;
+    }
+
+    /**
+     * Parses the annotations described by the specified byte array.
+     * resolving constant references in the specified constant pool.
+     * The array must contain an array of annotations as described
+     * in the RuntimeVisibleAnnotations_attribute:
+     *
+     *   u2 num_annotations;
+     *   annotation annotations[num_annotations];
+     *
+     * @throws AnnotationFormatError if an annotation is found to be
+     *         malformed.
+     */
+    public static Map<Class, Annotation> parseAnnotations(
+                byte[] rawAnnotations,
+                ConstantPool constPool,
+                Class container) {
+        if (rawAnnotations == null)
+            return Collections.emptyMap();
+
+        try {
+            return parseAnnotations2(rawAnnotations, constPool, container);
+        } catch(BufferUnderflowException e) {
+            throw new AnnotationFormatError("Unexpected end of annotations.");
+        } catch(IllegalArgumentException e) {
+            // Type mismatch in constant pool
+            throw new AnnotationFormatError(e);
+        }
+    }
+
+    private static Map<Class, Annotation> parseAnnotations2(
+                byte[] rawAnnotations,
+                ConstantPool constPool,
+                Class container) {
+        Map<Class, Annotation> result = new LinkedHashMap<Class, Annotation>();
+        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
+        int numAnnotations = buf.getShort() & 0xFFFF;
+        for (int i = 0; i < numAnnotations; i++) {
+           Annotation a = parseAnnotation(buf, constPool, container, false);
+            if (a != null) {
+                Class klass = a.annotationType();
+                AnnotationType type = AnnotationType.getInstance(klass);
+                if (type.retention() == RetentionPolicy.RUNTIME)
+                    if (result.put(klass, a) != null)
+                        throw new AnnotationFormatError(
+                            "Duplicate annotation for class: "+klass+": " + a);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Parses the parameter annotations described by the specified byte array.
+     * resolving constant references in the specified constant pool.
+     * The array must contain an array of annotations as described
+     * in the RuntimeVisibleParameterAnnotations_attribute:
+     *
+     *    u1 num_parameters;
+     *    {
+     *        u2 num_annotations;
+     *        annotation annotations[num_annotations];
+     *    } parameter_annotations[num_parameters];
+     *
+     * Unlike parseAnnotations, rawAnnotations must not be null!
+     * A null value must be handled by the caller.  This is so because
+     * we cannot determine the number of parameters if rawAnnotations
+     * is null.  Also, the caller should check that the number
+     * of parameters indicated by the return value of this method
+     * matches the actual number of method parameters.  A mismatch
+     * indicates that an AnnotationFormatError should be thrown.
+     *
+     * @throws AnnotationFormatError if an annotation is found to be
+     *         malformed.
+     */
+    public static Annotation[][] parseParameterAnnotations(
+                    byte[] rawAnnotations,
+                    ConstantPool constPool,
+                    Class container) {
+        try {
+            return parseParameterAnnotations2(rawAnnotations, constPool, container);
+        } catch(BufferUnderflowException e) {
+            throw new AnnotationFormatError(
+                "Unexpected end of parameter annotations.");
+        } catch(IllegalArgumentException e) {
+            // Type mismatch in constant pool
+            throw new AnnotationFormatError(e);
+        }
+    }
+
+    private static Annotation[][] parseParameterAnnotations2(
+                    byte[] rawAnnotations,
+                    ConstantPool constPool,
+                    Class container) {
+        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
+        int numParameters = buf.get() & 0xFF;
+        Annotation[][] result = new Annotation[numParameters][];
+
+        for (int i = 0; i < numParameters; i++) {
+            int numAnnotations = buf.getShort() & 0xFFFF;
+            List<Annotation> annotations =
+                new ArrayList<Annotation>(numAnnotations);
+            for (int j = 0; j < numAnnotations; j++) {
+                Annotation a = parseAnnotation(buf, constPool, container, false);
+                if (a != null) {
+                    AnnotationType type = AnnotationType.getInstance(
+                                              a.annotationType());
+                    if (type.retention() == RetentionPolicy.RUNTIME)
+                        annotations.add(a);
+                }
+            }
+            result[i] = annotations.toArray(EMPTY_ANNOTATIONS_ARRAY);
+        }
+        return result;
+    }
+
+    private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
+                    new Annotation[0];
+
+    /**
+     * Parses the annotation at the current position in the specified
+     * byte buffer, resolving constant references in the specified constant
+     * pool.  The cursor of the byte buffer must point to an "annotation
+     * structure" as described in the RuntimeVisibleAnnotations_attribute:
+     *
+     * annotation {
+     *    u2    type_index;
+     *       u2    num_member_value_pairs;
+     *       {    u2    member_name_index;
+     *             member_value value;
+     *       }    member_value_pairs[num_member_value_pairs];
+     *    }
+     * }
+     *
+     * Returns the annotation, or null if the annotation's type cannot
+     * be found by the VM, or is not a valid annotation type.
+     *
+     * @param exceptionOnMissingAnnotationClass if true, throw
+     * TypeNotPresentException if a referenced annotation type is not
+     * available at runtime
+     */
+    private static Annotation parseAnnotation(ByteBuffer buf,
+                                              ConstantPool constPool,
+                                              Class container,
+                                             boolean exceptionOnMissingAnnotationClass) {
+        int typeIndex = buf.getShort() & 0xFFFF;
+        Class annotationClass = null;
+       String sig = "[unknown]";
+        try {
+            try {
+                sig = constPool.getUTF8At(typeIndex);
+                annotationClass = parseSig(sig, container);
+            } catch (IllegalArgumentException ex) {
+                // support obsolete early jsr175 format class files
+                annotationClass = constPool.getClassAt(typeIndex);
+            }
+        } catch (NoClassDefFoundError e) {
+           if (exceptionOnMissingAnnotationClass)
+               // note: at this point sig is "[unknown]" or VM-style
+               // name instead of a binary name
+               throw new TypeNotPresentException(sig, e);
+            skipAnnotation(buf, false);
+            return null;
+        }
+       catch (TypeNotPresentException e) {
+           if (exceptionOnMissingAnnotationClass)
+               throw e;
+            skipAnnotation(buf, false);
+            return null;
+        }
+        AnnotationType type = null;
+        try {
+            type = AnnotationType.getInstance(annotationClass);
+        } catch (IllegalArgumentException e) {
+            skipAnnotation(buf, false);
+            return null;
+        }
+
+        Map<String, Class> memberTypes = type.memberTypes();
+        Map<String, Object> memberValues =
+            new LinkedHashMap<String, Object>(type.memberDefaults());
+
+        int numMembers = buf.getShort() & 0xFFFF;
+        for (int i = 0; i < numMembers; i++) {
+            int memberNameIndex = buf.getShort() & 0xFFFF;
+            String memberName = constPool.getUTF8At(memberNameIndex);
+            Class memberType = memberTypes.get(memberName);
+
+            if (memberType == null) {
+                // Member is no longer present in annotation type; ignore it
+                skipMemberValue(buf);
+            } else {
+                Object value = parseMemberValue(memberType, buf, constPool, container);
+                if (value instanceof AnnotationTypeMismatchExceptionProxy)
+                    ((AnnotationTypeMismatchExceptionProxy) value).
+                        setMember(type.members().get(memberName));
+                memberValues.put(memberName, value);
+            }
+        }
+        return annotationForMap(annotationClass, memberValues);
+    }
+
+    /**
+     * Returns an annotation of the given type backed by the given
+     * member -> value map.
+     */
+    public static Annotation annotationForMap(
+        Class type, Map<String, Object> memberValues)
+    {
+        return (Annotation) Proxy.newProxyInstance(
+            type.getClassLoader(), new Class[] { type },
+            new AnnotationInvocationHandler(type, memberValues));
+    }
+
+    /**
+     * Parses the annotation member value at the current position in the
+     * specified byte buffer, resolving constant references in the specified
+     * constant pool.  The cursor of the byte buffer must point to a
+     * "member_value structure" as described in the
+     * RuntimeVisibleAnnotations_attribute:
+     *
+     *  member_value {
+     *    u1 tag;
+     *    union {
+     *       u2   const_value_index;
+     *       {
+     *           u2   type_name_index;
+     *           u2   const_name_index;
+     *       } enum_const_value;
+     *       u2   class_info_index;
+     *       annotation annotation_value; 
+     *       {
+     *           u2    num_values;
+     *           member_value values[num_values];
+     *       } array_value;
+     *    } value;
+     * }
+     *
+     * The member must be of the indicated type. If it is not, this
+     * method returns an AnnotationTypeMismatchExceptionProxy.
+     */
+    public static Object parseMemberValue(Class memberType, ByteBuffer buf,
+                                          ConstantPool constPool,
+                                          Class container) {
+        Object result = null;
+        int tag = buf.get();
+        switch(tag) {
+          case 'e':
+              return parseEnumValue(memberType, buf, constPool, container);
+          case 'c':
+              result = parseClassValue(buf, constPool, container);
+              break;
+          case '@':
+              result = parseAnnotation(buf, constPool, container, true);
+              break;
+          case '[':
+              return parseArray(memberType, buf, constPool, container);
+          default:
+              result = parseConst(tag, buf, constPool);
+        }
+
+        if (!(result instanceof ExceptionProxy) &&
+            !memberType.isInstance(result))
+            result = new AnnotationTypeMismatchExceptionProxy(
+                result.getClass() + "[" + result + "]");
+        return result;
+    }
+
+    /**
+     * Parses the primitive or String annotation member value indicated by 
+     * the specified tag byte at the current position in the specified byte
+     * buffer, resolving constant reference in the specified constant pool.
+     * The cursor of the byte buffer must point to an annotation member value
+     * of the type indicated by the specified tag, as described in the
+     * RuntimeVisibleAnnotations_attribute:
+     *
+     *       u2   const_value_index;
+     */
+    private static Object parseConst(int tag,
+                                     ByteBuffer buf, ConstantPool constPool) {
+        int constIndex = buf.getShort() & 0xFFFF;
+        switch(tag) {
+          case 'B':
+            return Byte.valueOf((byte) constPool.getIntAt(constIndex));
+          case 'C':
+            return Character.valueOf((char) constPool.getIntAt(constIndex));
+          case 'D':
+            return Double.valueOf(constPool.getDoubleAt(constIndex));
+          case 'F':
+            return Float.valueOf(constPool.getFloatAt(constIndex));
+          case 'I':
+            return Integer.valueOf(constPool.getIntAt(constIndex));
+          case 'J':
+            return Long.valueOf(constPool.getLongAt(constIndex));
+          case 'S':
+            return Short.valueOf((short) constPool.getIntAt(constIndex));
+          case 'Z':
+            return Boolean.valueOf(constPool.getIntAt(constIndex) != 0);
+          case 's':
+            return constPool.getUTF8At(constIndex);
+          default:
+            throw new AnnotationFormatError(
+                "Invalid member-value tag in annotation: " + tag);
+        }
+    }
+
+    /**
+     * Parses the Class member value at the current position in the
+     * specified byte buffer, resolving constant references in the specified
+     * constant pool.  The cursor of the byte buffer must point to a "class
+     * info index" as described in the RuntimeVisibleAnnotations_attribute:
+     *
+     *       u2   class_info_index;
+     */
+    private static Object parseClassValue(ByteBuffer buf,
+                                          ConstantPool constPool,
+                                          Class container) {
+        int classIndex = buf.getShort() & 0xFFFF;
+        try {
+            try {
+                String sig = constPool.getUTF8At(classIndex);
+                return parseSig(sig, container);
+            } catch (IllegalArgumentException ex) {
+                // support obsolete early jsr175 format class files
+                return constPool.getClassAt(classIndex);
+            }
+        } catch (NoClassDefFoundError e) {
+            return new TypeNotPresentExceptionProxy("[unknown]", e);
+        }
+        catch (TypeNotPresentException e) {
+            return new TypeNotPresentExceptionProxy(e.typeName(), e.getCause());
+        }
+    }
+
+    /**
+     * Parses a return type signature and returns the according Class object.
+     */
+    private static Class<?> parseSig(String sig, Class container) {
+        if (sig.equals("V")) {
+            return void.class;
+        }
+        else {
+            return toClass(new FieldSignatureParser(container, sig).getFieldType());
+        }
+    }
+
+    static Class<?> toClass(Type o) {
+        if (o instanceof GenericArrayType)
+            return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
+                                     0)
+                .getClass();
+        return (Class<?>)o;
+    }
+
+    /**
+     * Parses the enum constant member value at the current position in the
+     * specified byte buffer, resolving constant references in the specified
+     * constant pool.  The cursor of the byte buffer must point to a
+     * "enum_const_value structure" as described in the
+     * RuntimeVisibleAnnotations_attribute:
+     *
+     *       {
+     *           u2   type_name_index;
+     *           u2   const_name_index;
+     *       } enum_const_value;
+     */
+    private static Object parseEnumValue(Class enumType, ByteBuffer buf,
+                                         ConstantPool constPool,
+                                         Class container) {
+        int typeNameIndex = buf.getShort() & 0xFFFF;
+        String typeName  = constPool.getUTF8At(typeNameIndex);
+        int constNameIndex = buf.getShort() & 0xFFFF;
+        String constName = constPool.getUTF8At(constNameIndex);
+
+        if (!typeName.endsWith(";")) {
+            // support now-obsolete early jsr175-format class files.
+            if (!enumType.getName().equals(typeName))
+            return new AnnotationTypeMismatchExceptionProxy(
+                typeName + "." + constName);
+        } else if (enumType != parseSig(typeName, container)) {
+            return new AnnotationTypeMismatchExceptionProxy(
+                typeName + "." + constName);
+        }
+
+        try {
+            return  Enum.valueOf(enumType, constName);
+        } catch(IllegalArgumentException e) {
+            return new EnumConstantNotPresentExceptionProxy(
+                (Class<? extends Enum>)enumType, constName);
+        }
+    }
+
+    /**
+     * Parses the array value at the current position in the specified byte
+     * buffer, resolving constant references in the specified constant pool.
+     * The cursor of the byte buffer must point to an array value struct
+     * as specified in the RuntimeVisibleAnnotations_attribute:
+     *
+     *       {
+     *           u2    num_values;
+     *           member_value values[num_values];
+     *       } array_value;
+     *
+     * If the array values do not match arrayType, an
+     * AnnotationTypeMismatchExceptionProxy will be returned.
+     */
+    private static Object parseArray(Class arrayType,
+                                     ByteBuffer buf,
+                                     ConstantPool constPool,
+                                     Class container) {
+        int length = buf.getShort() & 0xFFFF;  // Number of array components
+        Class componentType = arrayType.getComponentType();
+
+        if (componentType == byte.class) {
+            return parseByteArray(length, buf, constPool); 
+        } else if (componentType == char.class) {
+            return parseCharArray(length, buf, constPool);
+        } else if (componentType == double.class) {
+            return parseDoubleArray(length, buf, constPool);
+        } else if (componentType == float.class) {
+            return parseFloatArray(length, buf, constPool);
+        } else if (componentType == int.class) {
+            return parseIntArray(length, buf, constPool);
+        } else if (componentType == long.class) {
+            return parseLongArray(length, buf, constPool);
+        } else if (componentType == short.class) {
+            return parseShortArray(length, buf, constPool);
+        } else if (componentType == boolean.class) {
+            return parseBooleanArray(length, buf, constPool);
+        } else if (componentType == String.class) {
+            return parseStringArray(length, buf, constPool);
+        } else if (componentType == Class.class) {
+            return parseClassArray(length, buf, constPool, container);
+        } else if (componentType.isEnum()) {
+            return parseEnumArray(length, componentType, buf,
+                                  constPool, container);
+        } else {
+            assert componentType.isAnnotation();
+            return parseAnnotationArray(length, componentType, buf,
+                                        constPool, container);
+        }
+    }
+
+    private static Object parseByteArray(int length,
+                                  ByteBuffer buf, ConstantPool constPool) {
+        byte[] result = new byte[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'B') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = (byte) constPool.getIntAt(index);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseCharArray(int length,
+                                  ByteBuffer buf, ConstantPool constPool) {
+        char[] result = new char[length];
+        boolean typeMismatch = false;
+        byte tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'C') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = (char) constPool.getIntAt(index);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseDoubleArray(int length,
+                                    ByteBuffer buf, ConstantPool constPool) {
+        double[] result = new  double[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'D') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = constPool.getDoubleAt(index);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseFloatArray(int length,
+                                   ByteBuffer buf, ConstantPool constPool) {
+        float[] result = new float[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'F') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = constPool.getFloatAt(index);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseIntArray(int length,
+                                 ByteBuffer buf, ConstantPool constPool) {
+        int[] result = new  int[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'I') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = constPool.getIntAt(index);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+    
+    private static Object parseLongArray(int length,
+                                  ByteBuffer buf, ConstantPool constPool) {
+        long[] result = new long[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'J') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = constPool.getLongAt(index);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseShortArray(int length,
+                                   ByteBuffer buf, ConstantPool constPool) {
+        short[] result = new short[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'S') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = (short) constPool.getIntAt(index);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseBooleanArray(int length,
+                                     ByteBuffer buf, ConstantPool constPool) {
+        boolean[] result = new boolean[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'Z') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = (constPool.getIntAt(index) != 0);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseStringArray(int length,
+                                    ByteBuffer buf,  ConstantPool constPool) {
+        String[] result = new String[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 's') {
+                int index = buf.getShort() & 0xFFFF;
+                result[i] = constPool.getUTF8At(index);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseClassArray(int length,
+                                          ByteBuffer buf,
+                                          ConstantPool constPool,
+                                          Class container) {
+        Object[] result = new Class[length];
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'c') {
+                result[i] = parseClassValue(buf, constPool, container);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseEnumArray(int length, Class enumType,
+                                         ByteBuffer buf,
+                                         ConstantPool constPool,
+                                         Class container) {
+        Object[] result = (Object[]) Array.newInstance(enumType, length);
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == 'e') {
+                result[i] = parseEnumValue(enumType, buf, constPool, container);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    private static Object parseAnnotationArray(int length,
+                                               Class annotationType,
+                                               ByteBuffer buf,
+                                               ConstantPool constPool,
+                                               Class container) {
+        Object[] result = (Object[]) Array.newInstance(annotationType, length);
+        boolean typeMismatch = false;
+        int tag = 0;
+
+        for (int i = 0; i < length; i++) {
+            tag = buf.get();
+            if (tag == '@') {
+                result[i] = parseAnnotation(buf, constPool, container, true);
+            } else {
+                skipMemberValue(tag, buf);
+                typeMismatch = true;
+            }
+        }
+        return typeMismatch ? exceptionProxy(tag) : result;
+    }
+
+    /**
+     * Return an appropriate exception proxy for a mismatching array
+     * annotation where the erroneous array has the specified tag.
+     */
+    private static ExceptionProxy exceptionProxy(int tag) {
+        return new AnnotationTypeMismatchExceptionProxy(
+            "Array with component tag: " + tag);
+    }
+
+    /**
+     * Skips the annotation at the current position in the specified
+     * byte buffer.  The cursor of the byte buffer must point to 
+     * an "annotation structure" OR two bytes into an annotation
+     * structure (i.e., after the type index).
+     * 
+     * @parameter complete true if the byte buffer points to the beginning
+     *     of an annotation structure (rather than two bytes in).
+     */
+    private static void skipAnnotation(ByteBuffer buf, boolean complete) {
+        if (complete)
+            buf.getShort();   // Skip type index
+        int numMembers = buf.getShort() & 0xFFFF;
+        for (int i = 0; i < numMembers; i++) {
+            buf.getShort();   // Skip memberNameIndex
+            skipMemberValue(buf);
+        }
+    }
+
+    /**
+     * Skips the annotation member value at the current position in the
+     * specified byte buffer.  The cursor of the byte buffer must point to a
+     * "member_value structure."
+     */
+    private static void skipMemberValue(ByteBuffer buf) {
+        int tag = buf.get();
+        skipMemberValue(tag, buf);
+    }
+
+    /**
+     * Skips the annotation member value at the current position in the
+     * specified byte buffer.  The cursor of the byte buffer must point
+     * immediately after the tag in a "member_value structure."
+     */
+    private static void skipMemberValue(int tag, ByteBuffer buf) {
+        switch(tag) {
+          case 'e': // Enum value
+            buf.getInt();  // (Two shorts, actually.)
+            break;
+          case '@':
+            skipAnnotation(buf, true);
+            break;
+          case '[':
+            skipArray(buf);
+            break;
+          default:
+            // Class, primitive, or String
+            buf.getShort();
+        }
+    }
+
+    /**
+     * Skips the array value at the current position in the specified byte
+     * buffer.  The cursor of the byte buffer must point to an array value
+     * struct.
+     */
+    private static void skipArray(ByteBuffer buf) {
+        int length = buf.getShort() & 0xFFFF;
+        for (int i = 0; i < length; i++)
+            skipMemberValue(buf);
+    }
+}
diff --git a/src/classes/gnu/sun/reflect/annotation/AnnotationType.java b/src/classes/gnu/sun/reflect/annotation/AnnotationType.java
new file mode 100644 (file)
index 0000000..ea559bb
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.reflect.annotation;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Represents an annotation type at run time.  Used to type-check annotations
+ * and apply member defaults.
+ *
+ * @author  Josh Bloch
+ * @since   1.5
+ */
+public class AnnotationType {
+    /**
+     * Annotation class -> AnnotationType mapping. This emulates
+     * sun.misc.SharedSecrets.getJavaLangAccess().getAnnotationType() and
+     * sun.misc.SharedSecrets.getJavaLangAccess().setAnnotationType() so
+     * this class can be used with gnu classpath.
+     *
+     * @author Mathias Panzenböck
+     */
+    private static Map<Class, AnnotationType> annotationTypes =
+        new HashMap<Class, AnnotationType>();
+
+    /**
+     * Member name -> type mapping. Note that primitive types
+     * are represented by the class objects for the corresponding wrapper
+     * types.  This matches the return value that must be used for a
+     * dynamic proxy, allowing for a simple isInstance test.
+     */
+    private final Map<String, Class> memberTypes = new HashMap<String,Class>();
+
+    /**
+     * Member name -> default value mapping.
+     */
+    private final Map<String, Object> memberDefaults =
+        new HashMap<String, Object>();
+
+    /**
+     * Member name -> Method object mapping. This (and its assoicated
+     * accessor) are used only to generate AnnotationTypeMismatchExceptions.
+     */
+    private final Map<String, Method> members = new HashMap<String, Method>();
+
+    /**
+     * The retention policy for this annotation type.
+     */
+    private RetentionPolicy retention = RetentionPolicy.RUNTIME;;
+
+    /**
+     * Whether this annotation type is inherited.
+     */
+    private boolean inherited = false;
+
+    /**
+     * Returns an AnnotationType instance for the specified annotation type.
+     *
+     * @throw IllegalArgumentException if the specified class object for
+     *     does not represent a valid annotation type
+     */
+    public static synchronized AnnotationType getInstance(
+        Class annotationClass)
+    {
+        /*
+       AnnotationType result = sun.misc.SharedSecrets.getJavaLangAccess(). 
+            getAnnotationType(annotationClass); 
+        */
+       // emulating OpenJDKs SharedSecrets in GNU Classpath:
+       AnnotationType result = annotationTypes.get(annotationClass); 
+       if (result == null)
+            result = new AnnotationType((Class<?>) annotationClass);
+
+        return result;
+    }
+
+    /**
+     * Sole constructor.
+     *
+     * @param annotationClass the class object for the annotation type
+     * @throw IllegalArgumentException if the specified class object for
+     *     does not represent a valid annotation type
+     */
+    private AnnotationType(final Class<?> annotationClass) {
+        if (!annotationClass.isAnnotation())
+            throw new IllegalArgumentException("Not an annotation type");
+
+       Method[] methods =      
+           AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
+               public Method[] run() {
+                   // Initialize memberTypes and defaultValues
+                   return annotationClass.getDeclaredMethods();
+               }
+           });
+
+
+       for (Method method :  methods) {
+           if (method.getParameterTypes().length != 0)
+               throw new IllegalArgumentException(method + " has params");
+           String name = method.getName();
+           Class type = method.getReturnType();
+           memberTypes.put(name, invocationHandlerReturnType(type));
+           members.put(name, method);
+                   
+           Object defaultValue = method.getDefaultValue();
+           if (defaultValue != null)
+               memberDefaults.put(name, defaultValue);
+
+           members.put(name, method);
+       }
+
+       /*
+        sun.misc.SharedSecrets.getJavaLangAccess(). 
+            setAnnotationType(annotationClass, this); 
+        */
+       // emulating OpenJDKs SharedSecrets in GNU Classpath:
+       annotationTypes.put(annotationClass, this);
+
+        // Initialize retention, & inherited fields.  Special treatment
+        // of the corresponding annotation types breaks infinite recursion.
+        if (annotationClass != Retention.class &&
+            annotationClass != Inherited.class) {
+            Retention ret = annotationClass.getAnnotation(Retention.class);
+            retention = (ret == null ? RetentionPolicy.CLASS : ret.value());
+            inherited = annotationClass.isAnnotationPresent(Inherited.class);
+        }
+    }
+
+    /**
+     * Returns the type that must be returned by the invocation handler
+     * of a dynamic proxy in order to have the dynamic proxy return
+     * the specified type (which is assumed to be a legal member type
+     * for an annotation).
+     */
+    public static Class invocationHandlerReturnType(Class type) {
+        // Translate primitives to wrappers
+        if (type == byte.class)
+            return Byte.class;
+        if (type == char.class)
+            return Character.class;
+        if (type == double.class)
+            return Double.class;
+        if (type == float.class)
+            return Float.class;
+        if (type == int.class)
+            return Integer.class;
+        if (type == long.class)
+            return Long.class;
+        if (type == short.class)
+            return Short.class;
+        if (type == boolean.class)
+            return Boolean.class;
+
+        // Otherwise, just return declared type
+        return type;
+    }
+
+    /**
+     * Returns member types for this annotation type
+     * (member name -> type mapping).
+     */
+    public Map<String, Class> memberTypes() {
+        return memberTypes;
+    }
+
+    /**
+     * Returns members of this annotation type
+     * (member name -> associated Method object mapping).
+     */
+    public Map<String, Method> members() {
+        return members;
+    }
+
+    /**
+     * Returns the default values for this annotation type
+     * (Member name -> default value mapping).
+     */
+    public Map<String, Object> memberDefaults() {
+        return memberDefaults;
+    }
+
+    /**
+     * Returns the retention policy for this annotation type.
+     */
+    public RetentionPolicy retention() {
+        return retention;
+    }
+
+    /**
+     * Returns true if this this annotation type is inherited.
+     */
+    public boolean isInherited() {
+        return inherited;
+    }
+
+    /**
+     * For debugging.
+     */
+    public String toString() {
+        StringBuffer s = new StringBuffer("Annotation Type:" + "\n");
+        s.append("   Member types: " + memberTypes + "\n");
+        s.append("   Member defaults: " + memberDefaults + "\n");
+        s.append("   Retention policy: " + retention + "\n");
+        s.append("   Inherited: " + inherited);
+        return s.toString();
+    }
+}
diff --git a/src/classes/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java b/src/classes/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java
new file mode 100644 (file)
index 0000000..a7f434f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.reflect.annotation;
+import java.lang.annotation.*;
+import java.lang.reflect.Method;
+
+/**
+ * ExceptionProxy for AnnotationTypeMismatchException.
+ *
+ * @author  Josh Bloch
+ * @since   1.5
+ */
+class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy {
+    private Method member;
+    private String foundType;
+
+    /**
+     * It turns out to be convenient to construct these proxies in
+     * two stages.  Since this is a private implementation class, we
+     * permit ourselves this liberty even though it's normally a very
+     * bad idea.
+     */
+    AnnotationTypeMismatchExceptionProxy(String foundType) {
+        this.foundType = foundType;
+    }
+
+    AnnotationTypeMismatchExceptionProxy setMember(Method member) {
+        this.member = member;
+        return this;
+    }
+
+    protected RuntimeException generateException() {
+        return new AnnotationTypeMismatchException(member, foundType);
+    }
+}
diff --git a/src/classes/gnu/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java b/src/classes/gnu/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java
new file mode 100644 (file)
index 0000000..6049a3f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.reflect.annotation;
+import java.lang.annotation.*;
+
+/**
+ * ExceptionProxy for EnumConstantNotPresentException.
+ *
+ * @author  Josh Bloch
+ * @since   1.5
+ */
+public class EnumConstantNotPresentExceptionProxy extends ExceptionProxy {
+    Class<? extends Enum> enumType;
+    String constName;
+
+    public EnumConstantNotPresentExceptionProxy(Class<? extends Enum> enumType,
+                                                String constName) {
+        this.enumType = enumType;
+        this.constName = constName;
+    }
+
+    protected RuntimeException generateException() {
+        return new EnumConstantNotPresentException(enumType, constName);
+    }
+}
diff --git a/src/classes/gnu/sun/reflect/annotation/ExceptionProxy.java b/src/classes/gnu/sun/reflect/annotation/ExceptionProxy.java
new file mode 100644 (file)
index 0000000..e9cda0b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.reflect.annotation;
+
+/**
+ * An instance of this class is stored in an AnnotationInvocationHandler's
+ * "memberValues" map in lieu of a value for an annotation member that
+ * cannot be returned due to some exceptional condition (typically some
+ * form of illegal evolution of the annotation class).  The ExceptionProxy
+ * instance describes the exception that the dynamic proxy should throw if
+ * it is queried for this member.
+ *
+ * @author  Josh Bloch
+ * @since   1.5
+ */
+public abstract class ExceptionProxy implements java.io.Serializable {
+    protected abstract RuntimeException generateException();
+}
diff --git a/src/classes/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java b/src/classes/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java
new file mode 100644 (file)
index 0000000..22cab5d
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.reflect.annotation;
+import java.lang.annotation.*;
+
+/**
+ * ExceptionProxy for TypeNotPresentException.
+ *
+ * @author  Josh Bloch
+ * @since   1.5
+ */
+public class TypeNotPresentExceptionProxy extends ExceptionProxy {
+    String typeName;
+    Throwable cause;
+
+    public TypeNotPresentExceptionProxy(String typeName, Throwable cause) {
+        this.typeName = typeName;
+        this.cause = cause;
+    }
+
+    protected RuntimeException generateException() {
+        return new TypeNotPresentException(typeName, cause);
+    }
+}
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
deleted file mode 100644 (file)
index bdc41c2..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-## src/lib/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
-##
-## This file is part of CACAO.
-##
-## This program is free software; you can redistribute it and/or
-## modify it under the terms of the GNU General Public License as
-## published by the Free Software Foundation; either version 2, or (at
-## your option) any later version.
-##
-## This program is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-## 02110-1301, USA.
-
-
-EXTRA_DIST = \
-       $(VM_JAVA_FILES)
-
-CLEANFILES = vm.zip
-
-if WITH_CLASSPATH_GNU
-VM_JAVA_FILES = \
-       $(top_srcdir)/src/lib/gnu/gnu/classpath/VMStackWalker.java \
-       $(top_srcdir)/src/lib/gnu/gnu/classpath/VMSystemProperties.java \
-       $(top_srcdir)/src/lib/gnu/gnu/java/lang/management/VMMemoryMXBeanImpl.java \
-       $(top_srcdir)/src/lib/gnu/gnu/java/lang/management/VMRuntimeMXBeanImpl.java \
-       $(top_srcdir)/src/lib/gnu/java/lang/VMClassLoader.java \
-       $(top_srcdir)/src/lib/gnu/java/lang/VMString.java \
-       $(top_srcdir)/src/lib/gnu/java/lang/VMThread.java \
-       $(top_srcdir)/src/lib/gnu/java/lang/VMThrowable.java \
-       $(top_srcdir)/src/lib/gnu/java/lang/reflect/Constructor.java \
-       $(top_srcdir)/src/lib/gnu/java/lang/reflect/Field.java \
-       $(top_srcdir)/src/lib/gnu/java/lang/reflect/Method.java \
-       $(top_srcdir)/src/lib/gnu/java/security/VMAccessController.java \
-       $(top_srcdir)/src/lib/gnu/sun/misc/Unsafe.java
-
-VM_CLASS_FILES = \
-       classes/gnu/classpath/VMStackWalker.class \
-       classes/gnu/classpath/VMSystemProperties.class \
-       classes/gnu/java/lang/management/VMMemoryMXBeanImpl.class \
-       classes/gnu/java/lang/management/VMRuntimeMXBeanImpl.class \
-       classes/java/lang/VMClassLoader.class \
-       classes/java/lang/VMString.class \
-       classes/java/lang/VMThread.class \
-       classes/java/lang/VMThrowable.class \
-       classes/java/lang/reflect/Constructor.class \
-       classes/java/lang/reflect/Field.class \
-       classes/java/lang/reflect/Method.class \
-       classes/java/security/VMAccessController.class \
-       classes/sun/misc/Unsafe.class
-
-if ENABLE_ANNOTATIONS
-VM_JAVA_FILES += \
-       $(top_srcdir)/src/lib/gnu/sun/reflect/ConstantPool.java \
-       $(top_srcdir)/src/lib/gnu/sun/reflect/annotation/ExceptionProxy.java \
-       $(top_srcdir)/src/lib/gnu/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java \
-       $(top_srcdir)/src/lib/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java \
-       $(top_srcdir)/src/lib/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java \
-       $(top_srcdir)/src/lib/gnu/sun/reflect/annotation/AnnotationType.java \
-       $(top_srcdir)/src/lib/gnu/sun/reflect/annotation/AnnotationParser.java
-
-VM_CLASS_FILES += \
-       classes/sun/reflect/ConstantPool.class \
-       classes/sun/reflect/annotation/ExceptionProxy.class \
-       classes/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.class \
-       classes/sun/reflect/annotation/TypeNotPresentExceptionProxy.class \
-       classes/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.class \
-       classes/sun/reflect/annotation/AnnotationType.class \
-       classes/sun/reflect/annotation/AnnotationParser.class
-endif
-
-if ENABLE_ZLIB
-pkgdata_DATA = vm.zip
-else
-pkgdata_DATA = nozip
-endif
-endif
-
-if WITH_CLASSPATH_CLDC1_1
-VM_JAVA_FILES = \
-       $(top_srcdir)/src/lib/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java
-
-VM_CLASS_FILES = \
-       classes/com/sun/cldchi/jvm/FileDescriptor.class
-
-if ENABLE_ZLIB
-pkgdata_DATA = vm.zip
-else
-pkgdata_DATA = nozip
-endif
-endif
-
-if ENABLE_ZLIB
-VM_ZIP = ../vm.zip
-
-vm.zip: $(VM_JAVA_FILES)
-       $(mkdir_p) classes
-       $(JAVAC) -source 1.5 -target 1.5 -d classes $(VM_JAVA_FILES)
-       @if test "$(JAR)" = "zip" -o "$(JAR)" = "zip.exe"; then \
-           cd classes && $(JAR) -r -D $(VM_ZIP) .; \
-       else \
-           cd classes && $(JAR) cvf $(VM_ZIP) .; \
-       fi
-else
-nozip: $(VM_JAVA_FILES)
-       $(mkdir_p) classes
-       $(JAVAC) -source 1.5 -target 1.5 -d classes $(VM_JAVA_FILES)
-endif
-
-clean-local:
-       -rm -rf classes
-
-
-## 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/lib/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java b/src/lib/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java
deleted file mode 100644 (file)
index 42aeb40..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* src/lib/com/sun/cldchi/jvm/FileDescriptor.java
-
-   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.
-
-*/
-
-package com.sun.cldchi.jvm;
-
-class FileDescriptor {
-    long pointer;
-    int position;
-    int length;
-}
diff --git a/src/lib/gnu/gnu/classpath/VMStackWalker.java b/src/lib/gnu/gnu/classpath/VMStackWalker.java
deleted file mode 100644 (file)
index 434edd2..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* VMStackWalker.java -- Reference implementation of VM hooks for stack access
-   Copyright (C) 2005 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package gnu.classpath;
-
-/**
- * This class provides access to the classes on the Java stack
- * for reflection and security purposes.
- *
- * <p>
- * This class is only available to privileged code (i.e., code loaded
- * by the bootstrap loader).
- *
- * @author John Keiser
- * @author Eric Blake <ebb9@email.byu.edu>
- * @author Archie Cobbs
- */
-public final class VMStackWalker
-{
-  /**
-   * Get a list of all the classes currently executing methods on the
-   * Java stack. <code>getClassContext()[0]</code> is the class associated
-   * with the currently executing method, i.e., the method that called
-   * <code>VMStackWalker.getClassContext()</code> (possibly through
-   * reflection). So you may need to pop off these stack frames from
-   * the top of the stack:
-   * <ul>
-   * <li><code>VMStackWalker.getClassContext()</code>
-   * <li><code>Method.invoke()</code>
-   * </ul>
-   *
-   * @return an array of the declaring classes of each stack frame
-   */
-  public static native Class[] getClassContext();
-
-  /**
-   * Get the class associated with the method invoking the method
-   * invoking this method, or <code>null</code> if the stack is not
-   * that deep (e.g., invoked via JNI invocation API). This method
-   * is an optimization for the expression <code>getClassContext()[1]</code>
-   * and should return the same result.
-   *
-   * <p>
-   * VM implementers are encouraged to provide a more efficient
-   * version of this method.
-   */
-//    public static Class getCallingClass()
-//    {
-//      Class[] ctx = getClassContext();
-//      if (ctx.length < 3)
-//        return null;
-//      return ctx[2];
-//    }
-  public static native Class getCallingClass();
-
-  /**
-   * Get the class loader associated with the Class returned by
-   * <code>getCallingClass()</code>, or <code>null</code> if no such class
-   * exists or it is the boot loader. This method is an optimization for the
-   * expression <code>VMStackWalker.getClassLoader(getClassContext()[1])</code>
-   * and should return the same result.
-   *
-   * <p>
-   * VM implementers are encouraged to provide a more efficient
-   * version of this method.
-   */
-//    public static ClassLoader getCallingClassLoader()
-//    {
-//      Class[] ctx = getClassContext();
-//      if (ctx.length < 3)
-//        return null;
-//      return getClassLoader(ctx[2]);
-//    }
-  public static native ClassLoader getCallingClassLoader();
-
-
-  /**
-   * Retrieve the class's ClassLoader, or <code>null</code> if loaded
-   * by the bootstrap loader. I.e., this should return the same thing
-   * as {@link java.lang.VMClass#getClassLoader}. This duplicate version
-   * is here to work around access permissions.
-   */
-//    public static native ClassLoader getClassLoader(Class cl);
-
-  /**
-   * Walk up the stack and return the first non-null class loader.
-   * If there aren't any non-null class loaders on the stack, return null.
-   */
-//   public static ClassLoader firstNonNullClassLoader()
-//   {
-//     Class[] stack = getClassContext();
-//     for (int i = 0; i < stack.length; i++)
-//       {
-//         ClassLoader loader = getClassLoader(stack[i]);
-//         if (loader != null)
-//           return loader;
-//       }
-//     return null;
-//   }
-    public static native ClassLoader firstNonNullClassLoader();
-}
diff --git a/src/lib/gnu/gnu/classpath/VMSystemProperties.java b/src/lib/gnu/gnu/classpath/VMSystemProperties.java
deleted file mode 100644 (file)
index 287a933..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/* VMSystemProperties.java -- Allow the VM to set System properties.
-   Copyright (C) 2004 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package gnu.classpath;
-
-import java.util.Properties;
-
-class VMSystemProperties
-{
-    /**
-     * Get the system properties. This is done here, instead of in System,
-     * because of the bootstrap sequence. Note that the native code should
-     * not try to use the Java I/O classes yet, as they rely on the properties
-     * already existing. The only safe method to use to insert these default
-     * system properties is {@link Properties#setProperty(String, String)}.
-     *
-     * <p>These properties MUST include:
-     * <dl>
-     * <dt>java.version         <dd>Java version number
-     * <dt>java.vendor          <dd>Java vendor specific string
-     * <dt>java.vendor.url      <dd>Java vendor URL
-     * <dt>java.home            <dd>Java installation directory
-     * <dt>java.vm.specification.version <dd>VM Spec version
-     * <dt>java.vm.specification.vendor  <dd>VM Spec vendor
-     * <dt>java.vm.specification.name    <dd>VM Spec name
-     * <dt>java.vm.version      <dd>VM implementation version
-     * <dt>java.vm.vendor       <dd>VM implementation vendor
-     * <dt>java.vm.name         <dd>VM implementation name
-     * <dt>java.specification.version    <dd>Java Runtime Environment version
-     * <dt>java.specification.vendor     <dd>Java Runtime Environment vendor
-     * <dt>java.specification.name       <dd>Java Runtime Environment name
-     * <dt>java.class.version   <dd>Java class version number
-     * <dt>java.class.path      <dd>Java classpath
-     * <dt>java.library.path    <dd>Path for finding Java libraries
-     * <dt>java.io.tmpdir       <dd>Default temp file path
-     * <dt>java.compiler        <dd>Name of JIT to use
-     * <dt>java.ext.dirs        <dd>Java extension path
-     * <dt>os.name              <dd>Operating System Name
-     * <dt>os.arch              <dd>Operating System Architecture
-     * <dt>os.version           <dd>Operating System Version
-     * <dt>file.separator       <dd>File separator ("/" on Unix)
-     * <dt>path.separator       <dd>Path separator (":" on Unix)
-     * <dt>line.separator       <dd>Line separator ("\n" on Unix)
-     * <dt>user.name            <dd>User account name
-     * <dt>user.home            <dd>User home directory
-     * <dt>user.dir             <dd>User's current working directory
-     * <dt>gnu.cpu.endian       <dd>"big" or "little"
-     * </dl>
-     *
-     * @param properties the Properties object to insert the system properties into
-     */
-    static native void preInit(Properties properties);
-
-    /**
-     * Here you get a chance to overwrite some of the properties set by
-     * the common SystemProperties code. For example, it might be
-     * a good idea to process the properties specified on the command
-     * line here.
-     */
-//     static void postInit(Properties properties)
-//     {
-//     }
-    static native void postInit(Properties properties);
-}
diff --git a/src/lib/gnu/gnu/java/lang/management/VMMemoryMXBeanImpl.java b/src/lib/gnu/gnu/java/lang/management/VMMemoryMXBeanImpl.java
deleted file mode 100644 (file)
index d71a06d..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* VMMemoryMXBeanImpl.java - VM impl. of a memory bean
-   Copyright (C) 2006 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package gnu.java.lang.management;
-
-import java.lang.management.MemoryUsage;
-
-/**
- * Provides access to information about the memory
- * management of the current invocation of the virtual
- * machine.  Instances of this bean are obtained by calling
- * {@link ManagementFactory#getMemoryMXBean()}.
- *
- * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
- * @since 1.5
- */
-final class VMMemoryMXBeanImpl
-{
-
-  /**
-   * Returns an instance of {@link java.lang.management.MemoryUsage}
-   * with appropriate initial, used, committed and maximum values
-   * for the heap.  By default, this uses the methods of
-   * {@link java.lang.Runtime} to provide some of the values.
-   *
-   * @return an {@link java.lang.management.MemoryUsage} instance
-   *         for the heap.
-   */
-//   static MemoryUsage getHeapMemoryUsage()
-//   {
-//     Runtime runtime = Runtime.getRuntime();
-//     long totalMem = runtime.totalMemory();
-//     return new MemoryUsage(-1, totalMem - runtime.freeMemory(),
-//                        totalMem, runtime.maxMemory());
-//   }
-  static native MemoryUsage getHeapMemoryUsage();
-
-  /**
-   * Returns an instance of {@link java.lang.management.MemoryUsage}
-   * with appropriate initial, used, committed and maximum values
-   * for non-heap memory.
-   *
-   * @return an {@link java.lang.management.MemoryUsage} instance
-   *         for non-heap memory.
-   */
-  static native MemoryUsage getNonHeapMemoryUsage();
-
-  /**
-   * Returns the number of objects ready to be garbage collected.
-   *
-   * @return the number of finalizable objects.
-   */
-  static native int getObjectPendingFinalizationCount();
-
-  /**
-   * Returns true if the virtual machine will emit additional
-   * information when memory is allocated and deallocated.  The
-   * format of the output is left up to the virtual machine.
-   *
-   * @return true if verbose class loading output is on.
-   */
-  static native boolean isVerbose();
-
-  /**
-   * Turns on or off the emission of additional information
-   * when memory is allocated and deallocated.  The format of the
-   * output is left up to the virtual machine.  This method
-   * may be called by multiple threads concurrently, but there
-   * is only one global setting of verbosity that is affected.
-   *
-   * @param verbose the new setting for verbose class loading
-   *                output.
-   */
-  static native void setVerbose(boolean verbose);
-
-}
diff --git a/src/lib/gnu/gnu/java/lang/management/VMRuntimeMXBeanImpl.java b/src/lib/gnu/gnu/java/lang/management/VMRuntimeMXBeanImpl.java
deleted file mode 100644 (file)
index 32a8660..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* VMRuntimeMXBeanImpl.java - VM implementation of an runtime bean
-   Copyright (C) 2006 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package gnu.java.lang.management;
-
-import gnu.classpath.SystemProperties;
-
-/**
- * Provides access to information about the virtual machine.
- *
- * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
- * @since 1.5
- */
-final class VMRuntimeMXBeanImpl
-{
-
-  /**
-   * Returns the command-line arguments supplied
-   * to the virtual machine, excluding those supplied
-   * to <code>main()</code>.
-   *
-   * @return the command-line arguments.
-   */
-  static native String[] getInputArguments();
-
-  /**
-   * Returns a developer-chosen name for the virtual
-   * machine, which may differ over different running
-   * instances of the same virtual machine binary.
-   * For example, this may include the particular
-   * process identifier used by this instance or
-   * the host name of the machine on which it is
-   * running.  The intention is that this name refers
-   * to the precise entity that the other data supplied
-   * by the bean refers to, rather than the VM in general.
-   *
-   * @return the custom name of the VM.
-   */
-  static String getName()
-  {
-    return SystemProperties.getProperty("java.vm.name") + " " +
-      SystemProperties.getProperty("java.vm.version");
-  }
-
-  /**
-   * The time in milliseconds at which the virtual
-   * machine was started.  This method is only executed
-   * once (for efficency), as the value is not expected
-   * to change.
-   *
-   * @return the VM start time.
-   */
-  static native long getStartTime();
-
-}
diff --git a/src/lib/gnu/java/lang/VMClassLoader.java b/src/lib/gnu/java/lang/VMClassLoader.java
deleted file mode 100644 (file)
index f09838b..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/* VMClassLoader.java -- Reference implementation of native interface
-   required by ClassLoader
-   Copyright (C) 1998, 2001, 2002, 2004, 2005, 2006 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package java.lang;
-
-import gnu.classpath.Configuration;
-import gnu.classpath.SystemProperties;
-import gnu.java.lang.InstrumentationImpl;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.instrument.Instrumentation;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.ProtectionDomain;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import java.util.zip.ZipFile;
-import java.util.Collections;
-import java.lang.Boolean;
-
-/**
- * java.lang.VMClassLoader is a package-private helper for VMs to implement
- * on behalf of java.lang.ClassLoader.
- *
- * @author John Keiser
- * @author Mark Wielaard (mark@klomp.org)
- * @author Eric Blake (ebb9@email.byu.edu)
- */
-final class VMClassLoader
-{
-
-
-  /** packages loaded by the bootstrap class loader */
-  static final HashMap definedPackages = new HashMap();
-
-  /** jars from property java.boot.class.path */
-  static final HashMap bootjars = new HashMap();
-  
-
-  /**
-   * Converts the array string of native package names to
-   * Packages. The packages are then put into the
-   * definedPackages hashMap
-   */
-  static
-  {
-    String[] packages = getBootPackages();
-    
-    if( packages != null)
-      {
-        String specName = 
-              SystemProperties.getProperty("java.specification.name");
-        String vendor =
-              SystemProperties.getProperty("java.specification.vendor");
-        String version =
-              SystemProperties.getProperty("java.specification.version");
-        
-        Package p;
-              
-        for(int i = 0; i < packages.length; i++)
-          {
-            p = new Package(packages[i],
-                  specName,
-                  vendor,
-                  version,
-                  "GNU Classpath",
-                  "GNU",
-                  Configuration.CLASSPATH_VERSION,
-                  null,
-                  null);
-
-            definedPackages.put(packages[i], p);
-          }
-      }
-  }
-
-  
-  /**
-   * Helper to define a class using a string of bytes. This assumes that
-   * the security checks have already been performed, if necessary.
-   *
-   * Implementations of this method are advised to consider the
-   * situation where user code modifies the byte array after it has
-   * been passed to defineClass.  This can be handled by making a
-   * private copy of the array, or arranging to only read any given
-   * byte a single time.
-   *
-   * @param name the name to give the class, or null if unknown
-   * @param data the data representing the classfile, in classfile format
-   * @param offset the offset into the data where the classfile starts
-   * @param len the length of the classfile data in the array
-   * @param pd the protection domain
-   * @return the class that was defined
-   * @throws ClassFormatError if data is not in proper classfile format
-   */
-  static final native Class defineClass(ClassLoader cl, String name,
-                                 byte[] data, int offset, int len,
-                                 ProtectionDomain pd)
-    throws ClassFormatError;
-
-  /**
-   * Helper to resolve all references to other classes from this class.
-   *
-   * @param c the class to resolve
-   */
-  static final native void resolveClass(Class c);
-
-  /**
-   * Helper to load a class from the bootstrap class loader.
-   *
-   * @param name the class name to load
-   * @param resolve whether to resolve it
-   * @return the class, loaded by the bootstrap classloader or null
-   * if the class wasn't found. Returning null is equivalent to throwing
-   * a ClassNotFoundException (but a possible performance optimization).
-   */
-  static final native Class loadClass(String name, boolean resolve)
-    throws ClassNotFoundException;
-
-  /**
-   * Helper to load a resource from the bootstrap class loader.
-   *
-   * @param name the resource to find
-   * @return the URL to the resource
-   */
-  static URL getResource(String name)
-  {
-    Enumeration e = getResources(name);
-    if (e.hasMoreElements())
-      return (URL)e.nextElement();
-    return null;
-  }
-  /**
-   * Helper to get a list of resources from the bootstrap class loader.
-   *
-   * @param name the resource to find
-   * @return an enumeration of resources
-   */
-  static Enumeration getResources(String name)
-  {
-//     StringTokenizer st = new StringTokenizer(
-//       SystemProperties.getProperty("java.boot.class.path", "."),
-//       File.pathSeparator);
-//     Vector v = new Vector();
-//     while (st.hasMoreTokens())
-//       {
-//     File file = new File(st.nextToken());
-//     if (file.isDirectory())
-//       {
-//         try
-//           {
-//                 File f = new File(file, name);
-//                 if (!f.exists()) continue;
-//                 v.add(new URL("file://" + f.getAbsolutePath()));
-//           }
-//         catch (MalformedURLException e)
-//           {
-//             throw new Error(e);
-//           }
-//       }
-//     else if (file.isFile())
-//       {
-//         ZipFile zip;
-//             synchronized(bootjars)
-//               {
-//                 zip = (ZipFile) bootjars.get(file.getName());
-//               }
-//             if(zip == null)
-//               {
-//                 try
-//               {
-//                     zip = new ZipFile(file);
-//                     synchronized(bootjars)
-//                       {
-//                         bootjars.put(file.getName(), zip);
-//                       }
-//               }
-//             catch (IOException e)
-//               {
-//                 continue;
-//               }
-//               }
-//         String zname = name.startsWith("/") ? name.substring(1) : name;
-//         if (zip.getEntry(zname) == null)
-//           continue;
-//         try
-//           {
-//             v.add(new URL("jar:file://"
-//               + file.getAbsolutePath() + "!/" + zname));
-//           }
-//         catch (MalformedURLException e)
-//           {
-//             throw new Error(e);
-//           }
-//       }
-//       }
-//     return v.elements();
-//   }
-    Vector urls = nativeGetResources(name);
-    Vector v = new Vector();
-    for (Enumeration en = urls.elements(); en.hasMoreElements();)
-      {
-       try
-         {
-           v.add(new URL((String) en.nextElement()));
-         }
-       catch (MalformedURLException e)
-         {
-           throw new Error(e);
-         }
-      }
-    return v.elements();
-  }
-
-  private native static final Vector nativeGetResources(String name);
-
-
-  /**
-   * Returns a String[] of native package names. The default
-   * implementation tries to load a list of package from
-   * the META-INF/INDEX.LIST file in the boot jar file.
-   * If not found or if any exception is raised, it returns
-   * an empty array. You may decide this needs native help.
-   */
-  private static String[] getBootPackages()
-  {
-    try
-      {
-        Enumeration indexListEnumeration = getResources("META-INF/INDEX.LIST");
-        Set packageSet = new HashSet();
-
-        while (indexListEnumeration.hasMoreElements())
-          {
-            try
-              {
-                String line;
-                int lineToSkip = 3;
-                BufferedReader reader = new BufferedReader(
-                                                           new InputStreamReader(
-                                                                                 ((URL) indexListEnumeration.nextElement()).openStream()));
-                while ((line = reader.readLine()) != null)
-                  {
-                    if (lineToSkip == 0)
-                      {
-                        if (line.length() == 0)
-                          lineToSkip = 1;
-                        else
-                          packageSet.add(line.replace('/', '.'));
-                      }
-                    else
-                      lineToSkip--;
-                  }
-                reader.close();
-              }
-            catch (IOException e)
-              {
-                // Empty catch block on purpose
-              }
-          }
-        return (String[]) packageSet.toArray(new String[packageSet.size()]);
-      }
-    catch (Exception e)
-      {
-        return new String[0];
-      }
-  }
-
-
-  /**
-   * Helper to get a package from the bootstrap class loader.
-   *
-   * @param name the name to find
-   * @return the named package, if it exists
-   */
-  static Package getPackage(String name)
-  {
-    return (Package)definedPackages.get(name);
-  }
-
-
-  
-  /**
-   * Helper to get all packages from the bootstrap class loader.  
-   *
-   * @return all named packages, if any exist
-   */
-  static Package[] getPackages()
-  {
-    Package[] packages = new Package[definedPackages.size()];
-    definedPackages.values().toArray(packages);
-    return packages;
-  }
-
-  /**
-   * Helper for java.lang.Integer, Byte, etc to get the TYPE class
-   * at initialization time. The type code is one of the chars that
-   * represents the primitive type as in JNI.
-   *
-   * <ul>
-   * <li>'Z' - boolean</li>
-   * <li>'B' - byte</li>
-   * <li>'C' - char</li>
-   * <li>'D' - double</li>
-   * <li>'F' - float</li>
-   * <li>'I' - int</li>
-   * <li>'J' - long</li>
-   * <li>'S' - short</li>
-   * <li>'V' - void</li>
-   * </ul>
-   *
-   * @param type the primitive type
-   * @return a "bogus" class representing the primitive type
-   */
-  static final native Class getPrimitiveClass(char type);
-
-  /**
-   * The system default for assertion status. This is used for all system
-   * classes (those with a null ClassLoader), as well as the initial value for
-   * every ClassLoader's default assertion status.
-   *
-   * @return the system-wide default assertion status
-   */
-  static native final boolean defaultAssertionStatus();
-
-  static native final boolean defaultUserAssertionStatus();
-
-
-  static final Map packageAssertionMap = 
-    Collections.unmodifiableMap(packageAssertionStatus0(Boolean.TRUE, Boolean.FALSE));
-  
-  static native final Map packageAssertionStatus0(Boolean jtrue, Boolean jfalse);
-  /**
-   * The system default for package assertion status. This is used for all
-   * ClassLoader's packageAssertionStatus defaults. It must be a map of
-   * package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package
-   * represented as a null key.
-   *
-   * @return a (read-only) map for the default packageAssertionStatus
-   */
-   
-  static final Map packageAssertionStatus() {
-    return packageAssertionMap;
-  }
-
-  static final Map classAssertionMap = 
-    Collections.unmodifiableMap(classAssertionStatus0(Boolean.TRUE, Boolean.FALSE));
-  
-  static native final Map classAssertionStatus0(Boolean jtrue, Boolean jfalse);
-
-  /**
-   * The system default for class assertion status. This is used for all
-   * ClassLoader's classAssertionStatus defaults. It must be a map of
-   * class names to Boolean.TRUE or Boolean.FALSE
-   *
-   * @return a (read-only) map for the default classAssertionStatus
-   */
-  static final Map classAssertionStatus() {
-    return classAssertionMap;
-  }
-  
-  static ClassLoader getSystemClassLoader()
-  {
-    return ClassLoader.defaultGetSystemClassLoader();
-  }
-
-  /**
-   * Find the class if this class loader previously defined this class
-   * or if this class loader has been recorded as the initiating class loader
-   * for this class.
-   */
-  static native Class findLoadedClass(ClassLoader cl, String name);
-
-  /**
-   * The Instrumentation object created by the vm when agents are defined.
-   */
-  static final Instrumentation instrumenter = null;
-
-  /**
-   * Call the transformers of the possible Instrumentation object. This
-   * implementation assumes the instrumenter is a
-   * <code>InstrumentationImpl</code> object. VM implementors would
-   * have to redefine this method if they provide their own implementation
-   * of the <code>Instrumentation</code> interface.
-   *
-   * @param loader the initiating loader
-   * @param name the name of the class
-   * @param data the data representing the classfile, in classfile format
-   * @param offset the offset into the data where the classfile starts
-   * @param len the length of the classfile data in the array
-   * @param pd the protection domain
-   * @return the new data representing the classfile
-   */
-  static final Class defineClassWithTransformers(ClassLoader loader,
-      String name, byte[] data, int offset, int len, ProtectionDomain pd)
-  {
-    
-    if (instrumenter != null)
-      {
-        byte[] modifiedData = new byte[len];
-        System.arraycopy(data, offset, modifiedData, 0, len);
-        modifiedData =
-          ((InstrumentationImpl)instrumenter).callTransformers(loader, name,
-            null, pd, modifiedData);
-        
-        return defineClass(loader, name, modifiedData, 0, modifiedData.length,
-            pd);
-      }
-    else
-      {
-        return defineClass(loader, name, data, offset, len, pd);
-      }
-  }
-}
diff --git a/src/lib/gnu/java/lang/VMString.java b/src/lib/gnu/java/lang/VMString.java
deleted file mode 100644 (file)
index 57e4423..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* VMString.java -- VM Specific String methods
-   Copyright (C) 2003 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package java.lang;
-
-import java.lang.ref.WeakReference;
-import java.util.WeakHashMap;
-
-/*
- * This class is a reference version, mainly for compiling a class library
- * jar.  It is likely that VM implementers replace this with their own
- * version that can communicate effectively with the VM.
- */
-
-/**
- * Code relocated from java.lang.String by 
- * @author Dave Grove <groved@us.ibm.com>
- */
-final class VMString
-{
-
-  /**
-   * Holds the references for each intern()'d String. If all references to
-   * the string disappear, and the VM properly supports weak references,
-   * the String will be GC'd.
-   */
-//    private static final WeakHashMap internTable = new WeakHashMap();
-
-  /**
-   * Fetches this String from the intern hashtable. If two Strings are
-   * considered equal, by the equals() method, then intern() will return the
-   * same String instance. ie. if (s1.equals(s2)) then
-   * (s1.intern() == s2.intern()). All string literals and string-valued
-   * constant expressions are already interned.
-   *
-   * @param str the String to intern
-   * @return the interned String
-   */
-//    static String intern(String str)
-//    {
-//      synchronized (internTable)
-//        {
-//          WeakReference ref = (WeakReference) internTable.get(str);
-//          if (ref != null)
-//            {
-//              String s = (String) ref.get();
-//              // If s is null, then no strong references exist to the String;
-//              // the weak hash map will soon delete the key.
-//              if (s != null)
-//                return s;
-//            }
-//          internTable.put(str, new WeakReference(str));
-//        }
-//      return str;
-//    }
-
-  /**
-   * this one is native in CACAO
-   */
-  static native String intern(String str);
-
-} // class VMString
diff --git a/src/lib/gnu/java/lang/VMThread.java b/src/lib/gnu/java/lang/VMThread.java
deleted file mode 100644 (file)
index a511f3c..0000000
+++ /dev/null
@@ -1,462 +0,0 @@
-/* VMThread -- VM interface for Thread of executable code
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package java.lang;
-
-/**
- * VM interface for Thread of executable code. Holds VM dependent state.
- * It is deliberately package local and final and should only be accessed
- * by the Thread class.
- * <p>
- * This is the GNU Classpath reference implementation, it should be adapted
- * for a specific VM.
- * <p>
- * The following methods must be implemented:
- * <ul>
- * <li>native void start(long stacksize);
- * <li>native void interrupt();
- * <li>native boolean isInterrupted();
- * <li>native void suspend();
- * <li>native void resume();
- * <li>native void nativeSetPriority(int priority);
- * <li>native void nativeStop(Throwable t);
- * <li>native static Thread currentThread();
- * <li>static native void yield();
- * <li>static native boolean interrupted();
- * </ul>
- * All other methods may be implemented to make Thread handling more efficient
- * or to implement some optional (and sometimes deprecated) behaviour. Default
- * implementations are provided but it is highly recommended to optimize them
- * for a specific VM.
- * 
- * @author Jeroen Frijters (jeroen@frijters.net)
- * @author Dalibor Topic (robilad@kaffe.org)
- */
-final class VMThread
-{
-    /**
-     * The Thread object that this VM state belongs to.
-     * Used in currentThread() and start().
-     * Note: when this thread dies, this reference is *not* cleared
-     */
-    volatile Thread thread;
-
-    /**
-     * Flag that is set when the thread runs, used by stop() to protect against
-     * stop's getting lost.
-     */
-    private volatile boolean running;
-
-    /**
-     * VM private data.
-     */
-    private transient Object vmdata;
-
-    /**
-     * Private constructor, create VMThreads with the static create method.
-     *
-     * @param thread The Thread object that was just created.
-     */
-    private VMThread(Thread thread)
-    {
-       this.thread = thread;
-    }
-
-    /**
-     * This method is the initial Java code that gets executed when a native
-     * thread starts. It's job is to coordinate with the rest of the VMThread
-     * logic and to start executing user code and afterwards handle clean up.
-     */
-    private void run()
-    {
-       try
-       {
-           try
-           {
-               running = true;
-               synchronized(thread)
-               {
-                   Throwable t = thread.stillborn;
-                   if(t != null)
-                   {
-                       thread.stillborn = null;
-                       throw t;
-                   }
-               }
-               thread.run();
-           }
-           catch(Throwable t)
-           {
-               try
-               {
-                 Thread.UncaughtExceptionHandler handler;
-                 handler = thread.getUncaughtExceptionHandler();
-                 handler.uncaughtException(thread, t);
-               }
-               catch(Throwable ignore)
-               {
-               }
-           }
-       }
-       finally
-       {
-           // Setting runnable to false is partial protection against stop
-           // being called while we're cleaning up. To be safe all code in
-           // VMThread be unstoppable.
-           running = false;
-           thread.die();
-           synchronized(this)
-           {
-               // release the threads waiting to join us
-               notifyAll();
-           }
-       }
-    }
-
-    /**
-     * Creates a native Thread. This is called from the start method of Thread.
-     * The Thread is started.
-     *
-     * @param thread The newly created Thread object
-     * @param stacksize Indicates the requested stacksize. Normally zero,
-     * non-zero values indicate requested stack size in bytes but it is up
-     * to the specific VM implementation to interpret them and may be ignored.
-     */
-    static void create(Thread thread, long stacksize)
-    {
-       VMThread vmThread = new VMThread(thread);
-       thread.vmThread = vmThread;
-       vmThread.start(stacksize);
-    }
-
-    /**
-     * Gets the name of the thread. Usually this is the name field of the
-     * associated Thread object, but some implementation might choose to
-     * return the name of the underlying platform thread.
-     */
-    String getName()
-    {
-       return thread.name;
-    }
-
-    /**
-     * Set the name of the thread. Usually this sets the name field of the
-     * associated Thread object, but some implementations might choose to
-     * set the name of the underlying platform thread.
-     * @param name The new name
-     */
-    void setName(String name)
-    {
-       thread.name = name;
-    }
-
-    /**
-     * Set the thread priority field in the associated Thread object and
-     * calls the native method to set the priority of the underlying
-     * platform thread.
-     * @param priority The new priority
-     */
-    void setPriority(int priority)
-    {
-       thread.priority = priority;
-       nativeSetPriority(priority);
-    }
-
-    /**
-     * Returns the priority. Usually this is the priority field from the
-     * associated Thread object, but some implementation might choose to
-     * return the priority of the underlying platform thread.
-     * @return this Thread's priority
-     */
-    int getPriority()
-    {
-        return thread.priority;
-    }
-
-    /**
-     * Returns true if the thread is a daemon thread. Usually this is the
-     * daemon field from the associated Thread object, but some
-     * implementation might choose to return the daemon state of the underlying
-     * platform thread.
-     * @return whether this is a daemon Thread or not
-     */
-    boolean isDaemon()
-    {
-        return thread.daemon;
-    }
-
-    /**
-     * Returns the number of stack frames in this Thread.
-     * Will only be called when when a previous call to suspend() returned true.
-     *
-     * @deprecated unsafe operation
-     */
-    native int countStackFrames();
-
-    /**
-     * Wait the specified amount of time for the Thread in question to die.
-     *
-     * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
-     * not offer that fine a grain of timing resolution. Besides, there is
-     * no guarantee that this thread can start up immediately when time expires,
-     * because some other thread may be active.  So don't expect real-time
-     * performance.
-     *
-     * @param ms the number of milliseconds to wait, or 0 for forever
-     * @param ns the number of extra nanoseconds to sleep (0-999999)
-     * @throws InterruptedException if the Thread is interrupted; it's
-     *         <i>interrupted status</i> will be cleared
-     */
-    synchronized void join(long ms, int ns) throws InterruptedException
-    {
-       // Round up
-       ms += (ns != 0) ? 1 : 0;
-
-       // 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.
-       while(thread.vmThread != null)
-       {
-           // We use the VMThread object to wait on, because this is a private
-           // object, so client code cannot call notify on us.
-           wait(ms);
-           if(ms != 0)
-           {
-               now = System.currentTimeMillis();
-               ms = end - now;
-               if(ms <= 0)
-               {
-                   break;
-               }
-           }
-       }
-    }
-
-    /**
-     * Cause this Thread to stop abnormally and throw the specified exception.
-     * If you stop a Thread that has not yet started, the stop is ignored
-     * (contrary to what the JDK documentation says).
-     * <b>WARNING</b>This bypasses Java security, and can throw a checked
-     * exception which the call stack is unprepared to handle. Do not abuse 
-     * this power.
-     *
-     * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
-     * leave data in bad states.
-     *
-     * <p><b>NOTE</b> stop() should take care not to stop a thread if it is
-     * executing code in this class.
-     *
-     * @param t the Throwable to throw when the Thread dies
-     * @deprecated unsafe operation, try not to use
-     */
-    void stop(Throwable t)
-    {
-       // Note: we assume that we own the lock on thread
-       // (i.e. that Thread.stop() is synchronized)
-       if(running)
-           nativeStop(t);
-       else
-           thread.stillborn = t;
-    }
-
-    /**
-     * Create a native thread on the underlying platform and start it executing
-     * on the run method of this object.
-     * @param stacksize the requested size of the native thread stack
-     */
-    native void start(long stacksize);
-
-    /**
-     * Interrupt this thread.
-     */
-    native void interrupt();
-
-    /**
-     * Determine whether this Thread has been interrupted, but leave
-     * the <i>interrupted status</i> alone in the process.
-     *
-     * @return whether the Thread has been interrupted
-     */
-    native boolean isInterrupted();
-
-    /**
-     * Suspend this Thread.  It will not come back, ever, unless it is resumed.
-     */
-    native void suspend();
-
-    /**
-     * Resume this Thread.  If the thread is not suspended, this method does
-     * nothing.
-     */
-    native void resume();
-
-    /**
-     * Set the priority of the underlying platform thread.
-     *
-     * @param priority the new priority
-     */
-    native void nativeSetPriority(int priority);
-
-    /**
-     * Asynchronously throw the specified throwable in this Thread.
-     *
-     * @param t the exception to throw
-     */
-    native void nativeStop(Throwable t);
-
-    /**
-     * Return the Thread object associated with the currently executing
-     * thread.
-     *
-     * @return the currently executing Thread
-     */
-    static native Thread currentThread();
-
-    /**
-     * Yield to another thread. The Thread will not lose any locks it holds
-     * during this time. There are no guarantees which thread will be
-     * next to run, and it could even be this one, but most VMs will choose
-     * the highest priority thread that has been waiting longest.
-     */
-    static native void yield();
-
-    /**
-     * Suspend the current Thread's execution for the specified amount of
-     * time. The Thread will not lose any locks it has during this time. There
-     * are no guarantees which thread will be next to run, but most VMs will
-     * choose the highest priority thread that has been waiting longest.
-     *
-     * <p>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
-     * not offer that fine a grain of timing resolution. Besides, there is
-     * no guarantee that this thread can start up immediately when time expires,
-     * because some other thread may be active.  So don't expect real-time
-     * performance.
-     *
-     * @param ms the number of milliseconds to sleep.
-     * @param ns the number of extra nanoseconds to sleep (0-999999)
-     * @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;
-       }
-
-      // 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;
-           }
-       }
-    }
-
-    /**
-     * Determine whether the current Thread has been interrupted, and clear
-     * the <i>interrupted status</i> in the process.
-     *
-     * @return whether the current Thread has been interrupted
-     */
-    static native boolean interrupted();
-
-    /**
-     * Checks whether the current thread holds the monitor on a given object.
-     * This allows you to do <code>assert Thread.holdsLock(obj)</code>.
-     *
-     * @param obj the object to check
-     * @return true if the current thread is currently synchronized on obj
-     * @throws NullPointerException if obj is null
-     */
-//     static boolean holdsLock(Object obj) 
-//     {
-//       /* Use obj.notify to check if the current thread holds
-//        * the monitor of the object.
-//        * If it doesn't, notify will throw an exception.
-//        */
-//       try 
-//     {
-//       obj.notify();
-//       // okay, current thread holds lock
-//       return true;
-//     }
-//       catch (IllegalMonitorStateException e)
-//     {
-//       // it doesn't hold the lock
-//       return false;
-//     }
-//     }
-    static native boolean holdsLock(Object obj);
-
-  /**
-   * Returns the current state of the thread.
-   * The value must be one of "BLOCKED", "NEW",
-   * "RUNNABLE", "TERMINATED", "TIMED_WAITING" or
-   * "WAITING".
-   *
-   * @return a string corresponding to one of the 
-   *         thread enumeration states specified above.
-   */
-  native String getState();
-
-}
diff --git a/src/lib/gnu/java/lang/VMThrowable.java b/src/lib/gnu/java/lang/VMThrowable.java
deleted file mode 100644 (file)
index d44c192..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* java.lang.VMThrowable -- VM support methods for Throwable.
-   Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package java.lang;
-
-import gnu.classpath.Pointer;
-
-/**
- * VM dependant state and support methods for Throwable.
- * It is deliberately package local and final and should only be accessed
- * by the Throwable class.
- * <p>
- * This is the GNU Classpath reference implementation, it should be adapted
- * for a specific VM. The reference implementation does nothing.
- *
- * @author Mark Wielaard (mark@klomp.org)
- */
-final class VMThrowable
-{
-  /* IMPORTANT: the rawdata field is not a java object */
-  private final Pointer vmData;
-
-  /**
-   * VM private data.
-   */
-  private transient Object vmdata;
-
-  /**
-   * Private contructor, create VMThrowables with fillInStackTrace();
-   */
-//    private VMThrowable() { }
-  private VMThrowable()
-  {
-    vmData = null;
-  }
-
-  /**
-   * Fill in the stack trace with the current execution stack.
-   * Called by <code>Throwable.fillInStackTrace()</code> to get the state of
-   * the VM. Can return null when the VM does not support caputing the VM
-   * execution state.
-   *
-   * @return a new VMThrowable containing the current execution stack trace.
-   * @see Throwable#fillInStackTrace()
-   */
-  static native VMThrowable fillInStackTrace(Throwable t);
-
-  /**
-   * Returns an <code>StackTraceElement</code> array based on the execution
-   * state of the VM as captured by <code>fillInStackTrace</code>.
-   * Called by <code>Throwable.getStackTrace()</code>.
-   *
-   * @return a non-null but possible zero length array of StackTraceElement.
-   * @see Throwable#getStackTrace()
-   */
-  native StackTraceElement[] getStackTrace(Throwable t);
-}
diff --git a/src/lib/gnu/java/lang/reflect/Constructor.java b/src/lib/gnu/java/lang/reflect/Constructor.java
deleted file mode 100644 (file)
index 0f6e1f0..0000000
+++ /dev/null
@@ -1,462 +0,0 @@
-/* java.lang.reflect.Constructor - reflection of Java constructors
-   Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package java.lang.reflect;
-
-import gnu.java.lang.ClassHelper;
-
-import gnu.java.lang.reflect.MethodSignatureParser;
-
-import java.lang.annotation.Annotation;
-import java.util.Map;
-import java.util.Arrays;
-
-/**
- * The Constructor class represents a constructor of a class. It also allows
- * dynamic creation of an object, via reflection. Invocation on Constructor
- * objects knows how to do widening conversions, but throws
- * {@link IllegalArgumentException} if a narrowing conversion would be
- * necessary. You can query for information on this Constructor regardless
- * of location, but construction access may be limited by Java language
- * access controls. If you can't do it in the compiler, you can't normally
- * do it here either.<p>
- *
- * <B>Note:</B> This class returns and accepts types as Classes, even
- * primitive types; there are Class types defined that represent each
- * different primitive type.  They are <code>java.lang.Boolean.TYPE,
- * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
- * byte.class</code>, etc.  These are not to be confused with the
- * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
- * real classes.<p>
- *
- * Also note that this is not a serializable class.  It is entirely feasible
- * to make it serializable using the Externalizable interface, but this is
- * on Sun, not me.
- *
- * @author John Keiser
- * @author Eric Blake <ebb9@email.byu.edu>
- * @see Member
- * @see Class
- * @see java.lang.Class#getConstructor(Class[])
- * @see java.lang.Class#getDeclaredConstructor(Class[])
- * @see java.lang.Class#getConstructors()
- * @see java.lang.Class#getDeclaredConstructors()
- * @since 1.1
- * @status updated to 1.4
- */
-public final class Constructor<T>
-  extends AccessibleObject
-  implements GenericDeclaration, Member
-{
-  private Class<T> clazz;
-  private int slot;
-
-  /**
-   * Unparsed annotations.
-   */
-  private byte[] annotations = null;
-
-  /**
-   * Unparsed parameter annotations.
-   */
-  private byte[] parameterAnnotations = null;
-  
-  /**
-   * Annotations get parsed the first time they are
-   * accessed and are then cached it this map.
-   */
-  private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations = null;
-  
-  private static final int CONSTRUCTOR_MODIFIERS
-    = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
-  
-  /**
-   * Helper array for creating a new array from a java.util.Container.
-   */
-  private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
-    new Annotation[0];
-
-  /**
-   * This class is uninstantiable except from native code.
-   */
-  private Constructor(Class declaringClass,int slot)
-  {
-    this.clazz = declaringClass;
-    this.slot = slot;
-  }
-
-  private Constructor()
-  {
-  }
-
-  /**
-   * Gets the class that declared this constructor.
-   * @return the class that declared this member
-   */
-  public Class<T> getDeclaringClass()
-  {
-    return clazz;
-  }
-
-  /**
-   * Gets the name of this constructor (the non-qualified name of the class
-   * it was declared in).
-   * @return the name of this constructor
-   */
-  public String getName()
-  {
-    return getDeclaringClass().getName();
-  }
-
-  /**
-   * Return the raw modifiers for this constructor.  In particular
-   * this will include the synthetic and varargs bits.
-   * @return the constructor's modifiers
-   */
-  private native int getModifiersInternal();
-
-  /**
-   * Gets the modifiers this constructor uses.  Use the <code>Modifier</code>
-   * class to interpret the values. A constructor can only have a subset of the
-   * following modifiers: public, private, protected.
-   *
-   * @return an integer representing the modifiers to this Member
-   * @see Modifier
-   */
-  public int getModifiers()
-  {
-    return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
-  }
-
-  /**
-   * Return true if this constructor is synthetic, false otherwise.
-   * A synthetic member is one which is created by the compiler,
-   * and which does not appear in the user's source code.
-   * @since 1.5
-   */
-  public boolean isSynthetic()
-  {
-    return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
-  }
-
-  /**
-   * Return true if this is a varargs constructor, that is if
-   * the constructor takes a variable number of arguments.
-   * @since 1.5
-   */
-  public boolean isVarArgs()
-  {
-    return (getModifiersInternal() & Modifier.VARARGS) != 0;
-  }
-
-  /**
-   * Get the parameter list for this constructor, in declaration order. If the
-   * constructor takes no parameters, returns a 0-length array (not null).
-   *
-   * @return a list of the types of the constructor's parameters
-   */
-  public native Class<?>[] getParameterTypes();
-
-  /**
-   * Get the exception types this constructor says it throws, in no particular
-   * order. If the constructor has no throws clause, returns a 0-length array
-   * (not null).
-   *
-   * @return a list of the types in the constructor's throws clause
-   */
-  public native Class<?>[] getExceptionTypes();
-
-  /**
-   * Compare two objects to see if they are semantically equivalent.
-   * Two Constructors are semantically equivalent if they have the same
-   * declaring class and the same parameter list.  This ignores different
-   * exception clauses, but since you can't create a Method except through the
-   * VM, this is just the == relation.
-   *
-   * @param o the object to compare to
-   * @return <code>true</code> if they are equal; <code>false</code> if not.
-   */
-  public boolean equals(Object o)
-  {
-    if (!(o instanceof Constructor))
-      return false;
-    Constructor that = (Constructor)o; 
-    if (this.getDeclaringClass() != that.getDeclaringClass())
-      return false;
-    if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
-      return false;
-    return true;
-  }
-
-  /**
-   * Get the hash code for the Constructor. The Constructor hash code is the
-   * hash code of the declaring class's name.
-   *
-   * @return the hash code for the object
-   */
-  public int hashCode()
-  {
-    return getDeclaringClass().getName().hashCode();
-  }
-
-  /**
-   * Get a String representation of the Constructor. A Constructor's String
-   * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
-   * throws &lt;exceptions&gt;", where everything after ')' is omitted if
-   * there are no exceptions.<br> Example:
-   * <code>public java.io.FileInputStream(java.lang.Runnable)
-   * throws java.io.FileNotFoundException</code>
-   *
-   * @return the String representation of the Constructor
-   */
-  public String toString()
-  {
-    // 128 is a reasonable buffer initial size for constructor
-    StringBuilder sb = new StringBuilder(128);
-    Modifier.toString(getModifiers(), sb).append(' ');
-    sb.append(getDeclaringClass().getName()).append('(');
-    Class[] c = getParameterTypes();
-    if (c.length > 0)
-      {
-        sb.append(ClassHelper.getUserName(c[0]));
-        for (int i = 1; i < c.length; i++)
-          sb.append(',').append(ClassHelper.getUserName(c[i]));
-      }
-    sb.append(')');
-    c = getExceptionTypes();
-    if (c.length > 0)
-      {
-        sb.append(" throws ").append(c[0].getName());
-        for (int i = 1; i < c.length; i++)
-          sb.append(',').append(c[i].getName());
-      }
-    return sb.toString();
-  }
-
-  static <X extends GenericDeclaration>
-  void addTypeParameters(StringBuilder sb, TypeVariable<X>[] typeArgs)
-  {
-    if (typeArgs.length == 0)
-      return;
-    sb.append('<');
-    for (int i = 0; i < typeArgs.length; ++i)
-      {
-        if (i > 0)
-          sb.append(',');
-        sb.append(typeArgs[i]);
-      }
-    sb.append("> ");
-  }
-
-  public String toGenericString()
-  {
-    StringBuilder sb = new StringBuilder(128);
-    Modifier.toString(getModifiers(), sb).append(' ');
-    addTypeParameters(sb, getTypeParameters());
-    sb.append(getDeclaringClass().getName()).append('(');
-    Type[] types = getGenericParameterTypes();
-    if (types.length > 0)
-      {
-        sb.append(types[0]);
-        for (int i = 1; i < types.length; ++i)
-          sb.append(',').append(types[i]);
-      }
-    sb.append(')');
-    types = getGenericExceptionTypes();
-    if (types.length > 0)
-      {
-        sb.append(" throws ").append(types[0]);
-        for (int i = 1; i < types.length; i++)
-          sb.append(',').append(types[i]);
-      }
-    return sb.toString();
-  }
-
-  /**
-   * Create a new instance by invoking the constructor. Arguments are
-   * automatically unwrapped and widened, if needed.<p>
-   *
-   * If this class is abstract, you will get an
-   * <code>InstantiationException</code>. If the constructor takes 0
-   * arguments, you may use null or a 0-length array for <code>args</code>.<p>
-   *
-   * If this Constructor enforces access control, your runtime context is
-   * evaluated, and you may have an <code>IllegalAccessException</code> if
-   * you could not create this object in similar compiled code. If the class
-   * is uninitialized, you trigger class initialization, which may end in a
-   * <code>ExceptionInInitializerError</code>.<p>
-   *
-   * Then, the constructor is invoked. If it completes normally, the return
-   * value will be the new object. If it completes abruptly, the exception is
-   * wrapped in an <code>InvocationTargetException</code>.
-   *
-   * @param args the arguments to the constructor
-   * @return the newly created object
-   * @throws IllegalAccessException if the constructor could not normally be
-   *         called by the Java code (i.e. it is not public)
-   * @throws IllegalArgumentException if the number of arguments is incorrect;
-   *         or if the arguments types are wrong even with a widening
-   *         conversion
-   * @throws InstantiationException if the class is abstract
-   * @throws InvocationTargetException if the constructor throws an exception
-   * @throws ExceptionInInitializerError if construction triggered class
-   *         initialization, which then failed
-   */
-  public T newInstance(Object... args)
-    throws InstantiationException, IllegalAccessException,
-           InvocationTargetException
-  {
-    return constructNative(args, clazz, slot);
-  }
-
-  private native T constructNative(Object[] args, Class declaringClass,
-                                  int slot)
-    throws InstantiationException, IllegalAccessException,
-           InvocationTargetException;
-
-  /**
-   * Returns an array of <code>TypeVariable</code> objects that represents
-   * the type variables declared by this constructor, in declaration order.
-   * An array of size zero is returned if this constructor has no type
-   * variables.
-   *
-   * @return the type variables associated with this constructor.
-   * @throws GenericSignatureFormatError if the generic signature does
-   *         not conform to the format specified in the Virtual Machine
-   *         specification, version 3.
-   * @since 1.5
-   */
-  public TypeVariable<Constructor<T>>[] getTypeParameters()
-  {
-    String sig = getSignature();
-    if (sig == null)
-      return new TypeVariable[0];
-    MethodSignatureParser p = new MethodSignatureParser(this, sig);
-    return p.getTypeParameters();
-  }
-
-  /**
-   * Return the String in the Signature attribute for this constructor. If there
-   * is no Signature attribute, return null.
-   */
-  private native String getSignature();
-
-  /**
-   * Returns an array of <code>Type</code> objects that represents
-   * the exception types declared by this constructor, in declaration order.
-   * An array of size zero is returned if this constructor declares no
-   * exceptions.
-   *
-   * @return the exception types declared by this constructor. 
-   * @throws GenericSignatureFormatError if the generic signature does
-   *         not conform to the format specified in the Virtual Machine
-   *         specification, version 3.
-   * @since 1.5
-   */
-  public Type[] getGenericExceptionTypes()
-  {
-    String sig = getSignature();
-    if (sig == null)
-      return getExceptionTypes();
-    MethodSignatureParser p = new MethodSignatureParser(this, sig);
-    return p.getGenericExceptionTypes();
-  }
-
-  /**
-   * Returns an array of <code>Type</code> objects that represents
-   * the parameter list for this constructor, in declaration order.
-   * An array of size zero is returned if this constructor takes no
-   * parameters.
-   *
-   * @return a list of the types of the constructor's parameters
-   * @throws GenericSignatureFormatError if the generic signature does
-   *         not conform to the format specified in the Virtual Machine
-   *         specification, version 3.
-   * @since 1.5
-   */
-  public Type[] getGenericParameterTypes()
-  {
-    String sig = getSignature();
-    if (sig == null)
-      return getParameterTypes();
-    MethodSignatureParser p = new MethodSignatureParser(this, sig);
-    return p.getGenericParameterTypes();
-  }
-    
-  /**
-   * @throws NullPointerException {@inheritDoc}
-   * @since 1.5
-   */
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    if (annotationClass == null)
-      throw new NullPointerException();
-
-    return (T)declaredAnnotations().get(annotationClass);
-  }
-
-  /**
-   * @since 1.5
-   */
-  public Annotation[] getDeclaredAnnotations() {
-    return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
-  }
-
-  /**
-   * Parses the annotations if they aren't parsed yet and stores them into
-   * the declaredAnnotations map and return this map.
-   */
-  private synchronized native Map<Class<? extends Annotation>, Annotation> declaredAnnotations();
-  
-  /**
-   * Returns an array of arrays that represent the annotations on the formal
-   * parameters, in declaration order, of the method represented by
-   * this <tt>Method</tt> object. (Returns an array of length zero if the
-   * underlying method is parameterless.  If the method has one or more
-   * parameters, a nested array of length zero is returned for each parameter
-   * with no annotations.) The annotation objects contained in the returned
-   * arrays are serializable.  The caller of this method is free to modify
-   * the returned arrays; it will have no effect on the arrays returned to
-   * other callers.
-   *
-   * @return an array of arrays that represent the annotations on the formal
-   *    parameters, in declaration order, of the method represented by this
-   *    Method object
-   * @since 1.5
-   */
-  public native Annotation[][] getParameterAnnotations();
-}
diff --git a/src/lib/gnu/java/lang/reflect/Field.java b/src/lib/gnu/java/lang/reflect/Field.java
deleted file mode 100644 (file)
index 39856a3..0000000
+++ /dev/null
@@ -1,706 +0,0 @@
-/* java.lang.reflect.Field - reflection of Java fields
-   Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package java.lang.reflect;
-
-import gnu.java.lang.ClassHelper;
-
-import gnu.java.lang.reflect.FieldSignatureParser;
-
-import java.lang.annotation.Annotation;
-import java.util.Map;
-
-
-/**
- * The Field class represents a member variable of a class. It also allows
- * dynamic access to a member, via reflection. This works for both
- * static and instance fields. Operations on Field objects know how to
- * do widening conversions, but throw {@link IllegalArgumentException} if
- * a narrowing conversion would be necessary. You can query for information
- * on this Field regardless of location, but get and set access may be limited
- * by Java language access controls. If you can't do it in the compiler, you
- * can't normally do it here either.<p>
- *
- * <B>Note:</B> This class returns and accepts types as Classes, even
- * primitive types; there are Class types defined that represent each
- * different primitive type.  They are <code>java.lang.Boolean.TYPE,
- * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
- * byte.class</code>, etc.  These are not to be confused with the
- * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
- * real classes.<p>
- *
- * Also note that this is not a serializable class.  It is entirely feasible
- * to make it serializable using the Externalizable interface, but this is
- * on Sun, not me.
- *
- * @author John Keiser
- * @author Eric Blake <ebb9@email.byu.edu>
- * @see Member
- * @see Class
- * @see Class#getField(String)
- * @see Class#getDeclaredField(String)
- * @see Class#getFields()
- * @see Class#getDeclaredFields()
- * @since 1.1
- * @status updated to 1.4
- */
-public final class Field
-extends AccessibleObject implements Member
-{
-  private Class clazz;
-  private String name;
-  private int slot;
-
-  /**
-   * Unparsed annotations.
-   */
-  private byte[] annotations = null;
-
-  /**
-   * Annotations get parsed the first time they are
-   * accessed and are then cached it this map.
-   */
-  private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations = null;
-
-  private static final int FIELD_MODIFIERS
-    = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
-      | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
-      | Modifier.VOLATILE;
-
-  /**
-   * Helper array for creating a new array from a java.util.Container.
-   */
-  private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
-    new Annotation[0];
-
-  /**
-   * This class is uninstantiable except natively.
-   */
-  private Field(Class declaringClass, String name, int slot)
-  {
-    this.clazz = declaringClass;
-    this.name = name;
-    this.slot = slot;
-  }
-
-  /**
-   * Gets the class that declared this field, or the class where this field
-   * is a non-inherited member.
-   * @return the class that declared this member
-   */
-  public Class<?> getDeclaringClass()
-  {
-    return clazz;
-  }
-
-  /**
-   * Gets the name of this field.
-   * @return the name of this field
-   */
-  public String getName()
-  {
-    return name;
-  }
-
-  /**
-   * Return the raw modifiers for this field.
-   * @return the field's modifiers
-   */
-  private native int getModifiersInternal();
-
-  /**
-   * Gets the modifiers this field uses.  Use the <code>Modifier</code>
-   * class to interpret the values.  A field can only have a subset of the
-   * following modifiers: public, private, protected, static, final,
-   * transient, and volatile.
-   *
-   * @return an integer representing the modifiers to this Member
-   * @see Modifier
-   */
-  public int getModifiers()
-  {
-    return getModifiersInternal() & FIELD_MODIFIERS;
-  }
-
-  /**
-   * Return true if this field is synthetic, false otherwise.
-   * @since 1.5
-   */
-  public boolean isSynthetic()
-  {
-    return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
-  }
-
-  /**
-   * Return true if this field represents an enum constant,
-   * false otherwise.
-   * @since 1.5
-   */
-  public boolean isEnumConstant()
-  {
-    return (getModifiersInternal() & Modifier.ENUM) != 0;
-  }
-
-  /**
-   * Gets the type of this field.
-   * @return the type of this field
-   */
-  public native Class<?> getType();
-
-  /**
-   * Compare two objects to see if they are semantically equivalent.
-   * Two Fields are semantically equivalent if they have the same declaring
-   * class, name, and type. Since you can't creat a Field except through
-   * the VM, this is just the == relation.
-   *
-   * @param o the object to compare to
-   * @return <code>true</code> if they are equal; <code>false</code> if not
-   */
-  public boolean equals(Object o)
-  {
-    if (!(o instanceof Field))
-      return false;
-    Field that = (Field)o; 
-    if (this.getDeclaringClass() != that.getDeclaringClass())
-      return false;
-    if (!this.getName().equals(that.getName()))
-      return false;
-    if (this.getType() != that.getType())
-      return false;
-    return true;
-  }
-
-  /**
-   * Get the hash code for the Field. The Field hash code is the hash code
-   * of its name XOR'd with the hash code of its class name.
-   *
-   * @return the hash code for the object.
-   */
-  public int hashCode()
-  {
-    return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
-  }
-
-  /**
-   * Get a String representation of the Field. A Field's String
-   * representation is "&lt;modifiers&gt; &lt;type&gt;
-   * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
-   * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
-   *
-   * @return the String representation of the Field
-   */
-  public String toString()
-  {
-    // 64 is a reasonable buffer initial size for field
-    StringBuilder sb = new StringBuilder(64);
-    Modifier.toString(getModifiers(), sb).append(' ');
-    sb.append(ClassHelper.getUserName(getType())).append(' ');
-    sb.append(getDeclaringClass().getName()).append('.');
-    sb.append(getName());
-    return sb.toString();
-  }
-
-  public String toGenericString()
-  {
-    StringBuilder sb = new StringBuilder(64);
-    Modifier.toString(getModifiers(), sb).append(' ');
-    sb.append(getGenericType()).append(' ');
-    sb.append(getDeclaringClass().getName()).append('.');
-    sb.append(getName());
-    return sb.toString();
-  }
-
-  /**
-   * Get the value of this Field.  If it is primitive, it will be wrapped
-   * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
-   *
-   * If the field is static, <code>o</code> will be ignored. Otherwise, if
-   * <code>o</code> is null, you get a <code>NullPointerException</code>,
-   * and if it is incompatible with the declaring class of the field, you
-   * get an <code>IllegalArgumentException</code>.<p>
-   *
-   * Next, if this Field enforces access control, your runtime context is
-   * evaluated, and you may have an <code>IllegalAccessException</code> if
-   * you could not access this field in similar compiled code. If the field
-   * is static, and its class is uninitialized, you trigger class
-   * initialization, which may end in a
-   * <code>ExceptionInInitializerError</code>.<p>
-   *
-   * Finally, the field is accessed, and primitives are wrapped (but not
-   * necessarily in new objects). This method accesses the field of the
-   * declaring class, even if the instance passed in belongs to a subclass
-   * which declares another field to hide this one.
-   *
-   * @param o the object to get the value of this Field from
-   * @return the value of the Field
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if <code>o</code> is not an instance of
-   *         the class or interface declaring this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #getBoolean(Object)
-   * @see #getByte(Object)
-   * @see #getChar(Object)
-   * @see #getShort(Object)
-   * @see #getInt(Object)
-   * @see #getLong(Object)
-   * @see #getFloat(Object)
-   * @see #getDouble(Object)
-   */
-  public native Object get(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Get the value of this boolean Field. If the field is static,
-   * <code>o</code> will be ignored.
-   *
-   * @param o the object to get the value of this Field from
-   * @return the value of the Field
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a boolean field of
-   *         <code>o</code>, or if <code>o</code> is not an instance of the
-   *         declaring class of this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #get(Object)
-   */
-  public native boolean getBoolean(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Get the value of this byte Field. If the field is static,
-   * <code>o</code> will be ignored.
-   *
-   * @param o the object to get the value of this Field from
-   * @return the value of the Field
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a byte field of
-   *         <code>o</code>, or if <code>o</code> is not an instance of the
-   *         declaring class of this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #get(Object)
-   */
-  public native byte getByte(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Get the value of this Field as a char. If the field is static,
-   * <code>o</code> will be ignored.
-   *
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a char field of
-   *         <code>o</code>, or if <code>o</code> is not an instance
-   *         of the declaring class of this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #get(Object)
-   */
-  public native char getChar(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Get the value of this Field as a short. If the field is static,
-   * <code>o</code> will be ignored.
-   *
-   * @param o the object to get the value of this Field from
-   * @return the value of the Field
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a byte or short
-   *         field of <code>o</code>, or if <code>o</code> is not an instance
-   *         of the declaring class of this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #get(Object)
-   */
-  public native short getShort(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Get the value of this Field as an int. If the field is static,
-   * <code>o</code> will be ignored.
-   *
-   * @param o the object to get the value of this Field from
-   * @return the value of the Field
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a byte, short, char, or
-   *         int field of <code>o</code>, or if <code>o</code> is not an
-   *         instance of the declaring class of this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #get(Object)
-   */
-  public native int getInt(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Get the value of this Field as a long. If the field is static,
-   * <code>o</code> will be ignored.
-   *
-   * @param o the object to get the value of this Field from
-   * @return the value of the Field
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a byte, short, char, int,
-   *         or long field of <code>o</code>, or if <code>o</code> is not an
-   *         instance of the declaring class of this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #get(Object)
-   */
-  public native long getLong(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Get the value of this Field as a float. If the field is static,
-   * <code>o</code> will be ignored.
-   *
-   * @param o the object to get the value of this Field from
-   * @return the value of the Field
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a byte, short, char, int,
-   *         long, or float field of <code>o</code>, or if <code>o</code> is
-   *         not an instance of the declaring class of this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #get(Object)
-   */
-  public native float getFloat(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Get the value of this Field as a double. If the field is static,
-   * <code>o</code> will be ignored.
-   *
-   * @param o the object to get the value of this Field from
-   * @return the value of the Field
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a byte, short, char, int,
-   *         long, float, or double field of <code>o</code>, or if
-   *         <code>o</code> is not an instance of the declaring class of this
-   *         field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #get(Object)
-   */
-  public native double getDouble(Object o)
-    throws IllegalAccessException;
-
-  /**
-   * Set the value of this Field.  If it is a primitive field, the value
-   * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
-   *
-   * If the field is static, <code>o</code> will be ignored. Otherwise, if
-   * <code>o</code> is null, you get a <code>NullPointerException</code>,
-   * and if it is incompatible with the declaring class of the field, you
-   * get an <code>IllegalArgumentException</code>.<p>
-   *
-   * Next, if this Field enforces access control, your runtime context is
-   * evaluated, and you may have an <code>IllegalAccessException</code> if
-   * you could not access this field in similar compiled code. This also
-   * occurs whether or not there is access control if the field is final.
-   * If the field is primitive, and unwrapping your argument fails, you will
-   * get an <code>IllegalArgumentException</code>; likewise, this error
-   * happens if <code>value</code> cannot be cast to the correct object type.
-   * If the field is static, and its class is uninitialized, you trigger class
-   * initialization, which may end in a
-   * <code>ExceptionInInitializerError</code>.<p>
-   *
-   * Finally, the field is set with the widened value. This method accesses
-   * the field of the declaring class, even if the instance passed in belongs
-   * to a subclass which declares another field to hide this one.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if <code>value</code> cannot be
-   *         converted by a widening conversion to the underlying type of
-   *         the Field, or if <code>o</code> is not an instance of the class
-   *         declaring this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #setBoolean(Object, boolean)
-   * @see #setByte(Object, byte)
-   * @see #setChar(Object, char)
-   * @see #setShort(Object, short)
-   * @see #setInt(Object, int)
-   * @see #setLong(Object, long)
-   * @see #setFloat(Object, float)
-   * @see #setDouble(Object, double)
-   */
-  public native void set(Object o, Object value)
-    throws IllegalAccessException;
-
-  /**
-   * Set this boolean Field. If the field is static, <code>o</code> will be
-   * ignored.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a boolean field, or if
-   *         <code>o</code> is not an instance of the class declaring this
-   *         field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #set(Object, Object)
-   */
-  public native void setBoolean(Object o, boolean value)
-    throws IllegalAccessException;
-
-  /**
-   * Set this byte Field. If the field is static, <code>o</code> will be
-   * ignored.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a byte, short, int, long,
-   *         float, or double field, or if <code>o</code> is not an instance
-   *         of the class declaring this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #set(Object, Object)
-   */
-  public native void setByte(Object o, byte value)
-    throws IllegalAccessException;
-
-  /**
-   * Set this char Field. If the field is static, <code>o</code> will be
-   * ignored.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a char, int, long,
-   *         float, or double field, or if <code>o</code> is not an instance
-   *         of the class declaring this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #set(Object, Object)
-   */
-  public native void setChar(Object o, char value)
-    throws IllegalAccessException;
-
-  /**
-   * Set this short Field. If the field is static, <code>o</code> will be
-   * ignored.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a short, int, long,
-   *         float, or double field, or if <code>o</code> is not an instance
-   *         of the class declaring this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #set(Object, Object)
-   */
-  public native void setShort(Object o, short value)
-    throws IllegalAccessException;
-
-  /**
-   * Set this int Field. If the field is static, <code>o</code> will be
-   * ignored.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not an int, long, float, or
-   *         double field, or if <code>o</code> is not an instance of the
-   *         class declaring this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #set(Object, Object)
-   */
-  public native void setInt(Object o, int value)
-    throws IllegalAccessException;
-
-  /**
-   * Set this long Field. If the field is static, <code>o</code> will be
-   * ignored.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a long, float, or double
-   *         field, or if <code>o</code> is not an instance of the class
-   *         declaring this field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #set(Object, Object)
-   */
-  public native void setLong(Object o, long value)
-    throws IllegalAccessException;
-
-  /**
-   * Set this float Field. If the field is static, <code>o</code> will be
-   * ignored.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a float or long field, or
-   *         if <code>o</code> is not an instance of the class declaring this
-   *         field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #set(Object, Object)
-   */
-  public native void setFloat(Object o, float value)
-    throws IllegalAccessException;
-
-  /**
-   * Set this double Field. If the field is static, <code>o</code> will be
-   * ignored.
-   *
-   * @param o the object to set this Field on
-   * @param value the value to set this Field to
-   * @throws IllegalAccessException if you could not normally access this field
-   *         (i.e. it is not public)
-   * @throws IllegalArgumentException if this is not a double field, or if
-   *         <code>o</code> is not an instance of the class declaring this
-   *         field
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static field triggered
-   *         class initialization, which then failed
-   * @see #set(Object, Object)
-   */
-  public native void setDouble(Object o, double value)
-    throws IllegalAccessException;
-
-  /**
-   * Return the generic type of the field. If the field type is not a generic
-   * type, the method returns the same as <code>getType()</code>.
-   *
-   * @throws GenericSignatureFormatError if the generic signature does
-   *         not conform to the format specified in the Virtual Machine
-   *         specification, version 3.
-   * @since 1.5
-   */
-  public Type getGenericType()
-  {
-    String signature = getSignature();
-    if (signature == null)
-      return getType();
-    FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(),
-                                                      signature);
-    return p.getFieldType();
-  }
-
-  /**
-   * Return the String in the Signature attribute for this field. If there
-   * is no Signature attribute, return null.
-   */
-  private native String getSignature();
-
-  /**
-   * @throws NullPointerException {@inheritDoc}
-   * @since 1.5
-   */
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    if (annotationClass == null)
-      throw new NullPointerException();
-
-    return (T)declaredAnnotations().get(annotationClass);
-  }
-
-  /**
-   * @since 1.5
-   */
-  public Annotation[] getDeclaredAnnotations() {
-    return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
-  }
-
-  /**
-   * Parses the annotations if they aren't parsed yet and stores them into
-   * the declaredAnnotations map and return this map.
-   */
-  private synchronized native Map<Class<? extends Annotation>, Annotation> declaredAnnotations();
-}
diff --git a/src/lib/gnu/java/lang/reflect/Method.java b/src/lib/gnu/java/lang/reflect/Method.java
deleted file mode 100644 (file)
index e705cef..0000000
+++ /dev/null
@@ -1,536 +0,0 @@
-/* java.lang.reflect.Method - reflection of Java methods
-   Copyright (C) 1998, 2001, 2002, 2005, 2007 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package java.lang.reflect;
-
-import gnu.java.lang.ClassHelper;
-
-import gnu.java.lang.reflect.MethodSignatureParser;
-
-import java.lang.annotation.Annotation;
-import java.util.Map;
-import java.util.Arrays;
-
-/**
- * The Method class represents a member method of a class. It also allows
- * dynamic invocation, via reflection. This works for both static and
- * instance methods. Invocation on Method objects knows how to do
- * widening conversions, but throws {@link IllegalArgumentException} if
- * a narrowing conversion would be necessary. You can query for information
- * on this Method regardless of location, but invocation access may be limited
- * by Java language access controls. If you can't do it in the compiler, you
- * can't normally do it here either.<p>
- *
- * <B>Note:</B> This class returns and accepts types as Classes, even
- * primitive types; there are Class types defined that represent each
- * different primitive type.  They are <code>java.lang.Boolean.TYPE,
- * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
- * byte.class</code>, etc.  These are not to be confused with the
- * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
- * real classes.<p>
- *
- * Also note that this is not a serializable class.  It is entirely feasible
- * to make it serializable using the Externalizable interface, but this is
- * on Sun, not me.
- *
- * @author John Keiser
- * @author Eric Blake <ebb9@email.byu.edu>
- * @see Member
- * @see Class
- * @see java.lang.Class#getMethod(String,Class[])
- * @see java.lang.Class#getDeclaredMethod(String,Class[])
- * @see java.lang.Class#getMethods()
- * @see java.lang.Class#getDeclaredMethods()
- * @since 1.1
- * @status updated to 1.4
- */
-public final class Method
-extends AccessibleObject implements Member, GenericDeclaration
-{
-  Class clazz;
-  String name;
-  int slot;
-  
-  /**
-   * Unparsed annotations.
-   */
-  private byte[] annotations          = null;
-
-  /**
-   * Unparsed parameter annotations.
-   */
-  private byte[] parameterAnnotations = null;
-  
-  /**
-   * Unparsed annotation default value.
-   */
-  private byte[] annotationDefault    = null;
-
-  /**
-   * Annotations get parsed the first time they are
-   * accessed and are then cached it this map.
-   */
-  private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations = null;
-
-  private static final int METHOD_MODIFIERS
-    = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
-      | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
-      | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
-
-  /**
-   * Helper array for creating a new array from a java.util.Container.
-   */
-  private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
-    new Annotation[0];
-
-  /**
-   * This class is uninstantiable.
-   */
-  private Method(Class declaringClass, String name, int slot)
-  {
-    this.clazz = declaringClass;
-    this.name = name;
-    this.slot = slot;
-  }
-
-  /**
-   * Gets the class that declared this method, or the class where this method
-   * is a non-inherited member.
-   * @return the class that declared this member
-   */
-  public Class<?> getDeclaringClass()
-  {
-    return clazz;
-  }
-
-  /**
-   * Gets the name of this method.
-   * @return the name of this method
-   */
-  public String getName()
-  {
-    return name;
-  }
-
-  /**
-   * Return the raw modifiers for this method.
-   * @return the method's modifiers
-   */
-  private native int getModifiersInternal();
-
-  /**
-   * Gets the modifiers this method uses.  Use the <code>Modifier</code>
-   * class to interpret the values.  A method can only have a subset of the
-   * following modifiers: public, private, protected, abstract, static,
-   * final, synchronized, native, and strictfp.
-   *
-   * @return an integer representing the modifiers to this Member
-   * @see Modifier
-   */
-  public int getModifiers()
-  {
-    return getModifiersInternal() & METHOD_MODIFIERS;
-  }
-
-  /**
-   * Return true if this method is a bridge method.  A bridge method
-   * is generated by the compiler in some situations involving
-   * generics and inheritance.
-   * @since 1.5
-   */
-  public boolean isBridge()
-  {
-    return (getModifiersInternal() & Modifier.BRIDGE) != 0;
-  }
-
-  /**
-   * Return true if this method is synthetic, false otherwise.
-   * @since 1.5
-   */
-  public boolean isSynthetic()
-  {
-    return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
-  }
-
-  /**
-   * Return true if this is a varargs method, that is if
-   * the method takes a variable number of arguments.
-   * @since 1.5
-   */
-  public boolean isVarArgs()
-  {
-    return (getModifiersInternal() & Modifier.VARARGS) != 0;
-  }
-
-  /**
-   * Gets the return type of this method.
-   * @return the type of this method
-   */
-  public native Class<?> getReturnType();
-
-  /**
-   * Get the parameter list for this method, in declaration order. If the
-   * method takes no parameters, returns a 0-length array (not null).
-   *
-   * @return a list of the types of the method's parameters
-   */
-  public native Class<?>[] getParameterTypes();
-
-  /**
-   * Get the exception types this method says it throws, in no particular
-   * order. If the method has no throws clause, returns a 0-length array
-   * (not null).
-   *
-   * @return a list of the types in the method's throws clause
-   */
-  public native Class<?>[] getExceptionTypes();
-
-  /**
-   * Compare two objects to see if they are semantically equivalent.
-   * Two Methods are semantically equivalent if they have the same declaring
-   * class, name, parameter list, and return type.
-   *
-   * @param o the object to compare to
-   * @return <code>true</code> if they are equal; <code>false</code> if not
-   */
-  public boolean equals(Object o)
-  {
-      // Implementation note:
-      // The following is a correct but possibly slow implementation.
-      //
-      // This class has a private field 'slot' that could be used by
-      // the VM implementation to "link" a particular method to a Class.
-      // In that case equals could be simply implemented as:
-      //
-      // if (o instanceof Method)
-      // {
-      //    Method m = (Method)o;
-      //    return m.clazz == this.clazz
-      //           && m.slot == this.slot;
-      // }
-      // return false;
-      //
-      // If a VM uses the Method class as their native/internal representation
-      // then just using the following would be optimal:
-      //
-      // return this == o;
-      //
-    if (!(o instanceof Method))
-      return false;
-    Method that = (Method)o;
-    if (this.getDeclaringClass() != that.getDeclaringClass())
-      return false;
-    if (!this.getName().equals(that.getName()))
-      return false;
-    if (this.getReturnType() != that.getReturnType())
-      return false;
-    if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
-      return false;
-    return true;
-  }
-
-  /**
-   * Get the hash code for the Method. The Method hash code is the hash code
-   * of its name XOR'd with the hash code of its class name.
-   *
-   * @return the hash code for the object
-   */
-  public int hashCode()
-  {
-    return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
-  }
-
-  /**
-   * Get a String representation of the Method. A Method's String
-   * representation is "&lt;modifiers&gt; &lt;returntype&gt;
-   * &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
-   * everything after ')' is omitted if there are no exceptions.<br> Example:
-   * <code>public static int run(java.lang.Runnable,int)</code>
-   *
-   * @return the String representation of the Method
-   */
-  public String toString()
-  {
-    // 128 is a reasonable buffer initial size for constructor
-    StringBuilder sb = new StringBuilder(128);
-    Modifier.toString(getModifiers(), sb).append(' ');
-    sb.append(ClassHelper.getUserName(getReturnType())).append(' ');
-    sb.append(getDeclaringClass().getName()).append('.');
-    sb.append(getName()).append('(');
-    Class[] c = getParameterTypes();
-    if (c.length > 0)
-      {
-        sb.append(ClassHelper.getUserName(c[0]));
-        for (int i = 1; i < c.length; i++)
-          sb.append(',').append(ClassHelper.getUserName(c[i]));
-      }
-    sb.append(')');
-    c = getExceptionTypes();
-    if (c.length > 0)
-      {
-        sb.append(" throws ").append(c[0].getName());
-        for (int i = 1; i < c.length; i++)
-          sb.append(',').append(c[i].getName());
-      }
-    return sb.toString();
-  }
-
-  public String toGenericString()
-  {
-    // 128 is a reasonable buffer initial size for constructor
-    StringBuilder sb = new StringBuilder(128);
-    Modifier.toString(getModifiers(), sb).append(' ');
-    Constructor.addTypeParameters(sb, getTypeParameters());
-    sb.append(getGenericReturnType()).append(' ');
-    sb.append(getDeclaringClass().getName()).append('.');
-    sb.append(getName()).append('(');
-    Type[] types = getGenericParameterTypes();
-    if (types.length > 0)
-      {
-        sb.append(types[0]);
-        for (int i = 1; i < types.length; i++)
-          sb.append(',').append(types[i]);
-      }
-    sb.append(')');
-    types = getGenericExceptionTypes();
-    if (types.length > 0)
-      {
-        sb.append(" throws ").append(types[0]);
-        for (int i = 1; i < types.length; i++)
-          sb.append(',').append(types[i]);
-      }
-    return sb.toString();
-  }
-
-  /**
-   * Invoke the method. Arguments are automatically unwrapped and widened,
-   * and the result is automatically wrapped, if needed.<p>
-   *
-   * If the method is static, <code>o</code> will be ignored. Otherwise,
-   * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
-   * mimic the behavior of nonvirtual lookup (as in super.foo()). This means
-   * you will get a <code>NullPointerException</code> if <code>o</code> is
-   * null, and an <code>IllegalArgumentException</code> if it is incompatible
-   * with the declaring class of the method. If the method takes 0 arguments,
-   * you may use null or a 0-length array for <code>args</code>.<p>
-   *
-   * Next, if this Method enforces access control, your runtime context is
-   * evaluated, and you may have an <code>IllegalAccessException</code> if
-   * you could not acces this method in similar compiled code. If the method
-   * is static, and its class is uninitialized, you trigger class
-   * initialization, which may end in a
-   * <code>ExceptionInInitializerError</code>.<p>
-   *
-   * Finally, the method is invoked. If it completes normally, the return value
-   * will be null for a void method, a wrapped object for a primitive return
-   * method, or the actual return of an Object method. If it completes
-   * abruptly, the exception is wrapped in an
-   * <code>InvocationTargetException</code>.
-   *
-   * @param o the object to invoke the method on
-   * @param args the arguments to the method
-   * @return the return value of the method, wrapped in the appropriate
-   *         wrapper if it is primitive
-   * @throws IllegalAccessException if the method could not normally be called
-   *         by the Java code (i.e. it is not public)
-   * @throws IllegalArgumentException if the number of arguments is incorrect;
-   *         if the arguments types are wrong even with a widening conversion;
-   *         or if <code>o</code> is not an instance of the class or interface
-   *         declaring this method
-   * @throws InvocationTargetException if the method throws an exception
-   * @throws NullPointerException if <code>o</code> is null and this field
-   *         requires an instance
-   * @throws ExceptionInInitializerError if accessing a static method triggered
-   *         class initialization, which then failed
-   */
-  public Object invoke(Object o, Object... args)
-    throws IllegalAccessException, InvocationTargetException
-  {
-    return invokeNative(o, args, clazz, slot);
-  }
-
-  /*
-   * NATIVE HELPERS
-   */
-
-  private native Object invokeNative(Object o, Object[] args,
-                                     Class declaringClass, int slot)
-    throws IllegalAccessException, InvocationTargetException;
-
-  /**
-   * Returns an array of <code>TypeVariable</code> objects that represents
-   * the type variables declared by this constructor, in declaration order.
-   * An array of size zero is returned if this class has no type
-   * variables.
-   *
-   * @return the type variables associated with this class. 
-   * @throws GenericSignatureFormatError if the generic signature does
-   *         not conform to the format specified in the Virtual Machine
-   *         specification, version 3.
-   * @since 1.5
-   */
-  public TypeVariable<Method>[] getTypeParameters()
-  {
-    String sig = getSignature();
-    if (sig == null)
-      return new TypeVariable[0];
-    MethodSignatureParser p = new MethodSignatureParser(this, sig);
-    return p.getTypeParameters();
-  }
-
-  /**
-   * Return the String in the Signature attribute for this method. If there
-   * is no Signature attribute, return null.
-   */
-  private native String getSignature();
-
-  /**
-   * Returns an array of <code>Type</code> objects that represents
-   * the exception types declared by this method, in declaration order.
-   * An array of size zero is returned if this method declares no
-   * exceptions.
-   *
-   * @return the exception types declared by this method. 
-   * @throws GenericSignatureFormatError if the generic signature does
-   *         not conform to the format specified in the Virtual Machine
-   *         specification, version 3.
-   * @since 1.5
-   */
-  public Type[] getGenericExceptionTypes()
-  {
-    String sig = getSignature();
-    if (sig == null)
-      return getExceptionTypes();
-    MethodSignatureParser p = new MethodSignatureParser(this, sig);
-    return p.getGenericExceptionTypes();
-  }
-
-  /**
-   * Returns an array of <code>Type</code> objects that represents
-   * the parameter list for this method, in declaration order.
-   * An array of size zero is returned if this method takes no
-   * parameters.
-   *
-   * @return a list of the types of the method's parameters
-   * @throws GenericSignatureFormatError if the generic signature does
-   *         not conform to the format specified in the Virtual Machine
-   *         specification, version 3.
-   * @since 1.5
-   */
-  public Type[] getGenericParameterTypes()
-  {
-    String sig = getSignature();
-    if (sig == null)
-      return getParameterTypes();
-    MethodSignatureParser p = new MethodSignatureParser(this, sig);
-    return p.getGenericParameterTypes();
-  }
-
-  /**
-   * Returns the return type of this method.
-   *
-   * @return the return type of this method
-   * @throws GenericSignatureFormatError if the generic signature does
-   *         not conform to the format specified in the Virtual Machine
-   *         specification, version 3.
-   * @since 1.5
-   */
-  public Type getGenericReturnType()
-  {
-    String sig = getSignature();
-    if (sig == null)
-      return getReturnType();
-    MethodSignatureParser p = new MethodSignatureParser(this, sig);
-    return p.getGenericReturnType();
-  }
-
-  /**
-   * If this method is an annotation method, returns the default
-   * value for the method.  If there is no default value, or if the
-   * method is not a member of an annotation type, returns null.
-   * Primitive types are wrapped.
-   *
-   * @throws TypeNotPresentException if the method returns a Class,
-   * and the class cannot be found
-   *
-   * @since 1.5
-   */
-  public native Object getDefaultValue();
-  
-  /**
-   * @throws NullPointerException {@inheritDoc}
-   * @since 1.5
-   */
-  public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    if (annotationClass == null)
-      throw new NullPointerException();
-
-    return (T)declaredAnnotations().get(annotationClass);
-  }
-
-  /**
-   * @since 1.5
-   */
-  public Annotation[] getDeclaredAnnotations() {
-    return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
-  }
-
-  /**
-   * Parses the annotations if they aren't parsed yet and stores them into
-   * the declaredAnnotations map and return this map.
-   */
-  private synchronized native Map<Class<? extends Annotation>, Annotation> declaredAnnotations();
-  
-  /**
-   * Returns an array of arrays that represent the annotations on the formal
-   * parameters, in declaration order, of the method represented by
-   * this <tt>Method</tt> object. (Returns an array of length zero if the
-   * underlying method is parameterless.  If the method has one or more
-   * parameters, a nested array of length zero is returned for each parameter
-   * with no annotations.) The annotation objects contained in the returned
-   * arrays are serializable.  The caller of this method is free to modify
-   * the returned arrays; it will have no effect on the arrays returned to
-   * other callers.
-   *
-   * @return an array of arrays that represent the annotations on the formal
-   *    parameters, in declaration order, of the method represented by this
-   *    Method object
-   * @since 1.5
-   */
-  public native Annotation[][] getParameterAnnotations();
-}
diff --git a/src/lib/gnu/java/security/VMAccessController.java b/src/lib/gnu/java/security/VMAccessController.java
deleted file mode 100644 (file)
index 160df10..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/* VMAccessController.java -- VM-specific access controller methods.
-   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package java.security;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-
-final class VMAccessController
-{
-
-  // Fields.
-  // -------------------------------------------------------------------------
-
-  /**
-   * This is a per-thread stack of AccessControlContext objects (which can
-   * be null) for each call to AccessController.doPrivileged in each thread's
-   * call stack. We use this to remember which context object corresponds to
-   * which call.
-   */
-  private static final ThreadLocal contexts = new ThreadLocal();
-
-  /**
-   * This is a Boolean that, if set, tells getContext that it has already
-   * been called once, allowing us to handle recursive permission checks
-   * caused by methods getContext calls.
-   */
-  private static final ThreadLocal inGetContext = new ThreadLocal();
-
-  /**
-   * And we return this all-permissive context to ensure that privileged
-   * methods called from getContext succeed.
-   */
-  private static final AccessControlContext DEFAULT_CONTEXT;
-  static
-  {
-    CodeSource source = new CodeSource(null, null);
-    Permissions permissions = new Permissions();
-    permissions.add(new AllPermission());
-    ProtectionDomain[] domain = new ProtectionDomain[] {
-      new ProtectionDomain(source, permissions)
-    };
-    DEFAULT_CONTEXT = new AccessControlContext(domain);
-  }
-
-  private static final boolean DEBUG = gnu.classpath.Configuration.DEBUG;
-  private static void debug(String msg)
-  {
-    System.err.print(">>> VMAccessController: ");
-    System.err.println(msg);
-  }
-
-  // Constructors.
-  // -------------------------------------------------------------------------
-
-  private VMAccessController() { }
-
-  // Class methods.
-  // -------------------------------------------------------------------------
-
-  /**
-   * Relate a class (which should be an instance of {@link PrivilegedAction}
-   * with an access control context. This method is used by {@link
-   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
-   * to set up the context that will be returned by {@link #getContext()}.
-   * This method relates the class to the current thread, so contexts
-   * pushed from one thread will not be available to another.
-   *
-   * @param acc The access control context.
-   */
-  static void pushContext (AccessControlContext acc)
-  {
-    if (DEBUG)
-      debug("pushing " + acc);
-    LinkedList stack = (LinkedList) contexts.get();
-    if (stack == null)
-      {
-         if (DEBUG)
-           debug("no stack... creating ");
-        stack = new LinkedList();
-        contexts.set(stack);
-      }
-    stack.addFirst(acc);
-  }
-
-  /**
-   * Removes the relation of a class to an {@link AccessControlContext}.
-   * This method is used by {@link AccessController} when exiting from a
-   * call to {@link
-   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
-   */
-  static void popContext()
-  {
-    if (DEBUG)
-      debug("popping context");
-
-    // Stack should never be null, nor should it be empty, if this method
-    // and its counterpart has been called properly.
-    LinkedList stack = (LinkedList) contexts.get();
-    if (stack != null)
-      {
-        stack.removeFirst();
-        if (stack.isEmpty())
-          contexts.set(null);
-      }
-    else if (DEBUG)
-      {
-        debug("no stack during pop?????");
-      }
-  }
-
-  /**
-   * Examine the method stack of the currently running thread, and create
-   * an {@link AccessControlContext} filled in with the appropriate {@link
-   * ProtectionDomain} objects given this stack.
-   *
-   * @return The context.
-   */
-  static AccessControlContext getContext()
-  {
-    // If we are already in getContext, but called a method that needs
-    // a permission check, return the all-permissive context so methods
-    // called from here succeed.
-    //
-    // XXX is this necessary? We should verify if there are any calls in
-    // the stack below this method that require permission checks.
-    Boolean inCall = (Boolean) inGetContext.get();
-    if (inCall != null && inCall.booleanValue())
-      {
-        if (DEBUG)
-          debug("already in getContext");
-        return DEFAULT_CONTEXT;
-      }
-
-    inGetContext.set(Boolean.TRUE);
-
-    Object[][] stack = getStack();
-    Class[] classes = (Class[]) stack[0];
-    String[] methods = (String[]) stack[1];
-
-    if (DEBUG)
-      debug("got trace of length " + classes.length);
-
-    HashSet domains = new HashSet();
-    HashSet seenDomains = new HashSet();
-    AccessControlContext context = null;
-    int privileged = 0;
-
-    // We walk down the stack, adding each ProtectionDomain for each
-    // class in the call stack. If we reach a call to doPrivileged,
-    // we don't add any more stack frames. We skip the first three stack
-    // frames, since they comprise the calls to getStack, getContext,
-    // and AccessController.getContext.
-    for (int i = 3; i < classes.length && privileged < 2; i++)
-      {
-        Class clazz = classes[i];
-        String method = methods[i];
-
-        if (DEBUG)
-          {
-            debug("checking " + clazz + "." + method);
-            // subject to getClassLoader RuntimePermission
-            debug("loader = " + clazz.getClassLoader());
-          }
-
-        // If the previous frame was a call to doPrivileged, then this is
-        // the last frame we look at.
-        if (privileged == 1)
-          privileged = 2;
-
-        if (clazz.equals (AccessController.class)
-            && method.equals ("doPrivileged"))
-          {
-            // If there was a call to doPrivileged with a supplied context,
-            // return that context. If using JAAS doAs*, it should be 
-           // a context with a SubjectDomainCombiner
-            LinkedList l = (LinkedList) contexts.get();
-            if (l != null)
-              context = (AccessControlContext) l.getFirst();
-            privileged = 1;
-          }
-
-        // subject to getProtectionDomain RuntimePermission
-       ProtectionDomain domain = clazz.getProtectionDomain();
-
-        if (domain == null)
-          continue;
-        if (seenDomains.contains(domain))
-          continue;
-        seenDomains.add(domain);
-
-        // Create a static snapshot of this domain, which may change over time
-        // if the current policy changes.
-        domains.add(new ProtectionDomain(domain.getCodeSource(),
-                                         domain.getPermissions()));
-      }
-
-    if (DEBUG)
-      debug("created domains: " + domains);
-
-    ProtectionDomain[] result = (ProtectionDomain[])
-      domains.toArray(new ProtectionDomain[domains.size()]);
-
-    if (context != null)
-      {
-        DomainCombiner dc = context.getDomainCombiner ();
-        // If the supplied context had no explicit DomainCombiner, use
-        // our private version, which computes the intersection of the
-        // context's domains with the derived set.
-        if (dc == null)
-          context = new AccessControlContext
-            (IntersectingDomainCombiner.SINGLETON.combine
-             (result, context.getProtectionDomains ()));
-        // Use the supplied DomainCombiner. This should be secure,
-        // because only trusted code may create an
-        // AccessControlContext with a custom DomainCombiner.
-        else
-          context = new AccessControlContext (result, context, dc);
-      }
-    // No context was supplied. Return the derived one.
-    else
-      context = new AccessControlContext (result);
-
-    inGetContext.set(Boolean.FALSE);
-    return context;
-  }
-
-  /**
-   * Returns a snapshot of the current call stack as a pair of arrays:
-   * the first an array of classes in the call stack, the second an array
-   * of strings containing the method names in the call stack. The two
-   * arrays match up, meaning that method <i>i</i> is declared in class
-   * <i>i</i>. The arrays are clean; it will only contain Java methods,
-   * and no element of the list should be null.
-   *
-   * <p>The default implementation returns an empty stack, which will be
-   * interpreted as having no permissions whatsoever.
-   *
-   * @return A pair of arrays describing the current call stack. The first
-   *    element is an array of Class objects, and the second is an array
-   *    of Strings comprising the method names.
-   */
-//    private static Object[][] getStack()
-//    {
-//      return new Object[][] { new Class[0], new String[0] };
-//    }
-  private native static Object[][] getStack();
-}
diff --git a/src/lib/gnu/sun/misc/Unsafe.java b/src/lib/gnu/sun/misc/Unsafe.java
deleted file mode 100644 (file)
index 2ab3d7d..0000000
+++ /dev/null
@@ -1,985 +0,0 @@
-/*
- * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.misc;
-
-import java.security.*;
-import java.lang.reflect.*;
-
-
-/**
- * A collection of methods for performing low-level, unsafe operations.
- * Although the class and all methods are public, use of this class is
- * limited because only trusted code can obtain instances of it.
- *
- * @author John R. Rose
- * @version  1.28, 07/06/04
- * @see #getUnsafe
- */
-
-public final class Unsafe {
-
-    private static native void registerNatives();
-    static {
-        registerNatives();
-//     sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
-    }
-
-    private Unsafe() {}
-
-    private static final Unsafe theUnsafe = new Unsafe();
-
-    /**
-     * Provides the caller with the capability of performing unsafe
-     * operations.
-     * 
-     * <p> The returned <code>Unsafe</code> object should be carefully guarded
-     * by the caller, since it can be used to read and write data at arbitrary
-     * memory addresses.  It must never be passed to untrusted code.
-     * 
-     * <p> Most methods in this class are very low-level, and correspond to a
-     * small number of hardware instructions (on typical machines).  Compilers
-     * are encouraged to optimize these methods accordingly.
-     * 
-     * <p> Here is a suggested idiom for using unsafe operations:
-     * 
-     * <blockquote><pre>
-     * class MyTrustedClass {
-     *   private static final Unsafe unsafe = Unsafe.getUnsafe();
-     *   ...
-     *   private long myCountAddress = ...;
-     *   public int getCount() { return unsafe.getByte(myCountAddress); }
-     * }
-     * </pre></blockquote>
-     *
-     * (It may assist compilers to make the local variable be
-     * <code>final</code>.)
-     *
-     * @exception  SecurityException  if a security manager exists and its  
-     *             <code>checkPropertiesAccess</code> method doesn't allow
-     *             access to the system properties.
-     */
-    public static Unsafe getUnsafe() {
-       Class cc = sun.reflect.Reflection.getCallerClass(2);
-       if (cc.getClassLoader() != null)
-           throw new SecurityException("Unsafe");
-       return theUnsafe;
-    }
-
-    /// peek and poke operations
-    /// (compilers should optimize these to memory ops)
-
-    // These work on object fields in the Java heap.
-    // They will not work on elements of packed arrays.
-
-    /**
-     * Fetches a value from a given Java variable.
-     * More specifically, fetches a field or array element within the given
-     * object <code>o</code> at the given offset, or (if <code>o</code> is
-     * null) from the memory address whose numerical value is the given
-     * offset.
-     * <p>
-     * The results are undefined unless one of the following cases is true:
-     * <ul>
-     * <li>The offset was obtained from {@link #objectFieldOffset} on
-     * the {@link java.lang.reflect.Field} of some Java field and the object
-     * referred to by <code>o</code> is of a class compatible with that
-     * field's class.
-     *
-     * <li>The offset and object reference <code>o</code> (either null or
-     * non-null) were both obtained via {@link #staticFieldOffset}
-     * and {@link #staticFieldBase} (respectively) from the
-     * reflective {@link Field} representation of some Java field.
-     *
-     * <li>The object referred to by <code>o</code> is an array, and the offset
-     * is an integer of the form <code>B+N*S</code>, where <code>N</code> is
-     * a valid index into the array, and <code>B</code> and <code>S</code> are
-     * the values obtained by {@link #arrayBaseOffset} and {@link
-     * #arrayIndexScale} (respectively) from the array's class.  The value
-     * referred to is the <code>N</code><em>th</em> element of the array.
-     *
-     * </ul>
-     * <p>
-     * If one of the above cases is true, the call references a specific Java
-     * variable (field or array element).  However, the results are undefined
-     * if that variable is not in fact of the type returned by this method.
-     * <p>
-     * This method refers to a variable by means of two parameters, and so
-     * it provides (in effect) a <em>double-register</em> addressing mode
-     * for Java variables.  When the object reference is null, this method
-     * uses its offset as an absolute address.  This is similar in operation
-     * to methods such as {@link #getInt(long)}, which provide (in effect) a
-     * <em>single-register</em> addressing mode for non-Java variables.
-     * However, because Java variables may have a different layout in memory
-     * from non-Java variables, programmers should not assume that these
-     * two addressing modes are ever equivalent.  Also, programmers should
-     * remember that offsets from the double-register addressing mode cannot
-     * be portably confused with longs used in the single-register addressing
-     * mode.
-     *
-     * @param o Java heap object in which the variable resides, if any, else
-     *        null
-     * @param offset indication of where the variable resides in a Java heap
-     *        object, if any, else a memory address locating the variable
-     *        statically
-     * @return the value fetched from the indicated Java variable
-     * @throws RuntimeException No defined exceptions are thrown, not even
-     *         {@link NullPointerException}
-     */
-    public native int getInt(Object o, long offset);
-
-    /**
-     * Stores a value into a given Java variable.
-     * <p>
-     * The first two parameters are interpreted exactly as with
-     * {@link #getInt(Object, long)} to refer to a specific
-     * Java variable (field or array element).  The given value
-     * is stored into that variable.
-     * <p>
-     * The variable must be of the same type as the method
-     * parameter <code>x</code>.
-     *
-     * @param o Java heap object in which the variable resides, if any, else
-     *        null
-     * @param offset indication of where the variable resides in a Java heap
-     *        object, if any, else a memory address locating the variable
-     *        statically
-     * @param x the value to store into the indicated Java variable
-     * @throws RuntimeException No defined exceptions are thrown, not even
-     *         {@link NullPointerException}
-     */
-    public native void putInt(Object o, long offset, int x);
-
-    /**
-     * Fetches a reference value from a given Java variable.
-     * @see #getInt(Object, long)
-     */
-    public native Object getObject(Object o, long offset);
-
-    /**
-     * Stores a reference value into a given Java variable.
-     * <p>
-     * Unless the reference <code>x</code> being stored is either null
-     * or matches the field type, the results are undefined.
-     * If the reference <code>o</code> is non-null, car marks or
-     * other store barriers for that object (if the VM requires them)
-     * are updated.
-     * @see #putInt(Object, int, int)
-     */
-    public native void putObject(Object o, long offset, Object x);
-
-    /** @see #getInt(Object, long) */
-    public native boolean getBoolean(Object o, long offset);
-    /** @see #putInt(Object, int, int) */
-    public native void    putBoolean(Object o, long offset, boolean x);
-    /** @see #getInt(Object, long) */
-    public native byte    getByte(Object o, long offset);
-    /** @see #putInt(Object, int, int) */
-    public native void    putByte(Object o, long offset, byte x);
-    /** @see #getInt(Object, long) */
-    public native short   getShort(Object o, long offset);
-    /** @see #putInt(Object, int, int) */
-    public native void    putShort(Object o, long offset, short x);
-    /** @see #getInt(Object, long) */
-    public native char    getChar(Object o, long offset);
-    /** @see #putInt(Object, int, int) */
-    public native void    putChar(Object o, long offset, char x);
-    /** @see #getInt(Object, long) */
-    public native long    getLong(Object o, long offset);
-    /** @see #putInt(Object, int, int) */
-    public native void    putLong(Object o, long offset, long x);
-    /** @see #getInt(Object, long) */
-    public native float   getFloat(Object o, long offset);
-    /** @see #putInt(Object, int, int) */
-    public native void    putFloat(Object o, long offset, float x);
-    /** @see #getInt(Object, long) */
-    public native double  getDouble(Object o, long offset);
-    /** @see #putInt(Object, int, int) */
-    public native void    putDouble(Object o, long offset, double x);
-
-    /**
-     * This method, like all others with 32-bit offsets, was native
-     * in a previous release but is now a wrapper which simply casts
-     * the offset to a long value.  It provides backward compatibility
-     * with bytecodes compiled against 1.4.
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public int getInt(Object o, int offset) {
-       return getInt(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putInt(Object o, int offset, int x) {
-       putInt(o, (long)offset, x);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public Object getObject(Object o, int offset) {
-       return getObject(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putObject(Object o, int offset, Object x) {
-       putObject(o, (long)offset, x);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public boolean getBoolean(Object o, int offset) {
-       return getBoolean(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putBoolean(Object o, int offset, boolean x) {
-       putBoolean(o, (long)offset, x);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public byte getByte(Object o, int offset) {
-       return getByte(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putByte(Object o, int offset, byte x) {
-       putByte(o, (long)offset, x);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public short getShort(Object o, int offset) {
-       return getShort(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putShort(Object o, int offset, short x) {
-       putShort(o, (long)offset, x);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public char getChar(Object o, int offset) {
-       return getChar(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putChar(Object o, int offset, char x) {
-       putChar(o, (long)offset, x);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public long getLong(Object o, int offset) {
-       return getLong(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putLong(Object o, int offset, long x) {
-       putLong(o, (long)offset, x);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public float getFloat(Object o, int offset) {
-       return getFloat(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putFloat(Object o, int offset, float x) {
-       putFloat(o, (long)offset, x);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public double getDouble(Object o, int offset) {
-       return getDouble(o, (long)offset);
-    }
-
-    /**
-     * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long.
-     * See {@link #staticFieldOffset}.
-     */
-    @Deprecated
-    public void putDouble(Object o, int offset, double x) {
-       putDouble(o, (long)offset, x);
-    }
-
-    // These work on values in the C heap.
-
-    /**
-     * Fetches a value from a given memory address.  If the address is zero, or
-     * does not point into a block obtained from {@link #allocateMemory}, the
-     * results are undefined.
-     * 
-     * @see #allocateMemory
-     */
-    public native byte    getByte(long address);
-
-    /**
-     * Stores a value into a given memory address.  If the address is zero, or
-     * does not point into a block obtained from {@link #allocateMemory}, the
-     * results are undefined.
-     * 
-     * @see #getByte(long)
-     */
-    public native void    putByte(long address, byte x);
-
-    /** @see #getByte(long) */
-    public native short   getShort(long address);
-    /** @see #putByte(long, byte) */
-    public native void    putShort(long address, short x);
-    /** @see #getByte(long) */
-    public native char    getChar(long address);
-    /** @see #putByte(long, byte) */
-    public native void    putChar(long address, char x);
-    /** @see #getByte(long) */
-    public native int     getInt(long address);
-    /** @see #putByte(long, byte) */
-    public native void    putInt(long address, int x);
-    /** @see #getByte(long) */
-    public native long    getLong(long address);
-    /** @see #putByte(long, byte) */
-    public native void    putLong(long address, long x);
-    /** @see #getByte(long) */
-    public native float   getFloat(long address);
-    /** @see #putByte(long, byte) */
-    public native void    putFloat(long address, float x);
-    /** @see #getByte(long) */
-    public native double  getDouble(long address);
-    /** @see #putByte(long, byte) */
-    public native void    putDouble(long address, double x);
-
-    /**
-     * Fetches a native pointer from a given memory address.  If the address is
-     * zero, or does not point into a block obtained from {@link
-     * #allocateMemory}, the results are undefined.
-     *
-     * <p> If the native pointer is less than 64 bits wide, it is extended as
-     * an unsigned number to a Java long.  The pointer may be indexed by any
-     * given byte offset, simply by adding that offset (as a simple integer) to
-     * the long representing the pointer.  The number of bytes actually read
-     * from the target address maybe determined by consulting {@link
-     * #addressSize}.
-     *
-     * @see #allocateMemory
-     */
-    public native long getAddress(long address);
-
-    /**
-     * Stores a native pointer into a given memory address.  If the address is
-     * zero, or does not point into a block obtained from {@link
-     * #allocateMemory}, the results are undefined.
-     *
-     * <p> The number of bytes actually written at the target address maybe
-     * determined by consulting {@link #addressSize}.
-     * 
-     * @see #getAddress(long)
-     */
-    public native void putAddress(long address, long x);
-
-    /// wrappers for malloc, realloc, free:
-
-    /**
-     * Allocates a new block of native memory, of the given size in bytes.  The
-     * contents of the memory are uninitialized; they will generally be
-     * garbage.  The resulting native pointer will never be zero, and will be
-     * aligned for all value types.  Dispose of this memory by calling {@link
-     * #freeMemory}, or resize it with {@link #reallocateMemory}.
-     * 
-     * @throws IllegalArgumentException if the size is negative or too large
-     *         for the native size_t type
-     * 
-     * @throws OutOfMemoryError if the allocation is refused by the system
-     * 
-     * @see #getByte(long)
-     * @see #putByte(long, byte)
-     */
-    public native long allocateMemory(long bytes);
-
-    /**
-     * Resizes a new block of native memory, to the given size in bytes.  The
-     * contents of the new block past the size of the old block are
-     * uninitialized; they will generally be garbage.  The resulting native
-     * pointer will be zero if and only if the requested size is zero.  The
-     * resulting native pointer will be aligned for all value types.  Dispose
-     * of this memory by calling {@link #freeMemory}, or resize it with {@link
-     * #reallocateMemory}.  The address passed to this method may be null, in
-     * which case an allocation will be performed.
-     *
-     * @throws IllegalArgumentException if the size is negative or too large
-     *         for the native size_t type
-     * 
-     * @throws OutOfMemoryError if the allocation is refused by the system
-     * 
-     * @see #allocateMemory
-     */
-    public native long reallocateMemory(long address, long bytes);
-
-    /**
-     * Sets all bytes in a given block of memory to a fixed value
-     * (usually zero).
-     *
-     * <p>This method determines a block's base address by means of two parameters,
-     * and so it provides (in effect) a <em>double-register</em> addressing mode,
-     * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
-     * the offset supplies an absolute base address.
-     *
-     * <p>The stores are in coherent (atomic) units of a size determined
-     * by the address and length parameters.  If the effective address and
-     * length are all even modulo 8, the stores take place in 'long' units.
-     * If the effective address and length are (resp.) even modulo 4 or 2,
-     * the stores take place in units of 'int' or 'short'.
-     * 
-     * @since 1.7
-     */
-    public native void setMemory(Object o, long offset, long bytes, byte value);
-
-    /**
-     * Sets all bytes in a given block of memory to a fixed value
-     * (usually zero).  This provides a <em>single-register</em> addressing mode,
-     * as discussed in {@link #getInt(Object,long)}.
-     *
-     * <p>Equivalent to <code>setMemory(null, address, bytes, value)</code>.
-     */
-    public void setMemory(long address, long bytes, byte value) {
-        setMemory(null, address, bytes, value);
-    }
-
-    /**
-     * Sets all bytes in a given block of memory to a copy of another
-     * block.
-     *
-     * <p>This method determines each block's base address by means of two parameters,
-     * and so it provides (in effect) a <em>double-register</em> addressing mode,
-     * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
-     * the offset supplies an absolute base address.
-     *
-     * <p>The transfers are in coherent (atomic) units of a size determined
-     * by the address and length parameters.  If the effective addresses and
-     * length are all even modulo 8, the transfer takes place in 'long' units.
-     * If the effective addresses and length are (resp.) even modulo 4 or 2,
-     * the transfer takes place in units of 'int' or 'short'.
-     * 
-     * @since 1.7
-     */
-    public native void copyMemory(Object srcBase, long srcOffset,
-                                  Object destBase, long destOffset,
-                                 long bytes);
-    /**
-     * Sets all bytes in a given block of memory to a copy of another
-     * block.  This provides a <em>single-register</em> addressing mode,
-     * as discussed in {@link #getInt(Object,long)}.
-     *
-     * Equivalent to <code>copyMemory(null, srcAddress, null, destAddress, bytes)</code>.
-     */
-    public void copyMemory(long srcAddress, long destAddress, long bytes) {
-        copyMemory(null, srcAddress, null, destAddress, bytes);
-    }
-
-    /**
-     * Disposes of a block of native memory, as obtained from {@link
-     * #allocateMemory} or {@link #reallocateMemory}.  The address passed to
-     * this method may be null, in which case no action is taken.
-     *
-     * @see #allocateMemory
-     */
-    public native void freeMemory(long address);
-
-    /// random queries
-
-    /**
-     * This constant differs from all results that will ever be returned from
-     * {@link #staticFieldOffset}, {@link #objectFieldOffset},
-     * or {@link #arrayBaseOffset}.
-     */
-    public static final int INVALID_FIELD_OFFSET   = -1;
-
-    /**
-     * Returns the offset of a field, truncated to 32 bits.
-     * This method is implemented as follows:
-     * <blockquote><pre>
-     * public int fieldOffset(Field f) {
-     *     if (Modifier.isStatic(f.getModifiers()))
-     *         return (int) staticFieldOffset(f);
-     *     else
-     *         return (int) objectFieldOffset(f);
-     * }
-     * </pre></blockquote>
-     * @deprecated As of 1.4.1, use {@link #staticFieldOffset} for static
-     * fields and {@link #objectFieldOffset} for non-static fields.
-     */
-    @Deprecated
-    public int fieldOffset(Field f) {
-        if (Modifier.isStatic(f.getModifiers()))
-           return (int) staticFieldOffset(f);
-       else
-           return (int) objectFieldOffset(f);
-    }
-
-    /**
-     * Returns the base address for accessing some static field
-     * in the given class.  This method is implemented as follows:
-     * <blockquote><pre>
-     * public Object staticFieldBase(Class c) {
-     *     Field[] fields = c.getDeclaredFields();
-     *     for (int i = 0; i < fields.length; i++) {
-     *         if (Modifier.isStatic(fields[i].getModifiers())) {
-     *             return staticFieldBase(fields[i]);
-     *         }
-     *     }
-     *     return null;
-     * }
-     * </pre></blockquote>
-     * @deprecated As of 1.4.1, use {@link #staticFieldBase(Field)}
-     * to obtain the base pertaining to a specific {@link Field}.
-     * This method works only for JVMs which store all statics
-     * for a given class in one place.
-     */
-    @Deprecated
-    public Object staticFieldBase(Class c) {
-       Field[] fields = c.getDeclaredFields();
-       for (int i = 0; i < fields.length; i++) {
-           if (Modifier.isStatic(fields[i].getModifiers())) {
-               return staticFieldBase(fields[i]);
-           }
-       }
-       return null;
-    }
-
-    /**
-     * Report the location of a given field in the storage allocation of its
-     * class.  Do not expect to perform any sort of arithmetic on this offset;
-     * it is just a cookie which is passed to the unsafe heap memory accessors.
-     *
-     * <p>Any given field will always have the same offset and base, and no
-     * two distinct fields of the same class will ever have the same offset
-     * and base.
-     *
-     * <p>As of 1.4.1, offsets for fields are represented as long values,
-     * although the Sun JVM does not use the most significant 32 bits.
-     * However, JVM implementations which store static fields at absolute
-     * addresses can use long offsets and null base pointers to express
-     * the field locations in a form usable by {@link #getInt(Object,long)}.
-     * Therefore, code which will be ported to such JVMs on 64-bit platforms
-     * must preserve all bits of static field offsets.
-     * @see #getInt(Object, long)
-     */
-    public native long staticFieldOffset(Field f);
-
-    /**
-     * Report the location of a given static field, in conjunction with {@link
-     * #staticFieldBase}.
-     * <p>Do not expect to perform any sort of arithmetic on this offset;
-     * it is just a cookie which is passed to the unsafe heap memory accessors.
-     *
-     * <p>Any given field will always have the same offset, and no two distinct
-     * fields of the same class will ever have the same offset.
-     *
-     * <p>As of 1.4.1, offsets for fields are represented as long values,
-     * although the Sun JVM does not use the most significant 32 bits.
-     * It is hard to imagine a JVM technology which needs more than
-     * a few bits to encode an offset within a non-array object,
-     * However, for consistency with other methods in this class,
-     * this method reports its result as a long value.
-     * @see #getInt(Object, long)
-     */
-    public native long objectFieldOffset(Field f);
-
-    /**
-     * Report the location of a given static field, in conjunction with {@link
-     * #staticFieldOffset}.
-     * <p>Fetch the base "Object", if any, with which static fields of the
-     * given class can be accessed via methods like {@link #getInt(Object,
-     * long)}.  This value may be null.  This value may refer to an object
-     * which is a "cookie", not guaranteed to be a real Object, and it should
-     * not be used in any way except as argument to the get and put routines in
-     * this class.
-     */
-    public native Object staticFieldBase(Field f);
-
-    /**
-     * Ensure the given class has been initialized. This is often
-     * needed in conjunction with obtaining the static field base of a
-     * class.
-     */
-    public native void ensureClassInitialized(Class c);
-
-    /**
-     * Report the offset of the first element in the storage allocation of a
-     * given array class.  If {@link #arrayIndexScale} returns a non-zero value
-     * for the same class, you may use that scale factor, together with this
-     * base offset, to form new offsets to access elements of arrays of the
-     * given class.
-     *
-     * @see #getInt(Object, long)
-     * @see #putInt(Object, long, int)
-     */
-    public native int arrayBaseOffset(Class arrayClass);
-
-    /** The value of {@code arrayBaseOffset(boolean[].class)} */
-    public static final int ARRAY_BOOLEAN_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(boolean[].class);
-
-    /** The value of {@code arrayBaseOffset(byte[].class)} */
-    public static final int ARRAY_BYTE_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(byte[].class);
-
-    /** The value of {@code arrayBaseOffset(short[].class)} */
-    public static final int ARRAY_SHORT_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(short[].class);
-
-    /** The value of {@code arrayBaseOffset(char[].class)} */
-    public static final int ARRAY_CHAR_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(char[].class);
-
-    /** The value of {@code arrayBaseOffset(int[].class)} */
-    public static final int ARRAY_INT_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(int[].class);
-
-    /** The value of {@code arrayBaseOffset(long[].class)} */
-    public static final int ARRAY_LONG_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(long[].class);
-
-    /** The value of {@code arrayBaseOffset(float[].class)} */
-    public static final int ARRAY_FLOAT_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(float[].class);
-
-    /** The value of {@code arrayBaseOffset(double[].class)} */
-    public static final int ARRAY_DOUBLE_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(double[].class);
-
-    /** The value of {@code arrayBaseOffset(Object[].class)} */
-    public static final int ARRAY_OBJECT_BASE_OFFSET
-           = theUnsafe.arrayBaseOffset(Object[].class);
-
-    /**
-     * Report the scale factor for addressing elements in the storage
-     * allocation of a given array class.  However, arrays of "narrow" types
-     * will generally not work properly with accessors like {@link
-     * #getByte(Object, int)}, so the scale factor for such classes is reported
-     * as zero.
-     * 
-     * @see #arrayBaseOffset
-     * @see #getInt(Object, long)
-     * @see #putInt(Object, long, int)
-     */
-    public native int arrayIndexScale(Class arrayClass);
-
-    /** The value of {@code arrayIndexScale(boolean[].class)} */
-    public static final int ARRAY_BOOLEAN_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(boolean[].class);
-
-    /** The value of {@code arrayIndexScale(byte[].class)} */
-    public static final int ARRAY_BYTE_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(byte[].class);
-
-    /** The value of {@code arrayIndexScale(short[].class)} */
-    public static final int ARRAY_SHORT_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(short[].class);
-
-    /** The value of {@code arrayIndexScale(char[].class)} */
-    public static final int ARRAY_CHAR_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(char[].class);
-
-    /** The value of {@code arrayIndexScale(int[].class)} */
-    public static final int ARRAY_INT_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(int[].class);
-
-    /** The value of {@code arrayIndexScale(long[].class)} */
-    public static final int ARRAY_LONG_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(long[].class);
-
-    /** The value of {@code arrayIndexScale(float[].class)} */
-    public static final int ARRAY_FLOAT_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(float[].class);
-
-    /** The value of {@code arrayIndexScale(double[].class)} */
-    public static final int ARRAY_DOUBLE_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(double[].class);
-
-    /** The value of {@code arrayIndexScale(Object[].class)} */
-    public static final int ARRAY_OBJECT_INDEX_SCALE
-           = theUnsafe.arrayIndexScale(Object[].class);
-
-    /**
-     * Report the size in bytes of a native pointer, as stored via {@link
-     * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
-     * other primitive types (as stored in native memory blocks) is determined
-     * fully by their information content.
-     */
-    public native int addressSize();
-
-    /** The value of {@code addressSize()} */
-    public static final int ADDRESS_SIZE = theUnsafe.addressSize();
-
-    /**
-     * Report the size in bytes of a native memory page (whatever that is).
-     * This value will always be a power of two.
-     */
-    public native int pageSize();
-
-
-    /// random trusted operations from JNI:
-
-    /**
-     * Tell the VM to define a class, without security checks.  By default, the
-     * class loader and protection domain come from the caller's class.
-     */
-    public native Class defineClass(String name, byte[] b, int off, int len,
-                                   ClassLoader loader,
-                                   ProtectionDomain protectionDomain);
-
-    public native Class defineClass(String name, byte[] b, int off, int len);
-
-    /** Allocate an instance but do not run any constructor.
-        Initializes the class if it has not yet been. */
-    public native Object allocateInstance(Class cls)
-       throws InstantiationException;
-
-    /** Lock the object.  It must get unlocked via {@link #monitorExit}. */
-    public native void monitorEnter(Object o);
-
-    /**
-     * Unlock the object.  It must have been locked via {@link
-     * #monitorEnter}.
-     */
-    public native void monitorExit(Object o);
-
-    /**
-     * Tries to lock the object.  Returns true or false to indicate
-     * whether the lock succeeded.  If it did, the object must be
-     * unlocked via {@link #monitorExit}.
-     */
-    public native boolean tryMonitorEnter(Object o);
-
-    /** Throw the exception without telling the verifier. */
-    public native void throwException(Throwable ee);
-
-
-    /**
-     * Atomically update Java variable to <tt>x</tt> if it is currently
-     * holding <tt>expected</tt>.
-     * @return <tt>true</tt> if successful
-     */
-    public final native boolean compareAndSwapObject(Object o, long offset,
-                                                     Object expected,
-                                                     Object x);
-  
-    /**
-     * Atomically update Java variable to <tt>x</tt> if it is currently
-     * holding <tt>expected</tt>.
-     * @return <tt>true</tt> if successful
-     */
-    public final native boolean compareAndSwapInt(Object o, long offset,
-                                                  int expected,
-                                                  int x);
-
-    /**
-     * Atomically update Java variable to <tt>x</tt> if it is currently
-     * holding <tt>expected</tt>.
-     * @return <tt>true</tt> if successful
-     */
-    public final native boolean compareAndSwapLong(Object o, long offset,
-                                                   long expected,
-                                                   long x);
-
-    /**
-     * Fetches a reference value from a given Java variable, with volatile 
-     * load semantics. Otherwise identical to {@link #getObject(Object, long)}
-     */
-    public native Object getObjectVolatile(Object o, long offset);
-
-    /**
-     * Stores a reference value into a given Java variable, with 
-     * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)}
-     */
-    public native void    putObjectVolatile(Object o, long offset, Object x);
-
-    /** Volatile version of {@link #getInt(Object, long)}  */
-    public native int     getIntVolatile(Object o, long offset);
-
-    /** Volatile version of {@link #putInt(Object, long, int)}  */
-    public native void    putIntVolatile(Object o, long offset, int x);
-
-    /** Volatile version of {@link #getBoolean(Object, long)}  */
-    public native boolean getBooleanVolatile(Object o, long offset);
-
-    /** Volatile version of {@link #putBoolean(Object, long, boolean)}  */
-    public native void    putBooleanVolatile(Object o, long offset, boolean x);
-
-    /** Volatile version of {@link #getByte(Object, long)}  */
-    public native byte    getByteVolatile(Object o, long offset);
-
-    /** Volatile version of {@link #putByte(Object, long, byte)}  */
-    public native void    putByteVolatile(Object o, long offset, byte x);
-
-    /** Volatile version of {@link #getShort(Object, long)}  */
-    public native short   getShortVolatile(Object o, long offset);
-
-    /** Volatile version of {@link #putShort(Object, long, short)}  */
-    public native void    putShortVolatile(Object o, long offset, short x);
-
-    /** Volatile version of {@link #getChar(Object, long)}  */
-    public native char    getCharVolatile(Object o, long offset);
-
-    /** Volatile version of {@link #putChar(Object, long, char)}  */
-    public native void    putCharVolatile(Object o, long offset, char x);
-
-    /** Volatile version of {@link #getLong(Object, long)}  */
-    public native long    getLongVolatile(Object o, long offset);
-
-    /** Volatile version of {@link #putLong(Object, long, long)}  */
-    public native void    putLongVolatile(Object o, long offset, long x);
-
-    /** Volatile version of {@link #getFloat(Object, long)}  */
-    public native float   getFloatVolatile(Object o, long offset);
-
-    /** Volatile version of {@link #putFloat(Object, long, float)}  */
-    public native void    putFloatVolatile(Object o, long offset, float x);
-
-    /** Volatile version of {@link #getDouble(Object, long)}  */
-    public native double  getDoubleVolatile(Object o, long offset);
-
-    /** Volatile version of {@link #putDouble(Object, long, double)}  */
-    public native void    putDoubleVolatile(Object o, long offset, double x);
-
-    /** 
-     * Version of {@link #putObjectVolatile(Object, long, Object)}
-     * that does not guarantee immediate visibility of the store to
-     * other threads. This method is generally only useful if the
-     * underlying field is a Java volatile (or if an array cell, one
-     * that is otherwise only accessed using volatile accesses).
-     */
-    public native void    putOrderedObject(Object o, long offset, Object x);
-
-    /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)}  */
-    public native void    putOrderedInt(Object o, long offset, int x);
-
-    /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
-    public native void    putOrderedLong(Object o, long offset, long x);
-
-    /**
-     * Unblock the given thread blocked on <tt>park</tt>, or, if it is
-     * not blocked, cause the subsequent call to <tt>park</tt> not to
-     * block.  Note: this operation is "unsafe" solely because the
-     * caller must somehow ensure that the thread has not been
-     * destroyed. Nothing special is usually required to ensure this
-     * when called from Java (in which there will ordinarily be a live
-     * reference to the thread) but this is not nearly-automatically
-     * so when calling from native code.
-     * @param thread the thread to unpark.
-     * 
-     */
-    public native void unpark(Object thread);
-
-    /**
-     * Block current thread, returning when a balancing
-     * <tt>unpark</tt> occurs, or a balancing <tt>unpark</tt> has
-     * already occurred, or the thread is interrupted, or, if not
-     * absolute and time is not zero, the given time nanoseconds have
-     * elapsed, or if absolute, the given deadline in milliseconds
-     * since Epoch has passed, or spuriously (i.e., returning for no
-     * "reason"). Note: This operation is in the Unsafe class only
-     * because <tt>unpark</tt> is, so it would be strange to place it
-     * elsewhere.
-     */
-    public native void park(boolean isAbsolute, long time);
-
-    /**
-     * Gets the load average in the system run queue assigned
-     * to the available processors averaged over various periods of time.
-     * This method retrieves the given <tt>nelem</tt> samples and
-     * assigns to the elements of the given <tt>loadavg</tt> array.
-     * The system imposes a maximum of 3 samples, representing 
-     * averages over the last 1,  5,  and  15 minutes, respectively.
-     * 
-     * @params loadavg an array of double of size nelems
-     * @params nelems the number of samples to be retrieved and
-     *         must be 1 to 3.
-     *
-     * @return the number of samples actually retrieved; or -1
-     *         if the load average is unobtainable.
-     */
-    public native int getLoadAverage(double[] loadavg, int nelems);
-}
diff --git a/src/lib/gnu/sun/reflect/ConstantPool.java b/src/lib/gnu/sun/reflect/ConstantPool.java
deleted file mode 100644 (file)
index b24d28e..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.reflect;
-
-import java.lang.reflect.*;
-
-/** Provides reflective access to the constant pools of classes.
-    Currently this is needed to provide reflective access to annotations
-    but may be used by other internal subsystems in the future. */
-
-public class ConstantPool {
-  // Number of entries in this constant pool (= maximum valid constant pool index)
-  public int      getSize()                      { return getSize0            (constantPoolOop);        }
-  public Class    getClassAt         (int index) { return getClassAt0         (constantPoolOop, index); }
-  public Class    getClassAtIfLoaded (int index) { return getClassAtIfLoaded0 (constantPoolOop, index); }
-  // Returns either a Method or Constructor.
-  // Static initializers are returned as Method objects.
-  public Member   getMethodAt        (int index) { return getMethodAt0        (constantPoolOop, index); }
-  public Member   getMethodAtIfLoaded(int index) { return getMethodAtIfLoaded0(constantPoolOop, index); }
-  public Field    getFieldAt         (int index) { return getFieldAt0         (constantPoolOop, index); }
-  public Field    getFieldAtIfLoaded (int index) { return getFieldAtIfLoaded0 (constantPoolOop, index); }
-  // Fetches the class name, member (field, method or interface
-  // method) name, and type descriptor as an array of three Strings
-  public String[] getMemberRefInfoAt (int index) { return getMemberRefInfoAt0 (constantPoolOop, index); }
-  public int      getIntAt           (int index) { return getIntAt0           (constantPoolOop, index); }
-  public long     getLongAt          (int index) { return getLongAt0          (constantPoolOop, index); }
-  public float    getFloatAt         (int index) { return getFloatAt0         (constantPoolOop, index); }
-  public double   getDoubleAt        (int index) { return getDoubleAt0        (constantPoolOop, index); }
-  public String   getStringAt        (int index) { return getStringAt0        (constantPoolOop, index); }
-  public String   getUTF8At          (int index) { return getUTF8At0          (constantPoolOop, index); }
-
-  //---------------------------------------------------------------------------
-  // Internals only below this point
-  //
-/* This hides this member from being visible through the reflection API in OpenJDK
- * TODO: find out how to do this with GNU Classpath (if it's realy neccesary).
-
-  static {
-      Reflection.registerFieldsToFilter(ConstantPool.class, new String[] { "constantPoolOop" });
-  }
-*/
-  // HotSpot-internal constant pool object (set by the VM, name known to the VM)
-  private Object constantPoolOop;
-
-  private native int      getSize0            (Object constantPoolOop);
-  private native Class    getClassAt0         (Object constantPoolOop, int index);
-  private native Class    getClassAtIfLoaded0 (Object constantPoolOop, int index);
-  private native Member   getMethodAt0        (Object constantPoolOop, int index);
-  private native Member   getMethodAtIfLoaded0(Object constantPoolOop, int index);
-  private native Field    getFieldAt0         (Object constantPoolOop, int index);
-  private native Field    getFieldAtIfLoaded0 (Object constantPoolOop, int index);
-  private native String[] getMemberRefInfoAt0 (Object constantPoolOop, int index);
-  private native int      getIntAt0           (Object constantPoolOop, int index);
-  private native long     getLongAt0          (Object constantPoolOop, int index);
-  private native float    getFloatAt0         (Object constantPoolOop, int index);
-  private native double   getDoubleAt0        (Object constantPoolOop, int index);
-  private native String   getStringAt0        (Object constantPoolOop, int index);
-  private native String   getUTF8At0          (Object constantPoolOop, int index);
-}
diff --git a/src/lib/gnu/sun/reflect/annotation/AnnotationParser.java b/src/lib/gnu/sun/reflect/annotation/AnnotationParser.java
deleted file mode 100644 (file)
index 8c5aca3..0000000
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.reflect.annotation;
-
-import java.lang.annotation.*;
-import java.util.*;
-import java.nio.ByteBuffer;
-import java.nio.BufferUnderflowException;
-import java.lang.reflect.*;
-import sun.reflect.ConstantPool;
-
-import gnu.java.lang.reflect.FieldSignatureParser;
-
-
-/**
- * Parser for Java programming language annotations.  Translates
- * annotation byte streams emitted by compiler into annotation objects.
- *
- * @author  Josh Bloch
- * @since   1.5
- */
-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
-     * 
-     * @param rawAnnotations are the unparsed annotations
-     * @param constPool is the constant pool of the declaring class
-     * @param container is the containing class
-     * @return the parsed annotations in an array
-     * @throws AnnotationFormatError if an annotation is found to be
-     *         malformed.
-     */
-    public static Annotation[] parseAnnotationsIntoArray(
-                byte[] rawAnnotations,
-                ConstantPool constPool,
-                Class container) {
-        Map<Class, Annotation> annotations = parseAnnotations(rawAnnotations, constPool, container);
-        return annotations.values().toArray(EMPTY_ANNOTATIONS_ARRAY);
-    }
-
-    /**
-     * Parses parameter annotations.
-     * 
-     * @author Mathias Panzenböck
-     * 
-     * @param parameterAnnotations are the unparsed parameter annotations
-     * @param constPool is the constant pool of the declaring class
-     * @param container is the containing class
-     * @return the parsed parameter annotations in an array 2 dimensional array
-     * @throws AnnotationFormatError if an annotation is found to be
-     *         malformed.
-     */
-    public static Annotation[][] parseParameterAnnotations(
-                    byte[] parameterAnnotations,
-                    ConstantPool constPool,
-                    Class container,
-                    int numParameters) {
-        if (parameterAnnotations == null)
-            return new Annotation[numParameters][0];
-
-        Annotation[][] result = parseParameterAnnotations(
-            parameterAnnotations, constPool, container); 
-
-        if (result.length != numParameters)
-            throw new AnnotationFormatError(
-                "Parameter annotations don't match number of parameters (count was " +
-               result.length + " but should be " + numParameters + ").");
-        return result;
-    }
-
-    /**
-     * Parses the annotation default value of the supplied method.
-     * This method is basically copied from OpenJDKs
-     * java.lang.reflect.Method.getAnnotationDefault()
-     * 
-     * @author Mathias Panzenböck
-     *
-     * @param method represents the method for which the annotation default value has to be parsed
-     * @param annotationDefault is the unparsed annotation default value
-     * @param constPool is the constant pool of the declaring class
-     * @return the parsed annotation default value (boxed, if it's a primitive type)
-     * @throws AnnotationFormatError if an annotation is found to be
-     *         malformed.
-     */
-    public static Object parseAnnotationDefault(Method method,
-                                                byte[] annotationDefault,
-                                                ConstantPool constPool) {
-        if  (annotationDefault == null)
-            return null;
-        
-       Class memberType = AnnotationType.invocationHandlerReturnType(
-            method.getReturnType());
-        
-       Object result = AnnotationParser.parseMemberValue(
-            memberType, ByteBuffer.wrap(annotationDefault),
-            constPool, method.getDeclaringClass());
-
-        if (result instanceof sun.reflect.annotation.ExceptionProxy)
-            throw new AnnotationFormatError("Invalid default: " + method);
-        
-       return result;
-    }
-
-    /**
-     * Parses the annotations described by the specified byte array.
-     * resolving constant references in the specified constant pool.
-     * The array must contain an array of annotations as described
-     * in the RuntimeVisibleAnnotations_attribute:
-     *
-     *   u2 num_annotations;
-     *   annotation annotations[num_annotations];
-     *
-     * @throws AnnotationFormatError if an annotation is found to be
-     *         malformed.
-     */
-    public static Map<Class, Annotation> parseAnnotations(
-                byte[] rawAnnotations,
-                ConstantPool constPool,
-                Class container) {
-        if (rawAnnotations == null)
-            return Collections.emptyMap();
-
-        try {
-            return parseAnnotations2(rawAnnotations, constPool, container);
-        } catch(BufferUnderflowException e) {
-            throw new AnnotationFormatError("Unexpected end of annotations.");
-        } catch(IllegalArgumentException e) {
-            // Type mismatch in constant pool
-            throw new AnnotationFormatError(e);
-        }
-    }
-
-    private static Map<Class, Annotation> parseAnnotations2(
-                byte[] rawAnnotations,
-                ConstantPool constPool,
-                Class container) {
-        Map<Class, Annotation> result = new LinkedHashMap<Class, Annotation>();
-        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
-        int numAnnotations = buf.getShort() & 0xFFFF;
-        for (int i = 0; i < numAnnotations; i++) {
-           Annotation a = parseAnnotation(buf, constPool, container, false);
-            if (a != null) {
-                Class klass = a.annotationType();
-                AnnotationType type = AnnotationType.getInstance(klass);
-                if (type.retention() == RetentionPolicy.RUNTIME)
-                    if (result.put(klass, a) != null)
-                        throw new AnnotationFormatError(
-                            "Duplicate annotation for class: "+klass+": " + a);
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Parses the parameter annotations described by the specified byte array.
-     * resolving constant references in the specified constant pool.
-     * The array must contain an array of annotations as described
-     * in the RuntimeVisibleParameterAnnotations_attribute:
-     *
-     *    u1 num_parameters;
-     *    {
-     *        u2 num_annotations;
-     *        annotation annotations[num_annotations];
-     *    } parameter_annotations[num_parameters];
-     *
-     * Unlike parseAnnotations, rawAnnotations must not be null!
-     * A null value must be handled by the caller.  This is so because
-     * we cannot determine the number of parameters if rawAnnotations
-     * is null.  Also, the caller should check that the number
-     * of parameters indicated by the return value of this method
-     * matches the actual number of method parameters.  A mismatch
-     * indicates that an AnnotationFormatError should be thrown.
-     *
-     * @throws AnnotationFormatError if an annotation is found to be
-     *         malformed.
-     */
-    public static Annotation[][] parseParameterAnnotations(
-                    byte[] rawAnnotations,
-                    ConstantPool constPool,
-                    Class container) {
-        try {
-            return parseParameterAnnotations2(rawAnnotations, constPool, container);
-        } catch(BufferUnderflowException e) {
-            throw new AnnotationFormatError(
-                "Unexpected end of parameter annotations.");
-        } catch(IllegalArgumentException e) {
-            // Type mismatch in constant pool
-            throw new AnnotationFormatError(e);
-        }
-    }
-
-    private static Annotation[][] parseParameterAnnotations2(
-                    byte[] rawAnnotations,
-                    ConstantPool constPool,
-                    Class container) {
-        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
-        int numParameters = buf.get() & 0xFF;
-        Annotation[][] result = new Annotation[numParameters][];
-
-        for (int i = 0; i < numParameters; i++) {
-            int numAnnotations = buf.getShort() & 0xFFFF;
-            List<Annotation> annotations =
-                new ArrayList<Annotation>(numAnnotations);
-            for (int j = 0; j < numAnnotations; j++) {
-                Annotation a = parseAnnotation(buf, constPool, container, false);
-                if (a != null) {
-                    AnnotationType type = AnnotationType.getInstance(
-                                              a.annotationType());
-                    if (type.retention() == RetentionPolicy.RUNTIME)
-                        annotations.add(a);
-                }
-            }
-            result[i] = annotations.toArray(EMPTY_ANNOTATIONS_ARRAY);
-        }
-        return result;
-    }
-
-    private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
-                    new Annotation[0];
-
-    /**
-     * Parses the annotation at the current position in the specified
-     * byte buffer, resolving constant references in the specified constant
-     * pool.  The cursor of the byte buffer must point to an "annotation
-     * structure" as described in the RuntimeVisibleAnnotations_attribute:
-     *
-     * annotation {
-     *    u2    type_index;
-     *       u2    num_member_value_pairs;
-     *       {    u2    member_name_index;
-     *             member_value value;
-     *       }    member_value_pairs[num_member_value_pairs];
-     *    }
-     * }
-     *
-     * Returns the annotation, or null if the annotation's type cannot
-     * be found by the VM, or is not a valid annotation type.
-     *
-     * @param exceptionOnMissingAnnotationClass if true, throw
-     * TypeNotPresentException if a referenced annotation type is not
-     * available at runtime
-     */
-    private static Annotation parseAnnotation(ByteBuffer buf,
-                                              ConstantPool constPool,
-                                              Class container,
-                                             boolean exceptionOnMissingAnnotationClass) {
-        int typeIndex = buf.getShort() & 0xFFFF;
-        Class annotationClass = null;
-       String sig = "[unknown]";
-        try {
-            try {
-                sig = constPool.getUTF8At(typeIndex);
-                annotationClass = parseSig(sig, container);
-            } catch (IllegalArgumentException ex) {
-                // support obsolete early jsr175 format class files
-                annotationClass = constPool.getClassAt(typeIndex);
-            }
-        } catch (NoClassDefFoundError e) {
-           if (exceptionOnMissingAnnotationClass)
-               // note: at this point sig is "[unknown]" or VM-style
-               // name instead of a binary name
-               throw new TypeNotPresentException(sig, e);
-            skipAnnotation(buf, false);
-            return null;
-        }
-       catch (TypeNotPresentException e) {
-           if (exceptionOnMissingAnnotationClass)
-               throw e;
-            skipAnnotation(buf, false);
-            return null;
-        }
-        AnnotationType type = null;
-        try {
-            type = AnnotationType.getInstance(annotationClass);
-        } catch (IllegalArgumentException e) {
-            skipAnnotation(buf, false);
-            return null;
-        }
-
-        Map<String, Class> memberTypes = type.memberTypes();
-        Map<String, Object> memberValues =
-            new LinkedHashMap<String, Object>(type.memberDefaults());
-
-        int numMembers = buf.getShort() & 0xFFFF;
-        for (int i = 0; i < numMembers; i++) {
-            int memberNameIndex = buf.getShort() & 0xFFFF;
-            String memberName = constPool.getUTF8At(memberNameIndex);
-            Class memberType = memberTypes.get(memberName);
-
-            if (memberType == null) {
-                // Member is no longer present in annotation type; ignore it
-                skipMemberValue(buf);
-            } else {
-                Object value = parseMemberValue(memberType, buf, constPool, container);
-                if (value instanceof AnnotationTypeMismatchExceptionProxy)
-                    ((AnnotationTypeMismatchExceptionProxy) value).
-                        setMember(type.members().get(memberName));
-                memberValues.put(memberName, value);
-            }
-        }
-        return annotationForMap(annotationClass, memberValues);
-    }
-
-    /**
-     * Returns an annotation of the given type backed by the given
-     * member -> value map.
-     */
-    public static Annotation annotationForMap(
-        Class type, Map<String, Object> memberValues)
-    {
-        return (Annotation) Proxy.newProxyInstance(
-            type.getClassLoader(), new Class[] { type },
-            new AnnotationInvocationHandler(type, memberValues));
-    }
-
-    /**
-     * Parses the annotation member value at the current position in the
-     * specified byte buffer, resolving constant references in the specified
-     * constant pool.  The cursor of the byte buffer must point to a
-     * "member_value structure" as described in the
-     * RuntimeVisibleAnnotations_attribute:
-     *
-     *  member_value {
-     *    u1 tag;
-     *    union {
-     *       u2   const_value_index;
-     *       {
-     *           u2   type_name_index;
-     *           u2   const_name_index;
-     *       } enum_const_value;
-     *       u2   class_info_index;
-     *       annotation annotation_value; 
-     *       {
-     *           u2    num_values;
-     *           member_value values[num_values];
-     *       } array_value;
-     *    } value;
-     * }
-     *
-     * The member must be of the indicated type. If it is not, this
-     * method returns an AnnotationTypeMismatchExceptionProxy.
-     */
-    public static Object parseMemberValue(Class memberType, ByteBuffer buf,
-                                          ConstantPool constPool,
-                                          Class container) {
-        Object result = null;
-        int tag = buf.get();
-        switch(tag) {
-          case 'e':
-              return parseEnumValue(memberType, buf, constPool, container);
-          case 'c':
-              result = parseClassValue(buf, constPool, container);
-              break;
-          case '@':
-              result = parseAnnotation(buf, constPool, container, true);
-              break;
-          case '[':
-              return parseArray(memberType, buf, constPool, container);
-          default:
-              result = parseConst(tag, buf, constPool);
-        }
-
-        if (!(result instanceof ExceptionProxy) &&
-            !memberType.isInstance(result))
-            result = new AnnotationTypeMismatchExceptionProxy(
-                result.getClass() + "[" + result + "]");
-        return result;
-    }
-
-    /**
-     * Parses the primitive or String annotation member value indicated by 
-     * the specified tag byte at the current position in the specified byte
-     * buffer, resolving constant reference in the specified constant pool.
-     * The cursor of the byte buffer must point to an annotation member value
-     * of the type indicated by the specified tag, as described in the
-     * RuntimeVisibleAnnotations_attribute:
-     *
-     *       u2   const_value_index;
-     */
-    private static Object parseConst(int tag,
-                                     ByteBuffer buf, ConstantPool constPool) {
-        int constIndex = buf.getShort() & 0xFFFF;
-        switch(tag) {
-          case 'B':
-            return Byte.valueOf((byte) constPool.getIntAt(constIndex));
-          case 'C':
-            return Character.valueOf((char) constPool.getIntAt(constIndex));
-          case 'D':
-            return Double.valueOf(constPool.getDoubleAt(constIndex));
-          case 'F':
-            return Float.valueOf(constPool.getFloatAt(constIndex));
-          case 'I':
-            return Integer.valueOf(constPool.getIntAt(constIndex));
-          case 'J':
-            return Long.valueOf(constPool.getLongAt(constIndex));
-          case 'S':
-            return Short.valueOf((short) constPool.getIntAt(constIndex));
-          case 'Z':
-            return Boolean.valueOf(constPool.getIntAt(constIndex) != 0);
-          case 's':
-            return constPool.getUTF8At(constIndex);
-          default:
-            throw new AnnotationFormatError(
-                "Invalid member-value tag in annotation: " + tag);
-        }
-    }
-
-    /**
-     * Parses the Class member value at the current position in the
-     * specified byte buffer, resolving constant references in the specified
-     * constant pool.  The cursor of the byte buffer must point to a "class
-     * info index" as described in the RuntimeVisibleAnnotations_attribute:
-     *
-     *       u2   class_info_index;
-     */
-    private static Object parseClassValue(ByteBuffer buf,
-                                          ConstantPool constPool,
-                                          Class container) {
-        int classIndex = buf.getShort() & 0xFFFF;
-        try {
-            try {
-                String sig = constPool.getUTF8At(classIndex);
-                return parseSig(sig, container);
-            } catch (IllegalArgumentException ex) {
-                // support obsolete early jsr175 format class files
-                return constPool.getClassAt(classIndex);
-            }
-        } catch (NoClassDefFoundError e) {
-            return new TypeNotPresentExceptionProxy("[unknown]", e);
-        }
-        catch (TypeNotPresentException e) {
-            return new TypeNotPresentExceptionProxy(e.typeName(), e.getCause());
-        }
-    }
-
-    /**
-     * Parses a return type signature and returns the according Class object.
-     */
-    private static Class<?> parseSig(String sig, Class container) {
-        if (sig.equals("V")) {
-            return void.class;
-        }
-        else {
-            return toClass(new FieldSignatureParser(container, sig).getFieldType());
-        }
-    }
-
-    static Class<?> toClass(Type o) {
-        if (o instanceof GenericArrayType)
-            return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
-                                     0)
-                .getClass();
-        return (Class<?>)o;
-    }
-
-    /**
-     * Parses the enum constant member value at the current position in the
-     * specified byte buffer, resolving constant references in the specified
-     * constant pool.  The cursor of the byte buffer must point to a
-     * "enum_const_value structure" as described in the
-     * RuntimeVisibleAnnotations_attribute:
-     *
-     *       {
-     *           u2   type_name_index;
-     *           u2   const_name_index;
-     *       } enum_const_value;
-     */
-    private static Object parseEnumValue(Class enumType, ByteBuffer buf,
-                                         ConstantPool constPool,
-                                         Class container) {
-        int typeNameIndex = buf.getShort() & 0xFFFF;
-        String typeName  = constPool.getUTF8At(typeNameIndex);
-        int constNameIndex = buf.getShort() & 0xFFFF;
-        String constName = constPool.getUTF8At(constNameIndex);
-
-        if (!typeName.endsWith(";")) {
-            // support now-obsolete early jsr175-format class files.
-            if (!enumType.getName().equals(typeName))
-            return new AnnotationTypeMismatchExceptionProxy(
-                typeName + "." + constName);
-        } else if (enumType != parseSig(typeName, container)) {
-            return new AnnotationTypeMismatchExceptionProxy(
-                typeName + "." + constName);
-        }
-
-        try {
-            return  Enum.valueOf(enumType, constName);
-        } catch(IllegalArgumentException e) {
-            return new EnumConstantNotPresentExceptionProxy(
-                (Class<? extends Enum>)enumType, constName);
-        }
-    }
-
-    /**
-     * Parses the array value at the current position in the specified byte
-     * buffer, resolving constant references in the specified constant pool.
-     * The cursor of the byte buffer must point to an array value struct
-     * as specified in the RuntimeVisibleAnnotations_attribute:
-     *
-     *       {
-     *           u2    num_values;
-     *           member_value values[num_values];
-     *       } array_value;
-     *
-     * If the array values do not match arrayType, an
-     * AnnotationTypeMismatchExceptionProxy will be returned.
-     */
-    private static Object parseArray(Class arrayType,
-                                     ByteBuffer buf,
-                                     ConstantPool constPool,
-                                     Class container) {
-        int length = buf.getShort() & 0xFFFF;  // Number of array components
-        Class componentType = arrayType.getComponentType();
-
-        if (componentType == byte.class) {
-            return parseByteArray(length, buf, constPool); 
-        } else if (componentType == char.class) {
-            return parseCharArray(length, buf, constPool);
-        } else if (componentType == double.class) {
-            return parseDoubleArray(length, buf, constPool);
-        } else if (componentType == float.class) {
-            return parseFloatArray(length, buf, constPool);
-        } else if (componentType == int.class) {
-            return parseIntArray(length, buf, constPool);
-        } else if (componentType == long.class) {
-            return parseLongArray(length, buf, constPool);
-        } else if (componentType == short.class) {
-            return parseShortArray(length, buf, constPool);
-        } else if (componentType == boolean.class) {
-            return parseBooleanArray(length, buf, constPool);
-        } else if (componentType == String.class) {
-            return parseStringArray(length, buf, constPool);
-        } else if (componentType == Class.class) {
-            return parseClassArray(length, buf, constPool, container);
-        } else if (componentType.isEnum()) {
-            return parseEnumArray(length, componentType, buf,
-                                  constPool, container);
-        } else {
-            assert componentType.isAnnotation();
-            return parseAnnotationArray(length, componentType, buf,
-                                        constPool, container);
-        }
-    }
-
-    private static Object parseByteArray(int length,
-                                  ByteBuffer buf, ConstantPool constPool) {
-        byte[] result = new byte[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'B') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = (byte) constPool.getIntAt(index);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseCharArray(int length,
-                                  ByteBuffer buf, ConstantPool constPool) {
-        char[] result = new char[length];
-        boolean typeMismatch = false;
-        byte tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'C') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = (char) constPool.getIntAt(index);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseDoubleArray(int length,
-                                    ByteBuffer buf, ConstantPool constPool) {
-        double[] result = new  double[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'D') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = constPool.getDoubleAt(index);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseFloatArray(int length,
-                                   ByteBuffer buf, ConstantPool constPool) {
-        float[] result = new float[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'F') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = constPool.getFloatAt(index);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseIntArray(int length,
-                                 ByteBuffer buf, ConstantPool constPool) {
-        int[] result = new  int[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'I') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = constPool.getIntAt(index);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-    
-    private static Object parseLongArray(int length,
-                                  ByteBuffer buf, ConstantPool constPool) {
-        long[] result = new long[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'J') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = constPool.getLongAt(index);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseShortArray(int length,
-                                   ByteBuffer buf, ConstantPool constPool) {
-        short[] result = new short[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'S') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = (short) constPool.getIntAt(index);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseBooleanArray(int length,
-                                     ByteBuffer buf, ConstantPool constPool) {
-        boolean[] result = new boolean[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'Z') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = (constPool.getIntAt(index) != 0);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseStringArray(int length,
-                                    ByteBuffer buf,  ConstantPool constPool) {
-        String[] result = new String[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 's') {
-                int index = buf.getShort() & 0xFFFF;
-                result[i] = constPool.getUTF8At(index);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseClassArray(int length,
-                                          ByteBuffer buf,
-                                          ConstantPool constPool,
-                                          Class container) {
-        Object[] result = new Class[length];
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'c') {
-                result[i] = parseClassValue(buf, constPool, container);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseEnumArray(int length, Class enumType,
-                                         ByteBuffer buf,
-                                         ConstantPool constPool,
-                                         Class container) {
-        Object[] result = (Object[]) Array.newInstance(enumType, length);
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == 'e') {
-                result[i] = parseEnumValue(enumType, buf, constPool, container);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    private static Object parseAnnotationArray(int length,
-                                               Class annotationType,
-                                               ByteBuffer buf,
-                                               ConstantPool constPool,
-                                               Class container) {
-        Object[] result = (Object[]) Array.newInstance(annotationType, length);
-        boolean typeMismatch = false;
-        int tag = 0;
-
-        for (int i = 0; i < length; i++) {
-            tag = buf.get();
-            if (tag == '@') {
-                result[i] = parseAnnotation(buf, constPool, container, true);
-            } else {
-                skipMemberValue(tag, buf);
-                typeMismatch = true;
-            }
-        }
-        return typeMismatch ? exceptionProxy(tag) : result;
-    }
-
-    /**
-     * Return an appropriate exception proxy for a mismatching array
-     * annotation where the erroneous array has the specified tag.
-     */
-    private static ExceptionProxy exceptionProxy(int tag) {
-        return new AnnotationTypeMismatchExceptionProxy(
-            "Array with component tag: " + tag);
-    }
-
-    /**
-     * Skips the annotation at the current position in the specified
-     * byte buffer.  The cursor of the byte buffer must point to 
-     * an "annotation structure" OR two bytes into an annotation
-     * structure (i.e., after the type index).
-     * 
-     * @parameter complete true if the byte buffer points to the beginning
-     *     of an annotation structure (rather than two bytes in).
-     */
-    private static void skipAnnotation(ByteBuffer buf, boolean complete) {
-        if (complete)
-            buf.getShort();   // Skip type index
-        int numMembers = buf.getShort() & 0xFFFF;
-        for (int i = 0; i < numMembers; i++) {
-            buf.getShort();   // Skip memberNameIndex
-            skipMemberValue(buf);
-        }
-    }
-
-    /**
-     * Skips the annotation member value at the current position in the
-     * specified byte buffer.  The cursor of the byte buffer must point to a
-     * "member_value structure."
-     */
-    private static void skipMemberValue(ByteBuffer buf) {
-        int tag = buf.get();
-        skipMemberValue(tag, buf);
-    }
-
-    /**
-     * Skips the annotation member value at the current position in the
-     * specified byte buffer.  The cursor of the byte buffer must point
-     * immediately after the tag in a "member_value structure."
-     */
-    private static void skipMemberValue(int tag, ByteBuffer buf) {
-        switch(tag) {
-          case 'e': // Enum value
-            buf.getInt();  // (Two shorts, actually.)
-            break;
-          case '@':
-            skipAnnotation(buf, true);
-            break;
-          case '[':
-            skipArray(buf);
-            break;
-          default:
-            // Class, primitive, or String
-            buf.getShort();
-        }
-    }
-
-    /**
-     * Skips the array value at the current position in the specified byte
-     * buffer.  The cursor of the byte buffer must point to an array value
-     * struct.
-     */
-    private static void skipArray(ByteBuffer buf) {
-        int length = buf.getShort() & 0xFFFF;
-        for (int i = 0; i < length; i++)
-            skipMemberValue(buf);
-    }
-}
diff --git a/src/lib/gnu/sun/reflect/annotation/AnnotationType.java b/src/lib/gnu/sun/reflect/annotation/AnnotationType.java
deleted file mode 100644 (file)
index ea559bb..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.reflect.annotation;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * Represents an annotation type at run time.  Used to type-check annotations
- * and apply member defaults.
- *
- * @author  Josh Bloch
- * @since   1.5
- */
-public class AnnotationType {
-    /**
-     * Annotation class -> AnnotationType mapping. This emulates
-     * sun.misc.SharedSecrets.getJavaLangAccess().getAnnotationType() and
-     * sun.misc.SharedSecrets.getJavaLangAccess().setAnnotationType() so
-     * this class can be used with gnu classpath.
-     *
-     * @author Mathias Panzenböck
-     */
-    private static Map<Class, AnnotationType> annotationTypes =
-        new HashMap<Class, AnnotationType>();
-
-    /**
-     * Member name -> type mapping. Note that primitive types
-     * are represented by the class objects for the corresponding wrapper
-     * types.  This matches the return value that must be used for a
-     * dynamic proxy, allowing for a simple isInstance test.
-     */
-    private final Map<String, Class> memberTypes = new HashMap<String,Class>();
-
-    /**
-     * Member name -> default value mapping.
-     */
-    private final Map<String, Object> memberDefaults =
-        new HashMap<String, Object>();
-
-    /**
-     * Member name -> Method object mapping. This (and its assoicated
-     * accessor) are used only to generate AnnotationTypeMismatchExceptions.
-     */
-    private final Map<String, Method> members = new HashMap<String, Method>();
-
-    /**
-     * The retention policy for this annotation type.
-     */
-    private RetentionPolicy retention = RetentionPolicy.RUNTIME;;
-
-    /**
-     * Whether this annotation type is inherited.
-     */
-    private boolean inherited = false;
-
-    /**
-     * Returns an AnnotationType instance for the specified annotation type.
-     *
-     * @throw IllegalArgumentException if the specified class object for
-     *     does not represent a valid annotation type
-     */
-    public static synchronized AnnotationType getInstance(
-        Class annotationClass)
-    {
-        /*
-       AnnotationType result = sun.misc.SharedSecrets.getJavaLangAccess(). 
-            getAnnotationType(annotationClass); 
-        */
-       // emulating OpenJDKs SharedSecrets in GNU Classpath:
-       AnnotationType result = annotationTypes.get(annotationClass); 
-       if (result == null)
-            result = new AnnotationType((Class<?>) annotationClass);
-
-        return result;
-    }
-
-    /**
-     * Sole constructor.
-     *
-     * @param annotationClass the class object for the annotation type
-     * @throw IllegalArgumentException if the specified class object for
-     *     does not represent a valid annotation type
-     */
-    private AnnotationType(final Class<?> annotationClass) {
-        if (!annotationClass.isAnnotation())
-            throw new IllegalArgumentException("Not an annotation type");
-
-       Method[] methods =      
-           AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
-               public Method[] run() {
-                   // Initialize memberTypes and defaultValues
-                   return annotationClass.getDeclaredMethods();
-               }
-           });
-
-
-       for (Method method :  methods) {
-           if (method.getParameterTypes().length != 0)
-               throw new IllegalArgumentException(method + " has params");
-           String name = method.getName();
-           Class type = method.getReturnType();
-           memberTypes.put(name, invocationHandlerReturnType(type));
-           members.put(name, method);
-                   
-           Object defaultValue = method.getDefaultValue();
-           if (defaultValue != null)
-               memberDefaults.put(name, defaultValue);
-
-           members.put(name, method);
-       }
-
-       /*
-        sun.misc.SharedSecrets.getJavaLangAccess(). 
-            setAnnotationType(annotationClass, this); 
-        */
-       // emulating OpenJDKs SharedSecrets in GNU Classpath:
-       annotationTypes.put(annotationClass, this);
-
-        // Initialize retention, & inherited fields.  Special treatment
-        // of the corresponding annotation types breaks infinite recursion.
-        if (annotationClass != Retention.class &&
-            annotationClass != Inherited.class) {
-            Retention ret = annotationClass.getAnnotation(Retention.class);
-            retention = (ret == null ? RetentionPolicy.CLASS : ret.value());
-            inherited = annotationClass.isAnnotationPresent(Inherited.class);
-        }
-    }
-
-    /**
-     * Returns the type that must be returned by the invocation handler
-     * of a dynamic proxy in order to have the dynamic proxy return
-     * the specified type (which is assumed to be a legal member type
-     * for an annotation).
-     */
-    public static Class invocationHandlerReturnType(Class type) {
-        // Translate primitives to wrappers
-        if (type == byte.class)
-            return Byte.class;
-        if (type == char.class)
-            return Character.class;
-        if (type == double.class)
-            return Double.class;
-        if (type == float.class)
-            return Float.class;
-        if (type == int.class)
-            return Integer.class;
-        if (type == long.class)
-            return Long.class;
-        if (type == short.class)
-            return Short.class;
-        if (type == boolean.class)
-            return Boolean.class;
-
-        // Otherwise, just return declared type
-        return type;
-    }
-
-    /**
-     * Returns member types for this annotation type
-     * (member name -> type mapping).
-     */
-    public Map<String, Class> memberTypes() {
-        return memberTypes;
-    }
-
-    /**
-     * Returns members of this annotation type
-     * (member name -> associated Method object mapping).
-     */
-    public Map<String, Method> members() {
-        return members;
-    }
-
-    /**
-     * Returns the default values for this annotation type
-     * (Member name -> default value mapping).
-     */
-    public Map<String, Object> memberDefaults() {
-        return memberDefaults;
-    }
-
-    /**
-     * Returns the retention policy for this annotation type.
-     */
-    public RetentionPolicy retention() {
-        return retention;
-    }
-
-    /**
-     * Returns true if this this annotation type is inherited.
-     */
-    public boolean isInherited() {
-        return inherited;
-    }
-
-    /**
-     * For debugging.
-     */
-    public String toString() {
-        StringBuffer s = new StringBuffer("Annotation Type:" + "\n");
-        s.append("   Member types: " + memberTypes + "\n");
-        s.append("   Member defaults: " + memberDefaults + "\n");
-        s.append("   Retention policy: " + retention + "\n");
-        s.append("   Inherited: " + inherited);
-        return s.toString();
-    }
-}
diff --git a/src/lib/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java b/src/lib/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java
deleted file mode 100644 (file)
index a7f434f..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.reflect.annotation;
-import java.lang.annotation.*;
-import java.lang.reflect.Method;
-
-/**
- * ExceptionProxy for AnnotationTypeMismatchException.
- *
- * @author  Josh Bloch
- * @since   1.5
- */
-class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy {
-    private Method member;
-    private String foundType;
-
-    /**
-     * It turns out to be convenient to construct these proxies in
-     * two stages.  Since this is a private implementation class, we
-     * permit ourselves this liberty even though it's normally a very
-     * bad idea.
-     */
-    AnnotationTypeMismatchExceptionProxy(String foundType) {
-        this.foundType = foundType;
-    }
-
-    AnnotationTypeMismatchExceptionProxy setMember(Method member) {
-        this.member = member;
-        return this;
-    }
-
-    protected RuntimeException generateException() {
-        return new AnnotationTypeMismatchException(member, foundType);
-    }
-}
diff --git a/src/lib/gnu/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java b/src/lib/gnu/sun/reflect/annotation/EnumConstantNotPresentExceptionProxy.java
deleted file mode 100644 (file)
index 6049a3f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.reflect.annotation;
-import java.lang.annotation.*;
-
-/**
- * ExceptionProxy for EnumConstantNotPresentException.
- *
- * @author  Josh Bloch
- * @since   1.5
- */
-public class EnumConstantNotPresentExceptionProxy extends ExceptionProxy {
-    Class<? extends Enum> enumType;
-    String constName;
-
-    public EnumConstantNotPresentExceptionProxy(Class<? extends Enum> enumType,
-                                                String constName) {
-        this.enumType = enumType;
-        this.constName = constName;
-    }
-
-    protected RuntimeException generateException() {
-        return new EnumConstantNotPresentException(enumType, constName);
-    }
-}
diff --git a/src/lib/gnu/sun/reflect/annotation/ExceptionProxy.java b/src/lib/gnu/sun/reflect/annotation/ExceptionProxy.java
deleted file mode 100644 (file)
index e9cda0b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.reflect.annotation;
-
-/**
- * An instance of this class is stored in an AnnotationInvocationHandler's
- * "memberValues" map in lieu of a value for an annotation member that
- * cannot be returned due to some exceptional condition (typically some
- * form of illegal evolution of the annotation class).  The ExceptionProxy
- * instance describes the exception that the dynamic proxy should throw if
- * it is queried for this member.
- *
- * @author  Josh Bloch
- * @since   1.5
- */
-public abstract class ExceptionProxy implements java.io.Serializable {
-    protected abstract RuntimeException generateException();
-}
diff --git a/src/lib/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java b/src/lib/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java
deleted file mode 100644 (file)
index 22cab5d..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package sun.reflect.annotation;
-import java.lang.annotation.*;
-
-/**
- * ExceptionProxy for TypeNotPresentException.
- *
- * @author  Josh Bloch
- * @since   1.5
- */
-public class TypeNotPresentExceptionProxy extends ExceptionProxy {
-    String typeName;
-    Throwable cause;
-
-    public TypeNotPresentExceptionProxy(String typeName, Throwable cause) {
-        this.typeName = typeName;
-        this.cause = cause;
-    }
-
-    protected RuntimeException generateException() {
-        return new TypeNotPresentException(typeName, cause);
-    }
-}
index 6ddf673df6507c3bc7bb1a7d9ee0650e05ae93e0..22c39cec2ed77c989a22004cbf4b07976c250b7f 100644 (file)
@@ -1,9 +1,7 @@
 ## src/mm/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.
 ##
@@ -59,6 +57,10 @@ noinst_LTLIBRARIES = \
        libmm.la
 
 libmm_la_SOURCES = \
+       codememory.c \
+       codememory.h \
+       dumpmemory.c \
+       dumpmemory.h \
        $(GC_FILE) \
        gc-common.h \
        memory.c \
index 997bce7b7171db57f36d0984a0ee07ed26f5c0d0..e21bc3d8dfe22efeef43bca48e5b9360c624af8c 100644 (file)
@@ -1,88 +1,88 @@
-# Makefile for Borland C++ 5.5 on NT
-# If you have the Borland assembler, remove "-DUSE_GENERIC"
-#
-bc=       c:\Borland\BCC55
-bcbin=    $(bc)\bin
-bclib=    $(bc)\lib
-bcinclude= $(bc)\include
-
-gcinclude1 = $(bc)\gc6.2\include
-gcinclude2 = $(bc)\gc6.2\cord
-
-cc=     $(bcbin)\bcc32
-rc=     $(bcbin)\brc32
-lib=    $(bcbin)\tlib
-link=   $(bcbin)\ilink32
-cflags=  -O2 -R -v- -vi -H -H=gc.csm -I$(bcinclude);$(gcinclude1);$(gcinclude2) -L$(bclib) \
-        -w-pro -w-aus -w-par -w-ccc -w-rch -a4 -D__STDC__=0
-#defines= -DSILENT
-defines= -DSILENT -DALL_INTERIOR_POINTERS -DUSE_GENERIC -DNO_GETENV -DJAVA_FINALIZATION -DGC_OPERATOR_NEW_ARRAY
-
-.c.obj:
-       $(cc) @&&|
-       $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.c
-|
-
-.cpp.obj:
-       $(cc) @&&|
-       $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.cpp
-|
-
-.rc.res:
-    $(rc) -i$(bcinclude) -r -fo$* $*.rc
-
-XXXOBJS= XXXalloc.obj XXXreclaim.obj XXXallchblk.obj XXXmisc.obj \
-    XXXmach_dep.obj XXXos_dep.obj XXXmark_rts.obj XXXheaders.obj XXXmark.obj \
-    XXXobj_map.obj XXXblacklst.obj XXXfinalize.obj XXXnew_hblk.obj \
-    XXXdbg_mlc.obj XXXmalloc.obj XXXstubborn.obj XXXdyn_load.obj \
-    XXXtypd_mlc.obj XXXptr_chck.obj XXXgc_cpp.obj XXXmallocx.obj
-
-OBJS= $(XXXOBJS:XXX=)
-
-all: gctest.exe cord\de.exe test_cpp.exe
-
-$(OBJS) test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h MAKEFILE
-
-gc.lib: $(OBJS)
-       del gc.lib
-       $(lib) $* @&&|
-       $(XXXOBJS:XXX=+)
-|
-
-gctest.exe: tests\test.obj gc.lib
-    $(cc) @&&|
-       $(cflags) -W -e$* tests\test.obj gc.lib
-|
-
-cord\de.obj cord\de_win.obj: include\cord.h include\private\cord_pos.h cord\de_win.h \
-    cord\de_cmds.h
-
-cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\de.obj cord\de_win.obj \
-       cord\de_win.res gc.lib
-       $(cc) @&&|
-       $(cflags) -W -e$* cord\cordbscs.obj cord\cordxtra.obj \
-       cord\de.obj cord\de_win.obj gc.lib
-|
-    $(rc) cord\de_win.res cord\de.exe
-
-gc_cpp.obj: include\gc_cpp.h include\gc.h
-
-gc_cpp.cpp: gc_cpp.cc
-       copy gc_cpp.cc gc_cpp.cpp
-
-test_cpp.cpp: tests\test_cpp.cc
-       copy tests\test_cpp.cc test_cpp.cpp
-
-test_cpp.exe: test_cpp.obj include\gc_cpp.h include\gc.h gc.lib
-    $(cc) @&&|
-       $(cflags) -W -e$* test_cpp.obj gc.lib
-|
-
-scratch:
-    -del *.obj *.res *.exe *.csm cord\*.obj cord\*.res cord\*.exe cord\*.csm
-
-clean:
-      del gc.lib
-      del *.obj
-      del tests\test.obj
-
+# Makefile for Borland C++ 5.5 on NT\r
+# If you have the Borland assembler, remove "-DUSE_GENERIC"\r
+#\r
+bc=       c:\Borland\BCC55\r
+bcbin=    $(bc)\bin\r
+bclib=    $(bc)\lib\r
+bcinclude= $(bc)\include\r
+\r
+gcinclude1 = $(bc)\gc6.2\include\r
+gcinclude2 = $(bc)\gc6.2\cord\r
+\r
+cc=     $(bcbin)\bcc32\r
+rc=     $(bcbin)\brc32\r
+lib=    $(bcbin)\tlib\r
+link=   $(bcbin)\ilink32\r
+cflags=  -O2 -R -v- -vi -H -H=gc.csm -I$(bcinclude);$(gcinclude1);$(gcinclude2) -L$(bclib) \\r
+        -w-pro -w-aus -w-par -w-ccc -w-rch -a4 -D__STDC__=0\r
+#defines= -DSILENT\r
+defines= -DSILENT -DALL_INTERIOR_POINTERS -DUSE_GENERIC -DNO_GETENV -DJAVA_FINALIZATION -DGC_OPERATOR_NEW_ARRAY\r
+\r
+.c.obj:\r
+       $(cc) @&&|\r
+       $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.c\r
+|\r
+\r
+.cpp.obj:\r
+       $(cc) @&&|\r
+       $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.cpp\r
+|\r
+\r
+.rc.res:\r
+    $(rc) -i$(bcinclude) -r -fo$* $*.rc\r
+\r
+XXXOBJS= XXXalloc.obj XXXreclaim.obj XXXallchblk.obj XXXmisc.obj \\r
+    XXXmach_dep.obj XXXos_dep.obj XXXmark_rts.obj XXXheaders.obj XXXmark.obj \\r
+    XXXobj_map.obj XXXblacklst.obj XXXfinalize.obj XXXnew_hblk.obj \\r
+    XXXdbg_mlc.obj XXXmalloc.obj XXXstubborn.obj XXXdyn_load.obj \\r
+    XXXtypd_mlc.obj XXXptr_chck.obj XXXgc_cpp.obj XXXmallocx.obj\r
+\r
+OBJS= $(XXXOBJS:XXX=)\r
+\r
+all: gctest.exe cord\de.exe test_cpp.exe\r
+\r
+$(OBJS) test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h MAKEFILE\r
+\r
+gc.lib: $(OBJS)\r
+       del gc.lib\r
+       $(lib) $* @&&|\r
+       $(XXXOBJS:XXX=+)\r
+|\r
+\r
+gctest.exe: tests\test.obj gc.lib\r
+    $(cc) @&&|\r
+       $(cflags) -W -e$* tests\test.obj gc.lib\r
+|\r
+\r
+cord\de.obj cord\de_win.obj: include\cord.h include\private\cord_pos.h cord\de_win.h \\r
+    cord\de_cmds.h\r
+\r
+cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\de.obj cord\de_win.obj \\r
+       cord\de_win.res gc.lib\r
+       $(cc) @&&|\r
+       $(cflags) -W -e$* cord\cordbscs.obj cord\cordxtra.obj \\r
+       cord\de.obj cord\de_win.obj gc.lib\r
+|\r
+    $(rc) cord\de_win.res cord\de.exe\r
+\r
+gc_cpp.obj: include\gc_cpp.h include\gc.h\r
+\r
+gc_cpp.cpp: gc_cpp.cc\r
+       copy gc_cpp.cc gc_cpp.cpp\r
+\r
+test_cpp.cpp: tests\test_cpp.cc\r
+       copy tests\test_cpp.cc test_cpp.cpp\r
+\r
+test_cpp.exe: test_cpp.obj include\gc_cpp.h include\gc.h gc.lib\r
+    $(cc) @&&|\r
+       $(cflags) -W -e$* test_cpp.obj gc.lib\r
+|\r
+\r
+scratch:\r
+    -del *.obj *.res *.exe *.csm cord\*.obj cord\*.res cord\*.exe cord\*.csm\r
+\r
+clean:\r
+      del gc.lib\r
+      del *.obj\r
+      del tests\test.obj\r
+\r
index 1265b1449ed6c8ff98e76582f2decfe91c0c32b1..9778feee97624ea5745e384fe7148259c6a52d27 100644 (file)
@@ -1,90 +1,90 @@
-# Makefile to build Hans Boehm garbage collector using the Digital Mars
-# compiler from www.digitalmars.com
-# Written by Walter Bright
-
-
-DEFINES=-DNDEBUG -DSILENT -DGC_BUILD -D_WINDOWS -DGC_DLL -DALL_INTERIOR_POINTERS -D__STDC__ -DWIN32_THREADS
-CFLAGS=-Iinclude $(DEFINES) -wx -g
-LFLAGS=/ma/implib/co
-CC=sc
-
-.c.obj:
-       $(CC) -c $(CFLAGS) $*
-
-.cpp.obj:
-       $(CC) -c $(CFLAGS) -Aa $*
-
-OBJS=  \
-       allchblk.obj\
-       alloc.obj\
-       blacklst.obj\
-       checksums.obj\
-       dbg_mlc.obj\
-       dyn_load.obj\
-       finalize.obj\
-       gc_cpp.obj\
-       headers.obj\
-       mach_dep.obj\
-       malloc.obj\
-       mallocx.obj\
-       mark.obj\
-       mark_rts.obj\
-       misc.obj\
-       new_hblk.obj\
-       obj_map.obj\
-       os_dep.obj\
-       ptr_chck.obj\
-       reclaim.obj\
-       stubborn.obj\
-       typd_mlc.obj\
-       win32_threads.obj
-
-targets: gc.dll gc.lib gctest.exe
-
-gc.dll: $(OBJS) gc.def digimars.mak
-       sc -ogc.dll $(OBJS) -L$(LFLAGS) gc.def  kernel32.lib user32.lib
-
-gc.def: digimars.mak
-       echo LIBRARY GC >gc.def
-       echo DESCRIPTION "Hans Boehm Garbage Collector" >>gc.def
-       echo EXETYPE NT >>gc.def
-       echo EXPORTS >>gc.def
-       echo GC_is_visible_print_proc >>gc.def
-       echo GC_is_valid_displacement_print_proc >>gc.def
-
-clean:
-       del gc.def
-       del $(OBJS)
-
-
-gctest.exe : gc.lib tests\test.obj
-       sc -ogctest.exe tests\test.obj gc.lib
-
-tests\test.obj : tests\test.c
-       $(CC) -c -g -DNDEBUG -DSILENT -DGC_BUILD -D_WINDOWS -DGC_DLL \
-       -DALL_INTERIOR_POINTERS -DWIN32_THREADS \
-       -Iinclude tests\test.c -otests\test.obj
-
-allchblk.obj: allchblk.c
-alloc.obj: alloc.c
-blacklst.obj: blacklst.c
-checksums.obj: checksums.c
-dbg_mlc.obj: dbg_mlc.c
-dyn_load.obj: dyn_load.c
-finalize.obj: finalize.c
-gc_cpp.obj: gc_cpp.cpp
-headers.obj: headers.c
-mach_dep.obj: mach_dep.c
-malloc.obj: malloc.c
-mallocx.obj: mallocx.c
-mark.obj: mark.c
-mark_rts.obj: mark_rts.c
-misc.obj: misc.c
-new_hblk.obj: new_hblk.c
-obj_map.obj: obj_map.c
-os_dep.obj: os_dep.c
-ptr_chck.obj: ptr_chck.c
-reclaim.obj: reclaim.c
-stubborn.obj: stubborn.c
-typd_mlc.obj: typd_mlc.c
-win32_threads.obj: win32_threads.c
+# Makefile to build Hans Boehm garbage collector using the Digital Mars\r
+# compiler from www.digitalmars.com\r
+# Written by Walter Bright\r
+\r
+\r
+DEFINES=-DNDEBUG -DSILENT -DGC_BUILD -D_WINDOWS -DGC_DLL -DALL_INTERIOR_POINTERS -D__STDC__ -DWIN32_THREADS\r
+CFLAGS=-Iinclude $(DEFINES) -wx -g\r
+LFLAGS=/ma/implib/co\r
+CC=sc\r
+\r
+.c.obj:\r
+       $(CC) -c $(CFLAGS) $*\r
+\r
+.cpp.obj:\r
+       $(CC) -c $(CFLAGS) -Aa $*\r
+\r
+OBJS=  \\r
+       allchblk.obj\\r
+       alloc.obj\\r
+       blacklst.obj\\r
+       checksums.obj\\r
+       dbg_mlc.obj\\r
+       dyn_load.obj\\r
+       finalize.obj\\r
+       gc_cpp.obj\\r
+       headers.obj\\r
+       mach_dep.obj\\r
+       malloc.obj\\r
+       mallocx.obj\\r
+       mark.obj\\r
+       mark_rts.obj\\r
+       misc.obj\\r
+       new_hblk.obj\\r
+       obj_map.obj\\r
+       os_dep.obj\\r
+       ptr_chck.obj\\r
+       reclaim.obj\\r
+       stubborn.obj\\r
+       typd_mlc.obj\\r
+       win32_threads.obj\r
+\r
+targets: gc.dll gc.lib gctest.exe\r
+\r
+gc.dll: $(OBJS) gc.def digimars.mak\r
+       sc -ogc.dll $(OBJS) -L$(LFLAGS) gc.def  kernel32.lib user32.lib\r
+\r
+gc.def: digimars.mak\r
+       echo LIBRARY GC >gc.def\r
+       echo DESCRIPTION "Hans Boehm Garbage Collector" >>gc.def\r
+       echo EXETYPE NT >>gc.def\r
+       echo EXPORTS >>gc.def\r
+       echo GC_is_visible_print_proc >>gc.def\r
+       echo GC_is_valid_displacement_print_proc >>gc.def\r
+\r
+clean:\r
+       del gc.def\r
+       del $(OBJS)\r
+\r
+\r
+gctest.exe : gc.lib tests\test.obj\r
+       sc -ogctest.exe tests\test.obj gc.lib\r
+\r
+tests\test.obj : tests\test.c\r
+       $(CC) -c -g -DNDEBUG -DSILENT -DGC_BUILD -D_WINDOWS -DGC_DLL \\r
+       -DALL_INTERIOR_POINTERS -DWIN32_THREADS \\r
+       -Iinclude tests\test.c -otests\test.obj\r
+\r
+allchblk.obj: allchblk.c\r
+alloc.obj: alloc.c\r
+blacklst.obj: blacklst.c\r
+checksums.obj: checksums.c\r
+dbg_mlc.obj: dbg_mlc.c\r
+dyn_load.obj: dyn_load.c\r
+finalize.obj: finalize.c\r
+gc_cpp.obj: gc_cpp.cpp\r
+headers.obj: headers.c\r
+mach_dep.obj: mach_dep.c\r
+malloc.obj: malloc.c\r
+mallocx.obj: mallocx.c\r
+mark.obj: mark.c\r
+mark_rts.obj: mark_rts.c\r
+misc.obj: misc.c\r
+new_hblk.obj: new_hblk.c\r
+obj_map.obj: obj_map.c\r
+os_dep.obj: os_dep.c\r
+ptr_chck.obj: ptr_chck.c\r
+reclaim.obj: reclaim.c\r
+stubborn.obj: stubborn.c\r
+typd_mlc.obj: typd_mlc.c\r
+win32_threads.obj: win32_threads.c\r
index c4f6a18b8ce2e56ac4973f538a52061845d16073..ab0fc912e53e6779ad8414d17a80ac136e6d9761 100644 (file)
@@ -1,9 +1,7 @@
 /* src/mm/boehm.c - interface for boehm 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -34,6 +32,9 @@
 #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"
@@ -73,6 +74,8 @@ void gc_init(u4 heapmaxsize, u4 heapstartsize)
 {
        size_t heapcurrentsize;
 
+       TRACESUBSYSTEMINITIALIZATION("gc_init");
+
        /* just to be sure (should be set to 1 by JAVA_FINALIZATION macro) */
 
        GC_java_finalization = 1;
@@ -114,7 +117,7 @@ static void gc_ignore_warnings(char *msg, GC_word arg)
 }
 
 
-void *heap_alloc_uncollectable(u4 size)
+void *heap_alloc_uncollectable(size_t size)
 {
        void *p;
 
index 6a4ef9f93a78be45104a854828afc02500b78934..1f8f5db417ab966ca231be28a922a910a92e961e 100644 (file)
@@ -1,9 +1,7 @@
 /* src/mm/cacao-gc/gc.c - main garbage collector methods
 
-   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, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
 
 #include "config.h"
+
 #include <signal.h>
+#include <stdint.h>
+
 #include "vm/types.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "compact.h"
 #include "copy.h"
@@ -138,7 +139,7 @@ static void gc_reference_register_intern(list_t *list, java_object_t **ref, int3
 
 #if !defined(NDEBUG)
        /* check if this reference is already registered */
-       for (re = list_first_unsynced(list); re != NULL; re = list_next_unsynced(list, re)) {
+       for (re = list_first(list); re != NULL; re = list_next(list, re)) {
                if (re->ref == ref)
                        vm_abort("gc_reference_register_intern: reference already registered");
        }
@@ -153,7 +154,7 @@ static void gc_reference_register_intern(list_t *list, java_object_t **ref, int3
 #endif
 
        /* add the entry to the given list */
-       list_add_last_unsynced(list, re);
+       list_add_last(list, re);
 
        /* the global GC lock also guards the reference lists */
        GC_MUTEX_UNLOCK;
@@ -186,10 +187,10 @@ static void gc_reference_unregister_intern(list_t *list, java_object_t **ref)
        GC_LOG2( printf("Un-Registering Reference at %p\n", (void *) ref); );
 
        /* search for the appropriate reference entry */
-       for (re = list_first_unsynced(list); re != NULL; re = list_next_unsynced(list, re)) {
+       for (re = list_first(list); re != NULL; re = list_next(list, re)) {
                if (re->ref == ref) {
                        /* remove the entry from the given list */
-                       list_remove_unsynced(list, re);
+                       list_remove(list, re);
 
                        /* free the reference entry */
                        FREE(re, list_gcref_entry_t);
@@ -231,10 +232,9 @@ void gc_weakreference_unregister(java_object_t **ref)
 void gc_collect(s4 level)
 {
        rootset_t    *rs;
-       s4            dumpsize;
+       int32_t       dumpmarker;
 #if !defined(NDEBUG)
-       stackframeinfo_t *sfi;
-       stacktracebuffer *stb;
+       stacktrace_t *st;
 #endif
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start, time_suspend, time_rootset, time_mark, time_compact, time_end;
@@ -244,7 +244,7 @@ void gc_collect(s4 level)
        GC_MUTEX_LOCK;
 
        /* remember start of dump memory area */
-       dumpsize = dump_size();
+       DMARKER;
 
        GCSTAT_COUNT(gcstat_collections);
 
@@ -269,11 +269,10 @@ void gc_collect(s4 level)
 #if !defined(NDEBUG)
        /* get the stacktrace of the current thread and make sure it is non-empty */
        GC_LOG( printf("Stacktrace of current thread:\n"); );
-       sfi = STACKFRAMEINFO;
-       stb = stacktrace_create(sfi);
-       if (stb == NULL)
+       st = stacktrace_get_current();
+       if (st == NULL)
                vm_abort("gc_collect: no stacktrace available for current thread!");
-       GC_LOG( stacktrace_print_trace_from_buffer(stb); );
+       GC_LOG( stacktrace_print(st); );
 #endif
 
        /* sourcestate of the current thread, assuming we are in the native world */
@@ -382,7 +381,7 @@ void gc_collect(s4 level)
        RT_TIMING_TIME_DIFF(time_start  , time_end    , RT_TIMING_GC_TOTAL);
 
     /* free dump memory area */
-    dump_release(dumpsize);
+    DRELEASE;
 
        /* leave the global gc lock */
        GC_MUTEX_UNLOCK;
index 68fbefd59c7befe0c0340f57edc977234ad59183..31060381d73868057a9a8dcbfb33960a0ee6cf40 100644 (file)
@@ -1,9 +1,7 @@
 /* src/mm/cacao-gc/gc.h - main garbage collector header
 
-   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.
 
@@ -37,9 +35,7 @@
 #include "config.h"
 #include "vm/types.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "toolbox/list.h"
 #include "vm/jit/replace.h"
index 7b7d514ac157a91d1de4e13081fa6a43ea963903..c2c8a5c9b71a4896bf5b2c9743b3c9b0e91830ae 100644 (file)
@@ -1,9 +1,7 @@
-/* mm/cacao-gc/mark.c - GC module for marking heap objects
+/* src/mm/cacao-gc/mark.c - GC module for marking heap objects
 
-   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.
 
@@ -191,8 +189,12 @@ void mark_post(rootset_t *rs)
 #if defined(GCCONF_FINALIZER)
        /* objects with finalizers will also be marked here. if they have not been
           marked before the finalization is triggered */
-       /* REMEMBER: all threads are stopped, so we can use unsynced access here */
-       fe = list_first_unsynced(final_list);
+
+       /* REMEMBER: All threads are stopped, so we don't have to lock the
+          list here. */
+
+       fe = list_first(final_list);
+
        while (fe) {
                f_type = fe->type;
                ref    = fe->o;
@@ -240,7 +242,7 @@ void mark_post(rootset_t *rs)
                        }
                }
 
-               fe = list_next_unsynced(final_list, fe);
+               fe = list_next(final_list, fe);
        }
 #endif /*defined(GCCONF_FINALIZER)*/
 
index 1eabc815426177d8ffb584aed256b1d6f43a49cb..89ac2c2018b6df521a8f32f70583ca6bb55db34d 100644 (file)
@@ -1,9 +1,7 @@
 /* mm/cacao-gc/rootset.c - GC module for root set 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 "final.h"
 #include "heap.h"
 #include "mark.h"
+
 #include "mm/memory.h"
-#include "threads/threads-common.h"
+
+#include "threads/threadlist.h"
+#include "threads/thread.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/global.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/stacktrace.h"
@@ -79,8 +82,8 @@ rootset_t *rootset_resize(rootset_t *rs)
    Searches global variables to compile the global root set out of references
    contained in them.
 
-   REMEMBER: All threads are stopped, so we can use unsynced access
-   in this function.
+   REMEMBER: All threads are stopped, so we don't have to lock the
+   lists in this function.
 
    SEARCHES IN:
      - thread objects (threads.c)
@@ -114,7 +117,7 @@ static rootset_t *rootset_from_globals(rootset_t *rs)
        refcount = rs->refcount;
 
        /* walk through all registered strong references */
-       for (re = list_first_unsynced(gc_reflist_strong); re != NULL; re = list_next_unsynced(gc_reflist_strong, re)) {
+       for (re = list_first(gc_reflist_strong); re != NULL; re = list_next(gc_reflist_strong, re)) {
                GC_LOG2( printf("Found Registered Reference: %p at %p of type %d\n", *(re->ref), re->ref, ref->reftype); );
 
                /* add this registered reference to the root set */
@@ -122,7 +125,7 @@ static rootset_t *rootset_from_globals(rootset_t *rs)
        }
 
        /* walk through all registered weak references */
-       for (re = list_first_unsynced(gc_reflist_weak); re != NULL; re = list_next_unsynced(gc_reflist_weak, re)) {
+       for (re = list_first(gc_reflist_weak); re != NULL; re = list_next(gc_reflist_weak, re)) {
                GC_LOG2( printf("Found Registered Weak Reference: %p at %p of type %d\n", *(re->ref), re->ref, ref->reftype); );
 
                /* add this registered reference to the root set */
@@ -130,7 +133,7 @@ static rootset_t *rootset_from_globals(rootset_t *rs)
        }
 
        /* walk through all finalizer entries */
-       for (fe = list_first_unsynced(final_list); fe != NULL; fe = list_next_unsynced(final_list, fe)) {
+       for (fe = list_first(final_list); fe != NULL; fe = list_next(final_list, fe)) {
                GC_LOG2( printf("Found Finalizer Entry: %p\n", (void *) fe->o); );
 
                /* add this object with finalizer to the root set */
@@ -328,7 +331,7 @@ rootset_t *rootset_readout()
 {
        rootset_t    *rs_top;
        rootset_t    *rs;
-       threadobject *thread;
+       threadobject *t;
 
        /* find the global rootset ... */
        rs_top = rootset_create();
@@ -338,22 +341,22 @@ rootset_t *rootset_readout()
        /* ... and the rootsets for the threads */
        rs = rs_top;
 #if defined(ENABLE_THREADS)
-       for (thread = threads_list_first(); thread != NULL; thread = threads_list_next(thread)) {
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
 
                /* ignore threads which are in state NEW */
-               if (thread->state == THREAD_STATE_NEW)
+               if (t->state == THREAD_STATE_NEW)
                        continue;
 
                rs->next = rootset_create();
-               rs->next = rootset_from_thread(thread, rs->next);
+               rs->next = rootset_from_thread(t, rs->next);
 
                rs = rs->next;
        }
 #else
-       thread = THREADOBJECT;
+       t = THREADOBJECT;
 
        rs->next = rootset_create();
-       rs->next = rootset_from_thread(thread, rs->next);
+       rs->next = rootset_from_thread(t, rs->next);
 #endif
 
        return rs_top;
index 184c6b15389e25c7fe6eb60348f86447d80c152e..e61315f555a6fae6bdd8955515b270bcd31c65fa 100644 (file)
@@ -1,9 +1,7 @@
-/* mm/cacao-gc/rootset.h - GC header for root set management
+/* src/mm/cacao-gc/rootset.h - GC header for root set 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.
 
@@ -33,11 +31,7 @@ typedef struct rootset_t rootset_t;
 #include "config.h"
 #include "vm/types.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#else
-# include "threads/none/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/jit/replace.h"
 #include "vmcore/method.h"
diff --git a/src/mm/codememory.c b/src/mm/codememory.c
new file mode 100644 (file)
index 0000000..7d2fd89
--- /dev/null
@@ -0,0 +1,178 @@
+/* src/mm/codememory.c - code memory management
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/mman.h> /* REMOVEME */
+
+#include "threads/lock-common.h"
+#include "threads/thread.h"
+
+#include "mm/codememory.h"
+#include "mm/memory.h"
+
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#include "vmcore/system.h"
+
+#include "vm/global.h"
+
+
+/* global code memory variables ***********************************************/
+
+#define DEFAULT_CODE_MEMORY_SIZE    128 * 1024 /* defaulting to 128kB         */
+
+#if defined(ENABLE_THREADS)
+static java_object_t *lock_code_memory = NULL;
+#endif
+static void          *code_memory      = NULL;
+static int            code_memory_size = 0;
+static int            pagesize         = 0;
+
+
+/* codememory_init *************************************************************
+
+   Initialize the code memory subsystem.
+
+*******************************************************************************/
+
+void codememory_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("codememory_init");
+
+#if defined(ENABLE_THREADS)
+       /* create lock for code memory */
+
+       lock_code_memory = NEW(java_object_t);
+
+       lock_init_object_lock(lock_code_memory);
+#endif
+
+       /* Get the pagesize of this architecture. */
+
+       pagesize = system_getpagesize();
+}
+
+
+/* codememory_get **************************************************************
+
+   Allocates memory from the heap via mmap and make the memory read-,
+   write-, and executeable.
+
+*******************************************************************************/
+
+void *codememory_get(size_t size)
+{
+       void *p;
+
+       LOCK_MONITOR_ENTER(lock_code_memory);
+
+       size = MEMORY_ALIGN(size, ALIGNSIZE);
+
+       /* check if enough memory is available */
+
+       if (size > code_memory_size) {
+               /* set default code size */
+
+               code_memory_size = DEFAULT_CODE_MEMORY_SIZE;
+
+               /* do we need more? */
+
+               if (size > code_memory_size)
+                       code_memory_size = size;
+
+               /* align the size of the memory to be allocated */
+
+               code_memory_size = MEMORY_ALIGN(code_memory_size, pagesize);
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat) {
+                       codememusage += code_memory_size;
+
+                       if (codememusage > maxcodememusage)
+                               maxcodememusage = codememusage;
+               }
+#endif
+
+               /* allocate the memory */
+
+               p = system_mmap_anonymous(NULL, code_memory_size,
+                                                                 PROT_READ | PROT_WRITE | PROT_EXEC,
+                                                                 MAP_PRIVATE);
+
+               /* set global code memory pointer */
+
+               code_memory = p;
+       }
+
+       /* get a memory chunk of the allocated memory */
+
+       p = code_memory;
+
+       code_memory       = (void *) ((ptrint) code_memory + size);
+       code_memory_size -= size;
+
+       LOCK_MONITOR_EXIT(lock_code_memory);
+
+       return p;
+}
+
+
+/* codememory_release **********************************************************
+
+   Release the code memory and return it to the code memory
+   management.
+
+   IN:
+       p ...... pointer to the code memory
+          size ... size of the code memory
+
+*******************************************************************************/
+
+void codememory_release(void *p, size_t size)
+{
+       /* do nothing */
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of 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/codememory.h b/src/mm/codememory.h
new file mode 100644 (file)
index 0000000..c9dd383
--- /dev/null
@@ -0,0 +1,63 @@
+/* src/mm/codememory.h - code memory management
+
+   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 _CODEMEMORY_H
+#define _CODEMEMORY_H
+
+#include "config.h"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+
+/* convenience macros *********************************************************/
+
+#define CNEW(type,num)        ((type *) codememory_get(sizeof(type) * (num)))
+#define CFREE(ptr,num)        codememory_release((ptr),(num))
+
+
+/* function prototypes ********************************************************/
+
+void  codememory_init(void);
+
+void *codememory_get(size_t size);
+void  codememory_release(void *p, size_t size);
+
+#endif /* _CODEMEMORY_H */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/mm/dumpmemory.c b/src/mm/dumpmemory.c
new file mode 100644 (file)
index 0000000..0dc1915
--- /dev/null
@@ -0,0 +1,482 @@
+/* src/mm/dumpmemory.c - dump memory management
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "mm/dumpmemory.h"
+#include "mm/memory.h"
+
+#include "threads/thread.h"
+
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#include "vmcore/system.h"
+
+#include "vm/vm.h"
+
+
+/*******************************************************************************
+
+  This structure is used for dump memory allocation if cacao
+  runs without threads.
+
+*******************************************************************************/
+
+#if !defined(ENABLE_THREADS)
+static dumpinfo_t _no_threads_dumpinfo;
+#endif
+
+#if defined(ENABLE_THREADS)
+#define DUMPINFO    &((threadobject *) THREADOBJECT)->dumpinfo
+#else
+#define DUMPINFO    &_no_threads_dumpinfo
+#endif
+
+
+/* dump_check_canaries *********************************************************
+
+   Check canaries in dump memory.
+
+   IN:
+      di...........dumpinfo_t * of the dump area to check
+         bottomsize...dump size down to which the dump area should be checked
+                      (specify 0 to check the whole dump area)
+
+   ERROR HANDLING:
+      If any canary has been changed, this function aborts the VM with
+         an error message.
+
+*******************************************************************************/
+
+#if defined(ENABLE_MEMCHECK)
+static void dump_check_canaries(dumpinfo_t *di, s4 bottomsize)
+{
+       dump_allocation_t *da;
+       uint8_t           *pm;
+       int                i, j;
+
+       /* iterate over all dump memory allocations above bottomsize */
+
+       da = di->allocations;
+
+       while (da && da->used >= bottomsize) {
+               /* check canaries */
+
+               pm = ((uint8_t *) da->mem) - MEMORY_CANARY_SIZE;
+
+               for (i = 0; i < MEMORY_CANARY_SIZE; ++i) {
+                       if (pm[i] != i + MEMORY_CANARY_FIRST_BYTE) {
+                               fprintf(stderr, "canary bytes:");
+
+                               for (j = 0; j < MEMORY_CANARY_SIZE; ++j)
+                                       fprintf(stderr, " %02x", pm[j]);
+
+                               fprintf(stderr,"\n");
+
+                               vm_abort("error: dump memory bottom canary killed: "
+                                                "%p (%d bytes allocated at %p)\n",
+                                                pm + i, da->size, da->mem);
+                       }
+               }
+
+               pm = ((uint8_t *) da->mem) + da->size;
+
+               for (i = 0; i < MEMORY_CANARY_SIZE; ++i) {
+                       if (pm[i] != i + MEMORY_CANARY_FIRST_BYTE) {
+                               fprintf(stderr, "canary bytes:");
+
+                               for (j = 0; j < MEMORY_CANARY_SIZE; ++j)
+                                       fprintf(stderr, " %02x", pm[j]);
+
+                               fprintf(stderr, "\n");
+
+                               vm_abort("error: dump memory top canary killed: "
+                                                "%p (%d bytes allocated at %p)\n",
+                                                pm + i, da->size, da->mem);
+                       }
+               }
+
+               da = da->next;
+       }
+}
+#endif /* defined(ENABLE_MEMCHECK) */
+
+
+/* dumpmemory_alloc ************************************************************
+
+   ATTENTION: This function must only be called from dumpmemory_get!
+
+   Allocate a new dump memory block.
+
+   IN:
+      di ..... dumpinfo_t of the current thread
+      size ... required memory size
+
+*******************************************************************************/
+
+void dumpmemory_alloc(dumpinfo_t *di, size_t size)
+{
+       dumpblock_t *db;
+       size_t       newblocksize;
+
+       /* Allocate a new dumpblock_t structure. */
+
+       db = memory_checked_alloc(sizeof(dumpblock_t));
+
+       /* If requested size is greater than the default, make the new
+          dump block as big as the size requested. Else use the default
+          size. */
+
+       if (size > DUMPBLOCKSIZE) {
+               newblocksize = size;
+       }
+       else {
+               newblocksize = DUMPBLOCKSIZE;
+       }
+
+       /* allocate dumpblock memory */
+
+       db->dumpmem = memory_checked_alloc(newblocksize);
+
+       db->size  = newblocksize;
+       db->prev  = di->block;
+       di->block = db;
+
+       /* Used dump size is previously allocated dump size, because the
+          remaining free memory of the previous dump block cannot be
+          used. */
+
+       di->used = di->allocated;
+
+       /* Increase the allocated dump size by the size of the new dump
+          block. */
+
+       di->allocated += newblocksize;
+
+#if defined(ENABLE_STATISTICS)
+       /* The amount of globally allocated dump memory (thread save). */
+
+       if (opt_stat)
+               globalallocateddumpsize += newblocksize;
+#endif
+}
+
+
+/* dumpmemory_get **************************************************************
+
+   Allocate memory in the dump area.
+
+   IN:
+      size.........size of block to allocate, in bytes
+                                  may be zero, in which case NULL is returned
+
+   RETURN VALUE:
+      pointer to allocated memory, or
+         NULL iff `size` was zero
+
+   ERROR HANDLING:
+      XXX This function uses `memory_checked_alloc`, which *exits* if
+         no memory could be allocated.
+
+   THREADS:
+      dumpmemory_get is thread safe. Each thread has its own dump
+      memory area.
+
+   This function is a fast allocator suitable for scratch memory that
+   can be collectively freed when the current activity (eg. compiling)
+   is done.
+
+   You cannot selectively free dump memory. Before you start
+   allocating it, you remember the current size returned by
+   `dumpmemory_marker`. Later, when you no longer need the memory,
+   call `dumpmemory_release` with the remembered size and all dump
+   memory allocated since the call to `dumpmemory_marker` will be
+   freed.
+
+*******************************************************************************/
+
+void *dumpmemory_get(size_t size)
+{
+#if defined(DISABLE_DUMP)
+
+       /* use malloc memory for dump memory (for debugging only!) */
+
+       return mem_alloc(size);
+
+#else /* !defined(DISABLE_DUMP) */
+
+       void       *p;
+       dumpinfo_t *di;
+#if defined(ENABLE_MEMCHECK)
+       s4          origsize = size; /* needed for the canary system */
+#endif
+
+       di = DUMPINFO;
+
+       if (size == 0)
+               return NULL;
+
+#if defined(ENABLE_MEMCHECK)
+       size += 2 * MEMORY_CANARY_SIZE;
+#endif
+
+       size = MEMORY_ALIGN(size, ALIGNSIZE);
+
+       /* Check if we have enough memory in the current memory block. */
+
+       if (di->used + size > di->allocated) {
+               /* If not, allocate a new one. */
+
+               dumpmemory_alloc(di, size);
+       }
+
+       /* current dump block base address + the size of the current dump
+          block - the size of the unused memory = new start address  */
+
+       p = ((uint8_t *) di->block->dumpmem) + di->block->size -
+               (di->allocated - di->used);
+
+#if defined(ENABLE_MEMCHECK)
+       {
+               dump_allocation_t *da = NEW(dump_allocation_t);
+               uint8_t           *pm;
+               int                i;
+
+               /* add the allocation to our linked list of allocations */
+
+               da->next = di->allocations;
+               da->mem  = ((uint8_t *) p) + MEMORY_CANARY_SIZE;
+               da->size = origsize;
+               da->used = di->used;
+
+               di->allocations = da;
+
+               /* write the canaries */
+
+               pm = (uint8_t *) p;
+
+               for (i = 0; i < MEMORY_CANARY_SIZE; ++i)
+                       pm[i] = i + MEMORY_CANARY_FIRST_BYTE;
+
+               pm = ((uint8_t *) da->mem) + da->size;
+
+               for (i = 0; i < MEMORY_CANARY_SIZE; ++i)
+                       pm[i] = i + MEMORY_CANARY_FIRST_BYTE;
+
+               /* make m point after the bottom canary */
+
+               p = ((uint8_t *) p) + MEMORY_CANARY_SIZE;
+
+               /* clear the memory */
+
+               (void) system_memset(p, MEMORY_CLEAR_BYTE, da->size);
+       }
+#endif /* defined(ENABLE_MEMCHECK) */
+
+       /* Increase used dump size by the allocated memory size. */
+
+       di->used += size;
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               if (di->used > maxdumpsize)
+                       maxdumpsize = di->used;
+#endif
+
+       return p;
+
+#endif /* defined(DISABLE_DUMP) */
+}
+
+
+/* dumpmemory_realloc **********************************************************
+
+   Stupid realloc implementation for dump memory. Avoid, if possible.
+
+*******************************************************************************/
+
+void *dumpmemory_realloc(void *src, s4 len1, s4 len2)
+{
+#if defined(DISABLE_DUMP)
+       /* use malloc memory for dump memory (for debugging only!) */
+
+       return mem_realloc(src, len1, len2);
+#else
+       void *dst;
+
+       dst = dumpmemory_get(len2);
+
+       (void) system_memcpy(dst, src, len1);
+
+#if defined(ENABLE_MEMCHECK)
+       /* destroy the source */
+
+       (void) system_memset(src, MEMORY_CLEAR_BYTE, len1);
+#endif
+
+       return dst;
+#endif
+}
+
+
+/* dumpmemory_release **********************************************************
+
+   Release dump memory above the given size.
+
+   IN:
+       size........All dump memory above this mark will be freed. Usually
+                      `size` will be the return value of a `dumpmemory_marker`
+                                  call made earlier.
+
+       ERROR HANDLING:
+          XXX If the given size is invalid, this function *exits* with an
+              error message.
+                                  
+       See `dump_alloc`.
+
+*******************************************************************************/
+
+void dumpmemory_release(s4 size)
+{
+#if defined(DISABLE_DUMP)
+
+       /* use malloc memory for dump memory (for debugging only!) */
+
+       /* do nothing */
+
+#else /* !defined(DISABLE_DUMP) */
+
+       dumpinfo_t *di;
+
+       di = DUMPINFO;
+
+       if ((size < 0) || (size > di->used))
+               vm_abort("dump_release: Illegal dump release size: %d", size);
+
+#if defined(ENABLE_MEMCHECK)
+       {
+               dump_allocation_t *da, *next;
+
+               /* check canaries */
+
+               dump_check_canaries(di, size);
+
+               /* iterate over all dump memory allocations about to be released */
+
+               da = di->allocations;
+
+               while ((da != NULL) && (da->used >= size)) {
+                       next = da->next;
+
+                       /* invalidate the freed memory */
+
+                       (void) system_memset(da->mem, MEMORY_CLEAR_BYTE, da->size);
+
+                       FREE(da, dump_allocation_t);
+
+                       da = next;
+               }
+               di->allocations = da;
+       }
+#endif /* defined(ENABLE_MEMCHECK) */
+
+       /* Reset the used dump size to the size specified. */
+
+       di->used = size;
+
+       while ((di->block != NULL) && di->allocated - di->block->size >= di->used) {
+               dumpblock_t *tmp = di->block;
+
+               di->allocated -= tmp->size;
+               di->block      = tmp->prev;
+
+#if defined(ENABLE_STATISTICS)
+               /* the amount of globally allocated dump memory (thread save) */
+
+               if (opt_stat)
+                       globalallocateddumpsize -= tmp->size;
+#endif
+
+               /* Release the dump memory and the dumpinfo structure. */
+
+               system_free(tmp->dumpmem);
+               system_free(tmp);
+       }
+
+#endif /* defined(DISABLE_DUMP) */
+}
+
+
+/* dumpmemory_marker ***********************************************************
+
+   Returns a marker of the dump memory area.  This marker is actually
+   the used size of the dump memory area.
+
+   RETURN VALUE:
+       marker of the current dump memory status
+
+*******************************************************************************/
+
+int32_t dumpmemory_marker(void)
+{
+#if defined(DISABLE_DUMP)
+       /* use malloc memory for dump memory (for debugging only!) */
+
+       return 0;
+
+#else /* !defined(DISABLE_DUMP) */
+
+       dumpinfo_t *di;
+
+       di = DUMPINFO;
+
+       if (di == NULL)
+               return 0;
+
+       return di->used;
+
+#endif /* defined(DISABLE_DUMP) */
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of 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/dumpmemory.h b/src/mm/dumpmemory.h
new file mode 100644 (file)
index 0000000..f519777
--- /dev/null
@@ -0,0 +1,118 @@
+/* src/mm/dumpmemory.h - dump memory management
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _DUMPMEMORY_H
+#define _DUMPMEMORY_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct dumpblock_t dumpblock_t;
+typedef struct dumpinfo_t  dumpinfo_t;
+
+#include "config.h"
+
+#include <stdint.h>
+#include <string.h>
+
+
+/* ATTENTION: We need to define dumpblock_t and dumpinfo_t before
+   internal includes, as we need dumpinfo_t as nested structure in
+   threadobject. */
+
+/* dumpblock ******************************************************************/
+
+#define DUMPBLOCKSIZE    2 << 13    /* 2 * 8192 bytes */
+#define ALIGNSIZE        8
+
+struct dumpblock_t {
+       dumpblock_t *prev;
+       void        *dumpmem;
+       int32_t      size;
+};
+
+
+/* dump_allocation *************************************************************
+
+   This struct is used to record dump memory allocations for ENABLE_MEMCHECK.
+
+*******************************************************************************/
+
+#if defined(ENABLE_MEMCHECK)
+typedef struct dump_allocation_t dump_allocation_t;
+
+struct dump_allocation_t {
+       dump_allocation_t *next;
+       void              *mem;
+       int32_t            used;
+       int32_t            size;
+};
+#endif
+
+
+/* dumpinfo *******************************************************************/
+
+struct dumpinfo_t {
+       dumpblock_t       *block;                   /* the current top-most block */
+       int32_t            allocated;             /* allocated bytes in this area */
+       int32_t            used;                  /* used bytes in this dump area */
+#if defined(ENABLE_MEMCHECK)
+       dump_allocation_t *allocations;       /* list of allocations in this area */
+#endif
+};
+
+
+/* convenience macros *********************************************************/
+
+#define DMARKER               dumpmarker = dumpmemory_marker()
+#define DRELEASE              dumpmemory_release(dumpmarker)
+
+#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))
+
+/* function prototypes ********************************************************/
+
+void    *dumpmemory_get(size_t size);
+void    *dumpmemory_realloc(void *src, int32_t len1, int32_t len2);
+int32_t  dumpmemory_marker(void);
+void     dumpmemory_release(int32_t size);
+
+#endif /* _DUMPMEMORY_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 f3b6ff9259c19f10a28a78952173e691d8b97987..7bdf5cb57bfd70d6faebdce7adda481f3e1f3b42 100644 (file)
@@ -1,9 +1,7 @@
 /* src/mm/gc-common.h - gc independant interface for heap managment
 
-   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.
 
@@ -56,7 +54,7 @@ enum {
 
 void  gc_init(u4 heapmaxsize, u4 heapstartsize);
 
-void *heap_alloc_uncollectable(u4 size);
+void *heap_alloc_uncollectable(size_t size);
 void *heap_alloc(u4 size, u4 references, methodinfo *finalizer, bool collect);
 void  heap_free(void *p);
 
index 1be484983769978db63bb694c011f0ee5dba219a..0b74e53517e14d2a2fa788716ef834917addf308 100644 (file)
@@ -1,9 +1,7 @@
 /* src/mm/memory.c - memory management
 
-   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 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/mman.h>
 
 #if defined(__DARWIN__)
 /* If we compile with -ansi on darwin, <sys/types.h> is not
@@ -50,7 +47,7 @@
 #include "native/native.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
 # include "vmcore/statistics.h"
 #endif
 
-
-/*******************************************************************************
-
-  This structure is used for dump memory allocation if cacao
-  runs without threads.
-
-*******************************************************************************/
-
-#if !defined(ENABLE_THREADS)
-static dumpinfo_t _no_threads_dumpinfo;
-#endif
-
-#if defined(ENABLE_THREADS)
-#define DUMPINFO    &((threadobject *) THREADOBJECT)->dumpinfo
-#else
-#define DUMPINFO    &_no_threads_dumpinfo
-#endif
-
-
-/* global code memory variables ***********************************************/
-
-#define DEFAULT_CODE_MEMORY_SIZE    128 * 1024 /* defaulting to 128kB         */
-
-#if defined(ENABLE_THREADS)
-static java_object_t *lock_code_memory = NULL;
-#endif
-static void          *code_memory      = NULL;
-static int            code_memory_size = 0;
-static int            pagesize         = 0;
-
-
-/* memory_init *****************************************************************
-
-   Initialize the memory subsystem.
-
-*******************************************************************************/
-
-bool memory_init(void)
-{
-#if defined(ENABLE_THREADS)
-       /* create lock for code memory */
-
-       lock_code_memory = NEW(java_object_t);
-
-       lock_init_object_lock(lock_code_memory);
-#endif
-
-       /* get the pagesize of this architecture */
-
-       pagesize = getpagesize();
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* memory_mmap_anon ************************************************************
-
-   Maps anonymous memory, even on systems not defining
-   MAP_ANON(YMOUS).
-
-*******************************************************************************/
-
-void *memory_mmap_anon(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("memory_mmap_anon: 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("memory_mmap_anon: mmap failed: %s", strerror(errno));
-
-       return p;
-}
+#include "vmcore/system.h"
 
 
 /* memory_mprotect *************************************************************
@@ -172,8 +74,9 @@ void *memory_mmap_anon(void *addr, size_t len, int prot, int flags)
 
 void memory_mprotect(void *addr, size_t len, int prot)
 {
-       if (mprotect(addr, len, prot) != 0)
-               vm_abort("memory_mprotect: mprotect failed: %s", strerror(errno));
+       if (system_mprotect(addr, len, prot) != 0)
+               vm_abort("memory_mprotect: system_mprotect failed: %s",
+                                strerror(errno));
 }
 
 
@@ -186,7 +89,7 @@ void memory_mprotect(void *addr, size_t len, int prot)
 
 *******************************************************************************/
 
-static void *memory_checked_alloc(s4 size)
+void *memory_checked_alloc(size_t size)
 {
        /* always allocate memory zeroed out */
 
@@ -199,86 +102,7 @@ static void *memory_checked_alloc(s4 size)
 }
 
 
-/* memory_cnew *****************************************************************
-
-   Allocates memory from the heap via mmap and make the memory read-,
-   write-, and executeable.
-
-*******************************************************************************/
-
-void *memory_cnew(s4 size)
-{
-       void *p;
-
-       LOCK_MONITOR_ENTER(lock_code_memory);
-
-       size = MEMORY_ALIGN(size, ALIGNSIZE);
-
-       /* check if enough memory is available */
-
-       if (size > code_memory_size) {
-               /* set default code size */
-
-               code_memory_size = DEFAULT_CODE_MEMORY_SIZE;
-
-               /* do we need more? */
-
-               if (size > code_memory_size)
-                       code_memory_size = size;
-
-               /* align the size of the memory to be allocated */
-
-               code_memory_size = MEMORY_ALIGN(code_memory_size, pagesize);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat) {
-                       codememusage += code_memory_size;
-
-                       if (codememusage > maxcodememusage)
-                               maxcodememusage = codememusage;
-               }
-#endif
-
-               /* allocate the memory */
-
-               p = memory_mmap_anon(NULL, code_memory_size,
-                                                        PROT_READ | PROT_WRITE | PROT_EXEC,
-                                                        MAP_PRIVATE);
-
-               /* set global code memory pointer */
-
-               code_memory = p;
-       }
-
-       /* get a memory chunk of the allocated memory */
-
-       p = code_memory;
-
-       code_memory       = (void *) ((ptrint) code_memory + size);
-       code_memory_size -= size;
-
-       LOCK_MONITOR_EXIT(lock_code_memory);
-
-       return p;
-}
-
-
-/* memory_cfree ****************************************************************
-
-   Frees the code memory pointed to.
-
-   ATTENTION: This function currently does NOTHING!  Because we don't
-   have a memory management for code memory.
-
-*******************************************************************************/
-
-void memory_cfree(void *p, s4 size)
-{
-       /* do nothing */
-}
-
-
-void *mem_alloc(s4 size)
+void *mem_alloc(int32_t size)
 {
        void *m;
 
@@ -306,7 +130,7 @@ void *mem_alloc(s4 size)
 }
 
 
-void *mem_realloc(void *src, s4 len1, s4 len2)
+void *mem_realloc(void *src, int32_t len1, int32_t len2)
 {
        void *dst;
 
@@ -342,7 +166,7 @@ void *mem_realloc(void *src, s4 len1, s4 len2)
 }
 
 
-void mem_free(void *m, s4 size)
+void mem_free(void *m, int32_t size)
 {
        if (!m) {
                if (size == 0)
@@ -377,6 +201,10 @@ static void memory_thread(void)
 {
        int32_t seconds;
 
+       /* Prevent compiler warning. */
+
+       seconds = 1;
+
        /* If both arguments are specified, use the value of
           ProfileMemoryUsage. */
 
@@ -438,370 +266,6 @@ bool memory_start_thread(void)
 #endif
 
 
-/* dump_check_canaries *********************************************************
-
-   Check canaries in dump memory.
-
-   IN:
-      di...........dumpinfo_t * of the dump area to check
-         bottomsize...dump size down to which the dump area should be checked
-                      (specify 0 to check the whole dump area)
-
-   ERROR HANDLING:
-      If any canary has been changed, this function aborts the VM with
-         an error message.
-
-*******************************************************************************/
-
-#if defined(ENABLE_MEMCHECK)
-void dump_check_canaries(dumpinfo_t *di, s4 bottomsize)
-{
-       dump_allocation_t *da;
-       u1 *pm;
-       s4 i, j;
-
-       /* iterate over all dump memory allocations above bottomsize */
-
-       da = di->allocations;
-       while (da && da->useddumpsize >= bottomsize) {
-               /* check canaries */
-
-               pm = da->mem - MEMORY_CANARY_SIZE;
-               for (i=0; i<MEMORY_CANARY_SIZE; ++i)
-                       if (pm[i] != i + MEMORY_CANARY_FIRST_BYTE) {
-                               fprintf(stderr, "canary bytes:");
-                               for (j=0; j<MEMORY_CANARY_SIZE; ++j)
-                                       fprintf(stderr, " %02x", pm[j]);
-                               fprintf(stderr,"\n");
-                               vm_abort("error: dump memory bottom canary killed: "
-                                                "%p (%d bytes allocated at %p)\n",
-                                               pm + i, da->size, da->mem);
-                       }
-
-               pm = da->mem + da->size;
-               for (i=0; i<MEMORY_CANARY_SIZE; ++i)
-                       if (pm[i] != i + MEMORY_CANARY_FIRST_BYTE) {
-                               fprintf(stderr, "canary bytes:");
-                               for (j=0; j<MEMORY_CANARY_SIZE; ++j)
-                                       fprintf(stderr, " %02x", pm[j]);
-                               fprintf(stderr,"\n");
-                               vm_abort("error: dump memory top canary killed: "
-                                                "%p (%d bytes allocated at %p)\n",
-                                               pm + i, da->size, da->mem);
-                       }
-
-               da = da->next;
-       }
-}
-#endif /* defined(ENABLE_MEMCHECK) */
-
-
-/* dump_alloc ******************************************************************
-
-   Allocate memory in the dump area.
-
-   IN:
-      size.........size of block to allocate, in bytes
-                                  may be zero, in which case NULL is returned
-
-   RETURN VALUE:
-      pointer to allocated memory, or
-         NULL iff `size` was zero
-
-   ERROR HANDLING:
-      XXX This function uses `memory_checked_alloc`, which *exits* if no 
-         memory could be allocated.
-
-   THREADS:
-      dump_alloc is thread safe. Each thread has its own dump memory area.
-
-   dump_alloc is a fast allocator suitable for scratch memory that can be
-   collectively freed when the current activity (eg. compiling) is done.
-
-   You cannot selectively free dump memory. Before you start allocating it, 
-   you remember the current size returned by `dump_size`. Later, when you no 
-   longer need the memory, call `dump_release` with the remembered size and
-   all dump memory allocated since the call to `dump_size` will be freed.
-
-*******************************************************************************/
-
-void *dump_alloc(s4 size)
-{
-#if defined(DISABLE_DUMP)
-
-       /* use malloc memory for dump memory (for debugging only!) */
-
-       return mem_alloc(size);
-
-#else /* !defined(DISABLE_DUMP) */
-
-       void       *m;
-       dumpinfo_t *di;
-#if defined(ENABLE_MEMCHECK)
-       s4          origsize = size; /* needed for the canary system */
-#endif
-
-       /* If no threads are used, the dumpinfo structure is a static structure   */
-       /* defined at the top of this file.                                       */
-
-       di = DUMPINFO;
-
-       if (size == 0)
-               return NULL;
-
-#if defined(ENABLE_MEMCHECK)
-       size += 2*MEMORY_CANARY_SIZE;
-#endif
-
-       size = MEMORY_ALIGN(size, ALIGNSIZE);
-
-       if (di->useddumpsize + size > di->allocateddumpsize) {
-               dumpblock_t *newdumpblock;
-               s4         newdumpblocksize;
-
-               /* allocate a new dumplist structure */
-
-               newdumpblock = memory_checked_alloc(sizeof(dumpblock_t));
-
-               /* If requested size is greater than the default, make the new dump   */
-               /* block as big as the size requested. Else use the default size.     */
-
-               if (size > DUMPBLOCKSIZE) {
-                       newdumpblocksize = size;
-
-               } else {
-                       newdumpblocksize = DUMPBLOCKSIZE;
-               }
-
-               /* allocate dumpblock memory */
-
-               newdumpblock->dumpmem = memory_checked_alloc(newdumpblocksize);
-
-               newdumpblock->prev = di->currentdumpblock;
-               newdumpblock->size = newdumpblocksize;
-               di->currentdumpblock = newdumpblock;
-
-               /* Used dump size is previously allocated dump size, because the      */
-               /* remaining free memory of the previous dump block cannot be used.   */
-
-               di->useddumpsize = di->allocateddumpsize;
-
-               /* increase the allocated dump size by the size of the new dump block */
-
-               di->allocateddumpsize += newdumpblocksize;
-
-#if defined(ENABLE_STATISTICS)
-               /* the amount of globally allocated dump memory (thread save) */
-
-               if (opt_stat)
-                       globalallocateddumpsize += newdumpblocksize;
-#endif
-       }
-
-       /* current dump block base address + the size of the current dump block - */
-       /* the size of the unused memory = new start address                      */
-
-       m = di->currentdumpblock->dumpmem + di->currentdumpblock->size -
-               (di->allocateddumpsize - di->useddumpsize);
-
-#if defined(ENABLE_MEMCHECK)
-       {
-               dump_allocation_t *da = NEW(dump_allocation_t);
-               s4 i;
-               u1 *pm;
-
-               /* add the allocation to our linked list of allocations */
-
-               da->next = di->allocations;
-               da->mem = (u1*) m + MEMORY_CANARY_SIZE;
-               da->size = origsize;
-               da->useddumpsize = di->useddumpsize;
-
-               di->allocations = da;
-
-               /* write the canaries */
-
-               pm = (u1*)m;
-               for (i=0; i<MEMORY_CANARY_SIZE; ++i)
-                       pm[i] = i + MEMORY_CANARY_FIRST_BYTE;
-               pm = da->mem + da->size;
-               for (i=0; i<MEMORY_CANARY_SIZE; ++i)
-                       pm[i] = i + MEMORY_CANARY_FIRST_BYTE;
-
-               /* make m point after the bottom canary */
-
-               m = (u1*)m + MEMORY_CANARY_SIZE;
-
-               /* clear the memory */
-
-               memset(m, MEMORY_CLEAR_BYTE, da->size);
-       }
-#endif /* defined(ENABLE_MEMCHECK) */
-
-       /* increase used dump size by the allocated memory size */
-
-       di->useddumpsize += size;
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               if (di->useddumpsize > maxdumpsize)
-                       maxdumpsize = di->useddumpsize;
-#endif
-
-       return m;
-
-#endif /* defined(DISABLE_DUMP) */
-}
-
-
-/* dump_realloc ****************************************************************
-
-   Stupid realloc implementation for dump memory. Avoid, if possible.
-
-*******************************************************************************/
-
-void *dump_realloc(void *src, s4 len1, s4 len2)
-{
-#if defined(DISABLE_DUMP)
-       /* use malloc memory for dump memory (for debugging only!) */
-
-       return mem_realloc(src, len1, len2);
-#else
-       void *dst = dump_alloc(len2);
-
-       memcpy(dst, src, len1);
-
-#if defined(ENABLE_MEMCHECK)
-       /* destroy the source */
-       memset(src, MEMORY_CLEAR_BYTE, len1);
-#endif
-
-       return dst;
-#endif
-}
-
-
-/* dump_release ****************************************************************
-
-   Release dump memory above the given size.
-
-   IN:
-       size........All dump memory above this mark will be freed. Usually
-                      `size` will be the return value of a `dump_size` call
-                                  made earlier.
-
-       ERROR HANDLING:
-          XXX If the given size is invalid, this function *exits* with an
-              error message.
-                                  
-       See `dump_alloc`.
-
-*******************************************************************************/
-
-void dump_release(s4 size)
-{
-#if defined(DISABLE_DUMP)
-
-       /* use malloc memory for dump memory (for debugging only!) */
-
-       /* do nothing */
-
-#else /* !defined(DISABLE_DUMP) */
-
-       dumpinfo_t *di;
-
-       /* If no threads are used, the dumpinfo structure is a static structure   */
-       /* defined at the top of this file.                                       */
-
-       di = DUMPINFO;
-
-       if ((size < 0) || (size > di->useddumpsize))
-               vm_abort("Illegal dump release size: %d", size);
-
-#if defined(ENABLE_MEMCHECK)
-       {
-               dump_allocation_t *da, *next;
-
-               /* check canaries */
-
-               dump_check_canaries(di, size);
-
-               /* iterate over all dump memory allocations about to be released */
-
-               da = di->allocations;
-               while (da && da->useddumpsize >= size) {
-                       next = da->next;
-
-                       /* invalidate the freed memory */
-
-                       memset(da->mem, MEMORY_CLEAR_BYTE, da->size);
-
-                       FREE(da, dump_allocation_t);
-
-                       da = next;
-               }
-               di->allocations = da;
-       }
-#endif /* defined(ENABLE_MEMCHECK) */
-
-       /* reset the used dump size to the size specified */
-
-       di->useddumpsize = size;
-
-       while (di->currentdumpblock && di->allocateddumpsize - di->currentdumpblock->size >= di->useddumpsize) {
-               dumpblock_t *tmp = di->currentdumpblock;
-
-               di->allocateddumpsize -= tmp->size;
-               di->currentdumpblock = tmp->prev;
-
-#if defined(ENABLE_STATISTICS)
-               /* the amount of globally allocated dump memory (thread save) */
-
-               if (opt_stat)
-                       globalallocateddumpsize -= tmp->size;
-#endif
-
-               /* release the dump memory and the dumpinfo structure */
-
-               free(tmp->dumpmem);
-               free(tmp);
-       }
-
-#endif /* defined(DISABLE_DUMP) */
-}
-
-
-/* dump_size *******************************************************************
-
-   Return the current size of the dump memory area. See `dump_alloc`.
-
-*******************************************************************************/
-
-s4 dump_size(void)
-{
-#if defined(DISABLE_DUMP)
-       /* use malloc memory for dump memory (for debugging only!) */
-
-       return 0;
-
-#else /* !defined(DISABLE_DUMP) */
-
-       dumpinfo_t *di;
-
-       /* If no threads are used, the dumpinfo structure is a static structure   */
-       /* defined at the top of this file.                                       */
-
-       di = DUMPINFO;
-
-       if (di == NULL)
-               return 0;
-
-       return di->useddumpsize;
-
-#endif /* defined(DISABLE_DUMP) */
-}
-
-
 /*
  * These 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 bab1270da5f00a94839b2032874a82efb6e20ae6..0d2c74b2957d2d84bc4d6f8a4e0e3cb5d153e53f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/mm/memory.h - macros for memory management
 
-   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 _MEMORY_H
 #define _MEMORY_H
 
-/* forward typedefs ***********************************************************/
-
-typedef struct dumpblock_t dumpblock_t;
-typedef struct dumpinfo_t  dumpinfo_t;
 
 #include "config.h"
 
@@ -39,51 +33,8 @@ typedef struct dumpinfo_t  dumpinfo_t;
 
 #include "vm/types.h"
 
-
-/* ATTENTION: We need to define dumpblock_t and dumpinfo_t before
-   internal includes, as we need dumpinfo_t as nested structure in
-   threadobject. */
-
-/* dumpblock ******************************************************************/
-
-#define DUMPBLOCKSIZE    2 << 13    /* 2 * 8192 bytes */
-#define ALIGNSIZE        8
-
-struct dumpblock_t {
-       dumpblock_t *prev;
-       u1          *dumpmem;
-       s4           size;
-};
-
-
-/* dump_allocation *************************************************************
-
-   This struct is used to record dump memory allocations for ENABLE_MEMCHECK.
-
-*******************************************************************************/
-
-#if defined(ENABLE_MEMCHECK)
-typedef struct dump_allocation_t dump_allocation_t;
-
-struct dump_allocation_t {
-       dump_allocation_t *next;
-       u1                *mem;
-       s4                 useddumpsize;
-       s4                 size;
-};
-#endif
-
-
-/* dumpinfo *******************************************************************/
-
-struct dumpinfo_t {
-       dumpblock_t       *currentdumpblock;        /* the current top-most block */
-       s4                 allocateddumpsize;     /* allocated bytes in this area */
-       s4                 useddumpsize;          /* used bytes in this dump area */
-#if defined(ENABLE_MEMCHECK)
-       dump_allocation_t *allocations;       /* list of allocations in this area */
-#endif
-};
+#include "mm/codememory.h"
+#include "mm/dumpmemory.h"
 
 
 /* constants for ENABLE_MEMCHECK **********************************************/
@@ -112,15 +63,6 @@ There are two possible choices for allocating memory:
                        mem_realloc ... change size of a memory block (position may change)
                        mem_usage ..... amount of allocated memory
 
-
-       2.   explicit allocating, automatic deallocating
-       
-                       dump_alloc .... allocate a memory block in the dump area
-                       dump_realloc .. change size of a memory block (position may change)
-                       dump_size ..... marks the current top of dump
-                       dump_release .. free all memory requested after the mark
-                                       
-       
 There are some useful macros:
 
        NEW (type) ....... allocate memory for an element of type `type`
@@ -131,11 +73,6 @@ There are some useful macros:
        
        MREALLOC (ptr,type,num1,num2) .. enlarge the array to size num2
                                         
-These macros do the same except they operate on the dump area:
-       
-       DNEW,  DMNEW, DMREALLOC   (there is no DFREE)
-
-
 -------------------------------------------------------------------------------
 
 Some more macros:
@@ -153,7 +90,7 @@ Some more macros:
 
 #define MEMORY_ALIGN(pos,size) ((((pos) + (size) - 1) / (size)) * (size))
 #define PADDING(pos,size)     (MEMORY_ALIGN((pos),(size)) - (pos))
-#define OFFSET(s,el)          ((s4) ((ptrint) &(((s*) 0)->el)))
+#define OFFSET(s,el)          ((int32_t) ((ptrint) &(((s*) 0)->el)))
 
 
 #define NEW(type)             ((type *) mem_alloc(sizeof(type)))
@@ -166,19 +103,11 @@ Some more macros:
                                                         sizeof(type) * (num2))
 
 
-#define DNEW(type)            ((type *) dump_alloc(sizeof(type)))
-#define DMNEW(type,num)       ((type *) dump_alloc(sizeof(type) * (num)))
-#define DMREALLOC(ptr,type,num1,num2) dump_realloc((ptr), sizeof(type) * (num1), \
-                                                          sizeof(type) * (num2))
-
 #define MCOPY(dest,src,type,num) memcpy((dest), (src), sizeof(type) * (num))
 #define MSET(ptr,byte,type,num) memset((ptr), (byte), sizeof(type) * (num))
 #define MZERO(ptr,type,num)     MSET(ptr,0,type,num)
 #define MMOVE(dest,src,type,num) memmove((dest), (src), sizeof(type) * (num))
 
-#define CNEW(type,num)        ((type *) memory_cnew(sizeof(type) * (num)))
-#define CFREE(ptr,num)        memory_cfree((ptr),(num))
-
 
 /* GC macros (boehm only) *****************************************************/
 
@@ -198,28 +127,23 @@ Some more macros:
 
 /* function prototypes ********************************************************/
 
-/* initializes the memory subsystem */
-bool memory_init(void);
+bool  memory_init(void);
 
-void *memory_mmap_anon(void *addr, size_t len, int prot, int flags);
 void  memory_mprotect(void *addr, size_t len, int prot);
 
-void *memory_cnew(s4 size);
-void  memory_cfree(void *p, s4 size);
+void *memory_checked_alloc(size_t size);
+
+void *memory_cnew(int32_t size);
+void  memory_cfree(void *p, int32_t size);
 
-void *mem_alloc(s4 size);
-void  mem_free(void *m, s4 size);
-void *mem_realloc(void *src, s4 len1, s4 len2);
+void *mem_alloc(int32_t size);
+void  mem_free(void *m, int32_t size);
+void *mem_realloc(void *src, int32_t len1, int32_t len2);
 
 #if defined(ENABLE_THREADS)
 bool  memory_start_thread(void);
 #endif
 
-void *dump_alloc(s4 size);
-void *dump_realloc(void *src, s4 len1, s4 len2);
-s4    dump_size(void);
-void  dump_release(s4 size);
-
 #endif /* _MEMORY_H */
 
 
index fb85c4fb3a9ec95dd925df60f863f0843253d29d..6e3c1279df22f54310ee7ea25f8d3bb9c82e49ee 100644 (file)
@@ -1,9 +1,7 @@
 ## src/native/include/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.
 ##
@@ -23,6 +21,9 @@
 ## 02110-1301, USA.
 
 
+JAVAH    = $(CACAOH)
+JAVAHCMD = $(JAVAH) -bootclasspath $(BOOTCLASSPATH)
+
 COMMON_HEADER_FILES = \
        java_lang_Class.h \
        java_lang_Object.h \
@@ -70,7 +71,11 @@ JAVASE_HEADER_FILES += \
        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
@@ -146,25 +151,19 @@ DO_HEADER_FILES += \
 endif
 
 if WITH_CLASSPATH_GNU
-CLASSPATH = $(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
-VM_ZIP = $(top_builddir)/src/lib/vm.zip
-endif
-
-if WITH_CLASSPATH_SUN
-CLASSPATH = $(CLASSPATH_CLASSES)
+VM_ZIP = $(top_builddir)/src/classes/vm.zip
 endif
 
 if WITH_CLASSPATH_CLDC1_1
-CLASSPATH = $(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
-VM_ZIP = $(top_builddir)/src/lib/vm.zip
+VM_ZIP = $(top_builddir)/src/classes/vm.zip
 endif
 
 noinst_DATA = $(DO_HEADER_FILES)
 
 $(DO_HEADER_FILES): $(CACAOH) $(VM_ZIP) $(CLASSPATH_CLASSES)
        @class=`echo $@ | sed -e 's/\.h$$//' -e 's/_/\./g'`; \
-       echo "$(CACAOH) -bootclasspath $(CLASSPATH) -d . $$class"; \
-       $(CACAOH) -bootclasspath $(CLASSPATH) -d . $$class
+       echo "$(JAVAHCMD) -d . $$class"; \
+       $(JAVAHCMD) -d . $$class
 
 
 ## Local variables:
index 7ac2f8340bb7162ebf802019f18e73182a048dc5..77f02a3868a1553ca573be0d85df2ed6a0903e71 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/jni.c - implementation of the Java Native Interface 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 "native/include/java_lang_Throwable.h"
 
 #if defined(ENABLE_JAVASE)
+
 # if defined(WITH_CLASSPATH_SUN)
 #  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_nio_Buffer.h"
 
 # if defined(WITH_CLASSPATH_GNU)
+#  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
 
-#include "native/vm/java_lang_Class.h"
-
 #if defined(ENABLE_JAVASE)
-# include "native/vm/java_lang_ClassLoader.h"
 # include "native/vm/reflect.h"
 #endif
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
 /* debug **********************************************************************/
 
 #if !defined(NDEBUG)
-# define TRACEJNICALLS(format, ...) \
-    do { \
-        if (opt_TraceJNICalls) { \
-            log_println((format), __VA_ARGS__); \
-        } \
+# define TRACEJNICALLS(text)                                   \
+    do {                                                                               \
+        if (opt_TraceJNICalls) {                               \
+            log_println text;                                  \
+        }                                                                              \
     } while (0)
 #else
-# define TRACEJNICALLS(format, ...)
+# define TRACEJNICALLS(text)
 #endif
 
 
@@ -179,6 +187,8 @@ jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
 
 bool jni_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("jni_init");
+
        /* create global ref hashtable */
 
        hashtable_global_ref = NEW(hashtable);
@@ -796,83 +806,6 @@ static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
 }
 
 
-/* _Jv_jni_invokeNative ********************************************************
-
-   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 *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
-                                                                       java_handle_objectarray_t *params)
-{
-       methodinfo    *resm;
-       java_handle_t *ro;
-       s4             argcount;
-       s4             paramcount;
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 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->class))) {
-               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;
-}
-
-
 /* GetVersion ******************************************************************
 
    Returns the major version number in the higher 16 bits and the
@@ -882,7 +815,7 @@ java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
 
 jint _Jv_JNI_GetVersion(JNIEnv *env)
 {
-       TRACEJNICALLS("_Jv_JNI_GetVersion(env=%p)", env);
+       TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
 
        /* We support JNI 1.6. */
 
@@ -905,16 +838,16 @@ jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
 {
 #if defined(ENABLE_JAVASE)
        utf             *u;
-       classloader     *cl;
+       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);
+       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, (const uint8_t *) buf, NULL);
+       c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
 
        co = LLNI_classinfo_wrap(c);
 
@@ -937,7 +870,7 @@ jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
 
 *******************************************************************************/
 
-jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
+jclass jni_FindClass(JNIEnv *env, const char *name)
 {
 #if defined(ENABLE_JAVASE)
 
@@ -946,10 +879,17 @@ jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
        classinfo       *c;
        java_lang_Class *co;
 
-       TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
+       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. */
 
@@ -971,8 +911,10 @@ jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
        else
                c = load_class_from_classloader(u, cc->classloader);
 
-       if (c == NULL)
+       if (c == NULL) {
+               resolve_handle_pending_exception(true);
                return NULL;
+       }
 
        if (!link_class(c))
                return NULL;
@@ -986,13 +928,15 @@ jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
        utf       *u;
        classinfo *c;
 
-       TRACEJNICALLS("_Jv_JNI_FindClass(env=%p, name=%s)", env, name);
+       TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
 
        u = utf_new_char_classname((char *) name);
        c = load_class_bootstrap(u);
 
-       if (c == NULL)
+       if (c == NULL) {
+               resolve_handle_pending_exception(true);
                return NULL;
+       }
 
        if (!link_class(c))
                return NULL;
@@ -1000,7 +944,7 @@ jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
        return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
        
 #else
-       vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
+       vm_abort("jni_FindClass: not implemented in this configuration");
 
        /* keep compiler happy */
 
@@ -1023,7 +967,7 @@ jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
        classinfo       *super;
        java_lang_Class *co;
 
-       TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
+       TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
 
        c = LLNI_classinfo_unwrap(sub);
 
@@ -1046,15 +990,15 @@ jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
 
 jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
 {
-       java_lang_Class *csup;
-       java_lang_Class *csub;
+       classinfo *to;
+       classinfo *from;
 
-       csup = (java_lang_Class *) sup;
-       csub = (java_lang_Class *) sub;
+       TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
 
-       STATISTICS(jniinvokation());
+       to   = (classinfo *) sup;
+       from = (classinfo *) sub;
 
-       return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
+       return class_is_assignable_from(to, from);
 }
 
 
@@ -1124,7 +1068,7 @@ jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
 {
        java_handle_t *o;
 
-       TRACEJNICALLS("_Jv_JNI_ExceptionOccurred(env=%p)", env);
+       TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
 
        o = exceptions_get_exception();
 
@@ -1140,37 +1084,11 @@ jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
 
 *******************************************************************************/
 
-void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
+void jni_ExceptionDescribe(JNIEnv *env)
 {
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-
-       TRACEJNICALLS("_Jv_JNI_ExceptionDescribe(env=%p)", env);
-
-       /* Clear exception, because we are probably calling Java code
-          again. */
-
-       o = exceptions_get_and_clear_exception();
+       TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
 
-       if (o != NULL) {
-               /* get printStackTrace method from exception class */
-
-               LLNI_class_get(o, c);
-
-               m = class_resolveclassmethod(c,
-                                                                        utf_printStackTrace,
-                                                                        utf_void__void,
-                                                                        NULL,
-                                                                        true);
-
-               if (m == NULL)
-                       vm_abort("_Jv_JNI_ExceptionDescribe: could not find printStackTrace");
-
-               /* Print the stacktrace. */
-
-               (void) vm_call_method(m, o);
-       }
+       exceptions_print_stacktrace();
 }
 
 
@@ -1181,9 +1099,9 @@ void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
 
 *******************************************************************************/
 
-void _Jv_JNI_ExceptionClear(JNIEnv *env)
+void jni_ExceptionClear(JNIEnv *env)
 {
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
 
        exceptions_clear_exception();
 }
@@ -1326,7 +1244,7 @@ jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
 
        localref = localref_add(LLNI_DIRECT(o));
 
-       return localref;
+       return (jobject) localref;
 }
 
 
@@ -1530,15 +1448,16 @@ jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
 
 jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
 {
-       java_lang_Class  *c;
-       java_lang_Object *o;
+       classinfo     *c;
+       java_handle_t *h;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
 
-       c = (java_lang_Class *) clazz;
-       o = (java_lang_Object *) obj;
+       /* XXX Is this correct? */
+       c = LLNI_classinfo_unwrap(clazz);
+       h = (java_handle_t *) obj;
 
-       return _Jv_java_lang_Class_isInstance(c, o);
+       return class_is_instance(c, h);
 }
 
 
@@ -1551,45 +1470,74 @@ jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
   
 *******************************************************************************/
   
-jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
+jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
 {
 #if defined(ENABLE_JAVASE)
-       java_handle_t *o;
-       classinfo     *c;
-       methodinfo    *m;
-       s4             slot;
+       java_handle_t                   *o;
+       java_lang_reflect_Method        *rm;
+       java_lang_reflect_Constructor   *rc;
+       classinfo                       *c;
+       methodinfo                      *m;
+       int32_t                          slot;
+
+#if defined(WITH_CLASSPATH_GNU)
+       java_lang_reflect_VMMethod      *rvmm;
+       java_lang_reflect_VMConstructor *rvmc;
+#endif
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
 
        o = (java_handle_t *) method;
 
        if (o == NULL)
                return NULL;
-       
-       if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
-               java_lang_reflect_Method *rm;
 
-               rm   = (java_lang_reflect_Method *) method;
-               LLNI_field_get_cls(rm, clazz, c);
-               LLNI_field_get_val(rm, slot , slot);
-       }
-       else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
-               java_lang_reflect_Constructor *rc;
+       if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
+               rc = (java_lang_reflect_Constructor *) method;
+
+#if defined(WITH_CLASSPATH_GNU)
+
+               LLNI_field_get_ref(rc,   cons , rvmc);
+               LLNI_field_get_cls(rvmc, clazz, c);
+               LLNI_field_get_val(rvmc, slot , slot);
+
+#elif defined(WITH_CLASSPATH_SUN)
 
-               rc   = (java_lang_reflect_Constructor *) method;
                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_CLASSPATH_GNU)
+
+               LLNI_field_get_ref(rm,   m ,    rvmm);
+               LLNI_field_get_cls(rvmm, clazz, c);
+               LLNI_field_get_val(rvmm, slot , slot);
+
+#elif defined(WITH_CLASSPATH_SUN)
+
+               LLNI_field_get_cls(rm, clazz, c);
+               LLNI_field_get_val(rm, slot , slot);
+
+#else
+# error unknown configuration
+#endif
        }
-       else
-               return NULL;
 
        m = &(c->methods[slot]);
 
        return (jmethodID) m;
 #else
-       vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
+       vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
 
-       /* keep compiler happy */
+       /* Keep compiler happy. */
 
        return NULL;
 #endif
@@ -1602,30 +1550,47 @@ jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
 
 *******************************************************************************/
  
-jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
+jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
 {
 #if defined(ENABLE_JAVASE)
-       java_lang_reflect_Field *rf;
-       classinfo               *c;
-       fieldinfo               *f;
-       int32_t                  slot;
+       java_lang_reflect_Field   *rf;
+       classinfo                 *c;
+       fieldinfo                 *f;
+       int32_t                    slot;
 
-       STATISTICS(jniinvokation());
+#if defined(WITH_CLASSPATH_GNU)
+       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_CLASSPATH_GNU)
+
+       LLNI_field_get_ref(rf,   f,     rvmf);
+       LLNI_field_get_cls(rvmf, clazz, c);
+       LLNI_field_get_val(rvmf, slot , slot);
+
+#elif defined(WITH_CLASSPATH_SUN)
+
        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("_Jv_JNI_FromReflectedField: not implemented in this configuration");
+       vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
 
-       /* keep compiler happy */
+       /* Keep compiler happy. */
 
        return NULL;
 #endif
@@ -1648,7 +1613,7 @@ jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
        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);
+       TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
 
        m = (methodinfo *) methodID;
 
@@ -2153,7 +2118,7 @@ type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
 {                                                                         \
        intern ret;                                                           \
                                                                           \
-       STATISTICS(jniinvokation());                                          \
+       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
                                                                           \
        LLNI_CRITICAL_START;                                                  \
                                                                           \
@@ -2178,7 +2143,7 @@ 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);
+       TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
 
        LLNI_CRITICAL_START;
 
@@ -2186,7 +2151,7 @@ jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
 
        LLNI_CRITICAL_END;
 
-       return _Jv_JNI_NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -2205,7 +2170,7 @@ jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
                                                          type value)                                  \
 {                                                                          \
-       STATISTICS(jniinvokation());                                           \
+       TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
                                                                            \
        LLNI_CRITICAL_START;                                                   \
                                                                            \
@@ -2227,7 +2192,7 @@ 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);
+       TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
 
        LLNI_CRITICAL_START;
 
@@ -2257,7 +2222,7 @@ jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
        utf        *udesc;
        methodinfo *m;
 
-       TRACEJNICALLS("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig);
+       TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
 
        c = LLNI_classinfo_unwrap(clazz);
 
@@ -2367,6 +2332,8 @@ jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
        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);
@@ -2383,6 +2350,8 @@ jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
        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);
@@ -2397,6 +2366,8 @@ jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
        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);
@@ -2411,6 +2382,8 @@ void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
        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);
@@ -2424,6 +2397,8 @@ void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
 {
        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);
@@ -2435,6 +2410,8 @@ void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
 {
        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);
@@ -2530,7 +2507,7 @@ jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
 
        h = LLNI_WRAP(f->value->a);
 
-       return _Jv_JNI_NewLocalRef(env, h);
+       return _Jv_JNI_NewLocalRef(env, (jobject) h);
 }
 
 
@@ -2640,7 +2617,7 @@ jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
        java_lang_String *s;
        jsize             len;
 
-       TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
+       TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
 
        s = (java_lang_String *) str;
 
@@ -2756,7 +2733,7 @@ jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
 {
        java_lang_String *s;
 
-       TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
+       TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
 
        s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
 
@@ -2771,7 +2748,7 @@ jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
        java_lang_String *s;
        s4                length;
 
-       TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
+       TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
 
        s = (java_lang_String *) string;
 
@@ -2842,7 +2819,7 @@ jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
        java_handle_t *a;
        jsize          size;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
 
        a = (java_handle_t *) array;
 
@@ -2958,7 +2935,7 @@ type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
 JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
 JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
 JNI_NEW_ARRAY(Char,    jcharArray,    char)
-JNI_NEW_ARRAY(Short,   jshortArray,   byte)
+JNI_NEW_ARRAY(Short,   jshortArray,   short)
 JNI_NEW_ARRAY(Int,     jintArray,     int)
 JNI_NEW_ARRAY(Long,    jlongArray,    long)
 JNI_NEW_ARRAY(Float,   jfloatArray,   float)
@@ -2977,7 +2954,7 @@ type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
 {                                                                      \
        java_handle_##intern##array_t *a;                                  \
                                                                        \
-       STATISTICS(jniinvokation());                                       \
+       TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
                                                                        \
        a = (java_handle_##intern##array_t *) array;                       \
                                                                        \
@@ -3057,7 +3034,7 @@ void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
 {                                                                       \
        java_handle_##intern##array_t *a;                                   \
                                                                         \
-       STATISTICS(jniinvokation());                                        \
+       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;                        \
                                                                         \
@@ -3283,7 +3260,7 @@ void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
        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);
+       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);
@@ -3306,21 +3283,37 @@ void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
 
    Obtain a direct pointer to array elements.
 
+   ATTENTION: Critical section keeps open when this function returns!
+   See ReleasePrimitiveArrayCritical.
+
 *******************************************************************************/
 
-void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
-                                                                               jboolean *isCopy)
+void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
 {
-       java_handle_bytearray_t *ba;
-       jbyte                   *bp;
+       java_handle_t*   h;
+       java_array_t*    a;
+       arraydescriptor* ad;
+       void*            data;
 
-       ba = (java_handle_bytearray_t *) array;
+       TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
 
-       /* do the same as Kaffe does */
+       if (isCopy != NULL) {
+               *isCopy = JNI_FALSE;
+       }
 
-       bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
+       LLNI_CRITICAL_START;
+
+       h  = (java_handle_t*) array;
+       a  = (java_array_t*) LLNI_UNWRAP(h);
+       ad = a->objheader.vftbl->arraydesc;
+
+       /* Sanity check. */
 
-       return (void *) bp;
+       assert(ad != NULL);
+
+       data = (void*) (((intptr_t) a) + ad->dataoffset);
+
+       return data;
 }
 
 
@@ -3328,17 +3321,16 @@ void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
 
    No specific documentation.
 
+   ATTENTION: This function closes the critical section opened in
+   GetPrimitiveArrayCritical!
+
 *******************************************************************************/
 
-void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
-                                                                                  void *carray, jint mode)
+void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
 {
-       STATISTICS(jniinvokation());
-
-       /* do the same as Kaffe does */
+       TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
 
-       _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
-                                                                        mode);
+       LLNI_CRITICAL_END;
 }
 
 
@@ -3369,7 +3361,7 @@ void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
 
 jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
 {
-       TRACEJNICALLS("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj);
+       TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
 
        return obj;
 }
@@ -3377,7 +3369,7 @@ jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
 
 void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
 {
-       TRACEJNICALLS("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref);
+       TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
 }
 
 
@@ -3583,7 +3575,7 @@ jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
        gnu_classpath_Pointer32 *paddress;
 # endif
 
-       TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
+       TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
 
        /* alocate a gnu.classpath.Pointer{32,64} object */
 
@@ -3616,7 +3608,7 @@ jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
        int64_t addr;
        int32_t cap;
 
-       TRACEJNICALLS("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity);
+       TRACEJNICALLS(("_Jv_JNI_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld", env, address, capacity));
 
        /* Be paranoid about address sign-extension. */
 
@@ -3654,32 +3646,48 @@ jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
 {
 #if defined(ENABLE_JAVASE)
+       java_handle_t                 *h;
+
 # if defined(WITH_CLASSPATH_GNU)
 
        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                          *address;
+       void                          *p;
+
+       TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
 
-       TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
+       /* Prevent compiler warning. */
 
-       if ((buf != NULL) && !builtin_instanceof(buf, class_java_nio_Buffer))
+       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, paddress);
+       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);
-       /* this was the cast to avaoid warning: (void *) paddress->data */
 
-       return address;
+       p = (void *) (intptr_t) address;
+
+       return p;
 
 # elif defined(WITH_CLASSPATH_SUN)
 
@@ -3687,9 +3695,13 @@ void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
        int64_t          address;
        void            *p;
 
-       TRACEJNICALLS("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf);
+       TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
+
+       /* Prevent compiler warning. */
 
-       if ((buf != NULL) && !builtin_instanceof(buf, class_sun_nio_ch_DirectBuffer))
+       h = (java_handle_t *) buf;
+
+       if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
                return NULL;
 
        o = (java_nio_Buffer *) buf;
@@ -3778,9 +3790,12 @@ jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
 
 jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
 {
-       int32_t status;
+       int status;
+
+       TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
 
-       TRACEJNICALLS("_Jv_JNI_DestroyJavaVM(vm=%p)", vm);
+       if (vm_created == false)
+               return JNI_ERR;
 
     status = vm_destroy(vm);
 
@@ -3802,26 +3817,36 @@ jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
 
 *******************************************************************************/
 
-static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
+static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
 {
+#if defined(ENABLE_THREADS)
        JavaVMAttachArgs *vm_aargs;
+       bool              result;
 
-#if defined(ENABLE_THREADS)
-       if (threads_get_current_threadobject() == NULL) {
-               vm_aargs = (JavaVMAttachArgs *) thr_args;
+    /* If the current thread has already been attached, this operation
+          is a no-op. */
 
-               if (vm_aargs != NULL) {
-                       if ((vm_aargs->version != JNI_VERSION_1_2) &&
-                               (vm_aargs->version != JNI_VERSION_1_4))
-                               return JNI_EVERSION;
-               }
+       result = thread_current_is_attached();
 
-               if (!threads_attach_current_thread(vm_aargs, false))
-                       return JNI_ERR;
+       if (result == true) {
+               *p_env = _Jv_env;
 
-               if (!localref_table_init())
-                       return JNI_ERR;
+               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 (!threads_attach_current_thread(vm_aargs, false))
+               return JNI_ERR;
+
+       if (!localref_table_init())
+               return JNI_ERR;
 #endif
 
        *p_env = _Jv_env;
@@ -3832,9 +3857,16 @@ static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
 
 jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
 {
-       STATISTICS(jniinvokation());
+       int result;
+
+       TRACEJNICALLS(("_Jv_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 jni_attach_current_thread(p_env, thr_args, false);
+       return result;
 }
 
 
@@ -3858,14 +3890,24 @@ jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
 jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
 {
 #if defined(ENABLE_THREADS)
-       threadobject *thread;
+       threadobject *t;
+       bool          result;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS(("_Jv_JNI_DetachCurrentThread(vm=%p)", vm));
 
-       thread = threads_get_current_threadobject();
+       t = thread_get_current();
 
-       if (thread == NULL)
-               return JNI_ERR;
+       /* 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;
 
        /* We need to pop all frames before we can destroy the table. */
 
@@ -3874,7 +3916,7 @@ jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
        if (!localref_table_destroy())
                return JNI_ERR;
 
-       if (!threads_detach_thread(thread))
+       if (!threads_detach_thread(t))
                return JNI_ERR;
 #endif
 
@@ -3893,10 +3935,15 @@ jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
 
 jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
 {
-       TRACEJNICALLS("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version);
+       TRACEJNICALLS(("_Jv_JNI_GetEnv(vm=%p, env=%p, %d=version)", vm, env, version));
+
+       if (vm_created == false) {
+               *env = NULL;
+               return JNI_EDETACHED;
+       }
 
 #if defined(ENABLE_THREADS)
-       if (threads_get_current_threadobject() == NULL) {
+       if (thread_get_current() == NULL) {
                *env = NULL;
 
                return JNI_EDETACHED;
@@ -3942,9 +3989,16 @@ jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
 
 jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
 {
-       STATISTICS(jniinvokation());
+       int result;
 
-       return jni_attach_current_thread(penv, args, true);
+       TRACEJNICALLS(("_Jv_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;
 }
 
 
@@ -3973,9 +4027,9 @@ struct JNINativeInterface_ _Jv_JNINativeInterface = {
        _Jv_JNI_GetVersion,
 
        _Jv_JNI_DefineClass,
-       _Jv_JNI_FindClass,
-       _Jv_JNI_FromReflectedMethod,
-       _Jv_JNI_FromReflectedField,
+       jni_FindClass,
+       jni_FromReflectedMethod,
+       jni_FromReflectedField,
        _Jv_JNI_ToReflectedMethod,
        _Jv_JNI_GetSuperclass,
        _Jv_JNI_IsAssignableFrom,
@@ -3984,8 +4038,8 @@ struct JNINativeInterface_ _Jv_JNINativeInterface = {
        _Jv_JNI_Throw,
        _Jv_JNI_ThrowNew,
        _Jv_JNI_ExceptionOccurred,
-       _Jv_JNI_ExceptionDescribe,
-       _Jv_JNI_ExceptionClear,
+       jni_ExceptionDescribe,
+       jni_ExceptionClear,
        _Jv_JNI_FatalError,
        _Jv_JNI_PushLocalFrame,
        _Jv_JNI_PopLocalFrame,
@@ -4217,8 +4271,8 @@ struct JNINativeInterface_ _Jv_JNINativeInterface = {
        _Jv_JNI_GetStringRegion,
        _Jv_JNI_GetStringUTFRegion,
 
-       _Jv_JNI_GetPrimitiveArrayCritical,
-       _Jv_JNI_ReleasePrimitiveArrayCritical,
+       jni_GetPrimitiveArrayCritical,
+       jni_ReleasePrimitiveArrayCritical,
 
        _Jv_JNI_GetStringCritical,
        _Jv_JNI_ReleaseStringCritical,
@@ -4287,7 +4341,7 @@ jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
 
 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
 {
-       TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
+       TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
 
        if (bufLen <= 0)
                return JNI_ERR;
@@ -4310,7 +4364,7 @@ jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
 
 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);
+       TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
 
        /* actually create the JVM */
 
index 05a013659d12f8a74c0041aa7cff4d89f3ccbece..a74f68688c9fbe855c6ddcdf36fbd508c6d585c7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/jni.h - JNI types and data structures
 
-   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.
 
 */
 
 
-/* GNU Classpath jni.h *********************************************************
+/* jni.h ***********************************************************************
 
    ATTENTION: We include this file before we actually define our own
-   jni.h.  We do this because, otherwise we can get into unresolvable
+   jni.h.  We do this because otherwise we can get into unresolvable
    circular header dependencies.
 
    This is OK as GNU Classpath defines:
 
+   #define __CLASSPATH_JNI_MD_H__
    #define _CLASSPATH_JNI_H
 
-   CLASSPATH_JNI_H is in config.h defined.
+   and OpenJDK defines:
+
+   #define _JAVASOFT_JNI_MD_H_
+   #define _JAVASOFT_JNI_H_
+
+   CLASSPATH_JNI_MD_H and CLASSPATH_JNI_H are defined in config.h.
 
 *******************************************************************************/
 
 #include "config.h"
 
-/* XXX quick hack to not include GCJ's jni_md.h */
-#define __GCJ_JNI_MD_H__
+/* We include both headers with the absolute path so we can be sure
+   that the preprocessor does not take another header.  Furthermore we
+   include jni_md.h before jni.h as the latter includes the former. */
 
-#include CLASSPATH_JNI_MD_H
-#include CLASSPATH_JNI_H
+#include INCLUDE_JNI_MD_H
+#include INCLUDE_JNI_H
 
 #ifndef _JNI_H
 #define _JNI_H
@@ -108,9 +113,6 @@ struct hashtable_global_ref_entry {
 bool jni_init(void);
 bool jni_version_check(int version);
 
-java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
-                                                                       java_handle_objectarray_t *params);
-
 #endif /* _JNI_H */
 
 
index f5753dfe6430f3732325bcf4dbe8d7c38b25fb67..8db874a8fb8d8102250be0fe2d80aeb16f0ffbf1 100644 (file)
@@ -1,10 +1,8 @@
 /* src/native/jvmti/cacaodbg.c - contains entry points for debugging support 
                                  in cacao.
 
-   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., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Martin Platter
-
-   Changes: Edwin Steiner
-            Samuel Vinson
-
-
 */
 
 #include "native/jvmti/jvmti.h"
@@ -43,7 +33,8 @@
 #include "vm/jit/asmpart.h"
 #include "vm/stringlocal.h"
 #include "toolbox/logging.h"
-#include "threads/native/threads.h"
+#include "threads/mutex.h"
+#include "threads/thread.h"
 
 #include <sys/types.h>
 #include <unistd.h>
@@ -102,7 +93,7 @@ jvmtiError jvmti_get_all_threads (jint * threads_count_ptr,
 
 *******************************************************************************/
 jthread jvmti_get_current_thread() {
-       return (jthread)(threads_get_current_threadobject())->o.thread;
+       return (jthread)(thread_get_current)->o.thread;
 }
 
 
@@ -143,7 +134,7 @@ static void breakpointtable_creator() {
 void jvmti_set_system_breakpoint(int sysbrk, bool mode) {      
        struct brkpts *jvmtibrkpt;
 
-       pthread_mutex_lock(&dbgcomlock);
+       mutex_lock(&dbgcomlock);
        jvmtibrkpt = &dbgcom->jvmtibrkpt;
 
        assert (sysbrk < BEGINUSERBRK); 
@@ -154,7 +145,7 @@ void jvmti_set_system_breakpoint(int sysbrk, bool mode) {
                /* add breakpoint*/
                if (jvmtibrkpt->brk[sysbrk].count > 0) {
                        jvmtibrkpt->brk[sysbrk].count++;
-                       pthread_mutex_unlock(&dbgcomlock);
+                       mutex_unlock(&dbgcomlock);
                        return;
                }
                dbgcom->addbrkpt = true;
@@ -169,11 +160,11 @@ void jvmti_set_system_breakpoint(int sysbrk, bool mode) {
                } else {
                        /* avoid negative counter values */
                        if (jvmtibrkpt->brk[sysbrk].count > 0) jvmtibrkpt->brk[sysbrk].count--;
-                       pthread_mutex_unlock(&dbgcomlock);
+                       mutex_unlock(&dbgcomlock);
                        return;
                }
        }
-       pthread_mutex_unlock(&dbgcomlock);
+       mutex_unlock(&dbgcomlock);
        /* call cacaodbgserver */
        __asm__ ("setsysbrkpt:");
        TRAP; 
@@ -189,7 +180,7 @@ void jvmti_set_system_breakpoint(int sysbrk, bool mode) {
 void jvmti_add_breakpoint(void* addr, jmethodID method, jlocation location) {
        struct brkpts *jvmtibrkpt;
 
-       pthread_mutex_lock(&dbgcomlock);
+       mutex_lock(&dbgcomlock);
        jvmtibrkpt = &dbgcom->jvmtibrkpt;;
 
        if (jvmtibrkpt->size == jvmtibrkpt->num)
@@ -204,7 +195,7 @@ void jvmti_add_breakpoint(void* addr, jmethodID method, jlocation location) {
        /* todo: set breakpoint */
 /*     jvmtibrkpt.brk[jvmtibrkpt.num].orig = */
        jvmtibrkpt->num++;
-       pthread_mutex_unlock(&dbgcomlock);
+       mutex_unlock(&dbgcomlock);
 
        fprintf (stderr,"add brk done\n");
 }
@@ -218,7 +209,7 @@ void jvmti_add_breakpoint(void* addr, jmethodID method, jlocation location) {
 
 *******************************************************************************/
 void jvmti_cacaodbgserver_quit(){
-       pthread_mutex_lock(&dbgcomlock);
+       mutex_lock(&dbgcomlock);
        dbgcom->running--;
        if (dbgcom->running  == 0) {
                __asm__ ("cacaodbgserver_quit:");
@@ -227,7 +218,7 @@ void jvmti_cacaodbgserver_quit(){
                wait(NULL);
                dbgcom = NULL;
        }
-       pthread_mutex_unlock(&dbgcomlock);
+       mutex_unlock(&dbgcomlock);
 }
 
 
@@ -282,7 +273,7 @@ void jvmti_cacao_debug_init() {
        pid_t dbgserver;        
 
        /* start new cacaodbgserver if needed*/
-       pthread_mutex_lock(&dbgcomlock);
+       mutex_lock(&dbgcomlock);
        if (dbgcom == NULL) {
                dbgcom = heap_allocate(sizeof(cacaodbgcommunication),true,NULL);                
                dbgcom->running = 1;
@@ -307,12 +298,12 @@ void jvmti_cacao_debug_init() {
                                }
                        }
                }
-               pthread_mutex_unlock(&dbgcomlock);
+               mutex_unlock(&dbgcomlock);
                /* let cacaodbgserver get ready */
                sleep(1);
        } else {
                dbgcom->running++;
-               pthread_mutex_unlock(&dbgcomlock);
+               mutex_unlock(&dbgcomlock);
        }
 }
 
index 75ea36767ce0a301e3e7e249f4cb104dd5999c2f..4b4a219eb7025cd7e2b4dc57d8f111821369e188 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/jvmti/cacaodbg.h - contains cacao specifics for debugging support
 
-   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., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Martin Platter
-
-   Changes:
-
 */
 
 #ifndef _CACAODBG_H
 #define _CACAODBG_H
 
-#include "threads/native/threads.h"
+#include "threads/mutex.h"
+#include "threads/thread.h"
 #include "native/jvmti/jvmti.h"
 #include "native/include/java_lang_String.h"
 #include <ltdl.h>
@@ -120,7 +113,7 @@ cacaodbgcommunication *dbgcom;
 
 bool jvmti;                 /* jvmti agent  */
 
-extern pthread_mutex_t dbgcomlock;
+extern mutex_t dbgcomlock;
 
 jvmtiEnv* jvmti_new_environment();
 void jvmti_set_phase(jvmtiPhase p);
index 5061b77232cfbcd9ceeeefb040cab2e35497c38d..b80dae48d18ee8f3658d0990544d205cc2ddde94 100644 (file)
@@ -1,10 +1,8 @@
 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine 
                               Tool Interface 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.
 
@@ -54,8 +52,9 @@
 #include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "mm/memory.h"
-#include "threads/native/threads.h"
-#include "threads/native/lock.h"
+#include "threads/mutex.h"
+#include "threads/thread.h"
+#include "threads/lock-common.h"
 #include "vm/exceptions.h"
 #include "native/include/java_util_Vector.h"
 #include "native/include/java_io_PrintStream.h"
@@ -69,7 +68,6 @@
 #include "boehm-gc/include/gc.h"
 
 #if defined(ENABLE_THREADS)
-#include "threads/native/threads.h"
 #include <sched.h>
 #include <pthread.h>
 #endif 
@@ -79,7 +77,7 @@
 
 typedef struct _environment environment;
 static environment *envs=NULL;
-pthread_mutex_t dbgcomlock;
+mutex_t dbgcomlock;
 
 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
 
@@ -737,7 +735,7 @@ GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
 
        om=MNEW(java_objectheader*,size);
 
-       pthread_mutex_lock(&lock_global_pool_lock);
+       mutex_lock(&lock_global_pool_lock);
        lrp=lock_global_pool;
 
        /* iterate over all lock record pools */
@@ -758,7 +756,7 @@ GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
                lrp=lrp->header.next;
        }
 
-       pthread_mutex_unlock(&lock_global_pool_lock);
+       mutex_unlock(&lock_global_pool_lock);
 
        *owned_monitors_ptr     = 
                heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
@@ -807,7 +805,7 @@ GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
 
 #if defined(ENABLE_THREADS)
 
-       pthread_mutex_lock(&lock_global_pool_lock);
+       mutex_lock(&lock_global_pool_lock);
 
        lrp=lock_global_pool;
 
@@ -828,7 +826,7 @@ GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
                lrp=lrp->header.next;
        }
 
-       pthread_mutex_unlock(&lock_global_pool_lock);
+       mutex_unlock(&lock_global_pool_lock);
 
 
 #endif
index f23e0a7829f2a456bab5ca7e696aa7bb6c595ce0..e9df0d64328252041395f42b32d6abbe3af08c55 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/llni.c - low level native interfarce (LLNI)
 
-   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.
 
@@ -29,7 +27,7 @@
 
 #include <assert.h>
 
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 
 /* LLNI critical sections ******************************************************
index a84f472131f371718b3e30d7c111789c5c95b451..65e708685bd69a83c88cc14ccc77e757b50681a1 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/llni.h - low level native interfarce (LLNI)
 
-   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 "config.h"
 
-#include "native/localref.h"
+/* forward defines ************************************************************/
+
+/* LLNI wrapping / unwrapping macros *******************************************
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
+   ATTENTION: Only use these macros inside a LLNI critical section!
+   Once the ciritical section ends, all pointers onto the GC heap
+   retrieved through these macros are void!
+
+*******************************************************************************/
+
+#if defined(ENABLE_HANDLES)
+# define LLNI_WRAP(obj)      ((obj) == NULL ? NULL : localref_add(obj))
+# define LLNI_UNWRAP(hdl)    ((hdl) == NULL ? NULL : (hdl)->heap_object)
+# define LLNI_QUICKWRAP(obj) ((obj) == NULL ? NULL : &(obj))
+# define LLNI_DIRECT(hdl)    ((hdl)->heap_object)
 #else
-# include "threads/none/threads.h"
+# define LLNI_WRAP(obj)      (obj)
+# define LLNI_UNWRAP(hdl)    (hdl)
+# define LLNI_QUICKWRAP(obj) (obj)
+# define LLNI_DIRECT(hdl)    (hdl)
 #endif
 
 
+#include "native/localref.h"
+
+#include "threads/thread.h"
+
+
 /* LLNI macros *****************************************************************
 
    The following macros should be used whenever a Java Object is
@@ -76,7 +93,7 @@
        (variable) = (classinfo *) LLNI_field_direct(obj, field)
 
 #define LLNI_class_get(obj, variable) \
-       (variable) = LLNI_field_direct((java_handle_t *) obj, vftbl->class)
+       (variable) = LLNI_field_direct((java_handle_t *) obj, vftbl->clazz)
 
 
 /* LLNI_equals ****************************************************************
 #define LLNI_array_size(arr)          (LLNI_DIRECT((java_handle_objectarray_t *) (arr))->header.size)
 
 
-/* LLNI wrapping / unwrapping macros *******************************************
-
-   ATTENTION: Only use these macros inside a LLNI critical section!
-   Once the ciritical section ends, all pointers onto the GC heap
-   retrieved through these macros are void!
-
-*******************************************************************************/
-
-#if defined(ENABLE_HANDLES)
-# define LLNI_WRAP(obj)      ((obj) == NULL ? NULL : localref_add(obj))
-# define LLNI_UNWRAP(hdl)    ((hdl) == NULL ? NULL : (hdl)->heap_object)
-# define LLNI_QUICKWRAP(obj) ((obj) == NULL ? NULL : &(obj))
-# define LLNI_DIRECT(hdl)    ((hdl)->heap_object)
-#else
-# define LLNI_WRAP(obj)      (obj)
-# define LLNI_UNWRAP(hdl)    (hdl)
-# define LLNI_QUICKWRAP(obj) (obj)
-# define LLNI_DIRECT(hdl)    (hdl)
-#endif
-
-
 /* LLNI critical sections ******************************************************
 
    These macros handle the LLNI critical sections. While a critical
index e2781d1c8e3fbce2ac109fd472578fb15c4dc7fa..8e364b515e79ead77c0183e6996efeac655bd32b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/localref.c - 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.
 
@@ -34,7 +32,7 @@
 
 #include "native/localref.h"
 
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
@@ -74,7 +72,9 @@ localref_table *_no_threads_localref_table;
 
 /* some forward declarations **************************************************/
 
+#if !defined(NDEBUG)
 static bool localref_check_uncleared();
+#endif
 
 
 /* localref_table_init *********************************************************
@@ -87,6 +87,8 @@ bool localref_table_init(void)
 {
        localref_table *lrt;
 
+       TRACESUBSYSTEMINITIALIZATION("localref_table_init");
+
        assert(LOCALREFTABLE == NULL);
 
 #if !defined(ENABLE_GC_BOEHM)
index dc7afe47160feed4e61f797a4821d13d54061233..be2aea2f5bac0a89ea44c16a311f92fc827da93b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/native.c - table of native 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.
 
@@ -91,6 +89,8 @@ static s4 native_tree_native_methods_comparator(const void *treenode, const void
 
 bool native_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("native_init");
+
 #if defined(ENABLE_LTDL)
        /* initialize libltdl */
 
@@ -171,12 +171,12 @@ static utf *native_make_overloaded_function(utf *name, utf *descriptor)
        char *utf_ptr;
        u2    c;
        s4    i;
-       s4    dumpsize;
        utf  *u;
+       int32_t dumpmarker;
 
        /* mark memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        utf_ptr = descriptor->text;
        namelen = strlen(name->text) + strlen("__") + strlen("0");
@@ -268,7 +268,7 @@ static utf *native_make_overloaded_function(utf *name, utf *descriptor)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return u;
 }
@@ -351,12 +351,12 @@ static utf *native_method_symbol(utf *classname, utf *methodname)
        char *utf_endptr;
        u2    c;
        u4    pos;
-       s4    dumpsize;
        utf  *u;
+       int32_t dumpmarker;
 
        /* mark memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* Calculate length of native function name.  We multiply the
           class and method name length by 6 as this is the maxium
@@ -412,7 +412,7 @@ static utf *native_method_symbol(utf *classname, utf *methodname)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return u;
 }
@@ -475,7 +475,7 @@ static functionptr native_method_find(methodinfo *m)
 
        /* fill the temporary structure used for searching the tree */
 
-       tmpnmn.classname  = m->class->name;
+       tmpnmn.classname  = m->clazz->name;
        tmpnmn.name       = m->name;
        tmpnmn.descriptor = m->descriptor;
 
@@ -508,7 +508,7 @@ functionptr native_method_resolve(methodinfo *m)
        utf                            *newname;
        functionptr                     f;
 #if defined(ENABLE_LTDL)
-       classloader                    *cl;
+       classloader_t                  *cl;
        hashtable_library_loader_entry *le;
        hashtable_library_name_entry   *ne;
        u4                              key;    /* hashkey                        */
@@ -523,7 +523,7 @@ functionptr native_method_resolve(methodinfo *m)
 
        if (opt_verbosejni) {
                printf("[Dynamic-linking native method ");
-               utf_display_printable_ascii_classname(m->class->name);
+               utf_display_printable_ascii_classname(m->clazz->name);
                printf(".");
                utf_display_printable_ascii(m->name);
                printf(" ... ");
@@ -531,7 +531,7 @@ functionptr native_method_resolve(methodinfo *m)
 
        /* generate method symbol string */
 
-       name = native_method_symbol(m->class->name, m->name);
+       name = native_method_symbol(m->clazz->name, m->name);
 
        /* generate overloaded function (having the types in it's name)           */
 
@@ -545,7 +545,7 @@ functionptr native_method_resolve(methodinfo *m)
 #if defined(ENABLE_LTDL)
        /* Get the classloader. */
 
-       cl = class_get_classloader(m->class);
+       cl = class_get_classloader(m->clazz);
 
        /* normally addresses are aligned to 4, 8 or 16 bytes */
 
@@ -644,6 +644,12 @@ functionptr native_method_resolve(methodinfo *m)
 
    Open a native library with the given utf8 name.
 
+   IN:
+       filename ... filename of the library to open
+
+   RETURN:
+       handle of the opened library
+
 *******************************************************************************/
 
 #if defined(ENABLE_LTDL)
@@ -662,9 +668,12 @@ lt_dlhandle native_library_open(utf *filename)
        handle = lt_dlopen(filename->text);
 
        if (handle == NULL) {
+               if (opt_verbosejni)
+                       printf("failed ]\n");
+
                if (opt_verbose) {
                        log_start();
-                       log_print("native_library_load: lt_dlopen failed: ");
+                       log_print("native_library_open: lt_dlopen failed: ");
                        log_print(lt_dlerror());
                        log_finish();
                }
@@ -672,11 +681,50 @@ lt_dlhandle native_library_open(utf *filename)
                return NULL;
        }
 
+       if (opt_verbosejni)
+               printf("OK ]\n");
+
        return handle;
 }
 #endif
 
 
+/* native_library_close ********************************************************
+
+   Close the native library of the given handle.
+
+   IN:
+       handle ... handle of the open library
+
+*******************************************************************************/
+
+#if defined(ENABLE_LTDL)
+void native_library_close(lt_dlhandle handle)
+{
+       int result;
+
+       if (opt_verbosejni) {
+               printf("[Unloading native library ");
+/*             utf_display_printable_ascii(filename); */
+               printf(" ... ");
+       }
+
+       /* Close the library. */
+
+       result = lt_dlclose(handle);
+
+       if (result != 0) {
+               if (opt_verbose) {
+                       log_start();
+                       log_print("native_library_close: lt_dlclose failed: ");
+                       log_print(lt_dlerror());
+                       log_finish();
+               }
+       }
+}
+#endif
+
+
 /* native_library_add **********************************************************
 
    Adds an entry to the native library hashtable.
@@ -684,7 +732,7 @@ lt_dlhandle native_library_open(utf *filename)
 *******************************************************************************/
 
 #if defined(ENABLE_LTDL)
-void native_library_add(utf *filename, classloader *loader, lt_dlhandle handle)
+void native_library_add(utf *filename, classloader_t *loader, lt_dlhandle handle)
 {
        hashtable_library_loader_entry *le;
        hashtable_library_name_entry   *ne; /* library name                       */
@@ -767,7 +815,7 @@ void native_library_add(utf *filename, classloader *loader, lt_dlhandle handle)
 
 #if defined(ENABLE_LTDL)
 hashtable_library_name_entry *native_library_find(utf *filename,
-                                                                                                 classloader *loader)
+                                                                                                 classloader_t *loader)
 {
        hashtable_library_loader_entry *le;
        hashtable_library_name_entry   *ne; /* library name                       */
@@ -812,6 +860,86 @@ hashtable_library_name_entry *native_library_find(utf *filename,
 #endif
 
 
+/* native_library_load *********************************************************
+
+   Load a native library and initialize it, if possible.
+
+   IN:
+       name ... name of the library
+          cl ..... classloader which loads this library
+
+   RETURN:
+       1 ... library loaded successfully
+       0 ... error
+
+*******************************************************************************/
+
+int native_library_load(JNIEnv *env, utf *name, classloader_t *cl)
+{
+#if defined(ENABLE_LTDL)
+       lt_dlhandle        handle;
+# if defined(ENABLE_JNI)
+       lt_ptr             onload;
+       int32_t            version;
+# endif
+
+       if (name == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       /* Is the library already loaded? */
+
+       if (native_library_find(name, cl) != NULL)
+               return 1;
+
+       /* Open the library. */
+
+       handle = native_library_open(name);
+
+       if (handle == NULL)
+               return 0;
+
+# if defined(ENABLE_JNI)
+       /* Resolve JNI_OnLoad function. */
+
+       onload = lt_dlsym(handle, "JNI_OnLoad");
+
+       if (onload != NULL) {
+               JNIEXPORT int32_t (JNICALL *JNI_OnLoad) (JavaVM *, void *);
+               JavaVM *vm;
+
+               JNI_OnLoad = (JNIEXPORT int32_t (JNICALL *)(JavaVM *, void *)) (ptrint) onload;
+
+               (*env)->GetJavaVM(env, &vm);
+
+               version = JNI_OnLoad(vm, NULL);
+
+               /* If the version is not 1.2 and not 1.4 the library cannot be
+                  loaded. */
+
+               if ((version != JNI_VERSION_1_2) && (version != JNI_VERSION_1_4)) {
+                       lt_dlclose(handle);
+                       return 0;
+               }
+       }
+# endif
+
+       /* Insert the library name into the library hash. */
+
+       native_library_add(name, cl, handle);
+
+       return 1;
+#else
+       vm_abort("native_library_load: not available");
+
+       /* Keep compiler happy. */
+
+       return 0;
+#endif
+}
+
+
 /* native_new_and_init *********************************************************
 
    Creates a new object on the heap and calls the initializer.
index c67888c16231dcf8d7a2fa409e3600928789b75c..974a02bc0046a9ebe1be80985ccbd27ff8023174 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/native.h - table of native 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.
 
@@ -70,7 +68,7 @@ typedef struct hashtable_library_loader_entry hashtable_library_loader_entry;
 typedef struct hashtable_library_name_entry   hashtable_library_name_entry;
 
 struct hashtable_library_loader_entry {
-       classloader                    *loader;  /* class loader                  */
+       classloader_t                  *loader;  /* class loader                  */
        hashtable_library_name_entry   *namelink;/* libs loaded by this loader    */
        hashtable_library_loader_entry *hashlink;/* link for external chaining    */
 };
@@ -97,10 +95,10 @@ functionptr native_method_resolve(methodinfo *m);
 
 #if defined(ENABLE_LTDL)
 lt_dlhandle native_library_open(utf *filename);
-void        native_library_add(utf *filename, classloader *loader,
-                                                          lt_dlhandle handle);
-hashtable_library_name_entry *native_library_find(utf *filename,
-                                                                                                 classloader *loader);
+void        native_library_close(lt_dlhandle handle);
+void        native_library_add(utf *filename, classloader_t *loader, lt_dlhandle handle);
+hashtable_library_name_entry *native_library_find(utf *filename, classloader_t *loader);
+int         native_library_load(JNIEnv *env, utf *name, classloader_t *cl);
 #endif
 
 java_handle_t *native_new_and_init(classinfo *c);
index 708c861a787131c1597e450cc121ab969555454f..74cce363f2434752df10b1e0b4c318eea314d0b9 100644 (file)
@@ -1,9 +1,7 @@
 ## src/native/vm/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.
 ##
@@ -61,18 +59,6 @@ REFLECT_SOURCES = \
        reflect.c \
        reflect.h
 
-CLASSLOADER_SOURCES = \
-       java_lang_ClassLoader.c \
-       java_lang_ClassLoader.h
-
-JAVA_LANG_REFLECT_CONSTRUCTOR_SOURCES = \
-       java_lang_reflect_Constructor.c \
-       java_lang_reflect_Constructor.h
-
-JAVA_LANG_REFLECT_METHOD_SOURCES = \
-       java_lang_reflect_Method.c \
-       java_lang_reflect_Method.h
-
 SUN_MISC_UNSAFE_SOURCES = \
        sun_misc_Unsafe.c
 endif
@@ -84,16 +70,6 @@ libnativevm_la_SOURCES = \
        nativevm.c \
        nativevm.h \
        $(REFLECT_SOURCES) \
-       \
-       java_lang_Class.c \
-       java_lang_Class.h \
-       $(CLASSLOADER_SOURCES) \
-       java_lang_Runtime.c \
-       java_lang_Runtime.h \
-       java_lang_Thread.c \
-       java_lang_Thread.h \
-       $(JAVA_LANG_REFLECT_CONSTRUCTOR_SOURCES) \
-       $(JAVA_LANG_REFLECT_METHOD_SOURCES) \
        $(SUN_MISC_UNSAFE_SOURCES)
 
 libnativevm_la_LIBADD = \
index 8814d2f9f35d22222d3db3c5e2716003f3bd7fb1..b5b113a90e66edafecb863bd80e584f8201f23b3 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/cldc1.1/com_sun_cldchi_jvm_JVM.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
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -35,8 +33,6 @@
 
 #include "native/include/com_sun_cldchi_jvm_JVM.h"
 
-#include "native/vm/java_lang_Runtime.h"
-
 #include "vm/exceptions.h"
 #include "vm/stringlocal.h"
 
@@ -71,19 +67,23 @@ void _Jv_com_sun_cldchi_jvm_JVM_init(void)
  */
 JNIEXPORT void JNICALL Java_com_sun_cldchi_jvm_JVM_loadLibrary(JNIEnv *env, jclass clazz, java_lang_String *libName)
 {
-       s4   result;
+       int  result;
        utf *name;
 
-#if defined(ENABLE_JNI)
-       result = _Jv_java_lang_Runtime_loadLibrary(env, libName, NULL);
-#else
-       result = _Jv_java_lang_Runtime_loadLibrary(libName, NULL);
-#endif
+       /* 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 one in case */
+       /* Check for error and throw an exception in case. */
 
        if (result == 0) {
-               name = javastring_toutf((java_handle_t *) libName, false);
                exceptions_throw_unsatisfiedlinkerror(name);
        }
 }
index af400933833a497c8d158a5a4cebd128439f46e4..3d438a719b3c202e71e1c78b9137ea230e8f8def 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/cldc1.1/java_lang_Class.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
+   Copyright (C) 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -37,7 +35,8 @@
 
 #include "native/include/java_lang_Class.h"
 
-#include "native/vm/java_lang_Class.h"
+#include "vm/exceptions.h"
+#include "vm/initialize.h"
 
 
 /* native methods implemented by this file ************************************/
@@ -75,7 +74,51 @@ void _Jv_java_lang_Class_init(void)
  */
 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_Class_forName(JNIEnv *env, jclass clazz, java_lang_String *name)
 {
-       return _Jv_java_lang_Class_forName(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);
 }
 
 
@@ -102,9 +145,15 @@ JNIEXPORT java_lang_Object* JNICALL Java_java_lang_Class_newInstance(JNIEnv *env
  * Method:    isInstance
  * Signature: (Ljava/lang/Object;)Z
  */
-JNIEXPORT s4 JNICALL Java_java_lang_Class_isInstance(JNIEnv *env, java_lang_Class *this, java_lang_Object *obj)
+JNIEXPORT int32_t JNICALL Java_java_lang_Class_isInstance(JNIEnv *env, java_lang_Class *this, java_lang_Object *obj)
 {
-       return _Jv_java_lang_Class_isInstance(this, obj);
+       classinfo     *c;
+       java_handle_t *h;
+
+       c = LLNI_classinfo_unwrap(this);
+       h = (java_handle_t *) obj;
+
+       return class_is_instance(c, h);
 }
 
 
@@ -113,9 +162,20 @@ JNIEXPORT s4 JNICALL Java_java_lang_Class_isInstance(JNIEnv *env, java_lang_Clas
  * Method:    isAssignableFrom
  * Signature: (Ljava/lang/Class;)Z
  */
-JNIEXPORT s4 JNICALL Java_java_lang_Class_isAssignableFrom(JNIEnv *env, java_lang_Class *this, java_lang_Class *cls)
+JNIEXPORT int32_t JNICALL Java_java_lang_Class_isAssignableFrom(JNIEnv *env, java_lang_Class *this, java_lang_Class *cls)
 {
-       return _Jv_java_lang_Class_isAssignableFrom(this, 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);
 }
 
 
@@ -156,7 +216,11 @@ JNIEXPORT int32_t JNICALL Java_java_lang_Class_isArray(JNIEnv *env, java_lang_Cl
  */
 JNIEXPORT java_lang_String* JNICALL Java_java_lang_Class_getName(JNIEnv *env, java_lang_Class *this)
 {
-       return _Jv_java_lang_Class_getName(this);
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(this);
+
+       return (java_lang_String*) class_get_classname(c);
 }
 
 
index 59190b9d566b475c97016573b29457e2490fa919..838c6834325f69805aeba03523795111c6fc543a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/cldc1.1/java_lang_Runtime.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
+   Copyright (C) 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
 
 #include "config.h"
-#include "vm/types.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 "native/vm/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 *) (ptrint) &Java_java_lang_Runtime_exitInternal },
-       { "freeMemory",   "()J",  (void *) (ptrint) &Java_java_lang_Runtime_freeMemory   },
-       { "totalMemory",  "()J",  (void *) (ptrint) &Java_java_lang_Runtime_totalMemory  },
-       { "gc",           "()V",  (void *) (ptrint) &Java_java_lang_Runtime_gc           },
+       { "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           },
 };
  
  
@@ -67,9 +70,9 @@ void _Jv_java_lang_Runtime_init(void)
  * Method:    exitInternal
  * Signature: (I)V
  */
-JNIEXPORT void JNICALL Java_java_lang_Runtime_exitInternal(JNIEnv *env, java_lang_Runtime *this, s4 status)
+JNIEXPORT void JNICALL Java_java_lang_Runtime_exitInternal(JNIEnv *env, java_lang_Runtime *this, int32_t status)
 {
-       _Jv_java_lang_Runtime_exit(status);
+       vm_shutdown(status);
 }
 
 
@@ -78,9 +81,9 @@ JNIEXPORT void JNICALL Java_java_lang_Runtime_exitInternal(JNIEnv *env, java_lan
  * Method:    freeMemory
  * Signature: ()J
  */
-JNIEXPORT s8 JNICALL Java_java_lang_Runtime_freeMemory(JNIEnv *env, java_lang_Runtime *this)
+JNIEXPORT int64_t JNICALL Java_java_lang_Runtime_freeMemory(JNIEnv *env, java_lang_Runtime *this)
 {
-       return _Jv_java_lang_Runtime_freeMemory();
+       return gc_get_free_bytes();
 }
 
 
@@ -89,9 +92,9 @@ JNIEXPORT s8 JNICALL Java_java_lang_Runtime_freeMemory(JNIEnv *env, java_lang_Ru
  * Method:    totalMemory
  * Signature: ()J
  */
-JNIEXPORT s8 JNICALL Java_java_lang_Runtime_totalMemory(JNIEnv *env, java_lang_Runtime *this)
+JNIEXPORT int64_t JNICALL Java_java_lang_Runtime_totalMemory(JNIEnv *env, java_lang_Runtime *this)
 {
-       return _Jv_java_lang_Runtime_totalMemory();
+       return gc_get_heap_size();
 }
 
 
@@ -102,7 +105,7 @@ JNIEXPORT s8 JNICALL Java_java_lang_Runtime_totalMemory(JNIEnv *env, java_lang_R
  */
 JNIEXPORT void JNICALL Java_java_lang_Runtime_gc(JNIEnv *env, java_lang_Runtime *this)
 {
-       _Jv_java_lang_Runtime_gc();
+       gc_call();
 }
 
 
index ec3ed489738da669a50ca9c80da6f09455fe5bb5..da9ffd01a604c358179e4883a802ab22e1945a0f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/cldc1.1/java_lang_Thread.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
+   Copyright (C) 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -36,9 +34,7 @@
 
 #include "native/include/java_lang_Thread.h"
 
-#include "native/vm/java_lang_Thread.h"
-
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
@@ -86,7 +82,11 @@ void _Jv_java_lang_Thread_init(void)
  */
 JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_Thread_currentThread(JNIEnv *env, jclass clazz)
 {
-       return _Jv_java_lang_Thread_currentThread();
+       java_lang_Thread *to;
+
+       to = (java_lang_Thread *) thread_get_current_object();
+
+       return to;
 }
 
 
@@ -97,7 +97,19 @@ JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_Thread_currentThread(JNIEnv *
  */
 JNIEXPORT void JNICALL Java_java_lang_Thread_setPriority0(JNIEnv *env, java_lang_Thread *this, s4 oldPriority, s4 newPriority)
 {
-       _Jv_java_lang_Thread_setPriority(this, 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
 }
 
 
@@ -108,7 +120,9 @@ JNIEXPORT void JNICALL Java_java_lang_Thread_setPriority0(JNIEnv *env, java_lang
  */
 JNIEXPORT void JNICALL Java_java_lang_Thread_sleep(JNIEnv *env, jclass clazz, s8 millis)
 {
-       _Jv_java_lang_Thread_sleep(millis);
+#if defined(ENABLE_THREADS)
+       threads_sleep(millis, 0);
+#endif
 }
 
 
@@ -119,7 +133,9 @@ JNIEXPORT void JNICALL Java_java_lang_Thread_sleep(JNIEnv *env, jclass clazz, s8
  */
 JNIEXPORT void JNICALL Java_java_lang_Thread_start0(JNIEnv *env, java_lang_Thread *this)
 {
-       _Jv_java_lang_Thread_start(this, 0);
+#if defined(ENABLE_THREADS)
+       threads_thread_start((java_handle_t *) this);
+#endif
 }
 
 
index 1d5defa305a53ec3fd1300d2e3acf7c42d76fb15..35885d1355e98dbf85bd9005f4c54c0963410045 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/cldc1.1/java_lang_Throwable.c - java/lang/Throwable
 
-   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.
 
 #include "config.h"
 
 #include <assert.h>
-
-#include "vm/types.h"
+#include <stdint.h>
 
 #include "native/jni.h"
+#include "native/llni.h"
 #include "native/native.h"
 
 #include "native/include/java_lang_Object.h"
@@ -44,8 +42,8 @@
 /* native methods implemented by this file ************************************/
  
 static JNINativeMethod methods[] = {
-       { "printStackTrace",  "()V", (void *) (ptrint) &Java_java_lang_Throwable_printStackTrace  },
-       { "fillInStackTrace", "()V", (void *) (ptrint) &Java_java_lang_Throwable_fillInStackTrace },
+       { "printStackTrace",  "()V", (void *) (uintptr_t) &Java_java_lang_Throwable_printStackTrace  },
+       { "fillInStackTrace", "()V", (void *) (uintptr_t) &Java_java_lang_Throwable_fillInStackTrace },
 };
 
 
@@ -77,7 +75,7 @@ JNIEXPORT void JNICALL Java_java_lang_Throwable_printStackTrace(JNIEnv *env, jav
        o = (java_handle_t *) this;
 
        exceptions_print_exception(o);
-       stacktrace_print_trace(o);
+       stacktrace_print_exception(o);
 }
 
 
@@ -90,12 +88,12 @@ JNIEXPORT void JNICALL Java_java_lang_Throwable_fillInStackTrace(JNIEnv *env, ja
 {
        java_handle_bytearray_t *ba;
 
-       ba = stacktrace_fillInStackTrace();
+       ba = stacktrace_get_current();
 
        if (ba == NULL)
                return;
 
-       this->backtrace = (java_lang_Object *) ba;
+       LLNI_field_set_ref(this, backtrace, (java_lang_Object *) ba);
 }
 
 
index e2b53c77f9bf470f65401ed44da00937e9bf9bbf..219f88d5ea8bcba0284f962f6f308d410c3e3319 100644 (file)
@@ -1,9 +1,7 @@
 ## src/native/vm/gnu/Makefile.am
 ##
-## 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.
 ##
 ## 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
 
 
 AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR) -I$(top_builddir)/src
@@ -47,6 +41,7 @@ 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 \
@@ -60,9 +55,9 @@ libnativevmcore_la_SOURCES = \
        java_lang_VMThread.c \
        java_lang_VMThrowable.c \
        java_lang_management_VMManagementFactory.c \
-       java_lang_reflect_Constructor.c \
-       java_lang_reflect_Field.c \
-       java_lang_reflect_Method.c \
+       java_lang_reflect_VMConstructor.c \
+       java_lang_reflect_VMField.c \
+       java_lang_reflect_VMMethod.c \
        java_lang_reflect_VMProxy.c \
        java_security_VMAccessController.c \
        java_util_concurrent_atomic_AtomicLong.c \
index 55187d3df3e357eb737a7eb3a10e6ec56f56d38b..eca8f531a7935dde6fa5d7df6319180b85d306ac 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/gnu/gnu_classpath_VMStackWalker.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.
 
@@ -28,7 +26,6 @@
 #include "config.h"
 
 #include "native/jni.h"
-#include "native/llni.h"
 #include "native/native.h"
 
 #include "native/include/java_lang_Class.h"
 
 #include "native/include/gnu_classpath_VMStackWalker.h"
 
-#include "vm/array.h"
-#include "vm/builtin.h"
 #include "vm/global.h"
 
 #include "vm/jit/stacktrace.h"
 
 #include "vmcore/class.h"
+#include "vmcore/utf8.h"
 
 
 /* native methods implemented by this file ************************************/
@@ -93,20 +89,11 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_gnu_classpath_VMStackWalker_ge
  */
 JNIEXPORT java_lang_Class* JNICALL Java_gnu_classpath_VMStackWalker_getCallingClass(JNIEnv *env, jclass clazz)
 {
-       java_handle_objectarray_t *oa;
-       java_handle_t             *o;
-
-       oa = stacktrace_getClassContext();
-
-       if (oa == NULL)
-               return NULL;
+       classinfo *c;
 
-       if (LLNI_array_size(oa) < 2)
-               return NULL;
+       c = stacktrace_get_caller_class(2);
 
-       o = array_objectarray_element_get(oa, 1);
-
-       return (java_lang_Class *) o;
+       return (java_lang_Class *) c;
 }
 
 
@@ -117,19 +104,10 @@ JNIEXPORT java_lang_Class* JNICALL Java_gnu_classpath_VMStackWalker_getCallingCl
  */
 JNIEXPORT java_lang_ClassLoader* JNICALL Java_gnu_classpath_VMStackWalker_getCallingClassLoader(JNIEnv *env, jclass clazz)
 {
-       java_handle_objectarray_t *oa;
-       classinfo                 *c;
-       classloader               *cl;
-
-       oa = stacktrace_getClassContext();
+       classinfo     *c;
+       classloader_t *cl;
 
-       if (oa == NULL)
-               return NULL;
-
-       if (LLNI_array_size(oa) < 2)
-               return NULL;
-        
-       c  = (classinfo *) LLNI_array_direct(oa, 1);
+       c  = stacktrace_get_caller_class(2);
        cl = class_get_classloader(c);
 
        return (java_lang_ClassLoader *) cl;
@@ -143,25 +121,11 @@ JNIEXPORT java_lang_ClassLoader* JNICALL Java_gnu_classpath_VMStackWalker_getCal
  */
 JNIEXPORT java_lang_ClassLoader* JNICALL Java_gnu_classpath_VMStackWalker_firstNonNullClassLoader(JNIEnv *env, jclass clazz)
 {
-       java_handle_objectarray_t *oa;
-       classinfo                 *c;
-       classloader               *cl;
-       s4                         i;
-
-       oa = stacktrace_getClassContext();
+       classloader_t *cl;
 
-       if (oa == NULL)
-               return NULL;
+       cl = stacktrace_first_nonnull_classloader();
 
-       for (i = 0; i < LLNI_array_size(oa); i++) {
-               c  = (classinfo *) LLNI_array_direct(oa, i);
-               cl = class_get_classloader(c);
-
-               if (cl != NULL)
-                       return (java_lang_ClassLoader *) cl;
-       }
-
-       return NULL;
+       return (java_lang_ClassLoader *) cl;
 }
 
 
index 2763e9e43fda78c7521a70016749b0d4866c27da..5517c6c1a03bb1b80bdcb72843110e06150603da 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/gnu/gnu_classpath_VMSystemProperties.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.
 
@@ -100,7 +98,7 @@ JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_preInit(JNIEnv *env
 JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_postInit(JNIEnv *env, jclass clazz, java_util_Properties *properties)
 {
        java_handle_t *p;
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
        char *java_home;
        char *path;
        s4    len;
@@ -115,7 +113,7 @@ JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_postInit(JNIEnv *en
 
        /* post-set some properties */
 
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
        /* XXX when we do it that way, we can't set these properties on
           commandline */
 
index 7d428de8e69238938a9d739cc9c50bf567b131f5..e647e4d940e81a9a47d05b95fcde3f0701693496 100644 (file)
@@ -1,48 +1,49 @@
-/* src/native/vm/VMFrame.c - jdwp->jvmti interface
+/* src/native/vm/gnu/gnu_classpath_jdwp_VMFrame.c - jdwp->jvmti interface
 
-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.
+   This file is part of CACAO.
 
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2, or (at
-your option) any later version.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
 
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
+   You should have received a copy of the GNU General Public 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: Martin Platter
 
-Changes:
+#include "config.h"
 
-*/
+#include <stdint.h>
 
-#include "toolbox/logging.h"
 #include "native/jni.h"
+
+#include "native/include/java_lang_Object.h"
 #include "native/include/gnu_classpath_jdwp_VMFrame.h"
 
+#include "toolbox/logging.h"
+
 
 /*
  * Class:     gnu/classpath/jdwp/VMFrame
  * Method:    getValue
  * Signature: (I)Ljava/lang/Object;
  */
-JNIEXPORT struct java_lang_Object* JNICALL Java_gnu_classpath_jdwp_VMFrame_getValue(JNIEnv *env, struct gnu_classpath_jdwp_VMFrame* this, s4 par1) {
-    log_text ("JVMTI-Call: IMPLEMENT ME!!!");
-    return 0;
+JNIEXPORT java_lang_Object* JNICALL Java_gnu_classpath_jdwp_VMFrame_getValue(JNIEnv *env, gnu_classpath_jdwp_VMFrame* this, int32_t par1)
+{
+       log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       return 0;
 }
 
 
@@ -51,7 +52,23 @@ JNIEXPORT struct java_lang_Object* JNICALL Java_gnu_classpath_jdwp_VMFrame_getVa
  * Method:    setValue
  * Signature: (ILjava/lang/Object;)V
  */
-JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMFrame_setValue(JNIEnv *env, struct gnu_classpath_jdwp_VMFrame* this, s4 par1, struct java_lang_Object* par2) {
-    log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMFrame_setValue(JNIEnv *env, gnu_classpath_jdwp_VMFrame* this, int32_t par1, java_lang_Object* par2)
+{
+       log_text ("JVMTI-Call: 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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index cce58eb8dbfedadf4646f648f9ef8774060b3003..54ff53478a647926d4dce1029cc3a94d181551c8 100644 (file)
@@ -1,39 +1,36 @@
-/* src/native/vm/VMMethod.c - jdwp->jvmti interface
+/* src/native/vm/gnu/gnu_classpath_jdwp_VMMethod.c - jdwp->jvmti interface
 
-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.
+   This file is part of CACAO.
 
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2, or (at
-your option) any later version.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
 
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
+   You should have received a copy of the GNU General Public 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: Samuel Vinson
-         Martin Platter
-         
-
-Changes: 
 
+#include "config.h"
 
+#include <stdint.h>
 
 #include "native/jni.h"
+
 #include "native/include/gnu_classpath_jdwp_VMMethod.h"
+
 #include "native/jvmti/jvmti.h"
 #include "native/jvmti/VMjdwp.h"
 
@@ -55,7 +52,7 @@ void printjvmtierror(char *desc, jvmtiError err) {
  * Method:    getName
  * Signature: ()Ljava/lang/String;
  */
-JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getName(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this) 
+JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getName(JNIEnv *env, gnu_classpath_jdwp_VMMethod* this) 
 {
     jvmtiError err;
     char *name;
@@ -81,7 +78,7 @@ JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getN
  * Method:    getSignature
  * Signature: ()Ljava/lang/String;
  */
-JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getSignature(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this) 
+JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getSignature(JNIEnv *env, gnu_classpath_jdwp_VMMethod* this) 
 {
     jvmtiError err;
     char *signature;
@@ -107,7 +104,7 @@ JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getS
  * Method:    getModifiers
  * Signature: ()I
  */
-JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMMethod_getModifiers(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this) 
+JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMMethod_getModifiers(JNIEnv *env, gnu_classpath_jdwp_VMMethod* this) 
 {
     jvmtiError err;
     jint modifiers;
index eb5a4287bacb2e281e5a74fa83c2e98bd81f807b..9e06a6b57b737eb72827bb27444d8296e3118aa1 100644 (file)
@@ -1,34 +1,32 @@
-/* src/native/vm/VMVirtualMachine.c - jdwp->jvmti interface
+/* src/native/vm/gnu/gnu_classpath_jdwp_VMVirtualMachine.c - jdwp->jvmti interface
 
-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.
+   This file is part of CACAO.
 
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2, or (at
-your option) any later version.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
 
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
+   You should have received a copy of the GNU General Public 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: Martin Platter
 
-Changes: Samuel Vinson
+#include "config.h"
 
-*/
+#include <stdint.h>
+#include <string.h>
 
 #include "toolbox/logging.h"
 #include "native/jni.h"
@@ -41,7 +39,6 @@ Changes: Samuel Vinson
 #include "native/include/gnu_classpath_jdwp_VMVirtualMachine.h"
 #include "native/jvmti/jvmti.h"
 #include "native/jvmti/VMjdwp.h"
-#include <string.h>
 
 
 /*
@@ -76,7 +73,7 @@ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_resumeThread(JNI
  * Method:    getSuspendCount
  * Signature: (Ljava/lang/Thread;)I
  */
-JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSuspendCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
+JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSuspendCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
     log_text ("VMVirtualMachine_getSuspendCount: not supported");
        return 1;
 }
@@ -86,7 +83,7 @@ JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSuspendCount(JN
  * Method:    getAllLoadedClassesCount
  * Signature: ()I
  */
-JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClassesCount(JNIEnv *env, jclass clazz) {
+JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClassesCount(JNIEnv *env, jclass clazz) {
     jint count;
     jclass* classes;
        jvmtiError err;
@@ -157,7 +154,7 @@ JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMa
  * Method:    getClassStatus
  * Signature: (Ljava/lang/Class;)I
  */
-JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
+JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
        jint status;
        jvmtiError err;
 
@@ -237,7 +234,7 @@ JNIEXPORT struct gnu_classpath_jdwp_VMMethod* JNICALL Java_gnu_classpath_jdwp_VM
  * Method:    getFrames
  * Signature: (Ljava/lang/Thread;II)Ljava/util/ArrayList;
  */
-JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrames(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, s4 par2, s4 par3) {
+JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrames(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, int32_t par2, int32_t par3) {
     log_text ("VMVirtualMachine_getFrames - IMPLEMENT ME!!!");
 /*     jclass ec = (*env)->FindClass(env,"gnu/classpath/jdwp/JdwpInternalErrorException");
        if (JVMTI_ERROR_NONE != (*jvmtienv)->GetClassStatus(jvmtienv, par1, &status))
@@ -262,7 +259,7 @@ JNIEXPORT struct gnu_classpath_jdwp_VMFrame* JNICALL Java_gnu_classpath_jdwp_VMV
  * Method:    getFrameCount
  * Signature: (Ljava/lang/Thread;)I
  */
-JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
+JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
        jint count;
        jvmtiError err;
        err = (*jvmtienv)->GetFrameCount(jvmtienv, (jthread)par1, &count);
@@ -276,7 +273,7 @@ JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIE
  * Method:    getThreadStatus
  * Signature: (Ljava/lang/Thread;)I
  */
-JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
+JNIEXPORT int32_t JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
        jint status;
        jvmtiError err; 
        if (JVMTI_ERROR_NONE != (err = (*jvmtienv)->GetThreadState(jvmtienv, (jthread)par1, &status))) {
@@ -316,7 +313,7 @@ JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualM
  * Method:    executeMethod
  * Signature: (Ljava/lang/Object;Ljava/lang/Thread;Ljava/lang/Class;Ljava/lang/reflect/Method;[Ljava/lang/Object;Z)Lgnu/classpath/jdwp/util/MethodResult;
  */
-JNIEXPORT struct gnu_classpath_jdwp_util_MethodResult* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_executeMethod(JNIEnv *env, jclass clazz, struct java_lang_Object* par1, struct java_lang_Thread* par2, struct java_lang_Class* par3, struct java_lang_reflect_Method* par4, java_objectarray* par5, s4 par6) {
+JNIEXPORT struct gnu_classpath_jdwp_util_MethodResult* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_executeMethod(JNIEnv *env, jclass clazz, struct java_lang_Object* par1, struct java_lang_Thread* par2, struct java_lang_Class* par3, struct java_lang_reflect_Method* par4, java_objectarray* par5, int32_t par6) {
     log_text ("VMVirtualMachine_executeMethod");
        return 0;
 }
@@ -421,7 +418,7 @@ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_unregisterEvent(
  * Method:    clearEvents
  * Signature: (B)V
  */
-JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_clearEvents(JNIEnv *env, jclass clazz, s4 par1) {
+JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_clearEvents(JNIEnv *env, jclass clazz, int32_t par1) {
        /* jvmti events are not saved - there is nothing to clear */
 }
 
diff --git a/src/native/vm/gnu/gnu_java_lang_VMCPStringBuilder.c b/src/native/vm/gnu/gnu_java_lang_VMCPStringBuilder.c
new file mode 100644 (file)
index 0000000..0511085
--- /dev/null
@@ -0,0 +1,129 @@
+/* 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:
+ */
index b203a73a5728fdd58cc90e68790e29dd97a3fdc0..4c05838d9e9b632ec6360fe9e3b48aa976601146 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/gnu/gnu_java_lang_management_VMMemoryMXBeanImpl.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.
 
@@ -26,7 +24,8 @@
 
 
 #include "config.h"
-#include "vm/types.h"
+
+#include <stdint.h>
 
 #include "mm/gc-common.h"
 
 /* native methods implemented by this file ************************************/
 
 static JNINativeMethod methods[] = {
-       { "getHeapMemoryUsage",                "()Ljava/lang/management/MemoryUsage;", (void *) (ptrint) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getHeapMemoryUsage                },
-       { "getNonHeapMemoryUsage",             "()Ljava/lang/management/MemoryUsage;", (void *) (ptrint) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getNonHeapMemoryUsage             },
-       { "getObjectPendingFinalizationCount", "()I",                                  (void *) (ptrint) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount },
-       { "isVerbose",                         "()Z",                                  (void *) (ptrint) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose                         },
-       { "setVerbose",                        "(Z)V",                                 (void *) (ptrint) &Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose                        },
+       { "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                        },
 };
 
 
@@ -84,10 +83,10 @@ JNIEXPORT java_lang_management_MemoryUsage* JNICALL Java_gnu_java_lang_managemen
        java_handle_t                    *o;
        java_lang_management_MemoryUsage *mu;
        methodinfo                       *m;
-       s8                                init;
-       s8                                used;
-       s8                                commited;
-       s8                                maximum;
+       int64_t                           init;
+       int64_t                           used;
+       int64_t                           commited;
+       int64_t                           maximum;
 
        /* get the class */
        /* XXX optimize me! sometime... */
@@ -150,7 +149,7 @@ JNIEXPORT java_lang_management_MemoryUsage* JNICALL Java_gnu_java_lang_managemen
  * Method:    getObjectPendingFinalizationCount
  * Signature: ()I
  */
-JNIEXPORT s4 JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectPendingFinalizationCount(JNIEnv *env, jclass clazz)
+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!");
 
@@ -163,7 +162,7 @@ JNIEXPORT s4 JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_getObjectP
  * Method:    isVerbose
  * Signature: ()Z
  */
-JNIEXPORT s4 JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose(JNIEnv *env, jclass clazz)
+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;
 }
@@ -174,7 +173,7 @@ JNIEXPORT s4 JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_isVerbose(
  * Method:    setVerbose
  * Signature: (Z)V
  */
-JNIEXPORT void JNICALL Java_gnu_java_lang_management_VMMemoryMXBeanImpl_setVerbose(JNIEnv *env, jclass clazz, s4 verbose)
+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;
 }
index efd36b1277cbb38ba96996d6613efba566cee526..886a3ced0efcc183ea17f09a06750c34e842862a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/gnu/java_lang_VMClass.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
+   Copyright (C) 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -29,8 +27,6 @@
 
 #include <stdint.h>
 
-#include "vm/types.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 "native/vm/java_lang_Class.h"
-
 #include "vm/exceptions.h"
+#include "vm/initialize.h"
 #include "vm/stringlocal.h"
 
 #include "vmcore/class.h"
 
+#if defined(WITH_CLASSPATH_GNU) && 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 *) (ptrint) &Java_java_lang_VMClass_isInstance              },
-       { "isAssignableFrom",        "(Ljava/lang/Class;Ljava/lang/Class;)Z",                         (void *) (ptrint) &Java_java_lang_VMClass_isAssignableFrom        },
-       { "isInterface",             "(Ljava/lang/Class;)Z",                                          (void *) (ptrint) &Java_java_lang_VMClass_isInterface             },
-       { "isPrimitive",             "(Ljava/lang/Class;)Z",                                          (void *) (ptrint) &Java_java_lang_VMClass_isPrimitive             },
-       { "getName",                 "(Ljava/lang/Class;)Ljava/lang/String;",                         (void *) (ptrint) &Java_java_lang_VMClass_getName                 },
-       { "getSuperclass",           "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void *) (ptrint) &Java_java_lang_VMClass_getSuperclass           },
-       { "getInterfaces",           "(Ljava/lang/Class;)[Ljava/lang/Class;",                         (void *) (ptrint) &Java_java_lang_VMClass_getInterfaces           },
-       { "getComponentType",        "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void *) (ptrint) &Java_java_lang_VMClass_getComponentType        },
-       { "getModifiers",            "(Ljava/lang/Class;Z)I",                                         (void *) (ptrint) &Java_java_lang_VMClass_getModifiers            },
-       { "getDeclaringClass",       "(Ljava/lang/Class;)Ljava/lang/Class;",                          (void *) (ptrint) &Java_java_lang_VMClass_getDeclaringClass       },
-       { "getDeclaredClasses",      "(Ljava/lang/Class;Z)[Ljava/lang/Class;",                        (void *) (ptrint) &Java_java_lang_VMClass_getDeclaredClasses      },
-       { "getDeclaredFields",       "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;",                (void *) (ptrint) &Java_java_lang_VMClass_getDeclaredFields       },
-       { "getDeclaredMethods",      "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;",               (void *) (ptrint) &Java_java_lang_VMClass_getDeclaredMethods      },
-       { "getDeclaredConstructors", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;",          (void *) (ptrint) &Java_java_lang_VMClass_getDeclaredConstructors },
-       { "getClassLoader",          "(Ljava/lang/Class;)Ljava/lang/ClassLoader;",                    (void *) (ptrint) &Java_java_lang_VMClass_getClassLoader          },
-       { "forName",                 "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_VMClass_forName                 },
-       { "isArray",                 "(Ljava/lang/Class;)Z",                                          (void *) (ptrint) &Java_java_lang_VMClass_isArray                 },
-       { "throwException",          "(Ljava/lang/Throwable;)V",                                      (void *) (ptrint) &Java_java_lang_VMClass_throwException          },
+       { "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(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
-       { "getDeclaredAnnotations",  "(Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;",         (void *) (ptrint) &Java_java_lang_VMClass_getDeclaredAnnotations  },
+       { "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 *) (ptrint) &Java_java_lang_VMClass_getEnclosingClass       },
-       { "getEnclosingConstructor", "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;",            (void *) (ptrint) &Java_java_lang_VMClass_getEnclosingConstructor },
-       { "getEnclosingMethod",      "(Ljava/lang/Class;)Ljava/lang/reflect/Method;",                 (void *) (ptrint) &Java_java_lang_VMClass_getEnclosingMethod      },
-       { "getClassSignature",       "(Ljava/lang/Class;)Ljava/lang/String;",                         (void *) (ptrint) &Java_java_lang_VMClass_getClassSignature       },
-       { "isAnonymousClass",        "(Ljava/lang/Class;)Z",                                          (void *) (ptrint) &Java_java_lang_VMClass_isAnonymousClass        },
-       { "isLocalClass",            "(Ljava/lang/Class;)Z",                                          (void *) (ptrint) &Java_java_lang_VMClass_isLocalClass            },
-       { "isMemberClass",           "(Ljava/lang/Class;)Z",                                          (void *) (ptrint) &Java_java_lang_VMClass_isMemberClass           },
+       { "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           },
 };
 
 
@@ -107,9 +111,15 @@ void _Jv_java_lang_VMClass_init(void)
  * Method:    isInstance
  * Signature: (Ljava/lang/Class;Ljava/lang/Object;)Z
  */
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Object *o)
+JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Object *o)
 {
-       return _Jv_java_lang_Class_isInstance(klass, o);
+       classinfo     *c;
+       java_handle_t *h;
+
+       c = LLNI_classinfo_unwrap(klass);
+       h = (java_handle_t *) o;
+
+       return class_is_instance(c, h);
 }
 
 
@@ -118,9 +128,20 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz
  * Method:    isAssignableFrom
  * Signature: (Ljava/lang/Class;Ljava/lang/Class;)Z
  */
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Class *c)
+JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *klass, java_lang_Class *c)
 {
-       return _Jv_java_lang_Class_isAssignableFrom(klass, 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);
 }
 
 
@@ -129,7 +150,7 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass
  * Method:    isInterface
  * Signature: (Ljava/lang/Class;)Z
  */
-JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *klass)
+JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isInterface(JNIEnv *env, jclass clazz, java_lang_Class *klass)
 {
        classinfo *c;
 
@@ -161,7 +182,11 @@ JNIEXPORT int32_t JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass
  */
 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getName(JNIEnv *env, jclass clazz, java_lang_Class *klass)
 {
-       return _Jv_java_lang_Class_getName(klass);
+       classinfo* c;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       return (java_lang_String*) class_get_classname(c);
 }
 
 
@@ -260,7 +285,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIE
  * 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, s4 publicOnly)
+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;
@@ -278,9 +303,16 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredC
  * 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, s4 publicOnly)
+JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredFields(JNIEnv *env, jclass clazz, java_lang_Class *klass, int32_t publicOnly)
 {
-       return _Jv_java_lang_Class_getDeclaredFields(klass, publicOnly);
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       oa = class_get_declaredfields(c, publicOnly);
+
+       return oa;
 }
 
 
@@ -289,9 +321,16 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredF
  * 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, s4 publicOnly)
+JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JNIEnv *env, jclass clazz, java_lang_Class *klass, int32_t publicOnly)
 {
-       return _Jv_java_lang_Class_getDeclaredMethods(klass, publicOnly);
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       oa = class_get_declaredmethods(c, publicOnly);
+
+       return oa;
 }
 
 
@@ -300,9 +339,16 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredM
  * 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, s4 publicOnly)
+JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz, java_lang_Class *klass, int32_t publicOnly)
 {
-       return _Jv_java_lang_Class_getDeclaredConstructors(klass, publicOnly);
+       classinfo                 *c;
+       java_handle_objectarray_t *oa;
+
+       c = LLNI_classinfo_unwrap(klass);
+
+       oa = class_get_declaredconstructors(c, publicOnly);
+
+       return oa;
 }
 
 
@@ -313,8 +359,8 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredC
  */
 JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, java_lang_Class *klass)
 {
-       classinfo   *c;
-       classloader *cl;
+       classinfo     *c;
+       classloader_t *cl;
 
        c  = LLNI_classinfo_unwrap(klass);
        cl = class_get_classloader(c);
@@ -328,9 +374,57 @@ JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(J
  * 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, s4 initialize, java_lang_ClassLoader *loader)
+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)
 {
-       return _Jv_java_lang_Class_forName(name, initialize, 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);
 }
 
 
@@ -372,7 +466,64 @@ JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass
  */
 JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMClass_getDeclaredAnnotations(JNIEnv *env, jclass clazz, java_lang_Class* klass)
 {
-       return _Jv_java_lang_Class_getDeclaredAnnotations(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
 
@@ -402,7 +553,13 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getEnclosingClass(JNIE
  */
 JNIEXPORT java_lang_reflect_Constructor* JNICALL Java_java_lang_VMClass_getEnclosingConstructor(JNIEnv *env, jclass clazz, java_lang_Class *klass)
 {
-       return _Jv_java_lang_Class_getEnclosingConstructor(klass);
+       classinfo*     c;
+       java_handle_t* h;
+
+       c = LLNI_classinfo_unwrap(klass);
+       h = class_get_enclosingconstructor(c);
+
+       return (java_lang_reflect_Constructor*) h;
 }
 
 
@@ -413,7 +570,13 @@ JNIEXPORT java_lang_reflect_Constructor* JNICALL Java_java_lang_VMClass_getEnclo
  */
 JNIEXPORT java_lang_reflect_Method* JNICALL Java_java_lang_VMClass_getEnclosingMethod(JNIEnv *env, jclass clazz, java_lang_Class *klass)
 {
-       return _Jv_java_lang_Class_getEnclosingMethod(klass);
+       classinfo*     c;
+       java_handle_t* h;
+
+       c = LLNI_classinfo_unwrap(klass);
+       h = class_get_enclosingmethod(c);
+
+       return (java_lang_reflect_Method*) h;
 }
 
 
index e9a8b99778756d8c5fd5d1dc32e52d9f9c5c113f..7df215ca4a8ddbf57f5e43fc34fa53647a1f300d 100644 (file)
@@ -1,9 +1,7 @@
-/* src/native/vm/gnu/VMClassLoader.c
+/* src/native/vm/gnu/java_lang_VMClassLoader.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 "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 #include <sys/stat.h>
 
-#include "vm/types.h"
-
 #include "mm/memory.h"
 
 #include "native/jni.h"
@@ -48,8 +45,6 @@
 
 #include "native/include/java_lang_VMClassLoader.h"
 
-#include "native/vm/java_lang_ClassLoader.h"
-
 #include "toolbox/logging.h"
 #include "toolbox/list.h"
 
 /* native methods implemented by this file ************************************/
 
 static JNINativeMethod methods[] = {
-       { "defineClass",                "(Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_VMClassLoader_defineClass                },
-       { "getPrimitiveClass",          "(C)Ljava/lang/Class;",                                                                             (void *) (ptrint) &Java_java_lang_VMClassLoader_getPrimitiveClass          },
-       { "resolveClass",               "(Ljava/lang/Class;)V",                                                                             (void *) (ptrint) &Java_java_lang_VMClassLoader_resolveClass               },
-       { "loadClass",                  "(Ljava/lang/String;Z)Ljava/lang/Class;",                                                           (void *) (ptrint) &Java_java_lang_VMClassLoader_loadClass                  },
-       { "nativeGetResources",         "(Ljava/lang/String;)Ljava/util/Vector;",                                                           (void *) (ptrint) &Java_java_lang_VMClassLoader_nativeGetResources         },
-       { "defaultAssertionStatus",     "()Z",                                                                                              (void *) (ptrint) &Java_java_lang_VMClassLoader_defaultAssertionStatus     },
-       { "defaultUserAssertionStatus", "()Z",                                                                                              (void *) (ptrint) &Java_java_lang_VMClassLoader_defaultUserAssertionStatus },
-       { "packageAssertionStatus0",    "(Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;",                                          (void *) (ptrint) &Java_java_lang_VMClassLoader_packageAssertionStatus0    },
-       { "classAssertionStatus0",      "(Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;",                                          (void *) (ptrint) &Java_java_lang_VMClassLoader_classAssertionStatus0      },
-       { "findLoadedClass",            "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;",                                     (void *) (ptrint) &Java_java_lang_VMClassLoader_findLoadedClass            },
+       { "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            },
 };
 
 
@@ -116,9 +111,81 @@ void _Jv_java_lang_VMClassLoader_init(void)
  * 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, s4 offset, s4 len, java_security_ProtectionDomain *pd)
+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)
 {
-       return _Jv_java_lang_ClassLoader_defineClass(cl, name, data, offset, len, 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);
+
+#if defined(WITH_CLASSPATH_GNU)
+       /* set ProtectionDomain */
+
+       LLNI_field_set_ref(o, pd, pd);
+#endif
+
+       return o;
 }
 
 
@@ -127,7 +194,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
  * Method:    getPrimitiveClass
  * Signature: (C)Ljava/lang/Class;
  */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, s4 type)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, int32_t type)
 {
        classinfo *c;
 
@@ -172,7 +239,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jc
  * 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, s4 resolve)
+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;
@@ -218,10 +285,10 @@ JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResour
        char                 *buffer;    /* char buffer              */
        char                 *namestart; /* start of name to use     */
        char                 *tmppath;   /* temporary buffer         */
-       s4                    namelen;   /* length of name to use    */
-       s4                    searchlen; /* length of name to search */
-       s4                    bufsize;   /* size of buffer allocated */
-       s4                    pathlen;   /* name of path to assemble */
+       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"    */
 
@@ -352,7 +419,7 @@ return_NULL:
  * Method:    defaultAssertionStatus
  * Signature: ()Z
  */
-JNIEXPORT s4 JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv *env, jclass clazz)
+JNIEXPORT int32_t JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv *env, jclass clazz)
 {
 #if defined(ENABLE_ASSERTION)
        return assertion_system_enabled;
@@ -366,7 +433,7 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv
  * Method:    userAssertionStatus
  * Signature: ()Z
  */
-JNIEXPORT s4 JNICALL Java_java_lang_VMClassLoader_defaultUserAssertionStatus(JNIEnv *env, jclass clazz)
+JNIEXPORT int32_t JNICALL Java_java_lang_VMClassLoader_defaultUserAssertionStatus(JNIEnv *env, jclass clazz)
 {
 #if defined(ENABLE_ASSERTION)
        return assertion_user_enabled;
@@ -523,9 +590,9 @@ JNIEXPORT java_util_Map* JNICALL Java_java_lang_VMClassLoader_classAssertionStat
  */
 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_findLoadedClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *loader, java_lang_String *name)
 {
-       classloader *cl;
-       classinfo   *c;
-       utf         *u;
+       classloader_t *cl;
+       classinfo     *c;
+       utf           *u;
 
        /* XXX is it correct to add the classloader to the hashtable here? */
 
index a48cc03e0fbf013eebf43722479fb8dcae6ba9f9..25be0db79c490256d9d1a5bd524c8e4f47f5aa52 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/gnu/java_lang_VMRuntime.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 <sys/utsname.h>
 
 #if defined(__DARWIN__)
-# define OS_INLINE    /* required for <libkern/ppc/OSByteOrder.h> */
+# 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 "mm/memory.h"
 
 #include "native/jni.h"
 #include "native/native.h"
@@ -52,8 +52,6 @@
 
 #include "native/include/java_lang_VMRuntime.h"
 
-#include "native/vm/java_lang_Runtime.h"
-
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/stringlocal.h"
@@ -98,6 +96,9 @@ void _Jv_java_lang_VMRuntime_init(void)
 }
 
 
+static bool finalizeOnExit = false;
+
+
 /*
  * Class:     java/lang/VMRuntime
  * Method:    exit
@@ -105,7 +106,10 @@ void _Jv_java_lang_VMRuntime_init(void)
  */
 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, int32_t status)
 {
-       _Jv_java_lang_Runtime_exit(status);
+       if (finalizeOnExit)
+               gc_finalize_all();
+
+       vm_shutdown(status);
 }
 
 
@@ -116,7 +120,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz,
  */
 JNIEXPORT int64_t JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
 {
-       return _Jv_java_lang_Runtime_freeMemory();
+       return gc_get_free_bytes();
 }
 
 
@@ -127,7 +131,7 @@ JNIEXPORT int64_t JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclas
  */
 JNIEXPORT int64_t JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
 {
-       return _Jv_java_lang_Runtime_totalMemory();
+       return gc_get_heap_size();
 }
 
 
@@ -149,7 +153,7 @@ JNIEXPORT int64_t JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass
  */
 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
 {
-       _Jv_java_lang_Runtime_gc();
+       gc_call();
 }
 
 
@@ -171,7 +175,9 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jcl
  */
 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, int32_t value)
 {
-       _Jv_java_lang_Runtime_runFinalizersOnExit(value);
+       /* XXX threading */
+
+       finalizeOnExit = value;
 }
 
 
@@ -233,15 +239,21 @@ JNIEXPORT int32_t JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *e
  */
 JNIEXPORT int32_t JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *libname, java_lang_ClassLoader *loader)
 {
-       classloader *cl;
+       classloader_t *cl;
+       utf           *name;
 
        cl = loader_hashtable_classloader_add((java_handle_t *) loader);
 
-#if defined(ENABLE_JNI)
-       return _Jv_java_lang_Runtime_loadLibrary(env, libname, cl);
-#else
-       return _Jv_java_lang_Runtime_loadLibrary(libname, cl);
-#endif
+       /* 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);
 }
 
 
@@ -255,8 +267,8 @@ JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_mapLibraryName(JNIE
        utf           *u;
        char          *buffer;
        int32_t        buffer_len;
-       int32_t        dumpsize;
        java_handle_t *o;
+       int32_t        dumpmarker;
 
        if (libname == NULL) {
                exceptions_throw_nullpointerexception();
@@ -279,7 +291,8 @@ JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_mapLibraryName(JNIE
 
        buffer_len += strlen("0");
 
-       dumpsize = dump_size();
+       DMARKER;
+
        buffer = DMNEW(char, buffer_len);
 
        /* generate library name */
@@ -297,7 +310,7 @@ JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_mapLibraryName(JNIE
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return (java_lang_String *) o;
 }
index 0b574d9d71248b389c4b183c18518e8490512a88..40c978c8a433e2f96c18eac4ff13d3a79bd90db6 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/gnu/java_lang_VMSystem.c - java/lang/VMSystem
 
-   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"
 
+#include <stdint.h>
 #include <string.h>
 
-#include "vm/types.h"
-
 #include "mm/gc-common.h"
 
 #include "native/jni.h"
@@ -49,8 +46,8 @@
 /* native methods implemented by this file ************************************/
 
 static JNINativeMethod methods[] = {
-       { "arraycopy",        "(Ljava/lang/Object;ILjava/lang/Object;II)V", (void *) (ptrint) &Java_java_lang_VMSystem_arraycopy },
-       { "identityHashCode", "(Ljava/lang/Object;)I",                      (void *) (ptrint) &Java_java_lang_VMSystem_identityHashCode },
+       { "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 },
 };
 
 
@@ -75,7 +72,7 @@ void _Jv_java_lang_VMSystem_init(void)
  * 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, s4 srcStart, java_lang_Object *dest, s4 destStart, s4 len)
+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);
@@ -87,9 +84,9 @@ JNIEXPORT void JNICALL Java_java_lang_VMSystem_arraycopy(JNIEnv *env, jclass cla
  * Method:    identityHashCode
  * Signature: (Ljava/lang/Object;)I
  */
-JNIEXPORT s4 JNICALL Java_java_lang_VMSystem_identityHashCode(JNIEnv *env, jclass clazz, java_lang_Object *o)
+JNIEXPORT int32_t JNICALL Java_java_lang_VMSystem_identityHashCode(JNIEnv *env, jclass clazz, java_lang_Object *o)
 {
-       s4 hashcode;
+       int32_t hashcode;
 
        LLNI_CRITICAL_START;
 
index 49aa253ae6bb8e51fe6400887ae29cfaea2aef68..178bd41f57efbd567e079019c7913546e9fdbbd0 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/gnu/java_lang_VMThread.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/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 "native/include/java_lang_VMThread.h"
-
-#include "native/vm/java_lang_Thread.h"
+#include "threads/lock-common.h"
+#include "threads/thread.h"
 
-#include "threads/threads-common.h"
+#include "vm/exceptions.h"
+#include "vm/stringlocal.h"
 
 #include "vmcore/utf8.h"
 
@@ -94,7 +93,9 @@ JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_countStackFrames(JNIEnv *env,
 
        LLNI_field_get_ref(this, thread, thread);
 
-       return _Jv_java_lang_Thread_countStackFrames(thread);
+    log_println("Java_java_lang_VMThread_countStackFrames: IMPLEMENT ME!");
+
+    return 0;
 }
 
 
@@ -109,7 +110,9 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_start(JNIEnv *env, java_lang_VMTh
 
        LLNI_field_get_ref(this, thread, thread);
 
-       _Jv_java_lang_Thread_start(thread, stacksize);
+#if defined(ENABLE_THREADS)
+       threads_thread_start((java_handle_t *) thread);
+#endif
 }
 
 
@@ -121,14 +124,11 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_start(JNIEnv *env, java_lang_VMTh
 JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(JNIEnv *env, java_lang_VMThread *this)
 {
 #if defined(ENABLE_THREADS)
-       java_lang_Thread *object;
-       threadobject     *t;
-
-       /* XXX TWISTI: I think this and object->vmThread are equal. */
-
-       LLNI_field_get_ref(this, thread, object);
+       java_handle_t *h;
+       threadobject  *t;
 
-       t = (threadobject *) LLNI_field_direct(object, vmThread)->vmdata;
+       h = (java_handle_t *) this;
+       t = thread_get_thread(h);
 
        threads_thread_interrupt(t);
 #endif
@@ -142,11 +142,17 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(JNIEnv *env, java_lang_
  */
 JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, java_lang_VMThread *this)
 {
-       java_lang_Thread *thread;
+#if defined(ENABLE_THREADS)
+       java_handle_t *h;
+       threadobject  *t;
 
-       LLNI_field_get_ref(this, thread, thread);
+       h = (java_handle_t *) this;
+       t = thread_get_thread(h);
 
-       return _Jv_java_lang_Thread_isInterrupted(thread);
+       return thread_is_interrupted(t);
+#else
+       return 0;
+#endif
 }
 
 
@@ -157,11 +163,9 @@ JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, jav
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_suspend(JNIEnv *env, java_lang_VMThread *this)
 {
-       java_lang_Thread *thread;
-
-       LLNI_field_get_ref(this, thread, thread);
-
-       _Jv_java_lang_Thread_suspend(thread);
+#if defined(ENABLE_THREADS)
+       /* TODO Should we implement this or is it obsolete? */
+#endif
 }
 
 
@@ -172,11 +176,9 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_suspend(JNIEnv *env, java_lang_VM
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_resume(JNIEnv *env, java_lang_VMThread *this)
 {
-       java_lang_Thread *thread;
-
-       LLNI_field_get_ref(this, thread, thread);
-
-       _Jv_java_lang_Thread_resume(thread);
+#if defined(ENABLE_THREADS)
+       /* TODO Should we implement this or is it obsolete? */
+#endif
 }
 
 
@@ -187,11 +189,15 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_resume(JNIEnv *env, java_lang_VMT
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, java_lang_VMThread *this, int32_t priority)
 {
-       java_lang_Thread *thread;
+#if defined(ENABLE_THREADS)
+       java_handle_t *h;
+       threadobject  *t;
 
-       LLNI_field_get_ref(this, thread, thread);
+       h = (java_handle_t *) this;
+       t = thread_get_thread(h);
 
-       _Jv_java_lang_Thread_setPriority(thread, priority);
+       threads_set_thread_priority(t->tid, priority);
+#endif
 }
 
 
@@ -202,11 +208,9 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, ja
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeStop(JNIEnv *env, java_lang_VMThread *this, java_lang_Throwable *t)
 {
-       java_lang_Thread *thread;
-
-       LLNI_field_get_ref(this, thread, thread);
-
-       _Jv_java_lang_Thread_stop(thread, t);
+#if defined(ENABLE_THREADS)
+       /* TODO Should we implement this or is it obsolete? */
+#endif
 }
 
 
@@ -217,7 +221,11 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeStop(JNIEnv *env, java_lang
  */
 JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv *env, jclass clazz)
 {
-       return _Jv_java_lang_Thread_currentThread();
+       java_lang_Thread *to;
+
+       to = (java_lang_Thread *) thread_get_current_object();
+
+       return to;
 }
 
 
@@ -228,7 +236,9 @@ JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv
  */
 JNIEXPORT void JNICALL Java_java_lang_VMThread_yield(JNIEnv *env, jclass clazz)
 {
-       _Jv_java_lang_Thread_yield();
+#if defined(ENABLE_THREADS)
+       threads_yield();
+#endif
 }
 
 
@@ -239,7 +249,21 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_yield(JNIEnv *env, jclass clazz)
  */
 JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_interrupted(JNIEnv *env, jclass clazz)
 {
-       return _Jv_java_lang_Thread_interrupted();
+#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
 }
 
 
@@ -250,7 +274,20 @@ JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_interrupted(JNIEnv *env, jclas
  */
 JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_holdsLock(JNIEnv *env, jclass clazz, java_lang_Object* o)
 {
-       return _Jv_java_lang_Thread_holdsLock(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
 }
 
 
@@ -261,11 +298,51 @@ JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_holdsLock(JNIEnv *env, jclass
  */
 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMThread_getState(JNIEnv *env, java_lang_VMThread *this)
 {
-       java_lang_Thread *thread;
-
-       LLNI_field_get_ref(this, thread, thread);
-
-       return _Jv_java_lang_Thread_getState(thread);
+#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
 }
 
 
index 50fa002cd6a35375fcfae49b6c4552c251f771ca..29d6f654b8a886d1006dc4bbc3e5bc5b6c586a57 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/gnu/java_lang_VMThrowable.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/llni.h"
 #include "native/native.h"
 
-#include "native/include/gnu_classpath_Pointer.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 "native/vm/java_lang_Class.h"
-
 #include "vm/array.h"
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
@@ -88,23 +85,26 @@ void _Jv_java_lang_VMThrowable_init(void)
  */
 JNIEXPORT java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
 {
-       java_lang_VMThrowable   *o;
+       java_lang_VMThrowable   *vmto;
        java_handle_bytearray_t *ba;
+       java_lang_Object        *o;
 
-       o = (java_lang_VMThrowable *)
+       vmto = (java_lang_VMThrowable *)
                native_new_and_init(class_java_lang_VMThrowable);
 
-       if (o == NULL)
+       if (vmto == NULL)
                return NULL;
 
-       ba = stacktrace_get();
+       ba = stacktrace_get_current();
 
        if (ba == NULL)
                return NULL;
 
-       LLNI_field_set_ref(o, vmData, (gnu_classpath_Pointer *) ba);
+       o = (java_lang_Object *) ba;
+
+       LLNI_field_set_ref(vmto, vmdata, o);
 
-       return o;
+       return vmto;
 }
 
 
@@ -115,21 +115,24 @@ JNIEXPORT java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackT
  */
 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 *o;
+       java_lang_StackTraceElement *steo;
        codeinfo                    *code;
        methodinfo                  *m;
        java_lang_String            *filename;
        s4                           linenumber;
-       java_lang_String            *declaringclass;
+       java_handle_t               *declaringclass;
        int                          i;
 
-       /* get the stacktrace buffer from the VMThrowable object */
+       /* Get the stacktrace from the VMThrowable object. */
+
+       LLNI_field_get_ref(this, vmdata, o);
 
-       LLNI_field_get_ref(this, vmData, ba);
+       ba = (java_handle_bytearray_t *) o;
 
        st = (stacktrace_t *) LLNI_array_data(ba);
 
@@ -147,10 +150,10 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMThrowable_getStack
        for (i = 0; i < st->length; i++, ste++) {
                /* allocate a new stacktrace element */
 
-               o = (java_lang_StackTraceElement *)
+               steo = (java_lang_StackTraceElement *)
                        builtin_new(class_java_lang_StackTraceElement);
 
-               if (o == NULL)
+               if (steo == NULL)
                        return NULL;
 
                /* Get the codeinfo and methodinfo. */
@@ -161,8 +164,8 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMThrowable_getStack
                /* Get filename. */
 
                if (!(m->flags & ACC_NATIVE)) {
-                       if (m->class->sourcefile)
-                               filename = (java_lang_String *) javastring_new(m->class->sourcefile);
+                       if (m->clazz->sourcefile)
+                               filename = (java_lang_String *) javastring_new(m->clazz->sourcefile);
                        else
                                filename = NULL;
                }
@@ -185,18 +188,17 @@ JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_VMThrowable_getStack
 
                /* get declaring class name */
 
-               declaringclass =
-                       _Jv_java_lang_Class_getName(LLNI_classinfo_wrap(m->class));
+               declaringclass = class_get_classname(m->clazz);
 
                /* Fill the java.lang.StackTraceElement object. */
 
-               LLNI_field_set_ref(o, fileName      , filename);
-               LLNI_field_set_val(o, lineNumber    , linenumber);
-               LLNI_field_set_ref(o, declaringClass, declaringclass);
-               LLNI_field_set_ref(o, methodName    , (java_lang_String *) javastring_new(m->name));
-               LLNI_field_set_val(o, isNative      , (m->flags & ACC_NATIVE) ? 1 : 0);
+               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 *) o);
+               array_objectarray_element_set(oa, i, (java_handle_t *) steo);
        }
 
        return oa;
diff --git a/src/native/vm/gnu/java_lang_reflect_Constructor.c b/src/native/vm/gnu/java_lang_reflect_Constructor.c
deleted file mode 100644 (file)
index 606ab0a..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/* src/native/vm/gnu/java_lang_reflect_Constructor.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 <assert.h>
-#include <stdlib.h>
-
-#if defined(ENABLE_ANNOTATIONS)
-#include "vm/vm.h"
-#include "vm/exceptions.h"
-#endif
-
-#include "vm/types.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_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_reflect_Constructor.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 "native/vm/java_lang_reflect_Constructor.h"
-
-#include "vmcore/utf8.h"
-
-
-/* native methods implemented by this file ************************************/
-
-static JNINativeMethod methods[] = {
-       { "getModifiersInternal",    "()I",                                                       (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getModifiers        },
-       { "getParameterTypes",       "()[Ljava/lang/Class;",                                      (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getParameterTypes   },
-       { "getExceptionTypes",       "()[Ljava/lang/Class;",                                      (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getExceptionTypes   },
-       { "constructNative",         "([Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;", (void *) (ptrint) &Java_java_lang_reflect_Constructor_constructNative    },
-       { "getSignature",            "()Ljava/lang/String;",                                      (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getSignature        },
-#if defined(ENABLE_ANNOTATIONS)
-       { "declaredAnnotations",     "()Ljava/util/Map;",                                         (void *) (ptrint) &Java_java_lang_reflect_Constructor_declaredAnnotations     },
-       { "getParameterAnnotations", "()[[Ljava/lang/annotation/Annotation;",                     (void *) (ptrint) &Java_java_lang_reflect_Constructor_getParameterAnnotations },
-#endif
-};
-
-
-/* _Jv_java_lang_reflect_Constructor_init **************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_reflect_Constructor_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/reflect/Constructor");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/reflect/Constructor
- * Method:    constructNative
- * Signature: ([Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Constructor_constructNative(JNIEnv *env, java_lang_reflect_Constructor *this, java_handle_objectarray_t *args, java_lang_Class *declaringClass, s4 slot)
-{
-       /* just to be sure */
-
-       assert(LLNI_field_direct(this, clazz) == LLNI_DIRECT(declaringClass));
-       assert(LLNI_field_direct(this, slot)  == slot);
-
-       return _Jv_java_lang_reflect_Constructor_newInstance(env, this, args);
-}
-
-
-#if defined(ENABLE_ANNOTATIONS)
-/*
- * Class:     java/lang/reflect/Constructor
- * 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_Constructor_declaredAnnotations(JNIEnv *env, java_lang_reflect_Constructor *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/Constructor
- * 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_Constructor_getParameterAnnotations(JNIEnv *env, java_lang_reflect_Constructor *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/gnu/java_lang_reflect_Field.c b/src/native/vm/gnu/java_lang_reflect_Field.c
deleted file mode 100644 (file)
index 0dcc8c7..0000000
+++ /dev/null
@@ -1,1341 +0,0 @@
-/* src/native/vm/gnu/java_lang_reflect_Field.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 <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"
-
-#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_Field_getModifiersInternal },
-       { "getType",              "()Ljava/lang/Class;",                     (void *) (intptr_t) &Java_java_lang_reflect_Field_getType              },
-       { "get",                  "(Ljava/lang/Object;)Ljava/lang/Object;",  (void *) (intptr_t) &Java_java_lang_reflect_Field_get                  },
-       { "getBoolean",           "(Ljava/lang/Object;)Z",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getBoolean           },
-       { "getByte",              "(Ljava/lang/Object;)B",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getByte              },
-       { "getChar",              "(Ljava/lang/Object;)C",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getChar              },
-       { "getShort",             "(Ljava/lang/Object;)S",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getShort             },
-       { "getInt",               "(Ljava/lang/Object;)I",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getInt               },
-       { "getLong",              "(Ljava/lang/Object;)J",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getLong              },
-       { "getFloat",             "(Ljava/lang/Object;)F",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getFloat             },
-       { "getDouble",            "(Ljava/lang/Object;)D",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getDouble            },
-       { "set",                  "(Ljava/lang/Object;Ljava/lang/Object;)V", (void *) (intptr_t) &Java_java_lang_reflect_Field_set                  },
-       { "setBoolean",           "(Ljava/lang/Object;Z)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setBoolean           },
-       { "setByte",              "(Ljava/lang/Object;B)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setByte              },
-       { "setChar",              "(Ljava/lang/Object;C)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setChar              },
-       { "setShort",             "(Ljava/lang/Object;S)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setShort             },
-       { "setInt",               "(Ljava/lang/Object;I)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setInt               },
-       { "setLong",              "(Ljava/lang/Object;J)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setLong              },
-       { "setFloat",             "(Ljava/lang/Object;F)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setFloat             },
-       { "setDouble",            "(Ljava/lang/Object;D)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setDouble            },
-       { "getSignature",         "()Ljava/lang/String;",                    (void *) (intptr_t) &Java_java_lang_reflect_Field_getSignature         },
-#if defined(ENABLE_ANNOTATIONS)
-       { "declaredAnnotations",  "()Ljava/util/Map;",                       (void *) (intptr_t) &Java_java_lang_reflect_Field_declaredAnnotations  },
-#endif
-};
-
-
-/* _Jv_java_lang_reflect_Field_init ********************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_reflect_Field_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/reflect/Field");
-
-       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_Field *this,
-                                                               fieldinfo *f, classinfo *c, java_handle_t *o)
-{
-       int32_t flag;
-
-       /* check if we should bypass security checks (AccessibleObject) */
-
-       LLNI_field_get_val(this, flag, flag);
-       if (flag == false) {
-               /* this function is always called like this:
-                          java.lang.reflect.Field.xxx (Native Method)
-                  [0] <caller>
-               */
-               if (!access_check_field(f, 0))
-                       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/Field
- * Method:    getModifiersInternal
- * Signature: ()I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getModifiersInternal(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getType
- * Signature: ()Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_Field_getType(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    get
- * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Field_get(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getBoolean
- * Signature: (Ljava/lang/Object;)Z
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getBoolean(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getByte
- * Signature: (Ljava/lang/Object;)B
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getByte(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getChar
- * Signature: (Ljava/lang/Object;)C
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getChar(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getShort
- * Signature: (Ljava/lang/Object;)S
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getShort(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getInt
- * Signature: (Ljava/lang/Object;)I
- */
-JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getInt(JNIEnv *env , java_lang_reflect_Field *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/Field
- * Method:    getLong
- * Signature: (Ljava/lang/Object;)J
- */
-JNIEXPORT int64_t JNICALL Java_java_lang_reflect_Field_getLong(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getFloat
- * Signature: (Ljava/lang/Object;)F
- */
-JNIEXPORT float JNICALL Java_java_lang_reflect_Field_getFloat(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getDouble
- * Signature: (Ljava/lang/Object;)D
- */
-JNIEXPORT double JNICALL Java_java_lang_reflect_Field_getDouble(JNIEnv *env , java_lang_reflect_Field *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/Field
- * Method:    set
- * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_set(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    setBoolean
- * Signature: (Ljava/lang/Object;Z)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setBoolean(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    setByte
- * Signature: (Ljava/lang/Object;B)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setByte(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    setChar
- * Signature: (Ljava/lang/Object;C)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setChar(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    setShort
- * Signature: (Ljava/lang/Object;S)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setShort(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    setInt
- * Signature: (Ljava/lang/Object;I)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setInt(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    setLong
- * Signature: (Ljava/lang/Object;J)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setLong(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    setFloat
- * Signature: (Ljava/lang/Object;F)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setFloat(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    setDouble
- * Signature: (Ljava/lang/Object;D)V
- */
-JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setDouble(JNIEnv *env, java_lang_reflect_Field *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/Field
- * Method:    getSignature
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_Field_getSignature(JNIEnv *env, java_lang_reflect_Field* 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/Field
- * Method:    declaredAnnotations
- * Signature: ()Ljava/util/Map;
- */
-JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_Field_declaredAnnotations(JNIEnv *env, java_lang_reflect_Field *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/gnu/java_lang_reflect_Method.c b/src/native/vm/gnu/java_lang_reflect_Method.c
deleted file mode 100644 (file)
index 75f03b1..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/* src/native/vm/gnu/java_lang_reflect_Method.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 <assert.h>
-
-#if defined(ENABLE_ANNOTATIONS)
-#include "vm/vm.h"
-#endif
-
-#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"
-
-#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 "native/include/java_lang_reflect_Method.h"
-
-#include "native/vm/java_lang_reflect_Method.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 *) (ptrint) &Java_java_lang_reflect_Method_getModifiersInternal    },
-       { "getReturnType",           "()Ljava/lang/Class;",                                                         (void *) (ptrint) &Java_java_lang_reflect_Method_getReturnType           },
-       { "getParameterTypes",       "()[Ljava/lang/Class;",                                                        (void *) (ptrint) &Java_java_lang_reflect_Method_getParameterTypes       },
-       { "getExceptionTypes",       "()[Ljava/lang/Class;",                                                        (void *) (ptrint) &Java_java_lang_reflect_Method_getExceptionTypes       },
-       { "invokeNative",            "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;", (void *) (ptrint) &Java_java_lang_reflect_Method_invokeNative            },
-       { "getSignature",            "()Ljava/lang/String;",                                                        (void *) (ptrint) &Java_java_lang_reflect_Method_getSignature            },
-#if defined(ENABLE_ANNOTATIONS)
-       { "getDefaultValue",         "()Ljava/lang/Object;",                                                        (void *) (ptrint) &Java_java_lang_reflect_Method_getDefaultValue         },
-       { "declaredAnnotations",     "()Ljava/util/Map;",                                                           (void *) (ptrint) &Java_java_lang_reflect_Method_declaredAnnotations     },
-       { "getParameterAnnotations", "()[[Ljava/lang/annotation/Annotation;",                                       (void *) (ptrint) &Java_java_lang_reflect_Method_getParameterAnnotations },
-#endif
-};
-
-
-/* _Jv_java_lang_reflect_Method_init *******************************************
-
-   Register native functions.
-
-*******************************************************************************/
-
-void _Jv_java_lang_reflect_Method_init(void)
-{
-       utf *u;
-
-       u = utf_new_char("java/lang/reflect/Method");
-
-       native_method_register(u, methods, NATIVE_METHODS_COUNT);
-}
-
-
-/*
- * Class:     java/lang/reflect/Method
- * Method:    getModifiersInternal
- * Signature: ()I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_reflect_Method_getModifiersInternal(JNIEnv *env, java_lang_reflect_Method *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/Method
- * Method:    getReturnType
- * Signature: ()Ljava/lang/Class;
- */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_Method_getReturnType(JNIEnv *env, java_lang_reflect_Method *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/Method
- * Method:    getParameterTypes
- * Signature: ()[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_reflect_Method_getParameterTypes(JNIEnv *env, java_lang_reflect_Method *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/Method
- * Method:    getExceptionTypes
- * Signature: ()[Ljava/lang/Class;
- */
-JNIEXPORT java_handle_objectarray_t* JNICALL Java_java_lang_reflect_Method_getExceptionTypes(JNIEnv *env, java_lang_reflect_Method *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/Method
- * Method:    invokeNative
- * Signature: (Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;
- */
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Method_invokeNative(JNIEnv *env, java_lang_reflect_Method *this, java_lang_Object *o, java_handle_objectarray_t *args, java_lang_Class *clazz, s4 slot)
-{
-       /* just to be sure */
-
-       assert(LLNI_field_direct(this, clazz) == LLNI_DIRECT(clazz));
-       assert(LLNI_field_direct(this, slot)  == slot);
-
-       return _Jv_java_lang_reflect_Method_invoke(this, o, args);
-}
-
-
-/*
- * Class:     java/lang/reflect/Method
- * Method:    getSignature
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_Method_getSignature(JNIEnv *env, java_lang_reflect_Method* 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/Method
- * 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_Method_getDefaultValue(JNIEnv *env, struct java_lang_reflect_Method* 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()) */
-
-       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, annotationDefault, annotationDefault);
-
-       return (java_lang_Object*)vm_call_method(
-               m_parseAnnotationDefault, NULL,
-               this, annotationDefault, constantPool);
-}
-
-
-/*
- * Class:     java/lang/reflect/Method
- * 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_Method_declaredAnnotations(JNIEnv *env, java_lang_reflect_Method *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/Method
- * 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_Method_getParameterAnnotations(JNIEnv *env, java_lang_reflect_Method *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/gnu/java_lang_reflect_VMConstructor.c b/src/native/vm/gnu/java_lang_reflect_VMConstructor.c
new file mode 100644 (file)
index 0000000..db90cf9
--- /dev/null
@@ -0,0 +1,275 @@
+/* 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/gnu/java_lang_reflect_VMField.c b/src/native/vm/gnu/java_lang_reflect_VMField.c
new file mode 100644 (file)
index 0000000..b3da621
--- /dev/null
@@ -0,0 +1,1345 @@
+/* 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/gnu/java_lang_reflect_VMMethod.c b/src/native/vm/gnu/java_lang_reflect_VMMethod.c
new file mode 100644 (file)
index 0000000..8b1853f
--- /dev/null
@@ -0,0 +1,372 @@
+/* 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/java_lang_Class.c b/src/native/vm/java_lang_Class.c
deleted file mode 100644 (file)
index a183722..0000000
+++ /dev/null
@@ -1,606 +0,0 @@
-/* src/native/vm/java_lang_Class.c - java/lang/Class
-
-   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 <stdint.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.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(ENABLE_JAVASE)
-# if defined(WITH_CLASSPATH_SUN)
-#  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 "native/vm/java_lang_Class.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/vm/reflect.h"
-#endif
-
-#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 "vmcore/class.h"
-#include "vmcore/loader.h"
-
-#if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
-#include "native/include/sun_reflect_ConstantPool.h"
-
-#include "vm/vm.h"
-
-#include "vmcore/annotation.h"
-#endif
-
-/*
- * Class:     java/lang/Class
- * Method:    getName
- * Signature: ()Ljava/lang/String;
- */
-java_lang_String *_Jv_java_lang_Class_getName(java_lang_Class *klass)
-{
-       classinfo               *c;
-       java_lang_String        *s;
-       java_handle_chararray_t *ca;
-       u4                       i;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       /* create a java string */
-
-       s = (java_lang_String *) javastring_new(c->name);
-
-       if (s == NULL)
-               return NULL;
-
-       /* return string where '/' is replaced by '.' */
-
-       LLNI_field_get_ref(s, value, ca);
-
-       for (i = 0; i < LLNI_array_size(ca); i++) {
-               if (LLNI_array_direct(ca, i) == '/')
-                       LLNI_array_direct(ca, i) = '.';
-       }
-
-       return s;
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    forName
- * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
- */
-#if defined(ENABLE_JAVASE)
-java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader)
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
-#endif
-{
-#if defined(ENABLE_JAVASE)
-       classloader *cl;
-#endif
-       utf         *ufile;
-       utf         *uname;
-       classinfo   *c;
-       u2          *pos;
-       s4           i;
-
-#if defined(ENABLE_JAVASE)
-       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
-#endif
-
-       /* 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, ... */
-
-#if defined(ENABLE_JAVASE)
-       c = load_class_from_classloader(ufile, cl);
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-       c = load_class_bootstrap(ufile);
-#endif
-
-       if (c == NULL)
-           return NULL;
-
-       /* link, ... */
-
-       if (!link_class(c))
-               return NULL;
-       
-       /* ...and initialize it, if required */
-
-#if defined(ENABLE_JAVASE)
-       if (initialize)
-#endif
-               if (!initialize_class(c))
-                       return NULL;
-
-       return LLNI_classinfo_wrap(c);
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    isInstance
- * Signature: (Ljava/lang/Object;)Z
- */
-s4 _Jv_java_lang_Class_isInstance(java_lang_Class *klass, java_lang_Object *o)
-{
-       classinfo     *c;
-       java_handle_t *ob;
-
-       c = LLNI_classinfo_unwrap(klass);
-       ob = (java_handle_t *) o;
-
-       if (!(c->state & CLASS_LINKED))
-               if (!link_class(c))
-                       return 0;
-
-       return builtin_instanceof(ob, c);
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    isAssignableFrom
- * Signature: (Ljava/lang/Class;)Z
- */
-s4 _Jv_java_lang_Class_isAssignableFrom(java_lang_Class *klass, java_lang_Class *c)
-{
-       classinfo *kc;
-       classinfo *cc;
-
-       kc = LLNI_classinfo_unwrap(klass);
-       cc = LLNI_classinfo_unwrap(c);
-
-       if (cc == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       if (!(kc->state & CLASS_LINKED))
-               if (!link_class(kc))
-                       return 0;
-
-       if (!(cc->state & CLASS_LINKED))
-               if (!link_class(cc))
-                       return 0;
-
-       return class_isanysubclass(cc, kc);
-}
-
-
-#if defined(ENABLE_JAVASE)
-
-/*
- * Class:     java/lang/Class
- * Method:    getDeclaredFields
- * Signature: (Z)[Ljava/lang/reflect/Field;
- */
-java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, s4 publicOnly)
-{
-       classinfo                 *c;
-       java_handle_objectarray_t *oa;          /* result: array of field-objects */
-       fieldinfo                 *f;
-       java_lang_reflect_Field   *rf;
-       s4 public_fields;                    /* number of elements in field-array */
-       s4 pos;
-       s4 i;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       /* determine number of fields */
-
-       for (i = 0, public_fields = 0; i < c->fieldscount; i++)
-               if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
-                       public_fields++;
-
-       /* create array of fields */
-
-       oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
-
-       if (oa == NULL)
-               return NULL;
-
-       /* get the fields and store in the array */
-
-       for (i = 0, pos = 0; i < c->fieldscount; i++) {
-               f = &(c->fields[i]);
-
-               if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
-                       /* create Field object */
-
-                       rf = reflect_field_new(f);
-
-                       /* store object into array */
-
-                       array_objectarray_element_set(oa, pos, (java_handle_t *) rf);
-                       pos++;
-               }
-       }
-
-       return oa;
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    getDeclaredMethods
- * Signature: (Z)[Ljava/lang/reflect/Method;
- */
-java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, s4 publicOnly)
-{
-       classinfo                 *c;
-       java_lang_reflect_Method  *rm;
-       java_handle_objectarray_t *oa;         /* result: array of Method-objects */
-       methodinfo                *m;     /* the current method to be represented */
-       s4 public_methods;               /* number of public methods of the class */
-       s4 pos;
-       s4 i;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       public_methods = 0;
-
-       /* 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 */
-
-       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))
-                       public_methods++;
-       }
-
-       oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
-
-       if (oa == NULL)
-               return NULL;
-
-       for (i = 0, pos = 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 */
-
-                       rm = reflect_method_new(m);
-
-                       /* store object into array */
-
-                       array_objectarray_element_set(oa, pos, (java_handle_t *) rm);
-                       pos++;
-               }
-       }
-
-       return oa;
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    getDeclaredConstructors
- * Signature: (Z)[Ljava/lang/reflect/Constructor;
- */
-java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *klass, s4 publicOnly)
-{
-       classinfo                     *c;
-       methodinfo                    *m; /* the current method to be represented */
-       java_handle_objectarray_t     *oa;     /* result: array of Method-objects */
-       java_lang_reflect_Constructor *rc;
-       s4 public_methods;               /* number of public methods of the class */
-       s4 pos;
-       s4 i;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       /* determine number of constructors */
-
-       for (i = 0, public_methods = 0; i < c->methodscount; i++) {
-               m = &c->methods[i];
-
-               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
-                       (m->name == utf_init))
-                       public_methods++;
-       }
-
-       oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
-
-       if (oa == NULL)
-               return NULL;
-
-       for (i = 0, pos = 0; i < c->methodscount; i++) {
-               m = &c->methods[i];
-
-               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
-                       (m->name == utf_init)) {
-                       /* create Constructor object */
-
-                       rc = reflect_constructor_new(m);
-
-                       /* store object into array */
-
-                       array_objectarray_element_set(oa, pos, (java_handle_t *) rc);
-                       pos++;
-               }
-       }
-
-       return oa;
-}
-
-
-#if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
-/*
- * Class:     java/lang/Class
- * Method:    getDeclaredAnnotations
- * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
- */
-java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredAnnotations(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
-
-
-/* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
-
-   Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
-   _Jv_java_lang_Class_getEnclosingMethod.
-
-*******************************************************************************/
-
-static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(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;
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    getEnclosingConstructor
- * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
- */
-java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
-{
-       classinfo                     *c;
-       methodinfo                    *m;
-       java_lang_reflect_Constructor *rc;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       /* get enclosing method */
-
-       m = _Jv_java_lang_Class_getEnclosingMethod_intern(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;
-}
-
-
-/*
- * Class:     java/lang/Class
- * Method:    getEnclosingMethod
- * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
- */
-java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
-{
-       classinfo                *c;
-       methodinfo               *m;
-       java_lang_reflect_Method *rm;
-
-       c = LLNI_classinfo_unwrap(klass);
-
-       /* get enclosing method */
-
-       m = _Jv_java_lang_Class_getEnclosingMethod_intern(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 /* 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:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/native/vm/java_lang_Class.h b/src/native/vm/java_lang_Class.h
deleted file mode 100644 (file)
index e601b6a..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* src/native/vm/java_lang_Class.h - java/lang/Class functions
-
-   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 _JV_JAVA_LANG_CLASS_H
-#define _JV_JAVA_LANG_CLASS_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "native/jni.h"
-
-#include "native/include/java_lang_String.h" /* required by java_lang_Class.h */
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_Object.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_ClassLoader.h"
-# include "native/include/java_lang_Throwable.h"
-# include "native/include/java_lang_reflect_Constructor.h"
-# include "native/include/java_lang_reflect_Method.h"
-#endif
-
-
-/* function prototypes ********************************************************/
-
-java_lang_String              *_Jv_java_lang_Class_getName(java_lang_Class *klass);
-
-#if defined(ENABLE_JAVASE)
-java_lang_Class               *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader);
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-java_lang_Class               *_Jv_java_lang_Class_forName(java_lang_String *name);
-#endif
-
-s4                             _Jv_java_lang_Class_isInstance(java_lang_Class *klass, java_lang_Object *o);
-s4                             _Jv_java_lang_Class_isAssignableFrom(java_lang_Class *klass, java_lang_Class *c);
-
-#if defined(ENABLE_JAVASE)
-java_handle_objectarray_t     *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, s4 publicOnly);
-java_handle_objectarray_t     *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, s4 publicOnly);
-java_handle_objectarray_t     *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *klass, s4 publicOnly);
-
-#if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
-java_handle_objectarray_t     *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass);
-#endif
-
-java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass);
-java_lang_reflect_Method      *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass);
-#endif
-
-#endif /* _JV_JAVA_LANG_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/native/vm/java_lang_ClassLoader.c b/src/native/vm/java_lang_ClassLoader.c
deleted file mode 100644 (file)
index a789eb6..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* src/native/vm/java_lang_ClassLoader.c - java/lang/ClassLoader
-
-   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 <assert.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "vm/global.h"                          /* required by native headers */
-
-#include "native/jni.h"
-#include "native/llni.h"
-
-/* keep this order of the native includes */
-
-#include "native/include/java_lang_Object.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_String.h"            /* required by j.l.C */
-
-# if defined(WITH_CLASSPATH_SUN)
-#  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_security_ProtectionDomain.h"
-#endif
-
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/class.h"
-#include "vmcore/classcache.h"
-#include "vmcore/options.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-
-/*
- * Class:     java/lang/ClassLoader
- * Method:    defineClass
- * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
- */
-java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl, java_lang_String *name, java_handle_bytearray_t *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
-{
-       utf             *utfname;
-       classinfo       *c;
-       classloader     *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, (const uint8_t *) &LLNI_array_direct(data, offset), pd);
-
-       if (c == NULL)
-               return NULL;
-
-       /* for convenience */
-
-       o = LLNI_classinfo_wrap(c);
-
-#if defined(WITH_CLASSPATH_GNU)
-       /* set ProtectionDomain */
-
-       LLNI_field_set_ref(o, pd, pd);
-#endif
-
-       return 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/java_lang_ClassLoader.h b/src/native/vm/java_lang_ClassLoader.h
deleted file mode 100644 (file)
index 79a5e25..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* src/native/vm/java_lang_ClassLoader.h - java/lang/ClassLoader 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
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public 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 _JV_JAVA_LANG_CLASSLOADER_H
-#define _JV_JAVA_LANG_CLASSLOADER_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "native/jni.h"
-
-#include "native/include/java_lang_Object.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_String.h"/* required by java_lang_Class.h */
-# include "native/include/java_lang_Class.h"
-# include "native/include/java_lang_ClassLoader.h"
-# include "native/include/java_security_ProtectionDomain.h"
-#endif
-
-#include "vm/global.h"
-
-
-/* function prototypes ********************************************************/
-
-#if defined(ENABLE_JAVASE)
-java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl, java_lang_String *name, java_handle_bytearray_t *data, s4 offset, s4 len, java_security_ProtectionDomain *pd);
-#endif
-
-#endif /* _JV_JAVA_LANG_CLASSLOADER_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/java_lang_Runtime.c b/src/native/vm/java_lang_Runtime.c
deleted file mode 100644 (file)
index d167ec3..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/* src/native/vm/java_lang_VMRuntime.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"
-
-#if defined(ENABLE_LTDL) && defined(HAVE_LTDL_H)
-# include <ltdl.h>
-#endif
-
-#include "vm/types.h"
-
-#include "mm/gc-common.h"
-
-#include "native/jni.h"
-#include "native/native.h"
-
-#include "native/include/java_lang_String.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/options.h"
-
-
-/* should we run all finalizers on exit? */
-static bool finalizeOnExit = false;
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    exitInternal
- * Signature: (I)V
- */
-void _Jv_java_lang_Runtime_exit(s4 status)
-{
-       if (finalizeOnExit)
-               gc_finalize_all();
-
-       vm_shutdown(status);
-}
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    freeMemory
- * Signature: ()J
- */
-s8 _Jv_java_lang_Runtime_freeMemory(void)
-{
-       return gc_get_free_bytes();
-}
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    totalMemory
- * Signature: ()J
- */
-s8 _Jv_java_lang_Runtime_totalMemory(void)
-{
-       return gc_get_heap_size();
-}
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    gc
- * Signature: ()V
- */
-void _Jv_java_lang_Runtime_gc(void)
-{
-       gc_call();
-}
-
-
-/*
- * Class:     java/lang/Runtime
- * Method:    loadLibrary
- * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)I
- */
-#if defined(ENABLE_JNI)
-s4 _Jv_java_lang_Runtime_loadLibrary(JNIEnv *env, java_lang_String *libname, classloader *cl)
-#else
-s4 _Jv_java_lang_Runtime_loadLibrary(java_lang_String *libname, classloader *cl)
-#endif
-{
-#if defined(ENABLE_LTDL)
-       utf               *name;
-       lt_dlhandle        handle;
-# if defined(ENABLE_JNI)
-       lt_ptr             onload;
-       s4                 version;
-# endif
-
-       if (libname == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       name = javastring_toutf((java_handle_t *) libname, false);
-
-       /* is the library already loaded? */
-
-       if (native_library_find(name, cl) != NULL)
-               return 1;
-
-       /* open the library */
-
-       handle = native_library_open(name);
-
-       if (handle == NULL)
-               return 0;
-
-# if defined(ENABLE_JNI)
-       /* resolve JNI_OnLoad function */
-
-       onload = lt_dlsym(handle, "JNI_OnLoad");
-
-       if (onload != NULL) {
-               JNIEXPORT s4 (JNICALL *JNI_OnLoad) (JavaVM *, void *);
-               JavaVM *vm;
-
-               JNI_OnLoad = (JNIEXPORT s4 (JNICALL *)(JavaVM *, void *)) (ptrint) onload;
-
-               (*env)->GetJavaVM(env, &vm);
-
-               version = JNI_OnLoad(vm, NULL);
-
-               /* if the version is not 1.2 and not 1.4 the library cannot be loaded */
-
-               if ((version != JNI_VERSION_1_2) && (version != JNI_VERSION_1_4)) {
-                       lt_dlclose(handle);
-
-                       return 0;
-               }
-       }
-# endif
-
-       /* insert the library name into the library hash */
-
-       native_library_add(name, cl, handle);
-
-       return 1;
-#else
-       vm_abort("_Jv_java_lang_Runtime_loadLibrary: not available");
-
-       /* keep compiler happy */
-
-       return 0;
-#endif
-}
-
-
-#if defined(ENABLE_JAVASE)
-
-/*
- * Class:     java/lang/Runtime
- * Method:    runFinalizersOnExit
- * Signature: (Z)V
- */
-void _Jv_java_lang_Runtime_runFinalizersOnExit(s4 value)
-{
-       /* XXX threading */
-
-       finalizeOnExit = value;
-}
-
-#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/java_lang_Runtime.h b/src/native/vm/java_lang_Runtime.h
deleted file mode 100644 (file)
index d936432..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* src/native/vm/java_lang_Runtime.h
-
-   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 _JV_JAVA_LANG_RUNTIME_H
-#define _JV_JAVA_LANG_RUNTIME_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "native/jni.h"
-#include "native/include/java_lang_String.h"
-
-
-/* function prototypes *******************************************************/
-
-void _Jv_java_lang_Runtime_exit(s4 status);
-s8   _Jv_java_lang_Runtime_freeMemory(void);
-s8   _Jv_java_lang_Runtime_totalMemory(void);
-void _Jv_java_lang_Runtime_gc(void);
-
-#if defined(ENABLE_JNI)
-s4   _Jv_java_lang_Runtime_loadLibrary(JNIEnv *env, java_lang_String *libname, classloader *cl);
-#else
-s4   _Jv_java_lang_Runtime_loadLibrary(java_lang_String *libname, classloader *cl);
-#endif
-
-#if defined(ENABLE_JAVASE)
-void _Jv_java_lang_Runtime_runFinalizersOnExit(s4 value);
-#endif
-
-#endif /* _JV_JAVA_LANG_RUNTIME_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/java_lang_Thread.c b/src/native/vm/java_lang_Thread.c
deleted file mode 100644 (file)
index b6a6c7c..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-/* src/native/vm/java_lang_Thread.c - java/lang/Thread 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
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public 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"
-#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_Thread.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_ThreadGroup.h"
-
-# if defined(WITH_CLASSPATH_GNU)
-#  include "native/include/java_lang_VMThread.h"
-# endif
-#endif
-
-#include "threads/lock-common.h"
-#include "threads/threads-common.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/options.h"
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    countStackFrames
- * Signature: ()I
- */
-s4 _Jv_java_lang_Thread_countStackFrames(java_lang_Thread *this)
-{
-    log_text("java_lang_Thread_countStackFrames called");
-
-    return 0;
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    sleep
- * Signature: (J)V
- */
-void _Jv_java_lang_Thread_sleep(s8 millis)
-{
-#if defined(ENABLE_THREADS)
-       threads_sleep(millis, 0);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    start
- * Signature: (J)V
- */
-void _Jv_java_lang_Thread_start(java_lang_Thread *this, s8 stacksize)
-{
-#if defined(ENABLE_THREADS)
-       threads_thread_start((java_handle_t *) this);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    isInterrupted
- * Signature: ()Z
- */
-s4 _Jv_java_lang_Thread_isInterrupted(java_lang_Thread *this)
-{
-#if defined(ENABLE_THREADS)
-       threadobject *t;
-
-# if defined(WITH_CLASSPATH_GNU)
-       t = (threadobject *) LLNI_field_direct(this, vmThread)->vmdata;
-# elif defined(WITH_CLASSPATH_SUN)
-       /* XXX this is just a quick hack */
-
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
-               if (t->object == this)
-                       break;
-       }
-# elif defined(WITH_CLASSPATH_CLDC1_1)
-       t = (threadobject *) this->vm_thread;
-# else
-#  error unknown classpath configuration
-# endif
-
-       return threads_thread_has_been_interrupted(t);
-#else
-       return 0;
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    suspend
- * Signature: ()V
- */
-void _Jv_java_lang_Thread_suspend(java_lang_Thread *this)
-{
-#if defined(ENABLE_THREADS)
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    resume
- * Signature: ()V
- */
-void _Jv_java_lang_Thread_resume(java_lang_Thread *this)
-{
-#if defined(ENABLE_THREADS)
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    setPriority
- * Signature: (I)V
- */
-void _Jv_java_lang_Thread_setPriority(java_lang_Thread *this, s4 priority)
-{
-#if defined(ENABLE_THREADS)
-       threadobject *t;
-
-# if defined(WITH_CLASSPATH_GNU)
-       t = (threadobject *) LLNI_field_direct(this, vmThread)->vmdata;
-# elif defined(WITH_CLASSPATH_SUN)
-       /* XXX this is just a quick hack */
-
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
-               if (t->object == this)
-                       break;
-       }
-
-       /* The threadobject is null when a thread is created in Java. The
-          priority is set later during startup. */
-
-       if (t == NULL)
-               return;
-# elif defined(WITH_CLASSPATH_CLDC1_1)
-       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;
-# else
-#  error unknown classpath configuration
-# endif
-
-       threads_set_thread_priority(t->tid, priority);
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    stop
- * Signature: (Ljava/lang/Object;)V
- */
-void _Jv_java_lang_Thread_stop(java_lang_Thread *this, java_lang_Throwable *t)
-{
-#if defined(ENABLE_THREADS)
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    currentThread
- * Signature: ()Ljava/lang/Thread;
- */
-java_lang_Thread *_Jv_java_lang_Thread_currentThread(void)
-{
-#if defined(ENABLE_THREADS)
-       threadobject          *thread;
-#endif
-       java_lang_Thread      *t;
-#if defined(ENABLE_JAVASE)
-       java_lang_ThreadGroup *group;
-#endif
-
-#if defined(ENABLE_THREADS)
-       thread = THREADOBJECT;
-
-       t = (java_lang_Thread *) threads_thread_get_object(thread);
-
-       if (t == NULL)
-               log_text("t ptr is NULL\n");
-
-# if defined(ENABLE_JAVASE)
-       LLNI_field_get_ref(t, group, group);
-
-       if (group == NULL) {
-               /* ThreadGroup of currentThread is not initialized */
-
-               group = (java_lang_ThreadGroup *)
-                       native_new_and_init(class_java_lang_ThreadGroup);
-
-               if (group == NULL)
-                       log_text("unable to create ThreadGroup");
-
-               LLNI_field_set_ref(t, group, group);
-       }
-# endif
-#else
-       /* we just return a fake java.lang.Thread object, otherwise we get
-          NullPointerException's in GNU classpath */
-
-       t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
-#endif
-
-       return t;
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    yield
- * Signature: ()V
- */
-void _Jv_java_lang_Thread_yield(void)
-{
-#if defined(ENABLE_THREADS)
-       threads_yield();
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    interrupted
- * Signature: ()Z
- */
-s4 _Jv_java_lang_Thread_interrupted(void)
-{
-#if defined(ENABLE_THREADS)
-       return threads_check_if_interrupted_and_reset();
-#else
-       return 0;
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    holdsLock
- * Signature: (Ljava/lang/Object;)Z
- */
-s4 _Jv_java_lang_Thread_holdsLock(java_lang_Object* obj)
-{
-#if defined(ENABLE_THREADS)
-       java_handle_t *o;
-
-       o = (java_handle_t *) obj;
-
-       if (o == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       return lock_is_held_by_current_thread(o);
-#else
-       return 0;
-#endif
-}
-
-
-/*
- * Class:     java/lang/Thread
- * Method:    getState
- * Signature: ()Ljava/lang/String;
- */
-java_lang_String *_Jv_java_lang_Thread_getState(java_lang_Thread *this)
-{
-#if defined(ENABLE_THREADS)
-       threadobject  *thread;
-       utf           *u;
-       java_handle_t *o;
-
-# if defined(WITH_CLASSPATH_GNU)
-       thread = (threadobject *) LLNI_field_direct(this, vmThread)->vmdata;
-# elif defined(WITH_CLASSPATH_CLDC1_1)
-       thread = (threadobject *) this->vm_thread;
-# endif
-
-       u = threads_thread_get_state(thread);
-       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/java_lang_Thread.h b/src/native/vm/java_lang_Thread.h
deleted file mode 100644 (file)
index e29e8b6..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* src/native/vm/java_lang_Thread.h - java/lang/Thread functions
-
-   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 _JV_JAVA_LANG_THREAD_H
-#define _JV_JAVA_LANG_THREAD_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "native/jni.h"
-#include "native/include/java_lang_String.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_Thread.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_ThreadGroup.h"
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-# include "native/include/java_lang_VMThread.h"
-#endif
-
-
-/* function prototypes ********************************************************/
-
-s4                _Jv_java_lang_Thread_countStackFrames(java_lang_Thread *this);
-void              _Jv_java_lang_Thread_sleep(s8 millis);
-void              _Jv_java_lang_Thread_start(java_lang_Thread *this, s8 stacksize);
-s4                _Jv_java_lang_Thread_isInterrupted(java_lang_Thread *this);
-void              _Jv_java_lang_Thread_suspend(java_lang_Thread *this);
-void              _Jv_java_lang_Thread_resume(java_lang_Thread *this);
-void              _Jv_java_lang_Thread_setPriority(java_lang_Thread *this, s4 priority);
-void              _Jv_java_lang_Thread_stop(java_lang_Thread *this, java_lang_Throwable *t);
-java_lang_Thread *_Jv_java_lang_Thread_currentThread(void);
-void              _Jv_java_lang_Thread_yield(void);
-s4                _Jv_java_lang_Thread_interrupted(void);
-s4                _Jv_java_lang_Thread_holdsLock(java_lang_Object* o);
-java_lang_String *_Jv_java_lang_Thread_getState(java_lang_Thread *this);
-
-#endif /* _JV_JAVA_LANG_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:
- */
diff --git a/src/native/vm/java_lang_reflect_Constructor.c b/src/native/vm/java_lang_reflect_Constructor.c
deleted file mode 100644 (file)
index 72deed8..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/* src/native/vm/java_lang_reflect_Constructor.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 <assert.h>
-#include <stdlib.h>
-
-#include "vm/types.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-#include "native/native.h"
-
-#if defined(WITH_CLASSPATH_SUN)
-# 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 my j.l.C */
-#endif
-
-#include "native/include/java_lang_Object.h"             /* required my j.l.C */
-#include "native/include/java_lang_Class.h"
-#include "native/include/java_lang_String.h"
-
-#include "native/include/java_lang_reflect_Constructor.h"
-
-#include "native/vm/java_lang_reflect_Constructor.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/access.h"
-#include "vm/stringlocal.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-
-
-/*
- * Class:     java/lang/reflect/Constructor
- * Method:    getModifiers
- * Signature: ()I
- */
-s4 _Jv_java_lang_reflect_Constructor_getModifiers(JNIEnv *env, java_lang_reflect_Constructor *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/Constructor
- * Method:    getParameterTypes
- * Signature: ()[Ljava/lang/Class;
- */
-java_handle_objectarray_t *_Jv_java_lang_reflect_Constructor_getParameterTypes(JNIEnv *env, java_lang_reflect_Constructor *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/Constructor
- * Method:    getExceptionTypes
- * Signature: ()[Ljava/lang/Class;
- */
-java_handle_objectarray_t *_Jv_java_lang_reflect_Constructor_getExceptionTypes(JNIEnv *env, java_lang_reflect_Constructor *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/Constructor
- * Method:    newInstance
- * Signature: ([Ljava/lang/Object;)Ljava/lang/Object;
- */
-java_lang_Object *_Jv_java_lang_reflect_Constructor_newInstance(JNIEnv *env, java_lang_reflect_Constructor *this, java_handle_objectarray_t *args)
-{
-       classinfo     *c;
-       methodinfo    *m;
-       s4             override;
-       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]);
-
-       /* check method access */
-
-       /* check if we should bypass security checks (AccessibleObject) */
-
-#if defined(WITH_CLASSPATH_GNU)
-       LLNI_field_get_val(this, flag, override);
-#elif defined(WITH_CLASSPATH_SUN)
-       LLNI_field_get_val(this, override, override);
-#else
-# error unknown classpath configuration
-#endif
-
-       if (override == false) {
-               if (!access_check_method(m, 1))
-                       return NULL;
-       }
-
-       /* create object */
-
-       o = builtin_new(c);
-
-       if (o == NULL)
-               return NULL;
-        
-       /* call initializer */
-
-       (void) _Jv_jni_invokeNative(m, o, args);
-
-       return (java_lang_Object *) o;
-}
-
-
-/*
- * Class:     java/lang/reflect/Constructor
- * Method:    getSignature
- * Signature: ()Ljava/lang/String;
- */
-java_lang_String *_Jv_java_lang_reflect_Constructor_getSignature(JNIEnv *env, java_lang_reflect_Constructor *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;
-}
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of 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/java_lang_reflect_Constructor.h b/src/native/vm/java_lang_reflect_Constructor.h
deleted file mode 100644 (file)
index 4d06fe8..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* src/native/vm/java_lang_reflect_Constructor.h
-
-   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 _JV_JAVA_LANG_REFLECT_CONSTRUCTOR_H
-#define _JV_JAVA_LANG_REFLECT_CONSTRUCTOR_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "native/jni.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_reflect_Constructor.h"
-
-
-/* function prototypes ********************************************************/
-
-s4                         _Jv_java_lang_reflect_Constructor_getModifiers(JNIEnv *env, java_lang_reflect_Constructor *this);
-java_handle_objectarray_t *_Jv_java_lang_reflect_Constructor_getParameterTypes(JNIEnv *env, java_lang_reflect_Constructor *this);
-java_handle_objectarray_t *_Jv_java_lang_reflect_Constructor_getExceptionTypes(JNIEnv *env, java_lang_reflect_Constructor *this);
-java_lang_Object          *_Jv_java_lang_reflect_Constructor_newInstance(JNIEnv *env, java_lang_reflect_Constructor *this, java_handle_objectarray_t *args);
-java_lang_String          *_Jv_java_lang_reflect_Constructor_getSignature(JNIEnv *env, java_lang_reflect_Constructor *this);
-
-#endif /* _JV_JAVA_LANG_REFLECT_CONSTRUCTOR_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/native/vm/java_lang_reflect_Method.c b/src/native/vm/java_lang_reflect_Method.c
deleted file mode 100644 (file)
index b8c9646..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* src/native/vm/java_lang_reflect_Method.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 <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_reflect_Method.h"
-
-#include "vm/access.h"
-#include "vm/builtin.h"
-#include "vm/initialize.h"
-
-#include "vmcore/class.h"
-#include "vmcore/method.h"
-
-
-/*
- * Class:     java/lang/reflect/Method
- * Method:    invoke
- * Signature: (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
- */
-java_lang_Object *_Jv_java_lang_reflect_Method_invoke(java_lang_reflect_Method *this, java_lang_Object *o, java_handle_objectarray_t *args)
-{
-       classinfo  *c;
-       methodinfo *m;
-       s4          override;
-       int32_t     slot;
-
-       LLNI_field_get_cls(this, clazz, c);
-       LLNI_field_get_val(this, slot , slot);
-       m = &(c->methods[slot]);
-
-
-       /* check method access */
-
-       /* check if we should bypass security checks (AccessibleObject) */
-
-#if defined(WITH_CLASSPATH_GNU)
-       LLNI_field_get_val(this, flag, override);
-#elif defined(WITH_CLASSPATH_SUN)
-       LLNI_field_get_val(this, override, override);
-#else
-# error unknown classpath configuration
-#endif
-
-       if (override == false) {
-               if (!access_check_method(m, 1))
-                       return NULL;
-       }
-
-       /* check if method class is initialized */
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return NULL;
-
-       /* call the Java method via a helper function */
-
-       return (java_lang_Object *) _Jv_jni_invokeNative(m, (java_handle_t *) o, 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/native/vm/java_lang_reflect_Method.h b/src/native/vm/java_lang_reflect_Method.h
deleted file mode 100644 (file)
index 5ad53cc..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* src/native/vm/java_lang_reflect_Method.h
-
-   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 _JV_JAVA_LANG_REFLECT_METHOD_H
-#define _JV_JAVA_LANG_REFLECT_METHOD_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "native/jni.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_reflect_Method.h"
-
-#include "native/vm/java_lang_reflect_Method.h"
-
-#include "vm/global.h"
-
-
-/* function prototypes ********************************************************/
-
-java_lang_Object *_Jv_java_lang_reflect_Method_invoke(java_lang_reflect_Method *this, java_lang_Object *o, java_handle_objectarray_t *args);
-
-#endif /* _JV_JAVA_LANG_REFLECT_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:
- */
index 8fe1c47263f1b9ccc1b357b7536c88afb4e49a24..e6e2369d0668b2dcc918a6a50ded41df068586fe 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/nativevm.c - register the native 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.
 
 
 #include <stdint.h>
 
-#if defined(WITH_CLASSPATH_SUN)
-# include <string.h>
-#endif
-
 #include "native/vm/nativevm.h"
 
+#include "vm/initialize.h"
+
+#include "vmcore/class.h"
 #include "vmcore/method.h"
+#include "vmcore/options.h"
+#include "vmcore/system.h"
 
 #if defined(WITH_CLASSPATH_SUN)
 # include "mm/memory.h"
 
 # include "native/native.h"
 
+# include "native/vm/sun/hpi.h"
+
 # include "vm/properties.h"
 # include "vm/vm.h"
 
-# include "vmcore/class.h"
 # include "vmcore/utf8.h"
 #endif
 
 
 *******************************************************************************/
 
-bool nativevm_preinit(void)
+void nativevm_preinit(void)
 {
-       /* register native methods of all classes implemented */
+       /* Register native methods of all classes implemented. */
 
 #if defined(ENABLE_JAVASE)
-
 # if defined(WITH_CLASSPATH_GNU)
 
+       TRACESUBSYSTEMINITIALIZATION("nativevm_preinit");
+
        _Jv_gnu_classpath_VMStackWalker_init();
        _Jv_gnu_classpath_VMSystemProperties_init();
+       _Jv_gnu_java_lang_VMCPStringBuilder_init();
        _Jv_gnu_java_lang_management_VMClassLoadingMXBeanImpl_init();
        _Jv_gnu_java_lang_management_VMMemoryMXBeanImpl_init();
        _Jv_gnu_java_lang_management_VMRuntimeMXBeanImpl_init();
@@ -79,9 +81,9 @@ bool nativevm_preinit(void)
        _Jv_java_lang_VMThread_init();
        _Jv_java_lang_VMThrowable_init();
        _Jv_java_lang_management_VMManagementFactory_init();
-       _Jv_java_lang_reflect_Constructor_init();
-       _Jv_java_lang_reflect_Field_init();
-       _Jv_java_lang_reflect_Method_init();
+       _Jv_java_lang_reflect_VMConstructor_init();
+       _Jv_java_lang_reflect_VMField_init();
+       _Jv_java_lang_reflect_VMMethod_init();
        _Jv_java_lang_reflect_VMProxy_init();
        _Jv_java_security_VMAccessController_init();
        _Jv_java_util_concurrent_atomic_AtomicLong_init();
@@ -99,35 +101,47 @@ bool nativevm_preinit(void)
        utf         *u;
        lt_dlhandle  handle;
 
+       TRACESUBSYSTEMINITIALIZATION("nativevm_preinit");
+
+       /* Load libjava.so */
+
        boot_library_path = properties_get("sun.boot.library.path");
 
        len =
-               strlen(boot_library_path) +
-               strlen("/libjava.so") +
-               strlen("0");
+               system_strlen(boot_library_path) +
+               system_strlen("/libjava.so") +
+               system_strlen("0");
 
        p = MNEW(char, len);
 
-       strcpy(p, boot_library_path);
-       strcat(p, "/libjava.so");
+       system_strcpy(p, boot_library_path);
+       system_strcat(p, "/libjava.so");
 
        u = utf_new_char(p);
 
+       handle = native_library_open(u);
+
+       if (handle == NULL)
+               vm_abort("nativevm_init: failed to open libjava.so at: %s", p);
+
        MFREE(p, char, len);
 
-       handle = native_library_open(u);
        native_library_add(u, NULL, handle);
 
+       /* Initialize the HPI. */
+
+       hpi_initialize();
+
        _Jv_sun_misc_Unsafe_init();
 
 # else
-
 #  error unknown classpath configuration
-
 # endif
 
 #elif defined(ENABLE_JAVAME_CLDC1_1)
 
+       TRACESUBSYSTEMINITIALIZATION("nativevm_preinit");
+
        _Jv_com_sun_cldc_io_ResourceInputStream_init();
        _Jv_com_sun_cldc_io_j2me_socket_Protocol_init();
        _Jv_com_sun_cldchi_io_ConsoleOutputStream_init();
@@ -144,14 +158,8 @@ bool nativevm_preinit(void)
        _Jv_java_lang_Throwable_init();
 
 #else
-
 # error unknown Java configuration
-
 #endif
-
-       /* everything's ok */
-
-       return true;
 }
 
 
@@ -161,18 +169,22 @@ bool nativevm_preinit(void)
 
 *******************************************************************************/
 
-bool nativevm_init(void)
+void nativevm_init(void)
 {
 #if defined(ENABLE_JAVASE)
 
 # if defined(WITH_CLASSPATH_GNU)
 
+       TRACESUBSYSTEMINITIALIZATION("nativevm_init");
+
        /* nothing to do */
 
 # elif defined(WITH_CLASSPATH_SUN)
 
        methodinfo *m;
 
+       TRACESUBSYSTEMINITIALIZATION("nativevm_init");
+
        m = class_resolveclassmethod(class_java_lang_System,
                                                                 utf_new_char("initializeSystemClass"),
                                                                 utf_void__void,
@@ -180,29 +192,23 @@ bool nativevm_init(void)
                                                                 false);
 
        if (m == NULL)
-               return false;
+               vm_abort("nativevm_init: Error resolving java.lang.System.initializeSystemClass()");
 
        (void) vm_call_method(m, NULL);
 
 # else
-
 #  error unknown classpath configuration
-
 # endif
 
 #elif defined(ENABLE_JAVAME_CLDC1_1)
 
+       TRACESUBSYSTEMINITIALIZATION("nativevm_init");
+
        /* nothing to do */
 
 #else
-
 # error unknown Java configuration
-
 #endif
-
-       /* everything's ok */
-
-       return true;
 }
 
 
index 17e49446ace136a9a660718cc739264ced6661ca..6ed7acbfcc842ef391aa72675fff137e15a33ae5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/nativevm.h - register the native 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.
 
 
 /* function prototypes ********************************************************/
 
-bool nativevm_preinit(void);
-bool nativevm_init(void);
+void nativevm_preinit(void);
+void nativevm_init(void);
 
 #if defined(ENABLE_JAVASE)
-
 # if defined(WITH_CLASSPATH_GNU)
 
 void _Jv_gnu_classpath_VMStackWalker_init();
 void _Jv_gnu_classpath_VMSystemProperties_init();
+void _Jv_gnu_java_lang_VMCPStringBuilder_init();
 void _Jv_gnu_java_lang_management_VMClassLoadingMXBeanImpl_init();
 void _Jv_gnu_java_lang_management_VMMemoryMXBeanImpl_init();
 void _Jv_gnu_java_lang_management_VMRuntimeMXBeanImpl_init();
@@ -58,9 +56,9 @@ void _Jv_java_lang_VMSystem_init();
 void _Jv_java_lang_VMThread_init();
 void _Jv_java_lang_VMThrowable_init();
 void _Jv_java_lang_management_VMManagementFactory_init();
-void _Jv_java_lang_reflect_Constructor_init();
-void _Jv_java_lang_reflect_Field_init();
-void _Jv_java_lang_reflect_Method_init();
+void _Jv_java_lang_reflect_VMConstructor_init();
+void _Jv_java_lang_reflect_VMField_init();
+void _Jv_java_lang_reflect_VMMethod_init();
 void _Jv_java_lang_reflect_VMProxy_init();
 void _Jv_java_security_VMAccessController_init();
 void _Jv_java_util_concurrent_atomic_AtomicLong_init();
@@ -75,9 +73,7 @@ void _Jv_sun_reflect_ConstantPool_init();
 void _Jv_sun_misc_Unsafe_init();
 
 # else
-
 #  error unknown classpath configuration
-
 # endif
 
 #elif defined(ENABLE_JAVAME_CLDC1_1)
@@ -98,9 +94,7 @@ void _Jv_java_lang_Thread_init();
 void _Jv_java_lang_Throwable_init();
 
 #else
-
 # error unknown Java configuration
-
 #endif
 
 #endif /* _NATIVEVM_H */
index 7efe5010ee043e796b64db72891ec3b8bd8d363d..156bc097fa0fe2dbeb23355e55f969374f8f19f9 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/reflect.c - helper functions for java/lang/reflect
 
-   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/include/java_lang_reflect_Field.h"
 #include "native/include/java_lang_reflect_Method.h"
 
+#if defined(WITH_CLASSPATH_GNU)
+# 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_CLASSPATH_GNU)
 # include "vm/vm.h"
 # include "native/include/sun_reflect_ConstantPool.h"
 
 #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"
 
 java_lang_reflect_Constructor *reflect_constructor_new(methodinfo *m)
 {
-       classinfo                     *c;
-       java_handle_t                 *o;
-       java_lang_reflect_Constructor *rc;
-       int32_t                        slot;
-
-       /* get declaring class */
+       java_handle_t                   *o;
+       java_lang_reflect_Constructor   *rc;
+       int32_t                          slot;
 
-       c = m->class;
+#if defined(WITH_CLASSPATH_GNU)
+       java_lang_reflect_VMConstructor *rvmc;
+#endif
 
-       /* allocate a new object */
+       /* Allocate a java.lang.reflect.Constructor object. */
 
        o = builtin_new(class_java_lang_reflect_Constructor);
 
        if (o == NULL)
                return NULL;
 
-       /* initialize instance fields */
+       /* Initialize instance fields. */
 
        rc = (java_lang_reflect_Constructor *) o;
 
-       /* calculate the slot */
+       /* Calculate the slot. */
 
-       slot = m - c->methods;
+       slot = m - m->clazz->methods;
 
 #if defined(WITH_CLASSPATH_GNU)
 
-       LLNI_field_set_cls(rc, clazz               , c);
-       LLNI_field_set_val(rc, slot                , slot);
-       LLNI_field_set_ref(rc, annotations         , method_get_annotations(m));
-       LLNI_field_set_ref(rc, parameterAnnotations, method_get_parameterannotations(m));
+       /* 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_CLASSPATH_SUN)
 
-       LLNI_field_set_cls(rc, clazz               , c);
+       /* 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);
@@ -130,16 +154,15 @@ java_lang_reflect_Constructor *reflect_constructor_new(methodinfo *m)
 
 java_lang_reflect_Field *reflect_field_new(fieldinfo *f)
 {
-       classinfo               *c;
-       java_handle_t           *o;
-       java_lang_reflect_Field *rf;
-       int32_t                  slot;
+       java_handle_t             *o;
+       java_lang_reflect_Field   *rf;
+       int32_t                    slot;
 
-       /* get declaring class */
-
-       c = f->class;
+#if defined(WITH_CLASSPATH_GNU)
+       java_lang_reflect_VMField *rvmf;
+#endif
 
-       /* allocate a new object */
+       /* Allocate a java.lang.reflect.Field object. */
 
        o = builtin_new(class_java_lang_reflect_Field);
 
@@ -150,34 +173,52 @@ java_lang_reflect_Field *reflect_field_new(fieldinfo *f)
 
        rf = (java_lang_reflect_Field *) o;
 
-       /* calculate the slot */
+       /* Calculate the slot. */
 
-       slot = f - c->fields;
+       slot = f - f->clazz->fields;
 
 #if defined(WITH_CLASSPATH_GNU)
 
-       LLNI_field_set_cls(rf, clazz         , c);
+       /* 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(rf, name          , javastring_intern(javastring_new(f->name)));
-       LLNI_field_set_val(rf, slot          , slot);
-       LLNI_field_set_ref(rf, annotations   , field_get_annotations(f));
+       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_CLASSPATH_SUN)
 
-       LLNI_field_set_cls(rf, clazz         , c);
+       /* 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          , 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));
+       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
@@ -196,16 +237,15 @@ java_lang_reflect_Field *reflect_field_new(fieldinfo *f)
 
 java_lang_reflect_Method *reflect_method_new(methodinfo *m)
 {
-       classinfo                *c;
-       java_handle_t            *o;
-       java_lang_reflect_Method *rm;
-       int32_t                   slot;
-
-       /* get declaring class */
+       java_handle_t              *o;
+       java_lang_reflect_Method   *rm;
+       int32_t                     slot;
 
-       c = m->class;
+#if defined(WITH_CLASSPATH_GNU)
+       java_lang_reflect_VMMethod *rvmm;
+#endif
 
-       /* allocate a new object */
+       /* Allocate a java.lang.reflect.Method object. */
 
        o = builtin_new(class_java_lang_reflect_Method);
 
@@ -216,40 +256,56 @@ java_lang_reflect_Method *reflect_method_new(methodinfo *m)
 
        rm = (java_lang_reflect_Method *) o;
 
-       /* calculate the slot */
+       /* Calculate the slot. */
 
-       slot = m - c->methods;
+       slot = m - m->clazz->methods;
 
 #if defined(WITH_CLASSPATH_GNU)
 
-       LLNI_field_set_cls(rm, clazz               , m->class);
+       /* 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(rm, name                , javastring_intern(javastring_new(m->name)));
-       LLNI_field_set_val(rm, slot                , slot);
-       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));
+       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_CLASSPATH_SUN)
 
-       LLNI_field_set_cls(rm, clazz               , m->class);
+       LLNI_field_set_cls(rm, clazz,                m->clazz);
 
        /* The name needs to be interned */
        /* XXX implement me better! */
 
-       LLNI_field_set_ref(rm, name                , 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, 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));
+       LLNI_field_set_ref(rm, annotationDefault,    method_get_annotationdefault(m));
 
 #else
 # error unknown classpath configuration
@@ -259,6 +315,181 @@ java_lang_reflect_Method *reflect_method_new(methodinfo *m)
 }
 
 
+/* 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_CLASSPATH_GNU)
+               /* 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_CLASSPATH_SUN)
+               /* 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;
+#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_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
 /* reflect_get_declaredannotatios *********************************************
 
index ff83c265660dbe7b5075d8a6b6a0edf78b13cb8e..f0abceb77ad1ec491a5f3f3a6102c9fc9d11adc9 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/reflect.h - helper functions for java/lang/reflect
 
-   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.
 
@@ -25,6 +23,9 @@
 */
 
 
+#ifndef _REFLECT_H
+#define _REFLECT_H
+
 #include "config.h"
 
 #include <stdint.h>
@@ -32,7 +33,7 @@
 #include "native/jni.h"
 #include "native/native.h"
 
-/* keep this order of the native includes */
+/* Keep this order of the native includes. */
 
 #include "native/include/java_lang_String.h"
 
@@ -61,6 +62,8 @@
 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_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
 struct java_util_Map* reflect_get_declaredannotatios(
@@ -75,6 +78,9 @@ java_handle_objectarray_t* reflect_get_parameterannotations(
        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
index e1f7372a694df3fe1fc6e733c9e6e9e042e8aea0..1f1753140d188af5bfe7fe41af157071becfe6c4 100644 (file)
@@ -1,9 +1,7 @@
 ## src/native/vm/sun/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
+## Copyright (C) 2007, 2008
+## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 ##
 ## This file is part of CACAO.
 ##
@@ -31,6 +29,8 @@ noinst_LTLIBRARIES = \
        libnativevmcore.la
 
 libnativevmcore_la_SOURCES = \
+       hpi.c \
+       hpi.h \
        jvm.c
 
 
diff --git a/src/native/vm/sun/hpi.c b/src/native/vm/sun/hpi.c
new file mode 100644 (file)
index 0000000..9b97c30
--- /dev/null
@@ -0,0 +1,199 @@
+/* src/native/vm/sun/hpi.c - HotSpot HPI interface 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"
+
+/* We include hpi_md.h before hpi.h as the latter includes the
+   former. */
+
+#include INCLUDE_HPI_MD_H
+#include INCLUDE_HPI_H
+
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/native.h"
+
+#include "vm/properties.h"
+#include "vm/vm.h"
+
+#include "vmcore/options.h"
+#include "vmcore/system.h"
+#include "vmcore/utf8.h"
+
+
+/* VM callback functions ******************************************************/
+
+static vm_calls_t callbacks = {
+       /* TODO What should we use here? */
+/*   jio_fprintf, */
+/*   unimplemented_panic, */
+/*   unimplemented_monitorRegister, */
+       NULL,
+       NULL,
+       NULL,
+       
+       NULL, /* unused */
+       NULL, /* unused */
+       NULL  /* unused */
+};
+
+
+/* HPI interfaces *************************************************************/
+
+GetInterfaceFunc      hpi_get_interface = NULL;
+HPI_FileInterface    *hpi_file          = NULL;
+HPI_SocketInterface  *hpi_socket        = NULL;
+HPI_LibraryInterface *hpi_library       = NULL;
+HPI_SystemInterface  *hpi_system        = NULL;
+
+
+/* hpi_initialize **************************************************************
+
+   Initialize the Host Porting Interface (HPI).
+
+*******************************************************************************/
+
+void hpi_initialize(void)
+{
+       char        *boot_library_path;
+       int          len;
+       char        *p;
+       utf         *u;
+       lt_dlhandle  handle;
+       lt_ptr       dll_initialize;
+       int          result;
+    jint (JNICALL * DLL_Initialize)(GetInterfaceFunc *, void *);
+
+       TRACESUBSYSTEMINITIALIZATION("hpi_init");
+
+       /* Load libhpi.so */
+
+       boot_library_path = properties_get("sun.boot.library.path");
+
+       len =
+               system_strlen(boot_library_path) +
+               system_strlen("/native_threads/libhpi.so") +
+               system_strlen("0");
+
+       p = MNEW(char, len);
+
+       system_strcpy(p, boot_library_path);
+       system_strcat(p, "/native_threads/libhpi.so");
+
+       u = utf_new_char(p);
+
+    if (opt_TraceHPI)
+               log_println("hpi_init: Loading HPI %s ", p);
+
+       MFREE(p, char, len);
+
+       handle = native_library_open(u);
+
+       if (handle == NULL)
+               if (opt_TraceHPI)
+                       vm_abort("hpi_init: HPI open failed");
+
+       /* Resolve the DLL_Initialize function from the library. */
+
+       dll_initialize = lt_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", lt_dlerror());
+
+    if (DLL_Initialize == NULL ||
+        (*DLL_Initialize)(&hpi_get_interface, &callbacks) < 0) {
+
+        if (opt_TraceHPI)
+                       vm_abort("hpi_init: HPI DLL_Initialize failed");
+    }
+
+       native_library_add(u, NULL, handle);
+
+    if (opt_TraceHPI)
+               log_println("hpi_init: HPI loaded successfully");
+
+       /* Resolve the interfaces. */
+       /* NOTE: The intptr_t-case is only to prevent the a compiler
+          warning with -O2: warning: dereferencing type-punned pointer
+          will break strict-aliasing rules */
+
+       result = (*hpi_get_interface)((void **) (intptr_t) &hpi_file, "File", 1);
+
+       if (result != 0)
+               vm_abort("hpi_init: Can't find HPI_FileInterface");
+
+       result = (*hpi_get_interface)((void **) (intptr_t) &hpi_library, "Library", 1);
+
+       if (result != 0)
+               vm_abort("hpi_init: Can't find HPI_LibraryInterface");
+
+       result = (*hpi_get_interface)((void **) (intptr_t) &hpi_system, "System", 1);
+
+       if (result != 0)
+               vm_abort("hpi_init: Can't find HPI_SystemInterface");
+}
+
+
+/* hpi_initialize_socket_library ***********************************************
+
+   Initialize the library Host Porting Interface (HPI).
+
+*******************************************************************************/
+
+int hpi_initialize_socket_library(void)
+{
+       int result;
+
+       /* Resolve the socket library interface. */
+
+       result = (*hpi_get_interface)((void **) (intptr_t) &hpi_socket, "Socket", 1);
+
+       if (result != 0) {
+               if (opt_TraceHPI)
+                       log_println("hpi_initialize_socket_library: Can't find HPI_SocketInterface");
+
+               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/vm/sun/hpi.h b/src/native/vm/sun/hpi.h
new file mode 100644 (file)
index 0000000..9b0b19f
--- /dev/null
@@ -0,0 +1,74 @@
+/* src/native/vm/sun/hpi.h - HotSpot HPI interface 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 _HPI_H
+#define _HPI_H
+
+#include "config.h"
+
+/* HPI headers *****************************************************************
+
+   We include hpi_md.h before hpi.h as the latter includes the former.
+
+   These includes define:
+
+   #define _JAVASOFT_HPI_MD_H_
+   #define _JAVASOFT_HPI_H_
+
+*******************************************************************************/
+
+#include INCLUDE_HPI_MD_H
+#include INCLUDE_HPI_H
+
+
+/* HPI interfaces *************************************************************/
+
+extern HPI_FileInterface    *hpi_file;
+extern HPI_SocketInterface  *hpi_socket;
+extern HPI_LibraryInterface *hpi_library;
+extern HPI_SystemInterface  *hpi_system;
+
+
+/* functions ******************************************************************/
+
+void hpi_initialize(void);
+int  hpi_initialize_socket_library(void);
+
+#endif /* _HPI_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 91f490382052078a1329fe5b935db4f722677e98..18c4df92ac885a0aad5cde820ab4ca9ba0cfa388 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/sun/jvm.c - HotSpot JVM interface 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.
 
 */
 
 
-#define PRINTJVM 0
-
 #include "config.h"
 
 #include <assert.h>
 #include <errno.h>
-#include <fcntl.h>
 #include <ltdl.h>
 #include <stdint.h>
 #include <stdio.h>
 #include "native/include/java_lang_StackTraceElement.h"
 #include "native/include/java_lang_Throwable.h"
 #include "native/include/java_security_ProtectionDomain.h"
-#include "native/include/java_lang_Integer.h"
-#include "native/include/java_lang_Long.h"
-#include "native/include/java_lang_Short.h"
-#include "native/include/java_lang_Byte.h"
-#include "native/include/java_lang_Character.h"
-#include "native/include/java_lang_Boolean.h"
-#include "native/include/java_lang_Float.h"
-#include "native/include/java_lang_Double.h"
 
 #if defined(ENABLE_ANNOTATIONS)
 #include "native/include/sun_reflect_ConstantPool.h"
 #endif
 
-#include "native/vm/java_lang_Class.h"
-#include "native/vm/java_lang_ClassLoader.h"
-#include "native/vm/java_lang_Runtime.h"
-#include "native/vm/java_lang_Thread.h"
-#include "native/vm/java_lang_reflect_Constructor.h"
-#include "native/vm/java_lang_reflect_Method.h"
 #include "native/vm/reflect.h"
 
+#include "native/vm/sun/hpi.h"
+
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 #include "toolbox/list.h"
 
 #if !defined(NDEBUG)
 
-# define TRACEJVMCALLS(...)                                            \
+# 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_TraceJVMCalls) {                               \
-            log_println(__VA_ARGS__);                  \
+        if (opt_TraceJVMCallsVerbose) {                        \
+            log_println x;                                             \
         }                                                                              \
     } while (0)
 
-# define PRINTJVMWARNINGS(...)
+# define PRINTJVMWARNINGS(x)
 /*     do { \ */
 /*         if (opt_PrintJVMWarnings) { \ */
-/*             log_println(__VA_ARGS__); \ */
+/*             log_println x; \ */
 /*         } \ */
 /*     } while (0) */
 
 #else
 
-# define TRACEJVMCALLS(...)
-# define PRINTJVMWARNINGS(...)
+# define TRACEJVMCALLS(x)
+# define TRACEJVMCALLSENTER(x)
+# define TRACEJVMCALLSEXIT(x)
+# define TRACEJVMCALLSVERBOSE(x)
+# define PRINTJVMWARNINGS(x)
 
 #endif
 
@@ -199,18 +208,24 @@ int jio_snprintf(char *str, size_t count, const char *fmt, ...)
 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;
 }
 
 
@@ -230,9 +245,8 @@ jint JVM_GetInterfaceVersion()
 
 jlong JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored)
 {
-#if PRINTJVM
-       log_println("JVM_CurrentTimeMillis");
-#endif
+       TRACEJVMCALLS(("JVM_CurrentTimeMillis(env=%p, ignored=%p)", env, ignored));
+
        return (jlong) builtin_currenttimemillis();
 }
 
@@ -241,9 +255,8 @@ jlong JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored)
 
 jlong JVM_NanoTime(JNIEnv *env, jclass ignored)
 {
-#if PRINTJVM
-       log_println("JVM_NanoTime");
-#endif
+       TRACEJVMCALLS(("JVM_NanoTime(env=%p, ignored=%p)", env, ignored));
+
        return (jlong) builtin_nanotime();
 }
 
@@ -258,9 +271,7 @@ void JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobje
        s = (java_handle_t *) src;
        d = (java_handle_t *) dst;
 
-#if PRINTJVM
-       log_println("JVM_ArrayCopy: src=%p, src_pos=%d, dst=%p, dst_pos=%d, length=%d", src, src_pos, dst, dst_pos, length);
-#endif
+       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);
 }
@@ -271,11 +282,22 @@ void JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobje
 jobject JVM_InitProperties(JNIEnv *env, jobject properties)
 {
        java_handle_t *h;
+       char           buf[256];
 
-       TRACEJVMCALLS("JVM_InitProperties(env=%p, properties=%p)", env, properties);
+       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;
@@ -294,9 +316,8 @@ void JVM_Exit(jint code)
 
 void JVM_Halt(jint code)
 {
-#if PRINTJVM
-       log_println("JVM_Halt: code=%d", code);
-#endif
+       TRACEJVMCALLS(("JVM_Halt(code=%d)", code));
+
 /*     vm_exit(code); */
        vm_shutdown(code);
 }
@@ -314,7 +335,7 @@ void JVM_OnExit(void (*func)(void))
 
 void JVM_GC(void)
 {
-       TRACEJVMCALLS("JVM_GC()");
+       TRACEJVMCALLS(("JVM_GC()"));
 
        gc_call();
 }
@@ -325,6 +346,8 @@ void JVM_GC(void)
 jlong JVM_MaxObjectInspectionAge(void)
 {
        log_println("JVM_MaxObjectInspectionAge: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -348,7 +371,7 @@ void JVM_TraceMethodCalls(jboolean on)
 
 jlong JVM_TotalMemory(void)
 {
-       TRACEJVMCALLS("JVM_TotalMemory()");
+       TRACEJVMCALLS(("JVM_TotalMemory()"));
 
        return gc_get_heap_size();
 }
@@ -358,7 +381,7 @@ jlong JVM_TotalMemory(void)
 
 jlong JVM_FreeMemory(void)
 {
-       TRACEJVMCALLS("JVM_FreeMemory()");
+       TRACEJVMCALLS(("JVM_FreeMemory()"));
 
        return gc_get_free_bytes();
 }
@@ -368,7 +391,7 @@ jlong JVM_FreeMemory(void)
 
 jlong JVM_MaxMemory(void)
 {
-       TRACEJVMCALLS("JVM_MaxMemory()");
+       TRACEJVMCALLS(("JVM_MaxMemory()"));
 
        return gc_get_max_heap_size();
 }
@@ -378,7 +401,7 @@ jlong JVM_MaxMemory(void)
 
 jint JVM_ActiveProcessorCount(void)
 {
-       TRACEJVMCALLS("JVM_ActiveProcessorCount()");
+       TRACEJVMCALLS(("JVM_ActiveProcessorCount()"));
 
        return system_processors_online();
 }
@@ -391,16 +414,16 @@ 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);
+       TRACEJVMCALLS(("JVM_FillInStackTrace(env=%p, receiver=%p)", env, receiver));
 
        o = (java_lang_Throwable *) receiver;
 
-       ba = stacktrace_get();
+       ba = stacktrace_get_current();
 
        if (ba == NULL)
                return;
 
-       LLNI_field_set_ref(o, backtrace, ba);
+       LLNI_field_set_ref(o, backtrace, (java_lang_Object *) ba);
 }
 
 
@@ -416,21 +439,24 @@ void JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable)
 
 jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
 {
-       java_lang_Throwable     *t;
+       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);
+       TRACEJVMCALLS(("JVM_GetStackTraceDepth(env=%p, throwable=%p)", env, throwable));
 
        if (throwable == NULL) {
                exceptions_throw_nullpointerexception();
                return 0;
        }
 
-       t = (java_lang_Throwable *) throwable;
+       to = (java_lang_Throwable *) throwable;
+
+       LLNI_field_get_ref(to, backtrace, o);
 
-       LLNI_field_get_ref(t, backtrace, ba);
+       ba = (java_handle_bytearray_t *) o;
 
        if (ba == NULL)
                return 0;
@@ -454,23 +480,26 @@ jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
 
 jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
 {
-       java_lang_Throwable         *t;
+       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 *o;
-       java_lang_String            *declaringclass;
+       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);
+       TRACEJVMCALLS(("JVM_GetStackTraceElement(env=%p, throwable=%p, index=%d)", env, throwable, index));
+
+       to = (java_lang_Throwable *) throwable;
 
-       t = (java_lang_Throwable *) throwable;
+       LLNI_field_get_ref(to, backtrace, o);
 
-       LLNI_field_get_ref(t, backtrace, ba);
+       ba = (java_handle_bytearray_t *) o;
 
        /* FIXME critical section */
 
@@ -492,14 +521,14 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
 
        code = ste->code;
        m    = code->m;
-       c    = m->class;
+       c    = m->clazz;
 
        /* allocate a new StackTraceElement */
 
-       o = (java_lang_StackTraceElement *)
+       steo = (java_lang_StackTraceElement *)
                builtin_new(class_java_lang_StackTraceElement);
 
-       if (o == NULL)
+       if (steo == NULL)
                return NULL;
 
        /* get filename */
@@ -528,18 +557,18 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
 
        /* get declaring class name */
 
-       declaringclass = _Jv_java_lang_Class_getName(LLNI_classinfo_wrap(c));
+       declaringclass = class_get_classname(c);
 
        /* fill the java.lang.StackTraceElement element */
 
        /* FIXME critical section */
 
-       o->declaringClass = declaringclass;
-       o->methodName     = (java_lang_String *) javastring_new(m->name);
-       o->fileName       = filename;
-       o->lineNumber     = linenumber;
+       steo->declaringClass = (java_lang_String*) declaringclass;
+       steo->methodName     = (java_lang_String*) javastring_new(m->name);
+       steo->fileName       = filename;
+       steo->lineNumber     = linenumber;
 
-       return (jobject) o;
+       return (jobject) steo;
 }
 
 
@@ -547,7 +576,7 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
 
 jint JVM_IHashCode(JNIEnv* env, jobject handle)
 {
-       TRACEJVMCALLS("JVM_IHashCode(env=%p, jobject=%p)", env, handle);
+       TRACEJVMCALLS(("JVM_IHashCode(env=%p, jobject=%p)", env, handle));
 
        return (jint) ((ptrint) handle);
 }
@@ -561,7 +590,7 @@ void JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)
        java_handle_t *o;
 #endif
 
-       TRACEJVMCALLS("JVM_MonitorWait(env=%p, handle=%p, ms=%ld)", env, handle, ms);
+       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();
@@ -584,7 +613,7 @@ void JVM_MonitorNotify(JNIEnv* env, jobject handle)
        java_handle_t *o;
 #endif
 
-       TRACEJVMCALLS("JVM_MonitorNotify(env=%p, handle=%p)", env, handle);
+       TRACEJVMCALLS(("JVM_MonitorNotify(env=%p, handle=%p)", env, handle));
 
 #if defined(ENABLE_THREADS)
        o = (java_handle_t *) handle;
@@ -602,7 +631,7 @@ void JVM_MonitorNotifyAll(JNIEnv* env, jobject handle)
        java_handle_t *o;
 #endif
 
-       TRACEJVMCALLS("JVM_MonitorNotifyAll(env=%p, handle=%p)", env, handle);
+       TRACEJVMCALLS(("JVM_MonitorNotifyAll(env=%p, handle=%p)", env, handle));
 
 #if defined(ENABLE_THREADS)
        o = (java_handle_t *) handle;
@@ -616,9 +645,8 @@ void JVM_MonitorNotifyAll(JNIEnv* env, jobject handle)
 
 jobject JVM_Clone(JNIEnv* env, jobject handle)
 {
-#if PRINTJVM
-       log_println("JVM_Clone: handle=%p", handle);
-#endif
+       TRACEJVMCALLS(("JVM_Clone(env=%p, handle=%p)", env, handle));
+
        return (jobject) builtin_clone(env, (java_handle_t *) handle);
 }
 
@@ -636,6 +664,8 @@ void JVM_InitializeCompiler (JNIEnv *env, jclass compCls)
 jboolean JVM_IsSilentCompiler(JNIEnv *env, jclass compCls)
 {
        log_println("JVM_IsSilentCompiler: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -644,6 +674,8 @@ jboolean JVM_IsSilentCompiler(JNIEnv *env, jclass compCls)
 jboolean JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls)
 {
        log_println("JVM_CompileClass: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -652,6 +684,8 @@ jboolean JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls)
 jboolean JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname)
 {
        log_println("JVM_CompileClasses: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -660,6 +694,8 @@ jboolean JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname)
 jobject JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg)
 {
        log_println("JVM_CompilerCommand: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -667,8 +703,8 @@ jobject JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg)
 
 void JVM_EnableCompiler(JNIEnv *env, jclass compCls)
 {
-       TRACEJVMCALLS("JVM_EnableCompiler(env=%p, compCls=%p)", env, compCls);
-       PRINTJVMWARNINGS("JVM_EnableCompiler not supported");
+       TRACEJVMCALLS(("JVM_EnableCompiler(env=%p, compCls=%p)", env, compCls));
+       PRINTJVMWARNINGS(("JVM_EnableCompiler not supported"));
 }
 
 
@@ -676,8 +712,8 @@ void JVM_EnableCompiler(JNIEnv *env, jclass compCls)
 
 void JVM_DisableCompiler(JNIEnv *env, jclass compCls)
 {
-       TRACEJVMCALLS("JVM_DisableCompiler(env=%p, compCls=%p)", env, compCls);
-       PRINTJVMWARNINGS("JVM_DisableCompiler not supported");
+       TRACEJVMCALLS(("JVM_DisableCompiler(env=%p, compCls=%p)", env, compCls));
+       PRINTJVMWARNINGS(("JVM_DisableCompiler not supported"));
 }
 
 
@@ -685,25 +721,9 @@ void JVM_DisableCompiler(JNIEnv *env, jclass compCls)
 
 jint JVM_GetLastErrorString(char *buf, int len)
 {
-       const char *s;
-       int n;
-
-    if (errno == 0) {
-               return 0;
-    }
-       else {
-               s = strerror(errno);
-               n = strlen(s);
+       TRACEJVMCALLS(("JVM_GetLastErrorString(buf=%p, len=%d", buf, len));
 
-               if (n >= len)
-                       n = len - 1;
-
-               strncpy(buf, s, n);
-
-               buf[n] = '\0';
-
-               return n;
-    }
+       return hpi_system->GetLastErrorString(buf, len);
 }
 
 
@@ -711,11 +731,9 @@ jint JVM_GetLastErrorString(char *buf, int len)
 
 char *JVM_NativePath(char *path)
 {
-       TRACEJVMCALLS("JVM_NativePath(path=%s)", path);
+       TRACEJVMCALLS(("JVM_NativePath(path=%s)", path));
 
-       /* XXX is this correct? */
-
-       return path;
+       return hpi_file->NativePath(path);
 }
 
 
@@ -723,20 +741,13 @@ char *JVM_NativePath(char *path)
 
 jclass JVM_GetCallerClass(JNIEnv* env, int depth)
 {
-       java_handle_objectarray_t *oa;
-
-       TRACEJVMCALLS("JVM_GetCallerClass(env=%p, depth=%d)", env, depth);
-
-       oa = stacktrace_getClassContext();
-
-       if (oa == NULL)
-               return NULL;
+       classinfo *c;
 
-       if (oa->header.size < depth)
-               return NULL;
+       TRACEJVMCALLS(("JVM_GetCallerClass(env=%p, depth=%d)", env, depth));
 
-       return (jclass) oa->data[depth - 1];
+       c = stacktrace_get_caller_class(depth);
 
+       return (jclass) c;
 }
 
 
@@ -747,7 +758,7 @@ jclass JVM_FindPrimitiveClass(JNIEnv* env, const char* s)
        classinfo *c;
        utf       *u;
 
-       TRACEJVMCALLS("JVM_FindPrimitiveClass(env=%p, s=%s)", env, s);
+       TRACEJVMCALLS(("JVM_FindPrimitiveClass(env=%p, s=%s)", env, s));
 
        u = utf_new_char(s);
        c = primitive_class_get_by_name(u);
@@ -760,8 +771,8 @@ jclass JVM_FindPrimitiveClass(JNIEnv* env, const char* s)
 
 void JVM_ResolveClass(JNIEnv* env, jclass cls)
 {
-       TRACEJVMCALLS("JVM_ResolveClass(env=%p, cls=%p)", env, cls);
-       PRINTJVMWARNINGS("JVM_ResolveClass not implemented");
+       TRACEJVMCALLS(("JVM_ResolveClass(env=%p, cls=%p)", env, cls));
+       PRINTJVMWARNINGS(("JVM_ResolveClass not implemented"));
 }
 
 
@@ -769,11 +780,16 @@ void JVM_ResolveClass(JNIEnv* env, jclass cls)
 
 jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init, jobject loader, jboolean throwError)
 {
-       classinfo   *c;
-       utf         *u;
-       classloader *cl;
+       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. */
 
-       TRACEJVMCALLS("JVM_FindClassFromClassLoader: name=%s, init=%d, loader=%p, throwError=%d", name, init, loader, throwError);
+       assert(throwError == false);
 
        u  = utf_new_char(name);
        cl = loader_hashtable_classloader_add((java_handle_t *) loader);
@@ -797,6 +813,8 @@ jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init
 jclass JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jclass from)
 {
        log_println("JVM_FindClassFromClass: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -805,6 +823,8 @@ jclass JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jcla
 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;
 }
 
 
@@ -812,11 +832,11 @@ jclass JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyt
 
 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 *cl;
+       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);
+       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);
@@ -827,7 +847,7 @@ jclass JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
 
        /* XXX do something with source */
 
-       c = class_define(u, cl, len, (const uint8_t *) buf, (java_handle_t *) pd);
+       c = class_define(u, cl, len, (uint8_t *) buf, (java_handle_t *) pd);
 
        return (jclass) LLNI_classinfo_wrap(c);
 }
@@ -837,11 +857,11 @@ jclass JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
 
 jclass JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
 {
-       classloader *cl;
-       utf         *u;
-       classinfo   *c;
+       classloader_t *cl;
+       utf           *u;
+       classinfo     *c;
 
-       TRACEJVMCALLS("JVM_FindLoadedClass(env=%p, loader=%p, name=%p)", env, loader, name);
+       TRACEJVMCALLS(("JVM_FindLoadedClass(env=%p, loader=%p, name=%p)", env, loader, name));
 
        cl = loader_hashtable_classloader_add((java_handle_t *) loader);
 
@@ -856,10 +876,13 @@ jclass JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
 
 jstring JVM_GetClassName(JNIEnv *env, jclass cls)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassName: cls=%p", cls);
-#endif
-       return (jstring) _Jv_java_lang_Class_getName((java_lang_Class *) cls);
+       classinfo* c;
+
+       TRACEJVMCALLS(("JVM_GetClassName(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       return (jstring) class_get_classname(c);
 }
 
 
@@ -870,7 +893,7 @@ jobjectArray JVM_GetClassInterfaces(JNIEnv *env, jclass cls)
        classinfo                 *c;
        java_handle_objectarray_t *oa;
 
-       TRACEJVMCALLS("JVM_GetClassInterfaces(env=%p, cls=%p)", env, cls);
+       TRACEJVMCALLS(("JVM_GetClassInterfaces(env=%p, cls=%p)", env, cls));
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -884,14 +907,16 @@ jobjectArray JVM_GetClassInterfaces(JNIEnv *env, jclass cls)
 
 jobject JVM_GetClassLoader(JNIEnv *env, jclass cls)
 {
-       classinfo   *c;
-       classloader *cl;
+       classinfo     *c;
+       classloader_t *cl;
 
-       TRACEJVMCALLS("JVM_GetClassLoader(env=%p, cls=%p)", env, cls);
+       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;
 }
 
@@ -902,9 +927,7 @@ jboolean JVM_IsInterface(JNIEnv *env, jclass cls)
 {
        classinfo *c;
 
-#if PRINTJVM
-       log_println("JVM_IsInterface: cls=%p", cls);
-#endif
+       TRACEJVMCALLS(("JVM_IsInterface(env=%p, cls=%p)", env, cls));
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -917,6 +940,8 @@ jboolean JVM_IsInterface(JNIEnv *env, jclass cls)
 jobjectArray JVM_GetClassSigners(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassSigners: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -927,7 +952,7 @@ 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);
+       TRACEJVMCALLS(("JVM_SetClassSigners(env=%p, cls=%p, signers=%p)", env, cls, signers));
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -951,7 +976,7 @@ jobject JVM_GetProtectionDomain(JNIEnv *env, jclass cls)
 {
        classinfo *c;
 
-       TRACEJVMCALLS("JVM_GetProtectionDomain(env=%p, cls=%p)", env, cls);
+       TRACEJVMCALLS(("JVM_GetProtectionDomain(env=%p, cls=%p)", env, cls));
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -981,18 +1006,16 @@ void JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)
 
 jobject JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)
 {
-       java_handle_t *o;
+       java_handle_t *h;
        classinfo     *c;
        methodinfo    *m;
        java_handle_t *result;
        java_handle_t *e;
 
-#if PRINTJVM
-       log_println("JVM_DoPrivileged: action=%p, context=%p, wrapException=%d", action, context, wrapException);
-#endif
+       TRACEJVMCALLS(("JVM_DoPrivileged(env=%p, cls=%p, action=%p, context=%p, wrapException=%d)", env, cls, action, context, wrapException));
 
-       o = (java_handle_t *) action;
-       c = o->vftbl->class;
+       h = (java_handle_t *) action;
+       LLNI_class_get(h, c);
 
        if (action == NULL) {
                exceptions_throw_nullpointerexception();
@@ -1012,12 +1035,17 @@ jobject JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject contex
        /* XXX It seems something with a privileged stack needs to be done
           here. */
 
-       result = vm_call_method(m, o);
+       result = vm_call_method(m, h);
 
-       e = exceptions_get_and_clear_exception();
+       e = exceptions_get_exception();
 
        if (e != NULL) {
-               exceptions_throw_privilegedactionexception(e);
+               if ( builtin_instanceof(e, class_java_lang_Exception) &&
+                       !builtin_instanceof(e, class_java_lang_RuntimeException)) {
+                       exceptions_clear_exception();
+                       exceptions_throw_privilegedactionexception(e);
+               }
+
                return NULL;
        }
 
@@ -1030,6 +1058,8 @@ jobject JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject contex
 jobject JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetInheritedAccessControlContext: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -1037,7 +1067,7 @@ jobject JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)
 
 jobject JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls)
 {
-       TRACEJVMCALLS("JVM_GetStackAccessControlContext(env=%p, cls=%p): IMPLEMENT ME!", env, 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
@@ -1051,10 +1081,13 @@ jobject JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls)
 
 jboolean JVM_IsArrayClass(JNIEnv *env, jclass cls)
 {
-#if PRINTJVM
-       log_println("JVM_IsArrayClass: cls=%p", cls);
-#endif
-       return class_is_array(LLNI_classinfo_unwrap(cls));
+       classinfo *c;
+
+       TRACEJVMCALLS(("JVM_IsArrayClass(env=%p, cls=%p)", env, cls));
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       return class_is_array(c);
 }
 
 
@@ -1064,11 +1097,9 @@ jboolean JVM_IsPrimitiveClass(JNIEnv *env, jclass cls)
 {
        classinfo *c;
 
-       c = LLNI_classinfo_unwrap(cls);
+       TRACEJVMCALLS(("JVM_IsPrimitiveClass(env=%p, cls=%p)", env, cls));
 
-#if PRINTJVM
-       log_println("JVM_IsPrimitiveClass(cls=%p)", cls);
-#endif
+       c = LLNI_classinfo_unwrap(cls);
 
        return class_is_primitive(c);
 }
@@ -1081,7 +1112,7 @@ jclass JVM_GetComponentType(JNIEnv *env, jclass cls)
        classinfo *component;
        classinfo *c;
        
-       TRACEJVMCALLS("JVM_GetComponentType(env=%p, cls=%p)", env, cls);
+       TRACEJVMCALLS(("JVM_GetComponentType(env=%p, cls=%p)", env, cls));
 
        c = LLNI_classinfo_unwrap(cls);
        
@@ -1098,7 +1129,7 @@ jint JVM_GetClassModifiers(JNIEnv *env, jclass cls)
        classinfo *c;
        int32_t    flags;
 
-       TRACEJVMCALLS("JVM_GetClassModifiers(env=%p, cls=%p)", env, cls);
+       TRACEJVMCALLS(("JVM_GetClassModifiers(env=%p, cls=%p)", env, cls));
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -1115,7 +1146,7 @@ jobjectArray JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)
        classinfo                 *c;
        java_handle_objectarray_t *oa;
 
-       TRACEJVMCALLS("JVM_GetDeclaredClasses(env=%p, ofClass=%p)", env, ofClass);
+       TRACEJVMCALLS(("JVM_GetDeclaredClasses(env=%p, ofClass=%p)", env, ofClass));
 
        c = LLNI_classinfo_unwrap(ofClass);
 
@@ -1132,7 +1163,7 @@ jclass JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass)
        classinfo *c;
        classinfo *dc;
 
-       TRACEJVMCALLS("JVM_GetDeclaringClass(env=%p, ofClass=%p)", env, ofClass);
+       TRACEJVMCALLS(("JVM_GetDeclaringClass(env=%p, ofClass=%p)", env, ofClass));
 
        c = LLNI_classinfo_unwrap(ofClass);
 
@@ -1150,7 +1181,7 @@ jstring JVM_GetClassSignature(JNIEnv *env, jclass cls)
        utf           *u;
        java_handle_t *s;
 
-       TRACEJVMCALLS("JVM_GetClassSignature(env=%p, cls=%p)", env, cls);
+       TRACEJVMCALLS(("JVM_GetClassSignature(env=%p, cls=%p)", env, cls));
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -1176,7 +1207,7 @@ 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);
+       TRACEJVMCALLS(("JVM_GetClassAnnotations: cls=%p", cls));
 
        if (cls == NULL) {
                exceptions_throw_nullpointerexception();
@@ -1199,7 +1230,7 @@ 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);
+       TRACEJVMCALLS(("JVM_GetFieldAnnotations: field=%p", field));
 
        if (field == NULL) {
                exceptions_throw_nullpointerexception();
@@ -1221,7 +1252,7 @@ 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);
+       TRACEJVMCALLS(("JVM_GetMethodAnnotations: method=%p", method));
 
        if (method == NULL) {
                exceptions_throw_nullpointerexception();
@@ -1243,7 +1274,7 @@ 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);
+       TRACEJVMCALLS(("JVM_GetMethodDefaultAnnotationValue: method=%p", method));
 
        if (method == NULL) {
                exceptions_throw_nullpointerexception();
@@ -1265,7 +1296,7 @@ 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);
+       TRACEJVMCALLS(("JVM_GetMethodParameterAnnotations: method=%p", method));
 
        if (method == NULL) {
                exceptions_throw_nullpointerexception();
@@ -1284,10 +1315,16 @@ jbyteArray JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method)
 
 jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassDeclaredFields: ofClass=%p, publicOnly=%d", ofClass, publicOnly);
-#endif
-       return (jobjectArray) _Jv_java_lang_Class_getDeclaredFields((java_lang_Class *) ofClass, 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;
 }
 
 
@@ -1295,10 +1332,16 @@ jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean pu
 
 jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassDeclaredMethods: ofClass=%p, publicOnly=%d", ofClass, publicOnly);
-#endif
-       return (jobjectArray) _Jv_java_lang_Class_getDeclaredMethods((java_lang_Class *) ofClass, 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;
 }
 
 
@@ -1306,10 +1349,16 @@ jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean p
 
 jobjectArray JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassDeclaredConstructors: ofClass=%p, publicOnly=%d", ofClass, publicOnly);
-#endif
-       return (jobjectArray) _Jv_java_lang_Class_getDeclaredConstructors((java_lang_Class *) ofClass, 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;
 }
 
 
@@ -1319,7 +1368,7 @@ jint JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)
 {
        classinfo *c;
 
-       TRACEJVMCALLS("JVM_GetClassAccessFlags(env=%p, cls=%p)", env, cls);
+       TRACEJVMCALLS(("JVM_GetClassAccessFlags(env=%p, cls=%p)", env, cls));
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -1339,7 +1388,7 @@ jobject JVM_GetClassConstantPool(JNIEnv *env, jclass 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);
+       TRACEJVMCALLS(("JVM_GetClassConstantPool(env=%p, cls=%p)", env, cls));
 
        constantPool = 
                (sun_reflect_ConstantPool*)native_new_and_init(
@@ -1366,7 +1415,7 @@ 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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetSize(env=%p, unused=%p, jcpool=%p)", env, unused, jcpool));
 
        c = LLNI_classinfo_unwrap(jcpool);
 
@@ -1382,7 +1431,7 @@ jclass JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject unused, jobject jcpool, j
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetClassAt(env=%p, jcpool=%p, index=%d)", env, jcpool, index));
 
        c = LLNI_classinfo_unwrap(jcpool);
 
@@ -1407,7 +1456,7 @@ jclass JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject unused, jobject j
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetClassAtIfLoaded(env=%p, unused=%p, jcpool=%p, index=%d)", env, unused, jcpool, index));
 
        c = LLNI_classinfo_unwrap(jcpool);
 
@@ -1437,7 +1486,7 @@ jobject JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject unused, jobject jcpool,
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetMethodAt: jcpool=%p, index=%d", jcpool, index));
        
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Methodref);
@@ -1460,7 +1509,7 @@ jobject JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject unused, jobject
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetMethodAtIfLoaded: jcpool=%p, index=%d", jcpool, index));
 
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Methodref);
@@ -1489,7 +1538,7 @@ jobject JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject unused, jobject jcpool,
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetFieldAt: jcpool=%p, index=%d", jcpool, index));
 
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Fieldref);
@@ -1511,7 +1560,7 @@ jobject JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject unused, jobject
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetFieldAtIfLoaded: jcpool=%p, index=%d", jcpool, index));
 
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Fieldref);
@@ -1552,7 +1601,7 @@ jint JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject unused, jobject jcpool, jint
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetIntAt: jcpool=%p, index=%d", jcpool, index));
 
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_integer*)class_getconstant(cls, index, CONSTANT_Integer);
@@ -1573,7 +1622,7 @@ jlong JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject unused, jobject jcpool, jin
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetLongAt: jcpool=%p, index=%d", jcpool, index));
 
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_long*)class_getconstant(cls, index, CONSTANT_Long);
@@ -1594,7 +1643,7 @@ jfloat JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject unused, jobject jcpool, j
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetFloatAt: jcpool=%p, index=%d", jcpool, index));
 
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_float*)class_getconstant(cls, index, CONSTANT_Float);
@@ -1615,7 +1664,7 @@ jdouble JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject unused, jobject jcpool,
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetDoubleAt: jcpool=%p, index=%d", jcpool, index));
 
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_double*)class_getconstant(cls, index, CONSTANT_Double);
@@ -1636,7 +1685,7 @@ jstring JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject unused, jobject jcpool,
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetStringAt: jcpool=%p, index=%d", jcpool, index));
        
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (utf*)class_getconstant(cls, index, CONSTANT_String);
@@ -1658,7 +1707,7 @@ jstring JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject unused, jobject jcpool, j
        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);
+       TRACEJVMCALLS(("JVM_ConstantPoolGetUTF8At: jcpool=%p, index=%d", jcpool, index));
 
        cls = LLNI_classinfo_unwrap(jcpool);
        ref = (utf*)class_getconstant(cls, index, CONSTANT_Utf8);
@@ -1683,7 +1732,7 @@ jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)
        jboolean           status;
        utf               *name;
 
-       TRACEJVMCALLS("JVM_DesiredAssertionStatus(env=%p, unused=%p, cls=%p)", env, unused, cls);
+       TRACEJVMCALLS(("JVM_DesiredAssertionStatus(env=%p, unused=%p, cls=%p)", env, unused, cls));
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -1732,7 +1781,7 @@ jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
        s4                                     i, j;
 #endif
 
-       TRACEJVMCALLS("JVM_AssertionStatusDirectives(env=%p, unused=%p)", env, unused);
+       TRACEJVMCALLS(("JVM_AssertionStatusDirectives(env=%p, unused=%p)", env, unused));
 
        c = load_class_bootstrap(utf_new_char("java/lang/AssertionStatusDirectives"));
 
@@ -1819,9 +1868,11 @@ jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
 
 /* JVM_GetClassNameUTF */
 
-const charJVM_GetClassNameUTF(JNIEnv *env, jclass cls)
+const char *JVM_GetClassNameUTF(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -1838,6 +1889,8 @@ void JVM_GetClassCPTypes(JNIEnv *env, jclass cls, unsigned char *types)
 jint JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassCPEntriesCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1846,6 +1899,8 @@ jint JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls)
 jint JVM_GetClassFieldsCount(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassFieldsCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1854,6 +1909,8 @@ jint JVM_GetClassFieldsCount(JNIEnv *env, jclass cls)
 jint JVM_GetClassMethodsCount(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassMethodsCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1870,6 +1927,8 @@ void JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cls, jint method_index,
 jint JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cls, jint method_index)
 {
        log_println("JVM_GetMethodIxExceptionsCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1886,6 +1945,8 @@ void JVM_GetMethodIxByteCode(JNIEnv *env, jclass cls, jint method_index, unsigne
 jint JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cls, jint method_index)
 {
        log_println("JVM_GetMethodIxByteCodeLength: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1902,6 +1963,8 @@ void JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cls, jint method_ind
 jint JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxExceptionTableLength: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1910,6 +1973,8 @@ jint JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_ind
 jint JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxModifiers: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1918,6 +1983,8 @@ jint JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index)
 jint JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)
 {
        log_println("JVM_GetFieldIxModifiers: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1926,6 +1993,8 @@ jint JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)
 jint JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxLocalsCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1934,6 +2003,8 @@ jint JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index)
 jint JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxArgsSize: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1942,6 +2013,8 @@ jint JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index)
 jint JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxMaxStack: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1950,78 +2023,98 @@ jint JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index)
 jboolean JVM_IsConstructorIx(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_IsConstructorIx: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
 /* JVM_GetMethodIxNameUTF */
 
-const charJVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index)
+const char *JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index)
 {
        log_println("JVM_GetMethodIxNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetMethodIxSignatureUTF */
 
-const charJVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index)
+const char *JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index)
 {
        log_println("JVM_GetMethodIxSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPFieldNameUTF */
 
-const charJVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPFieldNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPMethodNameUTF */
 
-const charJVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPMethodNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPMethodSignatureUTF */
 
-const charJVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPMethodSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPFieldSignatureUTF */
 
-const charJVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPFieldSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPClassNameUTF */
 
-const charJVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPFieldClassNameUTF */
 
-const charJVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPFieldClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPMethodClassNameUTF */
 
-const charJVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPMethodClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2030,6 +2123,8 @@ const char* JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 jint JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)
 {
        log_println("JVM_GetCPFieldModifiers: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2038,6 +2133,8 @@ jint JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass calle
 jint JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)
 {
        log_println("JVM_GetCPMethodModifiers: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2054,30 +2151,35 @@ void JVM_ReleaseUTF(const char *utf)
 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;
 
-#if PRINTJVM
-       log_println("JVM_Open: fname=%s, flags=%d, mode=%d", fname, flags, mode);
-#endif
+       TRACEJVMCALLS(("JVM_Open(fname=%s, flags=%d, mode=%d)", fname, flags, mode));
 
-       result = open(fname, flags, mode);
+       result = hpi_file->Open(fname, flags, mode);
 
        if (result >= 0) {
                return result;
        }
        else {
-               switch(errno) {
+               switch (errno) {
                case EEXIST:
-                       /* XXX don't know what to do here */
-/*                     return JVM_EEXIST; */
-                       return -1;
+                       return JVM_EEXIST;
                default:
                        return -1;
                }
@@ -2089,10 +2191,9 @@ jint JVM_Open(const char *fname, jint flags, jint mode)
 
 jint JVM_Close(jint fd)
 {
-#if PRINTJVM
-       log_println("JVM_Close: fd=%d", fd);
-#endif
-       return close(fd);
+       TRACEJVMCALLS(("JVM_Close(fd=%d)", fd));
+
+       return hpi_file->Close(fd);
 }
 
 
@@ -2100,10 +2201,9 @@ jint JVM_Close(jint fd)
 
 jint JVM_Read(jint fd, char *buf, jint nbytes)
 {
-#if PRINTJVM
-       log_println("JVM_Read: fd=%d, buf=%p, nbytes=%d", fd, buf, nbytes);
-#endif
-       return read(fd, buf, nbytes);
+       TRACEJVMCALLS(("JVM_Read(fd=%d, buf=%p, nbytes=%d)", fd, buf, nbytes));
+
+       return (jint) hpi_file->Read(fd, buf, nbytes);
 }
 
 
@@ -2111,10 +2211,9 @@ jint JVM_Read(jint fd, char *buf, jint nbytes)
 
 jint JVM_Write(jint fd, char *buf, jint nbytes)
 {
-#if PRINTJVM
-       log_println("JVM_Write: fd=%d, buf=%s, nbytes=%d", fd, buf, nbytes);
-#endif
-       return write(fd, buf, nbytes);
+       TRACEJVMCALLS(("JVM_Write(fd=%d, buf=%s, nbytes=%d)", fd, buf, nbytes));
+
+       return (jint) hpi_file->Write(fd, buf, nbytes);
 }
 
 
@@ -2122,22 +2221,9 @@ jint JVM_Write(jint fd, char *buf, jint nbytes)
 
 jint JVM_Available(jint fd, jlong *pbytes)
 {
-#if defined(FIONREAD)
-       int bytes;
-
-       TRACEJVMCALLS("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes);
-
-       *pbytes = 0;
-
-       if (ioctl(fd, FIONREAD, &bytes) < 0)
-               return 0;
+       TRACEJVMCALLS(("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes));
 
-       *pbytes = bytes;
-
-       return 1;
-#else
-# error FIONREAD not defined
-#endif
+       return hpi_file->Available(fd, pbytes);
 }
 
 
@@ -2145,9 +2231,9 @@ jint JVM_Available(jint fd, jlong *pbytes)
 
 jlong JVM_Lseek(jint fd, jlong offset, jint whence)
 {
-       TRACEJVMCALLS("JVM_Lseek(fd=%d, offset=%ld, whence=%d)", fd, offset, whence);
+       TRACEJVMCALLS(("JVM_Lseek(fd=%d, offset=%ld, whence=%d)", fd, offset, whence));
 
-       return (jlong) lseek(fd, (off_t) offset, whence);
+       return hpi_file->Seek(fd, (off_t) offset, whence);
 }
 
 
@@ -2155,9 +2241,9 @@ jlong JVM_Lseek(jint fd, jlong offset, jint whence)
 
 jint JVM_SetLength(jint fd, jlong length)
 {
-       TRACEJVMCALLS("JVM_SetLength(fd=%d, length=%ld)", length);
+       TRACEJVMCALLS(("JVM_SetLength(fd=%d, length=%ld)", length));
 
-       return ftruncate(fd, length);
+       return hpi_file->SetLength(fd, length);
 }
 
 
@@ -2165,9 +2251,9 @@ jint JVM_SetLength(jint fd, jlong length)
 
 jint JVM_Sync(jint fd)
 {
-       TRACEJVMCALLS("JVM_Sync(fd=%d)", fd);
+       TRACEJVMCALLS(("JVM_Sync(fd=%d)", fd));
 
-       return fsync(fd);
+       return hpi_file->Sync(fd);
 }
 
 
@@ -2175,10 +2261,9 @@ jint JVM_Sync(jint fd)
 
 void JVM_StartThread(JNIEnv* env, jobject jthread)
 {
-#if PRINTJVM
-       log_println("JVM_StartThread: jthread=%p", jthread);
-#endif
-       _Jv_java_lang_Thread_start((java_lang_Thread *) jthread, 0);
+       TRACEJVMCALLS(("JVM_StartThread(env=%p, jthread=%p)", env, jthread));
+
+       threads_thread_start((java_handle_t *) jthread);
 }
 
 
@@ -2194,20 +2279,14 @@ void JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)
 
 jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread)
 {
-       threadobject *t;
-       bool          equal;
-       bool          result;
-
-       TRACEJVMCALLS("JVM_IsThreadAlive(env=%p, jthread=%p)", env, jthread);
-
-       /* XXX this is just a quick hack */
+       java_handle_t *h;
+       threadobject  *t;
+       bool           result;
 
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
-               LLNI_equals(t->object, jthread, equal);
+       TRACEJVMCALLS(("JVM_IsThreadAlive(env=%p, jthread=%p)", env, jthread));
 
-               if (equal == true)
-                       break;
-       }
+       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. */
@@ -2241,10 +2320,21 @@ void JVM_ResumeThread(JNIEnv* env, jobject jthread)
 
 void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio)
 {
-#if PRINTJVM
-       log_println("JVM_SetThreadPriority: jthread=%p, prio=%d", jthread, prio);
-#endif
-       _Jv_java_lang_Thread_setPriority((java_lang_Thread *) jthread, 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);
 }
 
 
@@ -2252,7 +2342,7 @@ void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio)
 
 void JVM_Yield(JNIEnv *env, jclass threadClass)
 {
-       TRACEJVMCALLS("JVM_Yield(env=%p, threadClass=%p)", env, threadClass);
+       TRACEJVMCALLS(("JVM_Yield(env=%p, threadClass=%p)", env, threadClass));
 
        threads_yield();
 }
@@ -2262,10 +2352,9 @@ void JVM_Yield(JNIEnv *env, jclass threadClass)
 
 void JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis)
 {
-#if PRINTJVM
-       log_println("JVM_Sleep: threadClass=%p, millis=%ld", threadClass, millis);
-#endif
-       _Jv_java_lang_Thread_sleep(millis);
+       TRACEJVMCALLS(("JVM_Sleep(env=%p, threadClass=%p, millis=%ld)", env, threadClass, millis));
+
+       threads_sleep(millis, 0);
 }
 
 
@@ -2273,10 +2362,13 @@ void JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis)
 
 jobject JVM_CurrentThread(JNIEnv* env, jclass threadClass)
 {
-#if PRINTJVM
-       log_println("JVM_CurrentThread: threadClass=%p", threadClass);
-#endif
-       return (jobject) _Jv_java_lang_Thread_currentThread();
+       java_object_t *o;
+
+       TRACEJVMCALLSVERBOSE(("JVM_CurrentThread(env=%p, threadClass=%p)", env, threadClass));
+
+       o = thread_get_current_object();
+
+       return (jobject) o;
 }
 
 
@@ -2285,6 +2377,8 @@ jobject JVM_CurrentThread(JNIEnv* env, jclass threadClass)
 jint JVM_CountStackFrames(JNIEnv* env, jobject jthread)
 {
        log_println("JVM_CountStackFrames: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2292,7 +2386,18 @@ jint JVM_CountStackFrames(JNIEnv* env, jobject jthread)
 
 void JVM_Interrupt(JNIEnv* env, jobject jthread)
 {
-       log_println("JVM_Interrupt: IMPLEMENT ME!");
+       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);
 }
 
 
@@ -2300,11 +2405,21 @@ void JVM_Interrupt(JNIEnv* env, jobject jthread)
 
 jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted)
 {
-#if PRINTJVM
-       log_println("JVM_IsInterrupted: jthread=%p, clear_interrupted=%d", jthread, clear_interrupted);
-#endif
-       /* XXX do something with clear_interrupted */
-       return _Jv_java_lang_Thread_isInterrupted((java_lang_Thread *) jthread);
+       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;
 }
 
 
@@ -2315,7 +2430,7 @@ 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);
+       TRACEJVMCALLS(("JVM_HoldsLock(env=%p, threadClass=%p, obj=%p)", env, threadClass, obj));
 
        h = (java_handle_t *) obj;
 
@@ -2343,6 +2458,8 @@ void JVM_DumpAllStacks(JNIEnv* env, jclass unused)
 jclass JVM_CurrentLoadedClass(JNIEnv *env)
 {
        log_println("JVM_CurrentLoadedClass: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2354,6 +2471,8 @@ jobject JVM_CurrentClassLoader(JNIEnv *env)
           doPrivileged, return NULL */
 
        log_println("JVM_CurrentClassLoader: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2361,9 +2480,8 @@ jobject JVM_CurrentClassLoader(JNIEnv *env)
 
 jobjectArray JVM_GetClassContext(JNIEnv *env)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassContext");
-#endif
+       TRACEJVMCALLS(("JVM_GetClassContext(env=%p)", env));
+
        return (jobjectArray) stacktrace_getClassContext();
 }
 
@@ -2373,6 +2491,8 @@ jobjectArray JVM_GetClassContext(JNIEnv *env)
 jint JVM_ClassDepth(JNIEnv *env, jstring name)
 {
        log_println("JVM_ClassDepth: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2381,6 +2501,8 @@ jint JVM_ClassDepth(JNIEnv *env, jstring name)
 jint JVM_ClassLoaderDepth(JNIEnv *env)
 {
        log_println("JVM_ClassLoaderDepth: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2392,11 +2514,13 @@ jstring JVM_GetSystemPackage(JNIEnv *env, jstring name)
        utf *u;
        utf *result;
 
-       TRACEJVMCALLS("JVM_GetSystemPackage(env=%p, name=%p)", env, name);
+       TRACEJVMCALLS(("JVM_GetSystemPackage(env=%p, name=%p)", env, name));
 
 /*     s = package_find(name); */
-       u = javastring_toutf(name, false);
+       u = javastring_toutf((java_handle_t *) name, false);
+
        result = package_find(u);
+
        if (result != NULL)
                s = javastring_new(result);
        else
@@ -2411,6 +2535,8 @@ jstring JVM_GetSystemPackage(JNIEnv *env, jstring name)
 jobjectArray JVM_GetSystemPackages(JNIEnv *env)
 {
        log_println("JVM_GetSystemPackages: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2419,6 +2545,8 @@ jobjectArray JVM_GetSystemPackages(JNIEnv *env)
 jobject JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, jclass initClass)
 {
        log_println("JVM_AllocateNewObject: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2427,6 +2555,8 @@ jobject JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, j
 jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint length)
 {
        log_println("JVM_AllocateNewArray: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2434,9 +2564,9 @@ jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint le
 
 jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
 {
-       classloader *cl;
+       classloader_t *cl;
 
-       TRACEJVMCALLS("JVM_LatestUserDefinedLoader(env=%p)", env);
+       TRACEJVMCALLS(("JVM_LatestUserDefinedLoader(env=%p)", env));
 
        cl = stacktrace_first_nonnull_classloader();
 
@@ -2449,6 +2579,8 @@ jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
 jclass JVM_LoadClass0(JNIEnv *env, jobject receiver, jclass currClass, jstring currClassName)
 {
        log_println("JVM_LoadClass0: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2458,7 +2590,7 @@ jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
 {
        java_handle_t *a;
 
-       TRACEJVMCALLS("JVM_GetArrayLength(arr=%p)", arr);
+       TRACEJVMCALLS(("JVM_GetArrayLength(arr=%p)", arr));
 
        a = (java_handle_t *) arr;
 
@@ -2473,7 +2605,7 @@ 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);
+       TRACEJVMCALLS(("JVM_GetArrayElement(env=%p, arr=%p, index=%d)", env, arr, index));
 
        a = (java_handle_t *) arr;
 
@@ -2492,7 +2624,13 @@ jobject JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index)
 
 jvalue JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode)
 {
+       jvalue jv;
+
        log_println("JVM_GetPrimitiveArrayElement: IMPLEMENT ME!");
+
+       jv.l = NULL;
+
+       return jv;
 }
 
 
@@ -2503,7 +2641,7 @@ 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);
+       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;
@@ -2529,7 +2667,7 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
        java_handle_t             *a;
        java_handle_objectarray_t *oa;
 
-       TRACEJVMCALLS("JVM_NewArray(env=%p, eltClass=%p, length=%d)", env, eltClass, length);
+       TRACEJVMCALLS(("JVM_NewArray(env=%p, eltClass=%p, length=%d)", env, eltClass, length));
 
        if (eltClass == NULL) {
                exceptions_throw_nullpointerexception();
@@ -2540,10 +2678,18 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
 
        c = LLNI_classinfo_unwrap(eltClass);
 
-       /* create primitive or object array */
+       /* 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;
@@ -2569,7 +2715,7 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
        classinfo                 *ac;
        java_handle_objectarray_t *a;
 
-       TRACEJVMCALLS("JVM_NewMultiArray(env=%p, eltClass=%p, dim=%p)", env, eltClass, dim);
+       TRACEJVMCALLS(("JVM_NewMultiArray(env=%p, eltClass=%p, dim=%p)", env, eltClass, dim));
 
        if (eltClass == NULL) {
                exceptions_throw_nullpointerexception();
@@ -2580,11 +2726,23 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 
        c = LLNI_classinfo_unwrap(eltClass);
 
-       /* XXX This is just a quick hack to get it working. */
-
        ia = (java_handle_intarray_t *) dim;
 
-       length = array_length_get(ia);
+       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);
 
@@ -2603,7 +2761,7 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
        if (ac == NULL)
                return NULL;
 
-       a = builtin_multianewarray(length, ac, dims);
+       a = builtin_multianewarray(length, (java_handle_t *) ac, dims);
 
        return (jobject) a;
 }
@@ -2613,7 +2771,9 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 
 jint JVM_InitializeSocketLibrary()
 {
-       log_println("JVM_InitializeSocketLibrary: IMPLEMENT ME!");
+       TRACEJVMCALLS(("JVM_InitializeSocketLibrary()"));
+
+       return hpi_initialize_socket_library();
 }
 
 
@@ -2621,9 +2781,9 @@ jint JVM_InitializeSocketLibrary()
 
 jint JVM_Socket(jint domain, jint type, jint protocol)
 {
-       TRACEJVMCALLS("JVM_Socket(domain=%d, type=%d, protocol=%d)", domain, type, protocol);
+       TRACEJVMCALLS(("JVM_Socket(domain=%d, type=%d, protocol=%d)", domain, type, protocol));
 
-       return socket(domain, type, protocol);
+       return system_socket(domain, type, protocol);
 }
 
 
@@ -2631,9 +2791,9 @@ jint JVM_Socket(jint domain, jint type, jint protocol)
 
 jint JVM_SocketClose(jint fd)
 {
-       TRACEJVMCALLS("JVM_SocketClose(fd=%d)", fd);
+       TRACEJVMCALLS(("JVM_SocketClose(fd=%d)", fd));
 
-       return close(fd);
+       return system_close(fd);
 }
 
 
@@ -2641,9 +2801,9 @@ jint JVM_SocketClose(jint fd)
 
 jint JVM_SocketShutdown(jint fd, jint howto)
 {
-       TRACEJVMCALLS("JVM_SocketShutdown(fd=%d, howto=%d)", fd, howto);
+       TRACEJVMCALLS(("JVM_SocketShutdown(fd=%d, howto=%d)", fd, howto));
 
-       return shutdown(fd, howto);
+       return system_shutdown(fd, howto);
 }
 
 
@@ -2652,6 +2812,8 @@ jint JVM_SocketShutdown(jint fd, jint howto)
 jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
 {
        log_println("JVM_Recv: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2660,6 +2822,8 @@ jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
 jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
 {
        log_println("JVM_Send: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2668,6 +2832,8 @@ jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
 jint JVM_Timeout(int fd, long timeout)
 {
        log_println("JVM_Timeout: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2675,9 +2841,9 @@ jint JVM_Timeout(int fd, long timeout)
 
 jint JVM_Listen(jint fd, jint count)
 {
-       TRACEJVMCALLS("JVM_Listen(fd=%d, count=%d)", fd, count);
+       TRACEJVMCALLS(("JVM_Listen(fd=%d, count=%d)", fd, count));
 
-       return listen(fd, count);
+       return system_listen(fd, count);
 }
 
 
@@ -2685,9 +2851,9 @@ jint JVM_Listen(jint fd, jint count)
 
 jint JVM_Connect(jint fd, struct sockaddr *him, jint len)
 {
-       TRACEJVMCALLS("JVM_Connect(fd=%d, him=%p, len=%d)", fd, him, len);
+       TRACEJVMCALLS(("JVM_Connect(fd=%d, him=%p, len=%d)", fd, him, len));
 
-       return connect(fd, him, len);
+       return system_connect(fd, him, len);
 }
 
 
@@ -2696,6 +2862,8 @@ jint JVM_Connect(jint fd, struct sockaddr *him, jint len)
 jint JVM_Bind(jint fd, struct sockaddr *him, jint len)
 {
        log_println("JVM_Bind: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2703,9 +2871,9 @@ jint JVM_Bind(jint fd, struct sockaddr *him, jint len)
 
 jint JVM_Accept(jint fd, struct sockaddr *him, jint *len)
 {
-       TRACEJVMCALLS("JVM_Accept(fd=%d, him=%p, len=%p)", fd, him, len);
+       TRACEJVMCALLS(("JVM_Accept(fd=%d, him=%p, len=%p)", fd, him, len));
 
-       return accept(fd, him, (socklen_t *) len);
+       return system_accept(fd, him, (socklen_t *) len);
 }
 
 
@@ -2714,6 +2882,8 @@ jint JVM_Accept(jint fd, struct sockaddr *him, jint *len)
 jint JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen)
 {
        log_println("JVM_RecvFrom: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2721,9 +2891,9 @@ jint JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *fr
 
 jint JVM_GetSockName(jint fd, struct sockaddr *him, int *len)
 {
-       TRACEJVMCALLS("JVM_GetSockName(fd=%d, him=%p, len=%p)", fd, him, len);
+       TRACEJVMCALLS(("JVM_GetSockName(fd=%d, him=%p, len=%p)", fd, him, len));
 
-       return getsockname(fd, him, (socklen_t *) len);
+       return system_getsockname(fd, him, (socklen_t *) len);
 }
 
 
@@ -2732,6 +2902,8 @@ jint JVM_GetSockName(jint fd, struct sockaddr *him, int *len)
 jint JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int tolen)
 {
        log_println("JVM_SendTo: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2741,12 +2913,15 @@ jint JVM_SocketAvailable(jint fd, jint *pbytes)
 {
 #if defined(FIONREAD)
        int bytes;
+       int result;
 
-       TRACEJVMCALLS("JVM_SocketAvailable(fd=%d, pbytes=%p)", fd, pbytes);
+       TRACEJVMCALLS(("JVM_SocketAvailable(fd=%d, pbytes=%p)", fd, pbytes));
 
        *pbytes = 0;
 
-       if (ioctl(fd, FIONREAD, &bytes) < 0)
+       result = ioctl(fd, FIONREAD, &bytes);
+
+       if (result < 0)
                return 0;
 
        *pbytes = bytes;
@@ -2762,13 +2937,9 @@ jint JVM_SocketAvailable(jint fd, jint *pbytes)
 
 jint JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen)
 {
-#if defined(HAVE_GETSOCKOPT)
-       TRACEJVMCALLS("JVM_GetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%p)", fd, level, optname, optval, optlen);
+       TRACEJVMCALLS(("JVM_GetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%p)", fd, level, optname, optval, optlen));
 
-       return getsockopt(fd, level, optname, optval, (socklen_t *) optlen);
-#else
-# error getsockopt not available
-#endif
+       return system_getsockopt(fd, level, optname, optval, (socklen_t *) optlen);
 }
 
 
@@ -2776,47 +2947,55 @@ jint JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen)
 
 jint JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen)
 {
-#if defined(HAVE_SETSOCKOPT)
-       TRACEJVMCALLS("JVM_SetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%d)", fd, level, optname, optval, optlen);
+       TRACEJVMCALLS(("JVM_SetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%d)", fd, level, optname, optval, optlen));
 
-       return setsockopt(fd, level, optname, optval, optlen);
-#else
-# error setsockopt not available
-#endif
+       return system_setsockopt(fd, level, optname, optval, optlen);
 }
 
 
 /* JVM_GetHostName */
 
-int JVM_GetHostName(charname, int namelen)
+int JVM_GetHostName(char *name, int namelen)
 {
-       TRACEJVMCALLS("JVM_GetHostName(name=%s, namelen=%d)", name, namelen);
+       int result;
+
+       TRACEJVMCALLSENTER(("JVM_GetHostName(name=%s, namelen=%d)", name, namelen));
+
+       result = system_gethostname(name, namelen);
+
+       TRACEJVMCALLSEXIT(("->%d (name=%s)", result, name));
 
-       return gethostname(name, namelen);
+       return result;
 }
 
 
 /* JVM_GetHostByAddr */
 
-struct hostentJVM_GetHostByAddr(const char* name, int len, int type)
+struct hostent *JVM_GetHostByAddr(const char* name, int len, int type)
 {
        log_println("JVM_GetHostByAddr: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetHostByName */
 
-struct hostentJVM_GetHostByName(char* name)
+struct hostent *JVM_GetHostByName(char* name)
 {
        log_println("JVM_GetHostByName: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetProtoByName */
 
-struct protoentJVM_GetProtoByName(char* name)
+struct protoent *JVM_GetProtoByName(char* name)
 {
        log_println("JVM_GetProtoByName: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2824,13 +3003,18 @@ struct protoent* JVM_GetProtoByName(char* name)
 
 void *JVM_LoadLibrary(const char *name)
 {
-       utf *u;
+       utf*  u;
+       void* handle;
 
-       TRACEJVMCALLS("JVM_LoadLibrary(name=%s)", name);
+       TRACEJVMCALLSENTER(("JVM_LoadLibrary(name=%s)", name));
 
        u = utf_new_char(name);
 
-       return native_library_open(u);
+       handle = native_library_open(u);
+
+       TRACEJVMCALLSEXIT(("->%p", handle));
+
+       return handle;
 }
 
 
@@ -2838,7 +3022,9 @@ void *JVM_LoadLibrary(const char *name)
 
 void JVM_UnloadLibrary(void* handle)
 {
-       log_println("JVM_UnloadLibrary: IMPLEMENT ME!");
+       TRACEJVMCALLS(("JVM_UnloadLibrary(handle=%p)", handle));
+
+       native_library_close(handle);
 }
 
 
@@ -2848,10 +3034,12 @@ void *JVM_FindLibraryEntry(void *handle, const char *name)
 {
        lt_ptr symbol;
 
-       TRACEJVMCALLS("JVM_FindLibraryEntry(handle=%p, name=%s)", handle, name);
+       TRACEJVMCALLSENTER(("JVM_FindLibraryEntry(handle=%p, name=%s)", handle, name));
 
        symbol = lt_dlsym(handle, name);
 
+       TRACEJVMCALLSEXIT(("->%p", symbol));
+
        return symbol;
 }
 
@@ -2861,6 +3049,8 @@ void *JVM_FindLibraryEntry(void *handle, const char *name)
 jboolean JVM_IsNaN(jdouble a)
 {
        log_println("JVM_IsNaN: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2868,7 +3058,7 @@ jboolean JVM_IsNaN(jdouble a)
 
 jboolean JVM_IsSupportedJNIVersion(jint version)
 {
-       TRACEJVMCALLS("JVM_IsSupportedJNIVersion(version=%d)", version);
+       TRACEJVMCALLS(("JVM_IsSupportedJNIVersion(version=%d)", version));
 
        return jni_version_check(version);
 }
@@ -2878,7 +3068,7 @@ jboolean JVM_IsSupportedJNIVersion(jint version)
 
 jstring JVM_InternString(JNIEnv *env, jstring str)
 {
-       TRACEJVMCALLS("JVM_InternString(env=%p, str=%p)", env, str);
+       TRACEJVMCALLS(("JVM_InternString(env=%p, str=%p)", env, str));
 
        return (jstring) javastring_intern((java_handle_t *) str);
 }
@@ -2890,9 +3080,7 @@ JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void)
 {
        java_object_t *o;
 
-#if PRINTJVM
-       log_println("JVM_RawMonitorCreate");
-#endif
+       TRACEJVMCALLS(("JVM_RawMonitorCreate()"));
 
        o = NEW(java_object_t);
 
@@ -2906,9 +3094,8 @@ JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void)
 
 JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon)
 {
-#if PRINTJVM
-       log_println("JVM_RawMonitorDestroy: mon=%p", mon);
-#endif
+       TRACEJVMCALLS(("JVM_RawMonitorDestroy(mon=%p)", mon));
+
        FREE(mon, java_object_t);
 }
 
@@ -2917,9 +3104,8 @@ JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon)
 
 JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon)
 {
-#if PRINTJVM
-       log_println("JVM_RawMonitorEnter: mon=%p", mon);
-#endif
+       TRACEJVMCALLS(("JVM_RawMonitorEnter(mon=%p)", mon));
+
        (void) lock_monitor_enter((java_object_t *) mon);
 
        return 0;
@@ -2930,9 +3116,8 @@ JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon)
 
 JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon)
 {
-#if PRINTJVM
-       log_println("JVM_RawMonitorExit: mon=%p", mon);
-#endif
+       TRACEJVMCALLS(("JVM_RawMonitorExit(mon=%p)", mon));
+
        (void) lock_monitor_exit((java_object_t *) mon);
 }
 
@@ -2958,6 +3143,8 @@ void JVM_GetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, jlongArray
 jboolean JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get)
 {
        log_println("JVM_AccessVMBooleanFlag: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2966,6 +3153,8 @@ jboolean JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_
 jboolean JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get)
 {
        log_println("JVM_AccessVMIntFlag: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2982,6 +3171,8 @@ void JVM_VMBreakPoint(JNIEnv *env, jobject obj)
 jobjectArray JVM_GetClassFields(JNIEnv *env, jclass cls, jint which)
 {
        log_println("JVM_GetClassFields: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2990,6 +3181,8 @@ jobjectArray JVM_GetClassFields(JNIEnv *env, jclass cls, jint which)
 jobjectArray JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which)
 {
        log_println("JVM_GetClassMethods: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2998,6 +3191,8 @@ jobjectArray JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which)
 jobjectArray JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which)
 {
        log_println("JVM_GetClassConstructors: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -3006,6 +3201,8 @@ jobjectArray JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which)
 jobject JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which)
 {
        log_println("JVM_GetClassField: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -3014,6 +3211,8 @@ jobject JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which)
 jobject JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types, jint which)
 {
        log_println("JVM_GetClassMethod: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -3022,6 +3221,8 @@ jobject JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray t
 jobject JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jint which)
 {
        log_println("JVM_GetClassConstructor: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -3030,6 +3231,8 @@ jobject JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jin
 jobject JVM_NewInstance(JNIEnv *env, jclass cls)
 {
        log_println("JVM_NewInstance: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -3038,6 +3241,8 @@ jobject JVM_NewInstance(JNIEnv *env, jclass cls)
 jobject JVM_GetField(JNIEnv *env, jobject field, jobject obj)
 {
        log_println("JVM_GetField: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -3045,7 +3250,13 @@ jobject JVM_GetField(JNIEnv *env, jobject field, jobject obj)
 
 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;
 }
 
 
@@ -3069,21 +3280,53 @@ void JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v, un
 
 jobject JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)
 {
-#if PRINTJVM
-       log_println("JVM_InvokeMethod: method=%p, obj=%p, args0=%p", method, obj, args0);
-#endif
-       return (jobject) _Jv_java_lang_reflect_Method_invoke((java_lang_reflect_Method *) method, (java_lang_Object *) obj, (java_handle_objectarray_t *) 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 c, jobjectArray args0)
+jobject JVM_NewInstanceFromConstructor(JNIEnv *env, jobject con, jobjectArray args0)
 {
-#if PRINTJVM
-       log_println("JVM_NewInstanceFromConstructor: c=%p, args0=%p", c, args0);
-#endif
-       return (jobject) _Jv_java_lang_reflect_Constructor_newInstance(env, (java_lang_reflect_Constructor *) c, (java_handle_objectarray_t *) 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;
 }
 
 
@@ -3091,7 +3334,7 @@ jobject JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args
 
 jboolean JVM_SupportsCX8()
 {
-       TRACEJVMCALLS("JVM_SupportsCX8()");
+       TRACEJVMCALLS(("JVM_SupportsCX8()"));
 
        /* IMPLEMENT ME */
 
@@ -3104,6 +3347,8 @@ jboolean JVM_SupportsCX8()
 jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlong newVal)
 {
        log_println("JVM_CX8Field: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -3112,6 +3357,8 @@ jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlon
 jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 {
        log_println("JVM_GetAllThreads: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -3120,14 +3367,20 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)
 {
        log_println("JVM_DumpThreads: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetManagement */
 
-voidJVM_GetManagement(jint version)
+void *JVM_GetManagement(jint version)
 {
-       log_println("JVM_GetManagement: IMPLEMENT ME!");
+       TRACEJVMCALLS(("JVM_GetManagement(version=%d)", version));
+
+       /* TODO We current don't support the management interface. */
+
+       return NULL;
 }
 
 
@@ -3136,6 +3389,8 @@ void* JVM_GetManagement(jint version)
 jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties)
 {
        log_println("JVM_InitAgentProperties: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -3143,7 +3398,32 @@ jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties)
 
 jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
 {
-       log_println("JVM_GetEnclosingMethodInfo: IMPLEMENT ME!");
+       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(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;
 }
 
 
@@ -3153,8 +3433,8 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
 {
        java_handle_intarray_t *ia;
 
-       TRACEJVMCALLS("JVM_GetThreadStateValues(env=%p, javaThreadState=%d)",
-                                 env, javaThreadState);
+       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
@@ -3241,8 +3521,8 @@ jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArra
        java_handle_objectarray_t *oa;
        java_object_t             *s;
 
-       TRACEJVMCALLS("JVM_GetThreadStateNames(env=%p, javaThreadState=%d, values=%p)",
-                                 env, javaThreadState, values);
+       TRACEJVMCALLS(("JVM_GetThreadStateNames(env=%p, javaThreadState=%d, values=%p)",
+                                 env, javaThreadState, values));
 
        ia = (java_handle_intarray_t *) values;
 
@@ -3374,7 +3654,7 @@ void *JVM_RegisterSignal(jint sig, void *handler)
 {
        functionptr newHandler;
 
-       TRACEJVMCALLS("JVM_RegisterSignal(sig=%d, handler=%p)", sig, handler);
+       TRACEJVMCALLS(("JVM_RegisterSignal(sig=%d, handler=%p)", sig, handler));
 
        if (handler == (void *) 2)
                newHandler = (functionptr) signal_thread_handler;
@@ -3416,6 +3696,7 @@ void *JVM_RegisterSignal(jint sig, void *handler)
 jboolean JVM_RaiseSignal(jint sig)
 {
        log_println("JVM_RaiseSignal: IMPLEMENT ME! sig=%s", sig);
+
        return false;
 }
 
@@ -3424,7 +3705,7 @@ jboolean JVM_RaiseSignal(jint sig)
 
 jint JVM_FindSignal(const char *name)
 {
-       TRACEJVMCALLS("JVM_FindSignal(name=%s)", name);
+       TRACEJVMCALLS(("JVM_FindSignal(name=%s)", name));
 
 #if defined(__LINUX__)
        if (strcmp(name, "HUP") == 0)
index ae23a95e913c1c2310ba1fd90e33bd2c7f4efac7..34192a356a6c72ea9d60ad1becaf320bb433fc43 100644 (file)
@@ -1,9 +1,7 @@
 /* src/native/vm/sun_misc_Unsafe.c - sun/misc/Unsafe
 
-   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.
 
@@ -30,6 +28,8 @@
 #include <stdint.h>
 #include <unistd.h>
 
+#include "machine-instr.h"
+
 #include "mm/memory.h"
 
 #include "native/jni.h"
 #include "native/include/java_lang_Thread.h"             /* required by s.m.U */
 #include "native/include/java_lang_Throwable.h"
 
+#if defined(WITH_CLASSPATH_GNU)
+# 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"
@@ -58,6 +62,7 @@
 #include "vm/initialize.h"
 #include "vm/stringlocal.h"
 
+#include "vmcore/system.h"
 #include "vmcore/utf8.h"
 
 
@@ -87,6 +92,8 @@ static JNINativeMethod methods[] = {
        { "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                     },
@@ -94,7 +101,14 @@ static JNINativeMethod methods[] = {
        { "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                },
@@ -110,8 +124,14 @@ static JNINativeMethod methods[] = {
        { "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                           },
 };
@@ -509,6 +529,39 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__JS(JNIEnv *env, sun_misc_U
 }
 
 
+/*
+ * 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
@@ -604,10 +657,26 @@ JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, su
        fieldinfo *f;
        int32_t    slot;
 
+#if defined(WITH_CLASSPATH_GNU)
+       java_lang_reflect_VMField *rvmf;
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+
+       LLNI_field_get_ref(field, f,     rvmf);
+       LLNI_field_get_cls(rvmf,  clazz, c);
+       LLNI_field_get_val(rvmf,  slot , slot);
+
+#elif defined(WITH_CLASSPATH_SUN)
+
        LLNI_field_get_cls(field, clazz, c);
        LLNI_field_get_val(field, slot , slot);
 
-       f = &c->fields[slot];
+#else
+# error unknown configuration
+#endif
+
+       f = &(c->fields[slot]);
 
        return (int64_t) f->offset;
 }
@@ -636,6 +705,9 @@ JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_m
 }
 
 
+#if 0
+/* OpenJDK 7 */
+
 /*
  * Class:     sun/misc/Unsafe
  * Method:    setMemory
@@ -659,8 +731,91 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, sun_misc_Unsa
 
        /* XXX Not sure this is correct. */
 
-       MSET(p, value, uint8_t, length);
+       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
 
 
 /*
@@ -707,9 +862,25 @@ JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv
        fieldinfo *f;
        int32_t    slot;
 
+#if defined(WITH_CLASSPATH_GNU)
+       java_lang_reflect_VMField *rvmf;
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+
+       LLNI_field_get_ref(rf,   f,     rvmf);
+       LLNI_field_get_cls(rvmf, clazz, c);
+       LLNI_field_get_val(rvmf, slot , slot);
+
+#elif defined(WITH_CLASSPATH_SUN)
+
        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);
@@ -811,7 +982,7 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_pageSize(JNIEnv *env, sun_misc_Un
  */
 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     *cl;
+       classloader_t   *cl;
        utf             *utfname;
        classinfo       *c;
        java_lang_Class *o;
@@ -843,8 +1014,8 @@ JNIEXPORT java_lang_Class* JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_
 
        /* define the class */
 
-       c = class_define(utfname, cl, len, (const uint8_t *) &(LLNI_array_direct(b, off)),
-                                        protectionDomain);
+       c = class_define(utfname, cl, len, (uint8_t *) &(LLNI_array_direct(b, off)),
+                                        (java_handle_t *) protectionDomain);
 
        if (c == NULL)
                return NULL;
@@ -903,6 +1074,7 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc
  */
 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;
 
@@ -919,6 +1091,21 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env,
        }
 
        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
 }
 
 
@@ -927,24 +1114,40 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env,
  * 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* obj, int64_t offset, int32_t expect, int32_t update)
+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 *) obj) + offset);
+       p = (int32_t *) (((uint8_t *) o) + offset);
 
        /* XXX this should be atomic */
 
        value = *p;
 
-       if (value == expect) {
-               *p = update;
+       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
 }
 
 
@@ -992,6 +1195,60 @@ JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEn
 }
 
 
+/*
+ * 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
@@ -999,14 +1256,18 @@ JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEn
  */
 JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
 {
-       volatile int32_t *p;
-       volatile int32_t  value;
-
-       p = (volatile int32_t *) (((uint8_t *) o) + offset);
+       UNSAFE_GET_VOLATILE(int32_t);
+}
 
-       value = *p;
 
-       return value;
+/*
+ * 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);
 }
 
 
@@ -1017,14 +1278,70 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_m
  */
 JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLongVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
 {
-       volatile int64_t *p;
-       volatile int64_t  value;
+       UNSAFE_GET_VOLATILE(int64_t);
+}
 
-       p = (volatile int64_t *) (((uint8_t *) o) + offset);
 
-       value = *p;
+/*
+ * 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);
+}
 
-       return value;
+
+/*
+ * 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);
 }
 
 
index 9ef68cfb57debb621b491f136d0fc1fa487e196d..b6cf86dd5bdfc94439964c1c0c7c11cd74faf3aa 100644 (file)
@@ -1,9 +1,7 @@
 ## src/threads/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,24 +26,40 @@ AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top
 LIB =
 
 DIST_SUBDIRS = \
-       native \
-       none
+       none \
+       posix
+
+if ENABLE_THREADS
+SUBDIRS = \
+       posix
 
+THREAD_LIB = \
+       posix/libthreadsposix.la
+else
 SUBDIRS = \
-       native
+       none
 
 THREAD_LIB = \
-       native/libthreadsposix.la
+       none/libthreadsnone.la
+endif
+
 
 noinst_LTLIBRARIES = \
        libthreads.la
 
+if ENABLE_THREADS
 libthreads_la_SOURCES = \
        critical.c \
        critical.h \
        lock-common.h \
-       threads-common.c \
-       threads-common.h
+       mutex.h \
+       threadlist.c \
+       threadlist.h \
+       thread.c \
+       thread.h
+else
+libthreads_la_SOURCES =
+endif
 
 libthreads_la_LIBADD = \
        $(THREAD_LIB)
index 5ff4ae2e406e9dff358fc9277fb2ed268bcedcf5..7bb2917c396620aa4fbdf074f5fb465b002ebc3f 100644 (file)
@@ -50,9 +50,6 @@ typedef struct critical_section_node_t critical_section_node_t;
 
    A node representing a restartable critical section.
 
-   CAUTION: This order must not be changed, it is used in
-            asm_criticalsections!
-
 *******************************************************************************/
 
 struct critical_section_node_t {
index 8d7edb6772aa8b136baba098df537668d13ef4de..1bc3cdc2b5113aff49b579879a552f15544f0bfc 100644 (file)
@@ -1,9 +1,7 @@
 /* src/threads/lock-common.h - common stuff of lock implementation
 
-   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.
 
@@ -34,7 +32,7 @@
 #include "vm/global.h"
 
 #if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
+# include "threads/posix/lock.h"
 #else
 # include "threads/none/lock.h"
 #endif
diff --git a/src/threads/mutex.h b/src/threads/mutex.h
new file mode 100644 (file)
index 0000000..7458b0d
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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/native/Makefile.am b/src/threads/native/Makefile.am
deleted file mode 100644 (file)
index abc3419..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-## src/threads/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
-##
-## This file is part of CACAO.
-##
-## This program is free software; you can redistribute it and/or
-## modify it under the terms of the GNU General Public License as
-## published by the Free Software Foundation; either version 2, or (at
-## your option) any later version.
-##
-## This program is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public 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) -I$(top_builddir)/src -I$(top_srcdir)/contrib/vmlog
-
-LIBS =
-
-noinst_LTLIBRARIES = \
-       libthreadsposix.la
-
-libthreadsposix_la_SOURCES = \
-       lock.c \
-       lock.h \
-       threads.c \
-       threads.h
-
-
-## 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/threads/native/generic-primitives.h b/src/threads/native/generic-primitives.h
deleted file mode 100644 (file)
index 312e380..0000000
+++ /dev/null
@@ -1,97 +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>
-
-extern pthread_mutex_t _atomic_add_lock;
-extern pthread_mutex_t _cas_lock;
-extern pthread_mutex_t _mb_lock;
-
-
-static inline void atomic_add(volatile int *mem, int val)
-{
-  pthread_mutex_lock(&_atomic_add_lock);
-
-  /* do the atomic add */
-  *mem += val;
-
-  pthread_mutex_unlock(&_atomic_add_lock);
-}
-
-
-static inline long compare_and_swap(volatile long *p, long oldval, long newval)
-{
-  long ret;
-
-  pthread_mutex_lock(&_cas_lock);
-
-  /* do the compare-and-swap */
-
-  ret = *p;
-
-  if (oldval == ret)
-    *p = newval;
-
-  pthread_mutex_unlock(&_cas_lock);
-
-  return ret;
-}
-
-
-#define MEMORY_BARRIER()                  (pthread_mutex_lock(&_mb_lock), \
-                                           pthread_mutex_unlock(&_mb_lock))
-#define STORE_ORDER_BARRIER()             MEMORY_BARRIER()
-#define MEMORY_BARRIER_BEFORE_ATOMIC()    /* nothing */
-#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:
- */
diff --git a/src/threads/native/lock.c b/src/threads/native/lock.c
deleted file mode 100644 (file)
index 8d23913..0000000
+++ /dev/null
@@ -1,1568 +0,0 @@
-/* src/threads/native/lock.c - lock 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
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public 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 <stdlib.h>
-#include <sys/time.h>
-#include <pthread.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "threads/lock-common.h"
-
-#include "threads/native/lock.h"
-#include "threads/native/threads.h"
-
-#include "toolbox/list.h"
-
-#include "vm/global.h"
-#include "vm/exceptions.h"
-#include "vm/finalizer.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vmcore/options.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#if defined(ENABLE_VMLOG)
-#include <vmlog_cacao.h>
-#endif
-
-/* arch.h must be here because it defines USE_FAKE_ATOMIC_INSTRUCTIONS */
-
-#include "arch.h"
-
-/* includes for atomic instructions: */
-
-#if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
-#include "threads/native/generic-primitives.h"
-#else
-#include "machine-instr.h"
-#endif
-
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/cacaodbg.h"
-#endif
-
-#if defined(ENABLE_GC_BOEHM)
-# include "mm/boehm-gc/include/gc.h"
-#endif
-
-
-/* debug **********************************************************************/
-
-#if !defined(NDEBUG)
-# define DEBUGLOCKS(format) \
-    do { \
-        if (opt_DebugLocks) { \
-            log_println format; \
-        } \
-    } while (0)
-#else
-# define DEBUGLOCKS(format)
-#endif
-
-
-/******************************************************************************/
-/* MACROS                                                                     */
-/******************************************************************************/
-
-/* number of lock records in the first pool allocated for a thread */
-#define LOCK_INITIAL_LOCK_RECORDS 8
-
-#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 THE FLAT LOCK CONTENTION BIT                                    */
-/******************************************************************************/
-
-#define LOCK_SET_FLC_BIT(obj)    ((obj)->hdrflags |= HDRFLAG_FLC)
-#define LOCK_CLEAR_FLC_BIT(obj)  ((obj)->hdrflags &= ~ HDRFLAG_FLC)
-#define LOCK_TEST_FLC_BIT(obj)   ((obj)->hdrflags & HDRFLAG_FLC)
-
-
-/******************************************************************************/
-/* MACROS FOR THIN/FAT LOCKS                                                  */
-/******************************************************************************/
-
-/* We use a variant of the tasuki locks described in the paper
- *     
- *     Tamiya Onodera, Kiyokuni Kawachiya
- *     A Study of Locking Objects with Bimodal Fields
- *     Proceedings of the ACM OOPSLA '99, pp. 223-237
- *     1999
- *
- * The underlying thin locks are a variant of the thin locks described in
- * 
- *     Bacon, Konuru, Murthy, Serrano
- *     Thin Locks: Featherweight Synchronization for Java
- *        Proceedings of the ACM Conference on Programming Language Design and 
- *        Implementation (Montreal, Canada), SIGPLAN Notices volume 33, number 6,
- *        June 1998
- *
- * In thin lock mode the lockword looks like this:
- *
- *     ,----------------------,-----------,---,
- *     |      thread ID       |   count   | 0 |
- *     `----------------------'-----------'---´
- *
- *     thread ID......the 'index' of the owning thread, or 0
- *     count..........number of times the lock has been entered        minus 1
- *     0..............the shape bit is 0 in thin lock mode
- *
- * In fat lock mode it is basically a lock_record_t *:
- *
- *     ,----------------------------------,---,
- *     |    lock_record_t * (without LSB) | 1 |
- *     `----------------------------------'---´
- *
- *     1..............the shape bit is 1 in fat lock mode
- */
-
-#if SIZEOF_VOID_P == 8
-#define THIN_LOCK_WORD_SIZE    64
-#else
-#define THIN_LOCK_WORD_SIZE    32
-#endif
-
-#define THIN_LOCK_SHAPE_BIT    0x01
-
-#define THIN_UNLOCKED          0
-
-#define THIN_LOCK_COUNT_SHIFT  1
-#define THIN_LOCK_COUNT_SIZE   8
-#define THIN_LOCK_COUNT_INCR   (1 << THIN_LOCK_COUNT_SHIFT)
-#define THIN_LOCK_COUNT_MAX    ((1 << THIN_LOCK_COUNT_SIZE) - 1)
-#define THIN_LOCK_COUNT_MASK   (THIN_LOCK_COUNT_MAX << THIN_LOCK_COUNT_SHIFT)
-
-#define THIN_LOCK_TID_SHIFT    (THIN_LOCK_COUNT_SIZE + THIN_LOCK_COUNT_SHIFT)
-#define THIN_LOCK_TID_SIZE     (THIN_LOCK_WORD_SIZE - THIN_LOCK_TID_SHIFT)
-
-#define IS_THIN_LOCK(lockword)  (!((lockword) & THIN_LOCK_SHAPE_BIT))
-#define IS_FAT_LOCK(lockword)     ((lockword) & THIN_LOCK_SHAPE_BIT)
-
-#define GET_FAT_LOCK(lockword)  ((lock_record_t *) ((lockword) & ~THIN_LOCK_SHAPE_BIT))
-#define MAKE_FAT_LOCK(ptr)      ((uintptr_t) (ptr) | THIN_LOCK_SHAPE_BIT)
-
-#define LOCK_WORD_WITHOUT_COUNT(lockword) ((lockword) & ~THIN_LOCK_COUNT_MASK)
-
-
-/* global variables ***********************************************************/
-
-/* hashtable mapping objects to lock records */
-static lock_hashtable_t lock_hashtable;
-
-
-/******************************************************************************/
-/* PROTOTYPES                                                                 */
-/******************************************************************************/
-
-static void lock_hashtable_init(void);
-
-static inline uintptr_t lock_lockword_get(threadobject *t, java_handle_t *o);
-static inline void lock_lockword_set(threadobject *t, java_handle_t *o, uintptr_t lockword);
-static void lock_record_enter(threadobject *t, lock_record_t *lr);
-static void lock_record_exit(threadobject *t, lock_record_t *lr);
-static bool lock_record_wait(threadobject *t, lock_record_t *lr, s8 millis, s4 nanos);
-static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one);
-
-
-/*============================================================================*/
-/* INITIALIZATION OF DATA STRUCTURES                                          */
-/*============================================================================*/
-
-
-/* lock_init *******************************************************************
-
-   Initialize global data for locking.
-
-*******************************************************************************/
-
-void lock_init(void)
-{
-       /* initialize lock hashtable */
-
-       lock_hashtable_init();
-
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_init_lock();
-#endif
-}
-
-
-/* lock_pre_compute_thinlock ***************************************************
-
-   Pre-compute the thin lock value for a thread index.
-
-   IN:
-      index........the thead index (>= 1)
-
-   RETURN VALUE:
-      the thin lock value for this thread index
-
-*******************************************************************************/
-
-ptrint lock_pre_compute_thinlock(s4 index)
-{
-       return (index << THIN_LOCK_TID_SHIFT) | THIN_UNLOCKED;
-}
-
-
-/* lock_record_new *************************************************************
-
-   Allocate a lock record.
-
-*******************************************************************************/
-
-static lock_record_t *lock_record_new(void)
-{
-       lock_record_t *lr;
-
-       /* allocate the data structure on the C heap */
-
-       lr = NEW(lock_record_t);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_lock_record += sizeof(lock_record_t);
-#endif
-
-       /* initialize the members */
-
-       lr->object  = NULL;
-       lr->owner   = NULL;
-       lr->count   = 0;
-       lr->waiters = list_create(OFFSET(lock_waiter_t, linkage));
-
-#if defined(ENABLE_GC_CACAO)
-       /* register the lock object as weak reference with the GC */
-
-       gc_weakreference_register(&(lr->object), GC_REFTYPE_LOCKRECORD);
-#endif
-
-       /* initialize the mutex */
-
-       pthread_mutex_init(&(lr->mutex), NULL);
-
-       DEBUGLOCKS(("[lock_record_new   : lr=%p]", (void *) lr));
-
-       return lr;
-}
-
-
-/* lock_record_free ************************************************************
-
-   Free a lock record.
-
-   IN:
-       lr....lock record to free
-
-*******************************************************************************/
-
-static void lock_record_free(lock_record_t *lr)
-{
-       DEBUGLOCKS(("[lock_record_free  : lr=%p]", (void *) lr));
-
-       /* Destroy the mutex. */
-
-       pthread_mutex_destroy(&(lr->mutex));
-
-#if defined(ENABLE_GC_CACAO)
-       /* unregister the lock object reference with the GC */
-
-       gc_weakreference_unregister(&(lr->object));
-#endif
-
-       /* Free the waiters list. */
-
-       list_free(lr->waiters);
-
-       /* Free the data structure. */
-
-       FREE(lr, lock_record_t);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_lock_record -= sizeof(lock_record_t);
-#endif
-}
-
-
-/*============================================================================*/
-/* HASHTABLE MAPPING OBJECTS TO LOCK RECORDS                                  */
-/*============================================================================*/
-
-/* lock_hashtable_init *********************************************************
-
-   Initialize the global hashtable mapping objects to lock records.
-
-*******************************************************************************/
-
-static void lock_hashtable_init(void)
-{
-       pthread_mutex_init(&(lock_hashtable.mutex), NULL);
-
-       lock_hashtable.size    = LOCK_INITIAL_HASHTABLE_SIZE;
-       lock_hashtable.entries = 0;
-       lock_hashtable.ptr     = MNEW(lock_record_t *, lock_hashtable.size);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_lock_hashtable += sizeof(lock_record_t *) * lock_hashtable.size;
-#endif
-
-       MZERO(lock_hashtable.ptr, lock_record_t *, lock_hashtable.size);
-}
-
-
-/* lock_hashtable_grow *********************************************************
-
-   Grow the lock record hashtable to about twice its current size and
-   rehash the entries.
-
-*******************************************************************************/
-
-/* must be called with hashtable mutex locked */
-static void lock_hashtable_grow(void)
-{
-       u4 oldsize;
-       u4 newsize;
-       lock_record_t **oldtable;
-       lock_record_t **newtable;
-       lock_record_t *lr;
-       lock_record_t *next;
-       u4 i;
-       u4 h;
-       u4 newslot;
-
-       /* allocate a new table */
-
-       oldsize = lock_hashtable.size;
-       newsize = oldsize*2 + 1; /* XXX should use prime numbers */
-
-       DEBUGLOCKS(("growing lock hashtable to size %d", newsize));
-
-       oldtable = lock_hashtable.ptr;
-       newtable = MNEW(lock_record_t *, newsize);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_lock_hashtable += sizeof(lock_record_t *) * newsize;
-#endif
-
-       MZERO(newtable, lock_record_t *, newsize);
-
-       /* rehash the entries */
-
-       for (i = 0; i < oldsize; i++) {
-               lr = oldtable[i];
-               while (lr) {
-                       next = lr->hashlink;
-
-                       h = heap_hashcode(lr->object);
-                       newslot = h % newsize;
-
-                       lr->hashlink = newtable[newslot];
-                       newtable[newslot] = lr;
-
-                       lr = next;
-               }
-       }
-
-       /* replace the old table */
-
-       lock_hashtable.ptr  = newtable;
-       lock_hashtable.size = newsize;
-
-       MFREE(oldtable, lock_record_t *, oldsize);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_lock_hashtable -= sizeof(lock_record_t *) * oldsize;
-#endif
-}
-
-
-/* lock_hashtable_cleanup ******************************************************
-
-   Removes (and frees) lock records which have a cleared object reference
-   from the hashtable. The locked object was reclaimed by the GC.
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-void lock_hashtable_cleanup(void)
-{
-       threadobject  *t;
-       lock_record_t *lr;
-       lock_record_t *prev;
-       lock_record_t *next;
-       int i;
-
-       t = THREADOBJECT;
-
-       /* lock the hashtable */
-
-       pthread_mutex_lock(&(lock_hashtable.mutex));
-
-       /* search the hashtable for cleared references */
-
-       for (i = 0; i < lock_hashtable.size; i++) {
-               lr = lock_hashtable.ptr[i];
-               prev = NULL;
-
-               while (lr) {
-                       next = lr->hashlink;
-
-                       /* remove lock records with cleared references */
-
-                       if (lr->object == NULL) {
-
-                               /* unlink the lock record from the hashtable */
-
-                               if (prev == NULL)
-                                       lock_hashtable.ptr[i] = next;
-                               else
-                                       prev->hashlink = next;
-
-                               /* free the lock record */
-
-                               lock_record_free(lr);
-
-                       } else {
-                               prev = lr;
-                       }
-
-                       lr = next;
-               }
-       }
-
-       /* unlock the hashtable */
-
-       pthread_mutex_unlock(&(lock_hashtable.mutex));
-}
-#endif
-
-
-/* lock_hashtable_get **********************************************************
-
-   Find the lock record for the given object.  If it does not exists,
-   yet, create it and enter it in the hashtable.
-
-   IN:
-      t....the current thread
-         o....the object to look up
-
-   RETURN VALUE:
-      the lock record to use for this object
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_BOEHM)
-static void lock_record_finalizer(void *object, void *p);
-#endif
-
-static lock_record_t *lock_hashtable_get(threadobject *t, java_handle_t *o)
-{
-       uintptr_t      lockword;
-       u4             slot;
-       lock_record_t *lr;
-
-       lockword = lock_lockword_get(t, o);
-
-       if (IS_FAT_LOCK(lockword))
-               return GET_FAT_LOCK(lockword);
-
-       /* lock the hashtable */
-
-       pthread_mutex_lock(&(lock_hashtable.mutex));
-
-       /* lookup the lock record in the hashtable */
-
-       LLNI_CRITICAL_START_THREAD(t);
-       slot = heap_hashcode(LLNI_DIRECT(o)) % lock_hashtable.size;
-       lr   = lock_hashtable.ptr[slot];
-
-       for (; lr != NULL; lr = lr->hashlink) {
-               if (lr->object == LLNI_DIRECT(o))
-                       break;
-       }
-       LLNI_CRITICAL_END_THREAD(t);
-
-       if (lr == NULL) {
-               /* not found, we must create a new one */
-
-               lr = lock_record_new();
-
-               LLNI_CRITICAL_START_THREAD(t);
-               lr->object = LLNI_DIRECT(o);
-               LLNI_CRITICAL_END_THREAD(t);
-
-#if defined(ENABLE_GC_BOEHM)
-               /* register new finalizer to clean up the lock record */
-
-               GC_REGISTER_FINALIZER(LLNI_DIRECT(o), lock_record_finalizer, 0, 0, 0);
-#endif
-
-               /* enter it in the hashtable */
-
-               lr->hashlink             = lock_hashtable.ptr[slot];
-               lock_hashtable.ptr[slot] = lr;
-               lock_hashtable.entries++;
-
-               /* check whether the hash should grow */
-
-               if (lock_hashtable.entries * 3 > lock_hashtable.size * 4) {
-                       lock_hashtable_grow();
-               }
-       }
-
-       /* unlock the hashtable */
-
-       pthread_mutex_unlock(&(lock_hashtable.mutex));
-
-       /* return the new lock record */
-
-       return lr;
-}
-
-
-/* lock_hashtable_remove *******************************************************
-
-   Remove the lock record for the given object from the hashtable
-   and free it afterwards.
-
-   IN:
-       t....the current thread
-       o....the object to look up
-
-*******************************************************************************/
-
-static void lock_hashtable_remove(threadobject *t, java_handle_t *o)
-{
-       uintptr_t      lockword;
-       lock_record_t *lr;
-       u4             slot;
-       lock_record_t *tmplr;
-
-       /* lock the hashtable */
-
-       pthread_mutex_lock(&(lock_hashtable.mutex));
-
-       /* get lock record */
-
-       lockword = lock_lockword_get(t, o);
-
-       assert(IS_FAT_LOCK(lockword));
-
-       lr = GET_FAT_LOCK(lockword);
-
-       /* remove the lock-record from the hashtable */
-
-       LLNI_CRITICAL_START_THREAD(t);
-       slot  = heap_hashcode(LLNI_DIRECT(o)) % lock_hashtable.size;
-       tmplr = lock_hashtable.ptr[slot];
-       LLNI_CRITICAL_END_THREAD(t);
-
-       if (tmplr == lr) {
-               /* special handling if it's the first in the chain */
-
-               lock_hashtable.ptr[slot] = lr->hashlink;
-       }
-       else {
-               for (; tmplr != NULL; tmplr = tmplr->hashlink) {
-                       if (tmplr->hashlink == lr) {
-                               tmplr->hashlink = lr->hashlink;
-                               break;
-                       }
-               }
-
-               assert(tmplr != NULL);
-       }
-
-       /* decrease entry count */
-
-       lock_hashtable.entries--;
-
-       /* unlock the hashtable */
-
-       pthread_mutex_unlock(&(lock_hashtable.mutex));
-
-       /* free the lock record */
-
-       lock_record_free(lr);
-}
-
-
-/* lock_record_finalizer *******************************************************
-
-   XXX Remove me for exact GC.
-
-*******************************************************************************/
-
-static void lock_record_finalizer(void *object, void *p)
-{
-       java_handle_t *o;
-       classinfo     *c;
-
-       o = (java_handle_t *) object;
-
-#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_class_get(o, c);
-
-#if !defined(NDEBUG)
-       if (opt_DebugFinalizer) {
-               log_start();
-               log_print("[finalizer lockrecord: o=%p p=%p class=", object, p);
-               class_print(c);
-               log_print("]");
-               log_finish();
-       }
-#endif
-
-       /* check for a finalizer function */
-
-       if (c->finalizer != NULL)
-               finalizer_run(object, p);
-
-       /* remove the lock-record entry from the hashtable and free it */
-
-       lock_hashtable_remove(THREADOBJECT, o);
-}
-
-
-/*============================================================================*/
-/* OBJECT LOCK INITIALIZATION                                                 */
-/*============================================================================*/
-
-
-/* lock_init_object_lock *******************************************************
-
-   Initialize the monitor pointer of the given object. The monitor gets
-   initialized to an unlocked state.
-
-*******************************************************************************/
-
-void lock_init_object_lock(java_object_t *o)
-{
-       assert(o);
-
-       o->lockword = THIN_UNLOCKED;
-       LOCK_CLEAR_FLC_BIT(o);
-}
-
-
-/*============================================================================*/
-/* LOCKING ALGORITHM                                                          */
-/*============================================================================*/
-
-
-/* lock_lockword_get ***********************************************************
-
-   Get the lockword for the given object.
-
-   IN:
-      t............the current thread
-      o............the object
-
-*******************************************************************************/
-
-static inline uintptr_t lock_lockword_get(threadobject *t, java_handle_t *o)
-{
-       uintptr_t lockword;
-
-       LLNI_CRITICAL_START_THREAD(t);
-       lockword = LLNI_DIRECT(o)->lockword;
-       LLNI_CRITICAL_END_THREAD(t);
-
-       return lockword;
-}
-
-
-/* lock_lockword_set ***********************************************************
-
-   Set the lockword for the given object.
-
-   IN:
-      t............the current thread
-      o............the object
-         lockword.....the new lockword value
-
-*******************************************************************************/
-
-static inline void lock_lockword_set(threadobject *t, java_handle_t *o, uintptr_t lockword)
-{
-       LLNI_CRITICAL_START_THREAD(t);
-       LLNI_DIRECT(o)->lockword = lockword;
-       LLNI_CRITICAL_END_THREAD(t);
-}
-
-
-/* lock_record_enter ***********************************************************
-
-   Enter the lock represented by the given lock record.
-
-   IN:
-      t.................the current thread
-         lr................the lock record
-
-*******************************************************************************/
-
-static inline void lock_record_enter(threadobject *t, lock_record_t *lr)
-{
-       pthread_mutex_lock(&(lr->mutex));
-       lr->owner = t;
-}
-
-
-/* lock_record_exit ************************************************************
-
-   Release the lock represented by the given lock record.
-
-   IN:
-      t.................the current thread
-         lr................the lock record
-
-   PRE-CONDITION:
-      The current thread must own the lock represented by this lock record.
-         This is NOT checked by this function!
-
-*******************************************************************************/
-
-static inline void lock_record_exit(threadobject *t, lock_record_t *lr)
-{
-       lr->owner = NULL;
-       pthread_mutex_unlock(&(lr->mutex));
-}
-
-
-/* lock_inflate ****************************************************************
-
-   Inflate the lock of the given object. This may only be called by the
-   owner of the monitor of the object.
-
-   IN:
-      t............the current thread
-         o............the object of which to inflate the lock
-         lr...........the lock record to install. The current thread must
-                      own the lock of this lock record!
-
-   PRE-CONDITION:
-      The current thread must be the owner of this object's monitor AND
-         of the lock record's lock!
-
-*******************************************************************************/
-
-static void lock_inflate(threadobject *t, java_handle_t *o, lock_record_t *lr)
-{
-       uintptr_t lockword;
-
-       /* get the current lock count */
-
-       lockword = lock_lockword_get(t, o);
-
-       if (IS_FAT_LOCK(lockword)) {
-               assert(GET_FAT_LOCK(lockword) == lr);
-       }
-       else {
-               assert(LOCK_WORD_WITHOUT_COUNT(lockword) == t->thinlock);
-
-               /* copy the count from the thin lock */
-
-               lr->count = (lockword & THIN_LOCK_COUNT_MASK) >> THIN_LOCK_COUNT_SHIFT;
-       }
-
-       DEBUGLOCKS(("[lock_inflate      : lr=%p, t=%p, o=%p, o->lockword=%lx, count=%d]",
-                               lr, t, o, lockword, lr->count));
-
-       /* clear flat-lock-contention bit */
-
-       LLNI_CRITICAL_START_THREAD(t);
-       LOCK_CLEAR_FLC_BIT(LLNI_DIRECT(o));
-       LLNI_CRITICAL_END_THREAD(t);
-
-       /* notify waiting objects */
-
-       lock_record_notify(t, lr, false);
-
-       /* install it */
-
-       lock_lockword_set(t, o, MAKE_FAT_LOCK(lr));
-}
-
-
-/* lock_monitor_enter **********************************************************
-
-   Acquire the monitor of the given object. If the current thread already
-   owns the monitor, the lock counter is simply increased.
-
-   This function blocks until it can acquire the monitor.
-
-   IN:
-      t............the current thread
-         o............the object of which to enter the monitor
-
-   RETURN VALUE:
-      true.........the lock has been successfully acquired
-         false........an exception has been thrown
-
-*******************************************************************************/
-
-bool lock_monitor_enter(java_handle_t *o)
-{
-       threadobject  *t;
-       /* CAUTION: This code assumes that ptrint is unsigned! */
-       ptrint         lockword;
-       ptrint         thinlock;
-       lock_record_t *lr;
-
-       if (o == NULL) {
-               exceptions_throw_nullpointerexception();
-               return false;
-       }
-
-       t = THREADOBJECT;
-
-       thinlock = t->thinlock;
-
-       /* 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);
-       LLNI_CRITICAL_END_THREAD(t);
-
-       if (lockword == THIN_UNLOCKED) {
-               /* success. we locked it */
-               /* The Java Memory Model requires a memory barrier here: */
-               MEMORY_BARRIER();
-               return true;
-       }
-
-       /* next common case: recursive lock with small recursion count */
-       /* We don't have to worry about stale values here, as any stale value  */
-       /* will indicate another thread holding the lock (or an inflated lock) */
-
-       if (LOCK_WORD_WITHOUT_COUNT(lockword) == thinlock) {
-               /* we own this monitor               */
-               /* check the current recursion count */
-
-               if ((lockword ^ thinlock) < (THIN_LOCK_COUNT_MAX << THIN_LOCK_COUNT_SHIFT))
-               {
-                       /* the recursion count is low enough */
-
-                       lock_lockword_set(t, o, lockword + THIN_LOCK_COUNT_INCR);
-
-                       /* success. we locked it */
-                       return true;
-               }
-               else {
-                       /* recursion count overflow */
-
-                       lr = lock_hashtable_get(t, o);
-                       lock_record_enter(t, lr);
-                       lock_inflate(t, o, lr);
-                       lr->count++;
-
-                       return true;
-               }
-       }
-
-       /* the lock is either contented or fat */
-
-       if (IS_FAT_LOCK(lockword)) {
-
-               lr = GET_FAT_LOCK(lockword);
-
-               /* check for recursive entering */
-               if (lr->owner == t) {
-                       lr->count++;
-                       return true;
-               }
-
-               /* acquire the mutex of the lock record */
-
-               lock_record_enter(t, lr);
-
-               assert(lr->count == 0);
-
-               return true;
-       }
-
-       /****** inflation path ******/
-
-       /* first obtain the lock record for this object */
-
-       lr = lock_hashtable_get(t, o);
-
-#if defined(ENABLE_JVMTI)
-       /* Monitor Contended Enter */
-       jvmti_MonitorContendedEntering(false, o);
-#endif
-
-       /* enter the monitor */
-
-       lock_record_enter(t, lr);
-
-#if defined(ENABLE_JVMTI)
-       /* Monitor Contended Entered */
-       jvmti_MonitorContendedEntering(true, o);
-#endif
-
-       /* inflation loop */
-
-       while (IS_THIN_LOCK(lockword = lock_lockword_get(t, o))) {
-               /* Set the flat lock contention bit to let the owning thread
-                  know that we want to be notified of unlocking. */
-
-               LLNI_CRITICAL_START_THREAD(t);
-               LOCK_SET_FLC_BIT(LLNI_DIRECT(o));
-               LLNI_CRITICAL_END_THREAD(t);
-
-               DEBUGLOCKS(("thread %d set flc bit on %p lr %p",
-                                       t->index, (void*) o, (void*) lr));
-
-               /* try to lock the object */
-
-               LLNI_CRITICAL_START_THREAD(t);
-               lockword = COMPARE_AND_SWAP_OLD_VALUE(&(LLNI_DIRECT(o)->lockword), THIN_UNLOCKED, thinlock);
-               LLNI_CRITICAL_END_THREAD(t);
-
-               if (lockword == THIN_UNLOCKED) {
-                       /* we can inflate the lock ourselves */
-
-                       DEBUGLOCKS(("thread %d inflating lock of %p to lr %p",
-                                               t->index, (void*) o, (void*) lr));
-
-                       lock_inflate(t, o, lr);
-               }
-               else {
-                       /* Wait until another thread sees the flc bit and notifies
-                          us of unlocking. */
-
-                       (void) lock_record_wait(t, lr, 0, 0);
-               }
-       }
-
-       /* we own the inflated lock now */
-
-       return true;
-}
-
-
-/* lock_monitor_exit ***********************************************************
-
-   Decrement the counter of a (currently owned) monitor. If the counter
-   reaches zero, release the monitor.
-
-   If the current thread is not the owner of the monitor, an 
-   IllegalMonitorState exception is thrown.
-
-   IN:
-      t............the current thread
-         o............the object of which to exit the monitor
-
-   RETURN VALUE:
-      true.........everything ok,
-         false........an exception has been thrown
-
-*******************************************************************************/
-
-bool lock_monitor_exit(java_handle_t *o)
-{
-       threadobject *t;
-       uintptr_t     lockword;
-       ptrint        thinlock;
-
-       if (o == NULL) {
-               exceptions_throw_nullpointerexception();
-               return false;
-       }
-
-       t = THREADOBJECT;
-
-       thinlock = t->thinlock;
-
-       /* We don't have to worry about stale values here, as any stale value */
-       /* will indicate that we don't own the lock.                          */
-
-       lockword = lock_lockword_get(t, o);
-
-       /* most common case: we release a thin lock that we hold once */
-
-       if (lockword == thinlock) {
-               /* memory barrier for Java Memory Model */
-               MEMORY_BARRIER();
-               lock_lockword_set(t, o, THIN_UNLOCKED);
-               /* memory barrier for thin locking */
-               MEMORY_BARRIER();
-
-               /* check if there has been a flat lock contention on this object */
-
-               if (LOCK_TEST_FLC_BIT(LLNI_DIRECT(o))) {
-                       lock_record_t *lr;
-
-                       DEBUGLOCKS(("thread %d saw flc bit on %p",
-                                               t->index, (void*) o));
-
-                       /* there has been a contention on this thin lock */
-
-                       lr = lock_hashtable_get(t, o);
-
-                       DEBUGLOCKS(("thread %d for %p got lr %p",
-                                               t->index, (void*) o, (void*) lr));
-
-                       lock_record_enter(t, lr);
-
-                       if (LOCK_TEST_FLC_BIT(LLNI_DIRECT(o))) {
-                               /* notify a thread that it can try to inflate the lock now */
-
-                               lock_record_notify(t, lr, true);
-                       }
-
-                       lock_record_exit(t, lr);
-               }
-
-               return true;
-       }
-
-       /* next common case: we release a recursive lock, count > 0 */
-
-       if (LOCK_WORD_WITHOUT_COUNT(lockword) == thinlock) {
-               lock_lockword_set(t, o, lockword - THIN_LOCK_COUNT_INCR);
-               return true;
-       }
-
-       /* either the lock is fat, or we don't hold it at all */
-
-       if (IS_FAT_LOCK(lockword)) {
-
-               lock_record_t *lr;
-
-               lr = GET_FAT_LOCK(lockword);
-
-               /* check if we own this monitor */
-               /* We don't have to worry about stale values here, as any stale value */
-               /* will be != t and thus fail this check.                             */
-
-               if (lr->owner != t) {
-                       exceptions_throw_illegalmonitorstateexception();
-                       return false;
-               }
-
-               /* { the current thread `t` owns the lock record `lr` on object `o` } */
-
-               if (lr->count != 0) {
-                       /* we had locked this one recursively. just decrement, it will */
-                       /* still be locked. */
-                       lr->count--;
-                       return true;
-               }
-
-               /* unlock this lock record */
-
-               lr->owner = NULL;
-               pthread_mutex_unlock(&(lr->mutex));
-
-               return true;
-       }
-
-       /* legal thin lock cases have been handled above, so this is an error */
-
-       exceptions_throw_illegalmonitorstateexception();
-
-       return false;
-}
-
-
-/* lock_record_add_waiter ******************************************************
-
-   Add a thread to the list of waiting threads of a lock record.
-
-   IN:
-      lr...........the lock record
-      thread.......the thread to add
-
-*******************************************************************************/
-
-static void lock_record_add_waiter(lock_record_t *lr, threadobject *thread)
-{
-       lock_waiter_t *w;
-
-       /* Allocate a waiter data structure. */
-
-       w = NEW(lock_waiter_t);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_lock_waiter += sizeof(lock_waiter_t);
-#endif
-
-       /* Store the thread in the waiter structure. */
-
-       w->thread = thread;
-
-       /* Add the waiter as last entry to waiters list. */
-
-       list_add_last(lr->waiters, w);
-}
-
-
-/* lock_record_remove_waiter ***************************************************
-
-   Remove a thread from the list of waiting threads of a lock record.
-
-   IN:
-      lr...........the lock record
-      t............the current thread
-
-   PRE-CONDITION:
-      The current thread must be the owner of the lock record.
-   
-*******************************************************************************/
-
-static void lock_record_remove_waiter(lock_record_t *lr, threadobject *thread)
-{
-       list_t        *l;
-       lock_waiter_t *w;
-
-       /* Get the waiters list. */
-
-       l = lr->waiters;
-
-       for (w = list_first_unsynced(l); w != NULL; w = list_next_unsynced(l, w)) {
-               if (w->thread == thread) {
-                       /* Remove the waiter entry from the list. */
-
-                       list_remove_unsynced(l, w);
-
-                       /* Free the waiter data structure. */
-
-                       FREE(w, lock_waiter_t);
-
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               size_lock_waiter -= sizeof(lock_waiter_t);
-#endif
-
-                       return;
-               }
-       }
-
-       /* This should never happen. */
-
-       vm_abort("lock_record_remove_waiter: thread not found in list of waiters\n");
-}
-
-
-/* lock_record_wait ************************************************************
-
-   Wait on a lock record for a given (maximum) amount of time.
-
-   IN:
-      t............the current thread
-         lr...........the lock record
-         millis.......milliseconds of timeout
-         nanos........nanoseconds of timeout
-
-   RETURN VALUE:
-      true.........we have been interrupted,
-      false........everything ok
-
-   PRE-CONDITION:
-      The current thread must be the owner of the lock record.
-         This is NOT checked by this function!
-   
-*******************************************************************************/
-
-static bool lock_record_wait(threadobject *thread, lock_record_t *lr, s8 millis, s4 nanos)
-{
-       s4   lockcount;
-       bool wasinterrupted;
-
-       DEBUGLOCKS(("[lock_record_wait  : lr=%p, t=%p, millis=%lld, nanos=%d]",
-                               lr, thread, millis, nanos));
-
-       /* { the thread t owns the fat lock record lr on the object o } */
-
-       /* register us as waiter for this object */
-
-       lock_record_add_waiter(lr, thread);
-
-       /* remember the old lock count */
-
-       lockcount = lr->count;
-
-       /* unlock this record */
-
-       lr->count = 0;
-       lock_record_exit(thread, lr);
-
-       /* wait until notified/interrupted/timed out */
-
-       wasinterrupted = threads_wait_with_timeout_relative(thread, millis, nanos);
-
-       /* re-enter the monitor */
-
-       lock_record_enter(thread, lr);
-
-       /* remove us from the list of waiting threads */
-
-       lock_record_remove_waiter(lr, thread);
-
-       /* restore the old lock count */
-
-       lr->count = lockcount;
-
-       /* return if we have been interrupted */
-
-       return wasinterrupted;
-}
-
-
-/* lock_monitor_wait ***********************************************************
-
-   Wait on an object for a given (maximum) amount of time.
-
-   IN:
-      t............the current thread
-         o............the object
-         millis.......milliseconds of timeout
-         nanos........nanoseconds of timeout
-
-   PRE-CONDITION:
-      The current thread must be the owner of the object's monitor.
-   
-*******************************************************************************/
-
-static void lock_monitor_wait(threadobject *t, java_handle_t *o, s8 millis, s4 nanos)
-{
-       uintptr_t      lockword;
-       lock_record_t *lr;
-
-       lockword = lock_lockword_get(t, o);
-
-       /* check if we own this monitor */
-       /* We don't have to worry about stale values here, as any stale value */
-       /* will fail this check.                                              */
-
-       if (IS_FAT_LOCK(lockword)) {
-
-               lr = GET_FAT_LOCK(lockword);
-
-               if (lr->owner != t) {
-                       exceptions_throw_illegalmonitorstateexception();
-                       return;
-               }
-       }
-       else {
-               /* it's a thin lock */
-
-               if (LOCK_WORD_WITHOUT_COUNT(lockword) != t->thinlock) {
-                       exceptions_throw_illegalmonitorstateexception();
-                       return;
-               }
-
-               /* inflate this lock */
-
-               lr = lock_hashtable_get(t, o);
-               lock_record_enter(t, lr);
-               lock_inflate(t, o, lr);
-       }
-
-       /* { the thread t owns the fat lock record lr on the object o } */
-
-       if (lock_record_wait(t, lr, millis, nanos))
-               exceptions_throw_interruptedexception();
-}
-
-
-/* lock_record_notify **********************************************************
-
-   Notify one thread or all threads waiting on the given lock record.
-
-   IN:
-      t............the current thread
-         lr...........the lock record
-         one..........if true, only notify one thread
-
-   PRE-CONDITION:
-      The current thread must be the owner of the lock record.
-         This is NOT checked by this function!
-   
-*******************************************************************************/
-
-static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one)
-{
-       list_t        *l;
-       lock_waiter_t *w;
-       threadobject  *waitingthread;
-
-       /* { the thread t owns the fat lock record lr on the object o } */
-
-       /* Get the waiters list. */
-
-       l = lr->waiters;
-
-       for (w = list_first_unsynced(l); w != NULL; w = list_next_unsynced(l, w)) {
-               /* signal the waiting thread */
-
-               waitingthread = w->thread;
-
-               /* If the thread was already signaled but hasn't removed
-                  itself from the list yet, just ignore it. */
-
-               if (waitingthread->signaled == true)
-                       continue;
-
-               /* Enter the wait-mutex. */
-
-               pthread_mutex_lock(&(waitingthread->waitmutex));
-
-               DEBUGLOCKS(("[lock_record_notify: lr=%p, t=%p, waitingthread=%p, sleeping=%d, one=%d]",
-                                       lr, t, waitingthread, waitingthread->sleeping, one));
-
-               /* Signal the thread if it's sleeping. */
-
-               if (waitingthread->sleeping)
-                       pthread_cond_signal(&(waitingthread->waitcond));
-
-               /* Mark the thread as signaled. */
-
-               waitingthread->signaled = true;
-
-               /* Leave the wait-mutex. */
-
-               pthread_mutex_unlock(&(waitingthread->waitmutex));
-
-               /* if we should only wake one, we are done */
-
-               if (one)
-                       break;
-       }
-}
-
-
-/* lock_monitor_notify *********************************************************
-
-   Notify one thread or all threads waiting on the given object.
-
-   IN:
-      t............the current thread
-         o............the object
-         one..........if true, only notify one thread
-
-   PRE-CONDITION:
-      The current thread must be the owner of the object's monitor.
-   
-*******************************************************************************/
-
-static void lock_monitor_notify(threadobject *t, java_handle_t *o, bool one)
-{
-       uintptr_t      lockword;
-       lock_record_t *lr;
-
-       lockword = lock_lockword_get(t, o);
-
-       /* check if we own this monitor */
-       /* We don't have to worry about stale values here, as any stale value */
-       /* will fail this check.                                              */
-
-       if (IS_FAT_LOCK(lockword)) {
-
-               lr = GET_FAT_LOCK(lockword);
-
-               if (lr->owner != t) {
-                       exceptions_throw_illegalmonitorstateexception();
-                       return;
-               }
-       }
-       else {
-               /* it's a thin lock */
-
-               if (LOCK_WORD_WITHOUT_COUNT(lockword) != t->thinlock) {
-                       exceptions_throw_illegalmonitorstateexception();
-                       return;
-               }
-
-               /* inflate this lock */
-
-               lr = lock_hashtable_get(t, o);
-               lock_record_enter(t, lr);
-               lock_inflate(t, o, lr);
-       }
-
-       /* { the thread t owns the fat lock record lr on the object o } */
-
-       lock_record_notify(t, lr, one);
-}
-
-
-
-/*============================================================================*/
-/* INQUIRY FUNCIONS                                                           */
-/*============================================================================*/
-
-
-/* lock_is_held_by_current_thread **********************************************
-
-   Return true if the current thread owns the monitor of the given object.
-
-   IN:
-         o............the object
-
-   RETURN VALUE:
-      true, if the current thread holds the lock of this object.
-   
-*******************************************************************************/
-
-bool lock_is_held_by_current_thread(java_handle_t *o)
-{
-       threadobject  *t;
-       uintptr_t      lockword;
-       lock_record_t *lr;
-
-       t = THREADOBJECT;
-
-       /* check if we own this monitor */
-       /* We don't have to worry about stale values here, as any stale value */
-       /* will fail this check.                                              */
-
-       lockword = lock_lockword_get(t, o);
-
-       if (IS_FAT_LOCK(lockword)) {
-               /* it's a fat lock */
-
-               lr = GET_FAT_LOCK(lockword);
-
-               return (lr->owner == t);
-       }
-       else {
-               /* it's a thin lock */
-
-               return (LOCK_WORD_WITHOUT_COUNT(lockword) == t->thinlock);
-       }
-}
-
-
-
-/*============================================================================*/
-/* WRAPPERS FOR OPERATIONS ON THE CURRENT THREAD                              */
-/*============================================================================*/
-
-
-/* lock_wait_for_object ********************************************************
-
-   Wait for the given object.
-
-   IN:
-         o............the object
-         millis.......milliseconds to wait
-         nanos........nanoseconds to wait
-   
-*******************************************************************************/
-
-void lock_wait_for_object(java_handle_t *o, s8 millis, s4 nanos)
-{
-       threadobject *thread;
-
-       thread = THREADOBJECT;
-
-       lock_monitor_wait(thread, o, millis, nanos);
-}
-
-
-/* lock_notify_object **********************************************************
-
-   Notify one thread waiting on the given object.
-
-   IN:
-         o............the object
-   
-*******************************************************************************/
-
-void lock_notify_object(java_handle_t *o)
-{
-       threadobject *thread;
-
-       thread = THREADOBJECT;
-
-       lock_monitor_notify(thread, o, true);
-}
-
-
-/* lock_notify_all_object ******************************************************
-
-   Notify all threads waiting on the given object.
-
-   IN:
-         o............the object
-   
-*******************************************************************************/
-
-void lock_notify_all_object(java_handle_t *o)
-{
-       threadobject *thread;
-
-       thread = THREADOBJECT;
-
-       lock_monitor_notify(thread, o, false);
-}
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of 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/native/lock.h b/src/threads/native/lock.h
deleted file mode 100644 (file)
index bbdf83c..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* src/threads/native/lock.h - lock 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
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public 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 _LOCK_H
-#define _LOCK_H
-
-#include "config.h"
-
-#include <pthread.h>
-
-#include "vm/types.h"
-
-#include "native/llni.h"
-
-#include "toolbox/list.h"
-
-#include "vm/global.h"
-
-
-
-/* typedefs *******************************************************************/
-
-typedef struct lock_record_t    lock_record_t;
-typedef struct lock_waiter_t    lock_waiter_t;
-typedef struct lock_hashtable_t lock_hashtable_t;
-
-
-/* lock_waiter_t ***************************************************************
-
-   List node for storing a waiting thread.
-
-*******************************************************************************/
-
-struct lock_waiter_t {
-       struct threadobject *thread;        /* the waiting thread                 */
-       listnode_t           linkage;
-};
-
-
-/* lock_record_t ***************************************************************
-
-   Lock record struct representing an inflated ("fat") lock.
-
-*******************************************************************************/
-
-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          */
-       pthread_mutex_t      mutex;              /* mutex for synchronizing       */
-       list_t              *waiters;            /* list of threads waiting       */
-       lock_record_t       *hashlink;           /* next record in hash chain     */
-};
-
-
-/* lock_hashtable_t ************************************************************
-   The global hashtable mapping objects to lock records.
-
-*******************************************************************************/
-
-struct lock_hashtable_t {
-       pthread_mutex_t      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. */
-};
-
-
-/* defines ********************************************************************/
-
-#define LOCK_INIT_OBJECT_LOCK(o) lock_init_object_lock((java_object_t *) (o))
-
-#define LOCK_MONITOR_ENTER(o)    lock_monitor_enter((java_handle_t *) LLNI_QUICKWRAP(o))
-#define LOCK_MONITOR_EXIT(o)     lock_monitor_exit((java_handle_t *) LLNI_QUICKWRAP(o))
-
-#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))
-
-#endif /* _LOCK_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/native/threads.c b/src/threads/native/threads.c
deleted file mode 100644 (file)
index 131c888..0000000
+++ /dev/null
@@ -1,2164 +0,0 @@
-/* src/threads/native/threads.c - native threads support
-
-   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"
-
-/* 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/native/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_CLASSPATH_GNU)
-# include "native/include/java_lang_VMThread.h"
-#endif
-
-#include "threads/lock-common.h"
-#include "threads/threads-common.h"
-
-#include "threads/native/threads.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__)
-# if defined(__LINUX__)
-#  define GC_LINUX_THREADS
-# elif defined(__IRIX__)
-#  define GC_IRIX_THREADS
-# endif
-# include <semaphore.h>
-# if defined(ENABLE_GC_BOEHM)
-#  include "mm/boehm-gc/include/gc.h"
-# endif
-#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;
-    
-       if (pthread_mutex_init(&sem->mutex, NULL) < 0)
-               return -1;
-
-       if (pthread_cond_init(&sem->cond, NULL) < 0)
-               return -1;
-
-       return 0;
-}
-
-static int sem_post(sem_t *sem)
-{
-       if (pthread_mutex_lock(&sem->mutex) < 0)
-               return -1;
-
-       sem->value++;
-
-       if (pthread_cond_signal(&sem->cond) < 0) {
-               pthread_mutex_unlock(&sem->mutex);
-               return -1;
-       }
-
-       if (pthread_mutex_unlock(&sem->mutex) < 0)
-               return -1;
-
-       return 0;
-}
-
-static int sem_wait(sem_t *sem)
-{
-       if (pthread_mutex_lock(&sem->mutex) < 0)
-               return -1;
-
-       while (sem->value == 0) {
-               pthread_cond_wait(&sem->cond, &sem->mutex);
-       }
-
-       sem->value--;
-
-       if (pthread_mutex_unlock(&sem->mutex) < 0)
-               return -1;    
-
-       return 0;
-}
-
-static int sem_destroy(sem_t *sem)
-{
-       if (pthread_cond_destroy(&sem->cond) < 0)
-               return -1;
-
-       if (pthread_mutex_destroy(&sem->mutex) < 0)
-               return -1;
-
-       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                                                           */
-/******************************************************************************/
-
-static methodinfo *method_thread_init;
-
-/* 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 *threads_current_threadobject;
-#else
-pthread_key_t threads_current_threadobject_key;
-#endif
-
-/* global mutex for the threads table */
-static pthread_mutex_t mutex_threads_list;
-
-/* global mutex for stop-the-world                                            */
-static pthread_mutex_t stopworldlock;
-
-#if defined(ENABLE_GC_CACAO)
-/* global mutex for the GC */
-static pthread_mutex_t mutex_gc;
-#endif
-
-/* global mutex and condition for joining threads on exit */
-static pthread_mutex_t mutex_join;
-static pthread_cond_t  cond_join;
-
-/* XXX We disable that whole bunch of code until we have the exact-GC
-   running. */
-
-#if 1
-
-/* this is one of the STOPWORLD_FROM_ constants, telling why the world is     */
-/* being stopped                                                              */
-static volatile int stopworldwhere;
-
-/* semaphore used for acknowleding thread suspension                          */
-static sem_t suspend_ack;
-#if defined(__IRIX__)
-static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
-#endif
-
-#endif /* 0 */
-
-/* mutexes used by the fake atomic instructions                               */
-#if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
-pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t _mb_lock = PTHREAD_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)
-{
-       pthread_mutex_lock(&stopworldlock);
-/*     stopworldwhere = where; */
-}
-
-
-/* unlock_stopworld ************************************************************
-
-   Release the stopworld lock.
-
-******************************************************************************/
-
-void unlock_stopworld(void)
-{
-/*     stopworldwhere = 0; */
-       pthread_mutex_unlock(&stopworldlock);
-}
-
-/* XXX We disable that whole bunch of code until we have the exact-GC
-   running. */
-
-#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 = threads_list_first(); t != NULL; t = threads_list_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)
-{
-       pthread_mutex_lock(&suspend_ack_lock);
-       pthread_cond_broadcast(&suspend_cond);
-       pthread_mutex_unlock(&suspend_ack_lock);
-}
-#endif
-#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__)
-       pthread_mutex_lock(&suspend_ack_lock);
-       threads_sem_post(&suspend_ack);
-       pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
-       pthread_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.
-
-*******************************************************************************/
-
-#if !defined(DISABLE_GC)
-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 */
-
-       threads_list_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 = threads_list_first(); t != NULL; t = threads_list_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 /* !defined(DISABLE_GC) */
-
-
-/* threads_startworld **********************************************************
-
-   Starts the world again after it has previously been stopped. 
-
-*******************************************************************************/
-
-#if !defined(DISABLE_GC)
-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 = threads_list_first(); t != NULL; t = threads_list_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 */
-
-       threads_list_unlock();
-
-       unlock_stopworld();
-}
-#endif
-
-
-/* threads_set_current_threadobject ********************************************
-
-   Set the current thread object.
-   
-   IN:
-      thread.......the thread object to set
-
-*******************************************************************************/
-
-void threads_set_current_threadobject(threadobject *thread)
-{
-#if !defined(HAVE___THREAD)
-       if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
-               vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
-#else
-       threads_current_threadobject = thread;
-#endif
-}
-
-
-/* threads_impl_thread_new *****************************************************
-
-   Initialize implementation fields of a threadobject.
-
-   IN:
-      t....the threadobject
-
-*******************************************************************************/
-
-void threads_impl_thread_new(threadobject *t)
-{
-       /* get the pthread id */
-
-       t->tid = pthread_self();
-
-       /* initialize the mutex and the condition */
-
-       pthread_mutex_init(&(t->waitmutex), NULL);
-       pthread_cond_init(&(t->waitcond), NULL);
-       pthread_mutex_init(&(t->suspendmutex), NULL);
-       pthread_cond_init(&(t->suspendcond), NULL);
-
-#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
-}
-
-
-/* threads_impl_thread_free ****************************************************
-
-   Cleanup thread stuff.
-
-   IN:
-      t....the threadobject
-
-*******************************************************************************/
-
-void threads_impl_thread_free(threadobject *t)
-{
-       /* destroy the mutex and the condition */
-
-       if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
-               vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
-                                strerror(errno));
-
-       if (pthread_cond_destroy(&(t->waitcond)) != 0)
-               vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
-                                strerror(errno));
-
-       if (pthread_mutex_destroy(&(t->suspendmutex)) != 0)
-               vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
-                                strerror(errno));
-
-       if (pthread_cond_destroy(&(t->suspendcond)) != 0)
-               vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
-                                strerror(errno));
-}
-
-
-/* threads_get_current_threadobject ********************************************
-
-   Return the threadobject of the current thread.
-   
-   RETURN VALUE:
-       the current threadobject *
-
-*******************************************************************************/
-
-threadobject *threads_get_current_threadobject(void)
-{
-       return THREADOBJECT;
-}
-
-
-/* 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)
-{
-       pthread_mutex_init(&stopworldlock, NULL);
-
-       /* initialize exit mutex and condition (on exit we join all
-          threads) */
-
-       pthread_mutex_init(&mutex_join, NULL);
-       pthread_cond_init(&cond_join, NULL);
-
-#if defined(ENABLE_GC_CACAO)
-       /* initialize the GC mutext */
-
-       pthread_mutex_init(&mutex_gc, NULL);
-#endif
-
-       /* initialize the threads-list mutex */
-
-       pthread_mutex_init(&mutex_threads_list, NULL);
-
-#if !defined(HAVE___THREAD)
-       pthread_key_create(&threads_current_threadobject_key, NULL);
-#endif
-
-       threads_sem_init(&suspend_ack, 0, 0);
-}
-
-
-/* threads_list_lock ***********************************************************
-
-   Enter the threads table mutex.
-
-   NOTE: We need this function as we can't use an internal lock for
-         the threads lists because the thread's lock is initialized in
-         threads_table_add (when we have the thread index), but we
-         already need the lock at the entry of the function.
-
-*******************************************************************************/
-
-void threads_list_lock(void)
-{
-       if (pthread_mutex_lock(&mutex_threads_list) != 0)
-               vm_abort("threads_list_lock: pthread_mutex_lock failed: %s",
-                                strerror(errno));
-}
-
-
-/* threads_list_unlock *********************************************************
-
-   Leave the threads list mutex.
-
-*******************************************************************************/
-
-void threads_list_unlock(void)
-{
-       if (pthread_mutex_unlock(&mutex_threads_list) != 0)
-               vm_abort("threads_list_unlock: pthread_mutex_unlock failed: %s",
-                                strerror(errno));
-}
-
-
-/* threads_mutex_gc_lock *******************************************************
-
-   Enter the global GC mutex.
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-void threads_mutex_gc_lock(void)
-{
-       if (pthread_mutex_lock(&mutex_gc) != 0)
-               vm_abort("threads_mutex_gc_lock: pthread_mutex_lock failed: %s",
-                                strerror(errno));
-}
-#endif
-
-
-/* threads_mutex_gc_unlock *****************************************************
-
-   Leave the global GC mutex.
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-void threads_mutex_gc_unlock(void)
-{
-       if (pthread_mutex_unlock(&mutex_gc) != 0)
-               vm_abort("threads_mutex_gc_unlock: pthread_mutex_unlock failed: %s",
-                                strerror(errno));
-}
-#endif
-
-/* threads_mutex_join_lock *****************************************************
-
-   Enter the join mutex.
-
-*******************************************************************************/
-
-void threads_mutex_join_lock(void)
-{
-       if (pthread_mutex_lock(&mutex_join) != 0)
-               vm_abort("threads_mutex_join_lock: pthread_mutex_lock failed: %s",
-                                strerror(errno));
-}
-
-
-/* threads_mutex_join_unlock ***************************************************
-
-   Leave the join mutex.
-
-*******************************************************************************/
-
-void threads_mutex_join_unlock(void)
-{
-       if (pthread_mutex_unlock(&mutex_join) != 0)
-               vm_abort("threads_mutex_join_unlock: pthread_mutex_unlock failed: %s",
-                                strerror(errno));
-}
-
-
-/* threads_init ****************************************************************
-
-   Initializes the threads required by the JVM: main, finalizer.
-
-*******************************************************************************/
-
-bool threads_init(void)
-{
-       threadobject     *mainthread;
-       java_handle_t    *threadname;
-       java_lang_Thread *t;
-       java_handle_t    *o;
-
-#if defined(ENABLE_JAVASE)
-       java_lang_ThreadGroup *threadgroup;
-       methodinfo            *m;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-       java_lang_VMThread    *vmt;
-#endif
-
-       pthread_attr_t attr;
-
-       /* get methods we need in this file */
-
-#if defined(WITH_CLASSPATH_GNU)
-       method_thread_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_CLASSPATH_SUN)
-       method_thread_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/String;)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-       method_thread_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/String;)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-#else
-# error unknown classpath configuration
-#endif
-
-       if (method_thread_init == NULL)
-               return false;
-
-       /* Get the main-thread (NOTE: The main threads is always the first
-          thread in the list). */
-
-       mainthread = threads_list_first();
-
-       /* create a java.lang.Thread for the main thread */
-
-       t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
-
-       if (t == NULL)
-               return false;
-
-       /* set the object in the internal data structure */
-
-       threads_thread_set_object(mainthread, (java_handle_t *) t);
-
-#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
-
-       threadname = javastring_new(utf_new_char("main"));
-
-#if defined(ENABLE_JAVASE)
-       /* allocate and init ThreadGroup */
-
-       threadgroup = (java_lang_ThreadGroup *)
-               native_new_and_init(class_java_lang_ThreadGroup);
-
-       if (threadgroup == NULL)
-               return false;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-       /* create a java.lang.VMThread for the main thread */
-
-       vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
-
-       if (vmt == NULL)
-               return false;
-
-       /* set the thread */
-
-       LLNI_field_set_ref(vmt, thread, t);
-       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) mainthread);
-
-       /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
-       o = (java_handle_t *) t;
-
-       (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
-                                                 false);
-
-#elif defined(WITH_CLASSPATH_SUN)
-
-       /* We trick java.lang.Thread.<init>, which sets the priority of
-          the current thread to the parent's one. */
-
-       t->priority = NORM_PRIORITY;
-
-       /* Call java.lang.Thread.<init>(Ljava/lang/String;)V */
-
-       o = (java_object_t *) t;
-
-       (void) vm_call_method(method_thread_init, o, threadname);
-
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-
-       /* set the thread */
-
-       t->vm_thread = (java_lang_Object *) mainthread;
-
-       /* call public Thread(String name) */
-
-       o = (java_handle_t *) t;
-
-       (void) vm_call_method(method_thread_init, o, threadname);
-#else
-# error unknown classpath configuration
-#endif
-
-       if (exceptions_get_exception())
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       LLNI_field_set_ref(t, group, threadgroup);
-
-# if defined(WITH_CLASSPATH_GNU)
-       /* add main thread to java.lang.ThreadGroup */
-
-       m = class_resolveclassmethod(class_java_lang_ThreadGroup,
-                                                                utf_addThread,
-                                                                utf_java_lang_Thread__V,
-                                                                class_java_lang_ThreadGroup,
-                                                                true);
-
-       o = (java_handle_t *) threadgroup;
-
-       (void) vm_call_method(m, o, t);
-
-       if (exceptions_get_exception())
-               return false;
-# else
-#  warning Do not know what to do here
-# endif
-#endif
-
-       threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
-
-       /* initialize the thread attribute object */
-
-       if (pthread_attr_init(&attr) != 0)
-               vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
-
-       if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
-               vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
-                                strerror(errno));
-
-       DEBUGTHREADS("starting (main)", mainthread);
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* 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       *thread;
-       java_lang_Thread   *object;
-#if defined(WITH_CLASSPATH_GNU)
-       java_lang_VMThread *vmt;
-#endif
-       sem_t              *psem;
-       classinfo          *c;
-       methodinfo         *m;
-       java_handle_t      *o;
-       functionptr         function;
-
-#if defined(ENABLE_INTRP)
-       u1 *intrp_thread_stack;
-
-       /* 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;
-
-       thread   = 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__)
-       thread->mach_thread = mach_thread_self();
-#endif
-
-       /* store the internal thread data-structure in the TSD */
-
-       threads_set_current_threadobject(thread);
-
-       /* get the java.lang.Thread object for this thread */
-
-       object = (java_lang_Thread *) threads_thread_get_object(thread);
-
-       /* set our priority */
-
-       threads_set_thread_priority(thread->tid, LLNI_field_direct(object, priority));
-
-       /* thread is completely initialized */
-
-       threads_thread_state_runnable(thread);
-
-       /* 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", thread);
-
-       /* find and run the Thread.run()V method if no other function was passed */
-
-       if (function == NULL) {
-#if defined(WITH_CLASSPATH_GNU)
-               /* 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_CLASSPATH_SUN) || defined(WITH_CLASSPATH_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_CLASSPATH_GNU)
-               /* 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_CLASSPATH_SUN) || defined(WITH_CLASSPATH_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", thread);
-
-#if defined(ENABLE_JVMTI)
-       /* fire thread end event */
-
-       if (jvmti)
-               jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
-#endif
-
-       /* We ignore the return value. */
-
-       (void) threads_detach_thread(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("threads_impl_thread_start: pthread_attr_init failed: %s",
-                                strerror(result));
-
-    result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-    if (result != 0)
-               vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
-                                strerror(result));
-
-       /* initialize thread stacksize */
-
-       result = pthread_attr_setstacksize(&attr, opt_stacksize);
-
-       if (result != 0)
-               vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
-                                strerror(result));
-
-       /* create the thread */
-
-       result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
-
-       if (result != 0)
-               vm_abort("threads_impl_thread_start: pthread_create failed: %s",
-                                strerror(result));
-
-       /* destroy the thread attributes */
-
-       result = pthread_attr_destroy(&attr);
-
-       if (result != 0)
-               vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
-                                strerror(result));
-
-       /* 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);
-}
-
-
-/* threads_attach_current_thread ***********************************************
-
-   Attaches the current thread to the VM.  Used in JNI.
-
-*******************************************************************************/
-
-bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
-{
-       threadobject          *thread;
-       utf                   *u;
-       java_handle_t         *s;
-       java_handle_t         *o;
-       java_lang_Thread      *t;
-
-#if defined(ENABLE_JAVASE)
-       java_lang_ThreadGroup *group;
-       threadobject          *mainthread;
-       java_lang_Thread      *mainthreado;
-       classinfo             *c;
-       methodinfo            *m;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-       java_lang_VMThread    *vmt;
-#endif
-
-       /* 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 */
-
-       thread = threads_thread_new();
-
-       /* thread is a Java thread and running */
-
-       thread->flags = THREAD_FLAG_JAVA;
-
-       if (isdaemon)
-               thread->flags |= THREAD_FLAG_DAEMON;
-
-       /* The thread is flagged and (non-)daemon thread, we can leave the
-          mutex. */
-
-       threads_mutex_join_unlock();
-
-       /* create a java.lang.Thread object */
-
-       t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
-
-       /* XXX memory leak!!! */
-       if (t == NULL)
-               return false;
-
-       threads_thread_set_object(thread, (java_handle_t *) t);
-
-       /* thread is completely initialized */
-
-       threads_thread_state_runnable(thread);
-
-       DEBUGTHREADS("attaching", thread);
-
-#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
-
-#if defined(WITH_CLASSPATH_GNU)
-
-       /* create a java.lang.VMThread object */
-
-       vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
-
-       /* XXX memory leak!!! */
-       if (vmt == NULL)
-               return false;
-
-       /* set the thread */
-
-       LLNI_field_set_ref(vmt, thread, t);
-       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
-
-#elif defined(WITH_CLASSPATH_SUN)
-
-       vm_abort("threads_attach_current_thread: IMPLEMENT ME!");
-
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-
-       LLNI_field_set_val(t, vm_thread, (java_lang_Object *) thread);
-
-#else
-# error unknown classpath configuration
-#endif
-
-       if (vm_aargs != NULL) {
-               u     = utf_new_char(vm_aargs->name);
-#if defined(ENABLE_JAVASE)
-               group = (java_lang_ThreadGroup *) vm_aargs->group;
-#endif
-       }
-       else {
-               u     = utf_null;
-#if defined(ENABLE_JAVASE)
-               /* get the main thread */
-
-               mainthread = threads_list_first();
-               mainthreado = (java_lang_Thread *) threads_thread_get_object(mainthread);
-               LLNI_field_get_ref(mainthreado, group, group);
-#endif
-       }
-
-       /* the the thread name */
-
-       s = javastring_new(u);
-
-       /* for convenience */
-
-       o = (java_handle_t *) t;
-
-#if defined(WITH_CLASSPATH_GNU)
-       (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
-                                                 isdaemon);
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-       (void) vm_call_method(method_thread_init, o, s);
-#endif
-
-       if (exceptions_get_exception())
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       /* store the thread group in the object */
-
-       LLNI_field_set_ref(t, group, group);
-
-       /* add thread to given thread-group */
-
-       LLNI_class_get(group, c);
-
-       m = class_resolveclassmethod(c,
-                                                                utf_addThread,
-                                                                utf_java_lang_Thread__V,
-                                                                class_java_lang_ThreadGroup,
-                                                                true);
-
-       o = (java_handle_t *) group;
-
-       (void) vm_call_method(m, o, t);
-
-       if (exceptions_get_exception())
-               return false;
-#endif
-
-       return true;
-}
-
-
-/* threads_detach_thread *******************************************************
-
-   Detaches the passed thread from the VM.  Used in JNI.
-
-*******************************************************************************/
-
-bool threads_detach_thread(threadobject *t)
-{
-       java_lang_Thread      *object;
-       java_handle_t         *o;
-#if defined(ENABLE_JAVASE)
-       java_lang_ThreadGroup *group;
-       java_handle_t         *e;
-       java_lang_Object      *handler;
-       classinfo             *c;
-       methodinfo            *m;
-#endif
-
-       DEBUGTHREADS("detaching", t);
-
-       object = (java_lang_Thread *) threads_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 a java_lang_Object here, as it's not trivial to
-                  build the java_lang_Thread_UncaughtExceptionHandler header
-                  file. */
-
-# if defined(WITH_CLASSPATH_GNU)
-               LLNI_field_get_ref(object, exceptionHandler, handler);
-# elif defined(WITH_CLASSPATH_SUN)
-               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_CLASSPATH_GNU)
-               m = class_resolveclassmethod(c,
-                                                                        utf_removeThread,
-                                                                        utf_java_lang_Thread__V,
-                                                                        class_java_lang_ThreadGroup,
-                                                                        true);
-# elif defined(WITH_CLASSPATH_SUN)
-               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;
-       }
-#endif
-
-       /* Thread has terminated. */
-
-       threads_thread_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 threads_thread_free, so
-          threads_join_all_threads gets the correct number of non-daemon
-          threads. */
-
-       threads_mutex_join_lock();
-
-       /* free the vm internal thread object */
-
-       threads_thread_free(t);
-
-       /* Signal that this thread has finished and leave the mutex. */
-
-       pthread_cond_signal(&cond_join);
-       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 */
-       if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
-               vm_abort("threads_suspend_thread: pthread_mutex_lock failed: %s",
-                                strerror(errno));
-
-       if (thread->suspended) {
-               pthread_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 */
-
-#if defined(ENABLE_GC_CACAO)
-       /* 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;
-
-               }
-       }
-#endif
-
-       /* 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 */
-       if (pthread_mutex_unlock(&(thread->suspendmutex)) != 0)
-               vm_abort("threads_suspend_ack: pthread_mutex_unlock failed: %s",
-                                strerror(errno));
-}
-
-
-/* threads_resume_thread *******************************************************
-
-   Resumes the execution of the passed thread.
-
-*******************************************************************************/
-
-bool threads_resume_thread(threadobject *thread)
-{
-       /* acquire the suspendmutex */
-       if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
-               vm_abort("threads_resume_ack: pthread_mutex_unlock failed: %s",
-                                strerror(errno));
-
-       if (!thread->suspended) {
-               pthread_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 */
-       pthread_mutex_unlock(&(thread->suspendmutex));
-
-       return true;
-}
-
-
-/* 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 */
-
-       threads_thread_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 (threads_list_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.
-
-   RETURN VALUE:
-      true.........if the wait has been interrupted,
-         false........if the wait was ended by notification or timeout
-
-*******************************************************************************/
-
-static bool threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
-{
-       bool wasinterrupted;
-
-       /* acquire the waitmutex */
-
-       pthread_mutex_lock(&t->waitmutex);
-
-       /* mark us as sleeping */
-
-       t->sleeping = true;
-
-       /* wait on waitcond */
-
-       if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
-               /* with timeout */
-               while (!t->interrupted && !t->signaled
-                          && threads_current_time_is_earlier_than(wakeupTime))
-               {
-                       threads_thread_state_timed_waiting(t);
-
-                       pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
-                                                                  wakeupTime);
-
-                       threads_thread_state_runnable(t);
-               }
-       }
-       else {
-               /* no timeout */
-               while (!t->interrupted && !t->signaled) {
-                       threads_thread_state_waiting(t);
-
-                       pthread_cond_wait(&t->waitcond, &t->waitmutex);
-
-                       threads_thread_state_runnable(t);
-               }
-       }
-
-       /* check if we were interrupted */
-
-       wasinterrupted = t->interrupted;
-
-       /* reset all flags */
-
-       t->interrupted = false;
-       t->signaled    = false;
-       t->sleeping    = false;
-
-       /* release the waitmutex */
-
-       pthread_mutex_unlock(&t->waitmutex);
-
-       return wasinterrupted;
-}
-
-
-/* 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
-
-   RETURN VALUE:
-      true.........if the wait has been interrupted,
-         false........if the wait was ended by notification or timeout
-
-*******************************************************************************/
-
-bool 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 */
-
-       return 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)
-{
-       /* Signal the thread a "waitcond" and tell it that it has been
-          interrupted. */
-
-       pthread_mutex_lock(&thread->waitmutex);
-
-       DEBUGTHREADS("interrupted", thread);
-
-       /* Interrupt blocking system call using a signal. */
-
-       pthread_kill(thread->tid, SIGHUP);
-
-       if (thread->sleeping)
-               pthread_cond_signal(&thread->waitcond);
-
-       thread->interrupted = true;
-
-       pthread_mutex_unlock(&thread->waitmutex);
-}
-
-
-/* threads_check_if_interrupted_and_reset **************************************
-
-   Check if the current thread has been interrupted and reset the
-   interruption flag.
-
-   RETURN VALUE:
-      true, if the current thread had been interrupted
-
-*******************************************************************************/
-
-bool threads_check_if_interrupted_and_reset(void)
-{
-       threadobject *thread;
-       bool intr;
-
-       thread = THREADOBJECT;
-
-       /* get interrupted flag */
-
-       intr = thread->interrupted;
-
-       /* reset interrupted flag */
-
-       thread->interrupted = false;
-
-       return intr;
-}
-
-
-/* threads_thread_has_been_interrupted *****************************************
-
-   Check if the given thread has been interrupted
-
-   IN:
-      t............the thread to check
-
-   RETURN VALUE:
-      true, if the given thread had been interrupted
-
-*******************************************************************************/
-
-bool threads_thread_has_been_interrupted(threadobject *thread)
-{
-       return thread->interrupted;
-}
-
-
-/* threads_sleep ***************************************************************
-
-   Sleep the current thread for the specified amount of time.
-
-*******************************************************************************/
-
-void threads_sleep(s8 millis, s4 nanos)
-{
-       threadobject    *thread;
-       struct timespec  wakeupTime;
-       bool             wasinterrupted;
-
-       thread = THREADOBJECT;
-
-       threads_calc_absolute_time(&wakeupTime, millis, nanos);
-
-       wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
-
-       if (wasinterrupted)
-               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/native/threads.h b/src/threads/native/threads.h
deleted file mode 100644 (file)
index f9633b9..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/* src/threads/native/threads.h - native threads 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 _THREADS_H
-#define _THREADS_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/jni.h"
-#include "native/localref.h"
-
-#include "threads/native/lock.h"
-
-#include "vm/global.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 {
-       pthread_mutex_t mutex;
-       pthread_cond_t cond;
-       int value;
-} sem_t;
-
-#else
-# include <semaphore.h>
-#endif
-
-
-/* current threadobject *******************************************************/
-
-#if defined(HAVE___THREAD)
-
-#define THREADSPECIFIC    __thread
-#define THREADOBJECT      threads_current_threadobject
-
-extern __thread threadobject *threads_current_threadobject;
-
-#else /* defined(HAVE___THREAD) */
-
-#define THREADSPECIFIC
-#define THREADOBJECT \
-       ((threadobject *) pthread_getspecific(threads_current_threadobject_key))
-
-extern pthread_key_t threads_current_threadobject_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
-
-       /* these are used for the wait/notify implementation                      */
-       pthread_mutex_t       waitmutex;
-       pthread_cond_t        waitcond;
-
-       pthread_mutex_t       suspendmutex; /* lock before suspending this thread */
-       pthread_cond_t        suspendcond;  /* notify to resume this thread       */
-
-       bool                  interrupted;
-       bool                  signaled;
-       bool                  sleeping;
-
-       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                       */
-};
-
-
-/* stackframeinfo *************************************************************/
-
-#define STACKFRAMEINFO    (THREADOBJECT->_stackframeinfo)
-
-
-/* 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
-
-/* 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);
-
-threadobject *threads_get_current_threadobject(void);
-
-bool threads_init(void);
-
-void threads_start_thread(threadobject *thread, functionptr function);
-
-void threads_set_thread_priority(pthread_t tid, int priority);
-
-bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
-bool threads_detach_thread(threadobject *thread);
-
-bool threads_suspend_thread(threadobject *thread, s4 reason);
-void threads_suspend_ack(u1* pc, u1* sp);
-bool threads_resume_thread(threadobject *thread);
-
-void threads_join_all_threads(void);
-
-void threads_sleep(s8 millis, s4 nanos);
-
-bool threads_wait_with_timeout_relative(threadobject *t, s8 millis, s4 nanos);
-
-void threads_thread_interrupt(threadobject *thread);
-bool threads_check_if_interrupted_and_reset(void);
-bool threads_thread_has_been_interrupted(threadobject *thread);
-
-#if !defined(DISABLE_GC)
-void threads_stopworld(void);
-void threads_startworld(void);
-#endif
-
-#endif /* _THREADS_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 a58f7af17cc881b64b5af366aca9d22266768c55..6d622afb1459778a0748c9705c0ff46935e7f744 100644 (file)
@@ -1,9 +1,7 @@
 ## src/threads/none/Makefile.am
 ##
-## 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.
 ##
 ## 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
-##
-## Changes:
 
-## Process this file with automake to produce Makefile.in
 
-EXTRA_DIST = \
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR) -I$(top_builddir)/src -I$(top_srcdir)/contrib/vmlog
+
+LIBS =
+
+noinst_LTLIBRARIES = \
+       libthreadsnone.la
+
+libthreadsnone_la_SOURCES = \
        lock.h \
-       threads.h
+       thread-none.c \
+       thread-none.h
 
 
 ## Local variables:
diff --git a/src/threads/none/thread-none.c b/src/threads/none/thread-none.c
new file mode 100644 (file)
index 0000000..8c333ad
--- /dev/null
@@ -0,0 +1,52 @@
+/* src/threads/none/thread-none.c - fake threads
+
+   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/thread.h"
+
+#include "vm/jit/stacktrace.h"
+
+
+/* global variables ***********************************************************/
+
+stackframeinfo_t *_no_threads_stackframeinfo = 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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/threads/none/thread-none.h b/src/threads/none/thread-none.h
new file mode 100644 (file)
index 0000000..db0b685
--- /dev/null
@@ -0,0 +1,114 @@
+/* src/threads/none/thread-none.h - fake threads 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 _THREAD_NONE_H
+#define _THREAD_NONE_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "vm/builtin.h"
+
+#include "vm/jit/stacktrace.h"
+
+
+/* define some stuff we need to no-ops ****************************************/
+
+#define THREADSPECIFIC
+#define THREADOBJECT      NULL
+#define THREADINFO        NULL
+
+#define threadobject      void
+
+
+/* native-world flags *********************************************************/
+
+#define THREAD_NATIVEWORLD_ENTER /*nop*/
+#define THREAD_NATIVEWORLD_EXIT  /*nop*/
+
+
+#if defined(ENABLE_DEBUG_FILTER)
+extern u2 _no_threads_filterverbosecallctr[2];
+#define FILTERVERBOSECALLCTR (_no_threads_filterverbosecallctr)
+#endif
+
+/* state for trace java call **************************************************/
+
+#if !defined(NDEBUG)
+extern s4 _no_threads_tracejavacallindent;
+#define TRACEJAVACALLINDENT (_no_threads_tracejavacallindent)
+
+extern u4 _no_threads_tracejavacallcount;
+#define TRACEJAVACALLCOUNT (_no_threads_tracejavacallcount)
+#endif
+
+
+/* global variables ***********************************************************/
+
+extern stackframeinfo_t *_no_threads_stackframeinfo;
+
+
+/* inline functions ***********************************************************/
+
+inline static java_handle_t *thread_get_current_object(void)
+{
+       java_handle_t *o;
+
+       /* We return a fake java.lang.Thread object, otherwise we get
+          NullPointerException's in GNU Classpath. */
+
+       o = builtin_new(class_java_lang_Thread);
+
+       return o;
+}
+
+inline static stackframeinfo_t *threads_get_current_stackframeinfo(void)
+{
+       return _no_threads_stackframeinfo;
+}
+
+inline static void threads_set_current_stackframeinfo(stackframeinfo_t *sfi)
+{
+       _no_threads_stackframeinfo = sfi;
+}
+
+#endif /* _THREAD_NONE_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/threads/none/threads.h b/src/threads/none/threads.h
deleted file mode 100644 (file)
index d119e48..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* src/threads/none/threads.h - fake threads 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 _THREADS_H
-#define _THREADS_H
-
-#include "config.h"
-#include "vm/types.h"
-#include "vm/global.h"
-
-
-/* define some stuff we need to no-ops ****************************************/
-
-#define THREADSPECIFIC
-#define THREADOBJECT      NULL
-#define THREADINFO        NULL
-
-#define threadobject      void
-
-
-/* stackframeinfo *************************************************************/
-
-#define STACKFRAMEINFO      (_no_threads_stackframeinfo)
-
-
-/* native-world flags *********************************************************/
-
-#define THREAD_NATIVEWORLD_ENTER /*nop*/
-#define THREAD_NATIVEWORLD_EXIT  /*nop*/
-
-
-#if defined(ENABLE_DEBUG_FILTER)
-extern u2 _no_threads_filterverbosecallctr[2];
-#define FILTERVERBOSECALLCTR (_no_threads_filterverbosecallctr)
-#endif
-
-/* state for trace java call **************************************************/
-
-#if !defined(NDEBUG)
-extern s4 _no_threads_tracejavacallindent;
-#define TRACEJAVACALLINDENT (_no_threads_tracejavacallindent)
-
-extern u4 _no_threads_tracejavacallcount;
-#define TRACEJAVACALLCOUNT (_no_threads_tracejavacallcount)
-#endif
-
-#endif /* _THREADS_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/threads/posix/Makefile.am b/src/threads/posix/Makefile.am
new file mode 100644 (file)
index 0000000..880d47f
--- /dev/null
@@ -0,0 +1,45 @@
+## src/threads/posix/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) -I$(top_builddir)/src -I$(top_srcdir)/contrib/vmlog
+
+LIBS =
+
+noinst_LTLIBRARIES = \
+       libthreadsposix.la
+
+libthreadsposix_la_SOURCES = \
+       lock.c \
+       lock.h \
+       mutex-posix.h \
+       thread-posix.c \
+       thread-posix.h
+
+
+## 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/threads/posix/generic-primitives.h b/src/threads/posix/generic-primitives.h
new file mode 100644 (file)
index 0000000..2ab03a1
--- /dev/null
@@ -0,0 +1,87 @@
+/* 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:
+ */
diff --git a/src/threads/posix/lock.c b/src/threads/posix/lock.c
new file mode 100644 (file)
index 0000000..07a5362
--- /dev/null
@@ -0,0 +1,1625 @@
+/* src/threads/posix/lock.c - lock implementation
+
+   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 <stdlib.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "threads/lock-common.h"
+#include "threads/mutex.h"
+#include "threads/threadlist.h"
+#include "threads/thread.h"
+
+#include "threads/posix/lock.h"
+
+#include "toolbox/list.h"
+
+#include "vm/global.h"
+#include "vm/exceptions.h"
+#include "vm/finalizer.h"
+#include "vm/stringlocal.h"
+#include "vm/vm.h"
+
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
+/* arch.h must be here because it defines USE_FAKE_ATOMIC_INSTRUCTIONS */
+
+#include "arch.h"
+
+/* includes for atomic instructions: */
+
+#if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
+#include "threads/posix/generic-primitives.h"
+#else
+#include "machine-instr.h"
+#endif
+
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/cacaodbg.h"
+#endif
+
+#if defined(ENABLE_GC_BOEHM)
+# include "mm/boehm-gc/include/gc.h"
+#endif
+
+
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+# define DEBUGLOCKS(format) \
+    do { \
+        if (opt_DebugLocks) { \
+            log_println format; \
+        } \
+    } while (0)
+#else
+# define DEBUGLOCKS(format)
+#endif
+
+
+/******************************************************************************/
+/* MACROS                                                                     */
+/******************************************************************************/
+
+/* number of lock records in the first pool allocated for a thread */
+#define LOCK_INITIAL_LOCK_RECORDS 8
+
+#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                                                  */
+/******************************************************************************/
+
+/* We use a variant of the tasuki locks described in the paper
+ *     
+ *     Tamiya Onodera, Kiyokuni Kawachiya
+ *     A Study of Locking Objects with Bimodal Fields
+ *     Proceedings of the ACM OOPSLA '99, pp. 223-237
+ *     1999
+ *
+ * The underlying thin locks are a variant of the thin locks described in
+ * 
+ *     Bacon, Konuru, Murthy, Serrano
+ *     Thin Locks: Featherweight Synchronization for Java
+ *        Proceedings of the ACM Conference on Programming Language Design and 
+ *        Implementation (Montreal, Canada), SIGPLAN Notices volume 33, number 6,
+ *        June 1998
+ *
+ * In thin lock mode the lockword looks like this:
+ *
+ *     ,----------------------,-----------,---,
+ *     |      thread ID       |   count   | 0 |
+ *     `----------------------'-----------'---´
+ *
+ *     thread ID......the 'index' of the owning thread, or 0
+ *     count..........number of times the lock has been entered        minus 1
+ *     0..............the shape bit is 0 in thin lock mode
+ *
+ * In fat lock mode it is basically a lock_record_t *:
+ *
+ *     ,----------------------------------,---,
+ *     |    lock_record_t * (without LSB) | 1 |
+ *     `----------------------------------'---´
+ *
+ *     1..............the shape bit is 1 in fat lock mode
+ */
+
+#if SIZEOF_VOID_P == 8
+#define THIN_LOCK_WORD_SIZE    64
+#else
+#define THIN_LOCK_WORD_SIZE    32
+#endif
+
+#define THIN_LOCK_SHAPE_BIT    0x01
+
+#define THIN_UNLOCKED          0
+
+#define THIN_LOCK_COUNT_SHIFT  1
+#define THIN_LOCK_COUNT_SIZE   8
+#define THIN_LOCK_COUNT_INCR   (1 << THIN_LOCK_COUNT_SHIFT)
+#define THIN_LOCK_COUNT_MAX    ((1 << THIN_LOCK_COUNT_SIZE) - 1)
+#define THIN_LOCK_COUNT_MASK   (THIN_LOCK_COUNT_MAX << THIN_LOCK_COUNT_SHIFT)
+
+#define THIN_LOCK_TID_SHIFT    (THIN_LOCK_COUNT_SIZE + THIN_LOCK_COUNT_SHIFT)
+#define THIN_LOCK_TID_SIZE     (THIN_LOCK_WORD_SIZE - THIN_LOCK_TID_SHIFT)
+
+#define IS_THIN_LOCK(lockword)  (!((lockword) & THIN_LOCK_SHAPE_BIT))
+#define IS_FAT_LOCK(lockword)     ((lockword) & THIN_LOCK_SHAPE_BIT)
+
+#define GET_FAT_LOCK(lockword)  ((lock_record_t *) ((lockword) & ~THIN_LOCK_SHAPE_BIT))
+#define MAKE_FAT_LOCK(ptr)      ((uintptr_t) (ptr) | THIN_LOCK_SHAPE_BIT)
+
+#define LOCK_WORD_WITHOUT_COUNT(lockword) ((lockword) & ~THIN_LOCK_COUNT_MASK)
+#define GET_THREAD_INDEX(lockword) ((unsigned) lockword >> THIN_LOCK_TID_SHIFT)
+
+
+/* global variables ***********************************************************/
+
+/* hashtable mapping objects to lock records */
+static lock_hashtable_t lock_hashtable;
+
+
+/******************************************************************************/
+/* PROTOTYPES                                                                 */
+/******************************************************************************/
+
+static void lock_hashtable_init(void);
+
+static inline uintptr_t lock_lockword_get(threadobject *t, java_handle_t *o);
+static inline void lock_lockword_set(threadobject *t, java_handle_t *o, uintptr_t lockword);
+static void lock_record_enter(threadobject *t, lock_record_t *lr);
+static void lock_record_exit(threadobject *t, lock_record_t *lr);
+static bool lock_record_wait(threadobject *t, lock_record_t *lr, s8 millis, s4 nanos);
+static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one);
+
+
+/*============================================================================*/
+/* INITIALIZATION OF DATA STRUCTURES                                          */
+/*============================================================================*/
+
+
+/* lock_init *******************************************************************
+
+   Initialize global data for locking.
+
+*******************************************************************************/
+
+void lock_init(void)
+{
+       /* initialize lock hashtable */
+
+       lock_hashtable_init();
+
+#if defined(ENABLE_VMLOG)
+       vmlog_cacao_init_lock();
+#endif
+}
+
+
+/* lock_pre_compute_thinlock ***************************************************
+
+   Pre-compute the thin lock value for a thread index.
+
+   IN:
+      index........the thead index (>= 1)
+
+   RETURN VALUE:
+      the thin lock value for this thread index
+
+*******************************************************************************/
+
+ptrint lock_pre_compute_thinlock(s4 index)
+{
+       return (index << THIN_LOCK_TID_SHIFT) | THIN_UNLOCKED;
+}
+
+
+/* lock_record_new *************************************************************
+
+   Allocate a lock record.
+
+*******************************************************************************/
+
+static lock_record_t *lock_record_new(void)
+{
+       lock_record_t *lr;
+
+       /* allocate the data structure on the C heap */
+
+       lr = NEW(lock_record_t);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_lock_record += sizeof(lock_record_t);
+#endif
+
+       /* initialize the members */
+
+       lr->object  = NULL;
+       lr->owner   = NULL;
+       lr->count   = 0;
+       lr->waiters = list_create(OFFSET(lock_waiter_t, linkage));
+
+#if defined(ENABLE_GC_CACAO)
+       /* register the lock object as weak reference with the GC */
+
+       gc_weakreference_register(&(lr->object), GC_REFTYPE_LOCKRECORD);
+#endif
+
+       /* initialize the mutex */
+
+       mutex_init(&(lr->mutex));
+
+       DEBUGLOCKS(("[lock_record_new   : lr=%p]", (void *) lr));
+
+       return lr;
+}
+
+
+/* lock_record_free ************************************************************
+
+   Free a lock record.
+
+   IN:
+       lr....lock record to free
+
+*******************************************************************************/
+
+static void lock_record_free(lock_record_t *lr)
+{
+       DEBUGLOCKS(("[lock_record_free  : lr=%p]", (void *) lr));
+
+       /* Destroy the mutex. */
+
+       mutex_destroy(&(lr->mutex));
+
+#if defined(ENABLE_GC_CACAO)
+       /* unregister the lock object reference with the GC */
+
+       gc_weakreference_unregister(&(lr->object));
+#endif
+
+       /* Free the waiters list. */
+
+       list_free(lr->waiters);
+
+       /* Free the data structure. */
+
+       FREE(lr, lock_record_t);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_lock_record -= sizeof(lock_record_t);
+#endif
+}
+
+
+/*============================================================================*/
+/* HASHTABLE MAPPING OBJECTS TO LOCK RECORDS                                  */
+/*============================================================================*/
+
+/* lock_hashtable_init *********************************************************
+
+   Initialize the global hashtable mapping objects to lock records.
+
+*******************************************************************************/
+
+static void lock_hashtable_init(void)
+{
+       mutex_init(&(lock_hashtable.mutex));
+
+       lock_hashtable.size    = LOCK_INITIAL_HASHTABLE_SIZE;
+       lock_hashtable.entries = 0;
+       lock_hashtable.ptr     = MNEW(lock_record_t *, lock_hashtable.size);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_lock_hashtable += sizeof(lock_record_t *) * lock_hashtable.size;
+#endif
+
+       MZERO(lock_hashtable.ptr, lock_record_t *, lock_hashtable.size);
+}
+
+
+/* lock_hashtable_grow *********************************************************
+
+   Grow the lock record hashtable to about twice its current size and
+   rehash the entries.
+
+*******************************************************************************/
+
+/* must be called with hashtable mutex locked */
+static void lock_hashtable_grow(void)
+{
+       u4 oldsize;
+       u4 newsize;
+       lock_record_t **oldtable;
+       lock_record_t **newtable;
+       lock_record_t *lr;
+       lock_record_t *next;
+       u4 i;
+       u4 h;
+       u4 newslot;
+
+       /* allocate a new table */
+
+       oldsize = lock_hashtable.size;
+       newsize = oldsize*2 + 1; /* XXX should use prime numbers */
+
+       DEBUGLOCKS(("growing lock hashtable to size %d", newsize));
+
+       oldtable = lock_hashtable.ptr;
+       newtable = MNEW(lock_record_t *, newsize);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_lock_hashtable += sizeof(lock_record_t *) * newsize;
+#endif
+
+       MZERO(newtable, lock_record_t *, newsize);
+
+       /* rehash the entries */
+
+       for (i = 0; i < oldsize; i++) {
+               lr = oldtable[i];
+               while (lr) {
+                       next = lr->hashlink;
+
+                       h = heap_hashcode(lr->object);
+                       newslot = h % newsize;
+
+                       lr->hashlink = newtable[newslot];
+                       newtable[newslot] = lr;
+
+                       lr = next;
+               }
+       }
+
+       /* replace the old table */
+
+       lock_hashtable.ptr  = newtable;
+       lock_hashtable.size = newsize;
+
+       MFREE(oldtable, lock_record_t *, oldsize);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_lock_hashtable -= sizeof(lock_record_t *) * oldsize;
+#endif
+}
+
+
+/* lock_hashtable_cleanup ******************************************************
+
+   Removes (and frees) lock records which have a cleared object reference
+   from the hashtable. The locked object was reclaimed by the GC.
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+void lock_hashtable_cleanup(void)
+{
+       threadobject  *t;
+       lock_record_t *lr;
+       lock_record_t *prev;
+       lock_record_t *next;
+       int i;
+
+       t = THREADOBJECT;
+
+       /* lock the hashtable */
+
+       mutex_lock(&(lock_hashtable.mutex));
+
+       /* search the hashtable for cleared references */
+
+       for (i = 0; i < lock_hashtable.size; i++) {
+               lr = lock_hashtable.ptr[i];
+               prev = NULL;
+
+               while (lr) {
+                       next = lr->hashlink;
+
+                       /* remove lock records with cleared references */
+
+                       if (lr->object == NULL) {
+
+                               /* unlink the lock record from the hashtable */
+
+                               if (prev == NULL)
+                                       lock_hashtable.ptr[i] = next;
+                               else
+                                       prev->hashlink = next;
+
+                               /* free the lock record */
+
+                               lock_record_free(lr);
+
+                       } else {
+                               prev = lr;
+                       }
+
+                       lr = next;
+               }
+       }
+
+       /* unlock the hashtable */
+
+       mutex_unlock(&(lock_hashtable.mutex));
+}
+#endif
+
+
+/* lock_hashtable_get **********************************************************
+
+   Find the lock record for the given object.  If it does not exists,
+   yet, create it and enter it in the hashtable.
+
+   IN:
+      t....the current thread
+         o....the object to look up
+
+   RETURN VALUE:
+      the lock record to use for this object
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_BOEHM)
+static void lock_record_finalizer(void *object, void *p);
+#endif
+
+static lock_record_t *lock_hashtable_get(threadobject *t, java_handle_t *o)
+{
+       uintptr_t      lockword;
+       u4             slot;
+       lock_record_t *lr;
+
+       lockword = lock_lockword_get(t, o);
+
+       if (IS_FAT_LOCK(lockword))
+               return GET_FAT_LOCK(lockword);
+
+       /* lock the hashtable */
+
+       mutex_lock(&(lock_hashtable.mutex));
+
+       /* lookup the lock record in the hashtable */
+
+       LLNI_CRITICAL_START_THREAD(t);
+       slot = heap_hashcode(LLNI_DIRECT(o)) % lock_hashtable.size;
+       lr   = lock_hashtable.ptr[slot];
+
+       for (; lr != NULL; lr = lr->hashlink) {
+               if (lr->object == LLNI_DIRECT(o))
+                       break;
+       }
+       LLNI_CRITICAL_END_THREAD(t);
+
+       if (lr == NULL) {
+               /* not found, we must create a new one */
+
+               lr = lock_record_new();
+
+               LLNI_CRITICAL_START_THREAD(t);
+               lr->object = LLNI_DIRECT(o);
+               LLNI_CRITICAL_END_THREAD(t);
+
+#if defined(ENABLE_GC_BOEHM)
+               /* register new finalizer to clean up the lock record */
+
+               GC_REGISTER_FINALIZER(LLNI_DIRECT(o), lock_record_finalizer, 0, 0, 0);
+#endif
+
+               /* enter it in the hashtable */
+
+               lr->hashlink             = lock_hashtable.ptr[slot];
+               lock_hashtable.ptr[slot] = lr;
+               lock_hashtable.entries++;
+
+               /* check whether the hash should grow */
+
+               if (lock_hashtable.entries * 3 > lock_hashtable.size * 4) {
+                       lock_hashtable_grow();
+               }
+       }
+
+       /* unlock the hashtable */
+
+       mutex_unlock(&(lock_hashtable.mutex));
+
+       /* return the new lock record */
+
+       return lr;
+}
+
+
+/* lock_hashtable_remove *******************************************************
+
+   Remove the lock record for the given object from the hashtable
+   and free it afterwards.
+
+   IN:
+       t....the current thread
+       o....the object to look up
+
+*******************************************************************************/
+
+static void lock_hashtable_remove(threadobject *t, java_handle_t *o)
+{
+       uintptr_t      lockword;
+       lock_record_t *lr;
+       u4             slot;
+       lock_record_t *tmplr;
+
+       /* lock the hashtable */
+
+       mutex_lock(&(lock_hashtable.mutex));
+
+       /* get lock record */
+
+       lockword = lock_lockword_get(t, o);
+
+       assert(IS_FAT_LOCK(lockword));
+
+       lr = GET_FAT_LOCK(lockword);
+
+       /* remove the lock-record from the hashtable */
+
+       LLNI_CRITICAL_START_THREAD(t);
+       slot  = heap_hashcode(LLNI_DIRECT(o)) % lock_hashtable.size;
+       tmplr = lock_hashtable.ptr[slot];
+       LLNI_CRITICAL_END_THREAD(t);
+
+       if (tmplr == lr) {
+               /* special handling if it's the first in the chain */
+
+               lock_hashtable.ptr[slot] = lr->hashlink;
+       }
+       else {
+               for (; tmplr != NULL; tmplr = tmplr->hashlink) {
+                       if (tmplr->hashlink == lr) {
+                               tmplr->hashlink = lr->hashlink;
+                               break;
+                       }
+               }
+
+               assert(tmplr != NULL);
+       }
+
+       /* decrease entry count */
+
+       lock_hashtable.entries--;
+
+       /* unlock the hashtable */
+
+       mutex_unlock(&(lock_hashtable.mutex));
+
+       /* free the lock record */
+
+       lock_record_free(lr);
+}
+
+
+/* lock_record_finalizer *******************************************************
+
+   XXX Remove me for exact GC.
+
+*******************************************************************************/
+
+static void lock_record_finalizer(void *object, void *p)
+{
+       java_handle_t *o;
+       classinfo     *c;
+
+       o = (java_handle_t *) object;
+
+#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_class_get(o, c);
+
+#if !defined(NDEBUG)
+       if (opt_DebugFinalizer) {
+               log_start();
+               log_print("[finalizer lockrecord: o=%p p=%p class=", object, p);
+               class_print(c);
+               log_print("]");
+               log_finish();
+       }
+#endif
+
+       /* check for a finalizer function */
+
+       if (c->finalizer != NULL)
+               finalizer_run(object, p);
+
+       /* remove the lock-record entry from the hashtable and free it */
+
+       lock_hashtable_remove(THREADOBJECT, o);
+}
+
+
+/*============================================================================*/
+/* OBJECT LOCK INITIALIZATION                                                 */
+/*============================================================================*/
+
+
+/* lock_init_object_lock *******************************************************
+
+   Initialize the monitor pointer of the given object. The monitor gets
+   initialized to an unlocked state.
+
+*******************************************************************************/
+
+void lock_init_object_lock(java_object_t *o)
+{
+       assert(o);
+
+       o->lockword = THIN_UNLOCKED;
+}
+
+
+/*============================================================================*/
+/* LOCKING ALGORITHM                                                          */
+/*============================================================================*/
+
+
+/* lock_lockword_get ***********************************************************
+
+   Get the lockword for the given object.
+
+   IN:
+      t............the current thread
+      o............the object
+
+*******************************************************************************/
+
+static inline uintptr_t lock_lockword_get(threadobject *t, java_handle_t *o)
+{
+       uintptr_t lockword;
+
+       LLNI_CRITICAL_START_THREAD(t);
+       lockword = LLNI_DIRECT(o)->lockword;
+       LLNI_CRITICAL_END_THREAD(t);
+
+       return lockword;
+}
+
+
+/* lock_lockword_set ***********************************************************
+
+   Set the lockword for the given object.
+
+   IN:
+      t............the current thread
+      o............the object
+         lockword.....the new lockword value
+
+*******************************************************************************/
+
+static inline void lock_lockword_set(threadobject *t, java_handle_t *o, uintptr_t lockword)
+{
+       LLNI_CRITICAL_START_THREAD(t);
+       LLNI_DIRECT(o)->lockword = lockword;
+       LLNI_CRITICAL_END_THREAD(t);
+}
+
+
+/* lock_record_enter ***********************************************************
+
+   Enter the lock represented by the given lock record.
+
+   IN:
+      t.................the current thread
+         lr................the lock record
+
+*******************************************************************************/
+
+static inline void lock_record_enter(threadobject *t, lock_record_t *lr)
+{
+       mutex_lock(&(lr->mutex));
+       lr->owner = t;
+}
+
+
+/* lock_record_exit ************************************************************
+
+   Release the lock represented by the given lock record.
+
+   IN:
+      t.................the current thread
+         lr................the lock record
+
+   PRE-CONDITION:
+      The current thread must own the lock represented by this lock record.
+         This is NOT checked by this function!
+
+*******************************************************************************/
+
+static inline void lock_record_exit(threadobject *t, lock_record_t *lr)
+{
+       lr->owner = NULL;
+       mutex_unlock(&(lr->mutex));
+}
+
+
+/* lock_inflate ****************************************************************
+
+   Inflate the lock of the given object. This may only be called by the
+   owner of the monitor of the object.
+
+   IN:
+      t............the current thread
+         o............the object of which to inflate the lock
+         lr...........the lock record to install. The current thread must
+                      own the lock of this lock record!
+
+   PRE-CONDITION:
+      The current thread must be the owner of this object's monitor AND
+         of the lock record's lock!
+
+*******************************************************************************/
+
+static void lock_inflate(threadobject *t, java_handle_t *o, lock_record_t *lr)
+{
+       uintptr_t lockword;
+
+       /* get the current lock count */
+
+       lockword = lock_lockword_get(t, o);
+
+       if (IS_FAT_LOCK(lockword)) {
+               assert(GET_FAT_LOCK(lockword) == lr);
+               return;
+       }
+       else {
+               assert(LOCK_WORD_WITHOUT_COUNT(lockword) == t->thinlock);
+
+               /* copy the count from the thin lock */
+
+               lr->count = (lockword & THIN_LOCK_COUNT_MASK) >> THIN_LOCK_COUNT_SHIFT;
+       }
+
+       DEBUGLOCKS(("[lock_inflate      : lr=%p, t=%p, o=%p, o->lockword=%lx, count=%d]",
+                               lr, t, o, lockword, lr->count));
+
+       /* install it */
+
+       lock_lockword_set(t, o, MAKE_FAT_LOCK(lr));
+}
+
+
+/* TODO Move this function into threadlist.[ch]. */
+
+static threadobject *threads_lookup_thread_id(int index)
+{
+       threadobject *t;
+
+       threadlist_lock();
+
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               if (t->state == THREAD_STATE_NEW)
+                       continue;
+               if (t->index == index)
+                       break;
+       }
+
+       threadlist_unlock();
+       return t;
+}
+
+static void sable_flc_waiting(ptrint lockword, threadobject *t, java_handle_t *o)
+{
+       int index;
+       threadobject *t_other;
+       int old_flc;
+
+       index = GET_THREAD_INDEX(lockword);
+       t_other = threads_lookup_thread_id(index);
+       if (!t_other)
+/*             failure, TODO: add statistics */
+               return;
+
+       mutex_lock(&t_other->flc_lock);
+       old_flc = t_other->flc_bit;
+       t_other->flc_bit = true;
+
+       DEBUGLOCKS(("thread %d set flc bit for lock-holding thread %d",
+                               t->index, t_other->index));
+
+       /* Set FLC bit first, then read the lockword again */
+       MEMORY_BARRIER();
+
+       lockword = lock_lockword_get(t, o);
+
+       /* Lockword is still the way it was seen before */
+       if (IS_THIN_LOCK(lockword) && (GET_THREAD_INDEX(lockword) == index))
+       {
+               /* Add tuple (t, o) to the other thread's FLC list */
+               t->flc_object = o;
+               t->flc_next = t_other->flc_list;
+               t_other->flc_list = t;
+
+               for (;;)
+               {
+                       threadobject *current;
+
+                       /* Wait until another thread sees the flc bit and notifies
+                          us of unlocking. */
+                       pthread_cond_wait(&t->flc_cond, &t_other->flc_lock);
+
+                       /* Traverse FLC list looking if we're still there */
+                       current = t_other->flc_list;
+                       while (current && current != t)
+                               current = current->flc_next;
+                       if (!current)
+                               /* not in list anymore, can stop waiting */
+                               break;
+
+                       /* We are still in the list -- the other thread cannot have seen
+                          the FLC bit yet */
+                       assert(t_other->flc_bit);
+               }
+
+               t->flc_object = NULL;   /* for garbage collector? */
+               t->flc_next = NULL;
+       }
+       else
+               t_other->flc_bit = old_flc;
+
+       mutex_unlock(&t_other->flc_lock);
+}
+
+static void notify_flc_waiters(threadobject *t, java_handle_t *o)
+{
+       threadobject *current;
+
+       mutex_lock(&t->flc_lock);
+
+       current = t->flc_list;
+       while (current)
+       {
+               if (current->flc_object != o)
+               {
+                       /* The object has to be inflated so the other threads can properly
+                          block on it. */
+
+                       /* Only if not already inflated */
+                       ptrint lockword = lock_lockword_get(t, current->flc_object);
+                       if (IS_THIN_LOCK(lockword)) {
+                               lock_record_t *lr = lock_hashtable_get(t, current->flc_object);
+                               lock_record_enter(t, lr);
+
+                               DEBUGLOCKS(("thread %d inflating lock of %p to lr %p",
+                                                       t->index, (void*) current->flc_object, (void*) lr));
+
+                               lock_inflate(t, current->flc_object, lr);
+                       }
+               }
+               /* Wake the waiting thread */
+               pthread_cond_broadcast(&current->flc_cond);
+
+               current = current->flc_next;
+       }
+
+       t->flc_list = NULL;
+       t->flc_bit = false;
+       mutex_unlock(&t->flc_lock);
+}
+
+/* lock_monitor_enter **********************************************************
+
+   Acquire the monitor of the given object. If the current thread already
+   owns the monitor, the lock counter is simply increased.
+
+   This function blocks until it can acquire the monitor.
+
+   IN:
+      t............the current thread
+         o............the object of which to enter the monitor
+
+   RETURN VALUE:
+      true.........the lock has been successfully acquired
+         false........an exception has been thrown
+
+*******************************************************************************/
+
+bool lock_monitor_enter(java_handle_t *o)
+{
+       threadobject  *t;
+       /* CAUTION: This code assumes that ptrint is unsigned! */
+       ptrint         lockword;
+       ptrint         thinlock;
+       lock_record_t *lr;
+
+       if (o == NULL) {
+               exceptions_throw_nullpointerexception();
+               return false;
+       }
+
+       t = THREADOBJECT;
+
+       thinlock = t->thinlock;
+
+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);
+       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();
+               return true;
+       }
+
+       /* next common case: recursive lock with small recursion count */
+       /* We don't have to worry about stale values here, as any stale value  */
+       /* will indicate another thread holding the lock (or an inflated lock) */
+
+       if (LOCK_WORD_WITHOUT_COUNT(lockword) == thinlock) {
+               /* we own this monitor               */
+               /* check the current recursion count */
+
+               if ((lockword ^ thinlock) < (THIN_LOCK_COUNT_MAX << THIN_LOCK_COUNT_SHIFT))
+               {
+                       /* the recursion count is low enough */
+
+                       lock_lockword_set(t, o, lockword + THIN_LOCK_COUNT_INCR);
+
+                       /* success. we locked it */
+                       return true;
+               }
+               else {
+                       /* recursion count overflow */
+
+                       lr = lock_hashtable_get(t, o);
+                       lock_record_enter(t, lr);
+                       lock_inflate(t, o, lr);
+                       lr->count++;
+
+                       notify_flc_waiters(t, o);
+
+                       return true;
+               }
+       }
+
+       /* the lock is either contented or fat */
+
+       if (IS_FAT_LOCK(lockword)) {
+
+               lr = GET_FAT_LOCK(lockword);
+
+               /* check for recursive entering */
+               if (lr->owner == t) {
+                       lr->count++;
+                       return true;
+               }
+
+               /* acquire the mutex of the lock record */
+
+               lock_record_enter(t, lr);
+
+               assert(lr->count == 0);
+
+               return true;
+       }
+
+       /****** inflation path ******/
+
+#if defined(ENABLE_JVMTI)
+       /* Monitor Contended Enter */
+       jvmti_MonitorContendedEntering(false, o);
+#endif
+
+       sable_flc_waiting(lockword, t, o);
+
+#if defined(ENABLE_JVMTI)
+       /* Monitor Contended Entered */
+       jvmti_MonitorContendedEntering(true, o);
+#endif
+       goto retry;
+}
+
+
+/* lock_monitor_exit ***********************************************************
+
+   Decrement the counter of a (currently owned) monitor. If the counter
+   reaches zero, release the monitor.
+
+   If the current thread is not the owner of the monitor, an 
+   IllegalMonitorState exception is thrown.
+
+   IN:
+      t............the current thread
+         o............the object of which to exit the monitor
+
+   RETURN VALUE:
+      true.........everything ok,
+         false........an exception has been thrown
+
+*******************************************************************************/
+
+bool lock_monitor_exit(java_handle_t *o)
+{
+       threadobject *t;
+       uintptr_t     lockword;
+       ptrint        thinlock;
+
+       if (o == NULL) {
+               exceptions_throw_nullpointerexception();
+               return false;
+       }
+
+       t = THREADOBJECT;
+
+       thinlock = t->thinlock;
+
+       /* We don't have to worry about stale values here, as any stale value */
+       /* will indicate that we don't own the lock.                          */
+
+       lockword = lock_lockword_get(t, o);
+
+       /* most common case: we release a thin lock that we hold once */
+
+       if (lockword == thinlock) {
+               /* memory barrier for Java Memory Model */
+               STORE_ORDER_BARRIER();
+               lock_lockword_set(t, o, THIN_UNLOCKED);
+               /* memory barrier for thin locking */
+               MEMORY_BARRIER();
+
+               /* check if there has been a flat lock contention on this object */
+
+               if (t->flc_bit) {
+                       DEBUGLOCKS(("thread %d saw flc bit", t->index));
+
+                       /* there has been a contention on this thin lock */
+                       notify_flc_waiters(t, o);
+               }
+
+               return true;
+       }
+
+       /* next common case: we release a recursive lock, count > 0 */
+
+       if (LOCK_WORD_WITHOUT_COUNT(lockword) == thinlock) {
+               lock_lockword_set(t, o, lockword - THIN_LOCK_COUNT_INCR);
+               return true;
+       }
+
+       /* either the lock is fat, or we don't hold it at all */
+
+       if (IS_FAT_LOCK(lockword)) {
+
+               lock_record_t *lr;
+
+               lr = GET_FAT_LOCK(lockword);
+
+               /* check if we own this monitor */
+               /* We don't have to worry about stale values here, as any stale value */
+               /* will be != t and thus fail this check.                             */
+
+               if (lr->owner != t) {
+                       exceptions_throw_illegalmonitorstateexception();
+                       return false;
+               }
+
+               /* { the current thread `t` owns the lock record `lr` on object `o` } */
+
+               if (lr->count != 0) {
+                       /* we had locked this one recursively. just decrement, it will */
+                       /* still be locked. */
+                       lr->count--;
+                       return true;
+               }
+
+               /* unlock this lock record */
+
+               lr->owner = NULL;
+               mutex_unlock(&(lr->mutex));
+
+               return true;
+       }
+
+       /* legal thin lock cases have been handled above, so this is an error */
+
+       exceptions_throw_illegalmonitorstateexception();
+
+       return false;
+}
+
+
+/* lock_record_add_waiter ******************************************************
+
+   Add a thread to the list of waiting threads of a lock record.
+
+   IN:
+      lr...........the lock record
+      thread.......the thread to add
+
+*******************************************************************************/
+
+static void lock_record_add_waiter(lock_record_t *lr, threadobject *thread)
+{
+       lock_waiter_t *w;
+
+       /* Allocate a waiter data structure. */
+
+       w = NEW(lock_waiter_t);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_lock_waiter += sizeof(lock_waiter_t);
+#endif
+
+       /* Store the thread in the waiter structure. */
+
+       w->thread = thread;
+
+       /* Add the waiter as last entry to waiters list. */
+
+       list_add_last(lr->waiters, w);
+}
+
+
+/* lock_record_remove_waiter ***************************************************
+
+   Remove a thread from the list of waiting threads of a lock record.
+
+   IN:
+      lr...........the lock record
+      t............the current thread
+
+   PRE-CONDITION:
+      The current thread must be the owner of the lock record.
+   
+*******************************************************************************/
+
+static void lock_record_remove_waiter(lock_record_t *lr, threadobject *thread)
+{
+       list_t        *l;
+       lock_waiter_t *w;
+
+       /* Get the waiters list. */
+
+       l = lr->waiters;
+
+       for (w = list_first(l); w != NULL; w = list_next(l, w)) {
+               if (w->thread == thread) {
+                       /* Remove the waiter entry from the list. */
+
+                       list_remove(l, w);
+
+                       /* Free the waiter data structure. */
+
+                       FREE(w, lock_waiter_t);
+
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               size_lock_waiter -= sizeof(lock_waiter_t);
+#endif
+
+                       return;
+               }
+       }
+
+       /* This should never happen. */
+
+       vm_abort("lock_record_remove_waiter: thread not found in list of waiters\n");
+}
+
+
+/* lock_record_wait ************************************************************
+
+   Wait on a lock record for a given (maximum) amount of time.
+
+   IN:
+      t............the current thread
+         lr...........the lock record
+         millis.......milliseconds of timeout
+         nanos........nanoseconds of timeout
+
+   RETURN VALUE:
+      true.........we have been interrupted,
+      false........everything ok
+
+   PRE-CONDITION:
+      The current thread must be the owner of the lock record.
+         This is NOT checked by this function!
+   
+*******************************************************************************/
+
+static bool lock_record_wait(threadobject *thread, lock_record_t *lr, s8 millis, s4 nanos)
+{
+       s4   lockcount;
+       bool wasinterrupted = false;
+
+       DEBUGLOCKS(("[lock_record_wait  : lr=%p, t=%p, millis=%lld, nanos=%d]",
+                               lr, thread, millis, nanos));
+
+       /* { the thread t owns the fat lock record lr on the object o } */
+
+       /* register us as waiter for this object */
+
+       lock_record_add_waiter(lr, thread);
+
+       /* remember the old lock count */
+
+       lockcount = lr->count;
+
+       /* unlock this record */
+
+       lr->count = 0;
+       lock_record_exit(thread, lr);
+
+       /* wait until notified/interrupted/timed out */
+
+       threads_wait_with_timeout_relative(thread, millis, nanos);
+
+       /* re-enter the monitor */
+
+       lock_record_enter(thread, lr);
+
+       /* remove us from the list of waiting threads */
+
+       lock_record_remove_waiter(lr, thread);
+
+       /* restore the old lock count */
+
+       lr->count = lockcount;
+
+       /* We can only be signaled OR interrupted, not both. If both flags
+          are set, reset only signaled and leave the thread in
+          interrupted state. Otherwise, clear both. */
+
+       if (!thread->signaled) {
+               wasinterrupted = thread->interrupted;
+               thread->interrupted = false;
+       }
+
+       thread->signaled = false;
+
+       /* return if we have been interrupted */
+
+       return wasinterrupted;
+}
+
+
+/* lock_monitor_wait ***********************************************************
+
+   Wait on an object for a given (maximum) amount of time.
+
+   IN:
+      t............the current thread
+         o............the object
+         millis.......milliseconds of timeout
+         nanos........nanoseconds of timeout
+
+   PRE-CONDITION:
+      The current thread must be the owner of the object's monitor.
+   
+*******************************************************************************/
+
+static void lock_monitor_wait(threadobject *t, java_handle_t *o, s8 millis, s4 nanos)
+{
+       uintptr_t      lockword;
+       lock_record_t *lr;
+
+       lockword = lock_lockword_get(t, o);
+
+       /* check if we own this monitor */
+       /* We don't have to worry about stale values here, as any stale value */
+       /* will fail this check.                                              */
+
+       if (IS_FAT_LOCK(lockword)) {
+
+               lr = GET_FAT_LOCK(lockword);
+
+               if (lr->owner != t) {
+                       exceptions_throw_illegalmonitorstateexception();
+                       return;
+               }
+       }
+       else {
+               /* it's a thin lock */
+
+               if (LOCK_WORD_WITHOUT_COUNT(lockword) != t->thinlock) {
+                       exceptions_throw_illegalmonitorstateexception();
+                       return;
+               }
+
+               /* inflate this lock */
+
+               lr = lock_hashtable_get(t, o);
+               lock_record_enter(t, lr);
+               lock_inflate(t, o, lr);
+
+               notify_flc_waiters(t, o);
+       }
+
+       /* { the thread t owns the fat lock record lr on the object o } */
+
+       if (lock_record_wait(t, lr, millis, nanos))
+               exceptions_throw_interruptedexception();
+}
+
+
+/* lock_record_notify **********************************************************
+
+   Notify one thread or all threads waiting on the given lock record.
+
+   IN:
+      t............the current thread
+         lr...........the lock record
+         one..........if true, only notify one thread
+
+   PRE-CONDITION:
+      The current thread must be the owner of the lock record.
+         This is NOT checked by this function!
+   
+*******************************************************************************/
+
+static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one)
+{
+       list_t        *l;
+       lock_waiter_t *w;
+       threadobject  *waitingthread;
+
+       /* { the thread t owns the fat lock record lr on the object o } */
+
+       /* Get the waiters list. */
+
+       l = lr->waiters;
+
+       for (w = list_first(l); w != NULL; w = list_next(l, w)) {
+               /* signal the waiting thread */
+
+               waitingthread = w->thread;
+
+               /* We must skip threads which have already been notified. They will
+                  remove themselves from the list. */
+
+               if (waitingthread->signaled)
+                       continue;
+
+               /* Enter the wait-mutex. */
+
+               mutex_lock(&(waitingthread->waitmutex));
+
+               DEBUGLOCKS(("[lock_record_notify: lr=%p, t=%p, waitingthread=%p, sleeping=%d, one=%d]",
+                                       lr, t, waitingthread, waitingthread->sleeping, one));
+
+               /* Signal the thread if it's sleeping. sleeping can be false
+                  when the waiting thread is blocked between giving up the
+                  monitor and entering the waitmutex. It will eventually
+                  observe that it's signaled and refrain from going to
+                  sleep. */
+
+               if (waitingthread->sleeping)
+                       pthread_cond_signal(&(waitingthread->waitcond));
+
+               /* Mark the thread as signaled. */
+
+               waitingthread->signaled = true;
+
+               /* Leave the wait-mutex. */
+
+               mutex_unlock(&(waitingthread->waitmutex));
+
+               /* if we should only wake one, we are done */
+
+               if (one)
+                       break;
+       }
+}
+
+
+/* lock_monitor_notify *********************************************************
+
+   Notify one thread or all threads waiting on the given object.
+
+   IN:
+      t............the current thread
+         o............the object
+         one..........if true, only notify one thread
+
+   PRE-CONDITION:
+      The current thread must be the owner of the object's monitor.
+   
+*******************************************************************************/
+
+static void lock_monitor_notify(threadobject *t, java_handle_t *o, bool one)
+{
+       uintptr_t      lockword;
+       lock_record_t *lr;
+
+       lockword = lock_lockword_get(t, o);
+
+       /* check if we own this monitor */
+       /* We don't have to worry about stale values here, as any stale value */
+       /* will fail this check.                                              */
+
+       if (IS_FAT_LOCK(lockword)) {
+
+               lr = GET_FAT_LOCK(lockword);
+
+               if (lr->owner != t) {
+                       exceptions_throw_illegalmonitorstateexception();
+                       return;
+               }
+       }
+       else {
+               /* it's a thin lock */
+
+               if (LOCK_WORD_WITHOUT_COUNT(lockword) != t->thinlock) {
+                       exceptions_throw_illegalmonitorstateexception();
+                       return;
+               }
+
+               /* no thread can wait on a thin lock, so there's nothing to do. */
+               return;
+       }
+
+       /* { the thread t owns the fat lock record lr on the object o } */
+
+       lock_record_notify(t, lr, one);
+}
+
+
+
+/*============================================================================*/
+/* INQUIRY FUNCIONS                                                           */
+/*============================================================================*/
+
+
+/* lock_is_held_by_current_thread **********************************************
+
+   Return true if the current thread owns the monitor of the given object.
+
+   IN:
+         o............the object
+
+   RETURN VALUE:
+      true, if the current thread holds the lock of this object.
+   
+*******************************************************************************/
+
+bool lock_is_held_by_current_thread(java_handle_t *o)
+{
+       threadobject  *t;
+       uintptr_t      lockword;
+       lock_record_t *lr;
+
+       t = THREADOBJECT;
+
+       /* check if we own this monitor */
+       /* We don't have to worry about stale values here, as any stale value */
+       /* will fail this check.                                              */
+
+       lockword = lock_lockword_get(t, o);
+
+       if (IS_FAT_LOCK(lockword)) {
+               /* it's a fat lock */
+
+               lr = GET_FAT_LOCK(lockword);
+
+               return (lr->owner == t);
+       }
+       else {
+               /* it's a thin lock */
+
+               return (LOCK_WORD_WITHOUT_COUNT(lockword) == t->thinlock);
+       }
+}
+
+
+
+/*============================================================================*/
+/* WRAPPERS FOR OPERATIONS ON THE CURRENT THREAD                              */
+/*============================================================================*/
+
+
+/* lock_wait_for_object ********************************************************
+
+   Wait for the given object.
+
+   IN:
+         o............the object
+         millis.......milliseconds to wait
+         nanos........nanoseconds to wait
+   
+*******************************************************************************/
+
+void lock_wait_for_object(java_handle_t *o, s8 millis, s4 nanos)
+{
+       threadobject *thread;
+
+       thread = THREADOBJECT;
+
+       lock_monitor_wait(thread, o, millis, nanos);
+}
+
+
+/* lock_notify_object **********************************************************
+
+   Notify one thread waiting on the given object.
+
+   IN:
+         o............the object
+   
+*******************************************************************************/
+
+void lock_notify_object(java_handle_t *o)
+{
+       threadobject *thread;
+
+       thread = THREADOBJECT;
+
+       lock_monitor_notify(thread, o, true);
+}
+
+
+/* lock_notify_all_object ******************************************************
+
+   Notify all threads waiting on the given object.
+
+   IN:
+         o............the object
+   
+*******************************************************************************/
+
+void lock_notify_all_object(java_handle_t *o)
+{
+       threadobject *thread;
+
+       thread = THREADOBJECT;
+
+       lock_monitor_notify(thread, o, false);
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of 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/lock.h b/src/threads/posix/lock.h
new file mode 100644 (file)
index 0000000..56e1722
--- /dev/null
@@ -0,0 +1,119 @@
+/* src/threads/posix/lock.h - lock implementation
+
+   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 _LOCK_H
+#define _LOCK_H
+
+#include "config.h"
+
+#include <pthread.h>
+
+#include "vm/types.h"
+
+#include "native/llni.h"
+
+#include "threads/mutex.h"
+
+#include "toolbox/list.h"
+
+#include "vm/global.h"
+
+
+
+/* typedefs *******************************************************************/
+
+typedef struct lock_record_t    lock_record_t;
+typedef struct lock_waiter_t    lock_waiter_t;
+typedef struct lock_hashtable_t lock_hashtable_t;
+
+
+/* lock_waiter_t ***************************************************************
+
+   List node for storing a waiting thread.
+
+*******************************************************************************/
+
+struct lock_waiter_t {
+       struct threadobject *thread;        /* the waiting thread                 */
+       listnode_t           linkage;
+};
+
+
+/* lock_record_t ***************************************************************
+
+   Lock record struct representing an inflated ("fat") lock.
+
+*******************************************************************************/
+
+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       */
+       list_t              *waiters;            /* list of threads waiting       */
+       lock_record_t       *hashlink;           /* next record in hash chain     */
+};
+
+
+/* lock_hashtable_t ************************************************************
+   The global hashtable mapping objects to lock records.
+
+*******************************************************************************/
+
+struct lock_hashtable_t {
+       mutex_t              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. */
+};
+
+
+/* defines ********************************************************************/
+
+#define LOCK_INIT_OBJECT_LOCK(o) lock_init_object_lock((java_object_t *) (o))
+
+#define LOCK_MONITOR_ENTER(o)    lock_monitor_enter((java_handle_t *) LLNI_QUICKWRAP(o))
+#define LOCK_MONITOR_EXIT(o)     lock_monitor_exit((java_handle_t *) LLNI_QUICKWRAP(o))
+
+#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))
+
+#endif /* _LOCK_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.h b/src/threads/posix/mutex-posix.h
new file mode 100644 (file)
index 0000000..b178c51
--- /dev/null
@@ -0,0 +1,150 @@
+/* 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/thread-posix.c b/src/threads/posix/thread-posix.c
new file mode 100644 (file)
index 0000000..7d53fec
--- /dev/null
@@ -0,0 +1,1824 @@
+/* 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_CLASSPATH_GNU)
+# 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__)
+# if defined(__LINUX__)
+#  define GC_LINUX_THREADS
+# elif defined(__IRIX__)
+#  define GC_IRIX_THREADS
+# endif
+# include <semaphore.h>
+# if defined(ENABLE_GC_BOEHM)
+#  include "mm/boehm-gc/include/gc.h"
+# endif
+#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;
+
+/* XXX We disable that whole bunch of code until we have the exact-GC
+   running. */
+
+#if 1
+
+/* this is one of the STOPWORLD_FROM_ constants, telling why the world is     */
+/* being stopped                                                              */
+static volatile int stopworldwhere;
+
+/* 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 /* 0 */
+
+/* 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. */
+
+#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
+
+#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.
+
+*******************************************************************************/
+
+#if !defined(DISABLE_GC)
+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. */
+}
+#endif /* !defined(DISABLE_GC) */
+
+
+/* threads_startworld **********************************************************
+
+   Starts the world again after it has previously been stopped. 
+
+*******************************************************************************/
+
+#if !defined(DISABLE_GC)
+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->sleeping = 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 mutext */
+
+       mutex_init(&mutex_gc);
+#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_sem_init(&suspend_ack, 0, 0);
+}
+
+
+/* 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_CLASSPATH_GNU)
+       java_lang_VMThread *vmt;
+#endif
+       sem_t              *psem;
+       classinfo          *c;
+       methodinfo         *m;
+       java_handle_t      *o;
+       functionptr         function;
+
+#if defined(ENABLE_INTRP)
+       u1 *intrp_thread_stack;
+
+       /* 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);
+
+       /* 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_CLASSPATH_GNU)
+               /* 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_CLASSPATH_SUN) || defined(WITH_CLASSPATH_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_CLASSPATH_GNU)
+               /* 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_CLASSPATH_SUN) || defined(WITH_CLASSPATH_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) threads_detach_thread(t);
+
+       /* 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);
+}
+
+
+/* threads_detach_thread *******************************************************
+
+   Detaches the passed thread from the VM.  Used in JNI.
+
+*******************************************************************************/
+
+bool threads_detach_thread(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
+
+    /* 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_CLASSPATH_GNU)
+               LLNI_field_get_ref(object, exceptionHandler, handler);
+# elif defined(WITH_CLASSPATH_SUN)
+               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_CLASSPATH_GNU)
+               m = class_resolveclassmethod(c,
+                                                                        utf_removeThread,
+                                                                        utf_java_lang_Thread__V,
+                                                                        class_java_lang_ThreadGroup,
+                                                                        true);
+# elif defined(WITH_CLASSPATH_SUN)
+               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;
+}
+
+
+/* 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 */
+
+#if defined(ENABLE_GC_CACAO)
+       /* 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;
+
+               }
+       }
+#endif
+
+       /* 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;
+}
+
+
+/* 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);
+
+       /* mark us as sleeping */
+
+       t->sleeping = true;
+
+       /* 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);
+               }
+       }
+
+       t->sleeping    = false;
+
+       /* 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)
+{
+       /* 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, SIGHUP);
+
+       if (thread->sleeping)
+               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.h b/src/threads/posix/thread-posix.h
new file mode 100644 (file)
index 0000000..99e6cb0
--- /dev/null
@@ -0,0 +1,310 @@
+/* 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 THREADSPECIFIC    __thread
+#define THREADOBJECT      thread_current
+
+extern __thread threadobject *thread_current;
+
+#else /* defined(HAVE___THREAD) */
+
+#define THREADSPECIFIC
+#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                  sleeping;
+
+       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);
+
+bool threads_detach_thread(threadobject *thread);
+
+bool threads_suspend_thread(threadobject *thread, s4 reason);
+void threads_suspend_ack(u1* pc, u1* sp);
+bool threads_resume_thread(threadobject *thread);
+
+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(DISABLE_GC)
+void threads_stopworld(void);
+void threads_startworld(void);
+#endif
+
+#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/thread.c b/src/threads/thread.c
new file mode 100644 (file)
index 0000000..1a7880f
--- /dev/null
@@ -0,0 +1,1218 @@
+/* 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"
+
+#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_CLASSPATH_GNU)
+# 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();
+
+       /* 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_CLASSPATH_GNU)
+
+       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_CLASSPATH_SUN)
+
+       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_CLASSPATH_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_CLASSPATH_GNU)
+       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_CLASSPATH_GNU)
+
+       /* 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_CLASSPATH_SUN)
+
+       /* 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_CLASSPATH_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_CLASSPATH_GNU)
+
+       /* 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_CLASSPATH_SUN)
+
+       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_CLASSPATH_GNU)
+       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_CLASSPATH_GNU)
+
+       /* 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_CLASSPATH_SUN)
+
+       /* Nothing to do. */
+
+#elif defined(WITH_CLASSPATH_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);
+}
+
+
+/* threads_attach_current_thread ***********************************************
+
+   Attaches the current thread to the VM.  Used in JNI.
+
+*******************************************************************************/
+
+bool threads_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;
+}
+
+
+/* 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_CLASSPATH_GNU)
+       java_lang_String *name;
+#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_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_CLASSPATH_GNU)
+
+       javastring_fprint((java_handle_t *) name, stream);
+
+#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_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_CLASSPATH_GNU)
+       java_lang_VMThread *vmto;
+       java_lang_Object   *to;
+#endif
+#if defined(WITH_CLASSPATH_SUN)
+       bool                equal;
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+
+       vmto = (java_lang_VMThread *) h;
+
+       LLNI_field_get_val(vmto, vmdata, to);
+
+       t = (threadobject *) to;
+
+#elif defined(WITH_CLASSPATH_SUN)
+
+       /* 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_CLASSPATH_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.h b/src/threads/thread.h
new file mode 100644 (file)
index 0000000..50099e3
--- /dev/null
@@ -0,0 +1,349 @@
+/* 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)
+{
+       return t->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          threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+
+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/threadlist.c b/src/threads/threadlist.c
new file mode 100644 (file)
index 0000000..8b7d92e
--- /dev/null
@@ -0,0 +1,379 @@
+/* src/threads/threadlist.c - different thread-lists
+
+   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 "mm/memory.h"
+
+#include "threads/mutex.h"
+#include "threads/threadlist.h"
+#include "threads/thread.h"
+
+#include "toolbox/list.h"
+
+#include "vmcore/options.h"
+
+
+/* global variables ***********************************************************/
+
+static mutex_t 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 */
+static list_t *list_thread_index_free;
+
+
+typedef struct thread_index_t {
+       int32_t    index;
+       listnode_t linkage;
+} thread_index_t;
+
+
+/* threadlist_init *************************************************************
+
+   Initialize thread-lists.
+
+*******************************************************************************/
+
+void threadlist_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("threadlist_init");
+
+       /* Initialize the thread list mutex. */
+
+       mutex_init(&threadlist_mutex);
+
+       /* Initialize the thread lists. */
+
+       list_thread            = list_create(OFFSET(threadobject, linkage));
+       list_thread_free       = list_create(OFFSET(threadobject, linkage_free));
+       list_thread_index_free = list_create(OFFSET(thread_index_t, linkage));
+}
+
+
+/* threadlist_lock *************************************************************
+
+   Enter the thread list mutex.
+
+   NOTE: We need this function as we can't use an internal lock for
+         the threads lists because the thread's lock is initialized in
+         threads_table_add (when we have the thread index), but we
+         already need the lock at the entry of the function.
+
+*******************************************************************************/
+
+void threadlist_lock(void)
+{
+       mutex_lock(&threadlist_mutex);
+}
+
+
+/* threadlist_unlock *********************************************************
+
+   Leave the thread list mutex.
+
+*******************************************************************************/
+
+void threadlist_unlock(void)
+{
+       mutex_unlock(&threadlist_mutex);
+}
+
+
+/* threadlist_add **************************************************************
+
+   Add the given threadobject as last entry to the thread list.
+
+   IN:
+       t ... threadobject to be added
+
+*******************************************************************************/
+
+void threadlist_add(threadobject *t)
+{
+       list_add_last(list_thread, t);
+}
+
+
+/* threadlist_remove ***********************************************************
+
+   Remove the given threadobject from the thread list.
+
+   IN:
+       t ... threadobject to be removed
+
+*******************************************************************************/
+
+void threadlist_remove(threadobject *t)
+{
+       list_remove(list_thread, t);
+}
+
+
+/* threadlist_first ************************************************************
+
+   Return the first entry in the thread list.
+
+   RETURN:
+       threadobject of the first entry
+
+*******************************************************************************/
+
+threadobject *threadlist_first(void)
+{
+       threadobject *t;
+
+       t = list_first(list_thread);
+
+       return t;
+}
+
+
+/* threadlist_next *************************************************************
+
+   Return the next entry in the thread list.
+
+   IN:
+       t ... threadobject to get next thread of
+
+   RETURN:
+       threadobject of the next entry
+
+*******************************************************************************/
+
+threadobject *threadlist_next(threadobject *t)
+{
+       threadobject *next;
+
+       next = list_next(list_thread, t);
+
+       return next;
+}
+
+
+/* threadlist_free_add *********************************************************
+
+   Add the given threadobject as last entry to the free thread list.
+
+   IN:
+       t ... threadobject to be added
+
+*******************************************************************************/
+
+void threadlist_free_add(threadobject *t)
+{
+       list_add_last(list_thread_free, t);
+}
+
+
+/* threadlist_free_remove ******************************************************
+
+   Remove the given entry from the free thread list.
+
+   IN:
+       t ... threadobject to be removed
+
+*******************************************************************************/
+
+void threadlist_free_remove(threadobject *t)
+{
+       list_remove(list_thread_free, t);
+}
+
+
+/* threadlist_free_first *******************************************************
+
+   Return the first entry in the free thread list.
+
+   RETURN:
+       threadobject of the first free entry
+
+*******************************************************************************/
+
+threadobject *threadlist_free_first(void)
+{
+       threadobject *t;
+
+       t = list_first(list_thread_free);
+
+       return t;
+}
+
+
+/* threadlist_get_non_daemons **************************************************
+
+   Return the number of non-daemon threads.
+
+   NOTE: This function does a linear-search over the threads list,
+         because it's only used for joining the threads.
+
+*******************************************************************************/
+
+int threadlist_get_non_daemons(void)
+{
+       threadobject *t;
+       int           nondaemons;
+
+       /* Lock the thread lists. */
+
+       threadlist_lock();
+
+       nondaemons = 0;
+
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               if (!thread_is_daemon(t))
+                       nondaemons++;
+       }
+
+       /* Unlock the thread lists. */
+
+       threadlist_unlock();
+
+       return nondaemons;
+}
+
+
+/* threadlist_index_first ******************************************************
+
+   Return the first entry in the thread-index list.
+
+   RETURN VALUE:
+       thread-index structure
+
+*******************************************************************************/
+
+static inline thread_index_t *threadlist_index_first(void)
+{
+       thread_index_t *ti;
+
+       ti = list_first(list_thread_index_free);
+
+       return ti;
+}
+
+
+/* threadlist_index_add ********************************************************
+
+   Add the given thread-index to the thread-index free list.
+
+   IN:
+       i ... thread index
+
+*******************************************************************************/
+
+void threadlist_index_add(int index)
+{
+       thread_index_t *ti;
+
+       ti = NEW(thread_index_t);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_thread_index_t += sizeof(thread_index_t);
+#endif
+
+       /* Set the index in the structure. */
+
+       ti->index = index;
+
+       list_add_last(list_thread_index_free, ti);
+}
+
+
+/* threadlist_index_remove *****************************************************
+
+   Remove the given thread-index from the thread-index list and free
+   the thread-index structure.
+
+   IN:
+       ti ... thread-index structure
+
+*******************************************************************************/
+
+static inline void threadlist_index_remove(thread_index_t *ti)
+{
+       list_remove(list_thread_index_free, ti);
+
+       FREE(ti, thread_index_t);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_thread_index_t -= sizeof(thread_index_t);
+#endif
+}
+
+
+/* threadlist_get_free_index ***************************************************
+
+   Return a free thread index.
+
+   RETURN VALUE:
+       free thread index
+
+*******************************************************************************/
+
+int threadlist_get_free_index(void)
+{
+       thread_index_t *ti;
+       int             index;
+
+       /* Try to get a thread index from the free-list. */
+
+       ti = threadlist_index_first();
+
+       /* Is a free thread index available? */
+
+       if (ti != NULL) {
+               /* Yes, get the index and remove it from the free list. */
+
+               index = ti->index;
+
+               threadlist_index_remove(ti);
+       }
+       else {
+               /* Get a new the thread index. */
+
+               index = list_thread->size + 1;
+       }
+
+       return index;
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of 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/threadlist.h b/src/threads/threadlist.h
new file mode 100644 (file)
index 0000000..b3dd2cb
--- /dev/null
@@ -0,0 +1,76 @@
+/* src/threads/threadlist.h - different thread-lists
+
+   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 _THREADLIST_H
+#define _THREADLIST_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/thread.h"
+
+
+/* function prototypes ********************************************************/
+
+void          threadlist_init(void);
+
+void          threadlist_add(threadobject *t);
+void          threadlist_remove(threadobject *t);
+threadobject *threadlist_first(void);
+threadobject *threadlist_next(threadobject *t);
+
+void          threadlist_free_add(threadobject *t);
+void          threadlist_free_remove(threadobject *t);
+threadobject *threadlist_free_first(void);
+
+int           threadlist_get_non_daemons(void);
+
+void          threadlist_index_add(int index);
+int           threadlist_get_free_index(void);
+
+/* implementation specific functions */
+
+void          threadlist_impl_init(void);
+
+void          threadlist_lock(void);
+void          threadlist_unlock(void);
+
+#endif /* _THREADLIST_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/threads-common.c b/src/threads/threads-common.c
deleted file mode 100644 (file)
index 5117772..0000000
+++ /dev/null
@@ -1,933 +0,0 @@
-/* src/threads/threads-common.c - machine independent thread 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
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public 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"
-
-#include "native/jni.h"
-#include "native/llni.h"
-
-#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Thread.h"
-
-#if defined(WITH_CLASSPATH_GNU)
-# include "native/include/java_lang_Throwable.h"
-# include "native/include/java_lang_VMThread.h"
-#endif
-
-#include "threads/critical.h"
-#include "threads/lock-common.h"
-#include "threads/threads-common.h"
-
-#include "toolbox/list.h"
-
-#include "vm/builtin.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
-
-#include "vm/jit/stacktrace.h"
-
-#include "vmcore/class.h"
-#include "vmcore/options.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#include "vmcore/utf8.h"
-
-
-/* global variables ***********************************************************/
-
-/* global threads list */
-static list_t *list_threads;
-
-/* global threads free-list */
-
-typedef struct thread_index_t {
-       int32_t    index;
-       listnode_t linkage;
-} thread_index_t;
-
-static list_t *list_free_thread_index;
-
-#if defined(__LINUX__)
-/* XXX Remove for exact-GC. */
-bool threads_pthreads_implementation_nptl;
-#endif
-
-
-/* threads_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_preinit(void)
-{
-       threadobject *mainthread;
-#if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
-       char         *pathbuf;
-       size_t        len;
-#endif
-
-#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 lists */
-
-       list_threads           = list_create(OFFSET(threadobject, linkage));
-       list_free_thread_index = list_create(OFFSET(thread_index_t, linkage));
-
-       /* Initialize the threads implementation (sets the thinlock on the
-          main thread). */
-
-       threads_impl_preinit();
-
-       /* create internal thread data-structure for the main thread */
-
-       mainthread = threads_thread_new();
-
-       /* 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 */
-
-       threads_set_current_threadobject(mainthread);
-
-       /* initialize locking subsystems */
-
-       lock_init();
-
-       /* initialize the critical section */
-
-       critical_init();
-}
-
-
-/* threads_list_first **********************************************************
-
-   Return the first entry in the threads list.
-
-   NOTE: This function does not lock the lists.
-
-*******************************************************************************/
-
-threadobject *threads_list_first(void)
-{
-       threadobject *t;
-
-       t = list_first_unsynced(list_threads);
-
-       return t;
-}
-
-
-/* threads_list_next ***********************************************************
-
-   Return the next entry in the threads list.
-
-   NOTE: This function does not lock the lists.
-
-*******************************************************************************/
-
-threadobject *threads_list_next(threadobject *t)
-{
-       threadobject *next;
-
-       next = list_next_unsynced(list_threads, t);
-
-       return next;
-}
-
-
-/* threads_list_get_non_daemons ************************************************
-
-   Return the number of non-daemon threads.
-
-   NOTE: This function does a linear-search over the threads list,
-         because it's only used for joining the threads.
-
-*******************************************************************************/
-
-s4 threads_list_get_non_daemons(void)
-{
-       threadobject *t;
-       s4            nondaemons;
-
-       /* lock the threads lists */
-
-       threads_list_lock();
-
-       nondaemons = 0;
-
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
-               if (!(t->flags & THREAD_FLAG_DAEMON))
-                       nondaemons++;
-       }
-
-       /* unlock the threads lists */
-
-       threads_list_unlock();
-
-       return nondaemons;
-}
-
-
-/* threads_thread_new **********************************************************
-
-   Allocates and initializes an internal thread data-structure and
-   adds it to the threads list.
-
-*******************************************************************************/
-
-threadobject *threads_thread_new(void)
-{
-       thread_index_t *ti;
-       int32_t         index;
-       threadobject   *t;
-       
-       /* lock the threads-lists */
-
-       threads_list_lock();
-
-       /* Try to get a thread index from the free-list. */
-
-       ti = list_first_unsynced(list_free_thread_index);
-
-       /* Is a free thread index available? */
-
-       if (ti != NULL) {
-               /* Yes, remove it from the free list, get the index and free
-                  the entry. */
-
-               list_remove_unsynced(list_free_thread_index, ti);
-
-               index = ti->index;
-
-               FREE(ti, thread_index_t);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       size_thread_index_t -= sizeof(thread_index_t);
-#endif
-       }
-       else {
-               /* Get a new the thread index. */
-
-               index = list_threads->size + 1;
-       }
-
-       /* Allocate a thread data structure. */
-
-#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. */
-
-       gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
-       gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
-#endif
-
-       /* 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_new(t);
-
-       /* Add the thread to the threads-list. */
-
-       list_add_last_unsynced(list_threads, t);
-
-       /* Unlock the threads-lists. */
-
-       threads_list_unlock();
-
-       return t;
-}
-
-
-/* threads_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 threads_thread_free(threadobject *t)
-{
-       thread_index_t *ti;
-
-       /* Lock the threads lists. */
-
-       threads_list_lock();
-
-       /* Cleanup the implementation specific bits. */
-
-       threads_impl_thread_free(t);
-
-       /* Remove the thread from the threads-list. */
-
-       list_remove_unsynced(list_threads, t);
-
-       /* Add the thread index to the free list. */
-
-       ti = NEW(thread_index_t);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_thread_index_t += sizeof(thread_index_t);
-#endif
-
-       ti->index = t->index;
-
-       list_add_last_unsynced(list_free_thread_index, ti);
-
-       /* Free the thread data structure. */
-
-#if defined(ENABLE_GC_BOEHM)
-       GCFREE(t);
-#else
-       FREE(t, threadobject);
-#endif
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_threadobject -= sizeof(threadobject);
-#endif
-
-       /* Unlock the threads lists. */
-
-       threads_list_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;
-       java_lang_Thread   *object;
-#if defined(WITH_CLASSPATH_GNU)
-       java_lang_VMThread *vmt;
-#endif
-
-       /* 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 = threads_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 */
-
-       object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
-
-       /* XXX memory leak!!! */
-       if (object == NULL)
-               return false;
-
-#if defined(WITH_CLASSPATH_GNU)
-       vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
-
-       /* XXX memory leak!!! */
-       if (vmt == NULL)
-               return false;
-
-       LLNI_field_set_ref(vmt, thread, object);
-       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) t);
-
-       LLNI_field_set_ref(object, vmThread, vmt);
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-       LLNI_field_set_val(object, vm_thread, (java_lang_Object *) t);
-#endif
-
-       threads_thread_set_object(t, (java_handle_t *) object);
-
-       /* set java.lang.Thread fields */
-
-#if defined(WITH_CLASSPATH_GNU)
-       LLNI_field_set_ref(object, name    , (java_lang_String *) javastring_new(name));
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-       /* FIXME: In cldc the name is a char[] */
-/*     LLNI_field_set_ref(object, name    , (java_chararray *) javastring_new(name)); */
-       LLNI_field_set_ref(object, name    , NULL);
-#endif
-
-#if defined(ENABLE_JAVASE)
-       LLNI_field_set_val(object, daemon  , true);
-#endif
-
-       LLNI_field_set_val(object, priority, NORM_PRIORITY);
-
-       /* 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   *o;
-       threadobject       *thread;
-#if defined(WITH_CLASSPATH_GNU)
-       java_lang_VMThread *vmt;
-#endif
-
-       o = (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 */
-
-       thread = threads_thread_new();
-
-       /* this is a normal Java thread */
-
-       thread->flags |= THREAD_FLAG_JAVA;
-
-#if defined(ENABLE_JAVASE)
-       /* is this a daemon thread? */
-
-       if (LLNI_field_direct(o, daemon) == true)
-               thread->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 */
-
-       threads_thread_set_object(thread, object);
-
-#if defined(WITH_CLASSPATH_GNU)
-       LLNI_field_get_ref(o, vmThread, vmt);
-
-       assert(vmt);
-       assert(LLNI_field_direct(vmt, vmdata) == NULL);
-
-       LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-       LLNI_field_set_val(o, vm_thread, (java_lang_Object *) thread);
-#endif
-
-       /* Start the thread.  Don't pass a function pointer (NULL) since
-          we want Thread.run()V here. */
-
-       threads_impl_thread_start(thread, NULL);
-}
-
-
-/* threads_thread_print_info ***************************************************
-
-   Print information of the passed thread.
-   
-*******************************************************************************/
-
-void threads_thread_print_info(threadobject *t)
-{
-       java_lang_Thread *object;
-#if defined(WITH_CLASSPATH_GNU)
-       java_lang_String *namestring;
-#endif
-       utf              *name;
-
-       assert(t->state != THREAD_STATE_NEW);
-
-       /* the thread may be currently in initalization, don't print it */
-
-       object = (java_lang_Thread *) threads_thread_get_object(t);
-
-       if (object != NULL) {
-               /* get thread name */
-
-#if defined(WITH_CLASSPATH_GNU)
-               LLNI_field_get_ref(object, name, namestring);
-               name = javastring_toutf((java_handle_t *) namestring, false);
-#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
-               /* FIXME: In cldc the name is a char[] */
-/*             name = object->name; */
-               name = utf_null;
-#else
-# error unknown classpath configuration
-#endif
-
-               printf("\"");
-               utf_display_printable_ascii(name);
-               printf("\"");
-
-               if (t->flags & THREAD_FLAG_DAEMON)
-                       printf(" daemon");
-
-               printf(" prio=%d", LLNI_field_direct(object, 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 */
-
-               switch (t->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("threads_thread_print_info: unknown thread state %d",
-                                        t->state);
-               }
-       }
-}
-
-
-/* threads_get_current_tid *****************************************************
-
-   Return the tid of the current thread.
-   
-   RETURN VALUE:
-       the current tid
-
-*******************************************************************************/
-
-ptrint threads_get_current_tid(void)
-{
-       threadobject *thread;
-
-       thread = THREADOBJECT;
-
-       /* this may happen during bootstrap */
-
-       if (thread == NULL)
-               return 0;
-
-       return (ptrint) thread->tid;
-}
-
-
-/* threads_thread_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 threads_thread_state_runnable(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threads_list_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED)
-               t->state = THREAD_STATE_RUNNABLE;
-
-       DEBUGTHREADS("is RUNNABLE", t);
-
-       threads_list_unlock();
-}
-
-
-/* threads_thread_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 threads_thread_state_waiting(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threads_list_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED)
-               t->state = THREAD_STATE_WAITING;
-
-       DEBUGTHREADS("is WAITING", t);
-
-       threads_list_unlock();
-}
-
-
-/* threads_thread_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 threads_thread_state_timed_waiting(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threads_list_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED)
-               t->state = THREAD_STATE_TIMED_WAITING;
-
-       DEBUGTHREADS("is TIMED_WAITING", t);
-
-       threads_list_unlock();
-}
-
-
-/* threads_thread_state_terminated *********************************************
-
-   Set the current state of the given thread to
-   THREAD_STATE_TERMINATED.
-
-*******************************************************************************/
-
-void threads_thread_state_terminated(threadobject *t)
-{
-       /* set the state in the lock */
-
-       threads_list_lock();
-
-       t->state = THREAD_STATE_TERMINATED;
-
-       DEBUGTHREADS("is TERMINATED", t);
-
-       threads_list_unlock();
-}
-
-
-/* threads_thread_get_state ****************************************************
-
-   Returns the current state of the given thread.
-
-*******************************************************************************/
-
-utf *threads_thread_get_state(threadobject *t)
-{
-       utf *u;
-
-       switch (t->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("threads_get_state: unknown thread state %d", t->state);
-
-               /* keep compiler happy */
-
-               u = NULL;
-       }
-
-       return u;
-}
-
-
-/* threads_thread_is_alive *****************************************************
-
-   Returns if the give thread is alive.
-
-*******************************************************************************/
-
-bool threads_thread_is_alive(threadobject *t)
-{
-       switch (t->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", t->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 threads lists */
-
-       threads_list_lock();
-
-       printf("Full thread dump CACAO "VERSION":\n");
-
-       /* iterate over all started threads */
-
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
-               /* ignore threads which are in state NEW */
-               if (t->state == THREAD_STATE_NEW)
-                       continue;
-
-               /* print thread info */
-
-               printf("\n");
-               threads_thread_print_info(t);
-               printf("\n");
-
-               /* print trace of thread */
-
-               threads_thread_print_stacktrace(t);
-       }
-
-       /* unlock the threads lists */
-
-       threads_list_unlock();
-}
-
-
-/* threads_thread_print_stacktrace *********************************************
-
-   Print the current stacktrace of the given thread.
-
-*******************************************************************************/
-
-void threads_thread_print_stacktrace(threadobject *thread)
-{
-       stackframeinfo_t        *sfi;
-       java_handle_bytearray_t *ba;
-       stacktrace_t            *st;
-
-       /* Build a stacktrace for the passed thread. */
-
-       sfi = thread->_stackframeinfo;
-
-       ba = stacktrace_get();
-       
-       /* 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);
-
-       /* Print stacktrace. */
-
-       if (st != NULL)
-               stacktrace_print(st);
-       else {
-               puts("\t<<No stacktrace available>>");
-               fflush(stdout);
-       }
-
-       LLNI_CRITICAL_END;
-}
-
-
-/* threads_print_stacktrace ****************************************************
-
-   Print the current stacktrace of the current thread.
-
-*******************************************************************************/
-
-void threads_print_stacktrace(void)
-{
-       threadobject *thread;
-
-       thread = THREADOBJECT;
-
-       threads_thread_print_stacktrace(thread);
-}
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of 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/threads-common.h b/src/threads/threads-common.h
deleted file mode 100644 (file)
index f744afb..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/* src/threads/threads-common.h - machine independent thread 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
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public 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 _THREADS_COMMON_H
-#define _THREADS_COMMON_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "native/llni.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#else
-# include "threads/none/threads.h"
-#endif
-
-#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); \
-                       threads_thread_print_info(thread); \
-                       printf("]\n"); \
-               } \
-       } while (0)
-#else
-# define DEBUGTHREADS(message, thread)
-#endif
-
-
-#if defined(__LINUX__)
-/* XXX Remove for exact-GC. */
-extern bool threads_pthreads_implementation_nptl;
-#endif
-
-
-/* inline functions ***********************************************************/
-
-/* threads_thread_get_object ***************************************************
-
-   Return the java.lang.Thread object for the given thread.
-
-*******************************************************************************/
-
-static inline java_handle_t *threads_thread_get_object(threadobject *t)
-{
-       return LLNI_WRAP(t->object);
-}
-
-
-/* threads_thread_set_object ***************************************************
-
-   Set the java.lang.Thread object for the given thread.
-
-*******************************************************************************/
-
-static inline void threads_thread_set_object(threadobject *t, java_handle_t *object)
-{
-       t->object = LLNI_DIRECT(object);
-}
-
-
-/* function prototypes ********************************************************/
-
-void          threads_preinit(void);
-
-threadobject *threads_list_first(void);
-threadobject *threads_list_next(threadobject *t);
-s4            threads_list_get_non_daemons(void);
-
-threadobject *threads_thread_new(void);
-void          threads_thread_free(threadobject *t);
-
-bool          threads_thread_start_internal(utf *name, functionptr f);
-void          threads_thread_start(java_handle_t *object);
-
-void          threads_thread_print_info(threadobject *t);
-
-ptrint        threads_get_current_tid(void);
-
-void          threads_thread_state_runnable(threadobject *t);
-void          threads_thread_state_waiting(threadobject *t);
-void          threads_thread_state_timed_waiting(threadobject *t);
-void          threads_thread_state_terminated(threadobject *t);
-utf          *threads_thread_get_state(threadobject *t);
-
-bool          threads_thread_is_alive(threadobject *t);
-
-void          threads_dump(void);
-void          threads_thread_print_stacktrace(threadobject *thread);
-void          threads_print_stacktrace(void);
-
-
-/* implementation specific functions */
-
-void          threads_impl_preinit(void);
-
-void          threads_list_lock(void);
-void          threads_list_unlock(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_set_current_threadobject(threadobject *thread);
-void          threads_impl_thread_new(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 /* _THREADS_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
index 0a5d3377c4c05591cf38c283fa0f527fc6901ec8..e6d1085cd40a0158c499e11e25802783ae87ce1b 100644 (file)
@@ -47,6 +47,8 @@ libtoolbox_la_SOURCES = \
        list.h \
        logging.c \
        logging.h \
+       set.h \
+       set.c \
        tree.c \
        tree.h \
        util.c \
index a9428c226a725861155b2fd436c282b2039a8934..9ca46ea472989042233808e483d67ce0d830a3c4 100644 (file)
@@ -33,6 +33,8 @@
 #ifndef _BITVECTOR_H
 #define _BITVECTOR_H
 
+#include "vm/global.h"
+
 #if !defined(NDEBUG)
 #include <assert.h>
 
index 3f35eb4a48bd7165983dab8a15630b4a5620d801..4de7222f628610d7a97a4014c967e1eef48ff0b6 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/list.c - double linked list
 
-   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"
 
 #include <assert.h>
+#include <stdint.h>
 #include <stdlib.h>
 
-#include "vm/types.h"
-
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
@@ -45,7 +42,7 @@
 
 *******************************************************************************/
 
-list_t *list_create(s4 nodeoffset)
+list_t *list_create(int nodeoffset)
 {
        list_t *l;
 
@@ -84,7 +81,7 @@ void list_free(list_t *l)
 
 *******************************************************************************/
 
-list_t *list_create_dump(s4 nodeoffset)
+list_t *list_create_dump(int nodeoffset)
 {
        list_t *l;
 
@@ -130,28 +127,10 @@ void list_unlock(list_t *l)
 *******************************************************************************/
 
 void list_add_first(list_t *l, void *element)
-{
-       LOCK_MONITOR_ENTER(l);
-
-       list_add_first_unsynced(l, element);
-
-       LOCK_MONITOR_EXIT(l);
-}
-
-
-/* list_add_first_unsynced *****************************************************
-
-   Adds the element as first element, but WITHOUT LOCKING!
-
-   ATTENTION: Use this function with care!!!
-
-*******************************************************************************/
-
-void list_add_first_unsynced(list_t *l, void *element)
 {
        listnode_t *ln;
 
-       ln = (listnode_t *) (((u1 *) element) + l->nodeoffset);
+       ln = (listnode_t *) (((uint8_t *) element) + l->nodeoffset);
 
        if (l->first) {
                ln->prev       = NULL;
@@ -166,7 +145,7 @@ void list_add_first_unsynced(list_t *l, void *element)
                l->first = ln;
        }
 
-       /* increase number of elements */
+       /* Increase number of elements. */
 
        l->size++;
 }
@@ -179,28 +158,10 @@ void list_add_first_unsynced(list_t *l, void *element)
 *******************************************************************************/
 
 void list_add_last(list_t *l, void *element)
-{
-       LOCK_MONITOR_ENTER(l);
-
-       list_add_last_unsynced(l, element);
-
-       LOCK_MONITOR_EXIT(l);
-}
-
-
-/* list_add_last_unsynced ******************************************************
-
-   Adds the element as last element but does NO locking!
-
-   ATTENTION: Use this function with care!!!
-
-*******************************************************************************/
-
-void list_add_last_unsynced(list_t *l, void *element)
 {
        listnode_t *ln;
 
-       ln = (listnode_t *) (((u1 *) element) + l->nodeoffset);
+       ln = (listnode_t *) (((uint8_t *) element) + l->nodeoffset);
 
        if (l->last) {
                ln->prev      = l->last;
@@ -215,7 +176,7 @@ void list_add_last_unsynced(list_t *l, void *element)
                l->first = ln;
        }
 
-       /* increase number of elements */
+       /* Increase number of elements. */
 
        l->size++;
 }
@@ -234,12 +195,10 @@ void list_add_before(list_t *l, void *element, void *newelement)
        listnode_t *ln;
        listnode_t *newln;
 
-       ln    = (listnode_t *) (((u1 *) element) + l->nodeoffset);
-       newln = (listnode_t *) (((u1 *) newelement) + l->nodeoffset);
-
-       LOCK_MONITOR_ENTER(l);
+       ln    = (listnode_t *) (((uint8_t *) element) + l->nodeoffset);
+       newln = (listnode_t *) (((uint8_t *) newelement) + l->nodeoffset);
 
-       /* set the new links */
+       /* Set the new links. */
 
        newln->prev = ln->prev;
        newln->next = ln;
@@ -257,11 +216,9 @@ void list_add_before(list_t *l, void *element, void *newelement)
        if (l->last == ln)
                l->last = newln;
 
-       /* increase number of elements */
+       /* Increase number of elements. */
 
        l->size++;
-
-       LOCK_MONITOR_EXIT(l);
 }
 
 
@@ -272,28 +229,10 @@ void list_add_before(list_t *l, void *element, void *newelement)
 *******************************************************************************/
 
 void list_remove(list_t *l, void *element)
-{
-       LOCK_MONITOR_ENTER(l);
-
-       list_remove_unsynced(l, element);
-
-       LOCK_MONITOR_EXIT(l);
-}
-
-
-/* list_remove_unsynced ********************************************************
-
-   Removes the element but does NO locking!
-
-   ATTENTION: Use this function with care!!!
-
-*******************************************************************************/
-
-void list_remove_unsynced(list_t *l, void *element)
 {
        listnode_t *ln;
 
-       ln = (listnode_t *) (((u1 *) element) + l->nodeoffset);
+       ln = (listnode_t *) (((uint8_t *) element) + l->nodeoffset);
        
        if (ln->next)
                ln->next->prev = ln->prev;
@@ -308,7 +247,7 @@ void list_remove_unsynced(list_t *l, void *element)
        ln->next = NULL;
        ln->prev = NULL;
 
-       /* decrease number of elements */
+       /* Decrease number of elements. */
 
        l->size--;
 }
@@ -324,32 +263,10 @@ void *list_first(list_t *l)
 {
        void *el;
 
-       LOCK_MONITOR_ENTER(l);
-
-       el = list_first_unsynced(l);
-
-       LOCK_MONITOR_EXIT(l);
-
-       return el;
-}
-
-
-/* list_first_unsynced *********************************************************
-
-   Returns the first element of the list, but does NO locking!
-
-   ATTENTION: Use this function with care!!!
-
-*******************************************************************************/
-
-void *list_first_unsynced(list_t *l)
-{
-       void *el;
-
        if (l->first == NULL)
                el = NULL;
        else
-               el = ((u1 *) l->first) - l->nodeoffset;
+               el = ((uint8_t *) l->first) - l->nodeoffset;
 
        return el;
 }
@@ -365,32 +282,10 @@ void *list_last(list_t *l)
 {
        void *el;
 
-       LOCK_MONITOR_ENTER(l);
-
-       el = list_last_unsynced(l);
-
-       LOCK_MONITOR_EXIT(l);
-
-       return el;
-}
-
-
-/* list_last_unsynced **********************************************************
-
-   Returns the last element of the list, but does NO locking!
-
-   ATTENTION: Use this function with care!!!
-
-*******************************************************************************/
-
-void *list_last_unsynced(list_t *l)
-{
-       void *el;
-
        if (l->last == NULL)
                el = NULL;
        else
-               el = ((u1 *) l->last) - l->nodeoffset;
+               el = ((uint8_t *) l->last) - l->nodeoffset;
 
        return el;
 }
@@ -403,39 +298,16 @@ void *list_last_unsynced(list_t *l)
 *******************************************************************************/
 
 void *list_next(list_t *l, void *element)
-{
-       void *el;
-
-       LOCK_MONITOR_ENTER(l);
-
-       el = list_next_unsynced(l, element);
-
-       LOCK_MONITOR_EXIT(l);
-
-       return el;
-}
-
-
-/* list_next_unsynced **********************************************************
-
-   Returns the next element of element from the list, but does NO
-   locking!
-
-   ATTENTION: Use this function with care!!!
-
-*******************************************************************************/
-
-void *list_next_unsynced(list_t *l, void *element)
 {
        listnode_t *ln;
-       void     *el;
+       void       *el;
 
-       ln = (listnode_t *) (((u1 *) element) + l->nodeoffset);
+       ln = (listnode_t *) (((uint8_t *) element) + l->nodeoffset);
 
        if (ln->next == NULL)
                el = NULL;
        else
-               el = ((u1 *) ln->next) - l->nodeoffset;
+               el = ((uint8_t *) ln->next) - l->nodeoffset;
 
        return el;
 }
@@ -448,39 +320,16 @@ void *list_next_unsynced(list_t *l, void *element)
 *******************************************************************************/
 
 void *list_prev(list_t *l, void *element)
-{
-       void *el;
-
-       LOCK_MONITOR_ENTER(l);
-
-       el = list_prev_unsynced(l, element);
-
-       LOCK_MONITOR_EXIT(l);
-
-       return el;
-}
-
-
-/* list_prev_unsynced **********************************************************
-
-   Returns the previous element of element from the list, but does NO
-   locking!
-
-   ATTENTION: Use this function with care!!!
-
-*******************************************************************************/
-
-void *list_prev_unsynced(list_t *l, void *element)
 {
        listnode_t *ln;
-       void     *el;
+       void       *el;
 
-       ln = (listnode_t *) (((u1 *) element) + l->nodeoffset);
+       ln = (listnode_t *) (((uint8_t *) element) + l->nodeoffset);
 
        if (ln->prev == NULL)
                el = NULL;
        else
-               el = ((u1 *) ln->prev) - l->nodeoffset;
+               el = ((uint8_t *) ln->prev) - l->nodeoffset;
 
        return el;
 }
index 31cb0b3e7546a0680042a8784dd73493696f990c..6837e3b78633199ea1026850e762ff8f01a4df8a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/list.h - synchronized linked list
 
-   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.
 
@@ -29,7 +27,8 @@
 #define _LIST_H
 
 #include "config.h"
-#include "vm/types.h"
+
+#include <stdint.h>
 
 #include "vm/global.h"
 
@@ -111,42 +110,32 @@ struct list_t {
 #endif
        listnode_t        *first;
        listnode_t        *last;
-       s4                 nodeoffset;
-       s4                 size;            /* number of elements in the list     */
+       int                nodeoffset;
+       int                size;            /* number of elements in the list     */
 };
 
 
 /* function prototypes ********************************************************/
 
-list_t *list_create(s4 nodeoffset);
-list_t *list_create_dump(s4 nodeoffset);
+list_t *list_create(int nodeoffset);
+list_t *list_create_dump(int nodeoffset);
+
 void    list_free(list_t *l);
 
 void    list_lock(list_t *l);
 void    list_unlock(list_t *l);
 
 void    list_add_first(list_t *l, void *element);
-void    list_add_first_unsynced(list_t *l, void *element);
-
 void    list_add_last(list_t *l, void *element);
-void    list_add_last_unsynced(list_t *l, void *element);
-
 void    list_add_before(list_t *l, void *element, void *newelement);
 
 void    list_remove(list_t *l, void *element);
-void    list_remove_unsynced(list_t *l, void *element);
 
 void   *list_first(list_t *l);
-void   *list_first_unsynced(list_t *l);
-
 void   *list_last(list_t *l);
-void   *list_last_unsynced(list_t *l);
 
 void   *list_next(list_t *l, void *element);
-void   *list_next_unsynced(list_t *l, void *element);
-
 void   *list_prev(list_t *l, void *element);
-void   *list_prev_unsynced(list_t *l, void *element);
 
 #endif /* _LIST_H */
 
index 7080954e8d04b37782d03fb45b112986a41b707b..c9fea656a0933c2942b683ff8ddd6640008f5f6d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/toolbox/logging.c - 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.
 
 #include "vm/types.h"
 
 #include "mm/memory.h"
-#include "threads/threads-common.h"
+
+#include "threads/thread.h"
+
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
+
 #include "vm/global.h"
 
 #if defined(ENABLE_STATISTICS)
@@ -254,13 +255,13 @@ void log_message_method(const char *msg, methodinfo *m)
        char *buf;
        s4    len;
 
-       len = strlen(msg) + utf_bytes(m->class->name) + strlen(".") +
+       len = strlen(msg) + utf_bytes(m->clazz->name) + strlen(".") +
                utf_bytes(m->name) + utf_bytes(m->descriptor) + strlen("0");
 
        buf = MNEW(char, len);
 
        strcpy(buf, msg);
-       utf_cat_classname(buf, m->class->name);
+       utf_cat_classname(buf, m->clazz->name);
        strcat(buf, ".");
        utf_cat(buf, m->name);
        utf_cat(buf, m->descriptor);
diff --git a/src/toolbox/set.c b/src/toolbox/set.c
new file mode 100644 (file)
index 0000000..b4fd7e7
--- /dev/null
@@ -0,0 +1,191 @@
+/* src/toolbox/set.c - Set implementation.
+
+   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.
+
+   This file implements a set of pointers.
+
+   The current implementation is naive and should be improved in the future,
+   so that the O(size) operations take O(log(size)) instead.
+
+   The representation of the set is an contingous unordered array of the
+   elements (pointers).
+*/
+
+#include "toolbox/set.h"
+
+#include <assert.h>
+
+#include "mm/memory.h"
+
+/* struct set ******************************************************************
+
+   Represents the set.
+
+*******************************************************************************/
+
+struct set {
+       void **elements;   /* An array of elements */
+       unsigned capacity; /* Size of elements */
+       unsigned size;     /* Current number of elements */
+};
+
+/* set_new ********************************************************************
+
+   Creates an instance of a set on the dump area.
+
+   IN:
+       capacity: Maximal number of elements of elements the set can hold.
+
+*******************************************************************************/
+
+set *set_new(unsigned capacity) {
+       set *s = DNEW(set);
+
+       s->elements = DMNEW(void *, capacity);
+       MZERO(s->elements, void *, capacity);
+       s->capacity = capacity;
+       s->size = 0;
+
+       return s;
+}
+
+/* set_insert ******************************************************************
+
+   Inserts element e into set s
+
+   The current implementation takes O(size).
+
+*******************************************************************************/
+
+void set_insert(set *s, void *element) {
+       unsigned i;
+
+       for (i = 0; i < s->size; ++i) {
+               if (s->elements[i] == element) {
+                       return;
+               }
+       }
+
+       assert(i < s->capacity);
+
+       s->size += 1;
+       s->elements[i] = element;
+}
+
+/* set_remove ******************************************************************
+
+   Removes element e into set s
+
+   The current implementation takes O(size).
+
+*******************************************************************************/
+
+void set_remove(set *s, void *element) {
+       unsigned i;
+       for (i = 0; i < s->size; ++i) {
+               if (s->elements[i] == element) {
+                       /* Do not creaet a "hole".
+                        * Overwrite this element with the last element.
+                        */
+                       if (i == (s->size - 1)) { /* The last one */
+                               s->elements[i] = NULL;
+                       } else {
+                               s->elements[i] = s->elements[s->size - 1];
+                               s->elements[s->size - 1] = NULL;
+                       }
+                       s->size -= 1;
+               }
+       }
+}
+
+/* set_size ********************************************************************
+
+   Returns the number of elements in the set s.
+   The complexity of the operation is O(1).
+
+*******************************************************************************/
+
+unsigned set_size(const set *s) {
+       return s->size;
+}
+
+/* set_empty *******************************************************************
+
+   Returns true, iif the set s is empty.
+   The complexity of the operation is O(1).
+
+*******************************************************************************/
+
+bool set_empty(const set *s) {
+       return s->size == 0;
+}
+
+/* set_contains ****************************************************************
+
+   Returns true, iif the set s contains element element.
+
+   The current implementation takes O(size).
+
+*******************************************************************************/
+
+bool set_contains(const set *s, void *element) {
+       unsigned i;
+       for (i = 0; i < s->size; ++i) {
+               if (s->elements[i] == element) {
+                       return true;
+               }
+       }
+       return false;
+}
+
+/* set_pop *********************************************************************
+
+   Pics and removes some element from the set s and returns it.
+   Returns NULL if the set s is empty.
+   The complexity of the operation is O(1).
+
+*******************************************************************************/
+
+void *set_pop(set *s) {
+       void *ret = NULL;
+
+       if (s->size > 0) {
+               ret = s->elements[s->size - 1];
+               s->elements[s->size - 1] = NULL;
+               s->size -= 1;
+       }
+
+       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/toolbox/set.h b/src/toolbox/set.h
new file mode 100644 (file)
index 0000000..491ce4f
--- /dev/null
@@ -0,0 +1,54 @@
+/* src/toolbox/set.h - Set implementation.
+
+   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 _TOOLBOX_SET_H
+#define _TOOLBOX_SET_H
+
+#include "vm/global.h"
+
+typedef struct set set;
+
+set *set_new(unsigned capacity);
+void set_insert(set *s, void *element);
+void set_remove(set *s, void *element);
+bool set_contains(const set *s, void *element);
+unsigned set_size(const set *s);
+bool set_empty(const set *s);
+void *set_pop(set *s);
+
+#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 4a146e9db76cbfc44dfd0425b533cc9c89d0aa73..c0d1ca816a4849538b28de7c923f933b20f04aee 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/access.c - checking access rights
 
-   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.
 
@@ -191,14 +189,14 @@ bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
   
    IN:
        f................the field to check
-          calldepth........number of callers to ignore
+          callerdepth......number of callers to ignore
                            For example if the stacktrace looks like this:
 
-                                          java.lang.reflect.Method.invokeNative (Native Method)
-                                  [0] java.lang.reflect.Method.invoke (Method.java:329)
-                                  [1] <caller>
+                                  [0] java.lang.reflect.Method.invokeNative (Native Method)
+                                  [1] java.lang.reflect.Method.invoke
+                                  [2] <caller>
 
-                                       you must specify 1 so the access rights of <caller> 
+                                       you must specify 2 so the access rights of <caller> 
                                                are checked.
   
    RETURN VALUE:
@@ -207,35 +205,31 @@ bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
    
 *******************************************************************************/
 
-bool access_check_field(fieldinfo *f, s4 calldepth)
+#if defined(ENABLE_JAVASE)
+bool access_check_field(fieldinfo *f, int callerdepth)
 {
-       java_handle_objectarray_t *oa;
-       classinfo                 *callerclass;
-       char                      *msg;
-       s4                         msglen;
-       utf                       *u;
+       classinfo *callerclass;
+       char      *msg;
+       int        msglen;
+       utf       *u;
 
-       /* if everything is public, there is nothing to check */
+       /* If everything is public, there is nothing to check. */
 
-       if ((f->class->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
+       if ((f->clazz->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
                return true;
 
-       /* get the caller's class */
+       /* Get the caller's class. */
 
-       oa = stacktrace_getClassContext();
+       callerclass = stacktrace_get_caller_class(callerdepth);
 
-       if (oa == NULL)
+       if (callerclass == NULL)
                return false;
 
-       assert(calldepth >= 0 && calldepth < LLNI_array_size(oa));
+       /* Check access rights. */
 
-       callerclass = (classinfo *) LLNI_array_direct(oa, calldepth);
-
-       /* check access rights */
-
-       if (!access_is_accessible_member(callerclass, f->class, f->flags)) {
+       if (!access_is_accessible_member(callerclass, f->clazz, f->flags)) {
                msglen =
-                       utf_bytes(f->class->name) +
+                       utf_bytes(f->clazz->name) +
                        strlen(".") +
                        utf_bytes(f->name) +
                        strlen(" not accessible from ") +
@@ -244,7 +238,7 @@ bool access_check_field(fieldinfo *f, s4 calldepth)
 
                msg = MNEW(char, msglen);
 
-               utf_copy_classname(msg, f->class->name);
+               utf_copy_classname(msg, f->clazz->name);
                strcat(msg, ".");
                utf_cat_classname(msg, f->name);
                strcat(msg, " not accessible from ");
@@ -263,6 +257,7 @@ bool access_check_field(fieldinfo *f, s4 calldepth)
 
        return true;
 }
+#endif
 
 
 /* access_check_method *********************************************************
@@ -272,14 +267,14 @@ bool access_check_field(fieldinfo *f, s4 calldepth)
   
    IN:
        m................the method to check
-          calldepth........number of callers to ignore
+          callerdepth......number of callers to ignore
                            For example if the stacktrace looks like this:
 
-                                          java.lang.reflect.Method.invokeNative (Native Method)
-                                  [0] java.lang.reflect.Method.invoke (Method.java:329)
-                                  [1] <caller>
+                                  [1] java.lang.reflect.Method.invokeNative (Native Method)
+                                  [1] java.lang.reflect.Method.invoke
+                                  [2] <caller>
 
-                                       you must specify 1 so the access rights of <caller> 
+                                       you must specify 2 so the access rights of <caller> 
                                                are checked.
   
    RETURN VALUE:
@@ -288,35 +283,31 @@ bool access_check_field(fieldinfo *f, s4 calldepth)
    
 *******************************************************************************/
 
-bool access_check_method(methodinfo *m, s4 calldepth)
+#if defined(ENABLE_JAVASE)
+bool access_check_method(methodinfo *m, int callerdepth)
 {
-       java_handle_objectarray_t *oa;
-       classinfo                 *callerclass;
-       char                      *msg;
-       s4                         msglen;
-       utf                       *u;
+       classinfo *callerclass;
+       char      *msg;
+       int        msglen;
+       utf       *u;
 
-       /* if everything is public, there is nothing to check */
+       /* If everything is public, there is nothing to check. */
 
-       if ((m->class->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
+       if ((m->clazz->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
                return true;
 
-       /* get the caller's class */
+       /* Get the caller's class. */
 
-       oa = stacktrace_getClassContext();
+       callerclass = stacktrace_get_caller_class(callerdepth);
 
-       if (oa == NULL)
+       if (callerclass == NULL)
                return false;
 
-       assert(calldepth >= 0 && calldepth < LLNI_array_size(oa));
+       /* Check access rights. */
 
-       callerclass = (classinfo *) LLNI_array_direct(oa, calldepth);
-
-       /* check access rights */
-
-       if (!access_is_accessible_member(callerclass, m->class, m->flags)) {
+       if (!access_is_accessible_member(callerclass, m->clazz, m->flags)) {
                msglen =
-                       utf_bytes(m->class->name) +
+                       utf_bytes(m->clazz->name) +
                        strlen(".") +
                        utf_bytes(m->name) +
                        utf_bytes(m->descriptor) +
@@ -326,7 +317,7 @@ bool access_check_method(methodinfo *m, s4 calldepth)
 
                msg = MNEW(char, msglen);
 
-               utf_copy_classname(msg, m->class->name);
+               utf_copy_classname(msg, m->clazz->name);
                strcat(msg, ".");
                utf_cat_classname(msg, m->name);
                utf_cat_classname(msg, m->descriptor);
@@ -346,6 +337,7 @@ bool access_check_method(methodinfo *m, s4 calldepth)
 
        return true;
 }
+#endif
 
 
 /*
index 4197126f8ae758da42035772ae3726725d32e409..2b8a10c173e93251be7fcfac22854e49a6c16f0a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/access.h - checking access rights
 
-   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.
 
@@ -29,7 +27,8 @@
 #define _ACCESS_H
 
 #include "config.h"
-#include "vm/types.h"
+
+#include <stdint.h>
 
 #include "vm/global.h"
 
 bool access_is_accessible_class(classinfo *referer, classinfo *cls);
 
 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
-                                                                s4 memberflags);
+                                                                int32_t memberflags);
 
-bool access_check_field(fieldinfo *f, s4 calldepth);
-bool access_check_method(methodinfo *m, s4 calldepth);
+#if defined(ENABLE_JAVASE)
+bool access_check_field(fieldinfo *f, int callerdepth);
+bool access_check_method(methodinfo *m, int callerdepth);
+#endif
 
 #endif /* _ACCESS_H */
 
index 673f396ed101a922269e5906be10e787cca3c927..30f231d3e720a8a60ae388a7dfb5abed406b3114 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/array.c - Java array functions
 
    Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -49,6 +49,11 @@ java_handle_t *array_element_get(java_handle_t *a, int32_t index)
        imm_union      value;
        java_handle_t *o;
 
+       if (a == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
        v = LLNI_vftbl_direct(a);
 
        type = v->arraydesc->arraytype;
@@ -89,6 +94,12 @@ imm_union array_element_primitive_get(java_handle_t *a, int32_t index)
        int       type;
        imm_union value;
 
+       if (a == NULL) {
+               exceptions_throw_nullpointerexception();
+               value.a = NULL;
+               return value;
+       }
+
        v = LLNI_vftbl_direct(a);
 
        type = v->arraydesc->arraytype;
@@ -149,6 +160,11 @@ void array_element_primitive_set(java_handle_t *a, int32_t index, imm_union valu
        vftbl_t *v;
        int      type;
 
+       if (a == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
+
        v = LLNI_vftbl_direct(a);
 
        type = v->arraydesc->arraytype;
@@ -216,7 +232,7 @@ type array_##name##array_element_get(java_handle_##name##array_t *a, int32_t ind
                                                                                \
        size = LLNI_array_size(a);                                                 \
                                                                                \
-       if ((index < 0) || (index > size)) {                                       \
+       if ((index < 0) || (index >= size)) {                                      \
                exceptions_throw_arrayindexoutofboundsexception();                     \
                return (type) 0;                                                       \
        }                                                                          \
@@ -238,7 +254,7 @@ java_handle_t *array_objectarray_element_get(java_handle_objectarray_t *a, int32
 
        size = LLNI_array_size(a);
 
-       if ((index < 0) || (index > size)) {
+       if ((index < 0) || (index >= size)) {
                exceptions_throw_arrayindexoutofboundsexception();
                return NULL;
        }
@@ -278,7 +294,7 @@ void array_##name##array_element_set(java_handle_##name##array_t *a, int32_t ind
                                                                                \
        size = LLNI_array_size(a);                                                 \
                                                                                \
-       if ((index < 0) || (index > size)) {                                       \
+       if ((index < 0) || (index >= size)) {                                      \
                exceptions_throw_arrayindexoutofboundsexception();                     \
                return;                                                                \
        }                                                                          \
@@ -295,9 +311,20 @@ void array_objectarray_element_set(java_handle_objectarray_t *a, int32_t index,
                return;
        }
 
+       /* Sanity check. */
+
+       assert(a->header.objheader.vftbl->arraydesc->arraytype == ARRAYTYPE_OBJECT);
+
+       if (value != NULL) {
+               if (builtin_canstore(a, value) == false) {
+                       exceptions_throw_illegalargumentexception();
+                       return;
+               }
+       }
+
        size = LLNI_array_size(a);
 
-       if ((index < 0) || (index > size)) {
+       if ((index < 0) || (index >= size)) {
                exceptions_throw_arrayindexoutofboundsexception();
                return;
        }
@@ -321,6 +348,13 @@ ARRAY_TYPEARRAY_ELEMENT_SET(double,  double)
 
    Returns a the length of the given Java array.
 
+   ARGUMENTS:
+       a ... Java array
+
+   RETURN VALUE:
+         -1 ... exception thrown
+          >= 0 ... length of the Java array
+
 *******************************************************************************/
 
 int32_t array_length_get(java_handle_t *a)
@@ -330,7 +364,7 @@ int32_t array_length_get(java_handle_t *a)
 
        if (a == NULL) {
                exceptions_throw_nullpointerexception();
-               return 0;
+               return -1;
        }
 
        LLNI_class_get(a, c);
@@ -338,7 +372,7 @@ int32_t array_length_get(java_handle_t *a)
        if (!class_is_array(c)) {
 /*             exceptions_throw_illegalargumentexception("Argument is not an array"); */
                exceptions_throw_illegalargumentexception();
-               return 0;
+               return -1;
        }
 
        size = LLNI_array_size(a);
index 95f37d32d075cd94403892962664d0d101319aed..3425d591226793d649017294c2a4e701668a935d 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/array.h - Java array functions
 
    Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
index 0140b0ac9e4c3d1778352f954a1553ab914f158b..afa01d4b169e30d30f9d0f914beff20d0ebf13e8 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/assertion.c - assertion options
 
-   Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
 */
 
+
 #include "config.h"
+
 #include <stdint.h>
 #include <errno.h>
 
-#if defined(HAVE_STRING_H)
-# include <string.h>
-#endif
-
 #include "mm/memory.h"
 
+#include "toolbox/list.h"
+
+#include "vm/assertion.h"
 #include "vm/global.h"
 #include "vm/vm.h"
 
-#include "toolbox/list.h"
+#include "vmcore/system.h"
 
-#include "vm/assertion.h"
 
 /* -ea/-da options ************************************************************/
 
@@ -47,13 +47,15 @@ int32_t  assertion_package_count  = 0;
 bool     assertion_user_enabled   = false;
 bool     assertion_system_enabled = false;
 
+
 /* assertion_ea_da *************************************************************
 
    Handle -ea:/-enableassertions: and -da:/-disableassertions: options.
 
 *******************************************************************************/
 
-void assertion_ea_da(const char *name, bool enabled) {
+void assertion_ea_da(const char *name, bool enabled)
+{
        bool              package;
        size_t            len;
        char             *buf;
@@ -66,13 +68,14 @@ void assertion_ea_da(const char *name, bool enabled) {
        }
 
        package = false;
-       len     = strlen(name);
+       len     = system_strlen(name);
 
        if (name[len - 1] == '/') {
                return;
        }
 
-       buf = strdup(name);
+       buf = system_strdup(name);
+
        if (buf == NULL) {
                vm_abort("assertion_ea_da: strdup failed: %s", strerror(errno));
        }
@@ -91,7 +94,8 @@ void assertion_ea_da(const char *name, bool enabled) {
                assertion_class_count += 1;
        }
 
-       len = strlen(buf);
+       len = system_strlen(buf);
+
        for (i = 0; i < len; i++) {
 #if defined(WITH_CLASSPATH_SUN)
                if (buf[i] == '.') {
@@ -112,9 +116,11 @@ void assertion_ea_da(const char *name, bool enabled) {
        if (list_assertion_names == NULL) {
                list_assertion_names = list_create(OFFSET(assertion_name_t, linkage));
        }
+
        list_add_last(list_assertion_names, item);
 }
 
+
 /*
  * These 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 a2c4484bb45ab03a367d65759a161dd3710b8d97..4175bec646502ee119598a75f10bd3641ec1a0ca 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/assertion.h - assertion options
 
    Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
index 0c4f1b50da7ecda5bd5cde5bf5e1d1f8b3c8ad99..86ba2e5469a3e06713fa99320f4d0261b315ce6e 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/builtin.c - functions for unsupported operations
 
-   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.
 
@@ -56,7 +54,7 @@
 #include "native/llni.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
@@ -107,13 +105,13 @@ CYCLES_STATS_DECLARE(builtin_overhead    , 80,1)
 static bool builtintable_init(void)
 {
        descriptor_pool    *descpool;
-       s4                  dumpsize;
        builtintable_entry *bte;
        methodinfo         *m;
+       int32_t             dumpmarker;
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* create a new descriptor pool */
 
@@ -136,7 +134,7 @@ static bool builtintable_init(void)
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
                        /* release dump area */
 
-                       dump_release(dumpsize);
+                       DRELEASE;
 
                        return false;
                }
@@ -146,7 +144,7 @@ static bool builtintable_init(void)
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
-                       dump_release(dumpsize);
+                       DRELEASE;
                        return false;
                }
        }
@@ -157,7 +155,7 @@ static bool builtintable_init(void)
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
-                       dump_release(dumpsize);
+                       DRELEASE;
                        return false;
                }
        }
@@ -217,7 +215,7 @@ static bool builtintable_init(void)
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return true;
 }
@@ -268,6 +266,8 @@ static void builtintable_sort_automatic(void)
 
 bool builtin_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("builtin_init");
+
        /* initialize the builtin tables */
 
        if (!builtintable_init())
@@ -416,7 +416,7 @@ bool builtintable_replace_function(void *iptr_)
 
 *******************************************************************************/
 
-s4 builtin_instanceof(java_handle_t *o, classinfo *class)
+bool builtin_instanceof(java_handle_t *o, classinfo *class)
 {
        classinfo *c;
 
@@ -439,7 +439,7 @@ s4 builtin_instanceof(java_handle_t *o, classinfo *class)
 
 *******************************************************************************/
 
-s4 builtin_checkcast(java_handle_t *o, classinfo *class)
+bool builtin_checkcast(java_handle_t *o, classinfo *class)
 {
        classinfo *c;
 
@@ -465,8 +465,7 @@ s4 builtin_checkcast(java_handle_t *o, classinfo *class)
                        
 *******************************************************************************/
 
-static s4 builtin_descriptorscompatible(arraydescriptor *desc,
-                                                                               arraydescriptor *target)
+static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target)
 {
        if (desc == target)
                return 1;
@@ -480,6 +479,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        /* {both arrays are arrays of references} */
 
        if (desc->dimension == target->dimension) {
+               if (!desc->elementvftbl)
+                       return 0;
                /* an array which contains elements of interface types is
            allowed to be casted to Object (JOWENN)*/
 
@@ -487,8 +488,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
                        (target->elementvftbl->baseval == 1))
                        return 1;
 
-               return class_isanysubclass(desc->elementvftbl->class,
-                                                                  target->elementvftbl->class);
+               return class_isanysubclass(desc->elementvftbl->clazz,
+                                                                  target->elementvftbl->clazz);
        }
 
        if (desc->dimension < target->dimension)
@@ -497,7 +498,7 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        /* {desc has higher dimension than target} */
 
        return class_isanysubclass(pseudo_class_Arraystub,
-                                                          target->elementvftbl->class);
+                                                          target->elementvftbl->clazz);
 }
 
 
@@ -516,7 +517,7 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
 
 *******************************************************************************/
 
-s4 builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
+bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
 {
        arraydescriptor *desc;
 
@@ -538,7 +539,7 @@ s4 builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
 
 *******************************************************************************/
 
-s4 builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass)
+bool builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass)
 {
        if (o == NULL)
                return 0;
@@ -553,9 +554,9 @@ s4 builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass)
 
 *******************************************************************************/
 
-s4 builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass)
+bool builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass)
 {
-       s4 result;
+       bool result;
 
        LLNI_CRITICAL_START;
 
@@ -635,9 +636,9 @@ java_object_t *builtin_retrieve_exception(void)
 
 *******************************************************************************/
 
-s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
+bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 {
-       int result;
+       bool result;
 
        LLNI_CRITICAL_START;
 
@@ -666,7 +667,7 @@ s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 
 *******************************************************************************/
 
-s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
+bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 {
        arraydescriptor *desc;
        arraydescriptor *valuedesc;
@@ -674,7 +675,7 @@ s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
        vftbl_t         *valuevftbl;
        int32_t          baseval;
        uint32_t         diffval;
-       int              result;
+       bool             result;
 
        if (o == NULL)
                return 1;
@@ -736,14 +737,14 @@ s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 
 
 /* This is an optimized version where a is guaranteed to be one-dimensional */
-s4 builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
+bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
 {
        arraydescriptor *desc;
        vftbl_t         *elementvftbl;
        vftbl_t         *valuevftbl;
        int32_t          baseval;
        uint32_t         diffval;
-       int              result;
+       bool             result;
        
        if (o == NULL)
                return 1;
@@ -787,12 +788,12 @@ s4 builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
 
 /* This is an optimized version where a is guaranteed to be a
  * one-dimensional array of a class type */
-s4 builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
+bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
 {
        vftbl_t  *elementvftbl;
        vftbl_t  *valuevftbl;
        uint32_t  diffval;
-       int       result;
+       bool      result;
        
        if (o == NULL)
                return 1;
@@ -992,7 +993,7 @@ java_object_t *builtin_fast_new(classinfo *c)
 
 *******************************************************************************/
 
-java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass)
+java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
 {
        arraydescriptor *desc;
        s4               dataoffset;
@@ -1055,7 +1056,7 @@ java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass)
 
 *******************************************************************************/
 
-java_handle_t *builtin_java_newarray(s4 size, java_handle_t *arrayclazz)
+java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
 {
        return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz));
 }
@@ -1073,7 +1074,7 @@ java_handle_t *builtin_java_newarray(s4 size, java_handle_t *arrayclazz)
 
 *******************************************************************************/
 
-java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass)
+java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
 {
        classinfo *arrayclass;
        
@@ -1108,7 +1109,7 @@ java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass)
 *******************************************************************************/
 
 #define BUILTIN_NEWARRAY_TYPE(type, arraytype)                             \
-java_handle_##type##array_t *builtin_newarray_##type(s4 size)              \
+java_handle_##type##array_t *builtin_newarray_##type(int32_t size)              \
 {                                                                          \
        return (java_handle_##type##array_t *)                                 \
                builtin_newarray(size, primitivetype_table[arraytype].arrayclass); \
@@ -1163,7 +1164,7 @@ static java_handle_t *builtin_multianewarray_intern(int n,
 
        /* get the class of the components to create */
 
-       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->class;
+       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
 
        /* The verifier guarantees that the dimension count is in the range. */
 
index a68519d629085635154fba8fad19037167a55fe5..af6fd824aeabf0d1af65c85853413f502e1e9733 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/builtin.h - prototypes of builtin 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.
 
@@ -122,20 +120,20 @@ bool builtintable_replace_function(void *iptr);
  * ICMD_BUILTIN3.)
  */
 
-s4 builtin_instanceof(java_handle_t *obj, classinfo *class);
+bool builtin_instanceof(java_handle_t *obj, classinfo *class);
 /* NOT AN OP */
-s4 builtin_checkcast(java_handle_t *obj, classinfo *class);
+bool builtin_checkcast(java_handle_t *obj, classinfo *class);
 /* NOT AN OP */
-s4 builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass);
+bool builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass);
 /* NOT AN OP */
-s4 builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass);
+bool builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass);
 #define BUILTIN_arrayinstanceof (functionptr) builtin_fast_arrayinstanceof
-s4 builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass);
+bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass);
 #define BUILTIN_arraycheckcast (functionptr) builtin_fast_arraycheckcast
 
-s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o);
+bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o);
 /* NOT AN OP */
-s4 builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o);
+bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o);
 #define BUILTIN_FAST_canstore (functionptr) builtin_fast_canstore
 
 void *builtin_throw_exception(java_object_t *exception);
@@ -150,29 +148,29 @@ java_handle_t *builtin_java_new(java_handle_t *c);
 java_object_t *builtin_fast_new(classinfo *c);
 #define BUILTIN_FAST_new (functionptr) builtin_fast_new
 
-java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass);
+java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass);
 /* NOT AN OP */
-java_handle_t *builtin_java_newarray(s4 size, java_handle_t *arrayclass);
+java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclass);
 #define BUILTIN_newarray (functionptr) builtin_java_newarray
 
-java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass);
+java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass);
 /* NOT AN OP */
 
-java_handle_booleanarray_t *builtin_newarray_boolean(s4 size);
+java_handle_booleanarray_t *builtin_newarray_boolean(int32_t size);
 #define BUILTIN_newarray_boolean (functionptr) builtin_newarray_boolean
-java_handle_chararray_t *builtin_newarray_char(s4 size);
+java_handle_chararray_t *builtin_newarray_char(int32_t size);
 #define BUILTIN_newarray_char (functionptr) builtin_newarray_char
-java_handle_floatarray_t *builtin_newarray_float(s4 size);
+java_handle_floatarray_t *builtin_newarray_float(int32_t size);
 #define BUILTIN_newarray_float (functionptr) builtin_newarray_float
-java_handle_doublearray_t *builtin_newarray_double(s4 size);
+java_handle_doublearray_t *builtin_newarray_double(int32_t size);
 #define BUILTIN_newarray_double (functionptr) builtin_newarray_double
-java_handle_bytearray_t *builtin_newarray_byte(s4 size);
+java_handle_bytearray_t *builtin_newarray_byte(int32_t size);
 #define BUILTIN_newarray_byte (functionptr) builtin_newarray_byte
-java_handle_shortarray_t *builtin_newarray_short(s4 size);
+java_handle_shortarray_t *builtin_newarray_short(int32_t size);
 #define BUILTIN_newarray_short (functionptr) builtin_newarray_short
-java_handle_intarray_t *builtin_newarray_int(s4 size);
+java_handle_intarray_t *builtin_newarray_int(int32_t size);
 #define BUILTIN_newarray_int (functionptr) builtin_newarray_int
-java_handle_longarray_t *builtin_newarray_long(s4 size);
+java_handle_longarray_t *builtin_newarray_long(int32_t size);
 #define BUILTIN_newarray_long (functionptr) builtin_newarray_long
 
 java_handle_objectarray_t *builtin_multianewarray(int n,
index d9e7e61974a5476c6721b37a1a7ba51a2652c2a5..735c1de70776c296d1113670634222df52a2526e 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/builtintable.inc - tables of builtin 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 "arch.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "threads/lock-common.h"
 
 #include "vm/builtin.h"
+
 #include "vm/jit/jit.h"
 
 
index b257535d15d884794dfa90fe13da6fd959577811..d258329c1f8c538ffe476884da8e0f4d2ecfd09a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/exceptions.c - exception related 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 "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/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/util.h"
 
@@ -83,35 +82,6 @@ java_object_t *_no_threads_exceptionptr = NULL;
 #endif
 
 
-/* exceptions_init *************************************************************
-
-   Initialize the exceptions subsystem.
-
-*******************************************************************************/
-
-void exceptions_init(void)
-{
-#if !(defined(__ARM__) && defined(__LINUX__))
-       /* On arm-linux the first memory page can't be mmap'ed, as it
-          contains the exception vectors. */
-
-       int pagesize;
-
-       /* mmap a memory page at address 0x0, so our hardware-exceptions
-          work. */
-
-       pagesize = system_getpagesize();
-
-       (void) system_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
-#endif
-
-       /* check if we get into trouble with our hardware-exceptions */
-
-       if (OFFSET(java_bytearray_t, data) <= EXCEPTION_HARDWARE_LARGEST)
-               vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray_t, data), EXCEPTION_HARDWARE_LARGEST);
-}
-
-
 /* exceptions_get_exception ****************************************************
 
    Returns the current exception pointer of the current thread.
@@ -175,7 +145,7 @@ void exceptions_set_exception(java_handle_t *e)
        if (opt_DebugExceptions) {
                printf("[exceptions_set_exception  : t=%p, o=%p, class=",
                           (void *) t, (void *) o);
-               class_print(o->vftbl->class);
+               class_print(o->vftbl->clazz);
                printf("]\n");
        }
 #endif
@@ -276,6 +246,51 @@ static void exceptions_abort(utf *classname, utf *message)
 }
 
 
+/* 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.
@@ -307,6 +322,99 @@ static java_handle_t *exceptions_new_utf(utf *classname)
 }
 
 
+/* 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
@@ -501,87 +609,6 @@ static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
 }
 
 
-/* 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 *s;
-       java_handle_t *o;
-
-       if (vm_initializing)
-               exceptions_abort(classname, message);
-
-       c = load_class_bootstrap(classname);
-
-       if (c == NULL)
-               return exceptions_get_exception();
-
-       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_throw_utf_utf ****************************************************
 
    Creates an exception object with the given name, initalizes and
@@ -794,7 +821,7 @@ void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
 
 void exceptions_throw_classnotfoundexception(utf *name)
 {      
-       exceptions_throw_utf_utf(utf_java_lang_ClassNotFoundException, name);
+       exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
 }
 
 
@@ -1207,7 +1234,7 @@ void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
 
        if (m != NULL)
                msglen =
-                       strlen("(class: ") + utf_bytes(m->class->name) +
+                       strlen("(class: ") + utf_bytes(m->clazz->name) +
                        strlen(", method: ") + utf_bytes(m->name) +
                        strlen(" signature: ") + utf_bytes(m->descriptor) +
                        strlen(") ") + strlen("0");
@@ -1224,7 +1251,7 @@ void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
 
        if (m != NULL) {
                strcpy(msg, "(class: ");
-               utf_cat_classname(msg, m->class->name);
+               utf_cat_classname(msg, m->clazz->name);
                strcat(msg, ", method: ");
                utf_cat(msg, m->name);
                strcat(msg, " signature: ");
@@ -1274,7 +1301,7 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
        msglen = 0;
 
        if (m != NULL)
-               msglen = strlen("(class: ") + utf_bytes(m->class->name) +
+               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") 
@@ -1288,7 +1315,7 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
 
        if (m != NULL) {
                strcpy(msg, "(class: ");
-               utf_cat_classname(msg, m->class->name);
+               utf_cat_classname(msg, m->clazz->name);
                strcat(msg, ", method: ");
                utf_cat(msg, m->name);
                strcat(msg, " signature: ");
@@ -1589,60 +1616,6 @@ void exceptions_throw_stringindexoutofboundsexception(void)
 }
 
 
-/* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
-
-   Check the exception for a ClassNotFoundException. If it is one,
-   convert it to a NoClassDefFoundError.
-
-*******************************************************************************/
-
-void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
-{
-       classinfo           *c;
-       java_handle_t       *o;
-       java_handle_t       *cause;
-       java_lang_Throwable *object;
-       java_lang_String    *s;
-
-       /* Load java/lang/ClassNotFoundException for the instanceof
-          check. */
-
-       c = load_class_bootstrap(utf_java_lang_ClassNotFoundException);
-
-       if (c == NULL)
-               return;
-
-       /* Get the cause. */
-
-       cause = exceptions_get_exception();
-
-       /* Convert ClassNotFoundException's to NoClassDefFoundError's. */
-
-       if (builtin_instanceof(cause, c)) {
-               /* clear exception, because we are calling jit code again */
-
-               exceptions_clear_exception();
-
-               /* create new error */
-
-               object = (java_lang_Throwable *) cause;
-               LLNI_field_get_ref(object, detailMessage, s);
-
-               o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
-                                                                                 (java_handle_t *) s);
-
-               /* we had an exception while creating the error */
-
-               if (exceptions_get_exception())
-                       return;
-
-               /* set new exception */
-
-               exceptions_set_exception(o);
-       }
-}
-
-
 /* exceptions_fillinstacktrace *************************************************
 
    Calls the fillInStackTrace-method of the currently thrown
@@ -1833,7 +1806,7 @@ void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, voi
                                if (!(c->state & CLASS_LOADED))
                                        /* use the methods' classloader */
                                        if (!load_class_from_classloader(c->name,
-                                                                                                        m->class->classloader))
+                                                                                                        m->clazz->classloader))
                                                goto exceptions_handle_exception_return;
 
                                /* XXX I think, if it is not linked, we can be sure
@@ -2016,63 +1989,104 @@ void exceptions_print_current_exception(void)
 
 void exceptions_print_stacktrace(void)
 {
-       java_handle_t *oxptr;
-       java_handle_t *xptr;
-       classinfo     *c;
-       methodinfo    *m;
+       java_handle_t    *e;
+       java_handle_t    *ne;
+       classinfo        *c;
+       methodinfo       *m;
 
-       /* get original exception */
+#if defined(ENABLE_THREADS)
+       threadobject     *t;
+       java_lang_Thread *to;
+#endif
 
-       oxptr = exceptions_get_and_clear_exception();
+       /* Get and clear exception because we are calling Java code
+          again. */
 
-       if (oxptr == NULL)
-               vm_abort("exceptions_print_stacktrace: no exception thrown");
+       e = exceptions_get_and_clear_exception();
 
-       /* clear exception, because we are calling jit code again */
+       if (e == NULL)
+               return;
 
-       LLNI_class_get(oxptr, c);
+#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. */
 
-       /* find the printStackTrace() method */
+               LLNI_class_get(e, c);
 
-       m = class_resolveclassmethod(c,
-                                                                utf_printStackTrace,
-                                                                utf_void__void,
-                                                                class_java_lang_Object,
-                                                                false);
+               /* Find the printStackTrace() method. */
 
-       if (m == NULL)
-               vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
+               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 ");
 
-       /* print compatibility message */
+#if defined(ENABLE_THREADS)
+               /* Print thread name.  We get the thread here explicitly as we
+                  need it afterwards. */
 
-       fprintf(stderr, "Exception in thread \"main\" ");
+               t  = thread_get_current();
+               to = (java_lang_Thread *) thread_get_object(t);
 
-       /* print the stacktrace */
+               if (to != NULL) {
+                       fprintf(stderr, "in thread \"");
+                       thread_fprint_name(t, stderr);
+                       fprintf(stderr, "\" ");
+               }
+#endif
 
-       (void) vm_call_method(m, oxptr);
+               /* Print the stacktrace. */
 
-       /* This normally means, we are EXTREMLY out of memory or
-          have a serious problem while printStackTrace. But may
-          be another exception, so print it. */
+               if (builtin_instanceof(e, class_java_lang_Throwable)) {
+                       (void) vm_call_method(m, e);
 
-       xptr = exceptions_get_exception();
+                       /* If this happens we are EXTREMLY out of memory or have a
+                          serious problem while printStackTrace.  But may be
+                          another exception, so print it. */
 
-       if (xptr != NULL) {
-               fprintf(stderr, "Exception while printStackTrace(): ");
+                       ne = exceptions_get_exception();
 
-               /* now print original exception */
+                       if (ne != NULL) {
+                               fprintf(stderr, "Exception while printStackTrace(): ");
 
-               exceptions_print_exception(xptr);
-               stacktrace_print_exception(xptr);
+                               /* Print the current exception. */
 
-               /* now print original exception */
+                               exceptions_print_exception(ne);
+                               stacktrace_print_exception(ne);
 
-               fprintf(stderr, "Original exception was: ");
-               exceptions_print_exception(oxptr);
-               stacktrace_print_exception(oxptr);
-       }
+                               /* Now print the original exception. */
 
-       fflush(stderr);
+                               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);
+       }
 }
 
 
index 93958851a4027ed9e82badfad239ad296cfb4503..1aea660408cd7c400337435b3106a30d2aa823c7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/exceptions.h - exception related functions prototypes
 
-   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 _EXCEPTIONS_H
 #define _EXCEPTIONS_H
 
-/* forward typedefs ***********************************************************/
-
 #include "config.h"
 #include "vm/types.h"
 
 #include "vm/global.h"
 
-#include "vm/jit/stacktrace.h"
-
 #include "vmcore/references.h"
 #include "vmcore/method.h"
 
 
-/* hardware-exception defines **************************************************
-
-   These defines define an internal number for the various hardware
-   exceptions.
-
-   ATTENTION: These values are also used as load-displacements on some
-   architectures. Thus, these values must NOT be aligned to 4 or
-   8-byte boundaries, since normal loads could have such offsets with
-   a base of NULL which should result in a NullPointerException.
-
-   NOTE: In exceptions_init() we have a check whether the offset of
-   java_arrayheader.data[0] is greater than the largest displacement
-   defined below.  Otherwise normal array loads/stores could trigger
-   an exception.
-
-*******************************************************************************/
-
-#define EXCEPTION_HARDWARE_NULLPOINTER              0
-#define EXCEPTION_HARDWARE_ARITHMETIC               1
-#define EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS    2
-#define EXCEPTION_HARDWARE_ARRAYSTORE               3
-
-#define EXCEPTION_HARDWARE_CLASSCAST                5
-#define EXCEPTION_HARDWARE_EXCEPTION                6
-#define EXCEPTION_HARDWARE_PATCHER                  7
-
-#define EXCEPTION_HARDWARE_COMPILER                 9
-
-#define EXCEPTION_HARDWARE_LARGEST                  9
-
-
 /* function prototypes ********************************************************/
 
-void           exceptions_init(void);
-
 java_handle_t *exceptions_get_exception(void);
 void           exceptions_set_exception(java_handle_t *o);
 void           exceptions_clear_exception(void);
@@ -131,8 +92,6 @@ void exceptions_throw_nullpointerexception(void);
 void exceptions_throw_privilegedactionexception(java_handle_t *cause);
 void exceptions_throw_stringindexoutofboundsexception(void);
 
-void exceptions_classnotfoundexception_to_noclassdeffounderror(void);
-
 java_handle_t *exceptions_fillinstacktrace(void);
 
 void exceptions_print_exception(java_handle_t *xptr);
index dc7da8532e1f5222e23e8a7a6b079fc69160505c..833efbfb127d02449d36c7d5c342e06e867df1d5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/finalizer.c - finalizer linked list and thread
 
-   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,7 +32,7 @@
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
@@ -62,6 +60,8 @@ static java_object_t *lock_thread_finalizer;
 
 bool finalizer_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("finalizer_init");
+
 #if defined(ENABLE_THREADS)
        lock_thread_finalizer = NEW(java_object_t);
 
index 0b7c7990e2a4774f7b7559fe1ad482809bad0994..c0fe462a21d6ecd52c6f96c0b7ec65e1d86e1ded 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/global.h - global definitions
 
-   Copyright (C) 1996-2005, 2007, 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, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -46,7 +44,6 @@ typedef unsigned int bool;              /* boolean data type                  */
 #define true         1
 #define false        0
 
-
 #if defined(ENABLE_SSA)
 /* immediate to get an addidional target Local Var Index */
 /* for IINC in Combination with SSA */
@@ -80,6 +77,24 @@ typedef union {
 #define ALIGN_2(a)                      ALIGN_EVEN(a)
 
 
+/* printf format defines ******************************************************/
+
+/* Define printf formats which change size between 32- and 64-bit. */
+
+#if SIZEOF_VOID_P == 8
+# define PRINTF_FORMAT_INT64_T    "%ld"
+#else
+# define PRINTF_FORMAT_INT64_T    "%lld"
+#endif
+
+
+/* convenience macros *********************************************************/
+
+/* Makes a string of the argument (which is not macro-expanded). */
+
+#define STR(a)  #a
+
+
 /* forward typedefs ***********************************************************/
 
 typedef struct java_object_t java_object_t; 
@@ -208,7 +223,6 @@ typedef struct java_objectarray_t java_objectarray_t;
 
 *******************************************************************************/
 
-#define HDRFLAG_FLC           0x01
 #define HDRFLAG_MARK1         0x02
 #define HDRFLAG_MARK2         0x04
 #define HDRFLAG_UNCOLLECTABLE 0x08
@@ -221,8 +235,8 @@ struct java_object_t {                 /* header for all objects              */
 #if defined(ENABLE_THREADS)
        uintptr_t      lockword;
 #endif
-#if defined(ENABLE_THREADS) || defined(ENABLE_GC_CACAO)
-       uintptr_t      hdrflags;           /* word containing the FLC and GC bits */
+#if defined(ENABLE_GC_CACAO)
+       uintptr_t      hdrflags;           /* word containing the GC bits         */
 #endif
 };
 
index 3843160a99a12a0192b6f13675c1a17815c8bacd..2c6ff024ddad81c18b4997484c477006380cbfe5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/initialize.c - static class initializer 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.
 
 static bool initialize_class_intern(classinfo *c);
 
 
+/* initialize_init *************************************************************
+
+   Initialize important system classes.
+
+*******************************************************************************/
+
+void initialize_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("initialize_init");
+
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_CLASSPATH_GNU)
+
+       /* Nothing. */
+
+# elif defined(WITH_CLASSPATH_SUN)
+
+       if (!initialize_class(class_java_lang_String))
+               vm_abort("initialize_init: Initialization failed: java.lang.String");
+
+       if (!initialize_class(class_java_lang_System))
+               vm_abort("initialize_init: Initialization failed: java.lang.System");
+
+       if (!initialize_class(class_java_lang_ThreadGroup))
+               vm_abort("initialize_init: Initialization failed: java.lang.ThreadGroup");
+
+       if (!initialize_class(class_java_lang_Thread))
+               vm_abort("initialize_init: Initialization failed: java.lang.Thread");
+
+# else
+#  error unknown classpath configuration
+# endif
+
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+
+       /* Nothing. */
+
+#else
+# error unknown Java configuration
+#endif
+}
+
 /* initialize_class ************************************************************
 
    In Java, every class can have a static initialization
index 82a8a09fd8b6af192a9ec88656880338be42be52..431c1c8d846eb3fb8d4c04733813aec3ce7441b5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/initialize.h - static class initializer 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/global.h"
 
-#include "vmcore/references.h"
+#include "vmcore/class.h"
 
 
 /* function prototypes ********************************************************/
 
-/* call initializer of class */
+void initialize_init(void);
 bool initialize_class(classinfo *c);
 
 #endif /* _INITIALIZE_H */
index 51956cdc2bf45f1f4518c4f6e0e9bac592842ed8..015a917ce6cc392c394ac03c84dfd99e8638e1cd 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/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.
 ##
@@ -30,6 +28,7 @@ LIBS =
 DIST_SUBDIRS = \
        allocator \
        inline \
+       ir \
        loop \
        optimizing \
        schedule \
@@ -49,6 +48,7 @@ DIST_SUBDIRS = \
        x86_64
 
 SUBDIRS = \
+       ir \
        optimizing \
        $(ARCH_DIR)
 
@@ -108,6 +108,10 @@ REPLACE_SOURCES += \
 STACK_SOURCES = \
        stack.c \
        stack.h
+
+TRAP_SOURCES = \
+       trap.c \
+       trap.h
 endif
 
 if ENABLE_REPLACEMENT
@@ -151,11 +155,15 @@ libjit_la_SOURCES = \
        emit-common.h \
        exceptiontable.c \
        exceptiontable.h \
+       executionstate.c \
+       executionstate.h \
        icmdtable.inc \
        jit.c \
        jit.h \
        linenumbertable.c \
        linenumbertable.h \
+       methodtree.c \
+       methodtree.h \
        parse.c \
        parse.h \
        patcher-common.c \
@@ -169,7 +177,8 @@ libjit_la_SOURCES = \
        stacktrace.c \
        stacktrace.h \
        trace.c \
-       trace.h
+       trace.h \
+       $(TRAP_SOURCES)
 
 libjit_la_SOURCES += \
        cfg.c \
@@ -177,8 +186,8 @@ libjit_la_SOURCES += \
 
 libjit_la_LIBADD = \
        allocator/liballocator.la \
-       $(ALLOCATOR_LIB) \
        $(INLINE_LIB) \
+       ir/libir.la \
        $(LOOP_LIB) \
        $(OPTIMIZING_LIB) \
        $(PROFILE_LIB) \
@@ -187,6 +196,15 @@ libjit_la_LIBADD = \
        $(INTRP_LIB) \
        $(ARCH_LIB)
 
+if ENABLE_PYTHON
+libjit_la_SOURCES += \
+       python.c
+AM_CPPFLAGS += \
+       @PYTHON_CSPEC@
+LIBS += \
+       @PYTHON_LSPEC@
+endif
+
 
 ## Local variables:
 ## mode: Makefile
index 99ed02b6d1154192e20578e329a606f2c43ff1e2..6a84ade40945d8609617f94385de998e6a2232d8 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/abi.h - common ABI defines
 
-   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"
 #include "vm/types.h"
 
+#include "arch.h"
+
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/stack.h"
 
-#include "arch.h"
 
 /* ABI externs ****************************************************************/
 
@@ -69,7 +69,7 @@ void md_param_alloc(methoddesc *md);
 void md_param_alloc_native(methoddesc *md);
 
 /* machine dependent return value handling function */
-void md_return_alloc(jitdata *jd, stackptr stackslot);
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot);
 
 #endif /* _ABI_H */
 
index 32ebf4dda5883b489a8c79d2a580a03a243d331c..5a0e1da95539354da4a5c092039ee7364de06f62 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/allocator/liveness.c - liveness analysis for lsra
 
-   Copyright (C) 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) 2005, 2006, 2007, 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 Ullrich
-
-
 */
 
 
 
 /* function prototypes */
 void liveness_scan_registers_canditates(jitdata *jd, int b_index, int iindex, 
-                                                                               stackptr src, lv_sets *sets);
-void liveness_set_stack(lsradata *ls, int block, int g_iindex, stackptr s,
+                                                                               stackelement_t* src, lv_sets *sets);
+void liveness_set_stack(lsradata *ls, int block, int g_iindex, stackelement_t* s,
                                                lv_sets *sets, int op);
 void liveness_set_local(lsradata *ls, int block, int g_iindex, s4 v_index,
                                                int type, lv_sets *sets, int op);
 
-void liveness_add_ss(struct lifetime *lt, stackptr s) {
+void liveness_add_ss(struct lifetime *lt, stackelement_t* s) {
        struct stackslot *ss;
        /* Stackslot noch nicht eingetragen? */
 
@@ -188,7 +181,7 @@ void liveness_join_lifetimes(jitdata *jd, int b_index) {
 
 void liveness_setup(jitdata *jd) {
        int i, icount, b_index;
-       stackptr src;
+       stackelement_t* src;
        methodinfo *m;
        lsradata *ls;
 
@@ -274,7 +267,7 @@ void liveness_setup(jitdata *jd) {
 void liveness_init(jitdata *jd) {
        int i, b_index, len;
        int lifetimes;
-       stackptr src, dst;
+       stackelement_t* src, dst;
        instruction *iptr;
        methodinfo *m;
        lsradata *ls;
@@ -330,7 +323,7 @@ void liveness_init(jitdata *jd) {
 void liveness_scan_basicblock(jitdata *jd, int b_index,
                                                          lv_sets *sets, int lifetimes) {
        int iindex;
-       stackptr    src;
+       stackelement_t*    src;
        instruction *iptr;
        int i;
        methodinfo *m;
@@ -424,7 +417,7 @@ void liveness(jitdata *jd) {
        int       i, p, t;
        methoddesc *md;
 #ifdef LV_DEBUG_CHECK
-       stackptr s;
+       stackelement_t* s;
 #endif
        methodinfo *m;
        registerdata *rd;
@@ -547,7 +540,7 @@ void liveness(jitdata *jd) {
                   
 }
 
-struct lifetime *liveness_get_ss_lifetime(lsradata *ls, stackptr s) {
+struct lifetime *liveness_get_ss_lifetime(lsradata *ls, stackelement_t* s) {
        struct lifetime *n;
        
        if (s->varnum >= 0) { /* new stackslot lifetime */
@@ -575,7 +568,7 @@ struct lifetime *liveness_get_ss_lifetime(lsradata *ls, stackptr s) {
        return n;
 }
 
-void liveness_set_stack(lsradata *ls, int block, int g_iindex, stackptr s,
+void liveness_set_stack(lsradata *ls, int block, int g_iindex, stackelement_t* s,
                                                lv_sets *sets,
                                                int op) {
        struct lifetime *n;
@@ -634,14 +627,14 @@ void liveness_set_local(lsradata *ls, int block, int g_iindex, s4 v_index,
 }
 
 void liveness_scan_registers_canditates(jitdata *jd, int b_index, int iindex,
-                                                                               stackptr src, lv_sets *sets)
+                                                                               stackelement_t* src, lv_sets *sets)
 {
 /*     methodinfo         *lm; */
        builtintable_entry *bte;
        methoddesc         *md;
        int i, g_iindex;
        instruction *iptr;
-       stackptr    dst;
+       stackelement_t*    dst;
        methodinfo *m;
        lsradata   *ls;
 
index b8fc55ac8da5b1f5d46c2d6d0ea71a6992d61a23..0ac20d24b929c59ad6b17e4b16b540b0bde8529f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/allocator/lsra.c - linear scan register allocator
 
-   Copyright (C) 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) 2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -79,7 +77,7 @@ struct freemem *lsra_getnewmem(int *);
 void lsra_setflags(int *, int);
 
 #ifdef LSRA_DEBUG_VERBOSE 
-void lsra_dump_stack(stackptr );
+void lsra_dump_stack(stackelement_t* );
 void print_lifetimes(jitdata *, int *, int);
 #endif
 
@@ -87,9 +85,9 @@ void print_lifetimes(jitdata *, int *, int);
 void lsra_scan_registers_canditates(jitdata *, int);
 void lsra_join_lifetimes(jitdata *, int);
 
-void _lsra_new_stack( lsradata *, stackptr , int , int, int);
-void _lsra_from_stack(lsradata *, stackptr , int , int, int);
-void lsra_add_ss(struct lifetime *, stackptr );
+void _lsra_new_stack( lsradata *, stackelement_t* , int , int, int);
+void _lsra_from_stack(lsradata *, stackelement_t* , int , int, int);
+void lsra_add_ss(struct lifetime *, stackelement_t* );
 void lsra_usage_local(lsradata *, s4 , int , int , int , int );
 #endif
 
@@ -105,7 +103,7 @@ bool lsra(jitdata *jd)
 #if defined(LSRA_DEBUG_CHECK)
        methodinfo   *m;
        int      b_index;
-       stackptr in,out;
+       stackelement_t* in,out;
        int      ind, outd;
 #endif
 
@@ -1979,7 +1977,7 @@ void lsra_join_lifetimes(jitdata *jd,int b_index) {
        }
 }
 
-struct stackslot *lsra_make_ss(stackptr s, int bb_index)
+struct stackslot *lsra_make_ss(stackelement_t* s, int bb_index)
 {
        struct stackslot *ss;
 
@@ -1989,7 +1987,7 @@ struct stackslot *lsra_make_ss(stackptr s, int bb_index)
        return ss;
 }
 
-void lsra_add_ss(struct lifetime *lt, stackptr s) {
+void lsra_add_ss(struct lifetime *lt, stackelement_t* s) {
        struct stackslot *ss;
 
        /* Stackslot not in list? */
@@ -2006,7 +2004,7 @@ void lsra_add_ss(struct lifetime *lt, stackptr s) {
        }
 }
 
-struct lifetime *get_ss_lifetime(lsradata *ls, stackptr s) {
+struct lifetime *get_ss_lifetime(lsradata *ls, stackelement_t* s) {
        struct lifetime *n;
        
        if (s->varnum >= 0) { /* new stackslot lifetime */
@@ -2078,7 +2076,7 @@ struct lifetime *get_ss_lifetime(lsradata *ls, stackptr s) {
 
 #define lsra_new_stack(ls, s, block, instr) \
        if ((s)->varkind != ARGVAR) _lsra_new_stack(ls, s, block, instr, LSRA_STORE)
-void _lsra_new_stack(lsradata *ls, stackptr s, int block, int instr, int store)
+void _lsra_new_stack(lsradata *ls, stackelement_t* s, int block, int instr, int store)
 {
        struct lifetime *n;
 
@@ -2102,7 +2100,7 @@ void _lsra_new_stack(lsradata *ls, stackptr s, int block, int instr, int store)
        if ((s)->varkind != ARGVAR) _lsra_from_stack(ls, s, block, instr, LSRA_LOAD)
 #define lsra_pop_from_stack(ls, s, block, instr) \
        if ((s)->varkind != ARGVAR) _lsra_from_stack(ls, s, block, instr, LSRA_POP)
-void _lsra_from_stack(lsradata *ls, stackptr s, int block, int instr, int store)
+void _lsra_from_stack(lsradata *ls, stackelement_t* s, int block, int instr, int store)
 {
        struct lifetime *n;
 
@@ -2166,7 +2164,7 @@ void lsra_usage_local(lsradata *ls, s4 v_index, int type, int block, int instr,
 }      
 
 #ifdef LSRA_DEBUG_VERBOSE
-void lsra_dump_stack(stackptr s)
+void lsra_dump_stack(stackelement_t* s)
 {
        while (s!=NULL) {
                printf("%p(R%3i N%3i K%3i T%3i F%3i) ",(void *)s,s->regoff, s->varnum, 
@@ -2186,8 +2184,8 @@ void lsra_scan_registers_canditates(jitdata *jd, int b_index)
        int i;
        int opcode;
        int iindex;
-       stackptr    src;
-       stackptr    dst;
+       stackelement_t*    src;
+       stackelement_t*    dst;
        instruction *iptr;
        bool join_ret; /* for lsra_join* Macros */
        methodinfo *m;
index 306480e5346d79f459c2637687d8f0450a6aea2a..3043bdced4676333c79a4c37d9e787f76dc0fc1f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/allocator/lsra.h - linear scan register allocator header
 
-   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., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Ullrich
-
-   Changes: Edwin Steiner
-
 */
 
 
@@ -129,7 +121,7 @@ struct b_loop {
 
 
 struct stackslot {
-       stackptr s;
+       stackelement_t* s;
        int bb;
        struct stackslot *next;
 };
index d400406f0e4e5171dc0d032efd0d9c6501333f80..bcb7b9b59310a70d9eb92950e845c2cbfa92703f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/allocator/simplereg.c - register allocator
 
-   Copyright (C) 1996-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) 1996-2005, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -1350,7 +1348,7 @@ static void simplereg_allocate_temporaries(jitdata *jd)
 
                        /* assert that all copy counts are zero */
 
-#if !defined(NDEBUG)
+#if !defined(NDEBUG) && !defined(ENABLE_SSA)
                        for (i=0; i < TOTAL_REG_CNT; ++i)
                                assert(rd->regcopycount[i] == 0);
 #endif
@@ -1801,8 +1799,8 @@ void simplereg_make_statistics(jitdata *jd)
        int i;
        s4 len;
 #if 0
-       stackptr    src, src_old;
-       stackptr    dst;
+       stackelement_t*    src, src_old;
+       stackelement_t*    dst;
        instruction *iptr;
 #endif
        basicblock  *bptr;
index e94ae058709c270487bfa5973b03a063e328fb83..cd4e0f470162efcf4cae8b40bd4f9d8d9f8e978f 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/alpha/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.
 ##
@@ -21,8 +19,8 @@
 ## along with this program; if not, write to the Free Software
 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 ## 02110-1301, USA.
-##
-##
+
+
 DIST_SUBDIRS = \
        freebsd \
        linux
@@ -57,6 +55,7 @@ libarch_la_SOURCES = \
        \
        md-abi.c \
        md-abi.h \
+       md-trap.h \
        md.c \
        md.h
 
index 4fced813c98bc3a74840e3b01d2394d8d809c8bb..b05a8afcd100b2cbd5781f1c4baa6cd30d359e35 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/alpha/asmpart.S - Java-C interface functions for alpha
 
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
+   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
@@ -139,9 +139,9 @@ L_asm_vm_call_method_stack_copy_done:
 L_asm_vm_call_method_recompute_pv:
        lda     pv,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)(ra)
 
+L_asm_vm_call_method_recompute_return:
        mov     s0,sp                       /* restore stack pointer              */
 
-L_asm_vm_call_method_recompute_return:
        ldq     ra,0*8(sp)                  /* restore RA                         */
        ldq     gp,1*8(sp)                  /* restore global pointer             */
        ldq     s0,3*8(sp)
index caddf5c9731c8a78f70b24302ffba6d249f5b283..e30d7d601b5702a0ebdfc0c2eb1ca79ce97a1331 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
 
-   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/reg.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
-#if defined(ENABLE_LSRA)
+#if defined(ENABLE_SSA)
+# include "vm/jit/optimizing/lsra.h"
+# include "vm/jit/optimizing/ssa.h"
+#elif defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
 
@@ -246,12 +248,12 @@ bool codegen_emit(jitdata *jd)
                /* decide which monitor enter function to call */
 
                if (m->flags & ACC_STATIC) {
-                       disp = dseg_add_address(cd, &m->class->object.header);
+                       disp = dseg_add_address(cd, &m->clazz->object.header);
                        M_ALD(REG_A0, REG_PV, disp);
                }
                else {
                        M_BNEZ(REG_A0, 1);
-                       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
                }
 
                M_AST(REG_A0, REG_SP, s1 * 8);
@@ -1274,7 +1276,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_L2F:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_unique_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
                        M_LST(s1, REG_PV, disp);
                        M_DLD(d, REG_PV, disp);
                        M_CVTLF(d, d);
@@ -1285,7 +1287,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_L2D:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_unique_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
                        M_LST(s1, REG_PV, disp);
                        M_DLD(d, REG_PV, disp);
                        M_CVTLD(d, d);
@@ -1296,7 +1298,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_D2I:
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_unique_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
                        M_CVTDL_C(s1, REG_FTMP2);
                        M_CVTLI(REG_FTMP2, REG_FTMP3);
                        M_DST(REG_FTMP3, REG_PV, disp);
@@ -1308,7 +1310,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_D2L:
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_unique_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
                        M_CVTDL_C(s1, REG_FTMP2);
                        M_DST(REG_FTMP2, REG_PV, disp);
                        M_LLD(d, REG_PV, disp);
@@ -1783,8 +1785,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
                                                                                  0);
                        }
 
@@ -1828,8 +1830,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
                                                                                  0);
                        }
 
@@ -1874,8 +1876,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
                                                                                  0);
                        }
                        
@@ -2653,9 +2655,9 @@ gen_method:
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
+                                               sizeof(methodptr*) * lm->clazz->index;
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
                                        
                                /* implicit null-pointer check */
index 63f1fbab4c6dc194525b4f96f80bedfd04456bc0..f0d1b7c8967e54335b258afce0b2c0e1d0265fc5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/alpha/emit.c - Alpha 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,8 +37,6 @@
 
 #include "threads/lock-common.h"
 
-#include "vm/exceptions.h"
-
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
@@ -50,6 +46,7 @@
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/trace.h"
+#include "vm/jit/trap.h"
 
 #include "vmcore/options.h"
 
@@ -327,7 +324,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
                M_BNEZ(reg, 1);
                /* Destination register must not be REG_ZERO, because then no
                   SIGSEGV is thrown. */
-               M_ALD_INTERN(reg, REG_ZERO, EXCEPTION_HARDWARE_ARITHMETIC);
+               M_ALD_INTERN(reg, REG_ZERO, TRAP_ArithmeticException);
        }
 }
 
@@ -344,7 +341,7 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1,
                M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
                M_CMPULT(s2, REG_ITMP3, REG_ITMP3);
                M_BNEZ(REG_ITMP3, 1);
-               M_ALD_INTERN(s2, REG_ZERO, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+               M_ALD_INTERN(s2, REG_ZERO, TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -361,7 +358,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
                M_BNEZ(REG_RESULT, 1);
                /* Destination register must not be REG_ZERO, because then no
                   SIGSEGV is thrown. */
-               M_ALD_INTERN(REG_RESULT, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_ALD_INTERN(REG_RESULT, REG_ZERO, TRAP_ArrayStoreException);
        }
 }
 
@@ -385,7 +382,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
                default:
                        vm_abort("emit_classcast_check: unknown condition %d", condition);
                }
-               M_ALD_INTERN(s1, REG_ZERO, EXCEPTION_HARDWARE_CLASSCAST);
+               M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
        }
 }
 
@@ -402,7 +399,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
                M_BNEZ(reg, 1);
                /* Destination register must not be REG_ZERO, because then no
                   SIGSEGV is thrown. */
-               M_ALD_INTERN(reg, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+               M_ALD_INTERN(reg, REG_ZERO, TRAP_NullPointerException);
        }
 }
 
@@ -419,7 +416,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
                M_BNEZ(REG_RESULT, 1);
                /* Destination register must not be REG_ZERO, because then no
                   SIGSEGV is thrown. */
-               M_ALD_INTERN(REG_RESULT, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);
+               M_ALD_INTERN(REG_RESULT, REG_ZERO, TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -432,7 +429,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 
 void emit_trap_compiler(codegendata *cd)
 {
-       M_ALD_INTERN(REG_METHODPTR, REG_ZERO, EXCEPTION_HARDWARE_COMPILER);
+       M_ALD_INTERN(REG_METHODPTR, REG_ZERO, TRAP_COMPILER);
 }
 
 
@@ -449,11 +446,11 @@ uint32_t emit_trap(codegendata *cd)
        /* Get machine code which is patched back in later. The
           trap is 1 instruction word long. */
 
-       mcode = *((u4 *) cd->mcodeptr);
+       mcode = *((uint32_t *) cd->mcodeptr);
 
        /* Destination register must not be REG_ZERO, because then no
           SIGSEGV is thrown. */
-       M_ALD_INTERN(REG_RESULT, REG_ZERO, EXCEPTION_HARDWARE_PATCHER);
+       M_ALD_INTERN(REG_RESULT, REG_ZERO, TRAP_PATCHER);
 
        return mcode;
 }
index 006c7009d8d645edc259905c3b1870bc1ee16ea1..afe391d11b2b86b0abc946d0a0ff509ff7ff80e1 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/alpha/linux/md-os.c - machine dependent Alpha Linux 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/alpha/md.h"
 #include "vm/jit/alpha/md-abi.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
 
 #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 ***************************************************
@@ -98,7 +97,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                type = disp;
 
-               if (type == EXCEPTION_HARDWARE_COMPILER) {
+               if (type == TRAP_COMPILER) {
                        /* The XPC is the RA minus 1, because the RA points to the
                           instruction after the call. */
 
@@ -113,14 +112,14 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                type = (int) addr;
        }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* Set registers. */
 
        switch (type) {
-       case EXCEPTION_HARDWARE_COMPILER:
+       case TRAP_COMPILER:
                if (p != NULL) {
                        _mc->sc_regs[REG_PV] = (uintptr_t) p;
                        _mc->sc_pc           = (uintptr_t) p;
@@ -141,7 +140,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                /* fall-through */
 
-       case EXCEPTION_HARDWARE_PATCHER:
+       case TRAP_PATCHER:
                if (p == NULL)
                        break;
 
@@ -208,18 +207,17 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-/* md_replace_executionstate_read **********************************************
+/* md_executionstate_read ******************************************************
 
-   Read the given context into an executionstate for Replacement.
+   Read the given context into an executionstate.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_read(executionstate_t *es, void *context)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
-       s4          i;
+       int         i;
 
        _uc = (ucontext_t *) context;
        _mc = &_uc->uc_mcontext;
@@ -228,30 +226,32 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
        es->pc = (u1 *) _mc->sc_pc;
        es->sp = (u1 *) _mc->sc_regs[REG_SP];
        es->pv = (u1 *) _mc->sc_regs[REG_PV];
+       es->ra = (u1 *) _mc->sc_regs[REG_RA];
 
        /* read integer registers */
        for (i = 0; i < INT_REG_CNT; i++)
                es->intregs[i] = _mc->sc_regs[i];
 
        /* read float registers */
-       for (i = 0; i < FLT_REG_CNT; i++)
-               es->fltregs[i] = _mc->sc_fpregs[i];
+       /* Do not use the assignment operator '=', as the type of
+        * 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));
 }
-#endif
 
 
-/* md_replace_executionstate_write *********************************************
+/* md_executionstate_write *****************************************************
 
-   Write the given executionstate back to the context for Replacement.
+   Write the given executionstate back to the context.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_write(executionstate_t *es, void *context)
+void md_executionstate_write(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
-       s4          i;
+       int         i;
 
        _uc = (ucontext_t *) context;
        _mc = &_uc->uc_mcontext;
@@ -261,15 +261,18 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
                _mc->sc_regs[i] = es->intregs[i];
 
        /* write float registers */
-       for (i = 0; i < FLT_REG_CNT; i++)
-               _mc->sc_fpregs[i] = es->fltregs[i];
+       /* Do not use the assignment operator '=', as the type of
+        * 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));
 
        /* write special registers */
        _mc->sc_pc           = (ptrint) es->pc;
        _mc->sc_regs[REG_SP] = (ptrint) es->sp;
        _mc->sc_regs[REG_PV] = (ptrint) es->pv;
+       _mc->sc_regs[REG_RA] = (ptrint) es->ra;
 }
-#endif
 
 
 /* md_critical_section_restart *************************************************
index e58cb1c8a07c4e107e903f0da86c6f02b787134d..3d054e195cd163039f1b1df75c3e53eed82a9771 100644 (file)
@@ -1,22 +1,6 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline void
-__attribute__ ((unused))
-atomic_add (volatile int *mem, int val)
-{
-    int temp;
-
-  __asm__ __volatile__ (
-    "1:\t"
-    "ldl_l  %1,%3\n\t"
-    "addl   %1,%2,%1\n\t"
-    "stl_c  %1,%0\n\t"
-    "beq    %1,1b\n\t"
-    : "=m"(*mem), "=&r"(temp)
-    : "r"(val), "m"(*mem));
-}
-
 static inline long
 __attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
@@ -39,7 +23,6 @@ compare_and_swap (volatile long *p, long oldval, long newval)
 }
 
 #define STORE_ORDER_BARRIER() __asm__ __volatile__ ("wmb" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
 #define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
 #define MEMORY_BARRIER() __asm__ __volatile__ ( \
                "mb" : : : "memory" );
index 2bc665662a31b3fed76332acc6aa5d8f13092798..90189e17ae6d47338e9eedd43eb6fa902785ab18 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/alpha/md-abi.c - functions for Alpha ABI
 
-   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.
 
@@ -246,7 +244,7 @@ void md_param_alloc_native(methoddesc *md)
    NOTE: Do not pass a LOCALVAR in stackslot->varnum.
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
 {
        methodinfo *m;
        methoddesc *md;
diff --git a/src/vm/jit/alpha/md-trap.h b/src/vm/jit/alpha/md-trap.h
new file mode 100644 (file)
index 0000000..c932579
--- /dev/null
@@ -0,0 +1,79 @@
+/* src/vm/jit/alpha/md-trap.h - Alpha hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (alpha) the trap numbers are used as load
+ * displacements and thus must not be 4- or 8-byte aligned.
+ *
+ * NOTE: In trap_init() we have a check whether the offset of
+ * java_arrayheader.data[0] is greater than the largest displacement
+ * defined below.  Otherwise normal array loads/stores could trigger
+ * an exception.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    1
+
+enum {
+       TRAP_NullPointerException           = 0,
+       TRAP_ArithmeticException            = 1,
+       TRAP_ArrayIndexOutOfBoundsException = 2,
+       TRAP_ArrayStoreException            = 3,
+
+       /* Don't use 4 (could be a normal load offset). */
+
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+
+       /* Don't use 8 (could be a normal load offset). */
+
+       TRAP_COMPILER                       = 9,
+       TRAP_END
+};
+
+#endif /* _MD_TRAP_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 125ff089211127a14b9eeb2db0d541ecc0e209fd..2958813c47ee7fad1d2dbb46fce1bce23dfbd051 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/alpha/md.c - 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.
 
@@ -27,7 +25,6 @@
 
 #include "config.h"
 
-#include <assert.h>
 #include <stdint.h>
 #include <ucontext.h>
 
@@ -41,10 +38,9 @@ extern void ieee_set_fp_control(unsigned long fp_control);
 #include "vm/jit/alpha/codegen.h"
 #include "vm/jit/alpha/md.h"
 
-#include "vm/exceptions.h"
-
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/trap.h"
 
 
 /* global variables ***********************************************************/
@@ -213,7 +209,7 @@ void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert)
                *(u4*)(savedmcode) = *(u4*)(pc);
 
                /* build the machine code for the patch */
-               mcode = (0xa41f0000 | (EXCEPTION_HARDWARE_PATCHER));
+               mcode = (0xa41f0000 | (TRAP_PATCHER));
 
                /* write the new machine code */
                *(u4*)(pc) = mcode;
index 253465b71d9e6d22f99f17f97de0b75cde0d2e80..f990bbe99fdcac16251520844b4b0d69f25646fd 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/alpha/patcher.c - Alpha code patching 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.
 
@@ -219,8 +217,8 @@ bool patcher_get_putstatic(patchref_t *pr)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        PATCH_BACK_ORIGINAL_MCODE;
@@ -392,12 +390,12 @@ bool patcher_invokeinterface(patchref_t *pr)
        /* patch interfacetable index */
 
        *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
-                                                                sizeof(methodptr*) * m->class->index) & 0x0000ffff);
+                                                                sizeof(methodptr*) * m->clazz->index) & 0x0000ffff);
 
        /* patch method offset */
 
        *((s4 *) (ra + 4 + 4)) |=
-               (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
+               (s4) ((sizeof(methodptr) * (m - m->clazz->methods)) & 0x0000ffff);
 
        md_icacheflush(NULL, 0);
 
index 0113cc7ca2ef713ba9484af7fd5ab647aa537d5b..5955ff12e0797bfd625b540da05f9c45f97af159 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/arm/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.
 ##
@@ -49,10 +47,13 @@ libarch_la_SOURCES = \
        codegen.h \
        $(DISASS_SOURCES) \
        emit.c \
-       md.c \
+       patcher.c \
+       \
        md-abi.c \
        md-abi.h \
-       patcher.c
+       md-trap.h \
+       md.c \
+       md.h
 
 libarch_la_LIBADD = \
        $(OS_DIR)/libmd.la
index 54875ce23717f24660824b9cef5a37484056727d..88dfc8f74d3a3c2e503018aba1ae986ed98c4034 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/asmpart.S - Java-C interface functions for ARM
 
-   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.
 
@@ -302,7 +300,9 @@ asm_abstractmethoderror:
 *                                                                              *
 *******************************************************************************/
 
-.equ sys_cacheflush,__ARM_NR_cacheflush /* syscall number for cache flushing  */
+L___ARM_NR_cacheflush:
+       .align 2
+       .word __ARM_NR_cacheflush
 
 asm_cacheflush:
        add   a1, a0, a1
@@ -313,20 +313,17 @@ asm_cacheflush:
           see "http://wiki.debian.org/ArmEabiPort" for additional details. */
 
        stmfd sp!, {r7}
-       mov   r7, #0x0f0000
-       add   r7, r7, #0x000002
-#endif
-
-#if 0
+       ldr   r7, L___ARM_NR_cacheflush
+       swi   0x0
+       ldmfd sp!, {r7}
+#else
+# if 0
        /* TWISTI: required on iyonix, maybe a linux-2.4 bug */
        mov   a0, #0x0
        mov   a1, #0xff000000
-#endif
-
-       swi   sys_cacheflush
+# endif
 
-#if defined(__ARM_EABI__)
-       ldmfd sp!, {r7}
+       swi   __ARM_NR_cacheflush
 #endif
 
        mov   pc, lr
index 9ff1c63e5b45695a6572322c66fdee4c947b3870..00a37a24206fb919ebe14e382dd6f2a6148977ae 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/codegen.c - machine code generator for Arm
 
-   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.
 
@@ -280,7 +278,7 @@ bool codegen_emit(jitdata *jd)
                /* get the correct lock object */
 
                if (m->flags & ACC_STATIC) {
-                       disp = dseg_add_address(cd, &m->class->object.header);
+                       disp = dseg_add_address(cd, &m->clazz->object.header);
                        M_DSEG_LOAD(REG_A0, disp);
                }
                else {
@@ -1385,9 +1383,9 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                           fi->class, 0);
+                                                           fi->clazz, 0);
                                }
                        }
 
@@ -1438,9 +1436,9 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                           fi->class, 0);
+                                                           fi->clazz, 0);
                                }
                        }
 
@@ -2313,8 +2311,8 @@ bool codegen_emit(jitdata *jd)
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                               sizeof(methodptr*) * lm->clazz->index;
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
 
                                /* implicit null-pointer check */
@@ -2345,7 +2343,7 @@ bool codegen_emit(jitdata *jd)
                           our ENABLE_SOFTFLOAT define */
                        if (iptr->opc == ICMD_BUILTIN && d != TYPE_VOID && IS_FLT_DBL_TYPE(d)) {
 #if 0 && !defined(NDEBUG)
-                               dolog("BUILTIN that returns float or double (%s.%s)", m->class->name->text, m->name->text);
+                               dolog("BUILTIN that returns float or double (%s.%s)", m->clazz->name->text, m->name->text);
 #endif
                                /* we cannot use this macro, since it is not defined
                                   in ENABLE_SOFTFLOAT M_CAST_FLT_TO_INT_TYPED(d,
@@ -3024,7 +3022,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        /* this depends on gcc; it is independent from our ENABLE_SOFTFLOAT define */
        if (md->returntype.type != TYPE_VOID && IS_FLT_DBL_TYPE(md->returntype.type)) {
 #if 0 && !defined(NDEBUG)
-               dolog("NATIVESTUB that returns float or double (%s.%s)", m->class->name->text, m->name->text);
+               dolog("NATIVESTUB that returns float or double (%s.%s)", m->clazz->name->text, m->name->text);
 #endif
                /* we cannot use this macro, since it is not defined in ENABLE_SOFTFLOAT */
                /* M_CAST_FLT_TO_INT_TYPED(md->returntype.type, REG_FRESULT, REG_RESULT_TYPED(md->returntype.type)); */
index 9432f05a5d1d07b72b6991cd7c7c4dde32fb98e0..fc7dee7e3af79d52e7dba065e6ef728e7e374883 100644 (file)
 /******************************************************************************/
 
 #if defined(__ARMEL__)
-#define SPLIT_OPEN(type, reg, tmpreg) \
+
+# define SPLIT_OPEN(type, reg, tmpreg) \
        if (IS_2_WORD_TYPE(type) && GET_HIGH_REG(reg)==REG_SPLIT) { \
                /*dolog("SPLIT_OPEN({R%d;SPL} > {R%d;R%d})", GET_LOW_REG(reg), GET_LOW_REG(reg), tmpreg);*/ \
                /*assert(GET_LOW_REG(reg) == 3);*/ \
                (reg) = PACK_REGS(GET_LOW_REG(reg), tmpreg); \
        }
-#define SPLIT_LOAD(type, reg, offset) \
-       if (IS_2_WORD_TYPE(type) && GET_LOW_REG(reg)==3) { \
-               /*dolog("SPLIT_LOAD({R%d;R%d} from [%x])", GET_LOW_REG(reg), GET_HIGH_REG(reg), offset);*/ \
-               M_LDR(GET_HIGH_REG(reg), REG_SP, 4 * (offset)); \
-       }
-#define SPLIT_STORE_AND_CLOSE(type, reg, offset) \
+
+# define SPLIT_STORE_AND_CLOSE(type, reg, offset) \
        if (IS_2_WORD_TYPE(type) && GET_LOW_REG(reg)==3) { \
                /*dolog("SPLIT_STORE({R%d;R%d} to [%x])", GET_LOW_REG(reg), GET_HIGH_REG(reg), offset);*/ \
                M_STR(GET_HIGH_REG(reg), REG_SP, 4 * (offset)); \
                (reg) = PACK_REGS(GET_LOW_REG(reg), REG_SPLIT); \
        }
+
 #else /* defined(__ARMEB__) */
-#define SPLIT_OPEN(type, reg, tmpreg) \
+
+# define SPLIT_OPEN(type, reg, tmpreg) \
        if (IS_2_WORD_TYPE(type) && GET_LOW_REG(reg)==REG_SPLIT) { \
                /*dolog("SPLIT_OPEN({SPL;R%d} > {R%d;R%d})", GET_HIGH_REG(reg), tmpreg, GET_HIGH_REG(reg));*/ \
                /*assert(GET_HIGH_REG(reg) == 3);*/ \
                (reg) = PACK_REGS(tmpreg, GET_HIGH_REG(reg)); \
        }
-#define SPLIT_LOAD(type, reg, offset) \
-       if (IS_2_WORD_TYPE(type) && GET_HIGH_REG(reg)==3) { \
-               /*dolog("SPLIT_LOAD({R%d;R%d} from [%x])", GET_LOW_REG(reg), GET_HIGH_REG(reg), offset);*/ \
-               M_LDR(GET_LOW_REG(reg), REG_SP, 4 * (offset)); \
-       }
-#define SPLIT_STORE_AND_CLOSE(type, reg, offset) \
+
+# define SPLIT_STORE_AND_CLOSE(type, reg, offset) \
        if (IS_2_WORD_TYPE(type) && GET_HIGH_REG(reg)==3) { \
                /*dolog("SPLIT_STORE({R%d;R%d} to [%x])", GET_LOW_REG(reg), GET_HIGH_REG(reg), offset);*/ \
                M_STR(GET_LOW_REG(reg), REG_SP, 4 * (offset)); \
                (reg) = PACK_REGS(REG_SPLIT, GET_HIGH_REG(reg)); \
        }
+
 #endif
 
 
index 9135c99619f715ae1806354644e6c25cd91073d7..4caac6dd7a2e01321fd6428b92dd50be3eba98a5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/emit.c - Arm 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.
 
@@ -50,6 +48,7 @@
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/trace.h"
+#include "vm/jit/trap.h"
 
 #include "toolbox/logging.h" /* XXX for debugging only */
 
@@ -475,7 +474,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                CHECK_INT_REG(reg);
                M_TEQ_IMM(reg, 0);
-               M_TRAPEQ(0, EXCEPTION_HARDWARE_ARITHMETIC);
+               M_TRAPEQ(0, TRAP_ArithmeticException);
        }
 }
 
@@ -490,14 +489,14 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
 {
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TST(reg, reg);
-               M_TRAPEQ(0, EXCEPTION_HARDWARE_NULLPOINTER);
+               M_TRAPEQ(0, TRAP_NullPointerException);
        }
 }
 
 void emit_nullpointer_check_force(codegendata *cd, instruction *iptr, s4 reg)
 {
        M_TST(reg, reg);
-       M_TRAPEQ(0, EXCEPTION_HARDWARE_NULLPOINTER);
+       M_TRAPEQ(0, TRAP_NullPointerException);
 }
 
 
@@ -512,7 +511,7 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1,
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_ILD_INTERN(REG_ITMP3, s1, OFFSET(java_array_t, size));
                M_CMP(s2, REG_ITMP3);
-               M_TRAPHS(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+               M_TRAPHS(s2, TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -527,7 +526,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
 {
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TST(REG_RESULT, REG_RESULT);
-               M_TRAPEQ(0, EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_TRAPEQ(0, TRAP_ArrayStoreException);
        }
 }
 
@@ -543,15 +542,15 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                switch (condition) {
                case BRANCH_EQ:
-                       M_TRAPEQ(s1, EXCEPTION_HARDWARE_CLASSCAST);
+                       M_TRAPEQ(s1, TRAP_ClassCastException);
                        break;
 
                case BRANCH_LE:
-                       M_TRAPLE(s1, EXCEPTION_HARDWARE_CLASSCAST);
+                       M_TRAPLE(s1, TRAP_ClassCastException);
                        break;
 
                case BRANCH_UGT:
-                       M_TRAPHI(s1, EXCEPTION_HARDWARE_CLASSCAST);
+                       M_TRAPHI(s1, TRAP_ClassCastException);
                        break;
 
                default:
@@ -570,7 +569,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 {
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TST(REG_RESULT, REG_RESULT);
-               M_TRAPEQ(0, EXCEPTION_HARDWARE_EXCEPTION);
+               M_TRAPEQ(0, TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -588,9 +587,9 @@ uint32_t emit_trap(codegendata *cd)
        /* Get machine code which is patched back in later. The
           trap is 1 instruction word long. */
 
-       mcode = *((u4 *) cd->mcodeptr);
+       mcode = *((uint32_t *) cd->mcodeptr);
 
-       M_TRAP(0, EXCEPTION_HARDWARE_PATCHER);
+       M_TRAP(0, TRAP_PATCHER);
 
        return mcode;
 }
index ebf0c7d6c85a36fa95e239cfcbfa90bc48c089b6..37aaabcdc46f8a151b9b4a7624faf3e6873825fd 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/arm/linux/md-os.c - machine dependent arm linux functions
+/* src/vm/jit/arm/linux/md-os.c - machine dependent ARM Linux 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.
 
@@ -27,7 +25,6 @@
 
 #include "config.h"
 
-#include <assert.h>
 #include <stdint.h>
 
 #include "vm/types.h"
@@ -52,16 +49,17 @@ typedef struct ucontext {
 
 #define scontext_t struct sigcontext
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
+#include "vm/vm.h"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -102,24 +100,21 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
        mcode = *((s4 *) xpc);
 
-       /* this is a NullPointerException */
+       /* This is a NullPointerException. */
 
        addr = *((s4 *) _sc + OFFSET(scontext_t, arm_r0)/4 + ((mcode >> 16) & 0x0f));
-       type = EXCEPTION_HARDWARE_NULLPOINTER;
+       type = addr;
        val  = 0;
 
-       if (addr != 0)
-               vm_abort("md_signal_handler_sigsegv: faulting address is not NULL: addr=%p", addr);
+       /* Handle the trap. */
 
-       /* Handle the type. */
-
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* set registers */
 
-       _sc->arm_r10 = (intptr_t) p;
-       _sc->arm_fp  = (intptr_t) xpc;
-       _sc->arm_pc  = (intptr_t) asm_handle_exception;
+       _sc->arm_r10 = (uintptr_t) p;
+       _sc->arm_fp  = (uintptr_t) xpc;
+       _sc->arm_pc  = (uintptr_t) asm_handle_exception;
 }
 
 
@@ -164,23 +159,23 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
 #if defined(ENABLE_DISASSEMBLER)
                DISASSINSTR(xpc);
 #endif
-               assert(0);
+               vm_abort("Aborting...");
        }
 
        type = (mcode >> 8) & 0x0fff;
        val  = *((s4 *) _sc + OFFSET(scontext_t, arm_r0)/4 + (mcode & 0x0f));
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* set registers if we have an exception, continue execution
           otherwise (this is needed for patchers to work) */
 
        if (p != NULL) {
-               _sc->arm_r10 = (intptr_t) p;
-               _sc->arm_fp  = (intptr_t) xpc;
-               _sc->arm_pc  = (intptr_t) asm_handle_exception;
+               _sc->arm_r10 = (uintptr_t) p;
+               _sc->arm_fp  = (uintptr_t) xpc;
+               _sc->arm_pc  = (uintptr_t) asm_handle_exception;
        }
 }
 
@@ -238,6 +233,82 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
+/**
+ * Read the given context into an executionstate.
+ *
+ * @param es      execution state
+ * @param context machine context
+ */
+void md_executionstate_read(executionstate_t *es, void *context)
+{
+       vm_abort("md_executionstate_read: IMPLEMENT ME!");
+
+#if 0
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       int         i;
+
+       _uc = (ucontext_t *) context;
+       _mc = &_uc->uc_mcontext;
+
+       /* read special registers */
+       es->pc = (u1 *) _mc->sc_pc;
+       es->sp = (u1 *) _mc->sc_regs[REG_SP];
+       es->pv = (u1 *) _mc->sc_regs[REG_PV];
+       es->ra = (u1 *) _mc->sc_regs[REG_RA];
+
+       /* read integer registers */
+       for (i = 0; i < INT_REG_CNT; i++)
+               es->intregs[i] = _mc->sc_regs[i];
+
+       /* read float registers */
+       /* Do not use the assignment operator '=', as the type of
+        * 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));
+#endif
+}
+
+
+/**
+ * Write the given executionstate back to the context.
+ *
+ * @param es      execution state
+ * @param context machine context
+ */
+void md_executionstate_write(executionstate_t *es, void *context)
+{
+       vm_abort("md_executionstate_write: IMPLEMENT ME!");
+
+#if 0
+       ucontext_t *_uc;
+       mcontext_t *_mc;
+       int         i;
+
+       _uc = (ucontext_t *) context;
+       _mc = &_uc->uc_mcontext;
+
+       /* write integer registers */
+       for (i = 0; i < INT_REG_CNT; i++)
+               _mc->sc_regs[i] = es->intregs[i];
+
+       /* write float registers */
+       /* Do not use the assignment operator '=', as the type of
+        * 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));
+
+       /* write special registers */
+       _mc->sc_pc           = (ptrint) es->pc;
+       _mc->sc_regs[REG_SP] = (ptrint) es->sp;
+       _mc->sc_regs[REG_PV] = (ptrint) es->pv;
+       _mc->sc_regs[REG_RA] = (ptrint) es->ra;
+#endif
+}
+
+
 /* md_critical_section_restart *************************************************
 
    Search the critical sections tree for a matching section and set
index 05cae0e468d773849a2d6803cbfb76dc5ebe73a1..82fba2952ff330c3cfc1549e3a6b6dabb5b43d7a 100644 (file)
@@ -1,28 +1,6 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline void atomic_add(int *mem, int val)
-{
-       int temp, temp2, temp3;
-       /*dolog("atomic_add(%p [%d], %d)", mem, *mem, val);*/
-
-       /* TODO: improve this one! */
-        __asm__ __volatile__ (
-               "1:\t"
-               "ldr   %0,[%3]\n\t"
-               "add   %1,%0,%4\n\t"
-               "swp   %2,%1,[%3]\n\t"
-               "cmp   %0,%2\n\t"
-               "swpne %1,%2,[%3]\n\t"
-               "bne   1b"
-               : "=&r" (temp), "=&r" (temp2), "=&r" (temp3)
-               : "r" (mem), "r"(val)
-               : "cc", "memory"
-       );
-
-       /*dolog("atomic_add() mem=%d", *mem);*/
-}
-
 static inline long compare_and_swap(long *p, long oldval, long newval)
 {
        long ret, temp;
@@ -49,7 +27,6 @@ static inline long compare_and_swap(long *p, long oldval, long newval)
 }
 
 #define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
 #define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
 #define MEMORY_BARRIER() __asm__ __volatile__ ("" : : : "memory" );
 
index 12d4110b0803db867ddc776f8fb4d36754087b18..b10d45665a84181304360d564ac1b6afadb580eb 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/md-abi.c - functions for arm ABI
 
-   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.
 
@@ -350,7 +348,7 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
 {
        methodinfo   *m;
        codeinfo     *code;
diff --git a/src/vm/jit/arm/md-trap.h b/src/vm/jit/arm/md-trap.h
new file mode 100644 (file)
index 0000000..7992441
--- /dev/null
@@ -0,0 +1,71 @@
+/* src/vm/jit/arm/md-trap.h - ARM hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (arm) we use illegal instructions as trap
+ * instructions.  Since the illegal instruction with the value 1 is
+ * used by the kernel to generate a SIGTRAP, we skip this one.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    0
+
+enum {
+       TRAP_NullPointerException           = 0,
+
+       /* Skip 1 because it's the SIGTRAP illegal instruction. */
+
+       TRAP_ArithmeticException            = 2,
+       TRAP_ArrayIndexOutOfBoundsException = 3,
+       TRAP_ArrayStoreException            = 4,
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+       TRAP_COMPILER                       = 8
+};
+
+#endif /* _MD_TRAP_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 b6450a27858e90ca53d6140ccbdc0734746d9968..d37b3a710cee1487c052c05e0b45191d0932b519 100644 (file)
@@ -138,12 +138,6 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr)
 }
 
 
-void *md_asm_codegen_get_pv_from_pc(void *ra)
-{
-       return md_codegen_get_pv_from_pc(ra);
-}
-
-
 /*
  * These 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 36e128a599e7bcb0dce2e8ac34926330461d6bfc..84e8287c502cb4a1b5f509a1e77f70daa1462aef 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/patcher.c - ARM code patching 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.
 
@@ -106,8 +104,8 @@ bool patcher_get_putstatic(patchref_t *pr)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        PATCH_BACK_ORIGINAL_MCODE;
@@ -366,11 +364,11 @@ bool patcher_invokeinterface(patchref_t *pr)
 
        /* patch interfacetable index */
 
-       gen_resolveload(*((s4 *) (ra + 1 * 4)), (s4) (OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * m->class->index));
+       gen_resolveload(*((s4 *) (ra + 1 * 4)), (s4) (OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * m->clazz->index));
 
        /* patch method offset */
 
-       gen_resolveload(*((s4 *) (ra + 2 * 4)), (s4) (sizeof(methodptr) * (m - m->class->methods)));
+       gen_resolveload(*((s4 *) (ra + 2 * 4)), (s4) (sizeof(methodptr) * (m - m->clazz->methods)));
 
        /* synchronize instruction cache */
 
index 4163852371c5261bf9242c1c3aedd4d00928f033..9cc8260996b94c8d72d0c5268c50dcb6c524a5f1 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/cfg.c - build a control-flow graph
+/* src/vm/jit/cfg.c - build a control-flow graph
 
-   Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   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,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes: Edwin Steiner
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
-
-#include "vm/types.h"
+#include <stdint.h>
 
 #include "mm/memory.h"
+
+#include "vm/global.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/stack.h"
 
@@ -86,7 +82,7 @@ static void cfg_allocate_successors(basicblock *bptr)
 static void cfg_insert_predecessors(basicblock *bptr, basicblock *pbptr)
 {
        basicblock **tbptr;
-       s4           i;
+       int          i;
 
        tbptr = bptr->predecessors;
 
@@ -102,6 +98,25 @@ static void cfg_insert_predecessors(basicblock *bptr, basicblock *pbptr)
        bptr->predecessorcount++;
 }
 
+static void cfg_insert_successors(basicblock *bptr, basicblock *pbptr)
+{
+       basicblock **tbptr;
+       int          i;
+
+       tbptr = bptr->successors;
+
+       /* check if the successor is already stored in the array */
+
+       for (i = 0; i < bptr->successorcount; i++, tbptr++)
+               if (*tbptr == pbptr)
+                       return;
+
+       /* not found, insert it */
+
+       bptr->successors[bptr->successorcount] = pbptr;
+       bptr->successorcount++;
+}
+
 
 /* cfg_build *******************************************************************
 
@@ -118,13 +133,21 @@ bool cfg_build(jitdata *jd)
        instruction     *iptr;
        branch_target_t *table;
        lookup_target_t *lookup;
-       s4               i;
+       int              i;
+       bool             has_fallthrough;
 
        /* process all basic blocks to find the predecessor/successor counts */
 
        bptr = jd->basicblocks;
 
        for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
+
+               if (bptr->type == BBTYPE_EXH) {
+                       /* predecessorcount for exception handlers is initialized to -1,
+                          so we need to fix it to 0. */
+                       bptr->predecessorcount += 1;
+               }
+
                if ((bptr->icount == 0) || (bptr->flags == BBUNDEF))
                        continue;
 
@@ -138,60 +161,77 @@ bool cfg_build(jitdata *jd)
                        iptr--;
                }
 
-               switch (iptr->opc) {
-               case ICMD_RETURN:
-               case ICMD_IRETURN:
-               case ICMD_LRETURN:
-               case ICMD_FRETURN:
-               case ICMD_DRETURN:
-               case ICMD_ARETURN:
-               case ICMD_ATHROW:
+               if (iptr->opc == ICMD_GOTO) {
+
+                       /*
+                        This is needed for the following special case caused by
+                        stack_reach_next_block:
+                        I.e. there might be instructions causing control flow before
+                        a GOTO:
+
+                        ....
+                        129: 192:  IFEQ            Ti102 0 (0x00000000) --> L052
+                        131: 193:  NOP
+                          0:   0:  GOTO            --> L060
+                       */
+
+                       bptr->successorcount++;
+
+                       tbptr = iptr->dst.block;
+                       tbptr->predecessorcount++;
+
+                       if (iptr == bptr->iinstr) {
+                               continue;
+                       }
+                       
+                       iptr--;
+
+                       while (iptr->opc == ICMD_NOP) {
+                               if (iptr == bptr->iinstr) {
+                                       break;
+                               }
+                               iptr--;
+                       }
+
+                       has_fallthrough = false;
+               } else {
+                       has_fallthrough = true;
+               }
+
+               switch (icmd_table[iptr->opc].controlflow) {
+
+               case CF_END:
                        break;
 
-               case ICMD_IFEQ:
-               case ICMD_IFNE:
-               case ICMD_IFLT:
-               case ICMD_IFGE:
-               case ICMD_IFGT:
-               case ICMD_IFLE:
-
-               case ICMD_IFNULL:
-               case ICMD_IFNONNULL:
-
-               case ICMD_IF_ICMPEQ:
-               case ICMD_IF_ICMPNE:
-               case ICMD_IF_ICMPLT:
-               case ICMD_IF_ICMPGE:
-               case ICMD_IF_ICMPGT:
-               case ICMD_IF_ICMPLE:
-
-               case ICMD_IF_ACMPEQ:
-               case ICMD_IF_ACMPNE:
+               case CF_IF:
+
                        bptr->successorcount += 2;
 
                        tbptr  = iptr->dst.block;
-                       ntbptr = bptr->next;
-
                        tbptr->predecessorcount++;
-                       ntbptr->predecessorcount++;
+
+                       if (has_fallthrough) {
+                               ntbptr = bptr->next;
+                               ntbptr->predecessorcount++;
+                       }
                        break;
 
-               case ICMD_JSR:
+               case CF_JSR:
                        bptr->successorcount++;
 
                        tbptr = iptr->sx.s23.s3.jsrtarget.block;
                        tbptr->predecessorcount++;
                        break;
 
-               case ICMD_GOTO:
-               case ICMD_RET:
+               case CF_GOTO:
+               case CF_RET:
                        bptr->successorcount++;
 
                        tbptr = iptr->dst.block;
                        tbptr->predecessorcount++;
                        break;
 
-               case ICMD_TABLESWITCH:
+               case CF_TABLE:
                        table = iptr->dst.table;
 
                        bptr->successorcount++;
@@ -211,7 +251,7 @@ bool cfg_build(jitdata *jd)
                        }
                        break;
                                        
-               case ICMD_LOOKUPSWITCH:
+               case CF_LOOKUP:
                        lookup = iptr->dst.lookup;
 
                        bptr->successorcount++;
@@ -231,14 +271,16 @@ bool cfg_build(jitdata *jd)
                        break;
 
                default:
-                       bptr->successorcount++;
+                       if (has_fallthrough) {
+                               bptr->successorcount++;
 
-                       tbptr = bptr->next;
+                               tbptr = bptr->next;
 
-                       /* An exception handler has no predecessors. */
+                               /* An exception handler has no predecessors. */
 
-                       if (tbptr->type != BBTYPE_EXH)
-                               tbptr->predecessorcount++;
+                               if (tbptr->type != BBTYPE_EXH)
+                                       tbptr->predecessorcount++;
+                       }
                        break;
                }
        }
@@ -262,74 +304,83 @@ bool cfg_build(jitdata *jd)
                        iptr--;
                }
 
-               switch (iptr->opc) {
-               case ICMD_RETURN:
-               case ICMD_IRETURN:
-               case ICMD_LRETURN:
-               case ICMD_FRETURN:
-               case ICMD_DRETURN:
-               case ICMD_ARETURN:
-               case ICMD_ATHROW:
+               if (iptr->opc == ICMD_GOTO) {
+                       tbptr = iptr->dst.block;
+
+                       cfg_allocate_successors(bptr);
+
+                       cfg_insert_successors(bptr, tbptr);
+
+                       cfg_allocate_predecessors(tbptr);
+
+                       cfg_insert_predecessors(tbptr, bptr);
+
+                       if (iptr == bptr->iinstr) {
+                               continue;
+                       }
+                       
+                       iptr--;
+
+                       while (iptr->opc == ICMD_NOP) {
+                               if (iptr == bptr->iinstr) {
+                                       break;
+                               }
+                               iptr--;
+                       }
+
+                       has_fallthrough = false;
+
+               } else {
+                       has_fallthrough = true;
+               }
+
+               switch (icmd_table[iptr->opc].controlflow) {
+
+               case CF_END:
                        break;
 
-               case ICMD_IFEQ:
-               case ICMD_IFNE:
-               case ICMD_IFLT:
-               case ICMD_IFGE:
-               case ICMD_IFGT:
-               case ICMD_IFLE:
-
-               case ICMD_IFNULL:
-               case ICMD_IFNONNULL:
-
-               case ICMD_IF_ICMPEQ:
-               case ICMD_IF_ICMPNE:
-               case ICMD_IF_ICMPLT:
-               case ICMD_IF_ICMPGE:
-               case ICMD_IF_ICMPGT:
-               case ICMD_IF_ICMPLE:
-
-               case ICMD_IF_ACMPEQ:
-               case ICMD_IF_ACMPNE:
+               case CF_IF:
+
                        tbptr  = iptr->dst.block;
                        ntbptr = bptr->next;
 
                        cfg_allocate_successors(bptr);
 
-                       bptr->successors[0] = tbptr;
-                       bptr->successors[1] = ntbptr;
-                       bptr->successorcount += 2;
+                       cfg_insert_successors(bptr, tbptr);
+                       if (has_fallthrough) {
+                               cfg_insert_successors(bptr, ntbptr);
+                       }
 
                        cfg_allocate_predecessors(tbptr);
-                       cfg_allocate_predecessors(ntbptr);
-
-                       tbptr->predecessors[tbptr->predecessorcount] = bptr;
-                       tbptr->predecessorcount++;
+                       if (has_fallthrough) {
+                               cfg_allocate_predecessors(ntbptr);
+                       }
 
-                       ntbptr->predecessors[ntbptr->predecessorcount] = bptr;
-                       ntbptr->predecessorcount++;
+                       cfg_insert_predecessors(tbptr, bptr);
+                       if (has_fallthrough) {
+                               cfg_insert_predecessors(ntbptr, bptr);
+                       }
                        break;
 
-               case ICMD_JSR:
+               case CF_JSR:
                        tbptr = iptr->sx.s23.s3.jsrtarget.block;
                        goto goto_tail;
 
-               case ICMD_GOTO:
-               case ICMD_RET:
+               case CF_GOTO:
+               case CF_RET:
+
                        tbptr = iptr->dst.block;
 goto_tail:
                        cfg_allocate_successors(bptr);
 
-                       bptr->successors[0] = tbptr;
-                       bptr->successorcount++;
+                       cfg_insert_successors(bptr, tbptr);
 
                        cfg_allocate_predecessors(tbptr);
 
-                       tbptr->predecessors[tbptr->predecessorcount] = bptr;
-                       tbptr->predecessorcount++;
+                       cfg_insert_predecessors(tbptr, bptr);
                        break;
 
-               case ICMD_TABLESWITCH:
+               case CF_TABLE:
                        table = iptr->dst.table;
 
                        tbptr = table->block;
@@ -337,13 +388,11 @@ goto_tail:
 
                        cfg_allocate_successors(bptr);
 
-                       bptr->successors[0] = tbptr;
-                       bptr->successorcount++;
+                       cfg_insert_successors(bptr, tbptr);
 
                        cfg_allocate_predecessors(tbptr);
 
-                       tbptr->predecessors[tbptr->predecessorcount] = bptr;
-                       tbptr->predecessorcount++;
+                       cfg_insert_predecessors(tbptr, bptr);
 
                        i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
 
@@ -351,28 +400,25 @@ goto_tail:
                                tbptr = table->block;
                                table++;
 
-                               bptr->successors[bptr->successorcount] = tbptr;
-                               bptr->successorcount++;
+                               cfg_insert_successors(bptr, tbptr);
 
                                cfg_allocate_predecessors(tbptr);
                                cfg_insert_predecessors(tbptr, bptr);
                        }
                        break;
                                        
-               case ICMD_LOOKUPSWITCH:
+               case CF_LOOKUP:
                        lookup = iptr->dst.lookup;
 
                        tbptr = iptr->sx.s23.s3.lookupdefault.block;
 
                        cfg_allocate_successors(bptr);
 
-                       bptr->successors[0] = tbptr;
-                       bptr->successorcount++;
+                       cfg_insert_successors(bptr, tbptr);
 
                        cfg_allocate_predecessors(tbptr);
 
-                       tbptr->predecessors[tbptr->predecessorcount] = bptr;
-                       tbptr->predecessorcount++;
+                       cfg_insert_predecessors(tbptr, bptr);
 
                        i = iptr->sx.s23.s2.lookupcount;
 
@@ -380,8 +426,7 @@ goto_tail:
                                tbptr = lookup->target.block;
                                lookup++;
 
-                               bptr->successors[bptr->successorcount] = tbptr;
-                               bptr->successorcount++;
+                               cfg_insert_successors(bptr, tbptr);
 
                                cfg_allocate_predecessors(tbptr);
                                cfg_insert_predecessors(tbptr, bptr);
@@ -389,20 +434,22 @@ goto_tail:
                        break;
 
                default:
-                       tbptr = bptr->next;
+                       if (has_fallthrough) {
+                               tbptr = bptr->next;
 
-                       cfg_allocate_successors(bptr);
+                               cfg_allocate_successors(bptr);
 
-                       bptr->successors[0] = tbptr;
-                       bptr->successorcount++;
+                               bptr->successors[0] = tbptr;
+                               bptr->successorcount++;
 
-                       /* An exception handler has no predecessors. */
+                               /* An exception handler has no predecessors. */
 
-                       if (tbptr->type != BBTYPE_EXH) {
-                               cfg_allocate_predecessors(tbptr);
+                               if (tbptr->type != BBTYPE_EXH) {
+                                       cfg_allocate_predecessors(tbptr);
 
-                               tbptr->predecessors[tbptr->predecessorcount] = bptr;
-                               tbptr->predecessorcount++;
+                                       tbptr->predecessors[tbptr->predecessorcount] = bptr;
+                                       tbptr->predecessorcount++;
+                               }
                        }
                        break;
                }
@@ -413,6 +460,125 @@ goto_tail:
        return true;
 }
 
+/* cfg_add_root ****************************************************************
+
+   Adds an empty root basicblock.
+   The numbers of all other basicblocks are set off by one.
+   Needed for some analyses that require the root basicblock to have no 
+   predecessors and to perform special initializations.
+
+*******************************************************************************/
+
+void cfg_add_root(jitdata *jd) {
+       basicblock *root, *zero, *it;
+
+       zero = jd->basicblocks;
+
+       root = DNEW(basicblock);
+       MZERO(root, basicblock, 1);
+
+       root->successorcount = 1;
+       root->successors = DMNEW(basicblock *, 1);
+       root->successors[0] = zero;
+       root->next = zero;
+       root->nr = 0;
+       root->type = BBTYPE_STD;
+
+       if (zero->predecessorcount == 0) {
+               zero->predecessors = DNEW(basicblock *);
+       } else {
+               zero->predecessors = DMREALLOC(zero->predecessors, basicblock *, zero->predecessorcount, zero->predecessorcount + 1);
+       }
+       zero->predecessors[zero->predecessorcount] = root;
+       zero->predecessorcount += 1;
+
+       jd->basicblocks = root;
+       jd->basicblockcount += 1;
+
+       for (it = zero; it; it = it->next) {
+               it->nr += 1;
+       }
+}
+
+#if defined(ENABLE_SSA)
+
+/* cfg_add_exceptional_edges ***************************************************
+   Edges from basicblocks to their exception handlers and from exception 
+   handlers to the blocks they handle exceptions for are added. Further
+   the number of potentially throwing instructions in the basicblocks are 
+   counted.
+
+   We don't consider nor do we determine the types of exceptions thrown. Edges
+   are added from every block to every potential handler.
+
+*******************************************************************************/
+
+void cfg_add_exceptional_edges(jitdata *jd) {
+       basicblock *bptr;
+       instruction *iptr;
+       exception_entry *ee;
+
+       /* Count the number of exceptional exits for every block.
+        * Every PEI is an exceptional out.
+        */
+
+       FOR_EACH_BASICBLOCK(jd, bptr) {
+
+               if (bptr->flags == BBUNDEF) {
+                       continue;
+               }
+
+               FOR_EACH_INSTRUCTION(bptr, iptr) {
+                       if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI) {      
+                               bptr->exouts += 1;
+                       }
+               }
+       }
+
+       /* Count the number of exception handlers for every block. */
+
+       for (ee = jd->exceptiontable; ee; ee = ee->down) {
+               for (bptr = ee->start; bptr != ee->end; bptr = bptr->next) {
+                       /* Linking a block with a handler, even if there are no exceptional exits
+                          breaks stuff in other passes. */
+                       if (bptr->exouts > 0) {
+                               bptr->exhandlercount += 1;
+                               ee->handler->expredecessorcount += 1;
+                       }
+               }
+       }
+
+       /* Allocate and fill exception handler arrays. */
+
+       for (ee = jd->exceptiontable; ee; ee = ee->down) {
+               for (bptr = ee->start; bptr != ee->end; bptr = bptr->next) {
+                       if (bptr->exouts > 0) {
+
+                               if (bptr->exhandlers == NULL) {
+                                       bptr->exhandlers = DMNEW(basicblock *, bptr->exhandlercount);
+                                       /* Move pointer past the end of the array, 
+                                        * It will be filled in the reverse order.
+                                        */
+                                       bptr->exhandlers += bptr->exhandlercount;
+                               }
+
+                               bptr->exhandlers -= 1;
+                               *(bptr->exhandlers) = ee->handler;
+
+                               if (ee->handler->expredecessors == NULL) {
+                                       ee->handler->expredecessors = DMNEW(basicblock *, ee->handler->expredecessorcount);
+                                       ee->handler->expredecessors += ee->handler->expredecessorcount;
+                               }
+
+                               ee->handler->expredecessors -= 1;
+                               *(ee->handler->expredecessors) = bptr;
+                       }
+               }
+       }
+}
+
+#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.
index a885aa9f8494b8c945c2ecad0ccec538d75ebba9..a82b75ad7036f4b3a9ed619c013743f642712df8 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/cfg.h - build a control-flow graph
+/* src/vm/jit/cfg.h - build a control-flow graph
 
-   Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   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,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
 */
 
 
@@ -35,7 +29,8 @@
 #define _CFG_H
 
 #include "config.h"
-#include "vm/types.h"
+
+#include "vm/global.h"
 
 #include "vm/jit/jit.h"
 
@@ -49,6 +44,8 @@
 
 bool cfg_build(jitdata *jd);
 
+void cfg_add_root(jitdata *jd);
+
 #endif /* _CFG_H */
 
 
index 6c086c100bedb34109484b399210f5668ff43a37..3bdc4678f5e4467ae9d329bd1f6e7e1c50fe9684 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/code.c - codeinfo struct for representing compiled 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.
 
 #include "config.h"
 
 #include <assert.h>
-
-#include "vm/types.h"
+#include <stdint.h>
 
 #include "arch.h"
 
 #include "mm/memory.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "vm/vm.h"
 
 #include "vm/jit/code.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/patcher-common.h"
+#include "vm/jit/methodtree.h"
 
 #include "vmcore/options.h"
 
 
 *******************************************************************************/
 
-bool code_init(void)
+void code_init(void)
 {
-       /* check for offset of code->m == 0 (see comment in code.h) */
-
-       assert(OFFSET(codeinfo, m) == 0);
+       /* Check if offset of codeinfo.m == 0 (see comment in code.h). */
 
-       /* everything's ok */
-
-       return true;
+       if (OFFSET(codeinfo, m) != 0)
+               vm_abort("code_init: offset of codeinfo.m != 0: %d != 0", OFFSET(codeinfo, m));
 }
 
 
@@ -105,7 +98,7 @@ codeinfo *code_codeinfo_new(methodinfo *m)
    Return the codeinfo for the compilation unit that contains the
    given PC.
 
-   IN:
+   ARGUMENTS:
        pc...............machine code position
 
    RETURN VALUE:
@@ -113,12 +106,11 @@ codeinfo *code_codeinfo_new(methodinfo *m)
 
 *******************************************************************************/
 
-codeinfo *code_find_codeinfo_for_pc(u1 *pc)
+codeinfo *code_find_codeinfo_for_pc(void *pc)
 {
-       u1 *pv;
+       void *pv;
 
-       pv = codegen_get_pv_from_pc(pc);
-       assert(pv);
+       pv = methodtree_find(pc);
 
        return code_get_codeinfo_for_pv(pv);
 }
@@ -138,11 +130,11 @@ codeinfo *code_find_codeinfo_for_pc(u1 *pc)
 
 *******************************************************************************/
 
-codeinfo *code_find_codeinfo_for_pc_nocheck(u1 *pc)
+codeinfo *code_find_codeinfo_for_pc_nocheck(void *pc)
 {
-       u1 *pv;
+       void *pv;
 
-       pv = codegen_get_pv_from_pc_nocheck(pc);
+       pv = methodtree_find_nocheck(pc);
 
        if (pv == NULL)
                return NULL;
@@ -163,7 +155,7 @@ codeinfo *code_find_codeinfo_for_pc_nocheck(u1 *pc)
 
 *******************************************************************************/
 
-methodinfo *code_get_methodinfo_for_pv(u1 *pv)
+methodinfo *code_get_methodinfo_for_pv(void *pv)
 {
        codeinfo *code;
 
index 4a8c48bf80835b99374fd3c3a857479b3b205817..adff257fe0262c85398d156effa7bb900144a240 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/code.h - codeinfo struct for representing compiled 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.
 
@@ -88,6 +86,8 @@ struct codeinfo {
        list_t       *patchers;
 
        /* replacement */                                   
+       s4            stackframesize;       /* size of the stackframe in slots    */
+
 #if defined(ENABLE_REPLACEMENT)
        rplpoint     *rplpoints;            /* replacement points                 */
        rplalloc     *regalloc;             /* register allocation info           */
@@ -95,7 +95,6 @@ struct codeinfo {
        s4            globalcount;          /* number of global allocations       */
        s4            regalloccount;        /* number of total allocations        */
        s4            memuse;               /* number of arg + local slots        */
-       s4            stackframesize;       /* size of the stackframe in slots    */
        u1            savedintcount;        /* number of callee saved int regs    */
        u1            savedfltcount;        /* number of callee saved flt regs    */
 # if defined(HAS_ADDRESS_REGISTER_FILE)
@@ -206,15 +205,15 @@ inline static codeinfo *code_get_codeinfo_for_pv(void *pv)
 
 /* function prototypes ********************************************************/
 
-bool code_init(void);
+void code_init(void);
 
 codeinfo *code_codeinfo_new(methodinfo *m);
 void code_codeinfo_free(codeinfo *code);
 
-codeinfo *code_find_codeinfo_for_pc(u1 *pc);
-codeinfo *code_find_codeinfo_for_pc_nocheck(u1 *pc);
+codeinfo *code_find_codeinfo_for_pc(void *pc);
+codeinfo *code_find_codeinfo_for_pc_nocheck(void *pc);
 
-methodinfo *code_get_methodinfo_for_pv(u1 *pv);
+methodinfo *code_get_methodinfo_for_pv(void *pv);
 
 #if defined(ENABLE_REPLACEMENT)
 int code_get_sync_slot_count(codeinfo *code);
index c17ddcb3c02832ed2390401333ce97ceb354303c..4f438809f627ab56ea1f84f9c33240d06e784ac4 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/codegen-common.c - 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.
 
 
 #if defined(WITH_CLASSPATH_SUN)
 # include "native/include/java_lang_Object.h"
-# include "native/include/java_lang_String.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
 
+#if defined(WITH_CLASSPATH_CLDC1_1)
+# include "native/include/java_lang_String.h"
+#endif
+
 #include "native/include/java_lang_Class.h"
 
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
@@ -93,6 +95,7 @@
 #include "vm/jit/jit.h"
 #include "vm/jit/linenumbertable.h"
 #include "vm/jit/methodheader.h"
+#include "vm/jit/methodtree.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 #if defined(ENABLE_SSA)
 
 #include "show.h"
 
-/* in this tree we store all method addresses *********************************/
-
-static avl_tree_t *methodtree = NULL;
-static s4 methodtree_comparator(const void *treenode, const void *node);
-
 
 /* codegen_init ****************************************************************
 
@@ -131,28 +129,6 @@ static s4 methodtree_comparator(const void *treenode, const void *node);
 
 void codegen_init(void)
 {
-       /* this tree is global, not method specific */
-
-       if (!methodtree) {
-#if defined(ENABLE_JIT)
-               methodtree_element *mte;
-#endif
-
-               methodtree = avl_create(&methodtree_comparator);
-
-#if defined(ENABLE_JIT)
-               /* insert asm_vm_call_method */
-
-               mte = NEW(methodtree_element);
-
-               mte->startpc = (u1 *) (ptrint) asm_vm_call_method;
-               mte->endpc   = (u1 *) (ptrint) asm_vm_call_method_end;
-
-               avl_insert(methodtree, mte);
-#endif /* defined(ENABLE_JIT) */
-
-       }
-
 }
 
 
@@ -495,13 +471,13 @@ void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
 
 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
 {
-       list_t             *list;
+       list_t             *l;
        branch_label_ref_t *br;
        s4                  mpc;
 
-       /* get the label list */
+       /* Get the label list. */
 
-       list = cd->brancheslabel;
+       l = cd->brancheslabel;
        
        /* calculate the current mpc */
 
@@ -515,9 +491,9 @@ void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u
        br->reg       = reg;
        br->options   = options;
 
-       /* add the branch to the list */
+       /* Add the branch to the list. */
 
-       list_add_last_unsynced(list, br);
+       list_add_last(l, br);
 }
 
 
@@ -531,13 +507,13 @@ void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u
 #if defined(ENABLE_THREADS)
 void codegen_critical_section_new(codegendata *cd)
 {
-       list_t                 *list;
+       list_t                 *l;
        critical_section_ref_t *csr;
        s4                      mpc;
 
-       /* get the critical section list */
+       /* Get the critical section list. */
 
-       list = cd->listcritical;
+       l = cd->listcritical;
        
        /* calculate the current mpc */
 
@@ -552,9 +528,9 @@ void codegen_critical_section_new(codegendata *cd)
        csr->end     = -1;
        csr->restart = mpc;
 
-       /* add the branch to the list */
+       /* Add the branch to the list. */
 
-       list_add_last_unsynced(list, csr);
+       list_add_last(l, csr);
 }
 #endif
 
@@ -569,21 +545,21 @@ void codegen_critical_section_new(codegendata *cd)
 #if defined(ENABLE_THREADS)
 void codegen_critical_section_start(codegendata *cd)
 {
-       list_t                 *list;
+       list_t                 *l;
        critical_section_ref_t *csr;
        s4                      mpc;
 
-       /* get the critical section list */
+       /* Get the critical section list. */
 
-       list = cd->listcritical;
+       l = cd->listcritical;
        
        /* calculate the current mpc */
 
        mpc = cd->mcodeptr - cd->mcodebase;
 
-       /* get the current critical section */
+       /* Get the current critical section. */
 
-       csr = list_last_unsynced(list);
+       csr = list_last(l);
 
        /* set the start point */
 
@@ -604,21 +580,21 @@ void codegen_critical_section_start(codegendata *cd)
 #if defined(ENABLE_THREADS)
 void codegen_critical_section_end(codegendata *cd)
 {
-       list_t                 *list;
+       list_t                 *l;
        critical_section_ref_t *csr;
        s4                      mpc;
 
-       /* get the critical section list */
+       /* Get the critical section list. */
 
-       list = cd->listcritical;
+       l = cd->listcritical;
        
        /* calculate the current mpc */
 
        mpc = cd->mcodeptr - cd->mcodebase;
 
-       /* get the current critical section */
+       /* Get the current critical section. */
 
-       csr = list_last_unsynced(list);
+       csr = list_last(l);
 
        /* set the end point */
 
@@ -641,7 +617,7 @@ static void codegen_critical_section_finish(jitdata *jd)
 {
        codeinfo    *code;
        codegendata *cd;
-       list_t                  *list;
+       list_t                  *l;
        critical_section_ref_t  *csr;
        critical_section_node_t *csn;
 
@@ -650,14 +626,13 @@ static void codegen_critical_section_finish(jitdata *jd)
        code = jd->code;
        cd   = jd->cd;
 
-       /* get the critical section list */
+       /* Get the critical section list. */
 
-       list = cd->listcritical;
+       l = cd->listcritical;
 
        /* iterate over all critical sections */
 
-       for (csr = list_first_unsynced(list); csr != NULL;
-                csr = list_next_unsynced(list, csr)) {
+       for (csr = list_first(l); csr != NULL; csr = list_next(l, csr)) {
                /* check if all points are set */
 
                assert(csr->start   != -1);
@@ -680,154 +655,6 @@ static void codegen_critical_section_finish(jitdata *jd)
 #endif
 
 
-/* methodtree_comparator *******************************************************
-
-   Comparator function used for the AVL tree of methods.
-
-   ARGUMENTS:
-      treenode....the node from the tree
-      node........the node to compare to the tree-node
-
-*******************************************************************************/
-
-static s4 methodtree_comparator(const void *treenode, const void *node)
-{
-       methodtree_element *mte;
-       methodtree_element *mtepc;
-
-       mte   = (methodtree_element *) treenode;
-       mtepc = (methodtree_element *) node;
-
-       /* compare both startpc and endpc of pc, even if they have the same value,
-          otherwise the avl_probe sometimes thinks the element is already in the
-          tree */
-
-#ifdef __S390__
-       /* On S390 addresses are 31 bit. Compare only 31 bits of value.
-        */
-#      define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
-#else
-#      define ADDR_MASK(a) (a)
-#endif
-
-       if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
-               ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
-               ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
-               ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
-               return 0;
-
-       } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
-               return -1;
-
-       } else {
-               return 1;
-       }
-
-#      undef ADDR_MASK
-}
-
-
-/* codegen_insertmethod ********************************************************
-
-   Insert the machine code range of a method into the AVL tree of methods.
-
-*******************************************************************************/
-
-void codegen_insertmethod(u1 *startpc, u1 *endpc)
-{
-       methodtree_element *mte;
-
-       /* allocate new method entry */
-
-       mte = NEW(methodtree_element);
-
-       mte->startpc = startpc;
-       mte->endpc   = endpc;
-
-       /* this function does not return an error, but asserts for
-          duplicate entries */
-
-       avl_insert(methodtree, mte);
-}
-
-
-/* codegen_get_pv_from_pc ******************************************************
-
-   Find the PV for the given PC by searching in the AVL tree of
-   methods.
-
-*******************************************************************************/
-
-u1 *codegen_get_pv_from_pc(u1 *pc)
-{
-       methodtree_element  mtepc;
-       methodtree_element *mte;
-
-       /* allocation of the search structure on the stack is much faster */
-
-       mtepc.startpc = pc;
-       mtepc.endpc   = pc;
-
-       mte = avl_find(methodtree, &mtepc);
-
-       if (mte == NULL) {
-               /* No method was found.  Let's dump a stacktrace. */
-
-#if defined(ENABLE_VMLOG)
-               vmlog_cacao_signl("SIGSEGV");
-#endif
-
-               log_println("We received a SIGSEGV and tried to handle it, but we were");
-               log_println("unable to find a Java method at:");
-               log_println("");
-#if SIZEOF_VOID_P == 8
-               log_println("PC=0x%016lx", pc);
-#else
-               log_println("PC=0x%08x", pc);
-#endif
-               log_println("");
-               assert(0);
-               log_println("Dumping the current stacktrace:");
-
-#if defined(ENABLE_THREADS)
-               /* XXX michi: This should be available even without threads! */
-               threads_print_stacktrace();
-#endif
-
-               vm_abort("Exiting...");
-       }
-
-       return mte->startpc;
-}
-
-
-/* codegen_get_pv_from_pc_nocheck **********************************************
-
-   Find the PV for the given PC by searching in the AVL tree of
-   methods.  This method does not check the return value and is used
-   by the profiler.
-
-*******************************************************************************/
-
-u1 *codegen_get_pv_from_pc_nocheck(u1 *pc)
-{
-       methodtree_element  mtepc;
-       methodtree_element *mte;
-
-       /* allocation of the search structure on the stack is much faster */
-
-       mtepc.startpc = pc;
-       mtepc.endpc   = pc;
-
-       mte = avl_find(methodtree, &mtepc);
-
-       if (mte == NULL)
-               return NULL;
-       else
-               return mte->startpc;
-}
-
-
 /* codegen_set_replacement_point_notrap ****************************************
 
    Record the position of a non-trappable replacement point.
@@ -904,7 +731,6 @@ void codegen_finish(jitdata *jd)
 #endif
        s4           alignedmcodelen;
        jumpref     *jr;
-       patchref_t  *pr;
        u1          *epoint;
        s4           alignedlen;
 
@@ -1010,12 +836,7 @@ void codegen_finish(jitdata *jd)
 
        /* patcher resolving */
 
-       pr = list_first_unsynced(code->patchers);
-       while (pr) {
-               pr->mpc += (ptrint) epoint;
-               pr->datap = (ptrint) (pr->disp + epoint);
-               pr = list_next_unsynced(code->patchers, pr);
-       }
+       patcher_resolve(jd);
 
 #if defined(ENABLE_REPLACEMENT)
        /* replacement point resolving */
@@ -1030,9 +851,9 @@ void codegen_finish(jitdata *jd)
        }
 #endif /* defined(ENABLE_REPLACEMENT) */
 
-       /* add method into methodtree to find the entrypoint */
+       /* Insert method into methodtree to find the entrypoint. */
 
-       codegen_insertmethod(code->entrypoint, code->entrypoint + mcodelen);
+       methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
 
 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
        /* resolve data segment references */
@@ -1067,11 +888,11 @@ u1 *codegen_generate_stub_compiler(methodinfo *m)
        codegendata *cd;
        ptrint      *d;                     /* pointer to data memory             */
        u1          *c;                     /* pointer to code memory             */
-       s4           dumpsize;
+       int32_t      dumpmarker;
 
        /* mark dump memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* allocate required data structures */
 
@@ -1154,7 +975,7 @@ u1 *codegen_generate_stub_compiler(methodinfo *m)
 
        /* release dump memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        /* return native stub code */
 
@@ -1173,11 +994,11 @@ void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
        jitdata  *jd;
        codeinfo *code;
        int       skipparams;
-       s4        dumpsize;
+       int32_t   dumpmarker;
 
        /* mark dump memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* Create JIT data structure. */
 
@@ -1187,6 +1008,10 @@ void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
 
        code = jd->code;
 
+       /* Stubs are non-leaf methods. */
+
+       code_unflag_leafmethod(code);
+
        /* setup code generation stuff */
 
        codegen_setup(jd);
@@ -1238,7 +1063,7 @@ void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 }
 
 
@@ -1255,14 +1080,14 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
 {
        jitdata     *jd;
        codeinfo    *code;
-       s4           dumpsize;
        methoddesc  *md;
        methoddesc  *nmd;       
        int          skipparams;
+       int32_t      dumpmarker;
 
        /* mark dump memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* Create JIT data structure. */
 
@@ -1272,6 +1097,10 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
 
        code = jd->code;
 
+       /* Stubs are non-leaf methods. */
+
+       code_unflag_leafmethod(code);
+
        /* set the flags for the current JIT run */
 
 #if defined(ENABLE_PROFILING)
@@ -1375,7 +1204,7 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        /* return native stub code */
 
@@ -1393,8 +1222,8 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
 void codegen_disassemble_stub(methodinfo *m, u1 *start, u1 *end)
 {
        printf("Stub code: ");
-       if (m->class != NULL)
-               utf_fprint_printable_ascii_classname(stdout, m->class->name);
+       if (m->clazz != NULL)
+               utf_fprint_printable_ascii_classname(stdout, m->clazz->name);
        else
                printf("NULL");
        printf(".");
@@ -1512,7 +1341,7 @@ java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
 #endif
 
 #if !defined(NDEBUG)
-# if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__X86_64__) || defined(__S390__)
+# if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
        /* print the call-trace if necesarry */
        /* BEFORE: filling the local reference table */
 
@@ -1537,7 +1366,7 @@ java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
        /* Return a wrapped classinfo for static methods. */
 
        if (m->flags & ACC_STATIC)
-               return LLNI_classinfo_wrap(m->class);
+               return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
        else
                return NULL;
 }
@@ -1590,7 +1419,10 @@ java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
 #elif defined(__I386__)
        datasp   = sp + framesize;
        ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
-#elif defined(__M68K__) || defined(__X86_64__)
+#elif defined(__M68K__)
+       datasp   = sp + framesize;
+       ret_regs = (uint64_t *) (sp + 2 * 8);
+#elif defined(__X86_64__)
        datasp   = sp + framesize;
        ret_regs = (uint64_t *) sp;
 #elif defined(__POWERPC__)
@@ -1634,7 +1466,7 @@ java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
 #endif
 
 #if !defined(NDEBUG)
-# if defined(__ALPHA__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__X86_64__) || defined(__S390__)
+# if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
        /* print the call-trace if necesarry */
        /* AFTER: unwrapping the return value */
 
@@ -1688,16 +1520,6 @@ void removenativestub(u1 *stub)
 
 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
 {
-
-#if 0
-       /* Do we have to generate a conditional move?  Yes, then always
-          return the temporary register.  The real register is identified
-          during the store. */
-
-       if (opcode & ICMD_CONDITION_MASK)
-               return tempregnum;
-#endif
-
        if (!(v->flags & INMEMORY))
                return v->vv.regoff;
 
@@ -1770,7 +1592,7 @@ void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
                        if (compileverbose)
                                printf("...returning - phi lifetimes where joined\n");
 #endif
-                       return;
+                       continue;
                }
 
                if (s->type == -1) {
@@ -1778,7 +1600,7 @@ void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
                        if (compileverbose)
                                printf("...returning - phi lifetimes where joined\n");
 #endif
-                       return;
+                       continue;
                }
 
                tmp_i.opc = 0;
index 33598a77b7bcbbd1563db32bc67f074adc38c921..cf1ad7d771a3f807472fb32185c86a5223dc175d 100644 (file)
@@ -225,16 +225,6 @@ struct linenumberref {
 };
 
 
-/* methodtree_element *********************************************************/
-
-typedef struct methodtree_element methodtree_element;
-
-struct methodtree_element {
-       u1 *startpc;
-       u1 *endpc;
-};
-
-
 /* function prototypes ********************************************************/
 
 void codegen_init(void);
@@ -260,10 +250,6 @@ void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr);
 
 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options);
 
-void codegen_insertmethod(u1 *startpc, u1 *endpc);
-u1 *codegen_get_pv_from_pc(u1 *pc);
-u1 *codegen_get_pv_from_pc_nocheck(u1 *pc);
-
 #if defined(ENABLE_REPLACEMENT)
 #if !defined(NDEBUG)
 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type);
index aa2f38997165a63b4ce578f3b4a9e64b36c51db3..3a167808265e151f477303cf419a2c7c6c4be292 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/emit-common.c - common code emitter functions
 
-   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.
 
@@ -269,7 +267,7 @@ void emit_patcher_traps(jitdata *jd)
 
        /* generate patcher traps code */
 
-       for (pr = list_first_unsynced(code->patchers); pr != NULL; pr = list_next_unsynced(code->patchers, pr)) {
+       for (pr = list_first(code->patchers); pr != NULL; pr = list_next(code->patchers, pr)) {
 
                /* Calculate the patch position where the original machine
                   code is located and the trap should be placed. */
@@ -522,48 +520,47 @@ void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options
 
        /* search if the label is already in the list */
 
-       for (br = list_first_unsynced(list); br != NULL;
-                br = list_next_unsynced(list, br)) {
+       for (br = list_first(list); br != NULL; br = list_next(list, br)) {
                /* is this entry the correct label? */
 
                if (br->label == label)
                        break;
        }
 
-       /* a branch reference was found */
+       if (br == NULL) {
+               /* current mcodeptr is the correct position,
+                  afterwards emit the NOPs */
 
-       if (br != NULL) {
-               /* calculate the mpc of the branch instruction */
+               codegen_branch_label_add(cd, label, condition, reg, options);
+
+               /* generate NOPs as placeholder for branch code */
+
+               BRANCH_NOPS;
+               return;
+       }
+
+       /* Branch reference was found. */
+
+       /* calculate the mpc of the branch instruction */
 
-               mpc  = cd->mcodeptr - cd->mcodebase;
-               disp = br->mpc - mpc;
+       mpc  = cd->mcodeptr - cd->mcodebase;
+       disp = br->mpc - mpc;
 
 #if defined(ENABLE_STATISTICS)
-               count_emit_branch++;
-               if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
-               else if ((int16_t)disp == disp) count_emit_branch_16bit++;
-               else if ((int32_t)disp == disp) count_emit_branch_32bit++;
+       count_emit_branch++;
+       if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
+       else if ((int16_t)disp == disp) count_emit_branch_16bit++;
+       else if ((int32_t)disp == disp) count_emit_branch_32bit++;
 # if SIZEOF_VOID_P == 8
-               else if ((int64_t)disp == disp) count_emit_branch_64bit++;
+       else if ((int64_t)disp == disp) count_emit_branch_64bit++;
 # endif
 #endif
 
-               emit_branch(cd, disp, condition, reg, options);
+       emit_branch(cd, disp, condition, reg, options);
 
-               /* now remove the branch reference */
-
-               list_remove_unsynced(list, br);
-       }
-       else {
-               /* current mcodeptr is the correct position,
-                  afterwards emit the NOPs */
+       /* now remove the branch reference */
 
-               codegen_branch_label_add(cd, label, condition, reg, options);
-
-               /* generate NOPs as placeholder for branch code */
-
-               BRANCH_NOPS;
-       }
+       list_remove(list, br);
 }
 
 
@@ -588,53 +585,52 @@ void emit_label(codegendata *cd, s4 label)
 
        /* search if the label is already in the list */
 
-       for (br = list_first_unsynced(list); br != NULL;
-                br = list_next_unsynced(list, br)) {
+       for (br = list_first(list); br != NULL; br = list_next(list, br)) {
                /* is this entry the correct label? */
 
                if (br->label == label)
                        break;
        }
 
-       /* a branch reference was found */
+       if (br == NULL) {
+               /* No branch reference found, add the label to the list (use
+                  invalid values for condition and register). */
 
-       if (br != NULL) {
-               /* calculate the mpc of the branch instruction */
+               codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
+               return;
+       }
+
+       /* Branch reference was found. */
+
+       /* calculate the mpc of the branch instruction */
 
-               mpc  = cd->mcodeptr - cd->mcodebase;
-               disp = mpc - br->mpc;
+       mpc  = cd->mcodeptr - cd->mcodebase;
+       disp = mpc - br->mpc;
 
-               /* temporary set the mcodeptr */
+       /* temporary set the mcodeptr */
 
-               mcodeptr     = cd->mcodeptr;
-               cd->mcodeptr = cd->mcodebase + br->mpc;
+       mcodeptr     = cd->mcodeptr;
+       cd->mcodeptr = cd->mcodebase + br->mpc;
 
 #if defined(ENABLE_STATISTICS)
-               count_emit_branch++;
-               if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
-               else if ((int16_t)disp == disp) count_emit_branch_16bit++;
-               else if ((int32_t)disp == disp) count_emit_branch_32bit++;
+       count_emit_branch++;
+       if ((int8_t)disp == disp)  count_emit_branch_8bit++; 
+       else if ((int16_t)disp == disp) count_emit_branch_16bit++;
+       else if ((int32_t)disp == disp) count_emit_branch_32bit++;
 # if SIZEOF_VOID_P == 8
-               else if ((int64_t)disp == disp) count_emit_branch_64bit++;
+       else if ((int64_t)disp == disp) count_emit_branch_64bit++;
 # endif
 #endif
 
-               emit_branch(cd, disp, br->condition, br->reg, br->options);
+       emit_branch(cd, disp, br->condition, br->reg, br->options);
 
-               /* restore mcodeptr */
+       /* restore mcodeptr */
 
-               cd->mcodeptr = mcodeptr;
+       cd->mcodeptr = mcodeptr;
 
-               /* now remove the branch reference */
+       /* now remove the branch reference */
 
-               list_remove_unsynced(list, br);
-       }
-       else {
-               /* add the label to the list (use invalid values for condition
-                  and register) */
-
-               codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
-       }
+       list_remove(list, br);
 }
 
 
index aeb5b1529f0dee94881d833b8462ab68dc447af6..102f455149a7ace0650b50342fb1bb954cb68b73 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/jit/exceptiontable.c - method exception table
 
    Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
index b0c5de94a8276257bb877b0ee0f2eb66cd7c54d8..903b250f26125de9c673263c0243cab151b384d9 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/jit/exceptiontable.h - method exception table
 
    Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
diff --git a/src/vm/jit/executionstate.c b/src/vm/jit/executionstate.c
new file mode 100644 (file)
index 0000000..34153a6
--- /dev/null
@@ -0,0 +1,258 @@
+/* src/vm/jit/executionstate.c - execution-state handling
+
+   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 <stdio.h>
+
+#include "md-abi.h"
+
+#include "vm/jit/abi.h"
+#include "vm/jit/executionstate.h"
+
+#include "vmcore/descriptor.h"
+#include "vmcore/system.h"
+
+
+/* executionstate_sanity_check *************************************************
+
+   Perform some sanity checks for the md_executionstate_read and
+   md_executionstate_write functions.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void executionstate_sanity_check(void *context)
+{
+    /* estimate a minimum for the context size */
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+#define MINIMUM_CONTEXT_SIZE  (SIZEOF_VOID_P    * ADR_REG_CNT \
+                                      + sizeof(double) * FLT_REG_CNT \
+                                                          + sizeof(int)    * INT_REG_CNT)
+#else
+#define MINIMUM_CONTEXT_SIZE  (SIZEOF_VOID_P    * INT_REG_CNT \
+                                      + sizeof(double) * FLT_REG_CNT)
+#endif
+
+       executionstate_t es1;
+       executionstate_t es2;
+       executionstate_t es3;
+       unsigned int i;
+       unsigned char reference[MINIMUM_CONTEXT_SIZE];
+
+       /* keep a copy of (a prefix of) the context for reference */
+
+       system_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));
+
+       md_executionstate_read(&es1, context);
+
+       /* verify that item-by-item copying preserves the state */
+
+       es2.pc = es1.pc;
+       es2.sp = es1.sp;
+       es2.pv = es1.pv;
+       es2.ra = es1.ra;
+       es2.code = es1.code;
+       for (i = 0; i < INT_REG_CNT; ++i)
+               es2.intregs[i] = es1.intregs[i];
+       for (i = 0; i < FLT_REG_CNT; ++i)
+               es2.fltregs[i] = es1.fltregs[i];
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i = 0; i < ADR_REG_CNT; ++i)
+               es2.adrregs[i] = es1.adrregs[i];
+#endif
+
+       /* write it back - this should not change the context */
+       /* We cannot check that completely, unfortunately, as we don't know */
+       /* the size of the (OS-dependent) context. */
+
+       md_executionstate_write(&es2, context);
+
+       /* Read it again, Sam! */
+
+       md_executionstate_read(&es3, context);
+
+       /* Compare. Note: Because of the NAN madness, we cannot compare
+        * doubles using '=='. */
+
+       assert(es3.pc == es1.pc);
+       assert(es3.sp == es1.sp);
+       assert(es3.pv == es1.pv);
+       for (i = 0; i < INT_REG_CNT; ++i)
+               assert(es3.intregs[i] == es1.intregs[i]);
+       for (i = 0; i < FLT_REG_CNT; ++i)
+               assert(memcmp(es3.fltregs+i, es1.fltregs+i, sizeof(double)) == 0);
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i = 0; i < ADR_REG_CNT; ++i)
+               assert(es3.adrregs[i] == es1.adrregs[i]);
+#endif
+
+       /* i386 and x86_64 do not have an RA register */
+
+#if defined(__I386__) || defined(__X86_64__)
+       assert(es3.ra != es1.ra);
+#else
+       assert(es3.ra == es1.ra);
+#endif
+
+       /* "code" is not set by the md_* functions */
+
+       assert(es3.code != es1.code);
+
+       /* assert that we have not messed up the context */
+
+       assert(memcmp(&reference, context, MINIMUM_CONTEXT_SIZE) == 0);
+}
+#endif
+
+
+/* executionstate_println ******************************************************
+   Print execution state
+  
+   IN:
+       es...............the execution state to print
+  
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void executionstate_println(executionstate_t *es)
+{
+       uint64_t *sp;
+       int       slots;
+       int       extraslots;
+       int       i;
+
+       if (!es) {
+               printf("(executionstate_t *)NULL\n");
+               return;
+       }
+
+       printf("executionstate_t:\n");
+       printf("\tpc = %p", es->pc);
+       printf("  sp = %p", es->sp);
+       printf("  pv = %p", es->pv);
+       printf("  ra = %p\n", es->ra);
+
+#if defined(ENABLE_DISASSEMBLER)
+       for (i=0; i<INT_REG_CNT; ++i) {
+               if (i%4 == 0)
+                       printf("\t");
+               else
+                       printf(" ");
+# if SIZEOF_VOID_P == 8
+               printf("%-3s = %016lx", abi_registers_integer_name[i], es->intregs[i]);
+# else
+               printf("%-3s = %08x", abi_registers_integer_name[i], (unsigned) es->intregs[i]);
+# endif
+               if (i%4 == 3)
+                       printf("\n");
+       }
+
+       for (i=0; i<FLT_REG_CNT; ++i) {
+               if (i%4 == 0)
+                       printf("\t");
+               else
+                       printf(" ");
+               printf("F%02d = %016llx",i,(unsigned long long)es->fltregs[i]);
+               if (i%4 == 3)
+                       printf("\n");
+       }
+
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (i%4 == 0)
+                       printf("\t");
+               else
+                       printf(" ");
+               printf("A%02d = %016llx",i,(unsigned long long)es->adrregs[i]);
+               if (i%4 == 3)
+                       printf("\n");
+       }
+# endif
+#endif
+
+       sp = (uint64_t *) es->sp;
+
+       extraslots = 2;
+
+       if (es->code) {
+               methoddesc *md = es->code->m->parseddesc;
+               slots = es->code->stackframesize;
+               extraslots = 1 + md->memuse;
+       }
+       else
+               slots = 0;
+
+
+       if (slots) {
+               printf("\tstack slots(+%d) at sp:", extraslots);
+               for (i=0; i<slots+extraslots; ++i) {
+                       if (i%4 == 0)
+                               printf("\n\t\t");
+                       printf("M%02d%c", i, (i >= slots) ? '(' : ' ');
+#ifdef HAS_4BYTE_STACKSLOT
+                       printf("%08lx",(unsigned long)*sp++);
+#else
+                       printf("%016llx",(unsigned long long)*sp++);
+#endif
+                       printf("%c", (i >= slots) ? ')' : ' ');
+               }
+               printf("\n");
+       }
+
+       printf("\tcode: %p", (void*)es->code);
+       if (es->code != NULL) {
+               printf(" stackframesize=%d ", es->code->stackframesize);
+               method_print(es->code->m);
+       }
+       printf("\n");
+
+       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/jit/executionstate.h b/src/vm/jit/executionstate.h
new file mode 100644 (file)
index 0000000..46211e7
--- /dev/null
@@ -0,0 +1,96 @@
+/* src/vm/jit/executionstate.h - execution-state handling
+
+   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 _EXECUTIONSTATE_H
+#define _EXECUTIONSTATE_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct executionstate_t executionstate_t;
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "arch.h"
+#include "md-abi.h"
+
+#include "vm/jit/code.h"
+
+
+/* executionstate_t ************************************************************
+
+   An execution-state represents the state of a thread containing all
+   registers that are important.  This structure is an internal
+   structure similar to mcontext_t.
+
+*******************************************************************************/
+
+struct executionstate_t {
+       uint8_t   *pc;                                         /* program counter */
+       uint8_t   *sp;                             /* stack pointer within method */
+       uint8_t   *pv;                             /* procedure value. NULL means */
+                                                  /* search the AVL tree         */
+       uint8_t   *ra;                          /* return address / link register */
+
+       uintptr_t  intregs[INT_REG_CNT];                       /* register values */
+       double     fltregs[FLT_REG_CNT];                       /* register values */
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       uintptr_t  adrregs[ADR_REG_CNT];                       /* register values */
+#endif
+
+       codeinfo  *code;                      /* codeinfo corresponding to the pv */
+};
+
+
+/* prototypes *****************************************************************/
+
+#if !defined(NDEBUG)
+void executionstate_sanity_check(void *context);
+void executionstate_println(executionstate_t *es);
+#endif
+
+/* Machine and OS dependent functions (code in ARCH_DIR/OS_DIR/md-os.c) */
+
+void md_executionstate_read(executionstate_t *es, void *ucontext);
+void md_executionstate_write(executionstate_t *es, void *ucontext);
+
+#endif /* _EXECUTIONSTATE_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 22561291dac22cf1d5a299b0792aa353144eafb8..0adf031286e8a9cf89c1a263b7b312ae905e2968 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/i386/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.
 ##
@@ -55,11 +53,13 @@ libarch_la_SOURCES = \
        $(DISASS_SOURCES) \
        emit.c \
        emit.h \
-       md.c \
        patcher.c \
        \
        md-abi.c \
-       md-abi.h
+       md-abi.h \
+       md-trap.h \
+       md.c \
+       md.h
 
 libarch_la_LIBADD = \
        $(OS_DIR)/libmd.la
index a2c27e00754fd506a4e0e3f319243380bc538e96..6904b0a89fa21ec96bb50975eacecad602962e5f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/asmpart.S - Java-C interface functions for i386
 
-   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.
 
@@ -122,7 +120,7 @@ asm_vm_call_method_long:
 asm_vm_call_method_float:
 asm_vm_call_method_double:
        push    bp
-       mov     sp,bp                       /* save stackptr                      */
+       mov     sp,bp                       /* save stack pointer                 */
        sub     $(4*4),sp                   /* create stackframe                  */
        and     $0xfffffff0,sp              /* align stack to 16-byte             */
 
@@ -217,7 +215,7 @@ L_asm_handle_exception_stack_loop:
        mov     t0,8*4(sp)                  /* save maybe-leaf flag               */
 
        mov     xpc,0*4(sp)                 /* pass exception pc                  */
-       call    codegen_get_pv_from_pc
+       call    methodtree_find
        mov     v0,6*4(sp)                  /* save data segment pointer          */
 
        mov     4*4(sp),itmp3               /* pass exception pointer             */
@@ -275,11 +273,11 @@ L_asm_handle_exception_no_leaf_stack:
        cmp     $2,itmp1
        je      int2
 
-       mov     -3*8(itmp2),s0
+       mov     -4-3*8(itmp2),s0
 int2:  
-       mov     -2*8(itmp2),s1
+       mov     -4-2*8(itmp2),s1
 int1:  
-       mov     -1*8(itmp2),s2
+       mov     -4-1*8(itmp2),s2
 
        shl     $2,itmp1                    /* multiply by 4 bytes                */
        sub     itmp1,itmp2
index 29c0572a5dac60c653dea786b289cb9838956937..d909a9b1d2c9655ef93f2f9beeb2c4c2396bd305 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/codegen.c - machine code generator for i386
 
-   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.
 
@@ -63,6 +61,7 @@
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 #if defined(ENABLE_SSA)
 # include "vm/jit/optimizing/lsra.h"
@@ -89,6 +88,7 @@ bool codegen_emit(jitdata *jd)
        codegendata        *cd;
        registerdata       *rd;
        s4                  len, s1, s2, s3, d, disp;
+       int                 align_off;      /* offset for alignment compensation  */
        varinfo            *var, *var1;
        basicblock         *bptr;
        instruction        *iptr;
@@ -149,11 +149,14 @@ bool codegen_emit(jitdata *jd)
     /* Keep stack of non-leaf functions 16-byte aligned. */
 
        if (!code_is_leafmethod(code)) {
-               ALIGN_ODD(cd->stackframesize);    /* XXX this is wrong, +4 is missing */
+               ALIGN_ODD(cd->stackframesize);
        }
 
+       align_off = cd->stackframesize ? 4 : 0;
+
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
+       (void) dseg_add_unique_s4(
+               cd, cd->stackframesize * 8 + align_off);           /* FrameSize       */
 
        code->synchronizedoffset = rd->memuse * 8;
 
@@ -181,7 +184,8 @@ bool codegen_emit(jitdata *jd)
        /* create stack frame (if necessary) */
 
        if (cd->stackframesize)
-               M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
+               /* align_off == 4 */
+               M_ASUB_IMM(cd->stackframesize * 8 + 4, REG_SP);
 
        /* save return address and used callee saved registers */
 
@@ -234,7 +238,8 @@ bool codegen_emit(jitdata *jd)
                        } 
                        else {
                                if (!(var->flags & INMEMORY)) {
-                                       M_ILD(d, REG_SP, cd->stackframesize * 8 + 4 + s1);
+                                       M_ILD(d, REG_SP,
+                                                 cd->stackframesize * 8 + 4 + align_off + s1);
                                } 
                                else {
                                        if (!IS_2_WORD_TYPE(t)) {
@@ -242,15 +247,17 @@ bool codegen_emit(jitdata *jd)
                                                /* no copy avoiding by now possible with SSA */
                                                if (ls != NULL) {
                                                        emit_mov_membase_reg(   /* + 4 for return address */
-                                                                cd, REG_SP, cd->stackframesize * 8 + s1 + 4,
-                                                                REG_ITMP1);    
+                                                               cd, REG_SP,
+                                                               cd->stackframesize * 8 + s1 + 4 + align_off,
+                                                               REG_ITMP1);    
                                                        emit_mov_reg_membase(
-                                                                cd, REG_ITMP1, REG_SP, var->vv.regoff);
+                                                               cd, REG_ITMP1, REG_SP, var->vv.regoff);
                                                }
                                                else 
 #endif /*defined(ENABLE_SSA)*/
                                                        /* reuse stackslot */
-                                                       var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
+                                                       var->vv.regoff = cd->stackframesize * 8 + 4 +
+                                                               align_off + s1;
 
                                        } 
                                        else {
@@ -258,20 +265,22 @@ bool codegen_emit(jitdata *jd)
                                                /* no copy avoiding by now possible with SSA */
                                                if (ls != NULL) {
                                                        emit_mov_membase_reg(  /* + 4 for return address */
-                                                                cd, REG_SP, cd->stackframesize * 8 + s1 + 4,
-                                                                REG_ITMP1);
+                                                               cd, REG_SP,
+                                                               cd->stackframesize * 8 + s1 + 4 + align_off,
+                                                               REG_ITMP1);
                                                        emit_mov_reg_membase(
-                                                                cd, REG_ITMP1, REG_SP, var->vv.regoff);
+                                                               cd, REG_ITMP1, REG_SP, var->vv.regoff);
                                                        emit_mov_membase_reg(   /* + 4 for return address */
-                                                                 cd, REG_SP, cd->stackframesize * 8 + s1 + 4 + 4,
-                                                                 REG_ITMP1);             
+                                                               cd, REG_SP,
+                                                               cd->stackframesize * 8 + s1 + 4 + 4 + align_off,
+                                                               REG_ITMP1);             
                                                        emit_mov_reg_membase(
-                                                                cd, REG_ITMP1, REG_SP, var->vv.regoff + 4);
+                                                               cd, REG_ITMP1, REG_SP, var->vv.regoff + 4);
                                                }
                                                else
 #endif /*defined(ENABLE_SSA)*/
                                                        /* reuse stackslot */
-                                                       var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
+                                                       var->vv.regoff = cd->stackframesize * 8 + 8 + s1;
                                        }
                                }
                        }
@@ -291,14 +300,16 @@ bool codegen_emit(jitdata *jd)
                                if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
                                        if (t == TYPE_FLT) {
                                                emit_flds_membase(
-                            cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
+                            cd, REG_SP,
+                                                       cd->stackframesize * 8 + s1 + 4 + align_off);
                                                assert(0);
 /*                                             emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
 
                                        } 
                                        else {
                                                emit_fldl_membase(
-                            cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
+                            cd, REG_SP,
+                                                       cd->stackframesize * 8 + s1 + 4 + align_off);
                                                assert(0);
 /*                                             emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
                                        }
@@ -308,24 +319,29 @@ bool codegen_emit(jitdata *jd)
                                        /* no copy avoiding by now possible with SSA */
                                        if (ls != NULL) {
                                                emit_mov_membase_reg(
-                                                cd, REG_SP, cd->stackframesize * 8 + s1 + 4, REG_ITMP1);
+                                                       cd, REG_SP,
+                                                       cd->stackframesize * 8 + s1 + 4 + align_off,
+                                                       REG_ITMP1);
                                                emit_mov_reg_membase(
-                                                                        cd, REG_ITMP1, REG_SP, var->vv.regoff);
+                                                       cd, REG_ITMP1, REG_SP, var->vv.regoff);
                                                if (t == TYPE_FLT) {
                                                        emit_flds_membase(
-                                                                 cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
+                                                               cd, REG_SP,
+                                                               cd->stackframesize * 8 + s1 + 4 + align_off);
                                                        emit_fstps_membase(cd, REG_SP, var->vv.regoff);
                                                } 
                                                else {
                                                        emit_fldl_membase(
-                                                                 cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
+                                                               cd, REG_SP,
+                                                               cd->stackframesize * 8 + s1 + 4 + align_off);
                                                        emit_fstpl_membase(cd, REG_SP, var->vv.regoff);
                                                }
                                        }
                                        else
 #endif /*defined(ENABLE_SSA)*/
                                                /* reuse stackslot */
-                                               var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
+                                               var->vv.regoff = cd->stackframesize * 8 + 4 +
+                                                       align_off + s1;
                                }
                        }
                }
@@ -338,13 +354,13 @@ bool codegen_emit(jitdata *jd)
                s1 = rd->memuse;
 
                if (m->flags & ACC_STATIC) {
-                       M_MOV_IMM(&m->class->object.header, REG_ITMP1);
+                       M_MOV_IMM(&m->clazz->object.header, REG_ITMP1);
                }
                else {
-                       M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + 4);
+                       M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + 4 + align_off);
                        M_TEST(REG_ITMP1);
                        M_BNE(6);
-                       M_ALD_MEM(REG_ITMP1, EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ALD_MEM(REG_ITMP1, TRAP_NullPointerException);
                }
 
                M_AST(REG_ITMP1, REG_SP, s1 * 8);
@@ -2178,8 +2194,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = (intptr_t) fi->value;
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
                        }
 
                        M_MOV_IMM(disp, REG_ITMP1);
@@ -2219,8 +2235,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = (intptr_t) fi->value;
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
                        }
 
                        M_MOV_IMM(disp, REG_ITMP1);
@@ -2261,8 +2277,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = (intptr_t) fi->value;
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
                        }
 
                        M_MOV_IMM(disp, REG_ITMP1);
@@ -2789,7 +2805,7 @@ nowperformreturn:
                        /* deallocate stack */
 
                        if (cd->stackframesize)
-                               M_AADD_IMM(cd->stackframesize * 8, REG_SP);
+                               M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP);
 
                        M_RET;
                        }
@@ -3007,9 +3023,9 @@ gen_method:
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr) * lm->class->index;
+                                               sizeof(methodptr) * lm->clazz->index;
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
 
                                        d = md->returntype.type;
                                }
@@ -3487,12 +3503,12 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
     /* keep stack 16-byte aligned */
 
-       ALIGN_ODD(cd->stackframesize);        /* XXX this is wrong, +4 is missing */
+       ALIGN_ODD(cd->stackframesize);
 
        /* create method header */
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
+       (void) dseg_add_unique_s4(cd, cd->stackframesize * 8 + 4); /* FrameSize       */
        (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
        (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
        (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
@@ -3510,7 +3526,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
        /* calculate stackframe size for native function */
 
-       M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
+       M_ASUB_IMM(cd->stackframesize * 8 + 4, REG_SP);
 
        /* Mark the whole fpu stack as free for native functions (only for saved  */
        /* register count == 0).                                                  */
@@ -3556,7 +3572,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
                if (!md->params[i].inmemory)
                        assert(0);
 
-               s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
+               s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;
                s2 = nmd->params[j].regoff;
 
                /* float/double in memory can be copied like int/longs */
@@ -3659,7 +3675,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
                M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
 #endif
 
-       M_AADD_IMM(cd->stackframesize * 8, REG_SP);
+       M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP);
 
        /* check for exception */
 
index 1e226a302626b06cbe016f49467da74ca8b8fe76..a20449d7b6c3d4be50cf5947fa50b7bcd6da989d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/cygwin/md-asm.h - assembler defines for Cygwin i386 ABI
 
-   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:
-
 */
 
 
 #define asm_builtin_d2i                       _asm_builtin_d2i
 #define asm_builtin_d2l                       _asm_builtin_d2l
 
-#define asm_criticalsections                  _asm_criticalsections
-#define asm_getclassvalues_atomic             _asm_getclassvalues_atomic
-
 
 /* external defines ***********************************************************/
 
 #define exceptions_get_and_clear_exception    _exceptions_get_and_clear_exception
 
 #define builtin_throw_exception               _builtin_throw_exception
-#define codegen_get_pv_from_pc                _codegen_get_pv_from_pc
+#define methodtree_find                       _methodtree_find
 #define exceptions_handle_exception           _exceptions_handle_exception
 #define jit_asm_compile                       _jit_asm_compile
 
index 1228b0607eafec6b39b3a19c246b2e7fb0b255cb..d610cc3ce1dc3a24803ccab9cf12b4332aa7eb40 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/darwin/md-asm.h - assembler defines for i386 Darwin ABI
 
-   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 asm_builtin_d2i                       _asm_builtin_d2i
 #define asm_builtin_d2l                       _asm_builtin_d2l
 
-#define asm_criticalsections                  _asm_criticalsections
-#define asm_getclassvalues_atomic             _asm_getclassvalues_atomic
-
 
 /* external defines ***********************************************************/
 
 #define exceptions_get_and_clear_exception    _exceptions_get_and_clear_exception
 
 #define builtin_throw_exception               _builtin_throw_exception
-#define codegen_get_pv_from_pc                _codegen_get_pv_from_pc
+#define methodtree_find                       _methodtree_find
 #define exceptions_handle_exception           _exceptions_handle_exception
 #define jit_asm_compile                       _jit_asm_compile
 
index 29bf42abe2542ed1d32c3bf6c907b4d6fd01087c..9ad6dc6814db1f18daa8a4abcf0cb66643a35500 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/darwin/md-os.c - machine dependent i386 Darwin 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/types.h"
 
 #include "vm/jit/i386/codegen.h"
+#include "vm/jit/i386/md.h"
 
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
-#include "vm/exceptions.h"
+#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/trap.h"
 
 #include "vm/jit/i386/codegen.h"
 
@@ -71,6 +73,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        intptr_t             val;
     int                  type;
     void                *p;
+       java_object_t       *o;
 
        _uc = (ucontext_t *) _p;
        _mc = _uc->uc_mcontext;
@@ -106,22 +109,58 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
             ((d == 4) ? _ss->esp :
             ((d == 5) ? _ss->ebp :
             ((d == 6) ? _ss->esi : _ss->edi))))));
+
+               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 = EXCEPTION_HARDWARE_NULLPOINTER;
+        type = TRAP_NullPointerException;
     }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
-    /* set registers */
+       /* Set registers. */
 
-    _ss->eax = (intptr_t) p;
-       _ss->ecx = (intptr_t) xpc;
-       _ss->eip = (intptr_t) asm_handle_exception;
+       if (type == TRAP_COMPILER) {
+               if (p == NULL) { 
+                       o = builtin_retrieve_exception();
+
+                       _ss->esp = (uintptr_t) sp;    /* Remove RA from stack. */
+
+                       _ss->eax = (uintptr_t) o;
+                       _ss->ecx = (uintptr_t) xpc;            /* REG_ITMP2_XPC */
+                       _ss->eip = (uintptr_t) asm_handle_exception;
+               }
+               else {
+                       _ss->eip = (uintptr_t) p;
+               }
+       }
+       else {
+               _ss->eax = (uintptr_t) p;
+               _ss->ecx = (uintptr_t) xpc;            /* REG_ITMP2_XPC */
+               _ss->eip = (uintptr_t) asm_handle_exception;
+       }
 }
 
 
@@ -155,18 +194,20 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
        xpc = (u1 *) _ss->eip;
        ra  = xpc;                          /* return address is equal to xpc     */
 
-    /* this is an ArithmeticException */
+    /* This is an ArithmeticException */
 
-    type = EXCEPTION_HARDWARE_ARITHMETIC;
+    type = TRAP_ArithmeticException;
     val  = 0;
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
-    _ss->eax = (intptr_t) p;
-       _ss->ecx = (intptr_t) xpc;
-       _ss->eip = (intptr_t) asm_handle_exception;
+       /* Set registers. */
+
+    _ss->eax = (uintptr_t) p;
+       _ss->ecx = (uintptr_t) xpc;            /* REG_ITMP2_XPC */
+       _ss->eip = (uintptr_t) asm_handle_exception;
 }
 
 
@@ -196,6 +237,122 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
+/* 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;
+       i386_thread_state_t *_ss;
+       u1                  *sp;
+       u1                  *ra;
+       u1                  *xpc;
+       int                  type;
+       intptr_t             val;
+       void                *p;
+
+
+       _uc = (ucontext_t *) _p;
+       _mc = _uc->uc_mcontext;
+       _ss = &_mc->ss;
+
+       pv  = NULL;                 /* is resolved during stackframeinfo creation */
+       sp  = (u1 *) _ss->esp;
+       xpc = (u1 *) _ss->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) {
+               _ss->eax = (uintptr_t) p;
+               _ss->ecx = (uintptr_t) xpc;            /* REG_ITMP2_XPC */
+               _ss->eip = (uintptr_t) asm_handle_exception;
+       }
+}
+
+/* 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; 
+       i386_thread_state_t *_ss;
+       int                  i;
+
+       _uc = (ucontext_t *) context;
+       _mc = _uc->uc_mcontext;
+       _ss = &_mc->ss;
+
+       /* read special registers */
+       es->pc = (u1 *) _ss->eip;
+       es->sp = (u1 *) _ss->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] = (i == 0) ? _ss->eax :
+                       ((i == 1) ? _ss->ecx :
+                       ((i == 2) ? _ss->edx :
+                       ((i == 3) ? _ss->ebx :
+                       ((i == 4) ? _ss->esp :
+                       ((i == 5) ? _ss->ebp :
+                       ((i == 6) ? _ss->esi : _ss->edi))))));
+
+       /* 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.
+
+*******************************************************************************/
+
+void md_executionstate_write(executionstate_t *es, void *context)
+{
+       ucontext_t*          _uc;
+       mcontext_t           _mc;
+       i386_thread_state_t* _ss;
+       int                  i;
+
+       _uc = (ucontext_t *) context;
+       _mc = _uc->uc_mcontext;
+       _ss = &_mc->ss;
+
+       /* write integer registers */
+       for (i = 0; i < INT_REG_CNT; i++)
+               *((i == 0) ? &_ss->eax :
+                 ((i == 1) ? &_ss->ecx :
+                 ((i == 2) ? &_ss->edx :
+                 ((i == 3) ? &_ss->ebx :
+                 ((i == 4) ? &_ss->esp :
+                 ((i == 5) ? &_ss->ebp :
+                 ((i == 6) ? &_ss->esi : &_ss->edi))))))) = es->intregs[i];
+
+       /* write special registers */
+       _ss->eip = (ptrint) es->pc;
+       _ss->esp = (ptrint) es->sp;
+}
+
+
 /* md_critical_section_restart *************************************************
 
    Search the critical sections tree for a matching section and set
index e35f99c292c549a9fd9a4d5def1fed9f21e85d85..1a0be3daee41e4beae3caf5a0241a95fe81a10dc 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/emit.c - i386 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.
 
@@ -49,6 +47,7 @@
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/trace.h"
+#include "vm/jit/trap.h"
 
 #include "vmcore/options.h"
 #include "vmcore/statistics.h"
@@ -410,7 +409,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(reg);
                M_BNE(6);
-               M_ALD_MEM(reg, EXCEPTION_HARDWARE_ARITHMETIC);
+               M_ALD_MEM(reg, TRAP_ArithmeticException);
        }
 }
 
@@ -427,7 +426,7 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1,
         M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
         M_CMP(REG_ITMP3, s2);
         M_BB(6);
-               M_ALD_MEM(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+               M_ALD_MEM(s2, TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -443,7 +442,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(REG_RESULT);
                M_BNE(6);
-               M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_ALD_MEM(REG_RESULT, TRAP_ArrayStoreException);
        }
 }
 
@@ -470,7 +469,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
                default:
                        vm_abort("emit_classcast_check: unknown condition %d", condition);
                }
-               M_ALD_MEM(s1, EXCEPTION_HARDWARE_CLASSCAST);
+               M_ALD_MEM(s1, TRAP_ClassCastException);
        }
 }
 
@@ -486,7 +485,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(reg);
                M_BNE(6);
-               M_ALD_MEM(reg, EXCEPTION_HARDWARE_NULLPOINTER);
+               M_ALD_MEM(reg, TRAP_NullPointerException);
        }
 }
 
@@ -502,7 +501,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(REG_RESULT);
                M_BNE(6);
-               M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_EXCEPTION);
+               M_ALD_MEM(REG_RESULT, TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -515,7 +514,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 
 void emit_trap_compiler(codegendata *cd)
 {
-       M_ALD_MEM(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+       M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
 }
 
 
@@ -562,6 +561,7 @@ void emit_verbosecall_enter(jitdata *jd)
        methoddesc   *md;
        int32_t       stackframesize;
        int           i;
+       int           align_off;             /* offset for alignment compensation */
 
        if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
                return;
@@ -595,10 +595,11 @@ void emit_verbosecall_enter(jitdata *jd)
 
        /* no argument registers to save */
 
+       align_off = cd->stackframesize ? 4 : 0;
        M_AST_IMM(m, REG_SP, 0 * 4);
        M_AST_IMM(0, REG_SP, 1 * 4);
        M_AST(REG_SP, REG_SP, 2 * 4);
-       M_IADD_IMM_MEMBASE(stackframesize * 8 + cd->stackframesize * 8 + 4, REG_SP, 2 * 4);
+       M_IADD_IMM_MEMBASE(stackframesize * 8 + cd->stackframesize * 8 + 4 + align_off, REG_SP, 2 * 4);
        M_MOV_IMM(trace_java_call_enter, REG_ITMP1);
        M_CALL(REG_ITMP1);
 
index 13a585970c2e7d59d89f8f72e4bd40688e56adb6..17630b05143dd0f437031b94877eb7efdf9e2c9b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/linux/md-os.c - machine dependent i386 Linux 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/i386/codegen.h"
 #include "vm/jit/i386/md.h"
 
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.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/trap.h"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -105,7 +104,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                val = _mc->gregs[REG_EAX - d];
 
-               if (type == EXCEPTION_HARDWARE_COMPILER) {
+               if (type == TRAP_COMPILER) {
                        /* The PV from the compiler stub is equal to the XPC. */
 
                        pv = xpc;
@@ -128,17 +127,17 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        else {
                /* this was a normal NPE */
 
-               type = EXCEPTION_HARDWARE_NULLPOINTER;
+               type = TRAP_NullPointerException;
                val  = 0;
        }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* Set registers. */
 
-       if (type == EXCEPTION_HARDWARE_COMPILER) {
+       if (type == TRAP_COMPILER) {
                if (p == NULL) {
                        o = builtin_retrieve_exception();
 
@@ -153,9 +152,9 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                }
        }
        else {
-               _mc->gregs[REG_EAX] = (intptr_t) p;
-               _mc->gregs[REG_ECX] = (intptr_t) xpc;                /* REG_ITMP2_XPC */
-               _mc->gregs[REG_EIP] = (intptr_t) asm_handle_exception;
+               _mc->gregs[REG_EAX] = (uintptr_t) p;
+               _mc->gregs[REG_ECX] = (uintptr_t) xpc;               /* REG_ITMP2_XPC */
+               _mc->gregs[REG_EIP] = (uintptr_t) asm_handle_exception;
        }
 }
 
@@ -187,20 +186,20 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
        xpc = (u1 *) _mc->gregs[REG_EIP];
        ra  = xpc;                          /* return address is equal to xpc     */
 
-       /* this is an ArithmeticException */
+       /* This is an ArithmeticException. */
 
-       type = EXCEPTION_HARDWARE_ARITHMETIC;
+       type = TRAP_ArithmeticException;
        val  = 0;
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
-       /* set registers */
+       /* Set registers. */
 
-       _mc->gregs[REG_EAX] = (intptr_t) p;
-       _mc->gregs[REG_ECX] = (intptr_t) xpc;                    /* REG_ITMP2_XPC */
-       _mc->gregs[REG_EIP] = (intptr_t) asm_handle_exception;
+       _mc->gregs[REG_EAX] = (uintptr_t) p;
+       _mc->gregs[REG_ECX] = (uintptr_t) xpc;                   /* REG_ITMP2_XPC */
+       _mc->gregs[REG_EIP] = (uintptr_t) asm_handle_exception;
 }
 
 
@@ -230,21 +229,19 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
        xpc = (u1 *) _mc->gregs[REG_EIP];
        ra  = xpc;                            /* return address is equal to xpc   */
 
-       /* this is an ArithmeticException */
-
-       type = EXCEPTION_HARDWARE_PATCHER;
+       type = TRAP_PATCHER;
        val  = 0;
 
-       /* generate appropriate exception */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
-       /* set registers (only if exception object ready) */
+       /* Set registers. */
 
        if (p != NULL) {
-               _mc->gregs[REG_EAX] = (ptrint) p;
-               _mc->gregs[REG_ECX] = (ptrint) xpc;                      /* REG_ITMP2_XPC */
-               _mc->gregs[REG_EIP] = (ptrint) asm_handle_exception;
+               _mc->gregs[REG_EAX] = (uintptr_t) p;
+               _mc->gregs[REG_ECX] = (uintptr_t) xpc;               /* REG_ITMP2_XPC */
+               _mc->gregs[REG_EIP] = (uintptr_t) asm_handle_exception;
        }
 }
 
@@ -302,14 +299,13 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-/* md_replace_executionstate_read **********************************************
+/* md_executionstate_read ******************************************************
 
    Read the given context into an executionstate for Replacement.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_read(executionstate_t *es, void *context)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
@@ -331,17 +327,15 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
        for (i = 0; i < FLT_REG_CNT; i++)
                es->fltregs[i] = 0xdeadbeefdeadbeefULL;
 }
-#endif
 
 
-/* md_replace_executionstate_write *********************************************
+/* md_executionstate_write *****************************************************
 
    Write the given executionstate back to the context for Replacement.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_write(executionstate_t *es, void *context)
+void md_executionstate_write(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
@@ -358,7 +352,6 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
        _mc->gregs[REG_EIP] = (ptrint) es->pc;
        _mc->gregs[REG_ESP] = (ptrint) es->sp;
 }
-#endif
 
 
 /* md_critical_section_restart *************************************************
index fb4aad984379c4b23b794c1aed68b836c4305578..1499e961fffae64cf15b5e6646eaee7f8c6e586f 100644 (file)
@@ -1,25 +1,6 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline void
-__attribute__ ((unused))
-atomic_add (volatile int *mem, int val)
-{
-  __asm__ __volatile__ ("lock; addl %1,%0"
-                                               : "=m" (*mem) 
-                                               : "ir" (val), "m" (*mem));
-}
-
-/* compare_and_swap ********************************************************
-
-  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
-
-***************************************************************************/
-
 static inline long
 __attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
@@ -33,8 +14,7 @@ compare_and_swap (volatile long *p, long oldval, long newval)
 }
 
 #define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER_AFTER_ATOMIC() /* nothing */
 #define MEMORY_BARRIER() __asm__ __volatile__ ( \
                "lock; add $0, 0(%%esp)" : : : "memory" );
 
index 71f99b0b8d573151547282d80e33a9c01a18730c..f4d9f4c66cc2dafe337d057741f35c0ccff7ce12 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/md-abi.c - functions for i386 Linux ABI
 
-   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.
 
@@ -159,7 +157,7 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
 {
        /* nothing */
 }
diff --git a/src/vm/jit/i386/md-trap.h b/src/vm/jit/i386/md-trap.h
new file mode 100644 (file)
index 0000000..0c39650
--- /dev/null
@@ -0,0 +1,79 @@
+/* src/vm/jit/x86_64/md-trap.h - i386 hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (i386) the trap numbers are used as load
+ * displacements and thus must not be 4- or 8-byte aligned.
+ *
+ * NOTE: In trap_init() we have a check whether the offset of
+ * java_arrayheader.data[0] is greater than the largest displacement
+ * defined below.  Otherwise normal array loads/stores could trigger
+ * an exception.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    1
+
+enum {
+       TRAP_NullPointerException           = 0,
+       TRAP_ArithmeticException            = 1,
+       TRAP_ArrayIndexOutOfBoundsException = 2,
+       TRAP_ArrayStoreException            = 3,
+
+       /* Don't use 4 (could be a normal load offset). */
+
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+
+       /* Don't use 8 (could be a normal load offset). */
+
+       TRAP_COMPILER                       = 9,
+       TRAP_END
+};
+
+#endif /* _MD_TRAP_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 f5289c8179f4bf6f20554fe64c49b58e0067c5c7..568f8e934d0115ac9bb15754eedc4e32cbb2346e 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/md.h - 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.
 
@@ -34,6 +32,7 @@
 #include <stdint.h>
 
 #include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
 
 
 /* inline functions ***********************************************************/
@@ -60,7 +59,7 @@ inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframe
 /* md_codegen_get_pv_from_pc ***************************************************
 
    On this architecture just a wrapper function to
-   codegen_get_pv_from_pc.
+   methodtree_find.
 
 *******************************************************************************/
 
@@ -71,7 +70,7 @@ inline static void *md_codegen_get_pv_from_pc(void *ra)
        /* Get the start address of the function which contains this
        address from the method table. */
 
-       pv = codegen_get_pv_from_pc(ra);
+       pv = methodtree_find(ra);
 
        return pv;
 }
index c1d6b5b9d0c232e438ac4dab72ba530a5be3d8ba..661c245e4ad0851dac5d088a938b982937d924aa 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/i386/patcher.c - i386 code patching 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.
 
@@ -93,8 +91,8 @@ bool patcher_get_putstatic(patchref_t *pr)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        PATCH_BACK_ORIGINAL_MCODE;
@@ -516,12 +514,12 @@ bool patcher_invokeinterface(patchref_t *pr)
        /* patch interfacetable index */
 
        *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
-                                                                  sizeof(methodptr) * m->class->index);
+                                                                  sizeof(methodptr) * m->clazz->index);
 
        /* patch method offset */
 
        *((s4 *) (ra + 2 + 6 + 2)) =
-               (s4) (sizeof(methodptr) * (m - m->class->methods));
+               (s4) (sizeof(methodptr) * (m - m->clazz->methods));
 
        return true;
 }
index 23e23184f19e39d5cb2baa74e7fb9d747e09f36b..210d9459903b1882db1b688cbb2ddf7b7a845ddb 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/inline/inline.c - method inlining
 
-   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 "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
 
 #if !defined(NDEBUG)
 #define INLINE_VERBOSE
-#define DOLOG(code) do{ if (opt_inline_debug_log) { code; } }while(0)
+#define DOLOG(code)       do{ if (opt_TraceInlining >= 2) { code; } }while(0)
+#define DOLOG_SHORT(code) do{ if (opt_TraceInlining >= 1) { code; } }while(0)
 #else
 #define DOLOG(code)
 #endif
@@ -310,7 +309,7 @@ static bool inline_jit_compile_intern(jitdata *jd)
 
        /* call parse pass */
 
-       DOLOG( log_message_class("Parsing ", m->class) );
+       DOLOG( log_message_class("Parsing ", m->clazz) );
        if (!parse(jd)) {
                return false;
        }
@@ -676,6 +675,7 @@ static void inline_add_block_reference(inline_node *iln, basicblock **blockp)
 }
 
 
+#if 0
 static void inline_add_blocknr_reference(inline_node *iln, s4 *nrp)
 {
        inline_target_ref *ref;
@@ -686,6 +686,7 @@ static void inline_add_blocknr_reference(inline_node *iln, s4 *nrp)
        ref->next = iln->refs;
        iln->refs = ref;
 }
+#endif
 
 
 static void inline_block_translation(inline_node *iln, basicblock *o_bptr, basicblock *n_bptr)
@@ -1076,7 +1077,7 @@ static void inline_generate_sync_builtin(inline_node *iln,
                syncvar = inline_new_temp_variable(iln->ctx->resultjd, TYPE_ADR);
 
                n_ins = inline_instruction(iln, ICMD_ACONST, o_iptr);
-               n_ins->sx.val.c.cls = callee->m->class;
+               n_ins->sx.val.c.cls = callee->m->clazz;
                n_ins->dst.varindex = syncvar;
                n_ins->flags.bits |= INS_FLAG_CLASS;
        }
@@ -1955,7 +1956,7 @@ static void inline_write_exception_handlers(inline_node *master, inline_node *il
                n_ins = master->inlined_iinstr_cursor++;
                if (iln->m->flags & ACC_STATIC) {
                        n_ins->opc = ICMD_ACONST;
-                       n_ins->sx.val.c.cls = iln->m->class;
+                       n_ins->sx.val.c.cls = iln->m->clazz;
                        n_ins->flags.bits = INS_FLAG_CLASS;
                }
                else {
@@ -2160,10 +2161,10 @@ static bool inline_transform(inline_node *iln, jitdata *jd)
 #endif
 
 #if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-       if (   (n_jd->instructioncount >= opt_inline_debug_min_size)
-               && (n_jd->instructioncount <= opt_inline_debug_max_size))
+       if (   (n_jd->instructioncount >= opt_InlineMinSize)
+               && (n_jd->instructioncount <= opt_InlineMaxSize))
        {
-          if (debug_counter <= opt_inline_debug_end_counter)
+          if (debug_counter < opt_InlineCount)
 #endif /* defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG) */
           {
                        /* install the inlined result */
@@ -2177,7 +2178,7 @@ static bool inline_transform(inline_node *iln, jitdata *jd)
 #if !defined(NDEBUG)
                        inline_stat_roots++;
 
-                       DOLOG(
+                       DOLOG_SHORT(
                        printf("==== %d.INLINE ==================================================================\n",
                                debug_counter);
                        printf("\ninline tree:\n");
index 2e3b28b77be73453b36db77b0795e488b5189d97..78ffb694ab159f914a7df1ed6aa97fec430ed03c 100644 (file)
@@ -1,3 +1,4 @@
+#if 0
 static void debug_dump_inline_context(inline_node *iln)
 {
        assert(iln->indent);
@@ -5,6 +6,7 @@ static void debug_dump_inline_context(inline_node *iln)
        printf("%sinline_context @%p: \n",
                        iln->indent, (void*)iln->ctx);
 }
+#endif
 
 
 static void dump_inline_tree(inline_node *iln, s4 blocknr)
index 5dd875335698581d6c53cba987e1085a87d81749..d0d7fd91010252675902156d3c960d07dc93f46d 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/intrp/Makefile.am
 ##
-## 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.
 ##
 ## 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
-##
-## Changes: Edwin Steiner
 
-## Process this file with automake to produce Makefile.in
 
 AM_CFLAGS = $(INTRP_CFLAGS)
 AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR) -I$(top_builddir) -I$(top_builddir)/src
@@ -76,7 +67,7 @@ libintrp_la_SOURCES = \
        peephole.c
 
 $(BUILT_SOURCES): $(srcdir)/java.vmg $(srcdir)/prims2x.fs $(srcdir)/vmgenx
-       $(srcdir)/vmgenx $(srcdir)/java.vmg && touch java-peephole.i
+       $(SHELL) $(srcdir)/vmgenx $(srcdir)/java.vmg && touch java-peephole.i
        true #GFORTHPATH=.:/nfs/nfstmp/anton/cacao/:/usr/lib/gforth/site-forth:/usr/share/gforth/site-forth:/usr/lib/gforth/0.6.2:/usr/share/gforth/0.6.2 $(srcdir)/vmgenx $(srcdir)/java.vmg && touch java-peephole.i
 
 
index 1d886a5352158e742c1b0f7d4fad50422b68410c..6bba262c8a44dad463058bf077ab57534ee1ce34 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/intrp/asmpart.c - Java-C interface functions 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.
 
 
 #include "arch.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#else
-# include "threads/none/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodheader.h"
-#include "vm/jit/intrp/intrp.h"
+#include "vm/jit/methodtree.h"
 #include "vm/jit/dseg.h"
 
+#include "vm/jit/intrp/intrp.h"
+
 #include "vmcore/class.h"
 #include "vmcore/linker.h"
 #include "vmcore/loader.h"
@@ -191,7 +187,7 @@ Inst *intrp_asm_handle_exception(Inst *ip, java_objectheader *o, Cell *fp, Cell
   /* for a description of the stack see IRETURN in java.vmg */
 
   for (; fp != NULL; ) {
-         u1 *f = codegen_get_pv_from_pc((u1 *) (ip - 1));
+         u1 *f = methodtree_find((u1 *) (ip - 1));
 
          /* get methodinfo pointer from method header */
 
@@ -286,7 +282,7 @@ Inst *intrp_asm_handle_exception(Inst *ip, java_objectheader *o, Cell *fp, Cell
                  /* get synchronization object */
 
                  if (m->flags & ACC_STATIC) {
-                         syncobj = (java_objectheader *) m->class;
+                         syncobj = (java_objectheader *) m->clazz;
                  }
                  else {
                          syncobj = (java_objectheader *) access_local_cell(-framesize + SIZEOF_VOID_P);
@@ -318,24 +314,6 @@ void intrp_asm_abstractmethoderror(void)
 }
 
 
-void intrp_asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out)
-{
-       s4 sbv, sdv, sv;
-
-       LOCK_MONITOR_ENTER(linker_classrenumber_lock);
-
-       sbv = super->baseval;
-       sdv = super->diffval;
-       sv  = sub->baseval;
-
-       LOCK_MONITOR_EXIT(linker_classrenumber_lock);
-
-       out->super_baseval = sbv;
-       out->super_diffval = sdv;
-       out->sub_baseval   = sv;
-}
-
-
 /*
  * These 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 ea45d60c61d6a69b5bf6ca7fe56a56804032388f..6fe3cc7270a935a532f0651a0c7e09e188b727e7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/intrp/codegen.c - code generator 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.
 
@@ -352,7 +350,7 @@ bool intrp_codegen(jitdata *jd)
 #if defined(ENABLE_THREADS)
        if (checksync && code_is_synchronized(code)) {
                if (m->flags & ACC_STATIC) {
-                       gen_ACONST(cd, (java_objectheader *) m->class);
+                       gen_ACONST(cd, (java_objectheader *) m->clazz);
                }
                else {
                        gen_ALOAD(cd, 0);
@@ -1106,7 +1104,7 @@ dont_opt_IF_LCMPxx:
                        case TYPE_INT:
                                if (fi == NULL)
                                        gen_PATCHER_GETSTATIC_INT(cd, 0, uf);
-                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        gen_PATCHER_GETSTATIC_CLINIT_INT(cd, 0, fi);
                                else
                                        gen_GETSTATIC_INT(cd, (u1 *) &(fi->value.i), fi);
@@ -1114,7 +1112,7 @@ dont_opt_IF_LCMPxx:
                        case TYPE_FLT:
                                if (fi == NULL)
                                        gen_PATCHER_GETSTATIC_FLOAT(cd, 0, uf);
-                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        gen_PATCHER_GETSTATIC_CLINIT_FLOAT(cd, 0, fi);
                                else
                                        gen_GETSTATIC_FLOAT(cd, (u1 *) &(fi->value.i), fi);
@@ -1123,7 +1121,7 @@ dont_opt_IF_LCMPxx:
                        case TYPE_DBL:
                                if (fi == NULL)
                                        gen_PATCHER_GETSTATIC_LONG(cd, 0, uf);
-                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        gen_PATCHER_GETSTATIC_CLINIT_LONG(cd, 0, fi);
                                else
                                        gen_GETSTATIC_LONG(cd, (u1 *) &(fi->value.l), fi);
@@ -1131,7 +1129,7 @@ dont_opt_IF_LCMPxx:
                        case TYPE_ADR:
                                if (fi == NULL)
                                        gen_PATCHER_GETSTATIC_CELL(cd, 0, uf);
-                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        gen_PATCHER_GETSTATIC_CLINIT_CELL(cd, 0, fi);
                                else
                                        gen_GETSTATIC_CELL(cd, (u1 *) &(fi->value.a), fi);
@@ -1157,7 +1155,7 @@ dont_opt_IF_LCMPxx:
                        case TYPE_INT:
                                if (fi == NULL)
                                        gen_PATCHER_PUTSTATIC_INT(cd, 0, uf);
-                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        gen_PATCHER_PUTSTATIC_CLINIT_INT(cd, 0, fi);
                                else
                                        gen_PUTSTATIC_INT(cd, (u1 *) &(fi->value.i), fi);
@@ -1165,7 +1163,7 @@ dont_opt_IF_LCMPxx:
                        case TYPE_FLT:
                                if (fi == NULL)
                                        gen_PATCHER_PUTSTATIC_FLOAT(cd, 0, uf);
-                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        gen_PATCHER_PUTSTATIC_CLINIT_FLOAT(cd, 0, fi);
                                else
                                        gen_PUTSTATIC_FLOAT(cd, (u1 *) &(fi->value.i), fi);
@@ -1174,7 +1172,7 @@ dont_opt_IF_LCMPxx:
                        case TYPE_DBL:
                                if (fi == NULL)
                                        gen_PATCHER_PUTSTATIC_LONG(cd, 0, uf);
-                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        gen_PATCHER_PUTSTATIC_CLINIT_LONG(cd, 0, fi);
                                else
                                        gen_PUTSTATIC_LONG(cd, (u1 *) &(fi->value.l), fi);
@@ -1182,7 +1180,7 @@ dont_opt_IF_LCMPxx:
                        case TYPE_ADR:
                                if (fi == NULL)
                                        gen_PATCHER_PUTSTATIC_CELL(cd, 0, uf);
-                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               else if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        gen_PATCHER_PUTSTATIC_CLINIT_CELL(cd, 0, fi);
                                else
                                        gen_PUTSTATIC_CELL(cd, (u1 *) &(fi->value.a), fi);
@@ -1517,7 +1515,7 @@ dont_opt_IF_LCMPxx:
 #if defined(ENABLE_THREADS)
                        if (checksync && code_is_synchronized(code)) {
                                if (m->flags & ACC_STATIC) {
-                                       gen_ACONST(cd, (java_objectheader *) m->class);
+                                       gen_ACONST(cd, (java_objectheader *) m->clazz);
                                } else {
                                        gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
@@ -1536,7 +1534,7 @@ dont_opt_IF_LCMPxx:
 #if defined(ENABLE_THREADS)
                        if (checksync && code_is_synchronized(code)) {
                                if (m->flags & ACC_STATIC) {
-                                       gen_ACONST(cd, (java_objectheader *) m->class);
+                                       gen_ACONST(cd, (java_objectheader *) m->clazz);
                                } else {
                                        gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
@@ -1554,7 +1552,7 @@ dont_opt_IF_LCMPxx:
 #if defined(ENABLE_THREADS)
                        if (checksync && code_is_synchronized(code)) {
                                if (m->flags & ACC_STATIC) {
-                                       gen_ACONST(cd, (java_objectheader *) m->class);
+                                       gen_ACONST(cd, (java_objectheader *) m->clazz);
                                } else {
                                        gen_ALOAD(cd, index2offset(m->maxlocals));
                                }
@@ -1719,9 +1717,9 @@ dont_opt_IF_LCMPxx:
                                md = lm->parseddesc;
 
                                s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                       sizeof(methodptr*) * lm->class->index;
+                                       sizeof(methodptr*) * lm->clazz->index;
 
-                               s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                               s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
 
                                gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, lm);
                        }
@@ -1838,8 +1836,8 @@ u1 *intrp_createcompilerstub(methodinfo *m)
        Inst        *s;
        Inst        *d;
        codegendata *cd;
-       s4           dumpsize;
        s4           stackframesize;
+       int32_t      dumpmarker;
 
        s = CNEW(Inst, COMPILERSTUB_SIZE);
 
@@ -1856,7 +1854,7 @@ u1 *intrp_createcompilerstub(methodinfo *m)
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
        
        cd = DNEW(codegendata);
     cd->mcodeptr = (u1 *) s;
@@ -1894,7 +1892,7 @@ u1 *intrp_createcompilerstub(methodinfo *m)
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
        
        return (u1 *) s;
 }
@@ -2090,7 +2088,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
        av_ptr(alist, _Jv_JNIEnv *, _Jv_env);
 
        if (m->flags & ACC_STATIC)
-               av_ptr(alist, classinfo *, m->class);
+               av_ptr(alist, classinfo *, m->clazz);
 
        for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
                switch (md->paramtypes[i].type) {
@@ -2158,7 +2156,7 @@ Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1
        /* for static methods, pass class pointer */
 
        if (m->flags & ACC_STATIC)
-               *pvalues++ = &m->class;
+               *pvalues++ = &m->clazz;
 
        /* pass parameter to native function */
 
@@ -2203,12 +2201,12 @@ u1 *createcalljavafunction(methodinfo *m)
        jitdata            *jd;
        codegendata        *cd;
        registerdata       *rd;
-       s4                  dumpsize;
        methoddesc         *md;
+       int32_t             dumpmarker;
 
        /* mark dump memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* allocate memory */
 
@@ -2264,7 +2262,7 @@ u1 *createcalljavafunction(methodinfo *m)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return entrypoint;
 }
index 5d5098990218ae758f65dbdb79711c42c418d90c..4219f0012aca3e5d91b97aa0be9bdf07ffe15608 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/intrp/disass.c - disassembler wrapper for interpreter
 
-   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
-            Reinhard Grafl
-
-   Changes: Christian Thalinger
-            Anton Ertl
-                       Edwin Steiner
-
 */
 
 
@@ -175,7 +164,7 @@ void printarg_af      (functionptr        af      )
 void printarg_afi     (fieldinfo *        afi      )
 {
        if (afi) {
-               utf_fprint_printable_ascii_classname(vm_out, afi->class->name);
+               utf_fprint_printable_ascii_classname(vm_out, afi->clazz->name);
                fprintf(vm_out, ".");
                utf_fprint_printable_ascii(vm_out, afi->name);
                utf_fprint_printable_ascii(vm_out, afi->descriptor);
@@ -186,7 +175,7 @@ void printarg_afi     (fieldinfo *        afi      )
 void printarg_am      (methodinfo *       am      )
 {
        if (am) {
-               utf_fprint_printable_ascii_classname(vm_out, am->class->name);
+               utf_fprint_printable_ascii_classname(vm_out, am->clazz->name);
                fprintf(vm_out, ".");
                utf_fprint_printable_ascii(vm_out, am->name);
                utf_fprint_printable_ascii(vm_out, am->descriptor);
index 923a9f510a7f2339d4a6dfe21e0f6811824ddae5..d735aa3c6182b83f6df1d55190279981314856f1 100644 (file)
 
 #include "mm/memory.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#else
-# include "threads/none/lock.h"
-#endif
+#include "threads/lock-common.h"
 
 #include "toolbox/hashtable.h"
 #include "toolbox/logging.h"
index d80ce18a798ff64490eec79656b92dc9d48f7f06..1e98d1e8bd821851d763ef412fe99f57145774a2 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/intrp/engine.c - #included by engine1.c and engine2.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"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#else
-# include "threads/none/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
@@ -62,7 +56,7 @@
 # ifndef USE_FAKE_ATOMIC_INSTRUCTIONS
 #  include "machine-instr.h"
 # else
-#  include "threads/native/generic-primitives.h"
+#  include "threads/posix/generic-primitives.h"
 # endif
 #endif
 
index 9e02efddb30c84e9792fde43e0944b34da3988da..a8f7107b24cc446510260953ff71047c1b45dac7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/intrp/patcher.c - Interpreter code patching 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.
 
@@ -67,8 +65,8 @@ bool intrp_patcher_get_putstatic(u1 *sp)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        /* patch the field's address */
@@ -100,8 +98,8 @@ bool intrp_patcher_get_putstatic_clinit(u1 *sp)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        /* patch the field's address */
@@ -305,12 +303,12 @@ bool intrp_patcher_invokeinterface(u1 *sp)
        /* patch interfacetable index */
 
        ip[1] = (OFFSET(vftbl_t, interfacetable[0]) -
-                        sizeof(methodptr*) * m->class->index);
+                        sizeof(methodptr*) * m->clazz->index);
 
        /* patch methodinfo and method offset */
 
        ip[4] = (ptrint) m;
-       ip[2] = (sizeof(methodptr) * (m - m->class->methods));
+       ip[2] = (sizeof(methodptr) * (m - m->clazz->methods));
 
        return true;
 }
diff --git a/src/vm/jit/ir/Makefile.am b/src/vm/jit/ir/Makefile.am
new file mode 100644 (file)
index 0000000..4417c43
--- /dev/null
@@ -0,0 +1,43 @@
+## src/vm/jit/ir/Makefile.am
+##
+## 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.
+
+## Process this file with automake to produce Makefile.in
+
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR)
+
+LIBS =
+
+noinst_LTLIBRARIES = \
+       libir.la
+
+libir_la_SOURCES = \
+       bytecode.c \
+       bytecode.h
+
+
+## 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/ir/bytecode.c b/src/vm/jit/ir/bytecode.c
new file mode 100644 (file)
index 0000000..b669f5f
--- /dev/null
@@ -0,0 +1,254 @@
+/* src/vm/jit/ir/bytecode.c - Java byte code handling
+
+   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"
+
+#include <stdint.h>
+
+#include "vm/jit/ir/bytecode.h"
+
+
+/* bytecodes ******************************************************************/
+
+bytecode_t bytecode[256] = {
+       { 1, 0,   "nop"             },
+       { 1, 1,   "aconst_null"     },
+       { 1, 1,   "iconst_m1"       },
+       { 1, 1,   "iconst"          },
+       { 1, 1,   "iconst_1"        },
+       { 1, 1,   "iconst_2"        },
+       { 1, 1,   "iconst_3"        },
+       { 1, 1,   "iconst_4"        },
+       { 1, 1,   "iconst_5"        },
+       { 1, 1,   "lconst_0"        },
+       { 1, 1,   "lconst_1"        },
+       { 1, 1,   "fconst_0"        },
+       { 1, 1,   "fconst_1"        },
+       { 1, 1,   "fconst_2"        },
+       { 1, 1,   "dconst_0"        },
+       { 1, 1,   "dconst_1"        },
+       { 2, 1,   "bipush"          },
+       { 3, 1,   "sipush"          },
+       { 2, 1,   "ldc"             },
+       { 3, 1,   "ldc_w"           },
+       { 3, 1,   "ldc2_w"          },
+       { 2, 1,   "iload"           },
+       { 2, 1,   "lload"           },
+       { 2, 1,   "fload"           },
+       { 2, 1,   "dload"           },
+       { 2, 1,   "aload"           },
+       { 1, 1,   "iload_0"         },
+       { 1, 1,   "iload_1"         },
+       { 1, 1,   "iload_2"         },
+       { 1, 1,   "iload_3"         },
+       { 1, 1,   "lload_0"         },
+       { 1, 1,   "lload_1"         },
+       { 1, 1,   "lload_2"         },
+       { 1, 1,   "lload_3"         },
+       { 1, 1,   "fload_0"         },
+       { 1, 1,   "fload_1"         },
+       { 1, 1,   "fload_2"         },
+       { 1, 1,   "fload_3"         },
+       { 1, 1,   "dload_0"         },
+       { 1, 1,   "dload_1"         },
+       { 1, 1,   "dload_2"         },
+       { 1, 1,   "dload_3"         },
+       { 1, 1,   "aload_0"         },
+       { 1, 1,   "aload_1"         },
+       { 1, 1,   "aload_2"         },
+       { 1, 1,   "aload_3"         },
+       { 1, 1,   "iaload"          },
+       { 1, 1,   "laload"          },
+       { 1, 1,   "faload"          },
+       { 1, 1,   "daload"          },
+       { 1, 1,   "aaload"          },
+       { 1, 1,   "baload"          },
+       { 1, 1,   "caload"          },
+       { 1, 1,   "saload"          },
+       { 2, 0,   "istore"          },
+       { 2, 0,   "lstore"          },
+       { 2, 0,   "fstore"          },
+       { 2, 0,   "dstore"          },
+       { 2, 0,   "astore"          },
+       { 1, 0,   "istore_0"        },
+       { 1, 0,   "istore_1"        },
+       { 1, 0,   "istore_2"        },
+       { 1, 0,   "istore_3"        },
+       { 1, 0,   "lstore_0"        },
+       { 1, 0,   "lstore_1"        },
+       { 1, 0,   "lstore_2"        },
+       { 1, 0,   "lstore_3"        },
+       { 1, 0,   "fstore_0"        },
+       { 1, 0,   "fstore_1"        },
+       { 1, 0,   "fstore_2"        },
+       { 1, 0,   "fstore_3"        },
+       { 1, 0,   "dstore_0"        },
+       { 1, 0,   "dstore_1"        },
+       { 1, 0,   "dstore_2"        },
+       { 1, 0,   "dstore_3"        },
+       { 1, 0,   "astore_0"        },
+       { 1, 0,   "astore_1"        },
+       { 1, 0,   "astore_2"        },
+       { 1, 0,   "astore_3"        },
+       { 1, 0,   "iastore"         },
+       { 1, 0,   "lastore"         },
+       { 1, 0,   "fastore"         },
+       { 1, 0,   "dastore"         },
+       { 1, 0,   "aastore"         },
+       { 1, 0,   "bastore"         },
+       { 1, 0,   "castore"         },
+       { 1, 0,   "sastore"         },
+       { 1, 0,   "pop"             },
+       { 1, 0,   "pop2"            },
+       { 1, 1,   "dup"             },
+       { 1, 1+3, "dup_x1"          },
+       { 1, 2+4, "dup_x2"          },
+       { 1, 2,   "dup2"            },
+       { 1, 2+5, "dup2_x1"         },
+       { 1, 3+6, "dup2_x2"         },
+       { 1, 1+2, "swap"            },
+       { 1, 1,   "iadd"            },
+       { 1, 1,   "ladd"            },
+       { 1, 1,   "fadd"            },
+       { 1, 1,   "dadd"            },
+       { 1, 1,   "isub"            },
+       { 1, 1,   "lsub"            },
+       { 1, 1,   "fsub"            },
+       { 1, 1,   "dsub"            },
+       { 1, 1,   "imul"            },
+       { 1, 1,   "lmul"            },
+       { 1, 1,   "fmul"            },
+       { 1, 1,   "dmul"            },
+       { 1, 1,   "idiv"            },
+       { 1, 1,   "ldiv"            },
+       { 1, 1,   "fdiv"            },
+       { 1, 1,   "ddiv"            },
+       { 1, 1,   "irem"            },
+       { 1, 1,   "lrem"            },
+       { 1, 1,   "frem"            },
+       { 1, 1,   "drem"            },
+       { 1, 1,   "ineg"            },
+       { 1, 1,   "lneg"            },
+       { 1, 1,   "fneg"            },
+       { 1, 1,   "dneg"            },
+       { 1, 1,   "ishl"            },
+       { 1, 1,   "lshl"            },
+       { 1, 1,   "ishr"            },
+       { 1, 1,   "lshr"            },
+       { 1, 1,   "iushr"           },
+       { 1, 1,   "lushr"           },
+       { 1, 1,   "iand"            },
+       { 1, 1,   "land"            },
+       { 1, 1,   "ior"             },
+       { 1, 1,   "lor"             },
+       { 1, 1,   "ixor"            },
+       { 1, 1,   "lxor"            },
+       { 3, 0,   "iinc"            },
+       { 1, 1,   "i2l"             },
+       { 1, 1,   "i2f"             },
+       { 1, 1,   "i2d"             },
+       { 1, 1,   "l2i"             },
+       { 1, 1,   "l2f"             },
+       { 1, 1,   "l2d"             },
+       { 1, 1,   "f2i"             },
+       { 1, 1,   "f2l"             },
+       { 1, 1,   "f2d"             },
+       { 1, 1,   "d2i"             },
+       { 1, 1,   "d2l"             },
+       { 1, 1,   "d2f"             },
+       { 1, 1,   "int2byte"        },
+       { 1, 1,   "int2char"        },
+       { 1, 1,   "int2short"       },
+       { 1, 1,   "lcmp"            },
+       { 1, 1,   "fcmpl"           },
+       { 1, 1,   "fcmpg"           },
+       { 1, 1,   "dcmpl"           },
+       { 1, 1,   "dcmpg"           },
+       { 3, 0,   "ifeq"            },
+       { 3, 0,   "ifne"            },
+       { 3, 0,   "iflt"            },
+       { 3, 0,   "ifge"            },
+       { 3, 0,   "ifgt"            },
+       { 3, 0,   "ifle"            },
+       { 3, 0,   "if_icmpe"        },
+       { 3, 0,   "if_icmpne"       },
+       { 3, 0,   "if_icmplt"       },
+       { 3, 0,   "if_icmpge"       },
+       { 3, 0,   "if_icmpgt"       },
+       { 3, 0,   "if_icmple"       },
+       { 3, 0,   "if_acmpeq"       },
+       { 3, 0,   "if_acmpne"       },
+       { 3, 0,   "goto"            },
+       { 3, 1,   "jsr"             },
+       { 2, 0,   "ret"             },
+       { 0, 0,   "tableswitch"     },
+       { 0, 0,   "lookupswitch"    },
+       { 1, 0,   "ireturn"         },
+       { 1, 0,   "lreturn"         },
+       { 1, 0,   "freturn"         },
+       { 1, 0,   "dreturn"         },
+       { 1, 0,   "areturn"         },
+       { 1, 0,   "return"          },
+       { 3, 1,   "getstatic"       },
+       { 3, 0,   "putstatic"       },
+       { 3, 1,   "getfield"        },
+       { 3, 0,   "putfield"        },
+       { 3, 1,   "invokevirtual"   },
+       { 3, 1,   "invokespecial"   },
+       { 3, 1,   "invokestatic"    },
+       { 5, 1,   "invokeinterface" },
+       { 1, 1,   "undef186"        }, /* XXX */
+       { 3, 1,   "new"             },
+       { 2, 1,   "newarray"        },
+       { 3, 1,   "anewarray"       },
+       { 1, 1,   "arraylength"     },
+       { 1, 1,   "athrow"          },
+       { 3, 1,   "checkcast"       },
+       { 3, 1,   "instanceof"      },
+       { 1, 0,   "monitorenter"    },
+       { 1, 0,   "monitorexit"     },
+       { 0, 0,   "wide"            },
+       { 4, 1,   "multianewarray"  },
+       { 3, 0,   "ifnull"          },
+       { 3, 0,   "ifnonnull"       },
+       { 5, 0,   "goto_w"          },
+       { 5, 1,   "jsr_w"           },
+       { 1, 0,   "breakpoint"      },
+};
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of 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/ir/bytecode.h b/src/vm/jit/ir/bytecode.h
new file mode 100644 (file)
index 0000000..fbedc92
--- /dev/null
@@ -0,0 +1,325 @@
+/* src/vm/jit/ir/bytecode.h - Java byte code definitions
+
+   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.
+
+*/
+
+
+#ifndef _VM_JIT_IR_BYTECODE_H
+#define _VM_JIT_IR_BYTECODE_H
+
+#include "config.h"
+
+
+/* bytecode_t *****************************************************************/
+
+typedef struct bytecode_t bytecode_t;
+
+struct bytecode_t {
+       int   length;                       /* length of the instruction in bytes */
+       int   slots;                        /* required stack slots               */
+       char *mnemonic;
+};
+
+extern bytecode_t bytecode[256];
+
+
+/* Java bytecodes *************************************************************/
+
+enum {
+       BC_nop             = 0,
+
+       BC_aconst_null     = 1,
+
+       BC_iconst_m1       = 2,
+       BC_iconst_0        = 3,
+       BC_iconst_1        = 4,
+       BC_iconst_2        = 5,
+       BC_iconst_3        = 6,
+       BC_iconst_4        = 7,
+       BC_iconst_5        = 8,
+
+       BC_lconst_0        = 9,
+       BC_lconst_1        = 10,
+
+       BC_fconst_0        = 11,
+       BC_fconst_1        = 12,
+       BC_fconst_2        = 13,
+
+       BC_dconst_0        = 14,
+       BC_dconst_1        = 15,
+
+       BC_bipush          = 16,
+       BC_sipush          = 17,
+
+       BC_ldc1            = 18,
+       BC_ldc2            = 19,
+       BC_ldc2w           = 20,
+
+       BC_iload           = 21,
+       BC_lload           = 22,
+       BC_fload           = 23,
+       BC_dload           = 24,
+       BC_aload           = 25,
+
+       BC_iload_0         = 26,
+       BC_iload_1         = 27,
+       BC_iload_2         = 28,
+       BC_iload_3         = 29,
+
+       BC_lload_0         = 30,
+       BC_lload_1         = 31,
+       BC_lload_2         = 32,
+       BC_lload_3         = 33,
+
+       BC_fload_0         = 34,
+       BC_fload_1         = 35,
+       BC_fload_2         = 36,
+       BC_fload_3         = 37,
+
+       BC_dload_0         = 38,
+       BC_dload_1         = 39,
+       BC_dload_2         = 40,
+       BC_dload_3         = 41,
+
+       BC_aload_0         = 42,
+       BC_aload_1         = 43,
+       BC_aload_2         = 44,
+       BC_aload_3         = 45,
+
+       BC_iaload          = 46,
+       BC_laload          = 47,
+       BC_faload          = 48,
+       BC_daload          = 49,
+       BC_aaload          = 50,
+       BC_baload          = 51,
+       BC_caload          = 52,
+       BC_saload          = 53,
+
+       BC_istore          = 54,
+       BC_lstore          = 55,
+       BC_fstore          = 56,
+       BC_dstore          = 57,
+       BC_astore          = 58,
+
+       BC_istore_0        = 59,
+       BC_istore_1        = 60,
+       BC_istore_2        = 61,
+       BC_istore_3        = 62,
+
+       BC_lstore_0        = 63,
+       BC_lstore_1        = 64,
+       BC_lstore_2        = 65,
+       BC_lstore_3        = 66,
+
+       BC_fstore_0        = 67,
+       BC_fstore_1        = 68,
+       BC_fstore_2        = 69,
+       BC_fstore_3        = 70,
+
+       BC_dstore_0        = 71,
+       BC_dstore_1        = 72,
+       BC_dstore_2        = 73,
+       BC_dstore_3        = 74,
+
+       BC_astore_0        = 75,
+       BC_astore_1        = 76,
+       BC_astore_2        = 77,
+       BC_astore_3        = 78,
+
+       BC_iastore         = 79,
+       BC_lastore         = 80,
+       BC_fastore         = 81,
+       BC_dastore         = 82,
+       BC_aastore         = 83,
+       BC_bastore         = 84,
+       BC_castore         = 85,
+       BC_sastore         = 86,
+
+       BC_pop             = 87,
+       BC_pop2            = 88,
+       BC_dup             = 89,
+       BC_dup_x1          = 90,
+       BC_dup_x2          = 91,
+       BC_dup2            = 92,
+       BC_dup2_x1         = 93,
+       BC_dup2_x2         = 94,
+       BC_swap            = 95,
+
+       BC_iadd            = 96,
+       BC_ladd            = 97,
+       BC_fadd            = 98,
+       BC_dadd            = 99,
+
+       BC_isub            = 100,
+       BC_lsub            = 101,
+       BC_fsub            = 102,
+       BC_dsub            = 103,
+
+       BC_imul            = 104,
+       BC_lmul            = 105,
+       BC_fmul            = 106,
+       BC_dmul            = 107,
+
+       BC_idiv            = 108,
+       BC_ldiv            = 109,
+       BC_fdiv            = 110,
+       BC_ddiv            = 111,
+
+       BC_irem            = 112,
+       BC_lrem            = 113,
+       BC_frem            = 114,
+       BC_drem            = 115,
+
+       BC_ineg            = 116,
+       BC_lneg            = 117,
+       BC_fneg            = 118,
+       BC_dneg            = 119,
+
+       BC_ishl            = 120,
+       BC_lshl            = 121,
+       BC_ishr            = 122,
+       BC_lshr            = 123,
+       BC_iushr           = 124,
+       BC_lushr           = 125,
+
+       BC_iand            = 126,
+       BC_land            = 127,
+       BC_ior             = 128,
+       BC_lor             = 129,
+       BC_ixor            = 130,
+       BC_lxor            = 131,
+
+       BC_iinc            = 132,
+
+       BC_i2l             = 133,
+       BC_i2f             = 134,
+       BC_i2d             = 135,
+       BC_l2i             = 136,
+       BC_l2f             = 137,
+       BC_l2d             = 138,
+       BC_f2i             = 139,
+       BC_f2l             = 140,
+       BC_f2d             = 141,
+       BC_d2i             = 142,
+       BC_d2l             = 143,
+       BC_d2f             = 144,
+
+       BC_int2byte        = 145,
+       BC_int2char        = 146,
+       BC_int2short       = 147,
+
+       BC_lcmp            = 148,
+       BC_fcmpl           = 149,
+       BC_fcmpg           = 150,
+       BC_dcmpl           = 151,
+       BC_dcmpg           = 152,
+
+       BC_ifeq            = 153,
+       BC_ifne            = 154,
+       BC_iflt            = 155,
+       BC_ifge            = 156,
+       BC_ifgt            = 157,
+       BC_ifle            = 158,
+
+       BC_if_icmpeq       = 159,
+       BC_if_icmpne       = 160,
+       BC_if_icmplt       = 161,
+       BC_if_icmpge       = 162,
+       BC_if_icmpgt       = 163,
+       BC_if_icmple       = 164,
+       BC_if_acmpeq       = 165,
+       BC_if_acmpne       = 166,
+
+       BC_goto            = 167,
+       BC_jsr             = 168,
+       BC_ret             = 169,
+
+       BC_tableswitch     = 170,
+       BC_lookupswitch    = 171,
+
+       BC_ireturn         = 172,
+       BC_lreturn         = 173,
+       BC_freturn         = 174,
+       BC_dreturn         = 175,
+       BC_areturn         = 176,
+       BC_return          = 177,
+
+       BC_getstatic       = 178,
+       BC_putstatic       = 179,
+       BC_getfield        = 180,
+       BC_putfield        = 181,
+
+       BC_invokevirtual   = 182,
+       BC_invokespecial   = 183,
+       BC_invokestatic    = 184,
+       BC_invokeinterface = 185,
+
+       /* xxxunusedxxx 186 */
+
+       BC_new             = 187,
+       BC_newarray        = 188,
+       BC_anewarray       = 189,
+
+       BC_arraylength     = 190,
+
+       BC_athrow          = 191,
+
+       BC_checkcast       = 192,
+       BC_instanceof      = 193,
+
+       BC_monitorenter    = 194,
+       BC_monitorexit     = 195,
+
+       BC_wide            = 196,
+
+       BC_multianewarray  = 197,
+
+       BC_ifnull          = 198,
+       BC_ifnonnull       = 199,
+
+       BC_goto_w          = 200,
+       BC_jsr_w           = 201,
+
+       /* Reserved opcodes. */
+
+       BC_breakpoint      = 202,
+
+       BC_impdep1         = 254,
+       BC_impdep2         = 255
+};
+
+#endif /* _VM_JIT_IR_BYTECODE_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 488103b81a61cd416cb1b26687df5944538065c2..ea9faea507a78b555716ad3f6522c667b906743f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/jit.c - calls the code generation 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 "toolbox/logging.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
 
 #include "vm/global.h"
 #include "vm/initialize.h"
 
 #include "vm/jit/asmpart.h"
 
-# include "vm/jit/cfg.h"
+#include "vm/jit/cfg.h"
 
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/disass.h"
@@ -64,6 +61,7 @@
 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
 # include "vm/jit/allocator/lsra.h"
 #endif
+
 #if defined(ENABLE_SSA)
 # include "vm/jit/optimizing/lsra.h"
 # include "vm/jit/optimizing/ssa.h"
@@ -73,6 +71,8 @@
 # include "vm/jit/inline/inline.h"
 #endif
 
+#include "vm/jit/ir/bytecode.h"
+
 #include "vm/jit/loop/analyze.h"
 #include "vm/jit/loop/graph.h"
 #include "vm/jit/loop/loop.h"
 
 #include "vm/jit/optimizing/reorder.h"
 
+#if defined(ENABLE_PYTHON)
+# include "vm/jit/python.h"
+#endif
+
 #include "vm/jit/verify/typecheck.h"
 
 #include "vmcore/class.h"
@@ -163,737 +167,6 @@ icmdtable_entry_t icmd_table[256] = {
 #define PEI 1
 
 
-/* stackelement requirements of Java opcodes **********************************/
-
-int stackreq[256] = {
-       0,    /* JAVA_NOP                         0 */
-       1,    /* JAVA_ACONST                      1 */
-       1,    /* JAVA_ICONST_M1                   2 */
-       1,    /* JAVA_ICONST_0                    3 */
-       1,    /* JAVA_ICONST_1                    4 */
-       1,    /* JAVA_ICONST_2                    5 */
-       1,    /* JAVA_ICONST_3                    6 */
-       1,    /* JAVA_ICONST_4                    7 */
-       1,    /* JAVA_ICONST_5                    8 */
-       1,    /* JAVA_LCONST_0                    9 */
-       1,    /* JAVA_LCONST_1                   10 */
-       1,    /* JAVA_FCONST_0                   11 */
-       1,    /* JAVA_FCONST_1                   12 */
-       1,    /* JAVA_FCONST_2                   13 */
-       1,    /* JAVA_DCONST_0                   14 */
-       1,    /* JAVA_DCONST_1                   15 */
-       1,    /* JAVA_BIPUSH                     16 */
-       1,    /* JAVA_SIPUSH                     17 */
-       1,    /* JAVA_LDC                        18 */
-       1,    /* JAVA_LDC_W                      19 */
-       1,    /* JAVA_LDC2_W                     20 */
-       1,    /* JAVA_ILOAD                      21 */
-       1,    /* JAVA_LLOAD                      22 */
-       1,    /* JAVA_FLOAD                      23 */
-       1,    /* JAVA_DLOAD                      24 */
-       1,    /* JAVA_ALOAD                      25 */
-       1,    /* JAVA_ILOAD_0                    26 */
-       1,    /* JAVA_ILOAD_1                    27 */
-       1,    /* JAVA_ILOAD_2                    28 */
-       1,    /* JAVA_ILOAD_3                    29 */
-       1,    /* JAVA_LLOAD_0                    30 */
-       1,    /* JAVA_LLOAD_1                    31 */
-       1,    /* JAVA_LLOAD_2                    32 */
-       1,    /* JAVA_LLOAD_3                    33 */
-       1,    /* JAVA_FLOAD_0                    34 */
-       1,    /* JAVA_FLOAD_1                    35 */
-       1,    /* JAVA_FLOAD_2                    36 */
-       1,    /* JAVA_FLOAD_3                    37 */
-       1,    /* JAVA_DLOAD_0                    38 */
-       1,    /* JAVA_DLOAD_1                    39 */
-       1,    /* JAVA_DLOAD_2                    40 */
-       1,    /* JAVA_DLOAD_3                    41 */
-       1,    /* JAVA_ALOAD_0                    42 */
-       1,    /* JAVA_ALOAD_1                    43 */
-       1,    /* JAVA_ALOAD_2                    44 */
-       1,    /* JAVA_ALOAD_3                    45 */
-       1,    /* JAVA_IALOAD                     46 */
-       1,    /* JAVA_LALOAD                     47 */
-       1,    /* JAVA_FALOAD                     48 */
-       1,    /* JAVA_DALOAD                     49 */
-       1,    /* JAVA_AALOAD                     50 */
-       1,    /* JAVA_BALOAD                     51 */
-       1,    /* JAVA_CALOAD                     52 */
-       1,    /* JAVA_SALOAD                     53 */
-       0,    /* JAVA_ISTORE                     54 */
-       0,    /* JAVA_LSTORE                     55 */
-       0,    /* JAVA_FSTORE                     56 */
-       0,    /* JAVA_DSTORE                     57 */
-       0,    /* JAVA_ASTORE                     58 */
-       0,    /* JAVA_ISTORE_0                   59 */
-       0,    /* JAVA_ISTORE_1                   60 */
-       0,    /* JAVA_ISTORE_2                   61 */
-       0,    /* JAVA_ISTORE_3                   62 */
-       0,    /* JAVA_LSTORE_0                   63 */
-       0,    /* JAVA_LSTORE_1                   64 */
-       0,    /* JAVA_LSTORE_2                   65 */
-       0,    /* JAVA_LSTORE_3                   66 */
-       0,    /* JAVA_FSTORE_0                   67 */
-       0,    /* JAVA_FSTORE_1                   68 */
-       0,    /* JAVA_FSTORE_2                   69 */
-       0,    /* JAVA_FSTORE_3                   70 */
-       0,    /* JAVA_DSTORE_0                   71 */
-       0,    /* JAVA_DSTORE_1                   72 */
-       0,    /* JAVA_DSTORE_2                   73 */
-       0,    /* JAVA_DSTORE_3                   74 */
-       0,    /* JAVA_ASTORE_0                   75 */
-       0,    /* JAVA_ASTORE_1                   76 */
-       0,    /* JAVA_ASTORE_2                   77 */
-       0,    /* JAVA_ASTORE_3                   78 */
-       0,    /* JAVA_IASTORE                    79 */
-       0,    /* JAVA_LASTORE                    80 */
-       0,    /* JAVA_FASTORE                    81 */
-       0,    /* JAVA_DASTORE                    82 */
-       0,    /* JAVA_AASTORE                    83 */
-       0,    /* JAVA_BASTORE                    84 */
-       0,    /* JAVA_CASTORE                    85 */
-       0,    /* JAVA_SASTORE                    86 */
-       0,    /* JAVA_POP                        87 */
-       0,    /* JAVA_POP2                       88 */
-       1,    /* JAVA_DUP                        89 */
-       1+3,  /* JAVA_DUP_X1                     90 */
-       2+4,  /* JAVA_DUP_X2                     91 */
-       2,    /* JAVA_DUP2                       92 */
-       2+5,  /* JAVA_DUP2_X1                    93 */
-       3+6,  /* JAVA_DUP2_X2                    94 */
-       1+2,  /* JAVA_SWAP                       95 */
-       1,    /* JAVA_IADD                       96 */
-       1,    /* JAVA_LADD                       97 */
-       1,    /* JAVA_FADD                       98 */
-       1,    /* JAVA_DADD                       99 */
-       1,    /* JAVA_ISUB                      100 */
-       1,    /* JAVA_LSUB                      101 */
-       1,    /* JAVA_FSUB                      102 */
-       1,    /* JAVA_DSUB                      103 */
-       1,    /* JAVA_IMUL                      104 */
-       1,    /* JAVA_LMUL                      105 */
-       1,    /* JAVA_FMUL                      106 */
-       1,    /* JAVA_DMUL                      107 */
-       1,    /* JAVA_IDIV                      108 */
-       1,    /* JAVA_LDIV                      109 */
-       1,    /* JAVA_FDIV                      110 */
-       1,    /* JAVA_DDIV                      111 */
-       1,    /* JAVA_IREM                      112 */
-       1,    /* JAVA_LREM                      113 */
-       1,    /* JAVA_FREM                      114 */
-       1,    /* JAVA_DREM                      115 */
-       1,    /* JAVA_INEG                      116 */
-       1,    /* JAVA_LNEG                      117 */
-       1,    /* JAVA_FNEG                      118 */
-       1,    /* JAVA_DNEG                      119 */
-       1,    /* JAVA_ISHL                      120 */
-       1,    /* JAVA_LSHL                      121 */
-       1,    /* JAVA_ISHR                      122 */
-       1,    /* JAVA_LSHR                      123 */
-       1,    /* JAVA_IUSHR                     124 */
-       1,    /* JAVA_LUSHR                     125 */
-       1,    /* JAVA_IAND                      126 */
-       1,    /* JAVA_LAND                      127 */
-       1,    /* JAVA_IOR                       128 */
-       1,    /* JAVA_LOR                       129 */
-       1,    /* JAVA_IXOR                      130 */
-       1,    /* JAVA_LXOR                      131 */
-       0,    /* JAVA_IINC                      132 */
-       1,    /* JAVA_I2L                       133 */
-       1,    /* JAVA_I2F                       134 */
-       1,    /* JAVA_I2D                       135 */
-       1,    /* JAVA_L2I                       136 */
-       1,    /* JAVA_L2F                       137 */
-       1,    /* JAVA_L2D                       138 */
-       1,    /* JAVA_F2I                       139 */
-       1,    /* JAVA_F2L                       140 */
-       1,    /* JAVA_F2D                       141 */
-       1,    /* JAVA_D2I                       142 */
-       1,    /* JAVA_D2L                       143 */
-       1,    /* JAVA_D2F                       144 */
-       1,    /* JAVA_INT2BYTE                  145 */
-       1,    /* JAVA_INT2CHAR                  146 */
-       1,    /* JAVA_INT2SHORT                 147 */
-       1,    /* JAVA_LCMP                      148 */
-       1,    /* JAVA_FCMPL                     149 */
-       1,    /* JAVA_FCMPG                     150 */
-       1,    /* JAVA_DCMPL                     151 */
-       1,    /* JAVA_DCMPG                     152 */
-       0,    /* JAVA_IFEQ                      153 */
-       0,    /* JAVA_IFNE                      154 */
-       0,    /* JAVA_IFLT                      155 */
-       0,    /* JAVA_IFGE                      156 */
-       0,    /* JAVA_IFGT                      157 */
-       0,    /* JAVA_IFLE                      158 */
-       0,    /* JAVA_IF_ICMPEQ                 159 */
-       0,    /* JAVA_IF_ICMPNE                 160 */
-       0,    /* JAVA_IF_ICMPLT                 161 */
-       0,    /* JAVA_IF_ICMPGE                 162 */
-       0,    /* JAVA_IF_ICMPGT                 163 */
-       0,    /* JAVA_IF_ICMPLE                 164 */
-       0,    /* JAVA_IF_ACMPEQ                 165 */
-       0,    /* JAVA_IF_ACMPNE                 166 */
-       0,    /* JAVA_GOTO                      167 */
-       1,    /* JAVA_JSR                       168 */
-       0,    /* JAVA_RET                       169 */
-       0,    /* JAVA_TABLESWITCH               170 */
-       0,    /* JAVA_LOOKUPSWITCH              171 */
-       0,    /* JAVA_IRETURN                   172 */
-       0,    /* JAVA_LRETURN                   173 */
-       0,    /* JAVA_FRETURN                   174 */
-       0,    /* JAVA_DRETURN                   175 */
-       0,    /* JAVA_ARETURN                   176 */
-       0,    /* JAVA_RETURN                    177 */
-       1,    /* JAVA_GETSTATIC                 178 */
-       0,    /* JAVA_PUTSTATIC                 179 */
-       1,    /* JAVA_GETFIELD                  180 */
-       0,    /* JAVA_PUTFIELD                  181 */
-       1,    /* JAVA_INVOKEVIRTUAL             182 */
-       1,    /* JAVA_INVOKESPECIAL             183 */
-       1,    /* JAVA_INVOKESTATIC              184 */
-       1,    /* JAVA_INVOKEINTERFACE           185 */
-       1,    /* JAVA_UNDEF186                  186 */
-       1,    /* JAVA_NEW                       187 */
-       1,    /* JAVA_NEWARRAY                  188 */
-       1,    /* JAVA_ANEWARRAY                 189 */
-       1,    /* JAVA_ARRAYLENGTH               190 */
-       1,    /* JAVA_ATHROW                    191 */
-       1,    /* JAVA_CHECKCAST                 192 */
-       1,    /* JAVA_INSTANCEOF                193 */
-       0,    /* JAVA_MONITORENTER              194 */
-       0,    /* JAVA_MONITOREXIT               195 */
-       0,    /* JAVA_WIDE                      196 */
-       1,    /* JAVA_MULTIANEWARRAY            197 */
-       0,    /* JAVA_IFNULL                    198 */
-       0,    /* JAVA_IFNONNULL                 199 */
-       0,    /* JAVA_GOTO_W                    200 */
-       1,    /* JAVA_JSR_W                     201 */
-       0,    /* JAVA_BREAKPOINT                202 */
-       1,    /* JAVA_UNDEF203                  203 */
-       1,    /* JAVA_UNDEF204                  204 */
-       1,    /* JAVA_UNDEF205                  205 */
-       1,    /* JAVA_UNDEF206                  206 */
-       1,    /* JAVA_UNDEF207                  207 */
-       1,    /* JAVA_UNDEF208                  208 */
-       1,    /* JAVA_UNDEF209                  209 */
-       1,    /* JAVA_UNDEF210                  210 */
-       1,    /* JAVA_UNDEF211                  211 */
-       1,    /* JAVA_UNDEF212                  212 */
-       1,    /* JAVA_UNDEF213                  213 */
-       1,    /* JAVA_UNDEF214                  214 */
-       1,    /* JAVA_UNDEF215                  215 */
-       1,    /* JAVA_UNDEF216                  216 */
-       1,    /* JAVA_UNDEF217                  217 */
-       1,    /* JAVA_UNDEF218                  218 */
-       1,    /* JAVA_UNDEF219                  219 */
-       1,    /* JAVA_UNDEF220                  220 */
-       1,    /* JAVA_UNDEF221                  221 */
-       1,    /* JAVA_UNDEF222                  222 */
-       1,    /* JAVA_UNDEF223                  223 */
-       1,    /* JAVA_UNDEF224                  224 */
-       1,    /* JAVA_UNDEF225                  225 */
-       1,    /* JAVA_UNDEF226                  226 */
-       1,    /* JAVA_UNDEF227                  227 */
-       1,    /* JAVA_UNDEF228                  228 */
-       1,    /* JAVA_UNDEF229                  229 */
-       1,    /* JAVA_UNDEF230                  230 */
-       1,    /* JAVA_UNDEF231                  231 */
-       1,    /* JAVA_UNDEF232                  232 */
-       1,    /* JAVA_UNDEF233                  233 */
-       1,    /* JAVA_UNDEF234                  234 */
-       1,    /* JAVA_UNDEF235                  235 */
-       1,    /* JAVA_UNDEF236                  236 */
-       1,    /* JAVA_UNDEF237                  237 */
-       1,    /* JAVA_UNDEF238                  238 */
-       1,    /* JAVA_UNDEF239                  239 */
-       1,    /* JAVA_UNDEF240                  240 */
-       1,    /* JAVA_UNDEF241                  241 */
-       1,    /* JAVA_UNDEF242                  242 */
-       1,    /* JAVA_UNDEF243                  243 */
-       1,    /* JAVA_UNDEF244                  244 */
-       1,    /* JAVA_UNDEF245                  245 */
-       1,    /* JAVA_UNDEF246                  246 */
-       1,    /* JAVA_UNDEF247                  247 */
-       1,    /* JAVA_UNDEF248                  248 */
-       1,    /* JAVA_UNDEF249                  249 */
-       1,    /* JAVA_UNDEF250                  250 */
-       1,    /* JAVA_UNDEF251                  251 */
-       1,    /* JAVA_UNDEF252                  252 */
-       1,    /* JAVA_UNDEF253                  253 */
-       1,    /* JAVA_UNDEF254                  254 */
-       1,    /* JAVA_UNDEF255                  255 */
-};
-
-
-/* size in bytes of Java opcodes **********************************************/
-                                
-int jcommandsize[256] = {
-
-       1,    /* JAVA_NOP                         0 */
-       1,    /* JAVA_ACONST_NULL                 1 */
-       1,    /* JAVA_ICONST_M1                   2 */
-       1,    /* JAVA_ICONST_0                    3 */
-       1,    /* JAVA_ICONST_1                    4 */
-       1,    /* JAVA_ICONST_2                    5 */
-       1,    /* JAVA_ICONST_3                    6 */
-       1,    /* JAVA_ICONST_4                    7 */
-       1,    /* JAVA_ICONST_5                    8 */
-       1,    /* JAVA_LCONST_0                    9 */
-       1,    /* JAVA_LCONST_1                   10 */
-       1,    /* JAVA_FCONST_0                   11 */
-       1,    /* JAVA_FCONST_1                   12 */
-       1,    /* JAVA_FCONST_2                   13 */
-       1,    /* JAVA_DCONST_0                   14 */
-       1,    /* JAVA_DCONST_1                   15 */
-       2,    /* JAVA_BIPUSH                     16 */
-       3,    /* JAVA_SIPUSH                     17 */
-       2,    /* JAVA_LDC1                       18 */
-       3,    /* JAVA_LDC2                       19 */
-       3,    /* JAVA_LDC2W                      20 */
-       2,    /* JAVA_ILOAD                      21 */
-       2,    /* JAVA_LLOAD                      22 */
-       2,    /* JAVA_FLOAD                      23 */
-       2,    /* JAVA_DLOAD                      24 */
-       2,    /* JAVA_ALOAD                      25 */
-       1,    /* JAVA_ILOAD_0                    26 */
-       1,    /* JAVA_ILOAD_1                    27 */
-       1,    /* JAVA_ILOAD_2                    28 */
-       1,    /* JAVA_ILOAD_3                    29 */
-       1,    /* JAVA_LLOAD_0                    30 */
-       1,    /* JAVA_LLOAD_1                    31 */
-       1,    /* JAVA_LLOAD_2                    32 */
-       1,    /* JAVA_LLOAD_3                    33 */
-       1,    /* JAVA_FLOAD_0                    34 */
-       1,    /* JAVA_FLOAD_1                    35 */
-       1,    /* JAVA_FLOAD_2                    36 */
-       1,    /* JAVA_FLOAD_3                    37 */
-       1,    /* JAVA_DLOAD_0                    38 */
-       1,    /* JAVA_DLOAD_1                    39 */
-       1,    /* JAVA_DLOAD_2                    40 */
-       1,    /* JAVA_DLOAD_3                    41 */
-       1,    /* JAVA_ALOAD_0                    42 */
-       1,    /* JAVA_ALOAD_1                    43 */
-       1,    /* JAVA_ALOAD_2                    44 */
-       1,    /* JAVA_ALOAD_3                    45 */
-       1,    /* JAVA_IALOAD                     46 */
-       1,    /* JAVA_LALOAD                     47 */
-       1,    /* JAVA_FALOAD                     48 */
-       1,    /* JAVA_DALOAD                     49 */
-       1,    /* JAVA_AALOAD                     50 */
-       1,    /* JAVA_BALOAD                     51 */
-       1,    /* JAVA_CALOAD                     52 */
-       1,    /* JAVA_SALOAD                     53 */
-       2,    /* JAVA_ISTORE                     54 */
-       2,    /* JAVA_LSTORE                     55 */
-       2,    /* JAVA_FSTORE                     56 */
-       2,    /* JAVA_DSTORE                     57 */
-       2,    /* JAVA_ASTORE                     58 */
-       1,    /* JAVA_ISTORE_0                   59 */
-       1,    /* JAVA_ISTORE_1                   60 */
-       1,    /* JAVA_ISTORE_2                   61 */
-       1,    /* JAVA_ISTORE_3                   62 */
-       1,    /* JAVA_LSTORE_0                   63 */
-       1,    /* JAVA_LSTORE_1                   64 */
-       1,    /* JAVA_LSTORE_2                   65 */
-       1,    /* JAVA_LSTORE_3                   66 */
-       1,    /* JAVA_FSTORE_0                   67 */
-       1,    /* JAVA_FSTORE_1                   68 */
-       1,    /* JAVA_FSTORE_2                   69 */
-       1,    /* JAVA_FSTORE_3                   70 */
-       1,    /* JAVA_DSTORE_0                   71 */
-       1,    /* JAVA_DSTORE_1                   72 */
-       1,    /* JAVA_DSTORE_2                   73 */
-       1,    /* JAVA_DSTORE_3                   74 */
-       1,    /* JAVA_ASTORE_0                   75 */
-       1,    /* JAVA_ASTORE_1                   76 */
-       1,    /* JAVA_ASTORE_2                   77 */
-       1,    /* JAVA_ASTORE_3                   78 */
-       1,    /* JAVA_IASTORE                    79 */
-       1,    /* JAVA_LASTORE                    80 */
-       1,    /* JAVA_FASTORE                    81 */
-       1,    /* JAVA_DASTORE                    82 */
-       1,    /* JAVA_AASTORE                    83 */
-       1,    /* JAVA_BASTORE                    84 */
-       1,    /* JAVA_CASTORE                    85 */
-       1,    /* JAVA_SASTORE                    86 */
-       1,    /* JAVA_POP                        87 */
-       1,    /* JAVA_POP2                       88 */
-       1,    /* JAVA_DUP                        89 */
-       1,    /* JAVA_DUP_X1                     90 */
-       1,    /* JAVA_DUP_X2                     91 */
-       1,    /* JAVA_DUP2                       92 */
-       1,    /* JAVA_DUP2_X1                    93 */
-       1,    /* JAVA_DUP2_X2                    94 */
-       1,    /* JAVA_SWAP                       95 */
-       1,    /* JAVA_IADD                       96 */
-       1,    /* JAVA_LADD                       97 */
-       1,    /* JAVA_FADD                       98 */
-       1,    /* JAVA_DADD                       99 */
-       1,    /* JAVA_ISUB                      100 */
-       1,    /* JAVA_LSUB                      101 */
-       1,    /* JAVA_FSUB                      102 */
-       1,    /* JAVA_DSUB                      103 */
-       1,    /* JAVA_IMUL                      104 */
-       1,    /* JAVA_LMUL                      105 */
-       1,    /* JAVA_FMUL                      106 */
-       1,    /* JAVA_DMUL                      107 */
-       1,    /* JAVA_IDIV                      108 */
-       1,    /* JAVA_LDIV                      109 */
-       1,    /* JAVA_FDIV                      110 */
-       1,    /* JAVA_DDIV                      111 */
-       1,    /* JAVA_IREM                      112 */
-       1,    /* JAVA_LREM                      113 */
-       1,    /* JAVA_FREM                      114 */
-       1,    /* JAVA_DREM                      115 */
-       1,    /* JAVA_INEG                      116 */
-       1,    /* JAVA_LNEG                      117 */
-       1,    /* JAVA_FNEG                      118 */
-       1,    /* JAVA_DNEG                      119 */
-       1,    /* JAVA_ISHL                      120 */
-       1,    /* JAVA_LSHL                      121 */
-       1,    /* JAVA_ISHR                      122 */
-       1,    /* JAVA_LSHR                      123 */
-       1,    /* JAVA_IUSHR                     124 */
-       1,    /* JAVA_LUSHR                     125 */
-       1,    /* JAVA_IAND                      126 */
-       1,    /* JAVA_LAND                      127 */
-       1,    /* JAVA_IOR                       128 */
-       1,    /* JAVA_LOR                       129 */
-       1,    /* JAVA_IXOR                      130 */
-       1,    /* JAVA_LXOR                      131 */
-       3,    /* JAVA_IINC                      132 */
-       1,    /* JAVA_I2L                       133 */
-       1,    /* JAVA_I2F                       134 */
-       1,    /* JAVA_I2D                       135 */
-       1,    /* JAVA_L2I                       136 */
-       1,    /* JAVA_L2F                       137 */
-       1,    /* JAVA_L2D                       138 */
-       1,    /* JAVA_F2I                       139 */
-       1,    /* JAVA_F2L                       140 */
-       1,    /* JAVA_F2D                       141 */
-       1,    /* JAVA_D2I                       142 */
-       1,    /* JAVA_D2L                       143 */
-       1,    /* JAVA_D2F                       144 */
-       1,    /* JAVA_INT2BYTE                  145 */
-       1,    /* JAVA_INT2CHAR                  146 */
-       1,    /* JAVA_INT2SHORT                 147 */
-       1,    /* JAVA_LCMP                      148 */
-       1,    /* JAVA_FCMPL                     149 */
-       1,    /* JAVA_FCMPG                     150 */
-       1,    /* JAVA_DCMPL                     151 */
-       1,    /* JAVA_DCMPG                     152 */
-       3,    /* JAVA_IFEQ                      153 */
-       3,    /* JAVA_IFNE                      154 */
-       3,    /* JAVA_IFLT                      155 */
-       3,    /* JAVA_IFGE                      156 */
-       3,    /* JAVA_IFGT                      157 */
-       3,    /* JAVA_IFLE                      158 */
-       3,    /* JAVA_IF_ICMPEQ                 159 */
-       3,    /* JAVA_IF_ICMPNE                 160 */
-       3,    /* JAVA_IF_ICMPLT                 161 */
-       3,    /* JAVA_IF_ICMPGE                 162 */
-       3,    /* JAVA_IF_ICMPGT                 163 */
-       3,    /* JAVA_IF_ICMPLE                 164 */
-       3,    /* JAVA_IF_ACMPEQ                 165 */
-       3,    /* JAVA_IF_ACMPNE                 166 */
-       3,    /* JAVA_GOTO                      167 */
-       3,    /* JAVA_JSR                       168 */
-       2,    /* JAVA_RET                       169 */
-       0,    /* JAVA_TABLESWITCH               170 */ /* variable length */
-       0,    /* JAVA_LOOKUPSWITCH              171 */ /* variable length */
-       1,    /* JAVA_IRETURN                   172 */
-       1,    /* JAVA_LRETURN                   173 */
-       1,    /* JAVA_FRETURN                   174 */
-       1,    /* JAVA_DRETURN                   175 */
-       1,    /* JAVA_ARETURN                   176 */
-       1,    /* JAVA_RETURN                    177 */
-       3,    /* JAVA_GETSTATIC                 178 */
-       3,    /* JAVA_PUTSTATIC                 179 */
-       3,    /* JAVA_GETFIELD                  180 */
-       3,    /* JAVA_PUTFIELD                  181 */
-       3,    /* JAVA_INVOKEVIRTUAL             182 */
-       3,    /* JAVA_INVOKESPECIAL             183 */
-       3,    /* JAVA_INVOKESTATIC              184 */
-       5,    /* JAVA_INVOKEINTERFACE           185 */
-       1,    /* UNDEF186 */
-       3,    /* JAVA_NEW                       187 */
-       2,    /* JAVA_NEWARRAY                  188 */
-       3,    /* JAVA_ANEWARRAY                 189 */
-       1,    /* JAVA_ARRAYLENGTH               190 */
-       1,    /* JAVA_ATHROW                    191 */
-       3,    /* JAVA_CHECKCAST                 192 */
-       3,    /* JAVA_INSTANCEOF                193 */
-       1,    /* JAVA_MONITORENTER              194 */
-       1,    /* JAVA_MONITOREXIT               195 */
-       0,    /* JAVA_WIDE                      196 */ /* variable length */
-       4,    /* JAVA_MULTIANEWARRAY            197 */
-       3,    /* JAVA_IFNULL                    198 */
-       3,    /* JAVA_IFNONNULL                 199 */
-       5,    /* JAVA_GOTO_W                    200 */
-       5,    /* JAVA_JSR_W                     201 */
-       1,    /* JAVA_BREAKPOINT                202 */
-
-       1,    /* UNDEF203 */
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,    /* UNDEF210 */
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,    /* UNDEF220 */
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,
-       1,    /* UNDEF230 */
-       1,
-       1,
-       1,
-       1,
-
-       /* unused */
-               1,1,1,1,1,1,
-       1,1,1,1,1,1,1,1,1,1,
-       1,1,1,1,1
-};
-
-
-/* Java opcode names *********************************************************/
-
-char *opcode_names[256] = {
-       "NOP            ", /*               0 */
-       "ACONST         ", /*               1 */
-       "ICONST_M1      ", /* ICONST_M1     2 */
-       "ICONST_0       ", /* ICONST_0      3 */
-       "ICONST_1       ", /* ICONST_1      4 */
-       "ICONST_2       ", /* ICONST_2      5 */
-       "ICONST_3       ", /* ICONST_3      6 */
-       "ICONST_4       ", /* ICONST_4      7 */
-       "ICONST_5       ", /* ICONST_5      8 */
-       "LCONST_0       ", /* LCONST_0      9 */
-       "LCONST_1       ", /* LCONST_1     10 */
-       "FCONST_0       ", /* FCONST_0     11 */
-       "FCONST_1       ", /* FCONST_1     12 */
-       "FCONST_2       ", /* FCONST_2     13 */
-       "DCONST_0       ", /* DCONST_0     14 */
-       "DCONST_1       ", /* DCONST_1     15 */
-       "BIPUSH         ", /* BIPUSH       16 */
-       "SIPUSH         ", /* SIPUSH       17 */
-       "LDC            ", /* LDC          18 */
-       "LDC_W          ", /* LDC_W        19 */
-       "LDC2_W         ", /* LDC2_W       20 */
-       "ILOAD          ", /*              21 */
-       "LLOAD          ", /*              22 */
-       "FLOAD          ", /*              23 */
-       "DLOAD          ", /*              24 */
-       "ALOAD          ", /*              25 */
-       "ILOAD_0        ", /* ILOAD_0      26 */
-       "ILOAD_1        ", /* ILOAD_1      27 */
-       "ILOAD_2        ", /* ILOAD_2      28 */
-       "ILOAD_3        ", /* ILOAD_3      29 */
-       "LLOAD_0        ", /* LLOAD_0      30 */
-       "LLOAD_1        ", /* LLOAD_1      31 */
-       "LLOAD_2        ", /* LLOAD_2      32 */
-       "LLOAD_3        ", /* LLOAD_3      33 */
-       "FLOAD_0        ", /* FLOAD_0      34 */
-       "FLOAD_1        ", /* FLOAD_1      35 */
-       "FLOAD_2        ", /* FLOAD_2      36 */
-       "FLOAD_3        ", /* FLOAD_3      37 */
-       "DLOAD_0        ", /* DLOAD_0      38 */
-       "DLOAD_1        ", /* DLOAD_1      39 */
-       "DLOAD_2        ", /* DLOAD_2      40 */ 
-       "DLOAD_3        ", /* DLOAD_3      41 */
-       "ALOAD_0        ", /* ALOAD_0      42 */
-       "ALOAD_1        ", /* ALOAD_1      43 */
-       "ALOAD_2        ", /* ALOAD_2      44 */
-       "ALOAD_3        ", /* ALOAD_3      45 */
-       "IALOAD         ", /*              46 */
-       "LALOAD         ", /*              47 */
-       "FALOAD         ", /*              48 */
-       "DALOAD         ", /*              49 */
-       "AALOAD         ", /*              50 */
-       "BALOAD         ", /*              51 */
-       "CALOAD         ", /*              52 */
-       "SALOAD         ", /*              53 */
-       "ISTORE         ", /*              54 */
-       "LSTORE         ", /*              55 */
-       "FSTORE         ", /*              56 */
-       "DSTORE         ", /*              57 */
-       "ASTORE         ", /*              58 */
-       "ISTORE_0       ", /* ISTORE_0     59 */
-       "ISTORE_1       ", /* ISTORE_1     60 */
-       "ISTORE_2       ", /* ISTORE_2     61 */
-       "ISTORE_3       ", /* ISTORE_3     62 */
-       "LSTORE_0       ", /* LSTORE_0     63 */
-       "LSTORE_1       ", /* LSTORE_1     64 */
-       "LSTORE_2       ", /* LSTORE_2     65 */
-       "LSTORE_3       ", /* LSTORE_3     66 */
-       "FSTORE_0       ", /* FSTORE_0     67 */
-       "FSTORE_1       ", /* FSTORE_1     68 */
-       "FSTORE_2       ", /* FSTORE_2     69 */
-       "FSTORE_3       ", /* FSTORE_3     70 */
-       "DSTORE_0       ", /* DSTORE_0     71 */
-       "DSTORE_1       ", /* DSTORE_1     72 */
-       "DSTORE_2       ", /* DSTORE_2     73 */
-       "DSTORE_3       ", /* DSTORE_3     74 */
-       "ASTORE_0       ", /* ASTORE_0     75 */
-       "ASTORE_1       ", /* ASTORE_1     76 */
-       "ASTORE_2       ", /* ASTORE_2     77 */
-       "ASTORE_3       ", /* ASTORE_3     78 */
-       "IASTORE        ", /*              79 */
-       "LASTORE        ", /*              80 */
-       "FASTORE        ", /*              81 */
-       "DASTORE        ", /*              82 */
-       "AASTORE        ", /*              83 */
-       "BASTORE        ", /*              84 */
-       "CASTORE        ", /*              85 */
-       "SASTORE        ", /*              86 */
-       "POP            ", /*              87 */
-       "POP2           ", /*              88 */
-       "DUP            ", /*              89 */
-       "DUP_X1         ", /*              90 */
-       "DUP_X2         ", /*              91 */
-       "DUP2           ", /*              92 */
-       "DUP2_X1        ", /*              93 */
-       "DUP2_X2        ", /*              94 */
-       "SWAP           ", /*              95 */
-       "IADD           ", /*              96 */
-       "LADD           ", /*              97 */
-       "FADD           ", /*              98 */
-       "DADD           ", /*              99 */
-       "ISUB           ", /*             100 */
-       "LSUB           ", /*             101 */
-       "FSUB           ", /*             102 */
-       "DSUB           ", /*             103 */
-       "IMUL           ", /*             104 */
-       "LMUL           ", /*             105 */
-       "FMUL           ", /*             106 */
-       "DMUL           ", /*             107 */
-       "IDIV           ", /*             108 */
-       "LDIV           ", /*             109 */
-       "FDIV           ", /*             110 */
-       "DDIV           ", /*             111 */
-       "IREM           ", /*             112 */
-       "LREM           ", /*             113 */
-       "FREM           ", /*             114 */
-       "DREM           ", /*             115 */
-       "INEG           ", /*             116 */
-       "LNEG           ", /*             117 */
-       "FNEG           ", /*             118 */
-       "DNEG           ", /*             119 */
-       "ISHL           ", /*             120 */
-       "LSHL           ", /*             121 */
-       "ISHR           ", /*             122 */
-       "LSHR           ", /*             123 */
-       "IUSHR          ", /*             124 */
-       "LUSHR          ", /*             125 */
-       "IAND           ", /*             126 */
-       "LAND           ", /*             127 */
-       "IOR            ", /*             128 */
-       "LOR            ", /*             129 */
-       "IXOR           ", /*             130 */
-       "LXOR           ", /*             131 */
-       "IINC           ", /*             132 */
-       "I2L            ", /*             133 */
-       "I2F            ", /*             134 */
-       "I2D            ", /*             135 */
-       "L2I            ", /*             136 */
-       "L2F            ", /*             137 */
-       "L2D            ", /*             138 */
-       "F2I            ", /*             139 */
-       "F2L            ", /*             140 */
-       "F2D            ", /*             141 */
-       "D2I            ", /*             142 */
-       "D2L            ", /*             143 */
-       "D2F            ", /*             144 */
-       "INT2BYTE       ", /*             145 */
-       "INT2CHAR       ", /*             146 */
-       "INT2SHORT      ", /*             147 */
-       "LCMP           ", /*             148 */
-       "FCMPL          ", /*             149 */
-       "FCMPG          ", /*             150 */
-       "DCMPL          ", /*             151 */
-       "DCMPG          ", /*             152 */
-       "IFEQ           ", /*             153 */
-       "IFNE           ", /*             154 */
-       "IFLT           ", /*             155 */
-       "IFGE           ", /*             156 */
-       "IFGT           ", /*             157 */
-       "IFLE           ", /*             158 */
-       "IF_ICMPEQ      ", /*             159 */
-       "IF_ICMPNE      ", /*             160 */
-       "IF_ICMPLT      ", /*             161 */
-       "IF_ICMPGE      ", /*             162 */
-       "IF_ICMPGT      ", /*             163 */
-       "IF_ICMPLE      ", /*             164 */
-       "IF_ACMPEQ      ", /*             165 */
-       "IF_ACMPNE      ", /*             166 */
-       "GOTO           ", /*             167 */
-       "JSR            ", /*             168 */
-       "RET            ", /*             169 */
-       "TABLESWITCH    ", /*             170 */
-       "LOOKUPSWITCH   ", /*             171 */
-       "IRETURN        ", /*             172 */
-       "LRETURN        ", /*             173 */
-       "FRETURN        ", /*             174 */
-       "DRETURN        ", /*             175 */
-       "ARETURN        ", /*             176 */
-       "RETURN         ", /*             177 */
-       "GETSTATIC      ", /*             178 */
-       "PUTSTATIC      ", /*             179 */
-       "GETFIELD       ", /*             180 */
-       "PUTFIELD       ", /*             181 */
-       "INVOKEVIRTUAL  ", /*             182 */
-       "INVOKESPECIAL  ", /*             183 */
-       "INVOKESTATIC   ", /*             184 */
-       "INVOKEINTERFACE", /*             185 */
-       "UNDEF186       ", /*             186 */
-       "NEW            ", /*             187 */
-       "NEWARRAY       ", /*             188 */
-       "ANEWARRAY      ", /*             189 */
-       "ARRAYLENGTH    ", /*             190 */
-       "ATHROW         ", /*             191 */
-       "CHECKCAST      ", /*             192 */
-       "INSTANCEOF     ", /*             193 */
-       "MONITORENTER   ", /*             194 */
-       "MONITOREXIT    ", /*             195 */
-       "WIDE           ", /* WIDE        196 */
-       "MULTIANEWARRAY ", /*             197 */
-       "IFNULL         ", /*             198 */
-       "IFNONNULL      ", /*             199 */
-       "GOTO_W         ", /* GOTO_W      200 */
-       "JSR_W          ", /* JSR_W       201 */
-       "BREAKPOINT     ", /* BREAKPOINT  202 */
-
-                               "UNDEF203", "UNDEF204", "UNDEF205",
-       "UNDEF206", "UNDEF207", "UNDEF208", "UNDEF209", "UNDEF210",
-       "UNDEF211", "UNDEF212", "UNDEF213", "UNDEF214", "UNDEF215",
-       "UNDEF216", "UNDEF217", "UNDEF218", "UNDEF219", "UNDEF220",
-       "UNDEF221", "UNDEF222", "UNDEF223", "UNDEF224", "UNDEF225",
-       "UNDEF226", "UNDEF227", "UNDEF228", "UNDEF229", "UNDEF230",
-       "UNDEF231", "UNDEF232", "UNDEF233", "UNDEF234", "UNDEF235",
-       "UNDEF236", "UNDEF237", "UNDEF238", "UNDEF239", "UNDEF240",
-       "UNDEF241", "UNDEF242", "UNDEF243", "UNDEF244", "UNDEF245",
-       "UNDEF246", "UNDEF247", "UNDEF248", "UNDEF249", "UNDEF250",
-       "UNDEF251", "UNDEF252", "UNDEF253", "UNDEF254", "UNDEF255"
-};
-
-
 /* jit_init ********************************************************************
 
    Initializes the JIT subsystem.
@@ -902,6 +175,8 @@ char *opcode_names[256] = {
 
 void jit_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("jit_init");
+
 #if defined(ENABLE_JIT)
        /* initialize stack analysis subsystem */
 
@@ -1024,7 +299,7 @@ u1 *jit_compile(methodinfo *m)
 {
        u1      *r;
        jitdata *jd;
-       s4       dumpsize;
+       int32_t  dumpmarker;
 
        STATISTICS(count_jit_calls++);
 
@@ -1034,13 +309,13 @@ u1 *jit_compile(methodinfo *m)
           otherwise we could run into a deadlock with <clinit>'s that
           call static methods of it's own class. */
 
-       if ((m->flags & ACC_STATIC) && !(m->class->state & CLASS_INITIALIZED)) {
+       if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
 #if !defined(NDEBUG)
                if (initverbose)
-                       log_message_class("Initialize class ", m->class);
+                       log_message_class("Initialize class ", m->clazz);
 #endif
 
-               if (!initialize_class(m->class))
+               if (!initialize_class(m->clazz))
                        return NULL;
 
                /* check if the method has been compiled during initialization */
@@ -1075,7 +350,7 @@ u1 *jit_compile(methodinfo *m)
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* create jitdata structure */
 
@@ -1101,7 +376,7 @@ u1 *jit_compile(methodinfo *m)
 #endif
 
 #if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
-       if (opt_inlining && opt_inline_debug_all)
+       if (opt_Inline && opt_InlineAll)
                jd->flags |= JITDATA_FLAG_INLINE;
 #endif
 
@@ -1115,7 +390,7 @@ u1 *jit_compile(methodinfo *m)
                jd->flags |= JITDATA_FLAG_VERBOSECALL;
 
 #if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
-       if (opt_inlining)
+       if (opt_Inline)
                jd->flags |= JITDATA_FLAG_COUNTDOWN;
 #endif
 
@@ -1158,7 +433,7 @@ u1 *jit_compile(methodinfo *m)
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
 #if defined(ENABLE_STATISTICS)
        /* measure time */
@@ -1188,7 +463,7 @@ u1 *jit_recompile(methodinfo *m)
        u1      *r;
        jitdata *jd;
        u1       optlevel;
-       s4       dumpsize;
+       int32_t  dumpmarker;
 
        /* check for max. optimization level */
 
@@ -1214,7 +489,7 @@ u1 *jit_recompile(methodinfo *m)
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* create jitdata structure */
 
@@ -1239,7 +514,7 @@ u1 *jit_recompile(methodinfo *m)
                jd->flags |= JITDATA_FLAG_VERBOSECALL;
 
 #if defined(ENABLE_INLINING)
-       if (opt_inlining)
+       if (opt_Inline)
                jd->flags |= JITDATA_FLAG_INLINE;
 #endif
 
@@ -1270,7 +545,7 @@ u1 *jit_recompile(methodinfo *m)
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
 #if defined(ENABLE_STATISTICS)
        /* measure time */
@@ -1286,6 +561,9 @@ u1 *jit_recompile(methodinfo *m)
        return r;
 }
 
+#if defined(ENABLE_PM_HACKS)
+#include "vm/jit/jit_pm_1.inc"
+#endif
 
 /* jit_compile_intern **********************************************************
 
@@ -1320,7 +598,7 @@ static u1 *jit_compile_intern(jitdata *jd)
        show_filters_apply(jd->m);
 #endif
 
-       /* handle native methods and create a native stub */
+       /* Handle native methods and create a native stub. */
 
        if (m->flags & ACC_NATIVE) {
                functionptr f;
@@ -1369,7 +647,7 @@ static u1 *jit_compile_intern(jitdata *jd)
           dynamically-generated bytecodes. */
 
 # if defined(ENABLE_VERIFIER)
-       if (class_issubclass(m->class, class_sun_reflect_MagicAccessorImpl))
+       if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
                jd->flags &= ~JITDATA_FLAG_VERIFY;
 # endif
 #endif
@@ -1468,6 +746,9 @@ static u1 *jit_compile_intern(jitdata *jd)
                }
 #endif
 
+#if defined(ENABLE_PM_HACKS)
+#include "vm/jit/jit_pm_2.inc"
+#endif
                DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
 
 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
@@ -1482,10 +763,12 @@ static u1 *jit_compile_intern(jitdata *jd)
 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
 #if defined(ENABLE_SSA)
                /* allocate registers */
-               if ((opt_lsra) && (jd->exceptiontablelength == 0)) {
+               if ((opt_lsra) /*&& (strcmp(jd->m->name->text, "findClass") == 0 || jd->exceptiontablelength == 0)*/) {
                        jd->ls = DNEW(lsradata);
-                       lsra(jd);
-
+                       jd->ls = NULL;
+                       ssa(jd);
+                       /*lsra(jd);*/ regalloc(jd);
+                       eliminate_subbasicblocks(jd);
                        STATISTICS(count_methods_allocated_by_lsra++);
 
                } else
@@ -1896,6 +1179,15 @@ void jit_check_basicblock_numbers(jitdata *jd)
 }
 #endif /* !defined(NDEBUG) */
 
+methoddesc *instruction_call_site(const instruction *iptr) {
+       if (iptr->opc == ICMD_BUILTIN) {
+               return iptr->sx.s23.s3.bte->md;
+       } else if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+               return iptr->sx.s23.s3.um->methodref->parseddesc.md;
+       } else {
+               return iptr->sx.s23.s3.fmiref->p.method->parseddesc;
+       }
+}
 
 /*
  * These are local overrides for various environment variables in Emacs.
index cc014ceac5c981c70548bbc017c79bff435a3520..f45733fe18f76c3afaa8336e651c7a864139c727 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/jit.h - code generation 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.
 
@@ -31,8 +29,6 @@
 /* forward typedefs ***********************************************************/
 
 typedef struct jitdata jitdata;
-typedef struct stackelement stackelement;
-typedef stackelement *stackptr;
 typedef struct basicblock basicblock;
 typedef struct instruction instruction;
 typedef struct insinfo_inline insinfo_inline;
@@ -50,12 +46,15 @@ typedef struct exception_entry exception_entry;
 #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"
 
 #if defined(ENABLE_INLINING)
 # include "vm/jit/inline/inline.h"
 #endif
 
+#include "vm/jit/ir/bytecode.h"
+
 #if defined(ENABLE_LOOP)
 # include "vm/jit/loop/loop.h"
 #endif
@@ -128,7 +127,7 @@ struct jitdata {
 
        instruction     *instructions;    /* ICMDs, valid between parse and stack */
        basicblock      *basicblocks;     /* start of basic block list            */
-       stackelement    *stack;           /* XXX should become stack.c internal   */
+       stackelement_t  *stack;           /* XXX should become stack.c internal   */
        s4               instructioncount;/* XXX remove this?                     */
        s4               basicblockcount; /* number of basic blocks               */
        s4               stackcount;      /* number of stackelements to allocate  */
@@ -145,6 +144,9 @@ struct jitdata {
                         /*     >= 0......index into jd->var, or                  */
                                         /*     UNUSED....this (javaindex,type) pair is not used  */
 
+       s4              *reverselocalmap; /* map from CACAO varindex to javaindex */
+                                         /* (varindex must be < localcount)      */
+
        s4               maxlocals;       /* max. number of javalocals            */
 
        interface_info  *interface_map;   /* interface variables (for simplereg)  */
@@ -160,6 +162,8 @@ struct jitdata {
        bool             branchtoend;          /* true if end dummy is a target   */
 };
 
+#define FOR_EACH_BASICBLOCK(jd, it) \
+       for ((it) = (jd)->basicblocks; (it) != NULL; (it) = (it)->next)
 
 #define UNUSED                     -1
 
@@ -210,17 +214,6 @@ struct jitdata {
     ((jd)->flags & JITDATA_FLAG_VERBOSECALL)
 
 
-/* macros for accessing variables *********************************************
-   Use VAROP for s1, s2, s3 and dst operands (eg. VAROP(iptr->s1)),
-   use VAR if you have the variable index (eg. VAR(iptr->sx.s23.s2.args[0])).
-
-******************************************************************************/
-
-#define VAROP(v) (jd->var + (v).varindex)
-#define VAR(i)   (jd->var + (i))
-
-
 /* exception_entry ************************************************************/
 
 struct exception_entry {
@@ -234,40 +227,37 @@ struct exception_entry {
 };
 
 
-/* stack element structure ****************************************************/
-
-/* flags */
+/* macros for accessing variables *********************************************
+   Use VAROP for s1, s2, s3 and dst operands (eg. VAROP(iptr->s1)),
+   use VAR if you have the variable index (eg. VAR(iptr->sx.s23.s2.args[0])).
 
-#define SAVEDVAR      1         /* variable has to survive method invocations */
-#define INMEMORY      2         /* variable stored in memory                  */
-#define SAVREG        4         /* allocated to a saved register              */
-#define ARGREG        8         /* allocated to an arg register               */
-#define PASSTHROUGH  32         /* stackslot was passed-through by an ICMD    */
-#define PREALLOC     64         /* preallocated var like for ARGVARS. Used    */
-                                /* with the new var system */
-#define INOUT    128            /* variable is an invar or/and an outvar      */
+******************************************************************************/
 
-#define IS_SAVEDVAR(x)    ((x) & SAVEDVAR)
-#define IS_INMEMORY(x)    ((x) & INMEMORY)
+#define VAROP(v) (jd->var + (v).varindex)
+#define VAR(i)   (jd->var + (i))
 
+static inline bool var_is_local(const jitdata *jd, s4 i) {
+       return (i < jd->localcount);
+}
 
-/* variable kinds */
+static inline bool var_is_prealloc(const jitdata *jd, s4 i) {
+       return ((i >= jd->localcount) && (jd->var[i].flags & PREALLOC));
+}
 
-#define UNDEFVAR   0            /* stack slot will become temp during regalloc*/
-#define TEMPVAR    1            /* stack slot is temp register                */
-#define STACKVAR   2            /* stack slot is numbered stack slot          */
-#define LOCALVAR   3            /* stack slot is local variable               */
-#define ARGVAR     4            /* stack slot is argument variable            */
+static inline bool var_is_inout(const jitdata *jd, s4 i) {
+       const varinfo *v = jd->var + i;
+       return ((i >= jd->localcount) && !(v->flags & PREALLOC) && (v->flags & INOUT));
+}
 
+static inline bool var_is_temp(const jitdata *jd, s4 i) {
+       const varinfo *v = jd->var + i;
+       return ((i >= jd->localcount) && !(v->flags & PREALLOC) && !(v->flags & INOUT));
+}
 
-struct stackelement {
-       stackptr prev;              /* pointer to next element towards bottom     */
-       instruction *creator;       /* instruction that created this element      */
-       s4       type;              /* slot type of stack element                 */
-       s4       flags;             /* flags (SAVED, INMEMORY)                    */
-       s4       varkind;           /* kind of variable or register               */
-       s4       varnum;            /* number of variable                         */
-};
+static inline bool var_is_saved(const jitdata *jd, s4 i) {
+       return (jd->var[i].flags & SAVEDVAR);
+}
 
 
 /**************************** instruction structure ***************************/
@@ -425,7 +415,6 @@ struct instruction {
                        md = iptr->sx.s23.s3.fmiref->parseddesc.md; \
        } while (0)
 
-
 /* additional info structs for special instructions ***************************/
 
 /* for ICMD_INLINE_START and ICMD_INLINE_END */
@@ -516,8 +505,52 @@ struct basicblock {
        insinfo_inline *inlineinfo; /* inlineinfo for the start of this block     */
 
        s4            mpc;          /* machine code pc at start of block          */
+
+       /* TODO: those fields are probably usefull for other passes as well. */
+
+#if defined(ENABLE_SSA)         
+       basicblock   *idom;         /* Immediate dominator, parent in dominator tree */
+       basicblock  **domsuccessors;/* Children in dominator tree                 */
+       s4            domsuccessorcount;
+
+       basicblock  **domfrontier;  /* Dominance frontier                         */
+       s4            domfrontiercount;
+
+       basicblock  **exhandlers;   /* Exception handlers for this block */
+       s4            exhandlercount;
+       basicblock  **expredecessors; /* Blocks this block is exception handler for */
+       s4            expredecessorcount;
+       s4            exouts;       /* Number of exceptional exits */
+
+       basicblock   *subbasicblocks;
+
+       void         *vp;           /* Freely used by different passes            */
+#endif
 };
 
+#define FOR_EACH_SUCCESSOR(bptr, it) \
+       for ((it) = (bptr)->successors; (it) != (bptr)->successors + (bptr)->successorcount; ++(it))
+
+#define FOR_EACH_PREDECESSOR(bptr, it) \
+       for ( \
+               (it) = (bptr)->predecessors; \
+               (it) != (bptr)->predecessors + ((bptr)->predecessorcount < 0 ? 0 : (bptr)->predecessorcount); \
+               ++(it) \
+       )
+
+#define FOR_EACH_INSTRUCTION(bptr, it) \
+       for ((it) = (bptr)->iinstr; (it) != (bptr)->iinstr + (bptr)->icount; ++(it))
+
+#if defined(ENABLE_SSA)
+
+#define FOR_EACH_EXHANDLER(bptr, it) \
+       for ((it) = (bptr)->exhandlers; (it) != (bptr)->exhandlers + (bptr)->exhandlercount; ++(it))
+
+#define FOR_EACH_EXPREDECESSOR(bptr, it) \
+       for ((it) = (bptr)->expredecessors; (it) != (bptr)->expredecessors + (bptr)->expredecessorcount; ++(it))
+
+#endif
+
 /* [+]...the javalocals array: This array is indexed by the javaindex (the    */
 /*       local variable index ocurring in the original bytecode). An element  */
 /*       javalocals[javaindex] encodes where to find the contents of the      */
@@ -548,7 +581,10 @@ struct basicblock {
                bptr->type   = BBTYPE_STD;                     \
                bptr->method = (m);                            \
        } while (0)
-                       
+
+static inline bool basicblock_reached(const basicblock *bptr) {
+       return (bptr->flags >= BBREACHED);
+}
 
 /* data-flow constants for the ICMD table ************************************/
 
@@ -629,624 +665,310 @@ extern icmdtable_entry_t icmd_table[256];
 
 /********** JavaVM operation codes (sorted) and instruction lengths ***********/
 
-extern char *opcode_names[256];
-extern int jcommandsize[256];
-extern int stackreq[256];
-
-#define JAVA_NOP               0
-#define ICMD_NOP               0
-
-#define JAVA_ACONST_NULL       1
-#define ICMD_ACONST            1        /* val.a = constant                   */
-
-#define JAVA_ICONST_M1         2
-#define ICMD_CHECKNULL         2
-
-#define JAVA_ICONST_0          3
-#define ICMD_ICONST            3        /* val.i = constant                   */
-
-#define JAVA_ICONST_1          4
-
-#define JAVA_ICONST_2          5
-#define ICMD_IDIVPOW2          5        /* val.i = constant                   */
-
-#define JAVA_ICONST_3          6
-#define ICMD_LDIVPOW2          6        /* val.l = constant                   */
-
-#define JAVA_ICONST_4          7
-
-#define JAVA_ICONST_5          8
-
-#define JAVA_LCONST_0          9
-#define ICMD_LCONST            9        /* val.l = constant                   */
-
-#define JAVA_LCONST_1         10
-#define ICMD_LCMPCONST        10        /* val.l = constant                   */
-
-#define JAVA_FCONST_0         11
-#define ICMD_FCONST           11        /* val.f = constant                   */
-
-#define JAVA_FCONST_1         12
-
-#define JAVA_FCONST_2         13
-
-#define JAVA_DCONST_0         14
-#define ICMD_DCONST           14        /* val.d = constant                   */
-
-#define JAVA_DCONST_1         15
-#define ICMD_COPY             15
-
-#define JAVA_BIPUSH           16
-#define ICMD_MOVE             16
-
-#define JAVA_SIPUSH           17
-
-#define JAVA_LDC1             18
-
-#define JAVA_LDC2             19
-
-#define JAVA_LDC2W            20
-
-                                           /* order of LOAD instructions must be */
-                                           /* equal to order of TYPE_* defines   */
-#define JAVA_ILOAD            21
-#define ICMD_ILOAD            21        /* op1 = local variable               */
-
-#define JAVA_LLOAD            22
-#define ICMD_LLOAD            22        /* op1 = local variable               */
-
-#define JAVA_FLOAD            23
-#define ICMD_FLOAD            23        /* op1 = local variable               */
-
-#define JAVA_DLOAD            24
-#define ICMD_DLOAD            24        /* op1 = local variable               */
-
-#define JAVA_ALOAD            25
-#define ICMD_ALOAD            25        /* op1 = local variable               */
-
-#define JAVA_ILOAD_0          26
-#define ICMD_IADDCONST        26        /* val.i = constant                   */
-
-#define JAVA_ILOAD_1          27
-#define ICMD_ISUBCONST        27        /* val.i = constant                   */
-
-#define JAVA_ILOAD_2          28
-#define ICMD_IMULCONST        28        /* val.i = constant                   */
-
-#define JAVA_ILOAD_3          29
-#define ICMD_IANDCONST        29        /* val.i = constant                   */
-
-#define JAVA_LLOAD_0          30
-#define ICMD_IORCONST         30        /* val.i = constant                   */
-
-#define JAVA_LLOAD_1          31
-#define ICMD_IXORCONST        31        /* val.i = constant                   */
-
-#define JAVA_LLOAD_2          32
-#define ICMD_ISHLCONST        32        /* val.i = constant                   */
-
-#define JAVA_LLOAD_3          33
-#define ICMD_ISHRCONST        33        /* val.i = constant                   */
-
-#define JAVA_FLOAD_0          34
-#define ICMD_IUSHRCONST       34        /* val.i = constant                   */
-
-#define JAVA_FLOAD_1          35
-#define ICMD_IREMPOW2         35        /* val.i = constant                   */
-
-#define JAVA_FLOAD_2          36
-#define ICMD_LADDCONST        36        /* val.l = constant                   */
-
-#define JAVA_FLOAD_3          37
-#define ICMD_LSUBCONST        37        /* val.l = constant                   */
-
-#define JAVA_DLOAD_0          38
-#define ICMD_LMULCONST        38        /* val.l = constant                   */
-
-#define JAVA_DLOAD_1          39
-#define ICMD_LANDCONST        39        /* val.l = constant                   */
-
-#define JAVA_DLOAD_2          40
-#define ICMD_LORCONST         40        /* val.l = constant                   */
-
-#define JAVA_DLOAD_3          41
-#define ICMD_LXORCONST        41        /* val.l = constant                   */
-
-#define JAVA_ALOAD_0          42
-#define ICMD_LSHLCONST        42        /* val.l = constant                   */
-
-#define JAVA_ALOAD_1          43
-#define ICMD_LSHRCONST        43        /* val.l = constant                   */
-
-#define JAVA_ALOAD_2          44
-#define ICMD_LUSHRCONST       44        /* val.l = constant                   */
-
-#define JAVA_ALOAD_3          45
-#define ICMD_LREMPOW2         45        /* val.l = constant                   */
-
-#define JAVA_IALOAD           46
-#define ICMD_IALOAD           46
-
-#define JAVA_LALOAD           47
-#define ICMD_LALOAD           47
-
-#define JAVA_FALOAD           48
-#define ICMD_FALOAD           48
-
-#define JAVA_DALOAD           49
-#define ICMD_DALOAD           49
-
-#define JAVA_AALOAD           50
-#define ICMD_AALOAD           50
-
-#define JAVA_BALOAD           51
-#define ICMD_BALOAD           51
-
-#define JAVA_CALOAD           52
-#define ICMD_CALOAD           52
-
-#define JAVA_SALOAD           53
-#define ICMD_SALOAD           53
-
-                                           /* order of STORE instructions must be*/
-                                           /* equal to order of TYPE_* defines   */
-#define JAVA_ISTORE           54
-#define ICMD_ISTORE           54        /* op1 = local variable               */
-
-#define JAVA_LSTORE           55
-#define ICMD_LSTORE           55        /* op1 = local variable               */
-
-#define JAVA_FSTORE           56
-#define ICMD_FSTORE           56        /* op1 = local variable               */
-
-#define JAVA_DSTORE           57
-#define ICMD_DSTORE           57        /* op1 = local variable               */
-
-#define JAVA_ASTORE           58
-#define ICMD_ASTORE           58        /* op1 = local variable               */
-
-#define JAVA_ISTORE_0         59
-#define ICMD_IF_LEQ           59        /* op1 = target JavaVM pc, val.l      */
-
-#define JAVA_ISTORE_1         60
-#define ICMD_IF_LNE           60        /* op1 = target JavaVM pc, val.l      */
-
-#define JAVA_ISTORE_2         61
-#define ICMD_IF_LLT           61        /* op1 = target JavaVM pc, val.l      */
-
-#define JAVA_ISTORE_3         62
-#define ICMD_IF_LGE           62        /* op1 = target JavaVM pc, val.l      */
-
-#define JAVA_LSTORE_0         63
-#define ICMD_IF_LGT           63        /* op1 = target JavaVM pc, val.l      */
-
-#define JAVA_LSTORE_1         64
-#define ICMD_IF_LLE           64        /* op1 = target JavaVM pc, val.l      */
-
-#define JAVA_LSTORE_2         65
-#define ICMD_IF_LCMPEQ        65        /* op1 = target JavaVM pc             */
-
-#define JAVA_LSTORE_3         66
-#define ICMD_IF_LCMPNE        66        /* op1 = target JavaVM pc             */
-
-#define JAVA_FSTORE_0         67
-#define ICMD_IF_LCMPLT        67        /* op1 = target JavaVM pc             */
-
-#define JAVA_FSTORE_1         68
-#define ICMD_IF_LCMPGE        68        /* op1 = target JavaVM pc             */
-
-#define JAVA_FSTORE_2         69
-#define ICMD_IF_LCMPGT        69        /* op1 = target JavaVM pc             */
-
-#define JAVA_FSTORE_3         70
-#define ICMD_IF_LCMPLE        70        /* op1 = target JavaVM pc             */
-
-#define JAVA_DSTORE_0         71
-
-#define JAVA_DSTORE_1         72
-
-#define JAVA_DSTORE_2         73
-
-#define JAVA_DSTORE_3         74
-
-#define JAVA_ASTORE_0         75
-
-#define JAVA_ASTORE_1         76
-
-#define JAVA_ASTORE_2         77
+enum {
+       ICMD_NOP               = BC_nop,
 
-#define JAVA_ASTORE_3         78
+       ICMD_ACONST            = BC_aconst_null,
 
-#define JAVA_IASTORE          79
-#define ICMD_IASTORE          79
+       ICMD_CHECKNULL         = 2,
 
-#define JAVA_LASTORE          80
-#define ICMD_LASTORE          80
+       ICMD_ICONST            = BC_iconst_0,
 
-#define JAVA_FASTORE          81
-#define ICMD_FASTORE          81
+       /* 3 */
+       /* 4 */
 
-#define JAVA_DASTORE          82
-#define ICMD_DASTORE          82
+       ICMD_IDIVPOW2          = 5,
+       ICMD_LDIVPOW2          = 6,
 
-#define JAVA_AASTORE          83
-#define ICMD_AASTORE          83
+       /* 7 */
+       /* 8 */
 
-#define JAVA_BASTORE          84
-#define ICMD_BASTORE          84
+       ICMD_LCONST            = BC_lconst_0,
+
+       ICMD_LCMPCONST         = 10,
 
-#define JAVA_CASTORE          85
-#define ICMD_CASTORE          85
-
-#define JAVA_SASTORE          86
-#define ICMD_SASTORE          86
-
-#define JAVA_POP              87
-#define ICMD_POP              87
-
-#define JAVA_POP2             88
-#define ICMD_POP2             88
-
-#define JAVA_DUP              89
-#define ICMD_DUP              89
-
-#define JAVA_DUP_X1           90
-#define ICMD_DUP_X1           90
-
-#define JAVA_DUP_X2           91
-#define ICMD_DUP_X2           91
-
-#define JAVA_DUP2             92
-#define ICMD_DUP2             92
-
-#define JAVA_DUP2_X1          93
-#define ICMD_DUP2_X1          93
-
-#define JAVA_DUP2_X2          94
-#define ICMD_DUP2_X2          94
-
-#define JAVA_SWAP             95
-#define ICMD_SWAP             95
-
-#define JAVA_IADD             96
-#define ICMD_IADD             96
-
-#define JAVA_LADD             97
-#define ICMD_LADD             97
-
-#define JAVA_FADD             98
-#define ICMD_FADD             98
-
-#define JAVA_DADD             99
-#define ICMD_DADD             99
-
-#define JAVA_ISUB             100
-#define ICMD_ISUB             100
-
-#define JAVA_LSUB             101
-#define ICMD_LSUB             101
-
-#define JAVA_FSUB             102
-#define ICMD_FSUB             102
-
-#define JAVA_DSUB             103
-#define ICMD_DSUB             103
-
-#define JAVA_IMUL             104
-#define ICMD_IMUL             104
-
-#define JAVA_LMUL             105
-#define ICMD_LMUL             105
-
-#define JAVA_FMUL             106
-#define ICMD_FMUL             106
-
-#define JAVA_DMUL             107
-#define ICMD_DMUL             107
-
-#define JAVA_IDIV             108
-#define ICMD_IDIV             108
-
-#define JAVA_LDIV             109
-#define ICMD_LDIV             109
-
-#define JAVA_FDIV             110
-#define ICMD_FDIV             110
-
-#define JAVA_DDIV             111
-#define ICMD_DDIV             111
-
-#define JAVA_IREM             112
-#define ICMD_IREM             112
-
-#define JAVA_LREM             113
-#define ICMD_LREM             113
-
-#define JAVA_FREM             114
-#define ICMD_FREM             114
-
-#define JAVA_DREM             115
-#define ICMD_DREM             115
-
-#define JAVA_INEG             116
-#define ICMD_INEG             116
-
-#define JAVA_LNEG             117
-#define ICMD_LNEG             117
-
-#define JAVA_FNEG             118
-#define ICMD_FNEG             118
-
-#define JAVA_DNEG             119
-#define ICMD_DNEG             119
-
-#define JAVA_ISHL             120
-#define ICMD_ISHL             120
-
-#define JAVA_LSHL             121
-#define ICMD_LSHL             121
-
-#define JAVA_ISHR             122
-#define ICMD_ISHR             122
-
-#define JAVA_LSHR             123
-#define ICMD_LSHR             123
-
-#define JAVA_IUSHR            124
-#define ICMD_IUSHR            124
-
-#define JAVA_LUSHR            125
-#define ICMD_LUSHR            125
-
-#define JAVA_IAND             126
-#define ICMD_IAND             126
-
-#define JAVA_LAND             127
-#define ICMD_LAND             127
-
-#define JAVA_IOR              128
-#define ICMD_IOR              128
-
-#define JAVA_LOR              129
-#define ICMD_LOR              129
-
-#define JAVA_IXOR             130
-#define ICMD_IXOR             130
-
-#define JAVA_LXOR             131
-#define ICMD_LXOR             131
-
-#define JAVA_IINC             132
-#define ICMD_IINC             132   /* op1 = local variable, val.i = constant */
-
-#define JAVA_I2L              133
-#define ICMD_I2L              133
-
-#define JAVA_I2F              134
-#define ICMD_I2F              134
-
-#define JAVA_I2D              135
-#define ICMD_I2D              135
-
-#define JAVA_L2I              136
-#define ICMD_L2I              136
-
-#define JAVA_L2F              137
-#define ICMD_L2F              137
-
-#define JAVA_L2D              138
-#define ICMD_L2D              138
-
-#define JAVA_F2I              139
-#define ICMD_F2I              139
-
-#define JAVA_F2L              140
-#define ICMD_F2L              140
-
-#define JAVA_F2D              141
-#define ICMD_F2D              141
-
-#define JAVA_D2I              142
-#define ICMD_D2I              142
-
-#define JAVA_D2L              143
-#define ICMD_D2L              143
-
-#define JAVA_D2F              144
-#define ICMD_D2F              144
-
-#define JAVA_INT2BYTE         145
-#define ICMD_INT2BYTE         145
-
-#define JAVA_INT2CHAR         146
-#define ICMD_INT2CHAR         146
-
-#define JAVA_INT2SHORT        147
-#define ICMD_INT2SHORT        147
-
-#define JAVA_LCMP             148
-#define ICMD_LCMP             148
-
-#define JAVA_FCMPL            149
-#define ICMD_FCMPL            149
-
-#define JAVA_FCMPG            150
-#define ICMD_FCMPG            150
-
-#define JAVA_DCMPL            151
-#define ICMD_DCMPL            151
-
-#define JAVA_DCMPG            152
-#define ICMD_DCMPG            152
-
-#define JAVA_IFEQ             153
-#define ICMD_IFEQ             153       /* op1 = target JavaVM pc, val.i      */
-
-#define JAVA_IFNE             154
-#define ICMD_IFNE             154       /* op1 = target JavaVM pc, val.i      */
-
-#define JAVA_IFLT             155
-#define ICMD_IFLT             155       /* op1 = target JavaVM pc, val.i      */
-
-#define JAVA_IFGE             156
-#define ICMD_IFGE             156       /* op1 = target JavaVM pc, val.i      */
-
-#define JAVA_IFGT             157
-#define ICMD_IFGT             157       /* op1 = target JavaVM pc, val.i      */
-
-#define JAVA_IFLE             158
-#define ICMD_IFLE             158       /* op1 = target JavaVM pc, val.i      */
-
-#define JAVA_IF_ICMPEQ        159
-#define ICMD_IF_ICMPEQ        159       /* op1 = target JavaVM pc             */
-
-#define JAVA_IF_ICMPNE        160
-#define ICMD_IF_ICMPNE        160       /* op1 = target JavaVM pc             */
-
-#define JAVA_IF_ICMPLT        161
-#define ICMD_IF_ICMPLT        161       /* op1 = target JavaVM pc             */
-
-#define JAVA_IF_ICMPGE        162
-#define ICMD_IF_ICMPGE        162       /* op1 = target JavaVM pc             */
-
-#define JAVA_IF_ICMPGT        163
-#define ICMD_IF_ICMPGT        163       /* op1 = target JavaVM pc             */
-
-#define JAVA_IF_ICMPLE        164
-#define ICMD_IF_ICMPLE        164       /* op1 = target JavaVM pc             */
-
-#define JAVA_IF_ACMPEQ        165
-#define ICMD_IF_ACMPEQ        165       /* op1 = target JavaVM pc             */
-
-#define JAVA_IF_ACMPNE        166
-#define ICMD_IF_ACMPNE        166       /* op1 = target JavaVM pc             */
-
-#define JAVA_GOTO             167
-#define ICMD_GOTO             167       /* op1 = target JavaVM pc             */
-
-#define JAVA_JSR              168
-#define ICMD_JSR              168       /* op1 = target JavaVM pc             */
-
-#define JAVA_RET              169
-#define ICMD_RET              169       /* op1 = local variable               */
-
-#define JAVA_TABLESWITCH      170
-#define ICMD_TABLESWITCH      170       /* val.a = pointer to s4 table        */
-                                        /* length must be computed            */
-#define JAVA_LOOKUPSWITCH     171
-#define ICMD_LOOKUPSWITCH     171       /* val.a = pointer to s4 table        */
-                                        /* length must be computed            */
-#define JAVA_IRETURN          172
-#define ICMD_IRETURN          172
-
-#define JAVA_LRETURN          173
-#define ICMD_LRETURN          173
-
-#define JAVA_FRETURN          174
-#define ICMD_FRETURN          174
-
-#define JAVA_DRETURN          175
-#define ICMD_DRETURN          175
-
-#define JAVA_ARETURN          176
-#define ICMD_ARETURN          176
-
-#define JAVA_RETURN           177
-#define ICMD_RETURN           177
-
-#define JAVA_GETSTATIC        178
-#define ICMD_GETSTATIC        178       /* op1 = type, val.a = field address  */
-
-#define JAVA_PUTSTATIC        179
-#define ICMD_PUTSTATIC        179       /* op1 = type, val.a = field address  */
-
-#define JAVA_GETFIELD         180
-#define ICMD_GETFIELD         180       /* op1 = type, val.i = field offset   */
-
-#define JAVA_PUTFIELD         181
-#define ICMD_PUTFIELD         181       /* op1 = type, val.i = field offset   */
-
-#define JAVA_INVOKEVIRTUAL    182
-#define ICMD_INVOKEVIRTUAL    182       /* val.a = method info pointer        */
-
-#define JAVA_INVOKESPECIAL    183
-#define ICMD_INVOKESPECIAL    183       /* val.a = method info pointer        */
-
-#define JAVA_INVOKESTATIC     184
-#define ICMD_INVOKESTATIC     184       /* val.a = method info pointer        */
-
-#define JAVA_INVOKEINTERFACE  185
-#define ICMD_INVOKEINTERFACE  185       /* val.a = method info pointer        */
-
-/* UNDEF186 */
-
-#define JAVA_NEW              187
-#define ICMD_NEW              187       /* op1 = 1, val.a = class pointer     */
-
-#define JAVA_NEWARRAY         188
-#define ICMD_NEWARRAY         188       /* op1 = basic type                   */
-
-#define JAVA_ANEWARRAY        189
-#define ICMD_ANEWARRAY        189       /* op1 = 0, val.a = array pointer     */
-                                        /* op1 = 1, val.a = class pointer     */
-#define JAVA_ARRAYLENGTH      190
-#define ICMD_ARRAYLENGTH      190
-
-#define JAVA_ATHROW           191
-#define ICMD_ATHROW           191
-
-#define JAVA_CHECKCAST        192
-#define ICMD_CHECKCAST        192       /* op1 = 0, val.a = array pointer     */
-                                        /* op1 = 1, val.a = class pointer     */
-#define JAVA_INSTANCEOF       193
-#define ICMD_INSTANCEOF       193       /* op1 = 0, val.a = array pointer     */
-                                        /* op1 = 1, val.a = class pointer     */
-#define JAVA_MONITORENTER     194
-#define ICMD_MONITORENTER     194
-
-#define JAVA_MONITOREXIT      195
-#define ICMD_MONITOREXIT      195
-
-#define JAVA_WIDE             196
-
-#define JAVA_MULTIANEWARRAY   197
-#define ICMD_MULTIANEWARRAY   197       /* op1 = dimension, val.a = array     */
-                                        /* pointer                            */
-#define JAVA_IFNULL           198
-#define ICMD_IFNULL           198       /* op1 = target JavaVM pc             */
-
-#define JAVA_IFNONNULL        199
-#define ICMD_IFNONNULL        199       /* op1 = target JavaVM pc             */
-
-#define JAVA_GOTO_W           200
-
-#define JAVA_JSR_W            201
-
-#define JAVA_BREAKPOINT       202
-
-/* UNDEF203 */
-
-#define ICMD_IASTORECONST     204
-#define ICMD_LASTORECONST     205
-#define ICMD_FASTORECONST     206
-#define ICMD_DASTORECONST     207
-#define ICMD_AASTORECONST     208
-#define ICMD_BASTORECONST     209
-#define ICMD_CASTORECONST     210
-#define ICMD_SASTORECONST     211
-
-#define ICMD_PUTSTATICCONST   212
-#define ICMD_PUTFIELDCONST    213
-
-#define ICMD_IMULPOW2         214
-#define ICMD_LMULPOW2         215
+       ICMD_FCONST            = BC_fconst_0,
+
+       /* 12 */
+       /* 13 */
+
+       ICMD_DCONST            = BC_dconst_0,
+
+       ICMD_COPY              = 15,
+       ICMD_MOVE              = 16,
+
+       /* 17 */
+       /* 18 */
+       /* 19 */
+       /* 20 */
+
+       /* Order of LOAD instructions must be equal to order of TYPE_*
+          defines. */
+
+       ICMD_ILOAD            = BC_iload,
+       ICMD_LLOAD            = BC_lload,
+       ICMD_FLOAD            = BC_fload,
+       ICMD_DLOAD            = BC_dload,
+       ICMD_ALOAD            = BC_aload,
+
+       ICMD_IADDCONST        = 26,
+       ICMD_ISUBCONST        = 27,
+       ICMD_IMULCONST        = 28,
+       ICMD_IANDCONST        = 29,
+       ICMD_IORCONST         = 30,
+       ICMD_IXORCONST        = 31,
+
+       ICMD_ISHLCONST        = 32,
+       ICMD_ISHRCONST        = 33,
+       ICMD_IUSHRCONST       = 34,
+
+       ICMD_IREMPOW2         = 35,
+
+       ICMD_LADDCONST        = 36,
+       ICMD_LSUBCONST        = 37,
+       ICMD_LMULCONST        = 38,
+       ICMD_LANDCONST        = 39,
+       ICMD_LORCONST         = 40,
+       ICMD_LXORCONST        = 41,
+
+       ICMD_LSHLCONST        = 42,
+       ICMD_LSHRCONST        = 43,
+       ICMD_LUSHRCONST       = 44,
+
+       ICMD_LREMPOW2         = 45,
+
+       ICMD_IALOAD           = BC_iaload,
+       ICMD_LALOAD           = BC_laload,
+       ICMD_FALOAD           = BC_faload,
+       ICMD_DALOAD           = BC_daload,
+       ICMD_AALOAD           = BC_aaload,
+       ICMD_BALOAD           = BC_baload,
+       ICMD_CALOAD           = BC_caload,
+       ICMD_SALOAD           = BC_saload,
+
+       /* Order of STORE instructions must be equal to order of TYPE_*
+          defines. */
+
+       ICMD_ISTORE           = BC_istore,
+       ICMD_LSTORE           = BC_lstore,
+       ICMD_FSTORE           = BC_fstore,
+       ICMD_DSTORE           = BC_dstore,
+       ICMD_ASTORE           = BC_astore,
+
+       ICMD_IF_LEQ           = 59,
+       ICMD_IF_LNE           = 60,
+       ICMD_IF_LLT           = 61,
+       ICMD_IF_LGE           = 62,
+       ICMD_IF_LGT           = 63,
+       ICMD_IF_LLE           = 64,
+
+       ICMD_IF_LCMPEQ        = 65,
+       ICMD_IF_LCMPNE        = 66,
+       ICMD_IF_LCMPLT        = 67,
+       ICMD_IF_LCMPGE        = 68,
+       ICMD_IF_LCMPGT        = 69,
+       ICMD_IF_LCMPLE        = 70,
+
+       /* 71 */
+       /* 72 */
+       /* 73 */
+       /* 74 */
+       /* 75 */
+       /* 76 */
+       /* 77 */
+       /* 78 */
+
+       ICMD_IASTORE          = BC_iastore,
+       ICMD_LASTORE          = BC_lastore,
+       ICMD_FASTORE          = BC_fastore,
+       ICMD_DASTORE          = BC_dastore,
+       ICMD_AASTORE          = BC_aastore,
+       ICMD_BASTORE          = BC_bastore,
+       ICMD_CASTORE          = BC_castore,
+       ICMD_SASTORE          = BC_sastore,
+
+       ICMD_POP              = BC_pop,
+       ICMD_POP2             = BC_pop2,
+       ICMD_DUP              = BC_dup,
+       ICMD_DUP_X1           = BC_dup_x1,
+       ICMD_DUP_X2           = BC_dup_x2,
+       ICMD_DUP2             = BC_dup2,
+       ICMD_DUP2_X1          = BC_dup2_x1,
+       ICMD_DUP2_X2          = BC_dup2_x2,
+       ICMD_SWAP             = BC_swap,
+
+       ICMD_IADD             = BC_iadd,
+       ICMD_LADD             = BC_ladd,
+       ICMD_FADD             = BC_fadd,
+       ICMD_DADD             = BC_dadd,
+
+       ICMD_ISUB             = BC_isub,
+       ICMD_LSUB             = BC_lsub,
+       ICMD_FSUB             = BC_fsub,
+       ICMD_DSUB             = BC_dsub,
+
+       ICMD_IMUL             = BC_imul,
+       ICMD_LMUL             = BC_lmul,
+       ICMD_FMUL             = BC_fmul,
+       ICMD_DMUL             = BC_dmul,
+
+       ICMD_IDIV             = BC_idiv,
+       ICMD_LDIV             = BC_ldiv,
+       ICMD_FDIV             = BC_fdiv,
+       ICMD_DDIV             = BC_ddiv,
+
+       ICMD_IREM             = BC_irem,
+       ICMD_LREM             = BC_lrem,
+       ICMD_FREM             = BC_frem,
+       ICMD_DREM             = BC_drem,
+
+       ICMD_INEG             = BC_ineg,
+       ICMD_LNEG             = BC_lneg,
+       ICMD_FNEG             = BC_fneg,
+       ICMD_DNEG             = BC_dneg,
+
+       ICMD_ISHL             = BC_ishl,
+       ICMD_LSHL             = BC_lshl,
+       ICMD_ISHR             = BC_ishr,
+       ICMD_LSHR             = BC_lshr,
+       ICMD_IUSHR            = BC_iushr,
+       ICMD_LUSHR            = BC_lushr,
+
+       ICMD_IAND             = BC_iand,
+       ICMD_LAND             = BC_land,
+       ICMD_IOR              = BC_ior,
+       ICMD_LOR              = BC_lor,
+       ICMD_IXOR             = BC_ixor,
+       ICMD_LXOR             = BC_lxor,
+
+       ICMD_IINC             = BC_iinc,
+
+       ICMD_I2L              = BC_i2l,
+       ICMD_I2F              = BC_i2f,
+       ICMD_I2D              = BC_i2d,
+       ICMD_L2I              = BC_l2i,
+       ICMD_L2F              = BC_l2f,
+       ICMD_L2D              = BC_l2d,
+       ICMD_F2I              = BC_f2i,
+       ICMD_F2L              = BC_f2l,
+       ICMD_F2D              = BC_f2d,
+       ICMD_D2I              = BC_d2i,
+       ICMD_D2L              = BC_d2l,
+       ICMD_D2F              = BC_d2f,
+
+       ICMD_INT2BYTE         = BC_int2byte,
+       ICMD_INT2CHAR         = BC_int2char,
+       ICMD_INT2SHORT        = BC_int2short,
+
+       ICMD_LCMP             = BC_lcmp,
+       ICMD_FCMPL            = BC_fcmpl,
+       ICMD_FCMPG            = BC_fcmpg,
+       ICMD_DCMPL            = BC_dcmpl,
+       ICMD_DCMPG            = BC_dcmpg,
+
+       ICMD_IFEQ             = BC_ifeq,
+       ICMD_IFNE             = BC_ifne,
+       ICMD_IFLT             = BC_iflt,
+       ICMD_IFGE             = BC_ifge,
+       ICMD_IFGT             = BC_ifgt,
+       ICMD_IFLE             = BC_ifle,
+
+       ICMD_IF_ICMPEQ        = BC_if_icmpeq,
+       ICMD_IF_ICMPNE        = BC_if_icmpne,
+       ICMD_IF_ICMPLT        = BC_if_icmplt,
+       ICMD_IF_ICMPGE        = BC_if_icmpge,
+       ICMD_IF_ICMPGT        = BC_if_icmpgt,
+       ICMD_IF_ICMPLE        = BC_if_icmple,
+       ICMD_IF_ACMPEQ        = BC_if_acmpeq,
+       ICMD_IF_ACMPNE        = BC_if_acmpne,
+
+       ICMD_GOTO             = BC_goto,
+       ICMD_JSR              = BC_jsr,
+       ICMD_RET              = BC_ret,
+
+       ICMD_TABLESWITCH      = BC_tableswitch,
+       ICMD_LOOKUPSWITCH     = BC_lookupswitch,
+
+       ICMD_IRETURN          = BC_ireturn,
+       ICMD_LRETURN          = BC_lreturn,
+       ICMD_FRETURN          = BC_freturn,
+       ICMD_DRETURN          = BC_dreturn,
+       ICMD_ARETURN          = BC_areturn,
+       ICMD_RETURN           = BC_return,
+
+       ICMD_GETSTATIC        = BC_getstatic,
+       ICMD_PUTSTATIC        = BC_putstatic,
+       ICMD_GETFIELD         = BC_getfield,
+       ICMD_PUTFIELD         = BC_putfield,
+
+       ICMD_INVOKEVIRTUAL    = BC_invokevirtual,
+       ICMD_INVOKESPECIAL    = BC_invokespecial,
+       ICMD_INVOKESTATIC     = BC_invokestatic,
+       ICMD_INVOKEINTERFACE  = BC_invokeinterface,
+
+       /* 186 */
+
+       ICMD_NEW              = BC_new,
+       ICMD_NEWARRAY         = BC_newarray,
+       ICMD_ANEWARRAY        = BC_anewarray,
+
+       ICMD_ARRAYLENGTH      = BC_arraylength,
+
+       ICMD_ATHROW           = BC_athrow,
+
+       ICMD_CHECKCAST        = BC_checkcast,
+       ICMD_INSTANCEOF       = BC_instanceof,
+
+       ICMD_MONITORENTER     = BC_monitorenter,
+       ICMD_MONITOREXIT      = BC_monitorexit,
+
+       /* 196 */
+
+       ICMD_MULTIANEWARRAY   = BC_multianewarray,
+
+       ICMD_IFNULL           = BC_ifnull,
+       ICMD_IFNONNULL        = BC_ifnonnull,
+
+       /* 200 */
+       /* 201 */
+       /* 202 */
+
+       ICMD_IASTORECONST     = 204,
+       ICMD_LASTORECONST     = 205,
+       ICMD_FASTORECONST     = 206,
+       ICMD_DASTORECONST     = 207,
+       ICMD_AASTORECONST     = 208,
+       ICMD_BASTORECONST     = 209,
+       ICMD_CASTORECONST     = 210,
+       ICMD_SASTORECONST     = 211,
+
+       ICMD_PUTSTATICCONST   = 212,
+       ICMD_PUTFIELDCONST    = 213,
+
+       ICMD_IMULPOW2         = 214,
+       ICMD_LMULPOW2         = 215,
+
+       ICMD_INLINE_START     = 251,        /* instruction before inlined method  */
+       ICMD_INLINE_END       = 252,        /* instruction after inlined method   */
+       ICMD_INLINE_BODY      = 253,        /* start of inlined body              */
+
+       ICMD_BUILTIN          = 255         /* internal opcode                    */
+};
 
-#define ICMD_INLINE_START     251       /* instruction before inlined method  */
-#define ICMD_INLINE_END       252       /* instruction after inlined method   */
-#define ICMD_INLINE_BODY      253       /* start of inlined body              */
+/* Additional instruction accessors */
 
-#define ICMD_BUILTIN          255       /* internal opcode                    */
+methoddesc *instruction_call_site(const instruction *iptr);
 
+static inline bool instruction_has_dst(const instruction *iptr) {
+       if (
+               (icmd_table[iptr->opc].dataflow == DF_INVOKE) ||
+               (icmd_table[iptr->opc].dataflow == DF_BUILTIN)
+               ) {
+               return instruction_call_site(iptr)->returntype.type != TYPE_VOID;
+       } else {
+               return icmd_table[iptr->opc].dataflow >= DF_DST_BASE;
+       }
+}
 
 /***************************** register types *********************************/
 
index c8a7e64018f842de0644f8182ac6975b6ac1e66a..835fea314f8d61f05eb41c73e9bff4828b439233 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/jit/linenumbertable.c - linenumber handling stuff
 
    Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -99,10 +99,13 @@ void linenumbertable_create(jitdata *jd)
        /* Fill the linenumber table entries in reverse order, so the
           search can be forward. */
 
+       /* FIXME I only made this change to prevent a problem when moving
+          to C++. This should be changed back when this file has
+          converted to C++. */
+
        pv = ADDR_MASK(uint8_t *, code->entrypoint);
 
-       for (le = list_last_unsynced(l); le != NULL;
-                le = list_prev_unsynced(l, le), lnte++) {
+       for (le = list_first(l); le != NULL; le = list_next(l, le), lnte++) {
                /* If the entry contains an mcode pointer (normal case),
                   resolve it (see doc/inlining_stacktrace.txt for
                   details). */
@@ -143,7 +146,7 @@ void linenumbertable_list_entry_add(codegendata *cd, int32_t linenumber)
        le->linenumber = linenumber;
        le->mpc        = cd->mcodeptr - cd->mcodebase;
 
-       list_add_last_unsynced(cd->linenumbers, le);
+       list_add_first(cd->linenumbers, le);
 }
 
 
@@ -169,7 +172,7 @@ void linenumbertable_list_entry_add_inline_start(codegendata *cd, instruction *i
        le->linenumber = (-2); /* marks start of inlined method */
        le->mpc        = (mpc = cd->mcodeptr - cd->mcodebase);
 
-       list_add_last_unsynced(cd->linenumbers, le);
+       list_add_first(cd->linenumbers, le);
 
        insinfo = iptr->sx.s23.s3.inlineinfo;
 
@@ -206,7 +209,7 @@ void linenumbertable_list_entry_add_inline_end(codegendata *cd, instruction *ipt
        le->linenumber = (-3) - iptr->line;
        le->mpc        = (uintptr_t) insinfo->method;
 
-       list_add_last_unsynced(cd->linenumbers, le);
+       list_add_first(cd->linenumbers, le);
 
        le = DNEW(linenumbertable_list_entry_t);
 
@@ -214,7 +217,7 @@ void linenumbertable_list_entry_add_inline_end(codegendata *cd, instruction *ipt
        le->linenumber = (-1);
        le->mpc        = insinfo->startmpc;
 
-       list_add_last_unsynced(cd->linenumbers, le);
+       list_add_first(cd->linenumbers, le);
 }
 
 
index 62d3015899b299e9a024f89335f154a5ba051b5a..925cf2405b51aaf03349f4a7c39149e1c305c9bc 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vm/jit/linenumbertable.h - linenumber table
 
    Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
index 67f06a1f3b478e6302b60a19772f26b9ea698bb5..43a7dad53c6e7c8558b960f94509082155f61706 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/loop/analyze.c - bound check removal 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: Christopher Kruegel
-
-   Changes: Christian Thalinger
-
-   Contains the functions which perform the bound check removals. With
-   the loops identified, these functions scan the code for array
-   accesses that take place in loops and try to guarantee that their
-   bounds are never violated. The function to call is
-   optimize_loops().
-
 */
 
 
 
 #include "mm/memory.h"
 #include "toolbox/logging.h"
+
 #include "vm/jit/jit.h"
+#include "vm/jit/stack.h"
+
 #include "vm/jit/loop/analyze.h"
 #include "vm/jit/loop/graph.h"
 #include "vm/jit/loop/loop.h"
@@ -1520,8 +1509,8 @@ int insert_static(methodinfo *m, codegendata *cd, loopdata *ld, int arrayRef, st
 
 /*     copy a stack and return the start pointer of the newly created one
 */
-stackptr copy_stack_from(stackptr source) { 
-       stackptr current, top;
+stackelement_t* copy_stack_from(stackelement_t* source) { 
+       stackelement_t* current, top;
 
        if (source == NULL)
                return NULL;
@@ -1561,7 +1550,7 @@ stackptr copy_stack_from(stackptr source) {
 
    inst: pointer to the new instruction
    tos: stackpointer before this operation is executed
-   newstack: temporary stackptr
+   newstack: temporary stackelement_t*
    stackdepth: counts the current stackdepth
    original start: blockpointer to the head of the new, optimized loop 
 */
@@ -2588,7 +2577,7 @@ void create_static_checks(methodinfo *m, codegendata *cd, loopdata *ld, struct L
 
        /* tos and newstack are needed by the macros, that insert instructions into */
        /* the new loop head                                                        */
-       stackptr newstack, tos;
+       stackelement_t* newstack, tos;
        exceptiontable *ex;
 
        /* prevent some compiler warnings */
index 8aaf6a7ae55b4c821bdd5e17dd9e2a5a2873a752..eb3c1f4aca3e7e711a278df17f2b0d655600ab87 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/m68k/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.
 ##
@@ -34,15 +32,15 @@ AM_CCASFLAGS = $(AM_CPPFLAGS)
 LIBS =
 
 noinst_HEADERS = \
-        arch.h \
-        machine-instr.h
+       arch.h \
+       machine-instr.h
 
 noinst_LTLIBRARIES = \
        libarch.la
 
 if ENABLE_DISASSEMBLER
 DISASS_SOURCES = \
-         disass.c
+       disass.c
 endif
 
 libarch_la_SOURCES = \
@@ -51,8 +49,11 @@ libarch_la_SOURCES = \
        codegen.h \
        $(DISASS_SOURCES) \
        emit.c \
+       patcher.c \
+       \
+       md-trap.h \
        md.c \
-       patcher.c
+       md.h
 
 libarch_la_LIBADD = \
        $(OS_DIR)/libmd.la
index 2d1ed85465ed3746d80a0c31405b24246b514d42..7441e256d7cb04f7b1c2a552f6c904e04e0c62d1 100644 (file)
 
 #define SPECIALMEMUSE
 #define JIT_COMPILER_VIA_SIGNAL
-/* #define HAS_4BYTE_STACKSLOT */
 /* #define SUPPORT_COMBINE_INTEGER_REGISTERS */
 
 #endif /* _ARCH_H */
index 1a6ee282740e4d7fb408a7870f9cfe7618d1af73..25ea601e87978856510a16e48e7057291af8d620 100644 (file)
@@ -91,8 +91,8 @@ asm_vm_call_method_double:
        movel   %sp@(12*4+2*4),%a2                              /* arg array */
        movel   %sp@(12*4+3*4),%d2                              /* arg count */
 
-       movel   %a3, %sp@(12*4)                                 /* copy method address to stackslot */
-       leal    %sp@(12*4), %a3                                 /* and store that address in %a3 */
+       movel   %a3, %sp@(11*4)                                 /* copy method address to stackslot */
+       leal    %sp@(11*4), %a3                                 /* and store that address in %a3 */
 #else
        addal #(-12*4-6*8), %sp
        moveml  %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@        /* save registers */
@@ -103,8 +103,8 @@ asm_vm_call_method_double:
        movel   %sp@(12*4+6*8+2*4),%a2                          /* arg array */
        movel   %sp@(12*4+6*8+3*4),%d2                          /* arg count */
 
-       movel   %a3, %sp@(12*4+6*8)                                     /* copy method address to stackslot */
-       leal    %sp@(12*4+6*8), %a3                                     /* and store that address in %a3 */
+       movel   %a3, %sp@(11*4+6*8)                                     /* copy method address to stackslot */
+       leal    %sp@(11*4+6*8), %a3                                     /* and store that address in %a3 */
 #endif
 
        moveal  %sp, %a5                                        /* memorize stack */
index 2b3ae563dc142e8225f26d7ceec344e3d34636c6..41bd7c7f7f83e459c527546e81fe368a01bbdf8b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/m68k/codegen.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.
 
@@ -31,7 +29,6 @@
 #include <stdint.h>
 
 #include "md-abi.h"
-#include "md-os.h"
 
 #include "vm/types.h"
 #include "vm/jit/m68k/codegen.h"
@@ -62,6 +59,7 @@
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
@@ -254,13 +252,13 @@ bool codegen_emit(jitdata *jd)
        /* call lock_monitor_enter function */
        if (checksync && code_is_synchronized(code))    {
                if (m->flags & ACC_STATIC)      {
-                       M_AMOV_IMM((&m->class->object.header), REG_ATMP1);
+                       M_AMOV_IMM((&m->clazz->object.header), REG_ATMP1);
                } else  {
                        /* for non-static case the first arg is the object */
                        M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
                        M_ATST(REG_ATMP1);
                        M_BNE(2);
-                       M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_TRAP(TRAP_NullPointerException);
                }
 
                M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
@@ -1119,8 +1117,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = (intptr_t) fi->value;
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
                                                                                0);
                                }
                        }
@@ -1173,8 +1171,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = (intptr_t) fi->value;
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
                                                                                0);
                        }
                
@@ -1734,8 +1732,8 @@ bool codegen_emit(jitdata *jd)
                                                s1 = 0;
                                                s2 = 0;
                                        } else {
-                                               s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
-                                               s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                               s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index;
+                                               s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                        }
                                        /* load object pointer (==argument 0) */
                                        M_ALD(REG_ATMP1, REG_SP, 0);
@@ -2412,25 +2410,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        (void) dseg_add_unique_s4(cd, 0);                              /* IntSave         */
        (void) dseg_add_unique_s4(cd, 0);                              /* FltSave         */
 
-       /* print call trace */
-#if !defined(NDEBUG)
-       if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
-               emit_verbosecall_enter(jd);
-       }
-#endif
-
        /* generate code */
        M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
 
-       /* get function address (this must happen before the stackframeinfo) */
-       if (f == NULL)  {
-               patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, 0);
-       }
-
-       M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
-
-       M_AST(REG_ATMP2, REG_SP, 4 * 4);
-
        /* put arguments for codegen_start_native_call onto stack */
        /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
        
@@ -2448,9 +2430,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        if (m->flags & ACC_STATIC)
                M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
 
-       /* load function pointer */
-       M_ALD(REG_ATMP2, REG_SP, 4 * 4);
-
        /* copy arguments into stackframe */
        for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j)       {
                t = md->paramtypes[i].type;
@@ -2469,15 +2448,19 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
                }
        }
 
-       /* for static function class as second arg */
-       if (m->flags & ACC_STATIC)
-               M_AST(REG_ATMP3, REG_SP, 1 * 4);
+       /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */
+       if (m->flags & ACC_NATIVE)      {
+               /* for static function class as second arg */
+               if (m->flags & ACC_STATIC)
+                       M_AST(REG_ATMP3, REG_SP, 1 * 4);
 
-       /* env ist first argument */
-       M_AMOV_IMM(_Jv_env, REG_ATMP1);
-       M_AST(REG_ATMP1, REG_SP, 0 * 4);
+               /* env ist first argument */
+               M_AMOV_IMM(_Jv_env, REG_ATMP1);
+               M_AST(REG_ATMP1, REG_SP, 0 * 4);
+       }
 
        /* call the native function */
+       M_AMOV_IMM(f, REG_ATMP2);
        M_JSR(REG_ATMP2);
 
        /* save return value */
@@ -2498,13 +2481,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                default: assert(0);
        }
-       
-       /* print call trace */
-#if ! defined(NDEBUG)
-       if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
-               emit_verbosecall_exit(jd);
-       }
-#endif
+
        /* remove native stackframe info */
        /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
 
@@ -2562,9 +2539,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
        /* should never be reached from within jit code*/
        M_JSR_IMM(0);
-
-       /* generate patcher stub call code */
-       emit_patcher_traps(jd);
 }
 
 
index 8d5ff5b02837de2000ac73f9ae1643b8d117aba3..689dd9b6a64b9ed3873809bcae88796ed0a54ab8 100644 (file)
@@ -67,7 +67,7 @@
 
 /* stub defines ***************************************************************/
 
-#define COMPILERSTUB_CODESIZE (6+6+2)
+#define COMPILERSTUB_CODESIZE (2+2)
 
 
 /* coldfire instruction format:
index 3e8b52f2b9bbdf5c83c081f611845a55246867f6..0b48ac636c1af9d0872cc588e17954fd0e7466a9 100644 (file)
 
 #include <assert.h>
 
-#include "emit.h"
-#include "vm/jit/emit-common.h"
-#include "vm/exceptions.h"
-#include "vm/jit/asmpart.h"
-#include "vm/builtin.h"
-#include "vm/jit/trace.h"
+#include "vm/jit/m68k/codegen.h"
+#include "vm/jit/m68k/emit.h"
 
 #include "mm/memory.h"
 
-#include "threads/lock-common.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/trap.h"
 
-#include "codegen.h"
-#include "md-os.h"
 
 /* emit_mov_imm_reg **************************************************************************
  *
@@ -149,7 +149,7 @@ void emit_copy(jitdata *jd, instruction *iptr)
 
 *******************************************************************************/
 
-inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
+void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
 
@@ -587,7 +587,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
                        vm_abort("emit_classcast_check: unknown condition %d", condition);
                }
                M_TRAP_SETREGISTER(s1);
-               M_TRAP(EXCEPTION_HARDWARE_CLASSCAST);
+               M_TRAP(TRAP_ClassCastException);
        }
 }
 
@@ -603,7 +603,7 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1,
                M_ICMP(s2, REG_ITMP3);
                M_BHI(4);
                M_TRAP_SETREGISTER(s2);
-               M_TRAP(EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+               M_TRAP(TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -619,8 +619,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_ITST(REG_RESULT);
                M_BNE(2);
-               /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);*/
-               M_TRAP(EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_TRAP(TRAP_ArrayStoreException);
        }
 }
 
@@ -630,6 +629,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
    Emit a NullPointerException check.
 
 *******************************************************************************/
+
 void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
 {
        if (INSTRUCTION_MUST_CHECK(iptr)) {
@@ -637,7 +637,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
                 * invocation at the beginning of codegen.c */
                M_ATST(reg);
                M_BNE(2);
-               M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
+               M_TRAP(TRAP_NullPointerException);
        }
 }
 
@@ -652,7 +652,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_ITST(reg);
                M_BNE(2);
-               M_TRAP(EXCEPTION_HARDWARE_ARITHMETIC);
+               M_TRAP(TRAP_ArithmeticException);
        }
 }
 
@@ -666,8 +666,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_ITST(REG_RESULT);
                M_BNE(2);
-               /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);*/
-               M_TRAP(EXCEPTION_HARDWARE_EXCEPTION);
+               M_TRAP(TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -680,7 +679,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 void emit_trap_compiler(codegendata *cd)
 {
        M_TRAP_SETREGISTER(REG_METHODPTR);
-       M_TRAP(EXCEPTION_HARDWARE_COMPILER);
+       M_TRAP(TRAP_COMPILER);
 }
 
 
@@ -699,7 +698,7 @@ uint32_t emit_trap(codegendata *cd)
 
        mcode = *((uint32_t *) cd->mcodeptr);
 
-       M_TRAP(EXCEPTION_HARDWARE_PATCHER);
+       M_TRAP(TRAP_PATCHER);
 
        return mcode;
 }
index 508ce9b49715edba1c23fa50afea6ce640922965..170c0f6c86fc5d13c70c02757a821d2b6e97f787 100644 (file)
@@ -1,9 +1,7 @@
-## src/vm/jit/powerpc64/linux/Makefile.am
+## src/vm/jit/m68k/linux/Makefile.am
 ##
-## 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.
 ##
 ## 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
-##
-## Changes:
 
-## Process this file with automake to produce Makefile.in
 
 AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)
 
@@ -37,12 +28,12 @@ LIBS =
 noinst_HEADERS = \
        md-asm.h
 
-noinst_LTLIBRARIES = libmd.la
+noinst_LTLIBRARIES = \
+       libmd.la
 
 libmd_la_SOURCES = \
        md-abi.c \
        md-abi.h \
-       md-os.h \
        md-os.c
 
 
index c8f5b77282f7b4ff7fe1ea6108fb8b8baf0f0099..cea5faea8ee3ba237592ff9f7d000cbbc625a6a4 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/m68k/linux/md-abi.c - linux specific abi 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.
 
@@ -89,8 +87,25 @@ const s4 abi_registers_float_temporary[]     = {0,1};
 
 void md_param_alloc_native(methoddesc *md)
 {
-               /* For now use system ABI */
-               md_param_alloc(md);
+       paramdesc       *pd;
+       s4      stacksize;
+       s4      i;
+
+       pd = md->params;
+       stacksize = 0;
+
+       for (i=0; i<md->paramcount; i++, pd++)  {
+               pd->inmemory = true;
+               pd->regoff = stacksize * 4;
+               pd->index = stacksize;
+               stacksize += IS_2_WORD_TYPE(md->paramtypes[i].type) ? 2:1;
+       }
+
+       md->memuse = stacksize;
+       md->argintreguse = 0;
+       md->argfltreguse = 0;
+       md->argadrreguse = 0;
+
 }
 
 
@@ -122,7 +137,8 @@ void md_param_alloc(methoddesc *md)
        for (i=0; i<md->paramcount; i++, pd++)  {
                pd->inmemory = true;
                pd->regoff = stacksize * 8;
-/*             stacksize += IS_2_WORD_TYPE(md->paramtypes[i].type) ? 2:1;*/
+               pd->index = stacksize;
+               stacksize ++;
        }
 
        md->memuse = stacksize;
@@ -138,7 +154,7 @@ void md_param_alloc(methoddesc *md)
    %d0 for all word types %d0-%d1 for 2 word types. %f0-%f1 for floats/doubles
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
 { 
 
 /* The Problem: %a0, %a1, %d0 and %d1 are scratch registers by platform abi
index d29faa6fa585efaba859a489cd788b981ee3d646..444f55c97edbeecc184ff9100fc27ebce2e86f60 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/m68k/linux/md-os.c - linux specific functions
+/* src/vm/jit/m68k/linux/md-os.c - m68k linux specific 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"
 
-#include "md-os.h"
-#include "md-abi.h"
+#include "vm/jit/m68k/md.h"
+#include "vm/jit/m68k/linux/md-abi.h"
 
-#include "vm/vm.h"
 #include "vm/exceptions.h"
-#include "vm/jit/asmpart.h"
 #include "vm/signallocal.h"
+#include "vm/vm.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/trap.h"
 
 #include <assert.h>
 #include <stdlib.h>
@@ -73,6 +74,7 @@ typedef struct actual_ucontext {
  * Invoked when a Nullpointerexception occured, or when the vm 
  * crashes, hard to tell the difference. 
  **********************************************************************/
+
 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 {      
        uint32_t        xpc, sp;
@@ -82,7 +84,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        void        *p;
        actual_mcontext_t       *_mc;
        actual_ucontext_t       *_uc;
-
+       int type;
 
        _uc = (actual_ucontext_t*)_p;
        _mc = &_uc->uc_mcontext;
@@ -120,24 +122,18 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
        /* val is now register number, adreg == true if it is an address regsiter */
        regval = _mc->gregs[adrreg ? GREGS_ADRREG_OFF + val : val];
-       /*
-       if (regval != 0)        {
-               vm_abort("md_signal_handler_sigsegv: faulting address is not NULL: addr=%p", regval);
-       }*/
-
-
-       /*fprintf(stderr, "SEGV: sp=%x, xpc=%x, regval=%x\n", sp, xpc, regval);
-       */
+       type   = regval;
 
        /* Handle the type. */
 
-       p = signal_handle(EXCEPTION_HARDWARE_NULLPOINTER, regval, NULL, (void*)sp, (void*)xpc, (void*)xpc, _p);
+       p = trap_handle(type, regval, NULL, (void*)sp, (void*)xpc, (void*)xpc, _p);
 
        _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1]     = (intptr_t) p;
        _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (intptr_t) xpc;
        _mc->gregs[R_PC]                             = (intptr_t) asm_handle_exception;
 }
 
+
 /* md_signal_handler_sigill *******************************************
  *
  * This handler is used to generate hardware exceptions.
@@ -146,6 +142,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
  * been created directly before the trap instruction (2 bytes long).
  * the last 3 bit of this tst instruction contain the register number.
  **********************************************************************/
+
 void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
 {
        uint32_t        xpc, sp, ra, pv;
@@ -180,26 +177,27 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
        /* Figure out in which register the object causing the exception resides for appropiate exceptions
         */
        switch (type)   {
-               case EXCEPTION_HARDWARE_ARITHMETIC:
-               case EXCEPTION_HARDWARE_EXCEPTION:
+               case TRAP_NullPointerException:
+               case TRAP_ArithmeticException:
+               case TRAP_CHECK_EXCEPTION:
                        /* nothing */
                        break;
-               case EXCEPTION_HARDWARE_CLASSCAST: 
+
+               case TRAP_ClassCastException: 
                        regval = *(uint16_t*)(xpc-4);
                        assert( (regval&0xfff0) == 0x4a00 );
                        /* was in a address register */
                        regval = _mc->gregs[ GREGS_ADRREG_OFF + (regval & 0x7) ];
                        break;
-               case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
+
+               case TRAP_ArrayIndexOutOfBoundsException:
                        regval = *(uint16_t*)(xpc-4);
                        assert( (regval&0xfff0) == 0x4a00 );
                        /* was a data register */
                        regval = _mc->gregs[regval & 0x7];
                        break;
-               case M68K_EXCEPTION_HARDWARE_NULLPOINTER:
-                       type = EXCEPTION_HARDWARE_NULLPOINTER;
-                       break;
-               case EXCEPTION_HARDWARE_COMPILER:
+
+               case TRAP_COMPILER:
                        regval = *(uint16_t*)(xpc-4);
                        assert( (regval&0xfff0) == 0x4a00 );
                        /* was in a address register */
@@ -210,54 +208,52 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
                        sp = sp + SIZEOF_VOID_P;
                        xpc = ra - 2;
                        break;
-               case EXCEPTION_HARDWARE_PATCHER:
+
+               case TRAP_PATCHER:
                        xpc -= 2;
                        ra = xpc;
                        break;
-
-               default: assert(0);
        }
 
-       /*fprintf(stderr, "NEW HWE: sp=%x, xpc=%x, tpye=%x, regval=%x\n", sp, xpc, type, regval);
-       */
-
-       /* Handle the type. */
-       p = signal_handle(type, regval, pv, (void*)sp, (void*)ra, (void*)xpc, _p);
+       /* Handle the trap. */
 
+       p = trap_handle(type, regval, pv, (void*)sp, (void*)ra, (void*)xpc, _p);
 
        switch (type)   {
-               case EXCEPTION_HARDWARE_COMPILER:
-                       if (p == NULL)  {
-                               /* exception when compiling the method */
-                               java_object_t *o = exceptions_get_and_clear_exceptions();
+       case TRAP_COMPILER:
+               if (p == NULL) {
+                       /* exception when compiling the method */
+                       java_object_t *o = builtin_retrieve_exception();
 
-                               _mc->gregs[R_SP] = sp;  /* remove RA from stack */
+                       _mc->gregs[R_SP] = sp;  /* remove RA from stack */
 
-                               _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1]     = (intptr_t) o;
-                               _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (intptr_t) xpc;
-                               _mc->gregs[R_PC]                             = (intptr_t) asm_handle_exception;
+                       _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1]     = (uintptr_t) o;
+                       _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (uintptr_t) xpc;
+                       _mc->gregs[R_PC]                             = (uintptr_t) asm_handle_exception;
+               }
+               else {
+                       /* compilation ok, execute */
+                       _mc->gregs[R_PC] = p;
+               }
+               break;
 
-                       } else  {
-                               /* compilation ok, execute */
-                               _mc->gregs[R_PC] = p;
-                       }
-                       break;
+       case TRAP_PATCHER:
+               if (p == NULL) { 
+                       /* No exception while patching, continue. */
+                       _mc->gregs[R_PC] = xpc; 
+                       return; 
+               }
+               /* fall-through in case of exception */
 
-               case EXCEPTION_HARDWARE_PATCHER:
-                       if (p == NULL) { 
-                               /* no expcetion while patching, continue */
-                               _mc->gregs[R_PC] = xpc; 
-                               return; 
-                       }
-                       /* fall-through in case of exception */
-               default:
-                       /* a normal exception with normal expcetion handling */
-                       _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1]     = (intptr_t) p;
-                       _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (intptr_t) xpc;
-                       _mc->gregs[R_PC]                             = (intptr_t) asm_handle_exception;
+       default:
+               /* a normal exception with normal expcetion handling */
+               _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1]     = (uintptr_t) p;
+               _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (uintptr_t) xpc;
+               _mc->gregs[R_PC]                             = (uintptr_t) asm_handle_exception;
        }
 }
 
+
 /* md_signal_handler_sigusr1 ***************************************************
 
    Signal handler for suspending threads.
diff --git a/src/vm/jit/m68k/linux/md-os.h b/src/vm/jit/m68k/linux/md-os.h
deleted file mode 100644 (file)
index d83c165..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* src/vm/jit/m68k/linux/md-os.h - linux specific 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
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public 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 trap #0 is reserved and will not be delivered to signal handler */
-#define M68K_EXCEPTION_HARDWARE_NULLPOINTER 14
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of 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 2f9fa6fae4ca0c223459c3eaf01872664737e51d..021e723b91d0030bc07dd663c8853b9d820e2765 100644 (file)
@@ -41,7 +41,6 @@ static inline long compare_and_swap(long *p, long oldval, long newval)
 
 
 #define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
 #define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
 #define MEMORY_BARRIER() __asm__ __volatile__ ( "" : : : "memory" );
 
diff --git a/src/vm/jit/m68k/md-trap.h b/src/vm/jit/m68k/md-trap.h
new file mode 100644 (file)
index 0000000..69a15a3
--- /dev/null
@@ -0,0 +1,69 @@
+/* src/vm/jit/m68k/md-trap.h - m68k hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * The trap #0 is reserved and will not be delivered to signal
+ * handler, so we skip this one.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    0
+
+enum {
+       /* Skip 0 because it's a reserved trap. */
+
+       TRAP_NullPointerException           = 1,
+       TRAP_ArithmeticException            = 2,
+       TRAP_ArrayIndexOutOfBoundsException = 3,
+       TRAP_ArrayStoreException            = 4,
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+       TRAP_COMPILER                       = 8
+};
+
+#endif /* _MD_TRAP_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 b9b6e33bff92d044ea401a8cfcf935f44c8524c1..9fb12da0c144ba32773430e615448de7fc377bd5 100644 (file)
@@ -111,6 +111,35 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr)
        return pa;
 }
 
+void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
+{
+       void *ra;
+
+       /* return address is above stackpointer */
+
+       ra = *((void **) (((uintptr_t) sp) + stackframesize));
+       
+       /* XXX: This helps for now, but it's a ugly hack
+        * the problem _may_ be: the link instruction is used
+        * by some gcc generated code, and we get an additional word
+        * on the stack, the old framepointer. Its address is somewhere
+        * near sp, but that all depends the code generated by the compiler.
+        * I'm unsure about a clean solution.
+        */
+#if 0
+       if (!(ra > 0x40000000 && ra < 0x80000000))      {
+               ra = *((u1**)(sp + framesize + 4));
+       }
+#endif
+
+       /* assert(ra > 0x40000000 && ra < 0x80000000);
+       printf("XXXXXX=%x\n", ra);
+        */
+
+       return ra;
+}
+
+
 
 /*
  * These are local overrides for various environment variables in Emacs.
index de87abbb124ba0fca88d420b5c1bbcb9943a86dd..bc64f4c73587868764b66054f8b02db2dbde342b 100644 (file)
@@ -34,6 +34,7 @@
 #include <stdint.h>
 
 #include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
 
 
 /* md_stacktrace_get_returnaddress *********************************************
 
 *******************************************************************************/
 
-inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize)
-{
-       void *ra;
-
-       /* return address is above stackpointer */
-
-       ra = *((void **) (((uintptr_t) sp) + stackframesize));
-       
-       /* XXX: This helps for now, but it's a ugly hack
-        * the problem _may_ be: the link instruction is used
-        * by some gcc generated code, and we get an additional word
-        * on the stack, the old framepointer. Its address is somewhere
-        * near sp, but that all depends the code generated by the compiler.
-        * I'm unsure about a clean solution.
-        */
-#if 0
-       if (!(ra > 0x40000000 && ra < 0x80000000))      {
-               ra = *((u1**)(sp + framesize + 4));
-       }
-#endif
-
-       /* assert(ra > 0x40000000 && ra < 0x80000000);
-       printf("XXXXXX=%x\n", ra);
-        */
-
-       return ra;
-}
+void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframesize);
 
 
 /* md_codegen_get_pv_from_pc ***************************************************
 
-   On this architecture just a wrapper function to
-   codegen_get_pv_from_pc.
+   On this architecture just a wrapper function to methodtree_find.
 
 *******************************************************************************/
 
@@ -83,7 +57,7 @@ inline static void *md_codegen_get_pv_from_pc(void *ra)
 {
        void *pv;
 
-       pv = codegen_get_pv_from_pc(ra);
+       pv = methodtree_find(ra);
 
        return pv;
 }
index e304865cf8a8dc8d93560509dd9da1b3ad3f1200..71607c7f42010a38a489cde522f59c4533c31759 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/m68k/patcher.c - m68k patcher 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.
 
@@ -244,8 +242,8 @@ bool patcher_get_putstatic(patchref_t *pr)
                return false;
 
        /* check if the field's class is initialized */
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        /* patch back original code */
@@ -610,13 +608,13 @@ bool patcher_invokeinterface(patchref_t *pr)
        assert( *((uint32_t*)ra) == 0x246f0000 );
 
        /* patch interfacetable index (first #0) */
-       disp = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * m->class->index;
+       disp = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * m->clazz->index;
        /* XXX this disp is negative, check! 
         * assert( (disp & 0x0000ffff) == disp);*/
        *((uint16_t *) (ra + 5 * 2)) = disp;
 
        /* patch method offset (second #0) */
-       disp = sizeof(methodptr) * (m - m->class->methods);
+       disp = sizeof(methodptr) * (m - m->clazz->methods);
        assert( (disp & 0x0000ffff) == disp);
        *((uint16_t *) (ra + 7 * 2)) = disp;
 
diff --git a/src/vm/jit/methodtree.c b/src/vm/jit/methodtree.c
new file mode 100644 (file)
index 0000000..262804e
--- /dev/null
@@ -0,0 +1,248 @@
+/* src/vm/jit/methodtree.c - AVL tree of methods
+
+   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 "mm/memory.h"
+
+#include "threads/thread.h"
+
+#include "toolbox/avl.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/methodtree.h"
+
+
+/* methodtree_element *********************************************************/
+
+typedef struct methodtree_element_t methodtree_element_t;
+
+struct methodtree_element_t {
+       void *startpc;
+       void *endpc;
+};
+
+
+/* in this tree we store all method addresses *********************************/
+
+static avl_tree_t *methodtree = NULL;
+
+
+/* static functions ***********************************************************/
+
+static int methodtree_comparator(const void *treenode, const void *node);
+
+
+/* methodtree_init *************************************************************
+
+   Initialize the global method tree.
+
+*******************************************************************************/
+
+void methodtree_init(void)
+{
+#if defined(ENABLE_JIT)
+       methodtree_element_t *mte;
+#endif
+
+       methodtree = avl_create(&methodtree_comparator);
+
+#if defined(ENABLE_JIT)
+       /* Insert asm_vm_call_method. */
+
+       mte = NEW(methodtree_element_t);
+
+       mte->startpc = (u1 *) (ptrint) asm_vm_call_method;
+       mte->endpc   = (u1 *) (ptrint) asm_vm_call_method_end;
+
+       avl_insert(methodtree, mte);
+#endif
+}
+
+
+/* methodtree_comparator *******************************************************
+
+   Comparator function used for the AVL tree of methods.
+
+   ARGUMENTS:
+       treenode ... the node from the tree
+       node ....... the node to compare to the tree-node
+
+   RETURN VALUE:
+       0 .... found
+       -1 ... go left
+       1 .... go right
+
+*******************************************************************************/
+
+static int methodtree_comparator(const void *treenode, const void *node)
+{
+       methodtree_element_t *mte;
+       methodtree_element_t *mtepc;
+
+       mte   = (methodtree_element_t *) treenode;
+       mtepc = (methodtree_element_t *) node;
+
+       /* compare both startpc and endpc of pc, even if they have the same value,
+          otherwise the avl_probe sometimes thinks the element is already in the
+          tree */
+
+#ifdef __S390__
+       /* On S390 addresses are 31 bit. Compare only 31 bits of value.
+        */
+#      define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
+#else
+#      define ADDR_MASK(a) (a)
+#endif
+
+       if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
+               ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
+               ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
+               ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
+               return 0;
+
+       } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
+               return -1;
+
+       } else {
+               return 1;
+       }
+
+#      undef ADDR_MASK
+}
+
+
+/* methodtree_insert ***********************************************************
+
+   Insert the machine code range of a method into the AVL tree of
+   methods.
+
+   ARGUMENTS:
+       startpc ... start address of the method
+          endpc ..... end address of the method
+
+*******************************************************************************/
+
+void methodtree_insert(void *startpc, void *endpc)
+{
+       methodtree_element_t *mte;
+
+       /* Allocate new method entry. */
+
+       mte = NEW(methodtree_element_t);
+
+       mte->startpc = startpc;
+       mte->endpc   = endpc;
+
+       /* This function does not return an error, but asserts for
+          duplicate entries. */
+
+       avl_insert(methodtree, mte);
+}
+
+
+/* methodtree_find *************************************************************
+
+   Find the PV for the given PC by searching in the AVL tree of
+   methods.
+
+*******************************************************************************/
+
+void *methodtree_find(void *pc)
+{
+       void *pv;
+
+       /* Try to find a method. */
+
+       pv = methodtree_find_nocheck(pc);
+
+       if (pv == NULL) {
+               /* No method was found.  Let's dump a stacktrace. */
+
+#if defined(ENABLE_VMLOG)
+               vmlog_cacao_signl("SIGSEGV");
+#endif
+
+               log_println("We received a SIGSEGV and tried to handle it, but we were");
+               log_println("unable to find a Java method at:");
+               log_println("");
+#if SIZEOF_VOID_P == 8
+               log_println("PC=0x%016lx", pc);
+#else
+               log_println("PC=0x%08x", pc);
+#endif
+               log_println("");
+
+               log_println("Dumping the current stacktrace:");
+
+               stacktrace_print_current();
+
+               vm_abort("Exiting...");
+       }
+
+       return pv;
+}
+
+
+/* methodtree_find_nocheck *****************************************************
+
+   Find the PV for the given PC by searching in the AVL tree of
+   methods.  This method does not check the return value and is used
+   by the profiler.
+
+*******************************************************************************/
+
+void *methodtree_find_nocheck(void *pc)
+{
+       methodtree_element_t  mtepc;
+       methodtree_element_t *mte;
+
+       mtepc.startpc = pc;
+       mtepc.endpc   = pc;
+
+       mte = avl_find(methodtree, &mtepc);
+
+       if (mte == NULL)
+               return NULL;
+       else
+               return mte->startpc;
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of 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/methodtree.h b/src/vm/jit/methodtree.h
new file mode 100644 (file)
index 0000000..e2be220
--- /dev/null
@@ -0,0 +1,58 @@
+/* src/vm/jit/methodtree.h - AVL tree of methods
+
+   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 _METHODTREE_H
+#define _METHODTREE_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "toolbox/avl.h"
+
+
+/* function prototypes ********************************************************/
+
+void  methodtree_init(void);
+void  methodtree_insert(void *startpc, void *endpc);
+void *methodtree_find(void *pc);
+void *methodtree_find_nocheck(void *pc);
+
+#endif /* _METHODTREE_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 c5fdfc9b54ccd4ab2b4930bea997b14682b4d26b..ce07cde79a90340b974fd6520b4ca34534e201ea 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/mips/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.
 ##
@@ -59,7 +57,9 @@ libarch_la_SOURCES = \
        \
        md-abi.c \
        md-abi.h \
-       md.c
+       md-trap.h \
+       md.c \
+       md.h
 
 libarch_la_LIBADD = \
        $(OS_DIR)/libmd.la
index 8cefe558a5ddc508f9cbfcbd315c660090098dc7..0d4a3dc538fdfb1ffe8064ff44362571bd85ca4c 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
 
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
+   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
@@ -212,9 +212,9 @@ L_asm_vm_call_method_recompute_pv:
 
        .set    reorder                   /* XXX we need to recompute pv          */
 
+calljava_return2:
        move    sp,s0                     /* restore stack pointer                */
 
-calljava_return2:
        ald     ra,0*8(sp)                /* restore return address               */
        ald     pv,1*8(sp)                /* restore procedure vector             */
        ald     s0,3*8(sp)
index 35502fe003154eb2f90b2b97ebbea77fc77366c3..cbb334513e2a6c18c17280cd72c742d045bc5a9b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
 
-   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.
 
@@ -58,6 +56,7 @@
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
+#include "vm/jit/trap.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
@@ -288,7 +287,7 @@ bool codegen_emit(jitdata *jd)
                /* get correct lock object */
 
                if (m->flags & ACC_STATIC) {
-                       disp = dseg_add_address(cd, &m->class->object.header);
+                       disp = dseg_add_address(cd, &m->clazz->object.header);
                        M_ALD(REG_A0, REG_PV, disp);
                        disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
                        M_ALD(REG_ITMP3, REG_PV, disp);
@@ -298,7 +297,7 @@ bool codegen_emit(jitdata *jd)
                        M_BNEZ(REG_A0, 2);
                        disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
                        M_ALD(REG_ITMP3, REG_PV, disp);                   /* branch delay */
-                       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
                }
 
                M_JSR(REG_RA, REG_ITMP3);
@@ -1977,9 +1976,9 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                                                 fi->class, disp);
+                                                                                 fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -2027,9 +2026,9 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                                                 fi->class, disp);
+                                                                                 fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -2076,9 +2075,9 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                                                 fi->class, disp);
+                                                                                 fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -3170,9 +3169,9 @@ gen_method:
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
+                                               sizeof(methodptr*) * lm->clazz->index;
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
 
                                /* implicit null-pointer check */
index 39e74e102a2f272b95527e5d01dfa826617cb918..a8a7e225f0e1d6cf83a67cf46e0dab43c5cc00db 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/emit.c - MIPS 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.
 
@@ -50,6 +48,7 @@
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
+#include "vm/jit/trap.h"
 
 #include "vmcore/options.h"
 
@@ -496,7 +495,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_BNEZ(reg, 2);
                M_NOP;
-               M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARITHMETIC);
+               M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_ArithmeticException);
        }
 }
 
@@ -514,7 +513,7 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1,
                M_CMPULT(s2, REG_ITMP3, REG_ITMP3);
                M_BNEZ(REG_ITMP3, 2);
                M_NOP;
-               M_ALD_INTERN(s2, REG_ZERO, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+               M_ALD_INTERN(s2, REG_ZERO, TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -530,7 +529,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_BNEZ(REG_RESULT, 2);
                M_NOP;
-               M_ALD_INTERN(REG_RESULT, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_ALD_INTERN(REG_RESULT, REG_ZERO, TRAP_ArrayStoreException);
        }
 }
 
@@ -562,7 +561,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
                }
 
                M_NOP;
-               M_ALD_INTERN(s1, REG_ZERO, EXCEPTION_HARDWARE_CLASSCAST);
+               M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
        }
 }
 
@@ -578,7 +577,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_BNEZ(reg, 2);
                M_NOP;
-               M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+               M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
        }
 }
 
@@ -594,7 +593,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_BNEZ(REG_RESULT, 2);
                M_NOP;
-               M_ALD_INTERN(REG_RESULT, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);
+               M_ALD_INTERN(REG_RESULT, REG_ZERO, TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -607,7 +606,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 
 void emit_trap_compiler(codegendata *cd)
 {
-       M_ALD_INTERN(REG_METHODPTR, REG_ZERO, EXCEPTION_HARDWARE_COMPILER);
+       M_ALD_INTERN(REG_METHODPTR, REG_ZERO, TRAP_COMPILER);
 }
 
 
@@ -624,9 +623,9 @@ uint32_t emit_trap(codegendata *cd)
        /* Get machine code which is patched back in later. The
           trap is 1 instruction word long. */
 
-       mcode = *((u4 *) cd->mcodeptr);
+       mcode = *((uint32_t *) cd->mcodeptr);
 
-       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_PATCHER);
+       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_PATCHER);
 
        return mcode;
 }
index bcaef12e3ebe3cab31233b9e8db740a7f3aca103..f8c9407d9e3bd82e24ddc26e16593690b0f03733 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/linux/md-os.c - machine dependent MIPS Linux 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.
 
@@ -47,6 +45,7 @@
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 
 /* md_init *********************************************************************
@@ -121,7 +120,8 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        sp  = (u1 *) (ptrint) _gregs[REG_SP];
        ra  = (u1 *) (ptrint) _gregs[REG_RA];        /* this is correct for leafs */
 
-#if !defined(__UCLIBC__) && ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 5))
+#if !defined(__UCLIBC__)
+# if ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 5))
        /* NOTE: We only need this for pre glibc-2.5. */
 
        xpc = (u1 *) (ptrint) _mc->pc;
@@ -144,6 +144,9 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                xpc = xpc - 4;
                break;
        }
+# else
+       xpc = (u1 *) (ptrint) _mc->pc;
+# endif
 #else
        xpc = (u1 *) (ptrint) _gregs[CTX_EPC];
 #endif
@@ -164,7 +167,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                type = disp;
                val  = _gregs[d];
 
-               if (type == EXCEPTION_HARDWARE_COMPILER) {
+               if (type == TRAP_COMPILER) {
                        /* The XPC is the RA minus 4, because the RA points to the
                           instruction after the call. */
 
@@ -176,18 +179,18 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                   define is 0. */
 
                addr = _gregs[s1];
-               type = (s4) addr;
+               type = (int) addr;
                val  = 0;
        }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* Set registers. */
 
        switch (type) {
-       case EXCEPTION_HARDWARE_COMPILER:
+       case TRAP_COMPILER:
                if (p != NULL) {
                        _gregs[REG_PV]  = (uintptr_t) p;
 #if defined(__UCLIBC__)
@@ -212,7 +215,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                /* fall-through */
 
-       case EXCEPTION_HARDWARE_PATCHER:
+       case TRAP_PATCHER:
                if (p == NULL) {
                        /* We set the PC again because the cause may have changed
                           the XPC. */
index 45a1941ec5cd5d0189dd5f499d87849a6bdeac4c..848a16480d242011033f312426a5e68d8334d45d 100644 (file)
@@ -9,27 +9,6 @@
  * It is outdated, too.
  */ 
 
-static inline long
-__attribute__ ((unused))
-atomic_swap (volatile long *p, long val)
-{
-  long ret, temp;
-
-  __asm__ __volatile__
-    ("1:\n\t"
-     ".set  push\n\t"
-     ".set  mips2\n\t"
-     "lld   %2,%4\n\t"
-     "move  %0,%3\n\t"
-     "scd   %0,%1\n\t"
-     ".set  pop\n\t"
-     "beqz  %0,1b\n"
-     : "=&r" (temp), "=m" (*p), "=&r" (ret)
-     : "r" (val), "m" (*p)
-     : "memory");
-
-  return ret;
-}
 static inline int
 __attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
@@ -57,16 +36,9 @@ compare_and_swap (volatile long *p, long oldval, long newval)
 
 #else
 
-static inline void
-atomic_add(int *mem, int val)
-{
-       *mem += val;
-}
-
 long compare_and_swap (long *p, long oldval, long newval);
 
 #define STORE_ORDER_BARRIER()
-#define MEMORY_BARRIER_BEFORE_ATOMIC()
 #define MEMORY_BARRIER_AFTER_ATOMIC()
 #define MEMORY_BARRIER()
 
index 1b3065edf3b80ce477aa745496fc87d644b46d82..256fa4717a8fe25180125c2e63ffe8ec469dd426 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/md-abi.c - functions for MIPS ABI
 
-   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,6 +26,7 @@
 #include "config.h"
 
 #include <stdarg.h>
+#include <stdint.h>
 
 #include "vm/types.h"
 
@@ -38,6 +37,7 @@
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
 
 #include "vmcore/descriptor.h"
 #include "vmcore/method.h"
@@ -641,7 +641,7 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
 {
        methodinfo *m;
        methoddesc *md;
diff --git a/src/vm/jit/mips/md-trap.h b/src/vm/jit/mips/md-trap.h
new file mode 100644 (file)
index 0000000..9fca702
--- /dev/null
@@ -0,0 +1,79 @@
+/* src/vm/jit/mips/md-trap.h - MIPS hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (mips) the trap numbers are used as load
+ * displacements and thus must not be 4- or 8-byte aligned.
+ *
+ * NOTE: In trap_init() we have a check whether the offset of
+ * java_arrayheader.data[0] is greater than the largest displacement
+ * defined below.  Otherwise normal array loads/stores could trigger
+ * an exception.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    1
+
+enum {
+       TRAP_NullPointerException           = 0,
+       TRAP_ArithmeticException            = 1,
+       TRAP_ArrayIndexOutOfBoundsException = 2,
+       TRAP_ArrayStoreException            = 3,
+
+       /* Don't use 4 (could be a normal load offset). */
+
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+
+       /* Don't use 8 (could be a normal load offset). */
+
+       TRAP_COMPILER                       = 9,
+       TRAP_END
+};
+
+#endif /* _MD_TRAP_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 dbf03fd6c72d15411c8dbb41551ef016e86b7acb..ef4f476b778cfda22773a1b01e5323a007735af3 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/patcher.c - MIPS code patching 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.
 
@@ -98,8 +96,8 @@ bool patcher_get_putstatic(patchref_t *pr)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        PATCH_BACK_ORIGINAL_MCODE;
@@ -441,12 +439,12 @@ bool patcher_invokeinterface(patchref_t *pr)
 
        *((s4 *) (ra + 1 * 4)) |=
                (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
-                          sizeof(methodptr*) * m->class->index) & 0x0000ffff);
+                          sizeof(methodptr*) * m->clazz->index) & 0x0000ffff);
 
        /* patch method offset */
 
        *((s4 *) (ra + 2 * 4)) |=
-               (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
+               (s4) ((sizeof(methodptr) * (m - m->clazz->methods)) & 0x0000ffff);
 
        /* synchronize instruction cache */
 
index b82b941f7b33383225b2d05f34ad5e51adcfcbb7..b0e3fba34acdc6158e806733aae1ae5ce5fb585e 100644 (file)
@@ -55,12 +55,18 @@ SSA_SOURCES = \
        lsra.h \
        ssa.c \
        ssa.h \
+       ssa_phi.c \
+       ssa_phi.h \
+       ssa_rename.c \
+       ssa_rename.h \
        graph.c \
        graph.h \
        dominators.c \
        dominators.h \
        lifetimes.c \
-       lifetimes.h
+       lifetimes.h \
+       ssa2.c \
+       ssa3.c
 endif
 
 noinst_LTLIBRARIES = \
index 82768c3417d2e1b6479cf0fe9246aa0a5ffad579..3fcf46f6b86fdf09fba5b2b2827b6d038c6e450e 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/dominators.c - dominators and dominance frontier
 
-   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
+*/
 
 
-*/
 #include "mm/memory.h"
 
 #include "toolbox/bitvector.h"
@@ -260,6 +255,391 @@ void dom_Link(dominatordata *dd, int p, int n) {
        dd->best[n] = n;
 }
 
+/*********************************************************/
+
+typedef struct basicblock_info basicblock_info;
+
+struct basicblock_info {
+       basicblock *bb;
+       int dfnum;
+       basicblock_info *parent;
+       basicblock_info *semi;
+       basicblock_info *ancestor;
+       basicblock_info *best;
+       basicblock_info *idom;
+       basicblock_info *samedom;
+       basicblock_info **bucket;
+       unsigned bucketcount;
+};
+
+typedef struct dominator_tree_info dominator_tree_info;
+
+struct dominator_tree_info {
+       jitdata *jd;
+       basicblock_info *basicblocks;
+       basicblock_info **df_map;
+       unsigned df_counter;
+};
+
+static dominator_tree_info *dominator_tree_init(jitdata *jd) {
+       dominator_tree_info *di;
+       basicblock *itb;
+       basicblock_info *iti;
+
+       di = DNEW(dominator_tree_info);
+
+       di->jd = jd;
+
+       di->basicblocks = DMNEW(basicblock_info, jd->basicblockcount);
+       MZERO(di->basicblocks, basicblock_info, jd->basicblockcount);
+       
+       for (iti = di->basicblocks; iti != di->basicblocks + jd->basicblockcount; ++iti) {
+               iti->dfnum = -1;
+               iti->bucket = DMNEW(basicblock_info *, jd->basicblockcount);
+               iti->bucketcount = 0;
+       }
+
+       for (itb = jd->basicblocks; itb; itb = itb->next) {
+               di->basicblocks[itb->nr].bb = itb;
+       }
+
+       di->df_map = DMNEW(basicblock_info *, jd->basicblockcount);
+       MZERO(di->df_map, basicblock_info *, jd->basicblockcount);
+
+       di->df_counter = 0;
+
+       return di;
+}
+
+inline basicblock_info *dominator_tree_get_basicblock(dominator_tree_info *di, basicblock *bb) {
+       return di->basicblocks + bb->nr;
+}
+
+static void dominator_tree_depth_first_search(
+       dominator_tree_info *di, basicblock_info *parent, basicblock_info *node
+) {
+       basicblock **it;
+
+       if (node->dfnum == -1) {
+
+               node->dfnum = di->df_counter;
+               node->parent = parent;
+               di->df_map[di->df_counter] = node;
+               di->df_counter += 1;
+
+               for (it = node->bb->successors; it != node->bb->successors + node->bb->successorcount; ++it) {
+                       dominator_tree_depth_first_search(
+                               di, node, 
+                               dominator_tree_get_basicblock(di, *it)
+                       );
+               }
+       }
+}
+
+void dominator_tree_link(dominator_tree_info *di, basicblock_info *parent, basicblock_info *node) {
+       node->ancestor = parent;
+       node->best = node;
+}
+
+basicblock_info *dominator_tree_ancestor_with_lowest_semi(
+       dominator_tree_info *di, basicblock_info *node
+) {
+       basicblock_info *a, *b;
+
+       a = node->ancestor;
+
+       if (a->ancestor != NULL) {
+               b = dominator_tree_ancestor_with_lowest_semi(di, a);
+               node->ancestor = a->ancestor;
+               if (b->semi->dfnum < node->best->semi->dfnum) {
+                       node->best = b;
+               }
+       }
+
+       return node->best;
+}
+
+void dominator_tree_build_intern(jitdata *jd) {
+       
+       dominator_tree_info *di;
+       basicblock_info *node;
+       basicblock_info *semicand;
+       basicblock_info *pred;
+       basicblock **itb;
+       basicblock_info **itii;
+       basicblock_info *v, *y;
+       int i;
+
+       di = dominator_tree_init(jd);
+
+       dominator_tree_depth_first_search(di, NULL, dominator_tree_get_basicblock(di, jd->basicblocks));
+
+       for (i = di->df_counter - 1; i >= 1; --i) {
+               node = di->df_map[i];
+
+               node->semi = node->parent;
+
+               for (
+                       itb = node->bb->predecessors; 
+                       itb != node->bb->predecessors + node->bb->predecessorcount; 
+                       ++itb
+               ) {
+
+                       pred = dominator_tree_get_basicblock(di, *itb);
+
+                       if (pred->dfnum <= node->dfnum) {
+                               semicand = pred;
+                       } else {
+                               semicand = dominator_tree_ancestor_with_lowest_semi(di, pred)->semi;
+                       }
+
+                       if (semicand->dfnum < node->semi->dfnum) {
+                               node->semi = semicand;
+                       }
+               }
+
+               node->semi->bucket[node->semi->bucketcount] = node;
+               node->semi->bucketcount += 1;
+
+               dominator_tree_link(di, node->parent, node);
+
+               for (itii = node->parent->bucket; itii != node->parent->bucket + node->parent->bucketcount; ++itii) {
+                       v = *itii;
+                       y = dominator_tree_ancestor_with_lowest_semi(di, v);
+                       if (y->semi == v->semi) {
+                               v->idom = node->parent;
+                       } else {
+                               v->samedom = y;
+                       }
+               }
+
+               node->parent->bucketcount = 0;
+       }
+
+       for (i = 1; i < di->df_counter; ++i) {
+               node = di->df_map[i];
+               if (node->samedom) {
+                       node->idom = node->samedom->idom;
+               }
+
+               node->bb->idom = node->idom->bb;
+               node->idom->bb->domsuccessorcount += 1;
+       }
+}
+
+void dominator_tree_link_children(jitdata *jd) {
+       basicblock *bb;
+       int32_t ds;
+       /* basicblock number => current number of successors */
+       unsigned *numsuccessors;
+
+       /* Allocate memory for successors */
+
+       for (bb = jd->basicblocks; bb; bb = bb->next) {
+               if (bb->domsuccessorcount > 0) {
+                       bb->domsuccessors = DMNEW(basicblock *, bb->domsuccessorcount);
+               }
+       }
+
+       /* Allocate memory for per basic block counter of successors */
+
+       ds = dumpmemory_marker();
+       numsuccessors = DMNEW(unsigned, jd->basicblockcount);
+       MZERO(numsuccessors, unsigned, jd->basicblockcount);
+
+       /* Link immediate dominators with successors */
+
+       for (bb = jd->basicblocks; bb; bb = bb->next) {
+               if (bb->idom) {
+                       bb->idom->domsuccessors[numsuccessors[bb->idom->nr]] = bb;
+                       numsuccessors[bb->idom->nr] += 1;
+               }
+       }
+
+       /* Free memory */
+
+       dumpmemory_release(ds);
+}
+
+bool dominator_tree_build(jitdata *jd) {
+       int32_t ds;
+       
+       ds = dumpmemory_marker();
+       dominator_tree_build_intern(jd);
+       dumpmemory_release(ds);
+
+       dominator_tree_link_children(jd);
+
+       return true;
+}
+
+typedef struct dominance_frontier_item dominance_frontier_item;
+
+struct dominance_frontier_item {
+       basicblock *bb;
+       dominance_frontier_item *next;
+};
+
+typedef struct dominance_frontier_list dominance_frontier_list;
+
+struct dominance_frontier_list {
+       dominance_frontier_item *first;
+       unsigned count;
+};
+
+void dominance_frontier_list_add(dominance_frontier_list *list, basicblock *bb) {
+       dominance_frontier_item *item;
+       
+       for (item = list->first; item; item = item->next) {
+               if (item->bb == bb) return;
+       }
+
+       item = DNEW(dominance_frontier_item);
+       item->bb = bb;
+       item->next = list->first;
+       list->first = item;
+       list->count += 1;
+}
+
+typedef struct dominance_frontier_info dominance_frontier_info;
+
+struct dominance_frontier_info {
+       jitdata *jd;
+       dominance_frontier_list *map;
+};
+
+dominance_frontier_info *dominance_frontier_init(jitdata *jd) {
+       dominance_frontier_info *dfi = DNEW(dominance_frontier_info);
+
+       dfi->jd = jd;
+
+       dfi->map = DMNEW(dominance_frontier_list, jd->basicblockcount);
+       MZERO(dfi->map, dominance_frontier_list, jd->basicblockcount);
+
+       return dfi;
+}
+
+bool dominance_frontier_dominates(basicblock *d, basicblock *x) {
+       x = x->idom;
+
+       while (x != NULL) {
+               if (x == d) {
+                       return true;
+               }
+               x = x->idom;
+       }
+
+       return false;
+}
+
+void dominance_frontier_for_block(dominance_frontier_info *dfi, basicblock *b) {
+       basicblock **it;
+       dominance_frontier_item *itdf;
+       dominance_frontier_list s = { NULL, 0 };
+
+       for (it = b->successors; it != b->successors + b->successorcount; ++it) {
+               if ((*it)->idom != b) {
+                       dominance_frontier_list_add(&s, *it);
+               }
+       }
+
+       for (it = b->domsuccessors; it != b->domsuccessors + b->domsuccessorcount; ++it) {
+               dominance_frontier_for_block(dfi, *it);
+               for (itdf = dfi->map[(*it)->nr].first; itdf; itdf = itdf->next) {
+                       if (! dominance_frontier_dominates(b, itdf->bb)) {
+                               dominance_frontier_list_add(&s, itdf->bb);
+                       }
+               }
+       }
+
+       dfi->map[b->nr] = s;
+}
+
+void dominance_frontier_store(dominance_frontier_info *dfi) {
+       basicblock *bb;
+       dominance_frontier_item *itdf;
+       basicblock **itout;
+
+       for (bb = dfi->jd->basicblocks; bb; bb = bb->next) {
+               if (bb->nr < dfi->jd->basicblockcount) {
+                       if (dfi->map[bb->nr].count > 0) {
+                               bb->domfrontiercount = dfi->map[bb->nr].count;
+                               itout = bb->domfrontier = DMNEW(basicblock *, bb->domfrontiercount);
+                               for (itdf = dfi->map[bb->nr].first; itdf; itdf = itdf->next) {
+                                       *itout = itdf->bb;
+                                       itout += 1;
+                               }
+                       }
+               }
+       }
+}
+
+bool dominance_frontier_build(jitdata *jd) {
+       int32_t ds = dumpmemory_marker();
+
+       dominance_frontier_info *dfi = dominance_frontier_init(jd);
+       dominance_frontier_for_block(dfi, jd->basicblocks);
+       dominance_frontier_store(dfi);
+}
+
+#include "vm/jit/show.h"
+#include "vm/jit/python.h"
+
+extern void graph_add_edge( graphdata *gd, int from, int to );
+
+void dominator_tree_validate(jitdata *jd, dominatordata *_dd) {
+       int32_t ds = dumpmemory_marker();
+       graphdata *gd;
+       int i, j;
+       basicblock *bptr, **it;
+       dominatordata *dd;
+       int *itnr;
+       bool found;
+
+       fprintf(stderr, "%s/%s: \n", jd->m->clazz->name->text, jd->m->name->text);
+       gd = graph_init(jd->basicblockcount);
+
+       for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
+               for (it = bptr->successors; it != bptr->successors + bptr->successorcount; ++it) {
+                       graph_add_edge(gd, bptr->nr, (*it)->nr);
+               }
+       }
+
+       dd = compute_Dominators(gd, jd->basicblockcount);
+
+       for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
+               if (bptr->flags >= BBREACHED) {
+                       if (bptr->idom == NULL) {
+                               if (!(dd->idom[bptr->nr] == -1)) {
+                                       printf("-- %d %d\n", dd->idom[bptr->nr], bptr->nr);
+                                       assert(0);
+                               }
+                       } else {
+                               assert(dd->idom[bptr->nr] == bptr->idom->nr);
+                       }
+               }
+       }
+
+       computeDF(gd, dd, jd->basicblockcount, 0);
+
+       for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
+               if (bptr->flags >= BBREACHED) {
+                       assert(bptr->domfrontiercount == dd->num_DF[bptr->nr]);
+                       for (itnr = dd->DF[bptr->nr]; itnr != dd->DF[bptr->nr] + dd->num_DF[bptr->nr]; ++itnr) {
+                               found = false;
+                               for (it = bptr->domfrontier; it != bptr->domfrontier + bptr->domfrontiercount; ++it) {
+                                       if ((*it)->nr == *itnr) {
+                                               found =true; break;
+                                       }
+                               }
+                               assert(found);
+                       }
+               }
+       }
+
+       dumpmemory_release(ds);
+}
+
 /*
  * These 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 13ac48c0cff3fd377e7ee341de9f11bcddabd6b4..376b78e4a601911acf9349da6d5d8c70ad829e9a 100644 (file)
@@ -70,6 +70,14 @@ typedef struct dominatordata dominatordata;
 dominatordata *compute_Dominators(graphdata *gd, int basicblockcount);
 void computeDF(graphdata *gd, dominatordata *dd, int basicblockcount, int n);
 
+/* ............................... */
+
+bool dominator_tree_build(jitdata *jd);
+
+bool dominance_frontier_build(jitdata *jd);
+
+void dominator_tree_validate(jitdata *jd, dominatordata *dd);
+
 #endif /* _DOMINATORS_H */
 
 /*
index d4ef46bedb8a52027fb4ffb4be3567a2b46016e1..9ffe18468e47f1721b733c4f75e9b2ead3d8af2b 100644 (file)
@@ -26,6 +26,7 @@
 
    Authors: Christian Ullrich
 
+   $Id: graph.c$
 
 */
 
@@ -56,6 +57,8 @@ void graph_add_edge( graphdata *gd, int from, int to );
 int graph_get_first_(graph_element *ge, graphiterator *i);
 void transform_CFG(jitdata *, graphdata *);
 
+void graph_phi_moves(jitdata *jd, basicblock *bptr, basicblock *dst_goto);
+
 #ifdef GRAPH_DEBUG_VERBOSE
 void graph_print(lsradata *ls, graphdata *gd);
 #endif
@@ -498,10 +501,8 @@ void graph_init_basicblock(jitdata *jd, basicblock *bptr, int b_index) {
 
 /*********************************************************************+
 After the "original" CFG has been created, it has to be adopted for
-SSA. (inluding insertion of new Basic Blocks)
+SSA. (inluding insertion of new Basic Blocks - edge splitting)
 
-TODO: Do not insert blocks right now - just adopt the call graph!
-      After the phi moves are determined create only the needed Blocks 
 **********************************************************************/
 void transform_CFG(jitdata *jd, graphdata *gd) {
        int i, j, k, n, num_new_blocks;
@@ -551,15 +552,13 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
        /* copy Basic Block References to ls->basicblocks */
 
        for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
-/*             if (bptr->flags >= BBREACHED) { */
-                       _GRAPH_ASSERT(bptr->nr < jd->basicblockcount);
-                       ls->basicblocks[bptr->nr + 1] = bptr;
-                       bptr->nr = bptr->nr+1;
-/*             } */
+               _GRAPH_ASSERT(bptr->nr < jd->basicblockcount);
+               ls->basicblocks[bptr->nr + 1] = bptr;
+               bptr->nr = bptr->nr+1;
        }
        
        /* Create new Basic Blocks:
-          0, [jd->new_basicblockcount..ls->basicblockcount[ */
+          0, [jd->basicblockcount..ls->basicblockcount[ */
        /* num_new_blocks have to be inserted*/
 
        tmp = DMNEW( basicblock, num_new_blocks);
@@ -569,7 +568,9 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
        ls->basicblocks[0]->next = ls->basicblocks[1];
 
        if (ls->basicblockcount > jd->basicblockcount + 1) {
+
                /* new Blocks have to be inserted                   */
+
                num_succ = DMNEW(int, ls->basicblockcount);
                successor = DMNEW(graph_element *, ls->basicblockcount);
        
@@ -578,6 +579,7 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
 
                /* regard the + 1 for the already inserted new BB 0 */
                /* So recreate ls->var_def                          */
+
                var_def = DMNEW(int *, ls->basicblockcount);
                for(i = 0; i < jd->basicblockcount + 1; i++) {
                        var_def[i] = ls->var_def[i];
@@ -609,6 +611,7 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
        }
 
        /* Now Split the edges */
+
        num_new_blocks = jd->basicblockcount + 1; /* first free new block index */
        for(i = 0; i < jd->basicblockcount + 1; i++) {
                if (graph_has_multiple_successors(gd, i)) {/* more than one successor */
@@ -623,6 +626,7 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
                                        /* splite the edge from BB i to j with the new BB */
                                        /* num_new_blocks ( i->j --> i->nnb->j)*/
                                        /* iter_succ shows the edge from i to j */
+
                                        graph_split_edge(gd, i, &iter, num_new_blocks);
 
                                        ls->basicblocks[num_new_blocks]->indepth =
@@ -651,19 +655,6 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
                                        _GRAPH_ASSERT(ls->basicblocks[num_new_blocks]->outdepth == 
                                                                  ls->basicblocks[j]->indepth );
 
-#if 0
-                                       /* !!!! There can't be inoutvar definitions in one of these */
-                                       /* newly inserted basicblocks !!!! */
-
-                                       /* Add Definition */
-                                       /* decrease nr temporarly, because ssa_set_interface*/
-                                       /* adds 1 since it is called from stack.c, where there is */
-                                       /* no new BB 0 inserted like now */
-
-                                       ls->basicblocks[num_new_blocks]->nr--;
-                                       ssa_set_interface(jd, ls->basicblocks[num_new_blocks]);
-                                       ls->basicblocks[num_new_blocks]->nr++;
-#endif
                                        num_new_blocks++;
                                }
                        }
@@ -739,10 +730,14 @@ void transform_BB(jitdata *jd, graphdata *gd) {
                                        ls->basicblocks[pred]->next;
                                ls->basicblocks[pred]->next =
                                        ls->basicblocks[n];
+#if 1
                                /* generate no instructions */
                                ls->basicblocks[n]->icount = 1; 
                                ls->basicblocks[n]->iinstr = NEW(instruction);
                                ls->basicblocks[n]->iinstr[0].opc =     ICMD_NOP;
+#else
+                               graph_phi_moves(jd, ls->basicblocks[n], NULL);
+#endif
                        } else {
                                /* Block n is in the Branch path */
                                /* link Block at the end */
@@ -752,8 +747,6 @@ void transform_BB(jitdata *jd, graphdata *gd) {
 
                                /* change the Branch Target to BB i */
 
-
-       
                                switch(iptr->opc) {
                                case ICMD_LOOKUPSWITCH:
                                        {
@@ -839,7 +832,7 @@ void transform_BB(jitdata *jd, graphdata *gd) {
                                        /* not handled by now -> fallback to regalloc */
                                        exit(1);
                                }
-
+#if 1
                                /* Generate the ICMD_GOTO */
                                ls->basicblocks[n]->icount = 1; 
                                ls->basicblocks[n]->iinstr =
@@ -848,11 +841,81 @@ void transform_BB(jitdata *jd, graphdata *gd) {
                                        ICMD_GOTO;
                                ls->basicblocks[n]->iinstr->dst.block =
                                        ls->basicblocks[succ];
+#else
+                               graph_phi_moves(jd, ls->basicblocks[n], ls->basicblocks[succ]);
+#endif
                        }
                }
        }
 }
 
+/* graph_phi_moves *************************************************************
+
+generate the instruction array for Basicblock n (== ls->basicblocks[n])
+
+IN:
+basicblock *bptr       Basicblock to change with ->iinstr == NULL
+basicblock *dst_goto   Destination Block for ICMD_GOTO at end of Block, or
+                       NULL for no ICMD_GOTO
+
+OUT:
+bptr->iinstr           points to a newly allocated instruction array containing
+                       the phi moves, the optional ICMD_GOTO at the end.
+bptr->icount           Count of instructions in bptr->iinstr
+
+*******************************************************************************/
+
+void graph_phi_moves(jitdata *jd, basicblock *bptr, basicblock *dst_goto) {
+       int lt_d,lt_s,i;
+       lsradata    *ls;
+       instruction *iptr;
+
+       ls = jd->ls;
+
+       _GRAPH_ASSERT(ls->num_phi_moves[bptr->nr] > 0);
+       bptr->icount = ls->num_phi_moves[bptr->nr];
+       if (dst_goto != NULL)
+               bptr->icount++;
+       bptr->iinstr = iptr = DMNEW(instruction, bptr->icount);
+
+       _GRAPH_ASSERT(iptr != NULL);
+
+       /* Moves from phi functions with highest indices have to be */
+       /* inserted first, since this is the order as is used for   */
+       /* conflict resolution */
+
+       for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
+               lt_d = ls->phi_moves[bptr->nr][i][0];
+               lt_s = ls->phi_moves[bptr->nr][i][1];
+
+#if defined(GRAPH_DEBUG_VERBOSE)
+               if (compileverbose)
+                       printf("graph_phi_moves: BB %3i Move %3i <- %3i\n", bptr->nr,
+                                  lt_d, lt_s);
+#endif
+               if (lt_s == UNUSED) {
+#if defined(SSA_DEBUG_VERBOSE)
+                       if (compileverbose)
+                               printf(" ... not processed \n");
+#endif
+                       continue;
+               }
+
+               _GRAPH_ASSERT(d->type != -1);
+               _GRAPH_ASSERT(s->type == -1);
+
+               iptr->opc = ICMD_MOVE;
+               iptr->s1.varindex  = ls->lifetime[lt_s].v_index;
+               iptr->dst.varindex = ls->lifetime[lt_d].v_index;
+               iptr++;
+       }
+
+       if (dst_goto != NULL) {
+               iptr->opc = ICMD_GOTO;
+               iptr->dst.block = dst_goto;
+       }
+}
+
 #ifdef GRAPH_DEBUG_VERBOSE
 void graph_print(lsradata *ls, graphdata *gd) {
        int i,j;
index adc0c95a15b3bc2b2a2e9fe5155836421aa79f17..54b9732d47b8afed16047b3d453a36a32089a6a5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/lsra.inc - lifetime anaylsis
 
-   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
-
-
 */
 
+
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -160,10 +154,7 @@ void lt_scanlifetimes(jitdata *jd, graphdata *gd, dominatordata *dd) {
                        continue;
                i = ls->var_0[i];
 /*             _LT_ASSERT( i < jd->cd->maxlocals); */
-#ifdef LT_DEBUG_VERBOSE
-               if (compileverbose)
-                       printf("param %3i -> L %3i/%3i",p,i,t);
-#endif
+/*                     printf("param %3i -> L %3i/%3i\n",p,i,t); */
                _LT_ASSERT(t == VAR(i)->type);
                
                /* Param to Local init happens before normal Code */
@@ -410,7 +401,7 @@ void lt_lifeness_analysis(jitdata *jd, graphdata *gd) {
                        atime++;
                        diff += 1000000;
                }
-               printf("%8li %s.%s.%s\n",diff, m->class->name->text, m->name->text,
+               printf("%8li %s.%s.%s\n",diff, m->clazz->name->text, m->name->text,
                           m->descriptor->text);
        }
 #endif
@@ -463,6 +454,7 @@ void lt_lifeatstatement(lsradata *ls, graphdata *gd, int b_index,
                                        /* real ICMD, no phi-function, no param initialisation */
 
                                        _LT_ASSERT(ls->basicblocks[b_index]->iinstr != NULL);
+
                                        iptr = ls->basicblocks[b_index]->iinstr + iindex;
                                        if (icmd_table[iptr->opc].flags & ICMDTABLE_CALLS)
                                                lt->savedvar = SAVEDVAR;
@@ -505,7 +497,7 @@ void lt_lifeatstatement(lsradata *ls, graphdata *gd, int b_index,
                        lt_is_live(ls, lt, b_index, iindex);
 
 
-                       if (iindex == -ls->varcount-1) { 
+                       if (iindex == -ls->ssavarcount-1) { 
 
 #ifdef LT_DEBUG_VERBOSE
                                if ((compileverbose))
@@ -513,7 +505,7 @@ void lt_lifeatstatement(lsradata *ls, graphdata *gd, int b_index,
                                                   lt->v_index, b_index, iindex);
 #endif
                                /* iindex is the first statement of b_index */
-                               /* Statements -ls->max_vars-1 .. -1 are possible phi functions*/
+                               /* Statements -ls->ssavarcounts-1 .. -1 are possible phi functions*/
                                /* lt->v_index is live-in at b_index */
                
                                pred = graph_get_first_predecessor(gd, b_index, &pred_iter);
@@ -533,7 +525,7 @@ void lt_lifeatstatement(lsradata *ls, graphdata *gd, int b_index,
 
                                        /* look through phi functions */
 
-                                       for(; prev_iindex > -ls->varcount-1; prev_iindex--)
+                                       for(; prev_iindex > -ls->ssavarcount-1; prev_iindex--)
                                                if (ls->phi[b_index][-prev_iindex-1] != NULL)
                                                        break;
 
@@ -577,7 +569,10 @@ void lt_lifeoutatblock(lsradata *ls, graphdata *gd, int *M, int b_index,
 void lt_move_use_sites(struct lifetime *from, struct lifetime *to) {
        struct site *s;
 
+#if 0
+       /* not anymore true for copy propagated lifetimes */
        _LT_ASSERT(from->use != NULL);
+#endif
        if (from->use == NULL)
                return;
        for(s = from->use; s->next != NULL; s = s->next);
@@ -751,7 +746,6 @@ void _lt_scanlifetimes(jitdata *jd, graphdata *gd, basicblock *bptr,
                        } 
                }
 
-
                if (bptr->iinstr != NULL) {
                        /* set iptr to last instruction of BB */
                        iptr = bptr->iinstr + iindex;
index f46b51b078e29318a3be0312e6f41c34fca591dc..08f4ae6ca6489ed2c50f6efe76d82d5e59f29b60 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/lsra/graph.h - lifetimes header
+/* src/vm/jit/optimizing/lifetimes.h - lifetimes header
 
-   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
-
-
 */
 
 
@@ -56,7 +49,7 @@
 
 typedef struct site *lt_iterator;
 void lt_scanlifetimes(jitdata *, graphdata *, dominatordata *);
-void lt_add_ss(struct lifetime *, stackptr );
+void lt_add_ss(struct lifetime *, stackelement_t *);
 void lt_remove_use_site(struct lifetime *lt, int block, int iindex);
 void lt_move_use_sites(struct lifetime *from, struct lifetime *to);
 void lt_lifeness_analysis(jitdata *, graphdata *);
index 10c17f657f37030e474de27e6a162d60104dc83b..3b2006772c6721b117d8feddd03204237f1f91c2 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/lsra.inc - linear scan register allocator
 
-   Copyright (C) 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) 2005, 2006, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 #include "vm/jit/reg.h"
 #include "vm/jit/jit.h"
 
-
 #include "vm/jit/optimizing/graph.h"
 #include "vm/jit/optimizing/lifetimes.h"
 #include "vm/jit/optimizing/ssa.h"
 
 #include "vm/jit/optimizing/lsra.h"
 
-#ifdef LSRA_TESTLT
-# include "vm/resolve.h"
-#include "vm/builtin.h"
-#endif
-
-
 #include "toolbox/logging.h"
 
 extern const char *string_java_lang_InternalError;
 /* function prototypes */
-void lsra_init(jitdata *);
-graphdata *lsra_setup(jitdata *);
+void lsra_setup(jitdata *);
 void lsra_main(jitdata *);
 #ifdef LSRA_DEBUG_VERBOSE
-void lsra_dump_stack(stackptr );
+void lsra_dump_stack(stackelement_t*);
 void print_lifetimes(jitdata *, int *, int);
 void print_all_lifetimes(jitdata *);
 #endif
@@ -95,7 +85,6 @@ void lsra(jitdata *jd) {
        codegendata *cd;
        registerdata *rd;
        lsradata *ls;
-       graphdata *gd;
 #if defined(ENABLE_STATISTICS)
        int locals_start;
        int i,j;
@@ -103,7 +92,7 @@ void lsra(jitdata *jd) {
 #if defined(LSRA_DEBUG_CHECK)
 #if 0
        int b_index;
-       stackptr in,out;
+       stackelement_t* in,out;
        int      ind, outd;
 #endif
 #endif
@@ -149,13 +138,13 @@ void lsra(jitdata *jd) {
 #if defined(LSRA_DEBUG_CHECK) || defined(LSRA_DEBUG_VERBOSE)
 #if defined(LSRA_DEBUG_VERBOSE)
        if (compileverbose) {
-               printf("%s %s ",m->class->name->text, m->name->text);
-               if (code_is_leafmethod(code))
+               printf("%s %s ",m->clazz->name->text, m->name->text);
+               if (code_is_leafmethod(jd->code))
                        printf("**Leafmethod**");
                printf("\n");
        }
 #endif
-       if (strcmp(m->class->name->text,"java/lang/String")==0)
+       if (strcmp(m->clazz->name->text,"java/lang/String")==0)
                if (strcmp(m->name->text,"toLowerCase")==0)
 #if defined(LSRA_DEBUG_VERBOSE)
                        if (compileverbose)
@@ -164,9 +153,8 @@ void lsra(jitdata *jd) {
                { int dummy=1; dummy++; }
 #endif
 #endif
-
-    lsra_init(jd);
-       gd = lsra_setup(jd);
+                       
+       lsra_setup(jd);
 
 #if defined(ENABLE_STATISTICS)
        /* find conflicts between locals for statistics */
@@ -187,30 +175,17 @@ void lsra(jitdata *jd) {
 #endif
        /* Run LSRA */
        lsra_main(jd);
-#ifdef LSRA_TESTLT
-       test_lifetimes( jd, gd );
-#endif
+
        fflush(stdout);
 }
 
 
-void lsra_init(jitdata *jd) 
-{
-       lsradata *ls = jd->ls;
-
-       /* Init LSRA Data Structures */
-       /* allocate lifetimes for all Basicblocks */
-
-       ls->v_index = -1;
-}
-
-graphdata *lsra_setup(jitdata *jd)
+void lsra_setup(jitdata *jd)
 {
        methodinfo *m;
        codegendata *cd;
        registerdata *rd;
        lsradata *ls;
-       graphdata *gd;
 
 #if defined(ENABLE_LOOPS)
        /* Loop optimization "destroys" the basicblock array */
@@ -226,18 +201,6 @@ graphdata *lsra_setup(jitdata *jd)
        rd = jd->rd;
        ls = jd->ls;
 
-       ssa_init(jd);
-
-       /* Setup LSRA Data structures */
-
-       /* Generate the Control Flow Graph */
-       /* Add one for a Basic Block 0 to be inserted, so lateron */
-       /* with SSA Parameter initialization is handled right */
-       gd = graph_init(jd->basicblockcount + 1);
-       graph_make_cfg(jd, gd);
-       ssa(jd, gd);
-       lt_lifeness_analysis(jd, gd);
-
 #ifdef LSRA_DEBUG_VERBOSE
        if (compileverbose) {
                printf("Lifetimes after LifenessAnalyse: \n");
@@ -252,7 +215,6 @@ graphdata *lsra_setup(jitdata *jd)
                printf("Basicblockcount: %4i\n",ls->basicblockcount);
        }
 #endif
-       return gd;
 }
 
 void lsra_reg_setup(jitdata *jd,
@@ -272,7 +234,7 @@ void lsra_reg_setup(jitdata *jd,
 
        int_reg->nregdesc = nregdescint;
        flt_reg->nregdesc = nregdescfloat;
-       if (code_is_leafmethod(code)) { 
+       if (code_is_leafmethod(jd->code)) { 
                /* Temp and Argumentregister can be used as saved registers */
 
                int_reg->sav_top = INT_ARG_CNT + INT_TMP_CNT + INT_SAV_CNT;
@@ -456,9 +418,8 @@ void lsra_param_sort(struct lsradata *ls, int *lifetime, int lifetime_count) {
        int param_count;
        int i,j,tmp;
 
-       /* count number of parameters ( .i_start == -1) */
+       /* count number of parameters ( .i_start == 0) */
        for (param_count=0; (param_count < lifetime_count) &&
-/*              (ls->lifetime[lifetime[param_count]].i_start == -1); param_count++); */
                 (ls->lifetime[lifetime[param_count]].i_start == 0); param_count++);
 
        if (param_count > 0) {
@@ -649,7 +610,10 @@ int lsra_getmem(struct lifetime *lt, struct freemem *fmem, int *mem_use)
        for (p=fmem; (p->next!=NULL) && (p->next->end < fm->end); p=p->next);
        fm->next=p->next;
        p->next=fm;
-       return fm->off;
+       /* HACK: stackslots are 8 bytes on all architectures for now, I hope.
+        * -- pm
+        */
+       return fm->off * 8;
 }
 
 struct freemem *lsra_getnewmem(int *mem_use)
@@ -704,7 +668,7 @@ void _lsra_main( jitdata *jd, int *lifet, int lifetimecount,
 #ifdef LSRA_SAVEDVAR
                lt->savedvar = SAVEDVAR;
 #endif
-               if (lt->savedvar || code_is_leafmethod(code)) {
+               if (lt->savedvar || code_is_leafmethod(jd->code)) {
                        /* use Saved Reg (in case of leafmethod all regs are saved regs) */
                        if (reg->sav_top > regsneeded) {
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
@@ -787,7 +751,7 @@ void _lsra_expire_old_intervalls(jitdata *jd, struct lifetime *lt,
                if (active[i]->i_end > lt->i_start) break;
 
                /* make active[i]->reg available again */
-               if (code_is_leafmethod(code)) { 
+               if (code_is_leafmethod(jd->code)) { 
                        /* leafmethod -> don't care about type -> put all again into */
                        /* reg->sav_reg */
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
@@ -835,7 +799,7 @@ void spill_at_intervall(jitdata *jd, struct lifetime *lt )
 
        ls = jd->ls;
 
-       if (lt->savedvar || code_is_leafmethod(code)) {
+       if (lt->savedvar || code_is_leafmethod(jd->code)) {
                _spill_at_intervall(lt, ls->active_sav, &(ls->active_sav_top));
        } else {
                _spill_at_intervall(lt, ls->active_tmp, &(ls->active_tmp_top));
@@ -970,7 +934,7 @@ void lsra_calc_lifetime_length(jitdata *jd)
 
                        switch (lt->type) {
                        case TYPE_LNG:
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)) || defined (__I386__)
                                flags = 0;
 #else
                                flags = 1;
index 98f9b9a7de19e6258f98db0352727d3b996df6bd..80aa29a91e12b6020c8b1f851969a06c1663ade4 100644 (file)
@@ -26,6 +26,7 @@
 
    Authors: Christian Ullrich
 
+   $Id: lsra.h,v 1.17 2005/11/22 14:36:16 christian Exp $
 
 */
 
 #define min(a,b) ((a)<(b)?(a):(b))
 #define max(a,b) ((a)<(b)?(b):(a))
 
-struct _backedge {
-       int start;
-       int end;
-       int nesting;
-       struct _backedge *next;
-};
-
 struct site {
        int b_index;
        int iindex;
@@ -107,14 +101,6 @@ struct l_loop {
        int nesting;
 };
 
-/*
-struct stackslot {
-       stackptr s;
-       int bb;
-       struct stackslot *next;
-};
-*/
-
 struct lsra_register {
        int *sav_reg;
        int *tmp_reg;
@@ -128,31 +114,7 @@ struct lsra_reg {
        int use;
 };
 
-struct igraph_lookup {
-       int var;
-       int igraph;
-};
-
-struct igraph_interference {
-       int v1;
-       int v2;
-       struct igraph_interference *next;
-};
-
-struct igraph_vars {
-       int v;
-       struct igraph_vars *next;
-};
-
-struct igraph {
-       struct igraph_interference *inter;
-       struct igraph_vars *vars;
-};
-
-
 struct lsradata {
-       /* int *var; */           /* unused entries are set to UNUSED    */
-                           /* maps to jd->vars array */
        int varcount;       /* size of vars array */
        int ssavarcount;    /* ls->vars[0..ssavarcount[ are all locals and iovars */
                            /* they are regarded for ssa renaming */
@@ -174,9 +136,6 @@ struct lsradata {
        int *sorted;         /* BB sorted in reverse post order */
        int *sorted_rev;     /* BB reverse lookup of sorted */
 
-       struct _backedge **backedge; /* backedge data structure */
-       int backedge_count;          /* number of backedges */
-
        long *nesting;    /* Nesting level of BB*/
 
        struct lifetime *lifetime; /* array of lifetimes */
@@ -194,8 +153,6 @@ struct lsradata {
        int active_tmp_top, active_sav_top;
 
        struct lsra_exceptiontable *ex;
-       int v_index;               /* next free index for stack slot lifetimes    */
-                                  /* decrements from -1 */
 
        /* SSA fields */
        bitvector *var_def; /* LocalVar Definition Bitvector [0..ls->bbcount]  */
@@ -249,11 +206,6 @@ struct lsradata {
        int **stack;
        int *stack_top;
 
-       /* structures for phi var interference graphs */
-       struct igraph_lookup **igraph_lookup; /* var to igraph index */
-       int igraph_lookup_top;   /* number of entries in above table */
-       struct igraph *igraph;   /* interference graphs */
-       int igraph_top;
 };
 
        
index 0880a21a64344227374f1b418cc49396932b6bc4..319b2289a7fe41f03d8b9a561b1e641c10740c58 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/profile.c - runtime profiling
 
-   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.
 
 
 #include "mm/memory.h"
 
-#include "threads/threads-common.h"
+#include "threads/threadlist.h"
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
 #include "vm/stringlocal.h"
 
 #include "vm/jit/jit.h"
 #include "vm/jit/methodheader.h"
+#include "vm/jit/methodtree.h"
+
 #include "vm/jit/optimizing/recompile.h"
 
 #include "vmcore/class.h"
@@ -94,11 +95,11 @@ static void profile_thread(void)
 
                /* lock the threads lists */
 
-               threads_list_lock();
+               threadlist_lock();
 
                /* iterate over all started threads */
 
-               for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
+               for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
                        /* is this a Java thread? */
 
                        if (!(t->flags & THREAD_FLAG_JAVA))
@@ -113,9 +114,9 @@ static void profile_thread(void)
 
                        pc = t->pc;
 
-                       /* get the PV for the current PC */
+                       /* Get the PV for the current PC. */
 
-                       pv = codegen_get_pv_from_pc_nocheck(pc);
+                       pv = methodtree_find_nocheck(pc);
 
                        /* get methodinfo pointer from data segment */
 
@@ -157,7 +158,7 @@ static void profile_thread(void)
 
                /* unlock the threads lists */
 
-               threads_list_unlock();
+               threadlist_unlock();
        }
 }
 #endif
index be643285eb4a8d208e3373aeb5a5be6b0294cfdf..aa61989136de157bb5bf04a944fa5e4389a78fff 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/recompile.c - 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.
 
@@ -35,7 +33,7 @@
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/list.h"
 
@@ -49,6 +47,7 @@
 #include "vm/jit/optimizing/recompile.h"
 
 #include "vmcore/classcache.h"
+#include "vmcore/options.h"
 
 
 /* global variables ***********************************************************/
@@ -65,6 +64,8 @@ static list_t        *list_recompile_methods;
 
 bool recompile_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("recompile_init");
+
        /* initialize the recompile lock object */
 
        lock_thread_recompile = NEW(java_object_t);
index 73df8dea60114a5ee10f15ed48af0bfee2bb20e1..aa9c2f4ccd7dbd77558fa7b1f116907f08013067 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/optimizing/ssa.c - static single-assignment form
 
-   Copyright (C) 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) 2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
 #include "vm/jit/jit.h" /* icmd_table */
 
+#include "vm/jit/ir/bytecode.h"
+
 #include "vm/jit/optimizing/dominators.h"
 #include "vm/jit/optimizing/graph.h"
 #include "vm/jit/optimizing/lifetimes.h"
 #include "vm/jit/optimizing/lsra.h"
 
 #include "vm/jit/optimizing/ssa.h"
+#include "vm/jit/optimizing/ssa_rename.h"
+#include "vm/jit/optimizing/ssa_phi.h"
+
+#include "vm/jit/python.h"
 
 #if defined(SSA_DEBUG_VERBOSE)
 #include "vmcore/options.h"   /* compileverbose */
@@ -58,22 +62,17 @@ void dead_code_elimination(jitdata *jd, graphdata *gd);
 void copy_propagation(jitdata *jd, graphdata *gd);
 void ssa_replace_use_sites(jitdata *, graphdata *, struct lifetime *,
                                                int , worklist *);
-void ssa_place_phi_functions(jitdata *jd, graphdata *gd, dominatordata *dd);
-void ssa_rename_init(jitdata *jd, graphdata *gd);
-void ssa_rename(jitdata *jd, graphdata *gd, dominatordata *dd);
-void ssa_rename_(jitdata *jd,  graphdata *gd, dominatordata *dd, int n);
 
 void ssa_set_def(lsradata *, int , int );
 void ssa_set_local_def(lsradata *, int , int );
 void ssa_set_iovar(lsradata *, s4 , int , s4 *);
 void ssa_set_interface(jitdata *, basicblock *, s4 *);
 
-void ssa_generate_phi_moves(jitdata *, graphdata *);
-int ssa_rename_def_(lsradata *ls, int a);
 
 #ifdef SSA_DEBUG_VERBOSE
 void ssa_print_trees(jitdata *jd, graphdata *gd, dominatordata *dd);
 void ssa_print_lt(lsradata *ls);
+void _ssa_print_lt(struct lifetime *lt);
 void ssa_show_variable(jitdata *jd, int index, varinfo *v, int stage);
 void ssa_print_phi(lsradata *, graphdata *);
 #endif
@@ -82,14 +81,69 @@ void ssa_print_phi(lsradata *, graphdata *);
 
 SSA main procedure:
 
-******************************************************************************/
+SSA Algorithms are based on "modern compiler implementation in C" from andrew 
+w. appel, edition 2004
+
+Corrections:
+page 441 Algorithm 19.6. Inserting phi-functions:
+
+...
+    for each Y in DF[n]
+-       if Y not element of A phi [n]
++       if a not element of A phi [n]
+            insert the statment a <- ...
+...
+...
+-       A phi [n] <- A phi [n] join {Y}
++       A phi [n] <- A phi [n] join {a}
+-      if Y not element of A orig [n]
++      if a not element of A orig [Y]
+           W <- W join {Y}
 
-void ssa(jitdata *jd, graphdata *gd) {
+******************************************************************************/
+void xssa(jitdata *jd);
+void yssa(jitdata *jd);
+void ssa(jitdata *jd) {
        struct dominatordata *dd;
        lsradata *ls;
+       graphdata *gd;
+
+#if defined(ENABLE_LOOPS)
+       /* Loop optimization "destroys" the basicblock array */
+       /* TODO: work with the basicblock list               */
+       if (opt_loops) {
+               log_text("lsra not possible with loop optimization\n");
+               exit(1);
+       }
+#endif
+
+       cfg_add_root(jd);
+       cfg_add_exceptional_edges(jd);
+       /*pythonpass_run(jd, "foo", "cfg_print");*/
+       /*dominator_tree_validate(jd, dd);*/
+       /*pythonpass_run(jd, "ssa2", "main");*/
+       /*pythonpass_run(jd, "alt_ssa", "main");*/
+       pythonpass_run(jd, "foo", "before");
+       if (getenv("XSSA")) {
+               dominator_tree_build(jd);
+               dominance_frontier_build(jd);
+               xssa(jd);
+       } else {
+               yssa(jd);
+       }
+       pythonpass_run(jd, "foo", "after");
+       return;
 
        ls = jd->ls;
 
+    ssa_init(jd);
+       /* Generate the Control Flow Graph */
+       /* Add one for a Basic Block 0 to be inserted, so lateron */
+       /* with SSA Parameter initialization is handled right */
+
+       gd = graph_init(jd->basicblockcount + 1);
+       graph_make_cfg(jd, gd);
+
        dd = compute_Dominators(gd, ls->basicblockcount);
        computeDF(gd, dd, ls->basicblockcount, 0);
 
@@ -108,26 +162,31 @@ void ssa(jitdata *jd, graphdata *gd) {
                ssa_print_lt(ls);
        }
 #endif
-/*     dead_code_elimination(jd, gd); */
+       if (opt_ssa_dce) {
+               dead_code_elimination(jd, gd); 
 #ifdef SSA_DEBUG_VERBOSE
-       if (compileverbose) {
-               printf("Phi after dead code elemination\n");
-               ssa_print_phi(ls, gd);
-               ssa_print_lt(ls);
-       }
+               if (compileverbose) {
+                       printf("Phi after dead code elemination\n");
+                       ssa_print_phi(ls, gd);
+                       ssa_print_lt(ls);
+               }
 #endif
-/*     copy_propagation(jd, gd); */
-#ifdef SSA_DEBUG_VERBOSE
-       if (compileverbose) {
-               printf("Phi after copy propagation\n");
-               ssa_print_phi(ls, gd);
-               ssa_print_lt(ls);
        }
+       if (opt_ssa_cp) {
+               copy_propagation(jd, gd);
+#ifdef SSA_DEBUG_VERBOSE
+               if (compileverbose) {
+                       printf("Phi after copy propagation\n");
+                       ssa_print_phi(ls, gd);
+                       ssa_print_lt(ls);
+               }
 #endif
+       }
 
        ssa_generate_phi_moves(jd, gd);
        transform_BB(jd, gd);
 
+       lt_lifeness_analysis(jd, gd);
 
 #ifdef SSA_DEBUG_CHECK
        {
@@ -162,7 +221,7 @@ void ssa(jitdata *jd, graphdata *gd) {
                                                        if ((in[in_d] != out[out_d]) || 
                                                        (VAR(in[in_d])->flags != VAR(out[out_d])->flags)) {
                                                                printf("Method: %s %s\n",
-                                                                          m->class->name->text, m->name->text);
+                                                                          m->clazz->name->text, m->name->text);
                                                                        printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
                                                                if (compileverbose)
                                                                        printf("Error: Stack Varnum Mismatch BBin %3i BBout %3i Stackdepth %3i\n", i, pred, in_d);
@@ -178,11 +237,11 @@ void ssa(jitdata *jd, graphdata *gd) {
 
 #endif
 
-
 #ifdef SSA_DEBUG_VERBOSE
        if (compileverbose)
                ssa_print_trees(jd, gd, dd);
 #endif
+
 }
 
 /* ssa_init *******************************************************************
@@ -233,13 +292,13 @@ void ssa_init(jitdata *jd) {
 #if defined(SSA_DEBUG_CHECK) || defined(SSA_DEBUG_VERBOSE)
 # if defined(SSA_DEBUG_VERBOSE)
        if (compileverbose) {
-               printf("%s %s ",m->class->name->text, m->name->text);
-               if (code_is_leafmethod(code))
+               printf("%s %s ",m->clazz->name->text, m->name->text);
+               if (code_is_leafmethod(jd->code))
                        printf("**Leafmethod**");
                printf("\n");
        }
 # endif
-       if (strcmp(m->class->name->text,"spec/benchmarks/_213_javac/Parser")==0)
+       if (strcmp(m->clazz->name->text,"spec/benchmarks/_213_javac/Parser")==0)
                if (strcmp(m->name->text,"parseTerm")==0)
 # if defined(SSA_DEBUG_VERBOSE)
                        if (compileverbose) 
@@ -255,11 +314,9 @@ void ssa_init(jitdata *jd) {
                           jd->basicblockcount, jd->localcount);
 #endif
 
-       /* As first step all definitions of local variables and in/out vars are */
-       /* gathered. in/outvars are coalesced for same type and depth           */
-       /* "normal" tempvars (just living within one basicblock are) ignored    */
-
-       /* ls->var holds the index to jd->vars  */
+       /* As first step all definitions of local variables and in/out vars are   */
+       /* gathered. in/outvars are coalesced for same type and depth             */
+       /* "normal" tempvars (just living within one basicblock are) ignored      */
 
        ls->num_defs = DMNEW(int, jd->varcount);
        ls->new_varindex = DMNEW(int , jd->varcount);
@@ -278,10 +335,10 @@ void ssa_init(jitdata *jd) {
 
        ls->ssavarcount = 0;
 
-       /* Add parameters first in right order, so the new local indices */
-       /* 0..p will correspond to "their" parameters */
-       /* They get defined at the artificial Block 0, the real method bbs will be*/
-       /* moved to start at block 1 */
+       /* Add parameters first in right order, so the new local indices          */
+       /* 0..p will correspond to "their" parameters                             */
+       /* They get defined at the artificial Block 0, the real method bbs will   */
+       /* be ed to start at block 1                                              */
 
        /* don't look at already eliminated (not used) parameters (locals) */
 
@@ -348,9 +405,9 @@ void ssa_init(jitdata *jd) {
 
                                if (v != UNUSED) {
                                        if (( v < jd->localcount) || ( VAR(v)->flags & INOUT )) {
+
                                  /* !IS_TEMPVAR && !IS_PREALLOC == (IS_LOCALVAR || IS_INOUT) */
 
-/*                                             _SSA_ASSERT(ls->new_varindex[v] != UNUSED); */
                                                ssa_set_local_def(ls, b_index, v);
                                        }
                                }
@@ -358,9 +415,9 @@ void ssa_init(jitdata *jd) {
                }
        }
        _SSA_ASSERT(ls->ssavarcount < jd->varcount);
+
 #ifdef SSA_DEBUG_VERBOSE
        if (compileverbose) {
-
                printf("ssa_init: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount, 
                           ls->ssavarcount);
                for(i = 0; i < jd->varcount; i++) {
@@ -507,849 +564,15 @@ void ssa_set_interface(jitdata *jd, basicblock *bptr, s4 *interface_map) {
                }
                ssa_set_iovar(ls, out[out_d], o_map_index, interface_map);
                if (in_d == out_d) {
-                       if (in[in_d] != out[out_d]) {
-
-                               /* out interface stackslot is defined in this basic block */
-
-/*                             ssa_set_def(ls, bptr->nr + 1, ls->new_varindex[out[out_d]]); */
-                       }
                        out_d--;
                        in_d--;
                }
                else {
-
-                       /* in_d < out_d */
-                       /* out interface stackslot is defined in this basic block */
-
-/*                     ssa_set_def(ls, bptr->nr + 1, ls->new_varindex[out[out_d]]); */
                        out_d--;
                }
        }
 }
 
-/* ssa_place_phi_functions *****************************************************
-
-ls->phi[n][a][p] is created and populated.
-
-For each basicblock Y in the dominance frontier of a basicblock n (0 <= n < 
-ls->basicblockcount)in which a variable (0 <= a < ls->ssavarcount) is defined an
-entry in ls->phi[Y][a] is created.
-This entry is an array with the number of predecessors of Y elements + 1 elements.
-This elements are all set to the variable a and represent the phi function which
-will get ai = phi(ai1, ai2, ..., aip) after ssa_rename.
-
-*******************************************************************************/
-
-
-void ssa_place_phi_functions(jitdata *jd, graphdata *gd, dominatordata *dd)
-{
-       int a,i,j,n,Y;
-       bitvector *def_sites;
-       bitvector *A_phi;    /* [0..ls->basicblockcount[ of ls->ssavarcount Bit */
-       worklist *W;
-       int num_pred;
-
-       lsradata *ls;
-
-       ls = jd->ls;
-
-       W = wl_new(ls->basicblockcount);
-
-       def_sites = DMNEW(bitvector, ls->ssavarcount);
-       for(a = 0; a < ls->ssavarcount; a++)
-               def_sites[a] = bv_new(ls->basicblockcount);
-
-       ls->phi = DMNEW(int **, ls->basicblockcount);
-       A_phi = DMNEW(bitvector, ls->basicblockcount);
-       for(i = 0; i < ls->basicblockcount; i++) {
-               ls->phi[i] = DMNEW(int *, ls->ssavarcount);
-               for(j = 0; j < ls->ssavarcount; j++)
-                       ls->phi[i][j] = NULL;
-               A_phi[i] = bv_new(ls->ssavarcount);
-       }
-
-       /* copy var_def to def_sites */
-       /* var_def is valid for 0.. jd->basicblockcount (bb 0 for param init) */
-
-       for(n = 0; n <= jd->basicblockcount; n++)
-               for(a = 0; a < ls->ssavarcount; a++)
-                       if (bv_get_bit(ls->var_def[n], a))
-                               bv_set_bit(def_sites[a], n);
-#ifdef SSA_DEBUG_VERBOSE
-       if (compileverbose) {
-               printf("var Definitions:\n");
-               for(i = 0; i < ls->ssavarcount; i++) {
-                       printf("def_sites[%3i]=%p:",i,(void *)def_sites[i]);
-                       for(j = 0; j < ls->basicblockcount; j++) {
-                               if ((j % 5) == 0) printf(" ");
-                               if (bv_get_bit(def_sites[i], j))
-                                       printf("1");
-                               else
-                                       printf("0");
-                       }
-                       printf(" (");
-
-                       printf("\n");
-               }
-       }
-#endif
-
-       for(a = 0; a < ls->ssavarcount; a++) {
-
-               /* W<-def_sites(a) */
-
-               for(n = 0; n < ls->basicblockcount; n++)
-                       if (bv_get_bit(def_sites[a],n)) {
-                               wl_add(W, n);
-                       }
-                               
-               while (!wl_is_empty(W)) { /* W not empty */
-                       n = wl_get(W);
-
-                       for(i = 0; i < dd->num_DF[n]; i++) {
-                               Y = dd->DF[n][i];
-                               /* Node Y is in Dominance Frontier of n -> */
-                               /* insert phi function for a at top of Y*/
-                               _SSA_CHECK_BOUNDS(Y, 0, ls->basicblockcount);
-                               if (bv_get_bit( A_phi[Y], a) == 0) { 
-                                       /* a is not a Element of A_phi[Y] */
-                                       /* a <- phi(a,a...,a) to be inserted at top of Block Y */
-                                       /* phi has as many arguments, as Y has predecessors    */
-#if 0
-#if 0
-                                       /* do not add a phi function for interface stackslots */
-                                       /* if a predecessor is not a def site of a <==>       */
-                                       /* the block does not have the corresponding inslot*/
-
-/*                                     if ((ls->var_to_index[a] >= 0) || */
-/*                                             (bv_get_bit(def_sites[a],  */
-/*                                                                     graph_get_first_predecessor(gd, Y, &iter)))) */
-
-#endif
-                                       /* for interface stackslots add a phi function only */
-                                       /* if the basicblock has the corresponding incoming */
-                                       /* stackslot -> it could be, that the stackslot is */
-                                       /* not live anymore at Y */
-
-#endif
-                                       num_pred =  graph_get_num_predecessor(gd, Y);
-                                       ls->phi[Y][a] = DMNEW(int, num_pred + 1);
-                                       for (j = 0; j < num_pred + 1; j++)
-                                               ls->phi[Y][a][j] = a;
-                                       /* increment the number of definitions of a by one */
-                                       /* for this phi function */
-                                       ls->num_defs[a]++;
-                                       
-                                       bv_set_bit(A_phi[Y], a);
-                                       if (bv_get_bit(ls->var_def[Y],a)==0) {
-                                               /* Iterated Dominance Frontier Criterion:*/
-                                               /* if Y had no definition for a insert it*/
-                                               /* into the Worklist, since now it       */
-                                               /* defines a through the phi function    */
-                                               wl_add(W, Y);
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-/* ssa_rename ******************************************************************
-
-Rename the variables a (0 <= a < ls->ssavarcount) so that each new variable
-has only one definition (SSA form).
-
-ls->def_count[0..ls->ssavarcount[ holds the number of definitions of each var.
-ls->var_0[0..ls->ssavarcount[ will be set to the new index of the first 
-                              definition of each old var.
-ls->varcount_with_indices     will be se to the new maximum varcount of LOCAL
-                              and IOVARS.
-
-All other vars (TEMPVAR and PREALLOC) will get a new unique index above 
-ls->varcount_with_indices.
-
-jd->var and jd->varcount will be set for this renamed vars.
-
-*******************************************************************************/
-
-void ssa_rename(jitdata *jd, graphdata *gd, dominatordata *dd)
-{
-       int i, mi, l, j, p, t;
-       int type, flags;
-       methoddesc *md = jd->m->parseddesc;
-
-       varinfo *new_vars;
-       lsradata *ls;
-
-       ls = jd->ls;
-       
-       ssa_rename_init(jd, gd);
-
-       /* Consider definition of Local Vars initialized with Arguments */
-       /* in Block 0 */
-       /* init is regarded as use too-> ssa_rename_use ->bullshit!!*/
-       for (p = 0, l= 0; p < md->paramcount; p++) {
-               t = md->paramtypes[p].type;
-               mi = l * 5 + t;
-               i = jd->local_map[mi];
-               l++;
-               if (IS_2_WORD_TYPE(t))
-                       l++;
-               if (i == UNUSED)
-                       continue;
-               /* !!!!! locals are now numbered as the parameters !!!! */
-               /* !!!!! no additional increment for 2 word types !!!!! */
-               /* this happens later on! here we still need the increment */
-           /* index of var can be in the range from 0 up to not including */
-           /* CD->maxlocals */
-
-               /* ignore return value, since first definition gives 0 -> */
-               /* no rename necessary */
-               
-               i = ls->new_varindex[i];
-               j = ssa_rename_def_(ls, i);
-               _SSA_ASSERT(j == 0);
-               jd->local_map[mi] = i;
-       }
-       ssa_rename_(jd, gd, dd, 0);
-
-#if 0
-       /* DO _NOT_ DO THIS! Look at java.util.stringtokenizer.counttokens! */
-       /* if there is no use of the defined Var itself by the phi function */
-       /* for a loop path, in which this var is not used, it will not be life */
-       /* in this path and overwritten! */
-
-       /* Invalidate all xij from phi(xi0)=xi1,xi2,xi3,..,xin with xij == xi0 */
-       /* this happens if the phi function is the first definition of x or in a */
-       /* path with a backedge xi has no definition */ 
-       /* a phi(xij) = ...,xij,... with the only use and definition of xij by */
-       /* this phi function would otherwise "deadlock" the dead code elemination */
-       /* invalidate means set it to ls->max_vars_with_indices */
-       /* a phi function phi(xi0)=xi1,xi2,...xin wiht xij == xi0 for all j in */
-       /* [1,n] can be removed */
-
-       for(i = 0; i < ls->ssavarcount; i++) {
-               for(t = 0; t < ls->basicblockcount; t++) {
-                       if (ls->phi[t][i] != 0) {
-                               remove_phi = true;
-                               for(p = 1; p <= graph_get_num_predecessor(gd, t); p++) {
-                                       if (ls->phi[t][i][0] == ls->phi[t][i][p])
-                                               ls->phi[t][i][p] = ls->varcount_with_indices;
-                                       else 
-                                               remove_phi = false;
-                               }
-                       }
-                       if (remove_phi)
-                               ls->phi[t][i] = NULL;
-               }
-       }
-#endif
-
-#if defined(SSA_DEBUG_CHECK) || defined(SSA_DEBUG_VERBOSE)
-# if defined(SSA_DEBUG_VERBOSE)
-       if (compileverbose) {
-               printf("%s %s ",jd->m->class->name->text, jd->m->name->text);
-               if (code_is_leafmethod(code))
-                       printf("**Leafmethod**");
-               printf("\n");
-       }
-# endif
-       if (strcmp(jd->m->class->name->text,"fp")==0)
-               if (strcmp(jd->m->name->text,"testfloat")==0)
-# if defined(SSA_DEBUG_VERBOSE)
-                       if (compileverbose) 
-                               printf("12-------------------12\n");
-# else
-               { int dummy=1; dummy++; }
-# endif
-#endif
-       /* recreate rd->locals[][] */
-       /* now only one (local_index/type) pair exists anymore     */
-       /* all var[t][i] with var_to_index[var[t][i]] >= 0 are locals */
-       /* max local index after SSA indexing is in ls->local_0[ls->max_locals] */
-       
-       new_vars = DMNEW(varinfo, ls->vartop);
-       for(i = 0; i < ls->vartop ; i++)
-               new_vars[i].type = UNUSED;
-       for(i = 0; i < jd->varcount; i++) {
-                       p = ls->new_varindex[i];
-                       if (p != UNUSED) {
-                               if (p < ls->ssavarcount)
-                                       p = ls->var_0[p];
-                               new_vars[p].type  = VAR(i)->type;
-                               new_vars[p].flags = VAR(i)->flags;
-                               ls->lifetime[p].v_index = p;
-                               ls->lifetime[p].type = VAR(i)->type;
-                       }
-       }
-
-       /* take care of newly indexed local & in/out vars */
-
-       for(i = 0; i < ls->ssavarcount; i++) {
-               j = ls->var_0[i];
-               type = new_vars[j].type;
-               flags = new_vars[j].flags;
-               j++;
-               for (; j < ls->var_0[i + 1]; j++) {
-                       new_vars[j].type = type;
-                       new_vars[j].flags = flags;
-                       ls->lifetime[j].v_index = j;
-                       ls->lifetime[j].type = type;
-               }
-       }
-
-#ifdef SSA_DEBUG_VERBOSE
-       if (compileverbose) {
-
-               printf("ssa_rename: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
-                          ls->ssavarcount);
-               for(i = 0; i < jd->varcount; i++) {
-                       printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
-                       ssa_show_variable(jd, i, VAR(i),0);
-                       j = ls->new_varindex[i];
-                       if ((j != UNUSED) && (j < ls->ssavarcount))
-                               printf(" -> %3i ... %3i", ls->var_0[j], ls->var_0[j + 1] - 1);
-                       else
-                               printf(" -> %3i", j);
-                       printf("\n");
-               }
-       }
-#endif
-
-       jd->var = new_vars;
-       jd->varcount = ls->vartop;
-       jd->vartop = ls->vartop;
-
-#ifdef SSA_DEBUG_VERBOSE
-       if (compileverbose) {
-               printf("ssa_rename: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
-                          ls->ssavarcount);
-               for(i = 0; i < jd->varcount; i++) {
-                       printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
-                       ssa_show_variable(jd, i, VAR(i),0);
-                       printf("\n");
-               }
-       }
-#endif
-}
-
-/* ssa_rename_init *************************************************************
-
-Setup the data structure for ssa_rename
-
-ls->def_count[0..ls->ssavarcount[ holds the number of definitions of each var.
-ls->var_0[0..ls->ssavarcount[ will be set to the new index of the first 
-                              definition of each old var.
-ls->varcount_with_indices     will be se to the new maximum varcount of LOCAL
-                              and IOVARS.
-
-All other vars (TEMPVAR and PREALLOC) will get a new unique index above 
-ls->varcount_with_indices.
-
-jd->var and jd->varcount will be set for this renamed vars.
-
-*******************************************************************************/
-
-void ssa_rename_init(jitdata *jd, graphdata *gd) 
-{
-       int a, i, p;
-       lsradata *ls;
-
-       ls = jd->ls;
-       
-       /* set up new locals */
-       /* ls->new_varindex[0..jd->varcount[ holds the new unique index */
-       /* for locals and iovars */
-
-       /* ls->num_defs[index] gives the number of indizes which will be created  */
-       /* from SSA */
-
-       /* -> vars will be numbered in this sequence: L0(0)..L0(i) L1(0)..L1(j) ..*/
-       /* ls->var_0[X] will point to each LX(0)  */
-       /* ls->var_0[ls->ssavarcount] will hold ls->varcount_with_indices */
-
-       /* as first step cummulate the num_defs array for locals and iovars       */
-       /* last element is the maximum var count */
-
-       ls->var_0 = DMNEW(int, max(1, ls->ssavarcount + 1));
-       ls->var_0[0] = 0;
-       ls->varcount_with_indices = 0;
-       for(i = 0; i < ls->ssavarcount; i++) {
-               ls->varcount_with_indices += ls->num_defs[i];
-               ls->var_0[i+1] = ls->var_0[i] + ls->num_defs[i];
-       }
-
-#if 0
-       /* Change the var indices in phi from La to La(0) */
-
-       for(i = 0; i < ls->basicblockcount; i++)
-               for (a = 0; a < ls->ssavarcount; a++)
-                       if (ls->phi[i][a] != NULL)                              
-                               for(p = 0; p < graph_get_num_predecessor(gd, i) + 1; p++)
-                                       ls->phi[i][a][p] = ls->var_0[a];
-#endif
-       
-       /* Initialization */
-
-       ls->count     = DMNEW(int, max(1, ls->ssavarcount));
-       ls->stack     = DMNEW(int *, max(1, ls->ssavarcount));
-       ls->stack_top = DMNEW(int, max(1, ls->ssavarcount));
-       for(a = 0; a < ls->ssavarcount; a++) {
-               ls->count[a] = 0;
-               ls->stack_top[a] = 0;
-
-               /* stack a has to hold number of defs of a Elements + 1 */
-
-               ls->stack[a] = DMNEW(int, ls->num_defs[a] + 1);
-               ls->stack[a][ls->stack_top[a]++] = 0;
-       }
-
-       if (ls->ssavarcount > 0) {
-
-               /* Create the num_var_use Array */
-
-               ls->num_var_use = DMNEW(int *, ls->basicblockcount);
-               for(i = 0; i < ls->basicblockcount; i++) {
-                       ls->num_var_use[i] =DMNEW(int, max(1, ls->varcount_with_indices));
-                       for(a = 0; a < ls->varcount_with_indices; a++)
-                               ls->num_var_use[i][a] = 0;
-               }
-
-               /* Create the use_sites Array of Bitvectors*/
-               /* use max(1,..), to ensure that the array is created! */
-
-               ls->use_sites =  DMNEW(bitvector, max(1, ls->varcount_with_indices));
-               for(a = 0; a < ls->varcount_with_indices; a++)
-                       ls->use_sites[a] = bv_new(ls->basicblockcount);
-       }
-
-       /* init lifetimes */
-       /* count number of TEMPVARs */
-
-       ls->lifetimecount = 0;
-       for(i = 0; i < jd->varcount; i++)
-               if ((i >= jd->localcount) || (!(jd->var[i].flags & (INOUT | PREALLOC))))
-                       ls->lifetimecount++;
-
-       ls->varcount = ls->varcount_with_indices + ls->lifetimecount;
-
-       ls->lifetimecount = ls->varcount;
-       ls->lifetime = DMNEW(struct lifetime, ls->lifetimecount);
-       ls->lt_used = DMNEW(int, ls->lifetimecount);
-       ls->lt_int = DMNEW(int, ls->lifetimecount);
-       ls->lt_int_count = 0;
-       ls->lt_flt = DMNEW(int, ls->lifetimecount);
-       ls->lt_flt_count = 0;
-       ls->lt_mem = DMNEW(int, ls->lifetimecount);
-       ls->lt_mem_count = 0;
-       for (i=0; i < ls->lifetimecount; i++) {
-               ls->lifetime[i].type = UNUSED;
-               ls->lifetime[i].savedvar = 0;           
-               ls->lifetime[i].flags = 0;
-               ls->lifetime[i].usagecount = 0;
-               ls->lifetime[i].bb_last_use = -1;
-               ls->lifetime[i].bb_first_def = -1;
-               ls->lifetime[i].use = NULL;
-               ls->lifetime[i].def = NULL;
-               ls->lifetime[i].last_use = NULL;
-       }
-
-       /* for giving TEMP and PREALLOC vars a new unique index */
-
-       ls->vartop = ls->varcount_with_indices; 
-
-#ifdef SSA_DEBUG_VERBOSE
-       if (compileverbose) {
-               printf("ssa_rename_init: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
-                          ls->ssavarcount);
-               for(i = 0; i < jd->varcount; i++) {
-                       if ((i < jd->localcount) || ( VAR(i)->flags & INOUT)) {
-                               printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
-                               ssa_show_variable(jd, i, VAR(i),0);
-                               if ((i < ls->ssavarcount) || (VAR(i)->flags & INOUT)) {
-                                       printf(" -> %3i", ls->new_varindex[i]);
-                               }
-                               printf("\n");
-                       }
-               }
-               ssa_print_phi(ls, gd);
-       }
-#endif
-}
-
-int ssa_rename_def_(lsradata *ls, int a) {
-       int i;
-       
-       _SSA_CHECK_BOUNDS(a,0,ls->ssavarcount);
-       ls->count[a]++;
-       i = ls->count[a] - 1;
-       /* push i on stack[a] */
-       _SSA_CHECK_BOUNDS(ls->stack_top[a], 0, ls->num_defs[a] + 1);
-       ls->stack[a][ls->stack_top[a]++] = i;
-       return i;
-}
-
-int ssa_rename_def(jitdata *jd, int *def_count, int a) {
-       int i, a1, ret;
-       lsradata *ls;
-
-       ls = jd->ls;
-       
-       a1 = ls->new_varindex[a];
-       _SSA_CHECK_BOUNDS(a1, UNUSED, ls->varcount);
-       if ((a1 != UNUSED) && (a1 < ls->ssavarcount)) {
-               /* local or inoutvar -> normal ssa renaming */
-               _SSA_ASSERT((a < jd->localcount) || (VAR(a)->flags & INOUT));
-               /* !IS_TEMPVAR && !IS_PREALLOC == (IS_LOCALVAR || IS_INOUT) */
-
-               def_count[a1]++;
-               i = ssa_rename_def_(ls, a1);
-               ret = ls->var_0[a1] + i;
-       }
-       else {
-               /* TEMP or PREALLOC var */
-               if (a1 == UNUSED) {
-                       ls->new_varindex[a] = ls->vartop;
-                       ret = ls->vartop;
-                       ls->vartop++;
-                       _SSA_ASSERT( ls->vartop < ls->varcount);
-               }
-               else
-                       ret = a1;
-       }
-       return ret;
-}
-
-void ssa_rename_use_(lsradata *ls, int n, int a) {
-       _SSA_CHECK_BOUNDS(a, 0, ls->varcount_with_indices);
-       if (ls->ssavarcount > 0) {
-               bv_set_bit(ls->use_sites[a], n);
-               ls->num_var_use[n][a]++;
-       }
-}
-
-int ssa_rename_use(lsradata *ls, int n, int a) {
-       int a1, i;
-       int ret;
-
-       a1 = ls->new_varindex[a];
-       _SSA_CHECK_BOUNDS(a1, UNUSED, ls->varcount);
-       if ((a1 != UNUSED) && (a1 < ls->ssavarcount)) {
-               /* local or inoutvar -> normal ssa renaming */
-               /* i <- top(stack[a]) */
-
-               _SSA_CHECK_BOUNDS(ls->stack_top[a1]-1, 0, ls->num_defs[a1]+1);
-               i = ls->stack[a1][ls->stack_top[a1] - 1]; 
-               _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a1]);
-
-               ret = ls->var_0[a1] + i;
-       }
-       else {
-               /* TEMP or PREALLOC var */
-               if (a1 == UNUSED) {
-                       ls->new_varindex[a] = ls->vartop;
-                       ret = ls->vartop;
-                       ls->vartop++;
-                       _SSA_ASSERT( ls->vartop < ls->varcount);
-               }
-               else
-                       ret = a1;
-       }
-
-       return ret;
-}
-
-#ifdef SSA_DEBUG_VERBOSE
-void ssa_rename_print(instruction *iptr, char *op, int from,  int to) {
-       if (compileverbose) {
-               printf("ssa_rename_: ");
-               if (iptr != NULL)
-                       printf("%s ", opcode_names[iptr->opc]);
-               else
-                       printf("       ");
-
-               printf("%s: %3i->%3i\n", op, from, to);
-       }
-}
-#endif
-
-void ssa_rename_(jitdata *jd, graphdata *gd, dominatordata *dd, int n) {
-       int a, i, j, k, iindex, Y, v;
-       int in_d, out_d;
-       int *def_count;
-       /* [0..ls->varcount[ Number of Definitions of this var in this  */
-       /* Basic Block. Used to remove the entries off the stack at the */
-       /* end of the function */
-       instruction *iptr;
-       s4 *in, *out, *argp;
-       graphiterator iter_succ, iter_pred;
-       struct lifetime *lt;
-
-       methoddesc *md;
-       methodinfo *m;
-       builtintable_entry *bte;
-       lsradata *ls;
-
-       ls = jd->ls;
-       m  = jd->m;
-
-#ifdef SSA_DEBUG_VERBOSE
-       if (compileverbose)
-               printf("ssa_rename_: BB %i\n",n);
-#endif
-
-       _SSA_CHECK_BOUNDS(n, 0, ls->basicblockcount);
-
-       def_count = DMNEW(int, max(1, ls->ssavarcount));
-       for(i = 0; i < ls->ssavarcount; i++)
-               def_count[i] = 0;
-
-       /* change Store of possible phi functions from a to ai*/
-
-       for(a = 0; a < ls->ssavarcount; a++)
-               if (ls->phi[n][a] != NULL) {
-                       def_count[a]++;
-                               /* do not mark this store as use - maybee this phi function */
-                               /* can be removed for unused Vars*/
-                       j = ls->var_0[a] + ssa_rename_def_(ls, a);
-#ifdef SSA_DEBUG_VERBOSE
-                       ssa_rename_print( NULL, "phi-st", ls->phi[n][a][0], j);
-#endif
-                       ls->phi[n][a][0] = j;
-               }
-
-       in   = ls->basicblocks[n]->invars;
-       in_d = ls->basicblocks[n]->indepth - 1;
-
-       /* change use of instack Interface stackslots except top SBR and EXH */
-       /* stackslots */
-
-       if ((ls->basicblocks[n]->type == BBTYPE_EXH) ||
-               (ls->basicblocks[n]->type == BBTYPE_SBR)) {
-               in_d--;
-       }
-/*     out   = ls->basicblocks[n]->outvars; */
-/*     out_d = ls->basicblocks[n]->outdepth - 1; */
-
-/*     for(; out_d > in_d; out_d--); */
-
-       for (; in_d >= 0; in_d--) {
-               /* Possible Use of ls->new_varindex[jd->var[in_d]] */
-               _SSA_ASSERT(ls->new_varindex[in[in_d]] != UNUSED);
-
-               a = ls->new_varindex[in[in_d]];
-               _SSA_CHECK_BOUNDS(a, 0, ls->ssavarcount);
-
-               /* i <- top(stack[a]) */
-
-               _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
-               i = ls->stack[a][ls->stack_top[a]-1]; 
-               _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
-
-               /* Replace use of x with xi */
-
-#ifdef SSA_DEBUG_VERBOSE
-                       ssa_rename_print( NULL, "invar", in[in_d], ls->var_0[a]+i);
-#endif
-               in[in_d] = ls->var_0[a] + i;
-               lt = ls->lifetime + in[in_d];
-
-               lt->v_index = in[in_d];
-               lt->bb_last_use = -1;
-       }
-
-       iptr = ls->basicblocks[n]->iinstr;
-
-       for(iindex = 0; iindex < ls->basicblocks[n]->icount; iindex++, iptr++) {
-
-               /* check for use (s1, s2, s3 or special (argp) ) */
-
-               switch (icmd_table[iptr->opc].dataflow) {
-               case DF_3_TO_0:
-               case DF_3_TO_1: /* icmd has s1, s2 and s3 */
-                       j = ssa_rename_use(ls, n, iptr->sx.s23.s3.varindex);
-#ifdef SSA_DEBUG_VERBOSE
-                       ssa_rename_print( iptr, "s3 ", iptr->sx.s23.s3.varindex, j);
-#endif
-                       iptr->sx.s23.s3.varindex = j;
-
-                       /* now "fall through" for handling of s2 and s1 */
-
-               case DF_2_TO_0:
-               case DF_2_TO_1: /* icmd has s1 and s2 */
-                       j = ssa_rename_use(ls, n, iptr->sx.s23.s2.varindex);
-#ifdef SSA_DEBUG_VERBOSE
-                       ssa_rename_print( iptr, "s2 ", iptr->sx.s23.s2.varindex, j);
-#endif
-                       iptr->sx.s23.s2.varindex = j;
-
-                       /* now "fall through" for handling of s1 */
-
-               case DF_1_TO_0:
-               case DF_1_TO_1:
-               case DF_MOVE:
-               case DF_COPY:
-                       j = ssa_rename_use(ls, n, iptr->s1.varindex);
-#ifdef SSA_DEBUG_VERBOSE
-                       ssa_rename_print( iptr, "s1 ", iptr->s1.varindex, j);
-#endif
-                       iptr->s1.varindex = j;
-                       break;
-
-               case DF_INVOKE:
-               case DF_BUILTIN:
-               case DF_N_TO_1:
-                       /* do not use md->paramcount, pass-through stackslots have */
-                       /* to be renamed, too */
-                       i = iptr->s1.argcount;
-                       argp = iptr->sx.s23.s2.args;
-                       while (--i >= 0) {
-                               j = ssa_rename_use(ls, n, *argp);
-#ifdef SSA_DEBUG_VERBOSE
-                               ssa_rename_print( iptr, "arg", *argp, j);
-#endif
-                               *argp = j;
-                               argp++;
-                       }
-                       break;
-               }
-                       
-
-               /* Look for definitions (iptr->dst). INVOKE and BUILTIN have */
-               /* an optional dst - so they to be checked first */
-
-               v = UNUSED;
-               if (icmd_table[iptr->opc].dataflow == DF_INVOKE) {
-                       INSTRUCTION_GET_METHODDESC(iptr,md);
-                       if (md->returntype.type != TYPE_VOID)
-                               v = iptr->dst.varindex;
-               }
-               else if (icmd_table[iptr->opc].dataflow == DF_BUILTIN) {
-                       bte = iptr->sx.s23.s3.bte;
-                       md = bte->md;
-                       if (md->returntype.type != TYPE_VOID)
-                               v = iptr->dst.varindex;
-               }
-               else if (icmd_table[iptr->opc].dataflow >= DF_DST_BASE) {
-                       v = iptr->dst.varindex;
-               }
-
-               if (v != UNUSED) {
-                       j = ssa_rename_def(jd, def_count, iptr->dst.varindex);
-#ifdef SSA_DEBUG_VERBOSE
-                       ssa_rename_print( iptr, "dst", iptr->dst.varindex, j);
-#endif
-                       iptr->dst.varindex = j;
-               }
-
-                               /* ?????????????????????????????????????????????????????????? */
-                               /* Mark Def as use, too. Since param initialisation is in     */
-                               /* var_def and this would not remove this locals, if not used */
-                               /* elsewhere   */
-                               /* ?????????????????????????????????????????????????????????? */
-
-       }
-
-       /* change outstack Interface stackslots */
-       out = ls->basicblocks[n]->outvars;
-       out_d = ls->basicblocks[n]->outdepth - 1;
-
-       for (;out_d >= 0; out_d--) {
-               /* Possible Use of ls->new_varindex[jd->var[out_d]] */
-               _SSA_ASSERT(ls->new_varindex[out[out_d]] != UNUSED);
-
-               a = ls->new_varindex[out[out_d]];
-               _SSA_CHECK_BOUNDS(a, 0, ls->ssavarcount);
-
-               /* i <- top(stack[a]) */
-
-               _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
-               i = ls->stack[a][ls->stack_top[a]-1]; 
-               _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
-
-               /* Replace use of x with xi */
-
-#ifdef SSA_DEBUG_VERBOSE
-                       ssa_rename_print( NULL, "outvar", out[out_d], ls->var_0[a]+i);
-#endif
-               out[out_d] = ls->var_0[a] + i;
-               lt = ls->lifetime + out[out_d];
-
-               lt->v_index = out[out_d];
-               lt->bb_last_use = -1;
-       }
-
-       /* change use in phi Functions of Successors */
-
-       Y = graph_get_first_successor(gd, n, &iter_succ);
-       for(; Y != -1; Y = graph_get_next(&iter_succ)) {
-               _SSA_CHECK_BOUNDS(Y, 0, ls->basicblockcount);
-               k = graph_get_first_predecessor(gd, Y, &iter_pred);
-               for (j = 0; (k != -1) && (k != n); j++)
-                       k = graph_get_next(&iter_pred);
-               _SSA_ASSERT(k == n);
-
-               /* n is jth Predecessor of Y */
-
-               for(a = 0; a < ls->ssavarcount; a++)
-                       if (ls->phi[Y][a] != NULL) {
-
-                               /* i <- top(stack[a]) */
-                               
-                               if (ls->stack_top[a] == 1) {
-                                       /* no definition till now in controll flow */
-#ifdef SSA_DEBUG_VERBOSE
-                                       if (compileverbose) {
-                                               printf("Succ %3i Arg %3i \n", Y, j);
-                                               ssa_rename_print( NULL, "phi-use", ls->phi[Y][a][j+1], UNUSED);
-                                       }
-#endif
-                                       ls->phi[Y][a][j+1] = UNUSED;
-                               }
-                               else {
-                                       _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
-                                       i = ls->stack[a][ls->stack_top[a]-1]; 
-                                       _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
-
-                                       /* change jth operand from a0 to ai */
-
-                                       i = ls->var_0[a] + i;
-#ifdef SSA_DEBUG_VERBOSE
-                                       if (compileverbose) {
-                                               printf("Succ %3i Arg %3i \n", Y, j);
-                                               ssa_rename_print( NULL, "phi-use", ls->phi[Y][a][j+1], i);
-                                       }
-#endif
-                                       ls->phi[Y][a][j+1] = i;
-                                       _SSA_CHECK_BOUNDS(ls->phi[Y][a][j+1], 0,
-                                                                         ls->varcount_with_indices);
-
-                                       /* use by phi function has to be remembered, too */
-
-                                       ssa_rename_use_(ls, n, ls->phi[Y][a][j+1]);
-                               }
-
-                               /* ????????????????????????????????????????????? */
-                               /* why was this only for local vars before ?     */
-                               /* ????????????????????????????????????????????? */
-
-                       }
-       }
-       
-       /* Call ssa_rename_ for all Childs of n of the Dominator Tree */
-       for(i = 0; i < ls->basicblockcount; i++)
-               if (dd->idom[i] == n)
-                       ssa_rename_(jd, gd, dd, i);
-
-       /* pop Stack[a] for each definition of a var a in the original S */
-       for(a = 0; a < ls->ssavarcount; a++) {
-               ls->stack_top[a] -= def_count[a];
-               _SSA_ASSERT(ls->stack_top[a] >= 0);
-       }
-}
-
-
-
 #ifdef SSA_DEBUG_VERBOSE
 void ssa_print_trees(jitdata *jd, graphdata *gd, dominatordata *dd) {
        int i,j;
@@ -1411,98 +634,8 @@ void ssa_print_trees(jitdata *jd, graphdata *gd, dominatordata *dd) {
                printf(")\n");
        }
 }
-
-void ssa_print_phi(lsradata *ls, graphdata *gd) {
-       int i,j,k;
-
-       printf("phi Functions (varcount_with_indices: %3i):\n", 
-                  ls->varcount_with_indices);
-       for(i = 0; i < ls->basicblockcount; i++) {
-               for(j = 0; j < ls->ssavarcount; j++) {
-                       if (ls->phi[i][j] != NULL) {
-                               printf("BB %3i %3i = phi(", i, ls->phi[i][j][0]);
-                               for(k = 1; k <= graph_get_num_predecessor(gd, i); k++)
-                                       printf("%3i ",ls->phi[i][j][k]);
-                               printf(")\n");
-                       }
-               }
-       }
-
-}
-
 #endif
 
-void ssa_generate_phi_moves(jitdata *jd, graphdata *gd) {
-       int a, i, j, pred;
-       graphiterator iter;
-       lsradata *ls;
-
-       ls = jd->ls;
-
-       /* count moves to be inserted at the end of each block in moves[] */
-       ls->num_phi_moves = DMNEW(int, ls->basicblockcount);
-       for(i = 0; i < ls->basicblockcount; i++)
-               ls->num_phi_moves[i] = 0;
-       for(i = 0; i < ls->basicblockcount; i++)
-               for(a = 0; a < ls->ssavarcount; a++)
-                       if (ls->phi[i][a] != NULL) {
-#if 0
-                               if (ls->lifetime[ls->phi[i][a][0]].use == NULL) {
-                                       /* Var defined (only <- SSA Form!) in this phi function */
-                                       /* and not used anywhere -> delete phi function and set */
-                                       /* var to unused */
-
-                                       /* TODO: first delete use sites of arguments of phi */
-                                       /* function */
-                                       VAR(ls->lifetime[ls->phi[i][a][0]].v_index)->type = UNUSED;
-                                       ls->lifetime[ls->phi[i][a][0]].def = NULL;
-                                       ls->phi[i][a] = NULL;
-                               }
-                               else 
-#endif
-                                       {
-                                       pred = graph_get_first_predecessor(gd, i, &iter);
-                                       for(; pred != -1; pred = graph_get_next(&iter)) {
-                                               ls->num_phi_moves[pred]++;
-                                       }
-                               }
-                       }
-
-       /* allocate ls->phi_moves */
-       ls->phi_moves = DMNEW( int **, ls->basicblockcount);
-       for(i = 0; i < ls->basicblockcount; i++) {
-               ls->phi_moves[i] = DMNEW( int *, ls->num_phi_moves[i]);
-               for(j = 0; j <ls->num_phi_moves[i]; j++)
-                       ls->phi_moves[i][j] = DMNEW(int, 2);
-#ifdef SSA_DEBUG_VERBOSE
-               if (compileverbose)
-                       printf("ssa_generate_phi_moves: ls_num_phi_moves[%3i] = %3i\n",
-                                  i, ls->num_phi_moves[i]);
-#endif
-       }
-
-       /* populate ls->phi_moves */
-       for(i = 0; i < ls->basicblockcount; i++)
-               ls->num_phi_moves[i] = 0;
-       for(i = 0; i < ls->basicblockcount; i++)
-               for(a = 0; a < ls->ssavarcount; a++)
-                       if (ls->phi[i][a] != NULL) {
-                               pred = graph_get_first_predecessor(gd, i, &iter);
-                               for(j = 0; pred != -1; j++, pred = graph_get_next(&iter)) {
-                                       /* target is phi[i][a][0] */
-                                       /* source is phi[i][a][j+1] */
-                                       if (ls->phi[i][a][j+1] != ls->varcount_with_indices) {
-                                               /* valid move */
-                                               if (ls->phi[i][a][0] != ls->phi[i][a][j+1]) {
-                                                       ls->phi_moves[pred][ls->num_phi_moves[pred]][0] =
-                                                               ls->phi[i][a][0];
-                                                       ls->phi_moves[pred][(ls->num_phi_moves[pred])++][1]=
-                                                               ls->phi[i][a][j+1];
-                                               }
-                                       }
-                               }
-                       }
-}
 
 /****************************************************************************
 Optimizations
@@ -1532,26 +665,34 @@ void dead_code_elimination(jitdata *jd, graphdata *gd) {
 
        W = wl_new(ls->lifetimecount);
        if (ls->lifetimecount > 0) {
-               /* put all lifetimes on Worklist */
+
+               /* put all lifetimes into Worklist W */
+
                for(a = 0; a < ls->lifetimecount; a++) {
-                       if (ls->lifetime[a].type != -1) {
+                       if (ls->lifetime[a].type != UNUSED) {
                                wl_add(W, a);
                        }
                }
        }
 
        /* Remove unused lifetimes */
+
        while(!wl_is_empty(W)) {
+
                /* take a var out of Worklist */
+
                a = wl_get(W);
 
                lt = &(ls->lifetime[a]);
-               if ((lt->def == NULL) || (lt->type == -1))
+               if ((lt->def == NULL) || (lt->type == UNUSED))
+
                        /* lifetime was already removed -> no defs anymore */
+
                        continue;
 
-               /* Remove lifetimes, which are only used in a phi function, which 
-                  defines them! */
+               /* Remove lifetimes, which are only used in the phi function which */
+               /* defines them! */
+
                remove_statement = (lt->use != NULL) && (lt->use->iindex < 0);
                for(use = lt->use; (remove_statement && (use != NULL)); 
                        use = use->next)
@@ -1560,21 +701,29 @@ void dead_code_elimination(jitdata *jd, graphdata *gd) {
                                (use->b_index == lt->def->b_index) &&
                                (use->iindex == lt->def->iindex);
                }
+
                if (remove_statement) {
 #ifdef SSA_DEBUG_CHECK
+
                        /* def == use can only happen in phi functions */
+
                        if (remove_statement)
                                _SSA_ASSERT(lt->use->iindex < 0);
 #endif
+
                        /* give it free for removal */
+
                        lt->use = NULL;
                }
 
                if (lt->use == NULL) {
+
                        /* Look at statement of definition of a and remove it,           */
                        /* if the Statement has no sideeffects other than the assignemnt */
                        /* of a */
+
                        if (lt->def->iindex < 0 ) {
+
                                /* phi function */
                                /* delete use of sources , delete phi functions  */
 
@@ -1582,32 +731,44 @@ void dead_code_elimination(jitdata *jd, graphdata *gd) {
                                                        NULL);
 
                                for (i = 1;i <= graph_get_num_predecessor(gd, lt->def->b_index);
-                                        i++) 
-                                       {
-                                               source =
-                                                       ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
-                                               if ((source != ls->varcount_with_indices) && 
-                                                       (source != lt->v_index)) {
+                                        i++) {
+                                       source =
+                                               ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
+                                       if ((source != ls->varcount_with_indices) && 
+                                               (source != lt->v_index) &&
+                                               (source != UNUSED)) {
 
-                                                       /* phi Argument was not already removed (already in 
-                                                          because of selfdefinition) */
+                                               /* phi Argument was not already removed (already in 
+                                                  because of "selfdefinition") */
 
-                                                       s_lt = &(ls->lifetime[source]);
+                                               s_lt = &(ls->lifetime[source]);
 
-                                                       /* remove it */
+                                               /* remove it */
 
-                                                       lt_remove_use_site(s_lt,lt->def->b_index,
-                                                                                       lt->def->iindex);
+                                               lt_remove_use_site(s_lt,lt->def->b_index,
+                                                                                  lt->def->iindex);
 
-                                                       /*  put it on the Worklist */
+                                               /*  put it on the Worklist */
 
-                                                       wl_add(W, source);
-                                               }
+                                               wl_add(W, source);
                                        }
+                               }
+
                                /* now delete phi function itself */
+#ifdef SSA_DEBUG_VERBOSE
+                                       if (compileverbose) {
+                                               printf("dce: BB%3i phi for var %3i=%3i removed \n",
+                                                          lt->def->b_index, -lt->def->iindex - 1,
+                                                          lt->v_index);
+                                       }
+#endif
+
                                ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
-                       } else {
+                       }
+                       else {
+
                                /* "normal" Use by ICMD */
+
                                remove_statement = false;
                                if (lt->def->b_index != 0) {
 
@@ -1616,56 +777,63 @@ void dead_code_elimination(jitdata *jd, graphdata *gd) {
                                        iptr = ls->basicblocks[lt->def->b_index]->iinstr + 
                                                lt->def->iindex;
 
-                                       if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI)
-                                               remove_statement = false;
+                                       if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI) {
 
-                                       /* if ICMD could throw an exception do not remove it! */
+                                               /* if ICMD could throw an exception do not remove it! */
 
-                                       else {
+                                               remove_statement = false;
+#ifdef SSA_DEBUG_VERBOSE
+                                               if (compileverbose) {
+                                                       printf("dce: PEI: BB%3i II%3i %s not removed \n",
+                                                                  lt->def->b_index, lt->def->iindex,
+                                                                  bytecode[iptr->opc].mnemonic);
+                                               }
+#endif
 
-                                               /* ICMD_INVOKE*, ICMD_BUILTIN and ICMD_MULTIANEWARRAY */
-                                               /* have possible sideeffects -> do not remove them    */
-
-/*                                             remove_statement = !(ICMD_HAS_SPECIAL(iptr->opc)); */
-
-                                               remove_statement = !(
-                                                       (icmd_table[iptr->opc].dataflow == DF_INVOKE) ||
-                                                       (icmd_table[iptr->opc].dataflow == DF_BUILTIN) ||
-                                                       (icmd_table[iptr->opc].dataflow == DF_N_TO_1));
-
-                                               if (remove_statement) {
-                                                       switch (icmd_table[iptr->opc].dataflow) {
-                                                       case DF_3_TO_0:
-                                                       case DF_3_TO_1: /* icmd has s1, s2 and s3 */
-                                                               a = iptr->sx.s23.s3.varindex;
-                                                               s_lt = ls->lifetime + a;
-                                                               lt_remove_use_site(s_lt, lt->def->b_index,
-                                                                                                  lt->def->iindex);
-                                                               wl_add(W, a);
-
-                                                               /* now "fall through" for handling of s2 and s1 */
-
-                                                       case DF_2_TO_0:
-                                                       case DF_2_TO_1: /* icmd has s1 and s2 */
-                                                               a = iptr->sx.s23.s2.varindex;
-                                                               s_lt = ls->lifetime + a;
-                                                               lt_remove_use_site(s_lt, lt->def->b_index,
-                                                                                                  lt->def->iindex);
-                                                               wl_add(W, a);
-
-                                                               /* now "fall through" for handling of s1 */
-
-                                                       case DF_1_TO_0:
-                                                       case DF_1_TO_1:
-                                                       case DF_MOVE:
-                                                       case DF_COPY:
-                                                               a = iptr->s1.varindex;
-                                                               s_lt = ls->lifetime + a;
-                                                               lt_remove_use_site(s_lt, lt->def->b_index,
-                                                                                                  lt->def->iindex);
-                                                               wl_add(W, a);
-                                                       }
+                                       }
+                                       else {
+                                               remove_statement = true;
+
+                                               switch (icmd_table[iptr->opc].dataflow) {
+                                               case DF_3_TO_0:
+                                               case DF_3_TO_1: /* icmd has s1, s2 and s3 */
+                                                       a = iptr->sx.s23.s3.varindex;
+                                                       s_lt = ls->lifetime + a;
+                                                       lt_remove_use_site(s_lt, lt->def->b_index,
+                                                                                          lt->def->iindex);
+                                                       wl_add(W, a);
+
+                                                       /* "fall through" for handling of s2 and s1 */
+
+                                               case DF_2_TO_0:
+                                               case DF_2_TO_1: /* icmd has s1 and s2 */
+                                                       a = iptr->sx.s23.s2.varindex;
+                                                       s_lt = ls->lifetime + a;
+                                                       lt_remove_use_site(s_lt, lt->def->b_index,
+                                                                                          lt->def->iindex);
+                                                       wl_add(W, a);
+
+                                                       /* "fall through" for handling of s1 */
+
+                                                       /* DF_{IINC,STORE,LOAD} are DF_{1_TO_1,MOVE,COPY} */
+
+                                               case DF_1_TO_0:
+                                               case DF_1_TO_1:
+                                               case DF_MOVE:
+                                               case DF_COPY:
+                                                       a = iptr->s1.varindex;
+                                                       s_lt = ls->lifetime + a;
+                                                       lt_remove_use_site(s_lt, lt->def->b_index,
+                                                                                          lt->def->iindex);
+                                                       wl_add(W, a);
+                                               }
+#ifdef SSA_DEBUG_VERBOSE
+                                               if (compileverbose) {
+                                                       printf("dce: BB%3i II%3i %s removed \n",
+                                                                  lt->def->b_index, lt->def->iindex,
+                                                                  bytecode[iptr->opc].mnemonic);
                                                }
+#endif
                                        }
 
                                        if (remove_statement) {
@@ -1674,8 +842,8 @@ void dead_code_elimination(jitdata *jd, graphdata *gd) {
 
 #ifdef SSA_DEBUG_VERBOSE
                                                if (compileverbose)
-                                                       printf("INFO: %s %s:at BB %3i II %3i NOP-<%s\n",
-                                                                  m->class->name->text, m->name->text, 
+                                                       printf("dce: %s %s:at BB %3i II %3i NOP-<%s\n",
+                                                                  m->clazz->name->text, m->name->text, 
                                                                   lt->def->b_index, lt->def->iindex, 
                                                                   icmd_table[iptr->opc].name);
 #endif
@@ -1686,9 +854,14 @@ void dead_code_elimination(jitdata *jd, graphdata *gd) {
 
                        /* remove definition of a */
 
-                       VAR(lt->v_index)->type = -1;
-                       lt->type = -1;
+#ifdef SSA_DEBUG_VERBOSE
+                       if (compileverbose)
+                               printf("dce: var %3i removed\n", lt->v_index);
+#endif
+                       VAR(lt->v_index)->type = UNUSED;
+                       lt->type = UNUSED;
                        lt->def = NULL;
+/*                     jd->var */
                } /* if (lt->use == NULL) */
        } /* while(!wl_is_empty(W)) */
 } /* dead_code_elimination */
@@ -1711,7 +884,6 @@ void copy_propagation(jitdata *jd, graphdata *gd) {
 
        instruction *iptr;
        struct lifetime *lt, *s_lt;
-       s4 *in;
 
        lsradata *ls;
 
@@ -1721,7 +893,7 @@ void copy_propagation(jitdata *jd, graphdata *gd) {
        if (ls->lifetimecount > 0) {
                /* put all lifetimes on Worklist */
                for(a = 0; a < ls->lifetimecount; a++) {
-                       if (ls->lifetime[a].type != -1) {
+                       if (ls->lifetime[a].type != UNUSED) {
                                wl_add(W, a);
                        }
                }
@@ -1732,10 +904,12 @@ void copy_propagation(jitdata *jd, graphdata *gd) {
                a = wl_get(W);
 
                lt = ls->lifetime + a;
-               if (lt->type == -1)
+               if (lt->type == UNUSED)
                        continue;
                _SSA_ASSERT(lt->def != NULL);
+#if 0
                _SSA_ASSERT(lt->use != NULL);
+#endif
                if (lt->def->iindex < 0 ) {
 
                        /* phi function */
@@ -1748,159 +922,146 @@ void copy_propagation(jitdata *jd, graphdata *gd) {
                        for (i = 1; i <= graph_get_num_predecessor(gd, lt->def->b_index);
                                 i++) {
                                        source = ls->phi[lt->def->b_index][-lt->def->iindex-1][i];
-                                       if (source != ls->varcount_with_indices) {      
+                                       if ((source != ls->varcount_with_indices) && 
+                                               (source != UNUSED)) {   
                                                if (only_source == ls->varcount_with_indices) {
+
                                                        /* first valid source argument of phi function */
+
                                                        only_source = source;
                                                } else {
+
                                                        /* second valid source argument of phi function */
                                                        /* exit for loop */
+
                                                        only_source = ls->varcount_with_indices;
                                                        break;
                                                }
                                        }
                        }
+
                        if (only_source != ls->varcount_with_indices) {
                                
+#ifdef SSA_DEBUG_VERBOSE
+                               if (compileverbose)
+                                       printf(
+                                                  "-- copy propagation phi-func: BB %3i II %3i: %3i -> %3i\n",
+                                                  lt->def->b_index, lt->def->iindex,
+                                                  only_source, lt->v_index);
+#endif
+                               s_lt = ls->lifetime + only_source;
+
                                /* replace all use sites of lt with the var_index only_source */
 
                                ssa_replace_use_sites( jd, gd, lt, only_source, W);
 
-                               /* delete def of lt and replace uses of lt with "only_source" */
+                               /* delete def of lt */
 
                                ls->phi[lt->def->b_index][-lt->def->iindex-1] = NULL;
 
-                               s_lt = ls->lifetime + only_source;
+                               /* remove this deleted use site of s_lt */
 
-                               VAR(lt->v_index)->type = -1;
                                lt_remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
+
                                lt->def = NULL;
+
                                /* move use sites from lt to s_lt */
+
                                lt_move_use_sites(lt, s_lt);
-                               lt->type = -1;
+
+                               /* invalidate lt */
+
+                               lt->type = UNUSED;
+                               VAR(lt->v_index)->type = UNUSED;
+
+                               /* add s_lt again to Worklist W */
+
+                               wl_add(W, s_lt->v_index);
+#ifdef SSA_DEBUG_VERBOSE
+                               if (compileverbose)
+                                       _ssa_print_lt(s_lt);
+#endif
                        } /* if (only_source != ls->varcount_with_indices) */
-               } else { /* if (lt->def->iindex < 0 )*/ 
+               }
+               else { /* if (lt->def->iindex < 0 ) */  
+
+                       /* def in argument passing - no propagation possible */
+                       /* (there is no ICMD for this... */
+
+                       if (lt->def->b_index == 0)
+                               continue;
+
                        /* def in "normal" ICMD */
-#if 0
+
                        iptr = ls->basicblocks[lt->def->b_index]->iinstr + 
                                lt->def->iindex;
-               
-                       if ( localvar ) {
-                               if (lt->def->b_index == 0)
-                                       continue;
-                               
-                               switch(iptr->opc) {
-                               case ICMD_ISTORE:
-                               case ICMD_LSTORE:
-                               case ICMD_FSTORE:
-                               case ICMD_DSTORE:
+                       
+                       switch(iptr->opc) {
+                       case ICMD_ISTORE:
+                       case ICMD_LSTORE:
+                       case ICMD_FSTORE:
+                       case ICMD_DSTORE:
                        case ICMD_ASTORE:
-                                       if (lt->def->iindex == 0) {
-                                               /* first instruction in bb -> instack==bb->instack */
-                                               in = ls->basicblocks[lt->def->b_index]->instack;
-                                       } else {
-                                               /* instack is (iptr-1)->dst */
-                                               in = (iptr-1)->dst;
-                                       }
-                                       
-                                       if (in->varkind != LOCALVAR) {
+                       case ICMD_ILOAD:
+                       case ICMD_LLOAD:
+                       case ICMD_FLOAD:
+                       case ICMD_DLOAD:
+                       case ICMD_ALOAD:
+                       case ICMD_MOVE:
 #ifdef SSA_DEBUG_VERBOSE
-                                               if (compileverbose)
-                                                       printf("copy propagation xstore: BB %3i I %3i: %3i -> %3i\n", lt->def->b_index, lt->def->iindex, iptr->op1, in->varnum);
+                               if (compileverbose)
+                                       printf(
+                                                  "-- copy propagation %3i %s: BB %3i II %3i: %3i -> %3i\n",
+                                                  iptr->opc, bytecode[iptr->opc].mnemonic,
+                                                  lt->def->b_index, lt->def->iindex,
+                                                  iptr->s1.varindex, iptr->dst.varindex);
 #endif
-                                               s_lt = &(ls->lifetime[-in->varnum-1]);
-                                               
-                                               for (ss = s_lt->local_ss; ss != NULL; ss = ss->next) {
-                                                       ss->s->varkind = LOCALVAR;
-                                                       ss->s->varnum = iptr->op1;
-                                               }
-                                               
-                                               /* replace all use sites of s_lt with the var_index */
-                                               /* iptr->op1 */
-
-                                               ssa_replace_use_sites(jd, gd, s_lt, iptr->op1, W);
+                               s_lt = ls->lifetime + iptr->s1.varindex;
                                
-                                               /* s_lt->def is the new def site of lt */
-                                               /* the old ->def site will get a use site of def */
-                                               /* only one def site */
-                                               _SSA_ASSERT(lt->def->next == NULL);
-                                               _SSA_ASSERT(s_lt->def != NULL);
-                                               _SSA_ASSERT(s_lt->def->next == NULL);
-
-                                               /* replace def of s_lt with iptr->op1 */
-                                               if (s_lt->def->iindex < 0) {
-                                                       /* phi function */
-                                                       _SSA_ASSERT(ls->phi[s_lt->def->b_index]
-                                                                              [-s_lt->def->iindex-1]
-                                                                       != NULL);
-                                                       ls->phi[s_lt->def->b_index][-s_lt->def->iindex-1][0]
-                                                               = iptr->op1;
-                                               } else
-                                                       if (in->varnum != iptr->op1)
-                                                               printf("copy propagation: LOCALVAR ss->ISTORE BB %i II %i\n",
-                                                                          lt->def->b_index, lt->def->iindex);
-                                                       
+                               _SSA_ASSERT( lt->v_index == iptr->dst.varindex);
+                               
+                               /* replace all use sites of lt with the var_index */
+                               /* iptr->s1.varindex (==lt->v_index) */
+                               
+                               ssa_replace_use_sites(jd, gd, lt, iptr->s1.varindex, W);
+                               
+                               _SSA_ASSERT(lt->def->next == NULL);
+                               _SSA_ASSERT(s_lt->def != NULL);
+                               _SSA_ASSERT(s_lt->def->next == NULL);
 
-                                               /* move def to use sites of lt */
-                                               lt->def->next = lt->use;
-                                               lt->use = lt->def;
-                                               
-                                               lt->def = s_lt->def;
+                               /* this ICMD is not a PEI -> so no danger in deleting it!     */
+                               /* delete def of lt (ICMD_NOP) */
 
-                                               s_lt->def = NULL;
+                               /* lt->def->iindex > 0 -> ICMD */
 
+                               iptr->opc = ICMD_NOP;
 
-                                               /* move use sites from s_lt to lt */
-                                               move_use_sites(s_lt, lt);
-                                               move_stackslots(s_lt, lt);
-                                               s_lt->type = -1;
-                                       }
-                                       break;
-                               }
-                       } else {
-                               /* Def Interface Stackslot */
-
-                               switch(iptr->opc) {
-                               case ICMD_ILOAD:
-                               case ICMD_LLOAD:
-                               case ICMD_FLOAD:
-                               case ICMD_DLOAD:
-                               case ICMD_ALOAD:
-                                       only_source = lt->local_ss->s->varnum;
-                                       if (lt->local_ss->s->varkind != LOCALVAR) {
-#ifdef SSA_DEBUG_VERBOSE
-                                               if (compileverbose)
-                                                       printf("copy propagation xload: BB %3i I %3i: %3i -> %3i\n", lt->def->b_index, lt->def->iindex, iptr->op1, lt->local_ss->s->varnum);
-#endif
-                                               _SSA_ASSERT(iptr->dst->varnum == lt->local_ss->s->varnum);
-                                               for (ss = lt->local_ss; ss != NULL; ss = ss->next) {
-                                                       ss->s->varkind = LOCALVAR;
-                                                       ss->s->varnum = iptr->op1;
-                                               }
+                               /* remove this deleted use site of s_lt */
 
-                                               /* replace all use sites of lt with the var_index iptr->op1*/
+                               lt_remove_use_site(s_lt, lt->def->b_index, lt->def->iindex);
 
-                                               ssa_replace_use_sites(jd, gd, lt, iptr->op1, W);
+                               /* invalidate def site of lt */
                                
-                                               lt->def = NULL;
-
-                                               s_lt = &(ls->lifetime[ls->maxlifetimes + iptr->op1]);
-
-                                               /* move use sites from lt to s_lt */
-                                               move_use_sites(lt, s_lt);
-                                               move_stackslots(lt, s_lt);
-                                               lt->type = -1;
-                                       } else
-                                               if (lt->local_ss->s->varnum != iptr->op1)
-                                                       printf("copy propagation: ILOAD -> LOCALVAR ss BB %i II %i\n",
-                                                                  lt->def->b_index, lt->def->iindex);
-                                       
-                                       break;
-                               }
-                       } /* localvar or interface stackslot */
+                               lt->def = NULL;
+                               
+                               /* move use sites from lt to s_lt */
+                               
+                               lt_move_use_sites(lt, s_lt);
+
+                               /* invalidate lt */
+
+                               lt->type = UNUSED;
+                               VAR(lt->v_index)->type = UNUSED;
+
+                               /* add s_lt again to Worklist W */
+                               wl_add(W, s_lt->v_index);
+#ifdef SSA_DEBUG_VERBOSE
+                               if (compileverbose)
+                                       _ssa_print_lt(s_lt);
 #endif
-               } /* i(lt->def->iindex < 0 ) */
-               
+                               break;
+                       }
+               } /* if (lt->def->iindex < 0 ) */
        } /* while(!wl_is_empty(W)) */
 }
 
@@ -1926,17 +1087,37 @@ void ssa_replace_use_sites(jitdata *jd, graphdata *gd, struct lifetime *lt,
 
                        for (i = 1;i <= graph_get_num_predecessor(gd, s->b_index); i++) {
                                source = ls->phi[s->b_index][-s->iindex-1][i];
-                               if (source == lt->v_index) {    
+                               if (source == lt->v_index) {
+
+                                       /* check if this use in this phi function is a     */
+                                       /* "selfdefinition" (x = phi(...,x,...))           */
+                                       /* if so replace the use with -1 (x=phi(...,-1,...)*/
+
+                                       if (new_v_index == ls->phi[s->b_index][-s->iindex-1][0]) {
 #ifdef SSA_DEBUG_VERBOSE
-                                       if (W != NULL) {
-                                               if (compileverbose)
-                                                       printf("copy propagation phi: BB %3i I %3i: %3i -> \
-                                     %3i\n", s->b_index, s->iindex,
-                                                                  new_v_index, source);
+                                               if (W != NULL) {
+                                                       if (compileverbose)
+                                                               printf(
+                                                        "copy propagation phi: BB %3i I %3i: %3i -> %3i\n",
+                                                        s->b_index, s->iindex, -1, source);
+                                               }
+#endif
+                                               ls->phi[s->b_index][-s->iindex-1][i] = -1;
+
+                                               /* remove this use site of use site */
+                                               lt_remove_use_site(lt, s->b_index, s->iindex);
                                        }
+                                       else {
+#ifdef SSA_DEBUG_VERBOSE
+                                               if (W != NULL) {
+                                                       if (compileverbose)
+                                                               printf(
+                                                        "copy propagation phi: BB %3i I %3i: %3i -> %3i\n",
+                                                        s->b_index, s->iindex, new_v_index, source);
+                                               }
 #endif
-                                       ls->phi[s->b_index][-s->iindex-1][i]
-                                               = new_v_index;
+                                               ls->phi[s->b_index][-s->iindex-1][i] = new_v_index;
+                                       }
                                }
                        }
                        if (W != NULL) {
@@ -1963,7 +1144,7 @@ void ssa_replace_use_sites(jitdata *jd, graphdata *gd, struct lifetime *lt,
 #ifdef SSA_DEBUG_VERBOSE
                                        if (W != NULL) {
                                                if (compileverbose)
-                                                       printf("copy propagation loc: BB %3i I %3i: %3i -> \
+                                                       printf("copy propagation loc3: BB %3i I %3i: %3i -> \
                                     %3i\n", s->b_index, s->iindex,
                                                                   new_v_index, iptr->sx.s23.s3.varindex);
                                        }
@@ -1979,7 +1160,7 @@ void ssa_replace_use_sites(jitdata *jd, graphdata *gd, struct lifetime *lt,
 #ifdef SSA_DEBUG_VERBOSE
                                        if (W != NULL) {
                                                if (compileverbose)
-                                                       printf("copy propagation loc: BB %3i I %3i: %3i -> \
+                                                       printf("copy propagation loc2: BB %3i I %3i: %3i -> \
                                     %3i\n", s->b_index, s->iindex,
                                                                   new_v_index, iptr->sx.s23.s2.varindex);
                                        }
@@ -1997,9 +1178,10 @@ void ssa_replace_use_sites(jitdata *jd, graphdata *gd, struct lifetime *lt,
 #ifdef SSA_DEBUG_VERBOSE
                                        if (W != NULL) {
                                                if (compileverbose)
-                                                       printf("copy propagation loc: BB %3i I %3i: %3i -> \
-                                    %3i\n", s->b_index, s->iindex,
-                                                                  new_v_index, iptr->s1.varindex);
+                                                       printf(
+                                                       "copy propagation loc1: BB %3i I %3i: %3i -> %3i\n",
+                                                       s->b_index, s->iindex, new_v_index,
+                                                       iptr->s1.varindex);
                                        }
 #endif
                                        iptr->s1.varindex = new_v_index;
@@ -2032,7 +1214,7 @@ void ssa_replace_use_sites(jitdata *jd, graphdata *gd, struct lifetime *lt,
                                                if (W != NULL) {
                                                        if (compileverbose)
                                                                printf(
-                                                                          "copy propagation loc: BB %3i I %3i: %3i -> %3i\n"
+                                                                          "copy propagation locN: BB %3i I %3i: %3i -> %3i\n"
                                                                           , s->b_index, s->iindex, new_v_index, *argp);
                                                }
 #endif
@@ -2051,21 +1233,26 @@ void ssa_replace_use_sites(jitdata *jd, graphdata *gd, struct lifetime *lt,
 void ssa_print_lt(lsradata *ls) {
        int i;
        struct lifetime *lt;
-       struct site *use;
 
        printf("SSA LT Def/Use\n");
        for(i = 0; i < ls->lifetimecount; i++) {
                lt = ls->lifetime + i;
-               if (lt->type != UNUSED) {
-                       printf("VI %3i Type %3i Def: ",lt->v_index, lt->type);
-                       if (lt->def != NULL)
-                               printf("%3i,%3i Use: ",lt->def->b_index, lt->def->iindex);
-                       else
-                               printf("%3i,%3i Use: ",0,0);
-                       for(use = lt->use; use != NULL; use = use->next)
-                               printf("%3i,%3i ",use->b_index, use->iindex);
-                       printf("\n");
-               }
+               _ssa_print_lt(lt);
+       }
+}
+
+void _ssa_print_lt(struct lifetime *lt) {
+       struct site *use;
+
+       if (lt->type != UNUSED) {
+               printf("VI %3i Type %3i Def: ",lt->v_index, lt->type);
+               if (lt->def != NULL)
+                       printf("%3i,%3i Use: ",lt->def->b_index, lt->def->iindex);
+               else
+                       printf("%3i,%3i Use: ",0,0);
+               for(use = lt->use; use != NULL; use = use->next)
+                       printf("%3i,%3i ",use->b_index, use->iindex);
+               printf("\n");
        }
 }
 
index 72e9b898bc1e043e5562da9f977aa2f62b71fba1..56ba88184953ecfde3b09a9475d03250d7589834 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/optimizing/ssa.h - static single assignment form header
 
-   Copyright (C) 2005, 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   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
@@ -26,6 +26,7 @@
 
    Authors: Christian Ullrich
 
+   $Id: ssa.h$
 
 */
 
@@ -51,7 +52,7 @@
 
 /* function prototypes */
 void ssa_init(jitdata *);
-void ssa(jitdata *, graphdata *);
+void ssa(jitdata */* , graphdata **/);
 
 #endif /* _SSA_H */
 
diff --git a/src/vm/jit/optimizing/ssa2.c b/src/vm/jit/optimizing/ssa2.c
new file mode 100644 (file)
index 0000000..0246777
--- /dev/null
@@ -0,0 +1,657 @@
+/* src/vm/optimizing/ssa2.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.
+
+   Reimplementation of code in ssa.c. 
+   Uses the new dominator tree and the new CFG.
+*/
+
+#include "config.h"
+
+#include "mm/memory.h"
+
+#include "toolbox/bitvector.h"
+#include "toolbox/set.h"
+#include "toolbox/worklist.h"
+
+#include "vm/global.h"
+#include "vm/jit/jit.h"
+
+#if 1
+#define printf(...) do { if (getenv("VERB")) printf(__VA_ARGS__); } while (0)
+#define show_method(...) do { if (getenv("VERB")) show_method(__VA_ARGS__); } while (0)
+#endif
+
+typedef struct phi_function {
+       s4 dst;
+       s4 *args;
+} phi_function;
+
+typedef struct basicblock_info {
+       bitvector defines;
+       bitvector phi;
+       unsigned phi_count;
+       phi_function *phi_functions;
+} basicblock_info;
+
+typedef struct var_info {
+       set *work;
+       unsigned num_defs;
+
+       unsigned offset;
+
+       unsigned count;
+       unsigned *stack;
+       unsigned *stack_top;
+
+} var_info;
+
+typedef struct ssa_info {
+       jitdata *jd;
+       var_info *vars;
+       unsigned vars_count;
+       unsigned total_local_count;
+} ssa_info;
+
+static inline basicblock_info *bb_info(basicblock *bb) {
+       return (basicblock_info *)(bb->vp);
+}
+
+static ssa_info *ssa_init(jitdata *jd) {
+       unsigned i;
+       ssa_info *ssa;
+
+       ssa = DNEW(ssa_info);
+       ssa->jd = jd;
+       ssa->vars_count = jd->localcount;
+
+       ssa->vars = DMNEW(var_info, ssa->vars_count);
+       MZERO(ssa->vars, var_info, ssa->vars_count);
+       for (i = 0; i < ssa->vars_count; ++i) {
+               ssa->vars[i].work = set_new(jd->basicblockcount);
+       }
+
+       return ssa;
+}
+
+static void ssa_place_phi_functions(ssa_info *ssa) {
+
+       basicblock *bptr, *Y, *n, **itdf;
+       basicblock_info *bbi;
+       instruction *iptr;
+       s4 a;
+       set *work;
+
+       for (bptr = ssa->jd->basicblocks; bptr; bptr = bptr->next) {
+       
+               bbi = DNEW(basicblock_info);
+               bbi->defines = bv_new(ssa->vars_count);
+               bbi->phi = bv_new(ssa->vars_count);
+               bbi->phi_count = 0;
+
+               bptr->vp = bbi;
+
+               for (iptr = bptr->iinstr; iptr != bptr->iinstr + bptr->icount; ++iptr) {
+                       if (instruction_has_dst(iptr)) {
+                               if (
+                                       var_is_local(ssa->jd, iptr->dst.varindex) 
+                               ) {
+                                       /* A_orig */
+                                       bv_set_bit(bbi->defines, iptr->dst.varindex);
+                                       /* defsites */
+                                       set_insert(ssa->vars[iptr->dst.varindex].work, bptr);
+                                       /* Accout definition */
+                                       ssa->vars[iptr->dst.varindex].num_defs += 1;
+                               }
+                       }
+               }
+       }
+
+       bptr = ssa->jd->basicblocks;
+       bbi = bb_info(bptr);
+       for (a = 0;  a < ssa->vars_count; ++a) {
+               bv_set_bit(bbi->defines, a);
+               set_insert(ssa->vars[a].work, bptr);
+               ssa->vars[a].num_defs += 1;
+       }
+
+       for (a = 0; a < ssa->vars_count; ++a) {
+               work = ssa->vars[a].work;
+               while (! set_empty(work)) {
+                       n = (basicblock *)set_pop(work);
+                       for (
+                               itdf = n->domfrontier; 
+                               itdf != n->domfrontier + n->domfrontiercount; 
+                               ++itdf
+                       ) {
+                               Y = *itdf;
+                               if (! bv_get_bit(bb_info(Y)->phi, a)) {
+                                       bv_set_bit(bb_info(Y)->phi, a);
+                                       printf(" *** BB %d: phi for var %d\n", Y->nr, a);
+                                       bb_info(Y)->phi_count += 1;
+                                       ssa->vars[a].num_defs += 1;
+                                       if (! bv_get_bit(bb_info(Y)->defines, a)) {
+                                               set_insert(work, Y);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+static void ssa_create_phi_functions(ssa_info *ssa) {
+       unsigned i, j;
+       basicblock_info *bbi;
+       basicblock *bptr;
+       phi_function *itph;
+
+       for (bptr = ssa->jd->basicblocks; bptr; bptr = bptr->next) {
+
+               bbi = bb_info(bptr);
+               bbi->phi_functions = DMNEW(phi_function, bbi->phi_count);
+               itph = bbi->phi_functions;
+
+               for (i = 0; i < ssa->vars_count; ++i) {
+                       if (bv_get_bit(bbi->phi, i)) {
+                               itph->dst = i;
+                               itph->args = DMNEW(s4, bptr->predecessorcount);
+                               for (j = 0; j < bptr->predecessorcount; ++j) {
+                                       itph->args[j] = i;
+                               }
+                               itph += 1;
+                       }
+               }
+       }
+}
+
+static void ssa_calculate_offsets(ssa_info *ssa) {
+       int i;
+       unsigned cur_offset = ssa->jd->localcount;
+
+       ssa->total_local_count = 0;
+
+       for (i = 0; i < ssa->vars_count; ++i) {
+
+               ssa->vars[i].offset = cur_offset;
+
+               ssa->total_local_count += ssa->vars[i].num_defs;
+
+               if (ssa->vars[i].num_defs > 1) {
+                       cur_offset += (ssa->vars[i].num_defs - 1);
+               }
+       }
+}
+
+
+static s4 ssa_rename_var(ssa_info *ssa, s4 var, unsigned index) {
+       s4 ret;
+#define return ret=
+       if (var_is_local(ssa->jd, var)) {
+               assert(0 < index && index <= ssa->vars[var].num_defs);
+               if (index == 1) {
+                       return var;
+               } else {
+                       return ssa->vars[var].offset + (index - 2);
+               }
+               assert(ret < ssa->total_local_count);
+       } else {
+               return ssa->total_local_count + (var - ssa->vars_count);
+       }
+#undef return
+       printf(" *** rename %c %d vers %d => %d\n", var_is_local(ssa->jd, var) ? 'L' : 'O',  var, index, ret);
+       return ret;
+}
+
+static void ssa_rename_uses(ssa_info *ssa, s4 *uses, unsigned uses_count) {
+       while (uses_count > 0) {
+               if (var_is_local(ssa->jd, *uses)) {
+                       *uses = ssa_rename_var(ssa, *uses, *(ssa->vars[*uses].stack_top));
+               } else {
+                       *uses = ssa_rename_var(ssa, *uses, 0);
+               }
+               uses_count -= 1;
+               uses += 1;
+       }
+}
+
+static void ssa_rename_definition(ssa_info *ssa, s4 *pdef) {
+       s4 def = *pdef;
+       unsigned i = 0;
+
+       if (var_is_local(ssa->jd, def)) {
+               ssa->vars[def].count += 1;
+               i = ssa->vars[def].count;
+               ssa->vars[def].stack_top += 1;
+               *(ssa->vars[def].stack_top) = i;
+       }
+
+       *pdef = ssa_rename_var(ssa, def, i);
+}
+
+static void ssa_rename_block(ssa_info *ssa, basicblock *bptr) {
+
+       basicblock_info *bbi = bb_info(bptr);
+       s4 s[3];
+       s4 *uses;
+       unsigned uses_count;
+       instruction *iptr;
+       basicblock **itsucc, **itpred, **itdsucc, *Y;
+       phi_function *itph;
+       unsigned j;
+       s4 i, tmp;
+       s4 a;
+       s4 **orig_stack_top;
+
+       /* XXX */
+       orig_stack_top = DMNEW(s4 *, ssa->vars_count);
+       for (a = 0; a < ssa->vars_count; ++a) orig_stack_top[a] = ssa->vars[a].stack_top;
+
+               int jj;
+
+printf(" *** === %d ===========\n", bptr->nr);
+
+       ssa_rename_uses(ssa, bptr->invars, bptr->indepth);
+
+       /* Phi functions are the first instructions in the block */
+printf(" *** --- phis ---------\n");
+       for (
+               itph = bbi->phi_functions; 
+               itph != bbi->phi_functions + bbi->phi_count;
+               ++itph
+       ) {
+               ssa_rename_definition(ssa, &(itph->dst));
+       }
+
+printf(" *** --- vars ---------\n");
+       
+       if (bptr == ssa->jd->basicblocks) {
+               for (i = 0; i < ssa->jd->localcount; ++i) {
+                       tmp = i;
+                       ssa_rename_definition(ssa, &tmp);
+               }
+       }
+
+       for (iptr = bptr->iinstr; iptr != bptr->iinstr + bptr->icount; ++iptr) {
+
+               /* Determine uses */
+
+               uses_count = 0;
+
+               switch (icmd_table[iptr->opc].dataflow) {
+                       case DF_3_TO_0:
+                       case DF_3_TO_1:
+                               s[2] = iptr->sx.s23.s3.varindex;
+                               uses_count += 1;
+
+                       case DF_2_TO_0:
+                       case DF_2_TO_1:
+                               s[1] = iptr->sx.s23.s2.varindex;
+                               uses_count += 1;
+
+                       case DF_1_TO_0:
+                       case DF_1_TO_1:
+                       case DF_COPY:
+                       case DF_MOVE:
+                               s[0] = iptr->s1.varindex;
+                               uses_count += 1;
+
+                               uses = s;
+                               break;
+               
+                       case DF_N_TO_1:
+                       case DF_INVOKE:
+                       case DF_BUILTIN:
+
+                               uses = iptr->sx.s23.s2.args;
+                               uses_count = iptr->s1.argcount;
+                               break;
+
+               }
+
+               printf(" *** %s uses ", icmd_table[iptr->opc].name);
+               for (jj = 0; jj < uses_count; ++jj) printf("%d ",uses[jj]);
+               printf("\n");
+
+               if (uses_count > 0) {
+                       /* Update uses, if there are any */
+
+                       ssa_rename_uses(ssa, uses, uses_count);
+
+                       /* If uses were s, then we need to update the instruction */
+
+                       if (uses == s) {
+                               switch (uses_count) {
+                                       case 3:
+                                               iptr->sx.s23.s3.varindex = s[2];
+                                       case 2:
+                                               iptr->sx.s23.s2.varindex = s[1];
+                                       case 1:
+                                               iptr->s1.varindex = s[0];
+                               }
+                       }
+               }
+
+               /* Rename definitions */
+
+               if (instruction_has_dst(iptr)) {
+                       printf(" *** %s defines %d\n", icmd_table[iptr->opc].name, iptr->dst.varindex);
+                       ssa_rename_definition(ssa, &(iptr->dst.varindex));
+               }
+
+       }
+
+       for (i = 0; i < bptr->outdepth; ++i) {
+               ssa_rename_definition(ssa, bptr->outvars + i);
+       }
+
+       /* Successors */
+
+       printf(" *** succs %d\n", bptr->successorcount);
+
+       for (
+               itsucc = bptr->successors; 
+               itsucc != bptr->successors + bptr->successorcount; 
+               ++itsucc
+       ) {
+               Y = *itsucc;
+
+               for (
+                       itpred = Y->predecessors, j = 0;
+                       itpred != Y->predecessors + Y->predecessorcount;
+                       ++itpred, ++j
+               ) {
+                       if (*itpred == bptr) break;
+               }
+
+               assert(j != Y->predecessorcount);
+
+               for (
+                       itph = bb_info(Y)->phi_functions;
+                       itph != bb_info(Y)->phi_functions + bb_info(Y)->phi_count;
+                       ++itph
+               ) {
+                       ssa_rename_uses(ssa, itph->args + j, 1);
+               }
+       }
+
+       /* Recurse */
+
+       for (
+               itdsucc = bptr->domsuccessors;
+               itdsucc != bptr->domsuccessors + bptr->domsuccessorcount;
+               ++itdsucc
+       ) {
+               ssa_rename_block(ssa, *itdsucc);
+       }
+
+       /* For each definition of some variable a in the original S, pop stack */
+
+       /* XXX */
+       for (a = 0; a < ssa->vars_count; ++a)  ssa->vars[a].stack_top = orig_stack_top[a];
+}
+
+static void ssa_rename(ssa_info *ssa) {
+       unsigned i;
+
+       for (i = 0; i < ssa->vars_count; ++i) {
+               ssa->vars[i].stack = DMNEW(unsigned, ssa->vars[i].num_defs + 1);
+               ssa->vars[i].stack[0] = 0;
+               ssa->vars[i].stack_top = ssa->vars[i].stack;
+       }
+
+       ssa_rename_block(ssa, ssa->jd->basicblocks);
+}
+
+static void ssa_export(ssa_info *ssa) {
+       unsigned i, j;
+       jitdata *jd = ssa->jd;
+       methoddesc *md = jd->m->parseddesc;
+       varinfo *vars, *it;
+       s4 vartop, varindex;
+
+       vartop = ssa->total_local_count + jd->vartop - jd->localcount;
+       vars = DMNEW(varinfo, vartop);
+
+       printf(" *** vartop(%d) = ssa->total_local_count(%d) + jd->vartop(%d) - jd->localcount(%d)\n",
+               vartop , ssa->total_local_count , jd->vartop , jd->localcount);
+
+       it = vars;
+
+       /* Version 1 of each local */
+
+       for (i = 0; i < jd->localcount; ++i) {
+               *(it++) = jd->var[i];
+       }
+
+       /* Other versions of each local */
+
+       for (i = 0; i < jd->localcount; ++i) {
+               for (j = 1; j < ssa->vars[i].num_defs; ++j) {
+                       *(it++) = jd->var[i];           
+               }
+       }
+
+       /* Other vars */
+
+       for (i = jd->localcount; i < jd->vartop; ++i) {
+               *(it++) = jd->var[i];
+       }
+
+       jd->var = vars;
+       jd->vartop = jd->varcount = vartop;
+
+       jd->local_map = DMREALLOC(jd->local_map, s4, 5 * jd->maxlocals, 5 * (jd->maxlocals + ssa->total_local_count - jd->localcount));
+
+       for (i = 0; i < ssa->total_local_count - jd->localcount; ++i) {
+               for (j = 0; j < 5; ++j) {
+                       varindex = jd->localcount + i;
+                       if (jd->var[varindex].type != j) {
+                               varindex = UNUSED;
+                       }
+                       jd->local_map[((jd->maxlocals + i) * 5) + j] = varindex;
+               }
+       }
+
+       jd->maxlocals += (ssa->total_local_count - jd->localcount);
+       jd->localcount = ssa->total_local_count;
+
+       printf(" *** jd->localcount %d, jd->maxlocals %d\n", jd->localcount , jd->maxlocals);
+}
+
+static unsigned get_predecessor_index(basicblock *from, basicblock *to) {
+       basicblock **itpred;
+       unsigned j = 0;
+
+       for (itpred = to->predecessors; itpred != to->predecessors + to->predecessorcount; ++itpred) {
+               if (*itpred == from) break;
+               j++;
+       }
+       
+       if (j == to->predecessorcount) {
+               printf(" *** %d => %d\n", from->nr, to->nr);
+               assert(j != to->predecessorcount);
+       }
+
+       return j;
+}
+
+static basicblock *create_block(ssa_info *ssa, basicblock *from, basicblock *to) {
+       basicblock *mid;
+       basicblock_info *toi;
+       instruction *iptr;
+       phi_function *itph;
+       unsigned j = get_predecessor_index(from, to);
+       
+       mid = DNEW(basicblock);
+       MZERO(mid, basicblock, 1);
+
+       toi = bb_info(to);
+       assert(toi);
+
+       mid->nr = ssa->jd->basicblockcount;
+       ssa->jd->basicblockcount += 1;
+       mid->mpc = -1;
+       mid->type = 666;
+       mid->icount = toi->phi_count + 1;
+       iptr = mid->iinstr = DMNEW(instruction, mid->icount);
+       MZERO(mid->iinstr, instruction, mid->icount);
+
+       for (itph = toi->phi_functions; itph != toi->phi_functions + toi->phi_count; ++itph) {
+               iptr->opc = ICMD_COPY;
+               iptr->dst.varindex = itph->dst;
+               iptr->s1.varindex =  itph->args[j];
+               assert(itph->dst < ssa->total_local_count);
+               assert(itph->args[j] < ssa->total_local_count);
+               iptr++;
+       }
+
+       iptr->opc = ICMD_GOTO;
+       iptr->dst.block = to;
+
+       while (from->next) {
+               from = from->next;
+       }
+
+       from->next = mid;
+
+       return mid;
+}
+
+static void crate_fallthrough(ssa_info *ssa, basicblock *bptr) {
+       unsigned j;
+       basicblock_info *toi;
+       instruction *iptr;
+       phi_function *itph;
+
+       if (bptr->next == NULL) return;
+
+       j = get_predecessor_index(bptr, bptr->next);
+
+       toi = bb_info(bptr->next);
+       assert(toi);
+
+       bptr->iinstr = DMREALLOC(bptr->iinstr, instruction, bptr->icount, bptr->icount + toi->phi_count);
+       iptr = bptr->iinstr + bptr->icount;
+       bptr->icount += toi->phi_count;
+
+       for (itph = toi->phi_functions; itph != toi->phi_functions + toi->phi_count; ++itph) {
+               iptr->opc = ICMD_COPY;
+               iptr->dst.varindex = itph->dst;
+               iptr->s1.varindex =  itph->args[j];
+               assert(itph->dst < ssa->total_local_count);
+               assert(itph->args[j] < ssa->total_local_count);
+               iptr++;
+       }
+
+}
+
+static void ssa_create_phi_moves(ssa_info *ssa) {
+       basicblock *bptr;
+       instruction *iptr;
+
+       s4 i, l;
+       branch_target_t *table;
+       lookup_target_t *lookup;
+       bool gt;
+
+       for (bptr = ssa->jd->basicblocks; bptr; bptr = bptr->next) {
+               if (bptr->type == 666) {
+                       bptr->type = BBTYPE_STD;
+                       continue;
+               }
+               if (! bptr->vp) continue;
+               if (! (bptr->flags >= BBREACHED)) continue;
+               gt = false;
+               for (iptr = bptr->iinstr; iptr != bptr->iinstr + bptr->icount; ++iptr) {
+                       switch (icmd_table[iptr->opc].controlflow) {
+                               case CF_IF:
+                               case CF_RET:
+                               case CF_GOTO:
+                                       iptr->dst.block = create_block(ssa, bptr, iptr->dst.block);     
+                                       break;
+                               case CF_TABLE:
+                                       table = iptr->dst.table;
+                                       l = iptr->sx.s23.s2.tablelow;
+                                       i = iptr->sx.s23.s3.tablehigh;
+                                       i = i - l + 1;
+                                       i += 1; /* default */
+                                       while (--i >= 0) {
+                                               table->block = create_block(ssa, bptr, table->block);
+                                               ++table;
+                                       }
+                                       break;
+                               case CF_LOOKUP:
+                                       lookup = iptr->dst.lookup;
+                                       i = iptr->sx.s23.s2.lookupcount;
+                                       while (--i >= 0) {
+                                               lookup->target.block = create_block(ssa, bptr, lookup->target.block);
+                                               lookup++;
+                                       }
+                                       iptr->sx.s23.s3.lookupdefault.block = create_block(ssa, bptr, iptr->sx.s23.s3.lookupdefault.block);
+                                       break;
+                               case CF_JSR:
+                                       iptr->sx.s23.s3.jsrtarget.block = create_block(ssa, bptr, iptr->sx.s23.s3.jsrtarget.block);
+                                       break;
+                       }
+                       if ((iptr->opc == ICMD_GOTO) || icmd_table[iptr->opc].controlflow == CF_END)
+                               gt = true;
+                       else if (iptr->opc != ICMD_NOP)
+                               gt = false;
+               }
+               if (! bptr->next) continue;
+               if (! (bptr->next->flags >= BBREACHED)) continue;
+               if (bptr->next->type == 666) continue;
+               if (!gt) crate_fallthrough(ssa, bptr);
+       }
+}
+
+void xssa(jitdata *jd) {
+       ssa_info *ssa = ssa_init(jd);
+
+       printf("=============== [ before %s ] =========================\n", jd->m->name->text);
+       show_method(jd, 3);
+       printf("=============== [ /before ] =========================\n");
+
+       ssa_place_phi_functions(ssa);
+       ssa_create_phi_functions(ssa);
+       ssa_calculate_offsets(ssa);
+       ssa_rename(ssa);
+       ssa_export(ssa);
+       ssa_create_phi_moves(ssa);
+
+       printf("=============== [ after ] =========================\n");
+       show_method(jd, 3);
+       printf("=============== [ /after ] =========================\n");
+}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of 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/optimizing/ssa3.c b/src/vm/jit/optimizing/ssa3.c
new file mode 100644 (file)
index 0000000..05aa36f
--- /dev/null
@@ -0,0 +1,1046 @@
+/* src/vm/optimizing/ssa3.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.
+
+   SSA transformation PROTOTYPE based on:
+
+   Moessenboeck, H., 
+   Adding Static Single Assignment Form and a Graph Coloring Register 
+   Allocator to the Java Hotspot Client Compiler, 2000 
+   (http://www.ssw.uni-linz.ac.at/Research/Reports/Report15.html)
+
+   TODO
+
+   * Adapt for exception handling [done]
+   * Eliminiation of redundand PHI functions
+   * Create PHI functions lazyly, when they are used for the first time
+     (I suspect that currently PHIs are created that are never used).
+   * REWRITE. The code was never designed for producion.
+*/
+
+#include "vm/jit/jit.h"
+#include "vm/global.h"
+#include "mm/memory.h"
+#include "mm/dumpmemory.h"
+#include "toolbox/list.h"
+
+#if 1
+static inline bool test_do_verbose(jitdata *jd) { 
+       return strcmp(jd->m->name->text, "close") == 0 &&
+               strcmp(jd->m->clazz->name->text, "antlr/PreservingFileWriter") == 0;
+}
+static bool do_verbose = 0;
+#define WHEN do_verbose
+#define printf(...) do { if (WHEN) printf(__VA_ARGS__); } while (0)
+#define show_method(...) do { if (WHEN) show_method(__VA_ARGS__); } while (0)
+#define show_basicblock(...) do { if (WHEN) show_basicblock(__VA_ARGS__); } while (0)
+#endif
+
+/*
+TODO
+move set and get uses into jit.h
+*/
+
+#define ICMD_PHI 666
+
+#define eqi(a, b) (((a) && (b) || (!(a) && !(b)))
+
+#define nn(x) ((x) < 0 ? 0 : (x))
+
+#define ass(dst, src) *(dst) = *(src)
+
+static inline const char *instruction_name(const instruction *iptr) {
+       if (iptr == NULL) {
+               return "null";
+       } else if (iptr->opc == ICMD_PHI) {
+               return "phi";
+       } else {
+               return icmd_table[iptr->opc].name;
+       }
+}
+
+static inline s4 instruction_line(const instruction *iptr) {
+       if (iptr == NULL) {
+               return -1;
+       } else {
+               return iptr->line;
+       }
+}
+
+typedef struct phi_function {
+       s4 dst;
+       s4 *args;
+       s4 local;
+       instruction instr;
+} phi_function;
+
+typedef struct basicblock_info {
+       bool visited;
+       bool active;
+       bool traversed;
+       unsigned backward_branches;
+
+       instruction **state_array;
+
+       unsigned phi_count;
+       unsigned phi_max;
+       phi_function *phi_functions;
+       unsigned complete_predecessors;
+       bool cow;
+} basicblock_info;
+
+typedef struct ssa_info {
+       jitdata *jd;
+
+       varinfo locals[3000]; /* XXX hardcoded max */
+       unsigned max_locals;
+       unsigned locals_count;
+
+       s4 s_buf[3];
+} ssa_info;
+
+static unsigned get_predecessor_count(basicblock *bb) {
+       unsigned ret;
+       basicblock **itpred;
+
+       ret = nn(bb->predecessorcount);
+
+       FOR_EACH_EXPREDECESSOR(bb, itpred) {
+               ret += (*itpred)->exouts;
+       }
+
+       return ret;
+}
+
+static unsigned get_predecessor_index(basicblock *from, basicblock *to) {
+       basicblock **itpred;
+       unsigned j = 0;
+
+       for (itpred = to->predecessors; itpred != to->predecessors + nn(to->predecessorcount); ++itpred) {
+               if (*itpred == from) break;
+               j++;
+       }
+       
+       if (j == nn(to->predecessorcount)) {
+               assert(j != nn(to->predecessorcount));
+       }
+
+       return j;
+}
+
+static void phi_set_argument(basicblock *bb, instruction *phi, unsigned j, instruction *value) {
+       phi_function *pf = (phi_function *)(
+               (char *)phi - OFFSET(phi_function, instr)
+       );
+       assert(j < phi->s1.argcount);
+       if (value == NULL) {
+               pf->args[j] = pf->local;
+       } else {
+               pf->args[j] = value->dst.varindex;
+       }
+       /*phi->sx.s23.s2.args[j] = value->dst.varindex;*/
+       printf(" *** in bb%d setting phi arg %d for local %d to %s@%d (%d)\n", bb->nr, j, pf->local, instruction_name(value), instruction_line(value), value ? value->dst.varindex : -1);
+}
+
+static inline basicblock_info *bb_info(basicblock *bb) {
+       return (basicblock_info *)(bb->vp);
+}
+
+static void mark_loops(basicblock *bb) {
+       basicblock_info *bbi = bb_info(bb);
+       basicblock **itsucc;
+
+       if (! bbi->visited) {
+               bbi->visited = true;
+               bbi->active = true;
+               FOR_EACH_SUCCESSOR(bb, itsucc) {
+                       mark_loops(*itsucc);
+               }
+               FOR_EACH_EXHANDLER(bb, itsucc) {
+                       mark_loops(*itsucc);
+               }
+               bbi->active = false;
+       } else if (bbi->active) {
+               bbi->backward_branches += 1;
+       }
+}
+
+static instruction *create_phi(ssa_info *ssa, basicblock *bb, s4 local) {
+       basicblock_info *bbi = bb_info(bb);
+       phi_function *phi;
+       s4 *itarg;
+       unsigned arg_count = get_predecessor_count(bb);
+
+       printf(" *** BB%d phi #%d for local %d\n", bb->nr, bbi->phi_count, local);
+
+       phi = bbi->phi_functions + bbi->phi_count;
+       assert(bbi->phi_count < bbi->phi_max);
+       bbi->phi_count += 1;
+
+
+       phi->local = local;
+       phi->args = DMNEW(s4, arg_count);
+       for (itarg = phi->args; itarg != phi->args + arg_count; ++itarg) {
+               /* Invalidate */
+               *itarg = 0x7fffffff;
+       }
+
+       assert(ssa->locals_count < ssa->max_locals);
+       ssa->locals[ssa->locals_count] = ssa->jd->var[local];
+       phi->dst = ssa->locals_count;
+       ssa->locals_count += 1;
+
+       phi->instr.opc = ICMD_PHI;
+       phi->instr.dst.varindex = phi->dst;
+       phi->instr.s1.argcount = arg_count;
+       phi->instr.sx.s23.s2.args = NULL;
+
+       return &(phi->instr);
+}
+
+static bool is_my_phi(basicblock *bb, instruction *iptr) {
+       basicblock_info *bbi = bb_info(bb);
+       if (iptr == NULL) {
+               return false;
+       }
+       if (iptr->opc != ICMD_PHI) {
+               return false;
+       }
+       if (    
+               ((char *)bbi->phi_functions <= (char *)iptr) &&
+               ((char *)iptr < (char *)(bbi->phi_functions + bbi->phi_count))
+       ) {
+               return true;
+       } else {
+               return false;
+       }
+}
+
+static void rename_def(ssa_info *ssa, basicblock *bptr, instruction *iptr) {
+       basicblock_info *bbi = bb_info(bptr);
+       assert(bbi->state_array);
+
+       bbi->state_array[iptr->dst.varindex] = iptr;
+
+       assert(ssa->locals_count < ssa->max_locals);
+
+       ssa->locals[ssa->locals_count] = ssa->jd->var[iptr->dst.varindex];
+       iptr->dst.varindex = ssa->locals_count;
+       printf(" *** BB%d %s def %d => %d\n", bptr->nr, instruction_name(iptr), iptr->dst.varindex, ssa->locals_count);
+
+       ssa->locals_count += 1;
+}
+
+static void rename_use(ssa_info *ssa, basicblock *bptr, instruction *iptr, s4 *use) {
+       basicblock_info *bbi = bb_info(bptr);
+       assert(bbi->state_array);
+
+       if (bbi->state_array[*use] != NULL) {
+               printf(" *** BB%d %s use %d => %d (%s) \n", bptr->nr, instruction_name(iptr), *use, bbi->state_array[*use]->dst.varindex, instruction_name(bbi->state_array[*use]) );
+               *use = bbi->state_array[*use]->dst.varindex;
+       } else {
+               printf(" *** BB%d %s use keep\n", bptr->nr, instruction_name(iptr));
+       }
+}
+
+static void get_uses(ssa_info *ssa, instruction *iptr, s4 **puses, unsigned *puses_count) {
+       unsigned uses_count = 0;
+
+       switch (icmd_table[iptr->opc].dataflow) {
+               case DF_3_TO_0:
+               case DF_3_TO_1:
+                       ssa->s_buf[2] = iptr->sx.s23.s3.varindex;
+                       uses_count += 1;
+
+               case DF_2_TO_0:
+               case DF_2_TO_1:
+                       ssa->s_buf[1] = iptr->sx.s23.s2.varindex;
+                       uses_count += 1;
+
+               case DF_1_TO_0:
+               case DF_1_TO_1:
+               case DF_COPY:
+               case DF_MOVE:
+                       ssa->s_buf[0] = iptr->s1.varindex;
+                       uses_count += 1;
+
+                       *puses_count = uses_count;
+                       *puses = ssa->s_buf;
+                       break;
+       
+               case DF_N_TO_1:
+               case DF_INVOKE:
+               case DF_BUILTIN:
+
+                       *puses = iptr->sx.s23.s2.args;
+                       *puses_count = iptr->s1.argcount;
+                       break;
+
+               default:
+
+                       *puses_count = 0;
+                       break;
+       }
+}
+
+static void set_uses(ssa_info *ssa, instruction *iptr, s4 *uses, unsigned uses_count) {
+       if (uses == ssa->s_buf) {
+               switch (uses_count) {
+                       case 3:
+                               iptr->sx.s23.s3.varindex = ssa->s_buf[2];
+                       case 2:
+                               iptr->sx.s23.s2.varindex = ssa->s_buf[1];
+                       case 1:
+                               iptr->s1.varindex = ssa->s_buf[0];
+               }
+       }
+}
+
+typedef void (*traverse_fun)(ssa_info *ssa, basicblock *bb);
+
+static void traverse(ssa_info *ssa, basicblock *bb, traverse_fun fun) {
+       basicblock_info *bbi = bb_info(bb);
+       basicblock **itsucc, **itpred;
+       basicblock_info *succi;
+       unsigned complete_preds;
+       unsigned j;
+
+       /*if (bbi->traversed) {
+               return;
+       }*/
+
+       /* Process block */
+
+       fun(ssa, bb);
+
+       /*bbi->traversed = true;*/
+
+       /* Recurse */
+
+       FOR_EACH_SUCCESSOR(bb, itsucc) {
+               merge(ssa, bbi->state_array, *itsucc, get_predecessor_index(bb, *itsucc));
+               succi = bb_info(*itsucc);
+               succi->complete_predecessors += 1;
+               if (succi->complete_predecessors == (/*nn((*itsucc)->predecessorcount)*/ get_predecessor_count(*itsucc) - succi->backward_branches)) {
+                       printf(" *** Traverse bb%d => bb%d\n", bb->nr, (*itsucc)->nr);
+                       traverse(ssa, *itsucc, fun);
+               }
+       }
+
+       FOR_EACH_EXHANDLER(bb, itsucc) {
+               succi = bb_info(*itsucc);
+               succi->complete_predecessors += bb->exouts; /* XXX this might be 0 */
+               if (succi->complete_predecessors == (/*nn((*itsucc)->predecessorcount)*/ get_predecessor_count(*itsucc) - succi->backward_branches)) {
+                       printf(" *** Traverse bb%d => bb%d\n", bb->nr, (*itsucc)->nr);
+                       traverse(ssa, *itsucc, fun);
+               }
+       }
+
+}
+
+void merge(ssa_info *ssa, instruction **state_array, basicblock *succ, unsigned j) {
+       basicblock_info *succi = bb_info(succ);
+       instruction *phi;
+       unsigned i;
+       unsigned a;
+
+#define mprintf(fmt, ...) printf(" *** merge bb? => bb%d > " fmt, succ->nr, __VA_ARGS__)
+
+       mprintf("(%d, %p)\n", j, succi->state_array);
+
+       if (succi->state_array == NULL) {
+
+               succi->state_array = DMNEW(instruction *, ssa->jd->localcount);
+
+               mprintf("creating state_array %p\n", succi->state_array );
+
+
+               if (succi->backward_branches > 0) {
+                       mprintf("bb%d is loop header, creating phis\n", succ->nr);
+                       for (i = 0; i < ssa->jd->localcount; ++i) {
+                               succi->state_array[i] = create_phi(ssa, succ, i);
+                       }
+               } else {
+                       /*
+                       printf(" *** merge bb%d cow state array\n", succ->nr);
+                       succi->state_array = bbi->state_array;
+                       succi->cow = true;
+                       */
+                       MCOPY(succi->state_array, state_array, instruction *, ssa->jd->localcount);
+                       return;
+               }
+       }
+
+       for (i = 0; i < ssa->jd->localcount; ++i) {
+               mprintf("local %d bb: %s@%d, succ: %s@%d\n", i, instruction_name(state_array[i]), instruction_line(state_array[i]), instruction_name(succi->state_array[i]), instruction_line(succi->state_array[i]));
+
+               if (succi->traversed) {
+                       /* Back edge, all phis already created */
+                       /* Only fill in phi arguments */
+                       /* We have created phis for *ALL* locals, so there is random access */
+                       phi_set_argument(succ, &(succi->phi_functions[i].instr), j, state_array[i]);
+               } else if (state_array[i] != succi->state_array[i]) {
+                       mprintf("merge bb%d need phi for local %d\n", succ->nr, i);
+                       /* Create new state array if needed */
+
+                       /*if (succi->cow) {
+                               printf(" *** merge bb%d cloning cow state array\n", succ->nr);
+                               state_array = DMNEW(instruction *, ssa->jd->localcount);
+                               MCOPY(state_array, succi->state_array, instruction *, ssa->jd->localcount);
+                               succi->state_array = state_array;
+                               succi->cow = false;
+                       }*/
+
+                       if (is_my_phi(succ, succi->state_array[i])) {
+                               /* State array is already phi function, just need to fill in argument */
+                               phi_set_argument(succ, succi->state_array[i], j, state_array[i]);
+                       } else {
+                               /* Create phi and initialize all arguments with current state array value
+                                * (We might have already merged this value from within several blocks).
+                                */
+                               phi = create_phi(ssa, succ, i);
+                               for (a = 0; a < get_predecessor_count(succ); ++a) {
+                                       phi_set_argument(succ, phi, a, succi->state_array[i]);
+                               }
+                               phi_set_argument(succ, phi, j, state_array[i]);
+                               succi->state_array[i] = phi;
+                       }
+               }
+       }
+#undef mprintf
+}
+
+static unsigned get_ex_predecessor_index(basicblock *from, unsigned pei, basicblock *to) {
+       unsigned i, j;
+       basicblock **itpred;
+       instruction *iti;
+
+       j = nn(to->predecessorcount);
+
+       FOR_EACH_EXPREDECESSOR(to, itpred) {
+               if ((*itpred)->nr == from->nr) {
+                       j += pei;
+                       return j;
+               } else {
+                       j += (*itpred)->exouts;
+               }
+       }
+
+       assert(0);
+}
+
+static void handle_pei(ssa_info *ssa, basicblock *bb, unsigned pei) {
+       basicblock_info *bbi = bb_info(bb);
+       basicblock **itsucc;
+
+       FOR_EACH_EXHANDLER(bb, itsucc) {
+               merge(ssa, bbi->state_array, *itsucc, get_ex_predecessor_index(bb, pei, *itsucc));
+       }
+}
+
+static void traverse_fun_impl(ssa_info *ssa, basicblock *bb) {
+       basicblock_info *bbi = bb_info(bb), *predi;
+       basicblock **itpred, *pred;
+       unsigned i;
+       bool need_phi;
+       instruction *iptr;
+       unsigned uses_count;
+       s4 *uses, *ituse;
+       unsigned pei = 0;
+
+       assert(! bbi->traversed);
+       bbi->traversed = true;
+
+       /*
+       if (bbi->state_array) {
+               return;
+       }
+       */
+
+       /* bb 0 */
+
+       if (bb->predecessorcount == 0) {
+               assert(! bbi->state_array);
+               bbi->state_array = DMNEW(instruction *, ssa->jd->localcount);
+               MZERO(bbi->state_array, instruction *, ssa->jd->localcount);
+               goto process_instructions;
+       }
+
+
+       /*
+       if ((bb->predecessorcount == 1) && (bb->predecessors[0]->successorcount == 1)) {
+               bbi->state_array = bb_info(bb->predecessors[0])->state_array;
+               assert(bbi->state_array);
+               goto process_instructions;
+       }
+       */
+
+       /*
+       bbi->state_array = DMNEW(instruction *, ssa->jd->localcount);
+       MZERO(bbi->state_array, instruction *, ssa->jd->localcount);
+       */
+
+       /*
+       if (bbi->backward_branches > 0) {
+               for (i = 0; i < ssa->jd->localcount; ++i) {
+                       bbi->state_array[i] = create_phi(ssa, bb, i);
+               }
+       } else {
+               for (i = 0; i < ssa->jd->localcount; ++i) {
+                       need_phi = false;
+                       assert(bb_info(bb->predecessors[0])->state_array);
+
+                       FOR_EACH_PREDECESSOR(bb, itpred) {
+                               assert(bb_info(*itpred)->state_array);
+                               if (bb_info(bb->predecessors[0])->state_array[i] != bb_info(*itpred)->state_array[i]) {
+                                       need_phi = true;
+                                       break;
+                               }
+                       }
+
+                       if (need_phi) {
+                               bbi->state_array[i] = create_phi(ssa, bb, i);
+                       } else {
+                               bbi->state_array[i] = bb_info(bb->predecessors[0])->state_array[i];
+                       }
+
+               }
+       }
+       */
+
+process_instructions:
+
+       assert(bbi->state_array);
+
+       FOR_EACH_INSTRUCTION(bb, iptr) {
+
+               if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI) {
+                       handle_pei(ssa, bb, pei++);
+               }
+
+               get_uses(ssa, iptr, &uses, &uses_count);
+
+               for (ituse = uses; ituse != uses + uses_count; ++ituse) {
+                       if (var_is_local(ssa->jd, *ituse)) {
+                               rename_use(ssa, bb, iptr, ituse);
+                       } else {
+                               *ituse += 0xFFFF;
+                       }
+               }
+
+               set_uses(ssa, iptr, uses, uses_count);
+
+               if (instruction_has_dst(iptr)) {
+                       if (var_is_local(ssa->jd, iptr->dst.varindex)) {
+                               rename_def(ssa, bb, iptr);
+                       } else {
+                               iptr->dst.varindex += 0xFFFF;
+                       }
+               }
+       }
+}
+
+static void ssa_rename_others(ssa_info *ssa) {
+
+       basicblock *bb;
+       instruction *iptr;
+       s4 *itinout, *uses, *ituse;
+       unsigned uses_count;
+       unsigned off = ssa->locals_count - ssa->jd->localcount;
+
+       FOR_EACH_BASICBLOCK(ssa->jd, bb) {
+
+               if (! basicblock_reached(bb)) continue;
+
+               for (itinout = bb->invars; itinout != bb->invars + bb->indepth; ++itinout) {
+                       *itinout += off;
+               }
+
+               for (itinout = bb->outvars; itinout != bb->outvars + bb->outdepth; ++itinout) {
+                       *itinout += off;
+               }
+
+               FOR_EACH_INSTRUCTION(bb, iptr) {
+                       if (instruction_has_dst(iptr)) {
+                               if (iptr->dst.varindex >= 0xFFFF) {
+                                       iptr->dst.varindex += off;
+                                       iptr->dst.varindex -= 0xFFFF;
+                               }
+                       }
+                       get_uses(ssa, iptr, &uses, &uses_count);
+                       for (ituse = uses; ituse != uses + uses_count; ++ituse) {
+                               if (*ituse >= 0xFFFF) {
+                                       *ituse += off;
+                                       *ituse -= 0xFFFF;
+                               }
+                       }
+                       set_uses(ssa, iptr, uses, uses_count);
+               }
+       }
+}
+
+static void fill_in_phi_args(ssa_info *ssa) {
+       basicblock *bb;
+       basicblock_info *bbi;
+       phi_function *itphi;
+       unsigned j;
+       basicblock **itpred;
+       basicblock_info *predi;
+
+       FOR_EACH_BASICBLOCK(ssa->jd, bb) {
+               if (!(bb->flags >= BBREACHED)) continue;
+               bbi = bb_info(bb);
+               j = 0;
+               FOR_EACH_PREDECESSOR(bb, itpred) {
+                       predi = bb_info(*itpred);
+                       for (itphi = bbi->phi_functions; itphi != bbi->phi_functions + bbi->phi_count; ++itphi) {
+                               if (predi->state_array[itphi->local]) {
+                                       itphi->args[j] = predi->state_array[itphi->local]->dst.varindex;
+                               } else {
+                                       itphi->args[j] = itphi->local;
+                               }
+                       }
+                       ++j;
+               }
+       }
+}
+
+static void ssa_export(ssa_info *ssa) {
+       unsigned i, j;
+       jitdata *jd = ssa->jd;
+       varinfo *vars, *it;
+       s4 vartop, varindex;
+
+       vartop = ssa->locals_count + jd->vartop - jd->localcount;
+       vars = DMNEW(varinfo, vartop);
+
+       MCOPY(vars, ssa->locals, varinfo, ssa->locals_count);
+       MCOPY(vars + ssa->locals_count, jd->var + jd->localcount, varinfo, jd->vartop - jd->localcount);
+
+       jd->var = vars;
+       jd->vartop = jd->varcount = vartop;
+
+       jd->local_map = DMREALLOC(jd->local_map, s4, 5 * jd->maxlocals, 5 * (jd->maxlocals + ssa->locals_count - jd->localcount));
+
+       for (i = 0; i < ssa->locals_count - jd->localcount; ++i) {
+               for (j = 0; j < 5; ++j) {
+                       varindex = jd->localcount + i;
+                       if (jd->var[varindex].type != j) {
+                               varindex = UNUSED;
+                       }
+                       jd->local_map[((jd->maxlocals + i) * 5) + j] = varindex;
+               }
+       }
+
+       jd->maxlocals += (ssa->locals_count - jd->localcount);
+       jd->localcount = ssa->locals_count;
+}
+
+static basicblock *create_block_intern(ssa_info *ssa, basicblock *from, basicblock *to, unsigned j) {
+       basicblock *mid;
+       basicblock_info *toi;
+       instruction *iptr;
+       phi_function *itph;
+       
+       mid = DNEW(basicblock);
+       MZERO(mid, basicblock, 1);
+
+       toi = bb_info(to);
+       assert(toi);
+
+       mid->nr = ssa->jd->basicblockcount;
+       ssa->jd->basicblockcount += 1;
+       mid->mpc = -1;
+       mid->type = 666;
+       mid->icount = toi->phi_count + 1;
+       iptr = mid->iinstr = DMNEW(instruction, mid->icount);
+       MZERO(mid->iinstr, instruction, mid->icount);
+
+       for (itph = toi->phi_functions; itph != toi->phi_functions + toi->phi_count; ++itph) {
+               iptr->opc = ICMD_COPY;
+               iptr->dst.varindex = itph->dst;
+               iptr->s1.varindex =  itph->args[j];
+               assert(j < itph->instr.s1.argcount);
+               assert(itph->dst < ssa->locals_count);
+               assert(itph->args[j] < ssa->locals_count);
+               iptr++;
+       }
+
+       iptr->opc = ICMD_GOTO;
+       iptr->dst.block = to;
+
+       return mid;
+}
+
+static basicblock *create_block(ssa_info *ssa, basicblock *from, basicblock *to) {
+       basicblock *ret;
+       ret = create_block_intern(ssa, from, to, get_predecessor_index(from, to));
+
+       while (from->next) {
+               from = from->next;
+       }
+
+       from->next = ret;
+
+       return ret;
+}
+
+static void crate_fallthrough(ssa_info *ssa, basicblock *bptr) {
+       unsigned j;
+       basicblock_info *toi;
+       instruction *iptr;
+       phi_function *itph;
+
+       if (bptr->next == NULL) return;
+
+       j = get_predecessor_index(bptr, bptr->next);
+
+       toi = bb_info(bptr->next);
+       assert(toi);
+
+       bptr->iinstr = DMREALLOC(bptr->iinstr, instruction, bptr->icount, bptr->icount + toi->phi_count);
+       iptr = bptr->iinstr + bptr->icount;
+       bptr->icount += toi->phi_count;
+
+       for (itph = toi->phi_functions; itph != toi->phi_functions + toi->phi_count; ++itph) {
+               iptr->opc = ICMD_COPY;
+               iptr->dst.varindex = itph->dst;
+               iptr->s1.varindex =  itph->args[j];
+               assert(itph->dst < ssa->locals_count);
+               assert(itph->args[j] < ssa->locals_count);
+               iptr++;
+       }
+
+}
+
+static void ssa_create_phi_moves(ssa_info *ssa) {
+       basicblock *bptr;
+       instruction *iptr;
+
+       s4 i, l;
+       branch_target_t *table;
+       lookup_target_t *lookup;
+       bool gt;
+
+       for (bptr = ssa->jd->basicblocks; bptr; bptr = bptr->next) {
+               if (bptr->type == 666) {
+                       bptr->type = BBTYPE_STD;
+                       continue;
+               }
+               if (! bptr->vp) continue;
+               if (! (bptr->flags >= BBREACHED)) continue;
+               gt = false;
+               for (iptr = bptr->iinstr; iptr != bptr->iinstr + bptr->icount; ++iptr) {
+                       switch (icmd_table[iptr->opc].controlflow) {
+                               case CF_IF:
+                               case CF_RET:
+                               case CF_GOTO:
+                                       iptr->dst.block = create_block(ssa, bptr, iptr->dst.block);     
+                                       break;
+                               case CF_TABLE:
+                                       table = iptr->dst.table;
+                                       l = iptr->sx.s23.s2.tablelow;
+                                       i = iptr->sx.s23.s3.tablehigh;
+                                       i = i - l + 1;
+                                       i += 1; /* default */
+                                       while (--i >= 0) {
+                                               table->block = create_block(ssa, bptr, table->block);
+                                               ++table;
+                                       }
+                                       break;
+                               case CF_LOOKUP:
+                                       lookup = iptr->dst.lookup;
+                                       i = iptr->sx.s23.s2.lookupcount;
+                                       while (--i >= 0) {
+                                               lookup->target.block = create_block(ssa, bptr, lookup->target.block);
+                                               lookup++;
+                                       }
+                                       iptr->sx.s23.s3.lookupdefault.block = create_block(ssa, bptr, iptr->sx.s23.s3.lookupdefault.block);
+                                       break;
+                               case CF_JSR:
+                                       iptr->sx.s23.s3.jsrtarget.block = create_block(ssa, bptr, iptr->sx.s23.s3.jsrtarget.block);
+                                       break;
+                       }
+                       if ((iptr->opc == ICMD_GOTO) || (iptr->opc == ICMD_JSR) || (iptr->opc == ICMD_RET) || icmd_table[iptr->opc].controlflow == CF_END || (iptr->opc == ICMD_TABLESWITCH) || (iptr->opc == ICMD_LOOKUPSWITCH))
+                               gt = true;
+                       else if (iptr->opc != ICMD_NOP)
+                               gt = false;
+               }
+               if (! bptr->next) continue;
+               if (! (bptr->next->flags >= BBREACHED)) continue;
+               if (bptr->next->type == 666) continue;
+               if (!gt) crate_fallthrough(ssa, bptr);
+       }
+}
+
+static basicblock *split_basicblock_at(ssa_info *ssa, basicblock *bptr, instruction *iptr) {
+
+       basicblock *newblock;
+       basicblock *tosplit;
+       basicblock **pnext;
+       unsigned icount;
+       basicblock *it;
+       unsigned pos;
+
+       unsigned origidx = iptr - bptr->iinstr;
+
+       printf(" *** split basicblock bb%d at %s/%d/%d\n", bptr->nr, instruction_name(iptr), instruction_line(iptr), origidx);
+       assert(origidx < bptr->icount);
+
+
+       if (! bptr->subbasicblocks) {
+               bptr->subbasicblocks = DNEW(basicblock);
+               ass(bptr->subbasicblocks, bptr);
+               bptr->subbasicblocks->subbasicblocks = NULL;
+               bptr->subbasicblocks->next = NULL;
+       }
+
+       tosplit = bptr->subbasicblocks;
+       pos = 0;
+
+       while (tosplit->next && (origidx >= (pos + tosplit->icount))) {
+               assert(bptr->nr == tosplit->nr);
+               pos += tosplit->icount;
+               tosplit = tosplit->next;
+       }
+
+       assert(bptr->nr == tosplit->nr);
+       
+       icount = iptr - tosplit->iinstr + 1;
+       assert(icount <= tosplit->icount);
+
+       if (icount < tosplit->icount) {
+               newblock = DNEW(basicblock);
+               ass(newblock, tosplit);
+       
+               tosplit->next = newblock;
+               tosplit->icount = icount;
+
+               newblock->icount -= icount;
+               newblock->iinstr += icount;
+               newblock->next = NULL;
+
+               assert(tosplit->nr == bptr->nr);
+               assert(newblock->nr == bptr->nr);
+               assert(newblock->next == NULL);
+       } else {
+               printf("xx split\n");
+       }
+
+       /* To not break references to block bptr, we will replace 
+          the block by the first fragment later. */
+
+       if (tosplit == bptr->subbasicblocks) tosplit = bptr;
+
+       return tosplit;
+}
+
+static exception_entry *create_exception_handler(ssa_info *ssa, basicblock *from, unsigned pei, basicblock *to, classref_or_classinfo catchtype) {
+       basicblock *it;
+       exception_entry *ee = DNEW(exception_entry);
+       basicblock *exh = create_block_intern(ssa, from, to, get_ex_predecessor_index(from, pei, to));
+       exh->type = BBTYPE_EXH;
+       to->type = BBTYPE_STD;
+
+       exh->indepth = exh->outdepth = 1;
+       exh->invars = exh->outvars = DNEW(s4);
+       /* assigned in caller */
+
+       ee->start = from;
+       /* XXX evil hack: if from is first fragment of BB, then from->next is not the next fragment */
+       ee->end = from->subbasicblocks ? from->subbasicblocks->next : from->next;
+       ee->handler = exh;
+       ee->catchtype = catchtype;
+       ee->next = NULL;
+       ee->down = NULL;
+
+       for (it = ssa->jd->basicblocks; it->next; it = it->next);
+
+       it->next = exh;
+
+       return ee;
+}
+
+static void ssa_create_ex_phi_moves(ssa_info *ssa) {
+       basicblock *bptr;
+       instruction *iptr;
+       basicblock_info *bbi;
+       exception_entry *ite;
+       exception_entry *firstee, *lastee, *ee;
+       basicblock *ittry, *try;
+       classref_or_classinfo catchtype;
+       unsigned pei;
+       unsigned exhandler_count = 0;
+       varinfo *v;
+
+       FOR_EACH_BASICBLOCK(ssa->jd, bptr) {
+               if (! bptr->vp) continue;
+               if (! (bptr->flags >= BBREACHED)) continue;
+               if (bptr->expredecessorcount == 0) continue;
+               bbi = bb_info(bptr);
+               if (bbi->phi_count == 0) continue;
+
+               for (ite = ssa->jd->exceptiontable; ite; ite = ite->down) {
+                       /* Traverse all exhandlers */
+                       if (bptr == ite->handler) {
+                               printf(" *** mess with handler bb%d\n", bptr->nr);
+                               catchtype = ite->catchtype;
+                               firstee = lastee = NULL;
+                               /* If bptr is handler, remove exhandler */
+                               /* Traverse all guarded blocks */
+                               for (ittry = ite->start; ittry != ite->end; ittry = ittry->next) {
+                                       pei = 0;
+                                       FOR_EACH_INSTRUCTION(ittry, iptr) {
+                                               if (icmd_table[iptr->opc].flags & ICMDTABLE_PEI) {
+                                                       /* try is basicblock fragment till (including) the pei */
+                                                       try = split_basicblock_at(ssa, ittry, iptr);
+                                                       /* ee is handler for try */
+                                                       ee = create_exception_handler(ssa, try, pei, bptr, catchtype);
+                                                       ee->handler->invars[0] = ssa->jd->vartop + exhandler_count;
+                                                       exhandler_count += 1;
+                                                       ssa->jd->exceptiontablelength += 1;
+                                                       if (firstee == NULL) {
+                                                               firstee = lastee = ee;
+                                                       } else {
+                                                               lastee->next = ee;
+                                                               lastee->down = ee;
+                                                               lastee = ee;
+                                                       }
+                                                       pei += 1;
+                                               }
+                                       }
+                               }
+                               /* XXX 
+                                  <------------------->
+                                  <---><--><--->missing */
+                               if (firstee) {
+                                       lastee->next = ite->next;
+                                       lastee->down = ite->down;
+                                       *ite = *firstee;
+                                       ite = lastee;
+                               }
+                       }
+               }
+       }
+       
+       /* Allocate interface vars */
+
+       ssa->jd->var = DMREALLOC(ssa->jd->var, varinfo, ssa->jd->vartop, ssa->jd->vartop + exhandler_count);
+       for (v = ssa->jd->var + ssa->jd->vartop; v != ssa->jd->var + ssa->jd->vartop + exhandler_count; ++v) {
+               v->type = TYPE_ADR;
+               v->flags = INOUT;
+       }
+       ssa->jd->vartop += exhandler_count;
+       ssa->jd->varcount += exhandler_count;
+}
+
+void yssa(jitdata *jd) {
+       basicblock *it;
+       basicblock_info *iti;
+       ssa_info *ssa;
+
+       if (jd->localcount == 0) return;
+
+       if (test_do_verbose(jd)) do_verbose = 1;
+
+       printf("=============== [ before %s ] =========================\n", jd->m->name->text);
+       show_method(jd, 3);
+       printf("=============== [ /before ] =========================\n");
+
+       ssa = DNEW(ssa_info);
+       ssa->jd = jd;
+       ssa->max_locals = sizeof(ssa->locals) / sizeof(ssa->locals[0]);
+       MCOPY(ssa->locals, jd->var, varinfo, jd->localcount);
+       ssa->locals_count = jd->localcount;
+
+       FOR_EACH_BASICBLOCK(jd, it) {
+               if (basicblock_reached(it)) {
+                       iti = DNEW(basicblock_info);
+                       MZERO(iti, basicblock_info, 1);
+                       if (jd->localcount > 0) {
+                               iti->phi_functions = DMNEW(phi_function, jd->localcount);
+                               iti->phi_max = jd->localcount;
+                       }
+                       it->vp = iti;
+               } else {
+                       it->vp = NULL;
+               }
+       }
+
+       mark_loops(jd->basicblocks);
+
+       traverse(ssa, jd->basicblocks, traverse_fun_impl);
+
+       ssa_rename_others(ssa);
+
+       /*fill_in_phi_args(ssa);*/
+
+       ssa_export(ssa);
+
+       ssa_create_phi_moves(ssa);
+       ssa_create_ex_phi_moves(ssa);
+
+       printf("=============== [ after ] =========================\n");
+       show_method(jd, 3);
+       printf("=============== [ /after ] =========================\n");
+
+       do_verbose = 0;
+}
+
+void eliminate_subbasicblocks(jitdata *jd) {
+       basicblock *bptr, *next;
+
+       FOR_EACH_BASICBLOCK(jd, bptr) {
+               if (bptr->subbasicblocks) {
+                       next = bptr->next;
+                       *bptr = *(bptr->subbasicblocks);
+                       bptr->subbasicblocks = NULL;
+
+                       /* *prev = bptr->subbasicblocks;
+                       bptr = bptr->subbasicblocks; */
+
+                       while (bptr->next) {
+                               bptr = bptr->next;
+                       }
+                       bptr->next = next;
+               }
+       }
+
+       if (test_do_verbose(jd)) do_verbose = 1;
+       printf("=============== [ elim ] =========================\n");
+       show_method(jd, 3);
+       printf("=============== [ /elim ] =========================\n");
+       do_verbose = 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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vm/jit/optimizing/ssa_phi.c b/src/vm/jit/optimizing/ssa_phi.c
new file mode 100644 (file)
index 0000000..9ab4f6c
--- /dev/null
@@ -0,0 +1,314 @@
+/* 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
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+   Contact: cacao@complang.tuwien.ac.at
+
+   Authors: Christian Ullrich
+
+   $Id: $
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mm/memory.h"
+
+#include "toolbox/bitvector.h"
+#include "toolbox/worklist.h"
+
+#include "vm/builtin.h"
+
+#include "vm/jit/jit.h" /* icmd_table */
+
+#include "vm/jit/optimizing/dominators.h"
+#include "vm/jit/optimizing/graph.h"
+#include "vm/jit/optimizing/lifetimes.h"
+#include "vm/jit/optimizing/lsra.h"
+#include "vm/jit/optimizing/ssa.h"
+#include "vm/jit/optimizing/ssa_phi.h"
+
+#if defined(SSA_DEBUG_VERBOSE)
+#include "vmcore/options.h"   /* compileverbose */
+#endif
+
+/* ssa_place_phi_functions *****************************************************
+
+Algorithm is based on "modern compiler implementation in C" from andrew 
+w. appel, edition 2004
+
+Corrections:
+page 441 Algorithm 19.6. Inserting phi-functions:
+
+...
+    for each Y in DF[n]
+-       if Y not element of A phi [n]
++       if a not element of A phi [n]
+            insert the statment a <- ...
+...
+...
+-       A phi [n] <- A phi [n] join {Y}
++       A phi [n] <- A phi [n] join {a}
+-      if Y not element of A orig [n]
++      if a not element of A orig [Y]
+           W <- W join {Y}
+
+
+ls->phi[n][a][p] is created and populated.
+
+n in [0..ls->basicblockcount[
+a in [0..ls->ssavarcount[
+p in [1..Count of Predecessors of Basicblock n]
+
+For each basicblock Y in the dominance frontier of a basicblock n (0 <= n < 
+ls->basicblockcount) in which a variable (0 <= a < ls->ssavarcount) is defined 
+an entry in ls->phi[Y][a] is created.
+This entry is an array with the number of predecessors of Y elements + 1
+elements.
+This elements are all set to the variable a and represent the phi function which
+will get ai = phi(ai1, ai2, ..., aip) after ssa_rename.
+
+
+ls->phi[n][a] == NULL, if no phi function for Variable a for Basicblock n exists
+
+or
+
+ls->phi[n][a][0] == a, representing the result of the phi function and
+ls->phi[n][a][p] == a, representing the arguments of the phi function.
+
+*******************************************************************************/
+
+
+void ssa_place_phi_functions(jitdata *jd, graphdata *gd, dominatordata *dd)
+{
+       int a,i,j,n,Y;
+       bitvector *def_sites;
+       bitvector *A_phi;    /* [0..ls->basicblockcount[ of */
+                            /* ls->ssavarcount Bit         */
+       worklist *W;
+       int num_pred;
+
+       lsradata *ls;
+
+       ls = jd->ls;
+
+       W = wl_new(ls->basicblockcount);
+
+       def_sites = DMNEW(bitvector, ls->ssavarcount);
+       for(a = 0; a < ls->ssavarcount; a++)
+               def_sites[a] = bv_new(ls->basicblockcount);
+
+       ls->phi = DMNEW(int **, ls->basicblockcount);
+       A_phi = DMNEW(bitvector, ls->basicblockcount);
+       for(i = 0; i < ls->basicblockcount; i++) {
+               ls->phi[i] = DMNEW(int *, ls->ssavarcount);
+               for(j = 0; j < ls->ssavarcount; j++)
+                       ls->phi[i][j] = NULL;
+               A_phi[i] = bv_new(ls->ssavarcount);
+       }
+
+       /* copy var_def to def_sites */
+       /* var_def is valid for 0.. jd->basicblockcount (bb 0 for param init) */
+
+       for(n = 0; n <= jd->basicblockcount; n++)
+               for(a = 0; a < ls->ssavarcount; a++)
+                       if (bv_get_bit(ls->var_def[n], a))
+                               bv_set_bit(def_sites[a], n);
+#ifdef SSA_DEBUG_VERBOSE
+       if (compileverbose) {
+               printf("var Definitions:\n");
+               for(i = 0; i < ls->ssavarcount; i++) {
+                       printf("def_sites[%3i]=%p:",i,(void *)def_sites[i]);
+                       for(j = 0; j < ls->basicblockcount; j++) {
+                               if ((j % 5) == 0) printf(" ");
+                               if (bv_get_bit(def_sites[i], j))
+                                       printf("1");
+                               else
+                                       printf("0");
+                       }
+                       printf(" (");
+
+                       printf("\n");
+               }
+       }
+#endif
+
+       for(a = 0; a < ls->ssavarcount; a++) {
+
+               /* W<-def_sites(a) */
+
+               for(n = 0; n < ls->basicblockcount; n++)
+                       if (bv_get_bit(def_sites[a],n)) {
+                               wl_add(W, n);
+                       }
+                               
+               while (!wl_is_empty(W)) { /* W not empty */
+                       n = wl_get(W);
+
+                       for(i = 0; i < dd->num_DF[n]; i++) {
+                               Y = dd->DF[n][i];
+
+                               /* Node Y is in Dominance Frontier of n -> */
+                               /* insert phi function for a at top of Y*/
+
+                               _SSA_CHECK_BOUNDS(Y, 0, ls->basicblockcount);
+                               if (bv_get_bit( A_phi[Y], a) == 0) { 
+
+                                       /* a is not a Element of A_phi[Y] */
+                                       /* a <- phi(a,a...,a) to be inserted at top of Block Y */
+                                       /* phi has as many arguments, as Y has predecessors    */
+
+                                       num_pred =  graph_get_num_predecessor(gd, Y);
+                                       ls->phi[Y][a] = DMNEW(int, num_pred + 1);
+                                       for (j = 0; j < num_pred + 1; j++)
+                                               ls->phi[Y][a][j] = a;
+
+                                       /* increment the number of definitions of a by one */
+                                       /* for this phi function */
+
+                                       ls->num_defs[a]++;
+                                       
+                                       bv_set_bit(A_phi[Y], a);
+                                       if (bv_get_bit(ls->var_def[Y],a)==0) {
+
+                                               /* Iterated Dominance Frontier Criterion:  */
+                                               /* if Y had no definition for a, insert it */
+                                               /* into the Worklist, since now it         */
+                                               /* defines a through the phi function      */
+
+                                               wl_add(W, Y);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+void ssa_generate_phi_moves(jitdata *jd, graphdata *gd) {
+       int a, i, j, pred;
+       graphiterator iter;
+       lsradata *ls;
+
+       ls = jd->ls;
+
+       /* count moves to be inserted at the end of each block in moves[] */
+
+       ls->num_phi_moves = DMNEW(int, ls->basicblockcount);
+       for(i = 0; i < ls->basicblockcount; i++)
+               ls->num_phi_moves[i] = 0;
+       for(i = 0; i < ls->basicblockcount; i++)
+               for(a = 0; a < ls->ssavarcount; a++)
+                       if (ls->phi[i][a] != NULL) {
+#if 0
+                               if (ls->lifetime[ls->phi[i][a][0]].use == NULL) {
+                                       /* Var defined (only <- SSA Form!) in this phi function */
+                                       /* and not used anywhere -> delete phi function and set */
+                                       /* var to unused */
+
+                                       /* TODO: first delete use sites of arguments of phi */
+                                       /* function */
+                                       VAR(ls->lifetime[ls->phi[i][a][0]].v_index)->type = UNUSED;
+                                       ls->lifetime[ls->phi[i][a][0]].def = NULL;
+                                       ls->phi[i][a] = NULL;
+                               }
+                               else 
+#endif
+                                       {
+                                       pred = graph_get_first_predecessor(gd, i, &iter);
+                                       for(; pred != -1; pred = graph_get_next(&iter)) {
+                                               ls->num_phi_moves[pred]++;
+                                       }
+                               }
+                       }
+
+       /* allocate ls->phi_moves */
+
+       ls->phi_moves = DMNEW( int **, ls->basicblockcount);
+       for(i = 0; i < ls->basicblockcount; i++) {
+               ls->phi_moves[i] = DMNEW( int *, ls->num_phi_moves[i]);
+               for(j = 0; j <ls->num_phi_moves[i]; j++)
+                       ls->phi_moves[i][j] = DMNEW(int, 2);
+#ifdef SSA_DEBUG_VERBOSE
+               if (compileverbose)
+                       printf("ssa_generate_phi_moves: ls_num_phi_moves[%3i] = %3i\n",
+                                  i, ls->num_phi_moves[i]);
+#endif
+       }
+
+       /* populate ls->phi_moves */
+
+       for(i = 0; i < ls->basicblockcount; i++)
+               ls->num_phi_moves[i] = 0;
+       for(i = 0; i < ls->basicblockcount; i++)
+               for(a = 0; a < ls->ssavarcount; a++)
+                       if (ls->phi[i][a] != NULL) {
+                               pred = graph_get_first_predecessor(gd, i, &iter);
+                               for(j = 0; pred != -1; j++, pred = graph_get_next(&iter)) {
+                                       /* target is phi[i][a][0] */
+                                       /* source is phi[i][a][j+1] */
+                                       if (ls->phi[i][a][j+1] != ls->varcount_with_indices) {
+                                               /* valid move */
+                                               if (ls->phi[i][a][0] != ls->phi[i][a][j+1]) {
+                                                       ls->phi_moves[pred][ls->num_phi_moves[pred]][0] =
+                                                               ls->phi[i][a][0];
+                                                       ls->phi_moves[pred][(ls->num_phi_moves[pred])++][1]=
+                                                               ls->phi[i][a][j+1];
+                                               }
+                                       }
+                               }
+                       }
+}
+
+#ifdef SSA_DEBUG_VERBOSE
+void ssa_print_phi(lsradata *ls, graphdata *gd) {
+       int i,j,k;
+
+       printf("phi Functions (varcount_with_indices: %3i):\n", 
+                  ls->varcount_with_indices);
+       for(i = 0; i < ls->basicblockcount; i++) {
+               for(j = 0; j < ls->ssavarcount; j++) {
+                       if (ls->phi[i][j] != NULL) {
+                               printf("BB %3i %3i = phi(", i, ls->phi[i][j][0]);
+                               for(k = 1; k <= graph_get_num_predecessor(gd, i); k++)
+                                       printf("%3i ",ls->phi[i][j][k]);
+                               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:
+ */
diff --git a/src/vm/jit/optimizing/ssa_phi.h b/src/vm/jit/optimizing/ssa_phi.h
new file mode 100644 (file)
index 0000000..5a0fda6
--- /dev/null
@@ -0,0 +1,64 @@
+/* src/vm/jit/optimizing/ssa.h - static single assignment form header
+
+   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
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+   Contact: cacao@complang.tuwien.ac.at
+
+   Authors: Christian Ullrich
+
+   $Id: ssa.h$
+
+*/
+
+
+#ifndef _SSA_PHI_H
+#define _SSA_PHI_H
+
+#include "vm/jit/optimizing/graph.h"
+
+#if !defined(NDEBUG)
+# include <assert.h>
+#endif
+
+/* function prototypes */
+void ssa_place_phi_functions(jitdata *jd, graphdata *gd, dominatordata *dd);
+void ssa_generate_phi_moves(jitdata *, graphdata *);
+#ifdef SSA_DEBUG_VERBOSE
+void ssa_print_phi(lsradata *ls, graphdata *gd);
+#endif
+
+#endif /* _SSA_PHI_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/optimizing/ssa_rename.c b/src/vm/jit/optimizing/ssa_rename.c
new file mode 100644 (file)
index 0000000..474419c
--- /dev/null
@@ -0,0 +1,779 @@
+/* src/vm/jit/optimizing/ssa.c - static single-assignment form
+
+   Copyright (C) 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., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mm/memory.h"
+
+#include "toolbox/bitvector.h"
+#include "toolbox/worklist.h"
+
+#include "vm/builtin.h"
+
+#include "vm/jit/jit.h" /* icmd_table */
+
+#include "vm/jit/optimizing/dominators.h"
+#include "vm/jit/optimizing/graph.h"
+#include "vm/jit/optimizing/lifetimes.h"
+#include "vm/jit/optimizing/lsra.h"
+#include "vm/jit/optimizing/ssa.h"
+#include "vm/jit/optimizing/ssa_rename.h"
+
+#if defined(SSA_DEBUG_VERBOSE)
+#include "vmcore/options.h"   /* compileverbose */
+#endif
+
+/* function prototypes */
+void ssa_rename_(jitdata *jd,  graphdata *gd, dominatordata *dd, int n);
+int ssa_rename_def_(lsradata *ls, int a);
+
+/* ssa_rename ******************************************************************
+
+Rename the variables a (0 <= a < ls->ssavarcount) so that each new variable
+has only one definition (SSA form).
+
+ls->def_count[0..ls->ssavarcount[ holds the number of definitions of each var.
+ls->var_0[0..ls->ssavarcount[ will be set to the new index of the first 
+                              definition of each old var.
+ls->varcount_with_indices     will be se to the new maximum varcount of LOCAL
+                              and IOVARS.
+
+All other vars (TEMPVAR and PREALLOC) will get a new unique index above 
+ls->varcount_with_indices.
+
+jd->var and jd->varcount will be set for this renamed vars.
+
+*******************************************************************************/
+
+void ssa_rename(jitdata *jd, graphdata *gd, dominatordata *dd)
+{
+       int i, mi, l, j, p, t;
+       int type, flags;
+       methoddesc *md = jd->m->parseddesc;
+
+       varinfo *new_vars;
+       lsradata *ls;
+
+       ls = jd->ls;
+       
+       ssa_rename_init(jd, gd);
+
+       /* Consider definition of Local Vars initialized with Arguments */
+       /* in Block 0 */
+       /* init is regarded as use too-> ssa_rename_use ->bullshit!!*/
+
+       for (p = 0, l= 0; p < md->paramcount; p++) {
+               t = md->paramtypes[p].type;
+               mi = l * 5 + t;
+               i = jd->local_map[mi];
+               l++;
+               if (IS_2_WORD_TYPE(t))
+                       l++;
+               if (i == UNUSED)
+                       continue;
+
+               /* !!!!! locals are now numbered as the parameters !!!!       */
+               /* !!!!! no additional increment for 2 word types !!!!!       */
+               /* this happens later on! here we still need the increment    */
+               /* index of var can be in the range from 0 up to not including*/
+               /* jd->varcount */
+
+               
+               i = ls->new_varindex[i];
+
+               /* ignore return value, since first definition gives 0 -> */
+               /* no rename necessary */
+
+               j = ssa_rename_def_(ls, i);
+               _SSA_ASSERT(j == 0);
+               jd->local_map[mi] = i;
+       }
+       ssa_rename_(jd, gd, dd, 0);
+
+#if 0
+       /* DO _NOT_ DO THIS! Look at java.util.stringtokenizer.counttokens!   */
+       /* if there is no use of the defined Var itself by the phi function   */
+       /* for a loop path, in which this var is not used, it will not be life*/
+       /* in this path and overwritten! */
+
+       /* Invalidate all xij from xi0=phi(xi1,xi2,xi3,..,xin) with xij == xi0*/
+       /* this happens if the phi function is the first definition of x or in*/
+       /* a path with a backedge xi has no definition */ 
+       /* a phi(xij) = ...,xij,... with the only use and definition of xij by*/
+       /* this phi function would otherwise "deadlock" the dead code         */
+       /* elemination (invalidate means set it to UNUSED)                    */
+       /* a phi function phi(xi0)=xi1,xi2,...xin wiht xij == xi0 for all j in*/
+       /* [1,n] can be removed */
+
+       for(i = 0; i < ls->ssavarcount; i++) {
+         for(t = 0; t < ls->basicblockcount; t++) {
+           if (ls->phi[t][i] != 0) {
+             remove_phi = true;
+             for(p = 1; p <= graph_get_num_predecessor(gd, t); p++) {
+               if (ls->phi[t][i][0] == ls->phi[t][i][p])
+                 ls->phi[t][i][p] = UNUSED;
+               else 
+                 remove_phi = false;
+             }
+           }
+           if (remove_phi)
+             ls->phi[t][i] = NULL;
+         }
+       }
+#endif
+
+#if defined(SSA_DEBUG_CHECK) || defined(SSA_DEBUG_VERBOSE)
+# if defined(SSA_DEBUG_VERBOSE)
+       if (compileverbose) {
+               printf("%s %s ",jd->m->clazz->name->text, jd->m->name->text);
+               if (code_is_leafmethod(jd->code))
+                       printf("**Leafmethod**");
+               printf("\n");
+       }
+# endif
+       if (strcmp(jd->m->clazz->name->text,"fp")==0)
+               if (strcmp(jd->m->name->text,"testfloat")==0)
+# if defined(SSA_DEBUG_VERBOSE)
+                       if (compileverbose) 
+                               printf("12-------------------12\n");
+# else
+               { int dummy=1; dummy++; }
+# endif
+#endif
+
+       /* recreate rd->locals[][] */
+       /* now only one (local_index/type) pair exists anymore     */
+       /* all var[t][i] with var_to_index[var[t][i]] >= 0 are locals */
+       /* max local index after SSA indexing is in ls->local_0[ls->max_locals] */
+       
+       new_vars = DMNEW(varinfo, ls->vartop);
+       for(i = 0; i < ls->vartop ; i++)
+               new_vars[i].type = UNUSED;
+       for(i = 0; i < jd->varcount; i++) {
+                       p = ls->new_varindex[i];
+                       if (p != UNUSED) {
+                               if (p < ls->ssavarcount)
+                                       p = ls->var_0[p];
+                               new_vars[p].type  = VAR(i)->type;
+                               new_vars[p].flags = VAR(i)->flags;
+                               ls->lifetime[p].v_index = p;
+                               ls->lifetime[p].type = VAR(i)->type;
+                       }
+       }
+
+       /* take care of newly indexed local & in/out vars */
+
+       for(i = 0; i < ls->ssavarcount; i++) {
+               j = ls->var_0[i];
+               type = new_vars[j].type;
+               flags = new_vars[j].flags;
+               j++;
+               for (; j < ls->var_0[i + 1]; j++) {
+                       new_vars[j].type = type;
+                       new_vars[j].flags = flags;
+                       ls->lifetime[j].v_index = j;
+                       ls->lifetime[j].type = type;
+               }
+       }
+
+#ifdef SSA_DEBUG_VERBOSE
+       if (compileverbose) {
+
+               printf("ssa_rename: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
+                          ls->ssavarcount);
+               for(i = 0; i < jd->varcount; i++) {
+                       printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
+                       ssa_show_variable(jd, i, VAR(i),0);
+                       j = ls->new_varindex[i];
+                       if ((j != UNUSED) && (j < ls->ssavarcount))
+                               printf(" -> %3i ... %3i", ls->var_0[j], ls->var_0[j + 1] - 1);
+                       else
+                               printf(" -> %3i", j);
+                       printf("\n");
+               }
+       }
+#endif
+
+       jd->var = new_vars;
+       jd->varcount = ls->vartop;
+       jd->vartop = ls->vartop;
+
+#ifdef SSA_DEBUG_VERBOSE
+       if (compileverbose) {
+               printf("ssa_rename: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
+                          ls->ssavarcount);
+               for(i = 0; i < jd->varcount; i++) {
+                       printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
+                       ssa_show_variable(jd, i, VAR(i),0);
+                       printf("\n");
+               }
+       }
+#endif
+}
+
+/* ssa_rename_init *************************************************************
+
+Setup the data structure for ssa_rename
+
+ls->def_count[0..ls->ssavarcount[ holds the number of definitions of each var.
+ls->var_0[0..ls->ssavarcount[ will be set to the new index of the first 
+                              definition of each old var.
+ls->varcount_with_indices     will be se to the new maximum varcount of LOCAL
+                              and IOVARS.
+
+All other vars (TEMPVAR and PREALLOC) will get a new unique index above 
+ls->varcount_with_indices.
+
+jd->var and jd->varcount will be set for this renamed vars.
+
+*******************************************************************************/
+
+void ssa_rename_init(jitdata *jd, graphdata *gd) 
+{
+       int a, i;
+#if 0
+       int p;
+#endif
+       lsradata *ls;
+
+       ls = jd->ls;
+       
+       /* set up new locals */
+       /* ls->new_varindex[0..jd->varcount[ holds the new unique index */
+       /* for locals and iovars */
+
+       /* ls->num_defs[index] gives the number of indizes which will be created  */
+       /* from SSA */
+
+       /* -> vars will be numbered in this sequence: L0(0)..L0(i) L1(0)..L1(j) ..*/
+       /* ls->var_0[X] will point to each LX(0)  */
+       /* ls->var_0[ls->ssavarcount] will hold ls->varcount_with_indices */
+
+       /* as first step cummulate the num_defs array for locals and iovars       */
+       /* last element is the maximum var count */
+
+       ls->var_0 = DMNEW(int, max(1, ls->ssavarcount + 1));
+       ls->var_0[0] = 0;
+       ls->varcount_with_indices = 0;
+       for(i = 0; i < ls->ssavarcount; i++) {
+               ls->varcount_with_indices += ls->num_defs[i];
+               ls->var_0[i+1] = ls->var_0[i] + ls->num_defs[i];
+       }
+
+#if 0
+       /* Change the var indices in phi from La to La(0) */
+
+       for(i = 0; i < ls->basicblockcount; i++)
+               for (a = 0; a < ls->ssavarcount; a++)
+                       if (ls->phi[i][a] != NULL)                              
+                               for(p = 0; p < graph_get_num_predecessor(gd, i) + 1; p++)
+                                       ls->phi[i][a][p] = ls->var_0[a];
+#endif
+       
+       /* Initialization */
+
+       ls->count     = DMNEW(int, max(1, ls->ssavarcount));
+       ls->stack     = DMNEW(int *, max(1, ls->ssavarcount));
+       ls->stack_top = DMNEW(int, max(1, ls->ssavarcount));
+       for(a = 0; a < ls->ssavarcount; a++) {
+               ls->count[a] = 0;
+               ls->stack_top[a] = 0;
+
+               /* stack a has to hold number of defs of a Elements + 1 */
+
+               ls->stack[a] = DMNEW(int, ls->num_defs[a] + 1);
+               ls->stack[a][ls->stack_top[a]++] = 0;
+       }
+
+       if (ls->ssavarcount > 0) {
+
+               /* Create the num_var_use Array */
+
+               ls->num_var_use = DMNEW(int *, ls->basicblockcount);
+               for(i = 0; i < ls->basicblockcount; i++) {
+                       ls->num_var_use[i] =DMNEW(int, max(1, ls->varcount_with_indices));
+                       for(a = 0; a < ls->varcount_with_indices; a++)
+                               ls->num_var_use[i][a] = 0;
+               }
+
+               /* Create the use_sites Array of Bitvectors*/
+               /* use max(1,..), to ensure that the array is created! */
+
+               ls->use_sites =  DMNEW(bitvector, max(1, ls->varcount_with_indices));
+               for(a = 0; a < ls->varcount_with_indices; a++)
+                       ls->use_sites[a] = bv_new(ls->basicblockcount);
+       }
+
+       /* init lifetimes */
+       /* count number of TEMPVARs */
+
+       ls->lifetimecount = 0;
+       for(i = 0; i < jd->varcount; i++)
+               if ((i >= jd->localcount) || (!(jd->var[i].flags & (INOUT | PREALLOC))))
+                       ls->lifetimecount++;
+
+       ls->varcount = ls->varcount_with_indices + ls->lifetimecount;
+
+       ls->lifetimecount = ls->varcount;
+       ls->lifetime = DMNEW(struct lifetime, ls->lifetimecount);
+       ls->lt_used = DMNEW(int, ls->lifetimecount);
+       ls->lt_int = DMNEW(int, ls->lifetimecount);
+       ls->lt_int_count = 0;
+       ls->lt_flt = DMNEW(int, ls->lifetimecount);
+       ls->lt_flt_count = 0;
+       ls->lt_mem = DMNEW(int, ls->lifetimecount);
+       ls->lt_mem_count = 0;
+       for (i=0; i < ls->lifetimecount; i++) {
+               ls->lifetime[i].type = UNUSED;
+               ls->lifetime[i].savedvar = 0;           
+               ls->lifetime[i].flags = 0;
+               ls->lifetime[i].usagecount = 0;
+               ls->lifetime[i].bb_last_use = -1;
+               ls->lifetime[i].bb_first_def = -1;
+               ls->lifetime[i].use = NULL;
+               ls->lifetime[i].def = NULL;
+               ls->lifetime[i].last_use = NULL;
+       }
+
+       /* for giving TEMP and PREALLOC vars a new unique index */
+
+       ls->vartop = ls->varcount_with_indices; 
+
+#ifdef SSA_DEBUG_VERBOSE
+       if (compileverbose) {
+               printf("ssa_rename_init: Vars: Orig:%3i SSAVar: %3i\n", jd->varcount,
+                          ls->ssavarcount);
+               for(i = 0; i < jd->varcount; i++) {
+                       if ((i < jd->localcount) || ( VAR(i)->flags & INOUT)) {
+                               printf("%3i(%3i,%3x) ",i,VAR(i)->type, VAR(i)->flags);
+                               ssa_show_variable(jd, i, VAR(i),0);
+                               if ((i < ls->ssavarcount) || (VAR(i)->flags & INOUT)) {
+                                       printf(" -> %3i", ls->new_varindex[i]);
+                               }
+                               printf("\n");
+                       }
+               }
+               ssa_print_phi(ls, gd);
+       }
+#endif
+}
+
+int ssa_rename_def_(lsradata *ls, int a) {
+       int i;
+       
+       _SSA_CHECK_BOUNDS(a,0,ls->ssavarcount);
+       ls->count[a]++;
+       i = ls->count[a] - 1;
+       /* push i on stack[a] */
+       _SSA_CHECK_BOUNDS(ls->stack_top[a], 0, ls->num_defs[a] + 1);
+       ls->stack[a][ls->stack_top[a]++] = i;
+       return i;
+}
+
+int ssa_rename_def(jitdata *jd, int *def_count, int a) {
+       int i, a1, ret;
+       lsradata *ls;
+
+       ls = jd->ls;
+       
+       a1 = ls->new_varindex[a];
+       _SSA_CHECK_BOUNDS(a1, UNUSED, ls->varcount);
+       if ((a1 != UNUSED) && (a1 < ls->ssavarcount)) {
+               /* local or inoutvar -> normal ssa renaming */
+               _SSA_ASSERT((a < jd->localcount) || (VAR(a)->flags & INOUT));
+               /* !IS_TEMPVAR && !IS_PREALLOC == (IS_LOCALVAR || IS_INOUT) */
+
+               def_count[a1]++;
+               i = ssa_rename_def_(ls, a1);
+               ret = ls->var_0[a1] + i;
+       }
+       else {
+               /* TEMP or PREALLOC var */
+               if (a1 == UNUSED) {
+                       ls->new_varindex[a] = ls->vartop;
+                       ret = ls->vartop;
+                       ls->vartop++;
+                       _SSA_ASSERT( ls->vartop < ls->varcount);
+               }
+               else
+                       ret = a1;
+       }
+       return ret;
+}
+
+void ssa_rename_use_(lsradata *ls, int n, int a) {
+       _SSA_CHECK_BOUNDS(a, 0, ls->varcount_with_indices);
+       if (ls->ssavarcount > 0) {
+               bv_set_bit(ls->use_sites[a], n);
+               ls->num_var_use[n][a]++;
+       }
+}
+
+int ssa_rename_use(lsradata *ls, int n, int a) {
+       int a1, i;
+       int ret;
+
+       a1 = ls->new_varindex[a];
+       _SSA_CHECK_BOUNDS(a1, UNUSED, ls->varcount);
+       if ((a1 != UNUSED) && (a1 < ls->ssavarcount)) {
+               /* local or inoutvar -> normal ssa renaming */
+               /* i <- top(stack[a]) */
+
+               _SSA_CHECK_BOUNDS(ls->stack_top[a1]-1, 0, ls->num_defs[a1]+1);
+               i = ls->stack[a1][ls->stack_top[a1] - 1]; 
+               _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a1]);
+
+               ret = ls->var_0[a1] + i;
+       }
+       else {
+               /* TEMP or PREALLOC var */
+               if (a1 == UNUSED) {
+                       ls->new_varindex[a] = ls->vartop;
+                       ret = ls->vartop;
+                       ls->vartop++;
+                       _SSA_ASSERT( ls->vartop < ls->varcount);
+               }
+               else
+                       ret = a1;
+       }
+
+       return ret;
+}
+
+#ifdef SSA_DEBUG_VERBOSE
+void ssa_rename_print(instruction *iptr, char *op, int from,  int to) {
+       if (compileverbose) {
+               printf("ssa_rename_: ");
+               if (iptr != NULL)
+                       printf("%s ", bytecode[iptr->opc].mnemonic);
+               else
+                       printf("       ");
+
+               printf("%s: %3i->%3i\n", op, from, to);
+       }
+}
+#endif
+
+/* ssa_rename_ ****************************************************************
+
+Algorithm is based on "modern compiler implementation in C" from andrew 
+w. appel, edition 2004
+
+page 443 Algorithm 19.7. Renaming Variables
+
+*******************************************************************************/
+
+void ssa_rename_(jitdata *jd, graphdata *gd, dominatordata *dd, int n) {
+       int a, i, j, k, iindex, Y, v;
+       int in_d, out_d;
+       int *def_count;
+       /* [0..ls->varcount[ Number of Definitions of this var in this  */
+       /* Basic Block. Used to remove the entries off the stack at the */
+       /* end of the function */
+       instruction *iptr;
+       s4 *in, *out, *argp;
+       graphiterator iter_succ, iter_pred;
+       struct lifetime *lt;
+
+       methoddesc *md;
+       methodinfo *m;
+       builtintable_entry *bte;
+       lsradata *ls;
+
+       ls = jd->ls;
+       m  = jd->m;
+
+#ifdef SSA_DEBUG_VERBOSE
+       if (compileverbose)
+               printf("ssa_rename_: BB %i\n",n);
+#endif
+
+       _SSA_CHECK_BOUNDS(n, 0, ls->basicblockcount);
+
+       def_count = DMNEW(int, max(1, ls->ssavarcount));
+       for(i = 0; i < ls->ssavarcount; i++)
+               def_count[i] = 0;
+
+       /* change Store of possible phi functions from a to ai*/
+
+       for(a = 0; a < ls->ssavarcount; a++)
+               if (ls->phi[n][a] != NULL) {
+                       def_count[a]++;
+
+                       /* do not mark this store as use - maybe this phi function */
+                       /* can be removed for unused Vars*/
+
+                       j = ls->var_0[a] + ssa_rename_def_(ls, a);
+#ifdef SSA_DEBUG_VERBOSE
+                       ssa_rename_print( NULL, "phi-st", ls->phi[n][a][0], j);
+#endif
+                       ls->phi[n][a][0] = j;
+               }
+
+       in   = ls->basicblocks[n]->invars;
+       in_d = ls->basicblocks[n]->indepth - 1;
+
+       /* change use of instack Interface stackslots except top SBR and EXH */
+       /* stackslots */
+
+       if ((ls->basicblocks[n]->type == BBTYPE_EXH) ||
+               (ls->basicblocks[n]->type == BBTYPE_SBR)) {
+               in_d--;
+       }
+/*     out   = ls->basicblocks[n]->outvars; */
+/*     out_d = ls->basicblocks[n]->outdepth - 1; */
+
+/*     for(; out_d > in_d; out_d--); */
+
+       for (; in_d >= 0; in_d--) {
+               /* Possible Use of ls->new_varindex[jd->var[in_d]] */
+               _SSA_ASSERT(ls->new_varindex[in[in_d]] != UNUSED);
+
+               a = ls->new_varindex[in[in_d]];
+               _SSA_CHECK_BOUNDS(a, 0, ls->ssavarcount);
+
+               /* i <- top(stack[a]) */
+
+               _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
+               i = ls->stack[a][ls->stack_top[a]-1]; 
+               _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
+
+               /* Replace use of x with xi */
+
+#ifdef SSA_DEBUG_VERBOSE
+                       ssa_rename_print( NULL, "invar", in[in_d], ls->var_0[a]+i);
+#endif
+               in[in_d] = ls->var_0[a] + i;
+               lt = ls->lifetime + in[in_d];
+
+               lt->v_index = in[in_d];
+               lt->bb_last_use = -1;
+       }
+
+       iptr = ls->basicblocks[n]->iinstr;
+
+       for(iindex = 0; iindex < ls->basicblocks[n]->icount; iindex++, iptr++) {
+
+               /* check for use (s1, s2, s3 or special (argp) ) */
+
+               switch (icmd_table[iptr->opc].dataflow) {
+               case DF_3_TO_0:
+               case DF_3_TO_1: /* icmd has s1, s2 and s3 */
+                       j = ssa_rename_use(ls, n, iptr->sx.s23.s3.varindex);
+#ifdef SSA_DEBUG_VERBOSE
+                       ssa_rename_print( iptr, "s3 ", iptr->sx.s23.s3.varindex, j);
+#endif
+                       iptr->sx.s23.s3.varindex = j;
+
+                       /* now "fall through" for handling of s2 and s1 */
+
+               case DF_2_TO_0:
+               case DF_2_TO_1: /* icmd has s1 and s2 */
+                       j = ssa_rename_use(ls, n, iptr->sx.s23.s2.varindex);
+#ifdef SSA_DEBUG_VERBOSE
+                       ssa_rename_print( iptr, "s2 ", iptr->sx.s23.s2.varindex, j);
+#endif
+                       iptr->sx.s23.s2.varindex = j;
+
+                       /* now "fall through" for handling of s1 */
+
+               case DF_1_TO_0:
+               case DF_1_TO_1:
+               case DF_MOVE:
+               case DF_COPY:
+                       j = ssa_rename_use(ls, n, iptr->s1.varindex);
+#ifdef SSA_DEBUG_VERBOSE
+                       ssa_rename_print( iptr, "s1 ", iptr->s1.varindex, j);
+#endif
+                       iptr->s1.varindex = j;
+                       break;
+
+               case DF_INVOKE:
+               case DF_BUILTIN:
+               case DF_N_TO_1:
+                       /* do not use md->paramcount, pass-through stackslots have */
+                       /* to be renamed, too */
+                       i = iptr->s1.argcount;
+                       argp = iptr->sx.s23.s2.args;
+                       while (--i >= 0) {
+                               j = ssa_rename_use(ls, n, *argp);
+#ifdef SSA_DEBUG_VERBOSE
+                               ssa_rename_print( iptr, "arg", *argp, j);
+#endif
+                               *argp = j;
+                               argp++;
+                       }
+                       break;
+               }
+                       
+
+               /* Look for definitions (iptr->dst). INVOKE and BUILTIN have */
+               /* an optional dst - so they to be checked first */
+
+               v = UNUSED;
+               if (icmd_table[iptr->opc].dataflow == DF_INVOKE) {
+                       INSTRUCTION_GET_METHODDESC(iptr,md);
+                       if (md->returntype.type != TYPE_VOID)
+                               v = iptr->dst.varindex;
+               }
+               else if (icmd_table[iptr->opc].dataflow == DF_BUILTIN) {
+                       bte = iptr->sx.s23.s3.bte;
+                       md = bte->md;
+                       if (md->returntype.type != TYPE_VOID)
+                               v = iptr->dst.varindex;
+               }
+               else if (icmd_table[iptr->opc].dataflow >= DF_DST_BASE) {
+                       v = iptr->dst.varindex;
+               }
+
+               if (v != UNUSED) {
+                       j = ssa_rename_def(jd, def_count, iptr->dst.varindex);
+#ifdef SSA_DEBUG_VERBOSE
+                       ssa_rename_print( iptr, "dst", iptr->dst.varindex, j);
+#endif
+                       iptr->dst.varindex = j;
+               }
+
+                               /* ?????????????????????????????????????????????????????????? */
+                               /* Mark Def as use, too. Since param initialisation is in     */
+                               /* var_def and this would not remove this locals, if not used */
+                               /* elsewhere   */
+                               /* ?????????????????????????????????????????????????????????? */
+
+       }
+
+       /* change outstack Interface stackslots */
+       out = ls->basicblocks[n]->outvars;
+       out_d = ls->basicblocks[n]->outdepth - 1;
+
+       for (;out_d >= 0; out_d--) {
+               /* Possible Use of ls->new_varindex[jd->var[out_d]] */
+               _SSA_ASSERT(ls->new_varindex[out[out_d]] != UNUSED);
+
+               a = ls->new_varindex[out[out_d]];
+               _SSA_CHECK_BOUNDS(a, 0, ls->ssavarcount);
+
+               /* i <- top(stack[a]) */
+
+               _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
+               i = ls->stack[a][ls->stack_top[a]-1]; 
+               _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
+
+               /* Replace use of x with xi */
+
+#ifdef SSA_DEBUG_VERBOSE
+                       ssa_rename_print( NULL, "outvar", out[out_d], ls->var_0[a]+i);
+#endif
+               out[out_d] = ls->var_0[a] + i;
+               lt = ls->lifetime + out[out_d];
+
+               lt->v_index = out[out_d];
+               lt->bb_last_use = -1;
+       }
+
+       /* change use in phi Functions of Successors */
+
+       Y = graph_get_first_successor(gd, n, &iter_succ);
+       for(; Y != -1; Y = graph_get_next(&iter_succ)) {
+               _SSA_CHECK_BOUNDS(Y, 0, ls->basicblockcount);
+               k = graph_get_first_predecessor(gd, Y, &iter_pred);
+               for (j = 0; (k != -1) && (k != n); j++)
+                       k = graph_get_next(&iter_pred);
+               _SSA_ASSERT(k == n);
+
+               /* n is jth Predecessor of Y */
+
+               for(a = 0; a < ls->ssavarcount; a++)
+                       if (ls->phi[Y][a] != NULL) {
+
+                               /* i <- top(stack[a]) */
+                               
+                               if (ls->stack_top[a] == 1) {
+                                       /* no definition till now in controll flow */
+#ifdef SSA_DEBUG_VERBOSE
+                                       if (compileverbose) {
+                                               printf("Succ %3i Arg %3i \n", Y, j);
+                                               ssa_rename_print( NULL, "phi-use", ls->phi[Y][a][j+1], UNUSED);
+                                       }
+#endif
+                                       ls->phi[Y][a][j+1] = UNUSED;
+                               }
+                               else {
+                                       _SSA_CHECK_BOUNDS(ls->stack_top[a]-1, 0, ls->num_defs[a]+1);
+                                       i = ls->stack[a][ls->stack_top[a]-1]; 
+                                       _SSA_CHECK_BOUNDS(i, 0, ls->num_defs[a]);
+
+                                       /* change jth operand from a0 to ai */
+
+                                       i = ls->var_0[a] + i;
+#ifdef SSA_DEBUG_VERBOSE
+                                       if (compileverbose) {
+                                               printf("Succ %3i Arg %3i \n", Y, j);
+                                               ssa_rename_print( NULL, "phi-use", ls->phi[Y][a][j+1], i);
+                                       }
+#endif
+                                       ls->phi[Y][a][j+1] = i;
+                                       _SSA_CHECK_BOUNDS(ls->phi[Y][a][j+1], 0,
+                                                                         ls->varcount_with_indices);
+
+                                       /* use by phi function has to be remembered, too */
+
+                                       ssa_rename_use_(ls, n, ls->phi[Y][a][j+1]);
+                               }
+
+                               /* ????????????????????????????????????????????? */
+                               /* why was this only for local vars before ?     */
+                               /* ????????????????????????????????????????????? */
+
+                       }
+       }
+       
+       /* Call ssa_rename_ for all Childs of n of the Dominator Tree */
+       for(i = 0; i < ls->basicblockcount; i++)
+               if (dd->idom[i] == n)
+                       ssa_rename_(jd, gd, dd, i);
+
+       /* pop Stack[a] for each definition of a var a in the original S */
+       for(a = 0; a < ls->ssavarcount; a++) {
+               ls->stack_top[a] -= def_count[a];
+               _SSA_ASSERT(ls->stack_top[a] >= 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/vm/jit/optimizing/ssa_rename.h b/src/vm/jit/optimizing/ssa_rename.h
new file mode 100644 (file)
index 0000000..2b8c9f1
--- /dev/null
@@ -0,0 +1,61 @@
+/* src/vm/jit/optimizing/ssa.h - static single assignment form header
+
+   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
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+   Contact: cacao@complang.tuwien.ac.at
+
+   Authors: Christian Ullrich
+
+   $Id: ssa.h$
+
+*/
+
+
+#ifndef _SSA_RENAME_H
+#define _SSA_RENAME_H
+
+#include "vm/jit/optimizing/graph.h"
+
+#if !defined(NDEBUG)
+# include <assert.h>
+#endif
+
+/* function prototypes */
+void ssa_rename_init(jitdata *jd, graphdata *gd);
+void ssa_rename(jitdata *jd, graphdata *gd, dominatordata *dd);
+
+#endif /* _SSA_RENAME_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 b2c74ccd7ec09230b1a99f19cc09c09d7ca79a5e..db707e71421de82ebc346a81d4d77ef221a5fad6 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
 
-   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.
 
@@ -50,6 +48,8 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/loop/loop.h"
 
+#include "vm/jit/ir/bytecode.h"
+
 #include "vmcore/linker.h"
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
@@ -495,10 +495,10 @@ fetch_opcode:
                   mark the current bytecode instruction as basic-block
                   starting instruction. */
 
-               /* NOTE: Some compilers put a JAVA_NOP after a blockend
+               /* NOTE: Some compilers put a BC_nop after a blockend
                   instruction. */
 
-               if (blockend && (opcode != JAVA_NOP)) {
+               if (blockend && (opcode != BC_nop)) {
                        MARK_BASICBLOCK(&pd, bcindex);
                        blockend = false;
                }
@@ -523,13 +523,13 @@ fetch_opcode:
 
                /* compute next instruction start */
 
-               nextbc = bcindex + jcommandsize[opcode];
+               nextbc = bcindex + bytecode[opcode].length;
 
                CHECK_END_OF_BYTECODE(nextbc);
 
                /* add stack elements produced by this instruction */
 
-               s_count += stackreq[opcode];
+               s_count += bytecode[opcode].slots;
 
                /* We check here for the space of 1 instruction in the
                   instruction array.  If an opcode is converted to more than
@@ -541,55 +541,55 @@ fetch_opcode:
                /* translate this bytecode instruction */
                switch (opcode) {
 
-               case JAVA_NOP:
+               case BC_nop:
                        break;
 
                /* pushing constants onto the stack ***********************************/
 
-               case JAVA_BIPUSH:
+               case BC_bipush:
                        OP_LOADCONST_I(SUCK_BE_S1(m->jcode + bcindex + 1));
                        break;
 
-               case JAVA_SIPUSH:
+               case BC_sipush:
                        OP_LOADCONST_I(SUCK_BE_S2(m->jcode + bcindex + 1));
                        break;
 
-               case JAVA_LDC1:
+               case BC_ldc1:
                        i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        goto pushconstantitem;
 
-               case JAVA_LDC2:
-               case JAVA_LDC2W:
+               case BC_ldc2:
+               case BC_ldc2w:
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
 
                pushconstantitem:
 
 #if defined(ENABLE_VERIFIER)
-                       if (i >= m->class->cpcount) {
+                       if (i >= m->clazz->cpcount) {
                                exceptions_throw_verifyerror(m,
                                        "Attempt to access constant outside range");
                                return false;
                        }
 #endif
 
-                       switch (m->class->cptags[i]) {
+                       switch (m->clazz->cptags[i]) {
                        case CONSTANT_Integer:
-                               OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_I(((constant_integer *) (m->clazz->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Long:
-                               OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_L(((constant_long *) (m->clazz->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Float:
-                               OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_F(((constant_float *) (m->clazz->cpinfos[i]))->value);
                                break;
                        case CONSTANT_Double:
-                               OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
+                               OP_LOADCONST_D(((constant_double *) (m->clazz->cpinfos[i]))->value);
                                break;
                        case CONSTANT_String:
-                               OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
+                               OP_LOADCONST_STRING(literalstring_new((utf *) (m->clazz->cpinfos[i])));
                                break;
                        case CONSTANT_Class:
-                               cr = (constant_classref *) (m->class->cpinfos[i]);
+                               cr = (constant_classref *) (m->clazz->cpinfos[i]);
 
                                if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
                                        return false;
@@ -609,42 +609,43 @@ fetch_opcode:
                        }
                        break;
 
-               case JAVA_ACONST_NULL:
+               case BC_aconst_null:
                        OP_LOADCONST_NULL();
                        break;
 
-               case JAVA_ICONST_M1:
-               case JAVA_ICONST_0:
-               case JAVA_ICONST_1:
-               case JAVA_ICONST_2:
-               case JAVA_ICONST_3:
-               case JAVA_ICONST_4:
-               case JAVA_ICONST_5:
-                       OP_LOADCONST_I(opcode - JAVA_ICONST_0);
+               case BC_iconst_m1:
+               case BC_iconst_0:
+               case BC_iconst_1:
+               case BC_iconst_2:
+               case BC_iconst_3:
+               case BC_iconst_4:
+               case BC_iconst_5:
+                       OP_LOADCONST_I(opcode - BC_iconst_0);
                        break;
 
-               case JAVA_LCONST_0:
-               case JAVA_LCONST_1:
-                       OP_LOADCONST_L(opcode - JAVA_LCONST_0);
+               case BC_lconst_0:
+               case BC_lconst_1:
+                       OP_LOADCONST_L(opcode - BC_lconst_0);
                        break;
 
-               case JAVA_FCONST_0:
-               case JAVA_FCONST_1:
-               case JAVA_FCONST_2:
-                       OP_LOADCONST_F(opcode - JAVA_FCONST_0);
+               case BC_fconst_0:
+               case BC_fconst_1:
+               case BC_fconst_2:
+                       OP_LOADCONST_F(opcode - BC_fconst_0);
                        break;
 
-               case JAVA_DCONST_0:
-               case JAVA_DCONST_1:
-                       OP_LOADCONST_D(opcode - JAVA_DCONST_0);
+               case BC_dconst_0:
+               case BC_dconst_1:
+                       OP_LOADCONST_D(opcode - BC_dconst_0);
                        break;
 
                /* stack operations ***************************************************/
 
-               /* We need space for additional ICMDs so we can translate these       */
-               /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
+               /* We need space for additional instruction so we can
+                  translate these instructions to sequences of ICMD_COPY and
+                  ICMD_MOVE instructions. */
 
-               case JAVA_DUP_X1:
+               case BC_dup_x1:
                        INSTRUCTIONS_CHECK(4);
                        OP(opcode);
                        OP(ICMD_NOP);
@@ -652,7 +653,7 @@ fetch_opcode:
                        OP(ICMD_NOP);
                        break;
 
-               case JAVA_DUP_X2:
+               case BC_dup_x2:
                        INSTRUCTIONS_CHECK(6);
                        OP(opcode);
                        OP(ICMD_NOP);
@@ -662,13 +663,13 @@ fetch_opcode:
                        OP(ICMD_NOP);
                        break;
 
-               case JAVA_DUP2:
+               case BC_dup2:
                        INSTRUCTIONS_CHECK(2);
                        OP(opcode);
                        OP(ICMD_NOP);
                        break;
 
-               case JAVA_DUP2_X1:
+               case BC_dup2_x1:
                        INSTRUCTIONS_CHECK(7);
                        OP(opcode);
                        OP(ICMD_NOP);
@@ -679,7 +680,7 @@ fetch_opcode:
                        OP(ICMD_NOP);
                        break;
 
-               case JAVA_DUP2_X2:
+               case BC_dup2_x2:
                        INSTRUCTIONS_CHECK(9);
                        OP(opcode);
                        OP(ICMD_NOP);
@@ -692,7 +693,7 @@ fetch_opcode:
                        OP(ICMD_NOP);
                        break;
 
-               case JAVA_SWAP:
+               case BC_swap:
                        INSTRUCTIONS_CHECK(3);
                        OP(opcode);
                        OP(ICMD_NOP);
@@ -701,9 +702,9 @@ fetch_opcode:
 
                /* local variable access instructions *********************************/
 
-               case JAVA_ILOAD:
-               case JAVA_FLOAD:
-               case JAVA_ALOAD:
+               case BC_iload:
+               case BC_fload:
+               case BC_aload:
                        if (iswide == false) {
                                i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
@@ -712,11 +713,11 @@ fetch_opcode:
                                nextbc = bcindex + 3;
                                iswide = false;
                        }
-                       OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
+                       OP_LOAD_ONEWORD(opcode, i, opcode - BC_iload);
                        break;
 
-               case JAVA_LLOAD:
-               case JAVA_DLOAD:
+               case BC_lload:
+               case BC_dload:
                        if (iswide == false) {
                                i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
@@ -725,47 +726,47 @@ fetch_opcode:
                                nextbc = bcindex + 3;
                                iswide = false;
                        }
-                       OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
+                       OP_LOAD_TWOWORD(opcode, i, opcode - BC_iload);
                        break;
 
-               case JAVA_ILOAD_0:
-               case JAVA_ILOAD_1:
-               case JAVA_ILOAD_2:
-               case JAVA_ILOAD_3:
-                       OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
+               case BC_iload_0:
+               case BC_iload_1:
+               case BC_iload_2:
+               case BC_iload_3:
+                       OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - BC_iload_0, TYPE_INT);
                        break;
 
-               case JAVA_LLOAD_0:
-               case JAVA_LLOAD_1:
-               case JAVA_LLOAD_2:
-               case JAVA_LLOAD_3:
-                       OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
+               case BC_lload_0:
+               case BC_lload_1:
+               case BC_lload_2:
+               case BC_lload_3:
+                       OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - BC_lload_0, TYPE_LNG);
                        break;
 
-               case JAVA_FLOAD_0:
-               case JAVA_FLOAD_1:
-               case JAVA_FLOAD_2:
-               case JAVA_FLOAD_3:
-                       OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
+               case BC_fload_0:
+               case BC_fload_1:
+               case BC_fload_2:
+               case BC_fload_3:
+                       OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - BC_fload_0, TYPE_FLT);
                        break;
 
-               case JAVA_DLOAD_0:
-               case JAVA_DLOAD_1:
-               case JAVA_DLOAD_2:
-               case JAVA_DLOAD_3:
-                       OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
+               case BC_dload_0:
+               case BC_dload_1:
+               case BC_dload_2:
+               case BC_dload_3:
+                       OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - BC_dload_0, TYPE_DBL);
                        break;
 
-               case JAVA_ALOAD_0:
-               case JAVA_ALOAD_1:
-               case JAVA_ALOAD_2:
-               case JAVA_ALOAD_3:
-                       OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
+               case BC_aload_0:
+               case BC_aload_1:
+               case BC_aload_2:
+               case BC_aload_3:
+                       OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - BC_aload_0, TYPE_ADR);
                        break;
 
-               case JAVA_ISTORE:
-               case JAVA_FSTORE:
-               case JAVA_ASTORE:
+               case BC_istore:
+               case BC_fstore:
+               case BC_astore:
                        if (iswide == false) {
                                i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
@@ -774,11 +775,11 @@ fetch_opcode:
                                nextbc = bcindex + 3;
                                iswide = false;
                        }
-                       OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
+                       OP_STORE_ONEWORD(opcode, i, opcode - BC_istore);
                        break;
 
-               case JAVA_LSTORE:
-               case JAVA_DSTORE:
+               case BC_lstore:
+               case BC_dstore:
                        if (iswide == false) {
                                i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
@@ -787,52 +788,51 @@ fetch_opcode:
                                nextbc = bcindex + 3;
                                iswide = false;
                        }
-                       OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
+                       OP_STORE_TWOWORD(opcode, i, opcode - BC_istore);
                        break;
 
-               case JAVA_ISTORE_0:
-               case JAVA_ISTORE_1:
-               case JAVA_ISTORE_2:
-               case JAVA_ISTORE_3:
-                       OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
+               case BC_istore_0:
+               case BC_istore_1:
+               case BC_istore_2:
+               case BC_istore_3:
+                       OP_STORE_ONEWORD(ICMD_ISTORE, opcode - BC_istore_0, TYPE_INT);
                        break;
 
-               case JAVA_LSTORE_0:
-               case JAVA_LSTORE_1:
-               case JAVA_LSTORE_2:
-               case JAVA_LSTORE_3:
-                       OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
+               case BC_lstore_0:
+               case BC_lstore_1:
+               case BC_lstore_2:
+               case BC_lstore_3:
+                       OP_STORE_TWOWORD(ICMD_LSTORE, opcode - BC_lstore_0, TYPE_LNG);
                        break;
 
-               case JAVA_FSTORE_0:
-               case JAVA_FSTORE_1:
-               case JAVA_FSTORE_2:
-               case JAVA_FSTORE_3:
-                       OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
+               case BC_fstore_0:
+               case BC_fstore_1:
+               case BC_fstore_2:
+               case BC_fstore_3:
+                       OP_STORE_ONEWORD(ICMD_FSTORE, opcode - BC_fstore_0, TYPE_FLT);
                        break;
 
-               case JAVA_DSTORE_0:
-               case JAVA_DSTORE_1:
-               case JAVA_DSTORE_2:
-               case JAVA_DSTORE_3:
-                       OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
+               case BC_dstore_0:
+               case BC_dstore_1:
+               case BC_dstore_2:
+               case BC_dstore_3:
+                       OP_STORE_TWOWORD(ICMD_DSTORE, opcode - BC_dstore_0, TYPE_DBL);
                        break;
 
-               case JAVA_ASTORE_0:
-               case JAVA_ASTORE_1:
-               case JAVA_ASTORE_2:
-               case JAVA_ASTORE_3:
-                       OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
+               case BC_astore_0:
+               case BC_astore_1:
+               case BC_astore_2:
+               case BC_astore_3:
+                       OP_STORE_ONEWORD(ICMD_ASTORE, opcode - BC_astore_0, TYPE_ADR);
                        break;
 
-               case JAVA_IINC:
+               case BC_iinc:
                        {
                                int v;
 
                                if (iswide == false) {
                                        i = SUCK_BE_U1(m->jcode + bcindex + 1);
                                        v = SUCK_BE_S1(m->jcode + bcindex + 2);
-
                                }
                                else {
                                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
@@ -848,14 +848,14 @@ fetch_opcode:
 
                /* wider index for loading, storing and incrementing ******************/
 
-               case JAVA_WIDE:
+               case BC_wide:
                        bcindex++;
                        iswide = true;
                        goto fetch_opcode;
 
                /* managing arrays ****************************************************/
 
-               case JAVA_NEWARRAY:
+               case BC_newarray:
                        switch (SUCK_BE_S1(m->jcode + bcindex + 1)) {
                        case 4:
                                bte = builtintable_get_internal(BUILTIN_newarray_boolean);
@@ -890,9 +890,9 @@ fetch_opcode:
                        OP_BUILTIN_CHECK_EXCEPTION(bte);
                        break;
 
-               case JAVA_ANEWARRAY:
+               case BC_anewarray:
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
+                       compr = (constant_classref *) class_getconstant(m->clazz, i, CONSTANT_Class);
                        if (compr == NULL)
                                return false;
 
@@ -909,11 +909,11 @@ fetch_opcode:
                        s_count++;
                        break;
 
-               case JAVA_MULTIANEWARRAY:
+               case BC_multianewarray:
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
                        j = SUCK_BE_U1(m->jcode + bcindex + 3);
   
-                       cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
+                       cr = (constant_classref *) class_getconstant(m->clazz, i, CONSTANT_Class);
                        if (cr == NULL)
                                return false;
   
@@ -929,23 +929,23 @@ fetch_opcode:
 
                /* control flow instructions ******************************************/
 
-               case JAVA_IFEQ:
-               case JAVA_IFLT:
-               case JAVA_IFLE:
-               case JAVA_IFNE:
-               case JAVA_IFGT:
-               case JAVA_IFGE:
-               case JAVA_IFNULL:
-               case JAVA_IFNONNULL:
-               case JAVA_IF_ICMPEQ:
-               case JAVA_IF_ICMPNE:
-               case JAVA_IF_ICMPLT:
-               case JAVA_IF_ICMPGT:
-               case JAVA_IF_ICMPLE:
-               case JAVA_IF_ICMPGE:
-               case JAVA_IF_ACMPEQ:
-               case JAVA_IF_ACMPNE:
-               case JAVA_GOTO:
+               case BC_ifeq:
+               case BC_iflt:
+               case BC_ifle:
+               case BC_ifne:
+               case BC_ifgt:
+               case BC_ifge:
+               case BC_ifnull:
+               case BC_ifnonnull:
+               case BC_if_icmpeq:
+               case BC_if_icmpne:
+               case BC_if_icmplt:
+               case BC_if_icmpgt:
+               case BC_if_icmple:
+               case BC_if_icmpge:
+               case BC_if_acmpeq:
+               case BC_if_acmpne:
+               case BC_goto:
                        i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
                        CHECK_BYTECODE_INDEX(i);
                        MARK_BASICBLOCK(&pd, i);
@@ -953,7 +953,7 @@ fetch_opcode:
                        OP_INSINDEX(opcode, i);
                        break;
 
-               case JAVA_GOTO_W:
+               case BC_goto_w:
                        i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
                        CHECK_BYTECODE_INDEX(i);
                        MARK_BASICBLOCK(&pd, i);
@@ -961,22 +961,22 @@ fetch_opcode:
                        OP_INSINDEX(ICMD_GOTO, i);
                        break;
 
-               case JAVA_JSR:
+               case BC_jsr:
                        i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
 jsr_tail:
                        CHECK_BYTECODE_INDEX(i);
                        MARK_BASICBLOCK(&pd, i);
                        blockend = true;
-                       OP_PREPARE_ZEROFLAGS(JAVA_JSR);
+                       OP_PREPARE_ZEROFLAGS(BC_jsr);
                        iptr->sx.s23.s3.jsrtarget.insindex = i;
                        PINC;
                        break;
 
-               case JAVA_JSR_W:
+               case BC_jsr_w:
                        i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
                        goto jsr_tail;
 
-               case JAVA_RET:
+               case BC_ret:
                        if (iswide == false) {
                                i = SUCK_BE_U1(m->jcode + bcindex + 1);
                        }
@@ -990,18 +990,18 @@ jsr_tail:
                        OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
                        break;
 
-               case JAVA_IRETURN:
-               case JAVA_LRETURN:
-               case JAVA_FRETURN:
-               case JAVA_DRETURN:
-               case JAVA_ARETURN:
-               case JAVA_RETURN:
+               case BC_ireturn:
+               case BC_lreturn:
+               case BC_freturn:
+               case BC_dreturn:
+               case BC_areturn:
+               case BC_return:
                        blockend = true;
                        /* XXX ARETURN will need a flag in the typechecker */
                        OP(opcode);
                        break;
 
-               case JAVA_ATHROW:
+               case BC_athrow:
                        blockend = true;
                        /* XXX ATHROW will need a flag in the typechecker */
                        OP(opcode);
@@ -1010,7 +1010,7 @@ jsr_tail:
 
                /* table jumps ********************************************************/
 
-               case JAVA_LOOKUPSWITCH:
+               case BC_lookupswitch:
                        {
                                s4 num, j;
                                lookup_target_t *lookup;
@@ -1078,8 +1078,7 @@ jsr_tail:
                                break;
                        }
 
-
-               case JAVA_TABLESWITCH:
+               case BC_tableswitch:
                        {
                                s4 num, j;
                                s4 deftarget;
@@ -1148,17 +1147,17 @@ jsr_tail:
 
                /* load and store of object fields ************************************/
 
-               case JAVA_AASTORE:
+               case BC_aastore:
                        OP(opcode);
                        code_unflag_leafmethod(code);
                        break;
 
-               case JAVA_GETSTATIC:
-               case JAVA_PUTSTATIC:
-               case JAVA_GETFIELD:
-               case JAVA_PUTFIELD:
+               case BC_getstatic:
+               case BC_putstatic:
+               case BC_getfield:
+               case BC_putfield:
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       fmi = class_getconstant(m->class, i, CONSTANT_Fieldref);
+                       fmi = class_getconstant(m->clazz, i, CONSTANT_Fieldref);
 
                        if (fmi == NULL)
                                return false;
@@ -1177,7 +1176,7 @@ jsr_tail:
                                        return false;
 
                                if (result != resolveSucceeded) {
-                                       uf = resolve_create_unresolved_field(m->class, m, iptr);
+                                       uf = resolve_create_unresolved_field(m->clazz, m, iptr);
 
                                        if (uf == NULL)
                                                return false;
@@ -1196,11 +1195,11 @@ jsr_tail:
 
                /* method invocation **************************************************/
 
-               case JAVA_INVOKESTATIC:
+               case BC_invokestatic:
                        OP_PREPARE_ZEROFLAGS(opcode);
 
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
+                       fmi = class_getconstant(m->clazz, i, CONSTANT_Methodref);
 
                        if (fmi == NULL)
                                return false;
@@ -1213,27 +1212,27 @@ jsr_tail:
 
                        goto invoke_method;
 
-               case JAVA_INVOKESPECIAL:
+               case BC_invokespecial:
                        OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
 
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
+                       fmi = class_getconstant(m->clazz, i, CONSTANT_Methodref);
 
                        goto invoke_nonstatic_method;
 
-               case JAVA_INVOKEINTERFACE:
+               case BC_invokeinterface:
                        OP_PREPARE_ZEROFLAGS(opcode);
 
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       fmi = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
+                       fmi = class_getconstant(m->clazz, i, CONSTANT_InterfaceMethodref);
 
                        goto invoke_nonstatic_method;
 
-               case JAVA_INVOKEVIRTUAL:
+               case BC_invokevirtual:
                        OP_PREPARE_ZEROFLAGS(opcode);
 
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
+                       fmi = class_getconstant(m->clazz, i, CONSTANT_Methodref);
 
 invoke_nonstatic_method:
                        if (fmi == NULL)
@@ -1256,7 +1255,7 @@ invoke_method:
                        if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
 #endif
                                result = resolve_method_lazy(m, fmi, 
-                                                                                        (opcode == JAVA_INVOKESPECIAL));
+                                                                                        (opcode == BC_invokespecial));
 
                                if (result == resolveFailed)
                                        return false;
@@ -1277,9 +1276,9 @@ invoke_method:
                                        }
                                }
                                else {
-                                       um = resolve_create_unresolved_method(m->class, m, fmi,
-                                                       (opcode == JAVA_INVOKESTATIC),
-                                                       (opcode == JAVA_INVOKESPECIAL));
+                                       um = resolve_create_unresolved_method(m->clazz, m, fmi,
+                                                       (opcode == BC_invokestatic),
+                                                       (opcode == BC_invokespecial));
 
                                        if (um == NULL)
                                                return false;
@@ -1297,9 +1296,9 @@ invoke_method:
 
                /* instructions taking class arguments ********************************/
 
-               case JAVA_NEW:
+               case BC_new:
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       cr = class_getconstant(m->class, i, CONSTANT_Class);
+                       cr = class_getconstant(m->clazz, i, CONSTANT_Class);
 
                        if (cr == NULL)
                                return false;
@@ -1314,9 +1313,9 @@ invoke_method:
                        s_count++;
                        break;
 
-               case JAVA_CHECKCAST:
+               case BC_checkcast:
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       cr = class_getconstant(m->class, i, CONSTANT_Class);
+                       cr = class_getconstant(m->clazz, i, CONSTANT_Class);
 
                        if (cr == NULL)
                                return false;
@@ -1336,9 +1335,9 @@ invoke_method:
                        OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
                        break;
 
-               case JAVA_INSTANCEOF:
+               case BC_instanceof:
                        i = SUCK_BE_U2(m->jcode + bcindex + 1);
-                       cr = class_getconstant(m->class, i, CONSTANT_Class);
+                       cr = class_getconstant(m->clazz, i, CONSTANT_Class);
 
                        if (cr == NULL)
                                return false;
@@ -1362,7 +1361,7 @@ invoke_method:
 
                /* synchronization instructions ***************************************/
 
-               case JAVA_MONITORENTER:
+               case BC_monitorenter:
 #if defined(ENABLE_THREADS)
                        if (checksync) {
                                bte = builtintable_get_internal(LOCK_monitor_enter);
@@ -1376,7 +1375,7 @@ invoke_method:
                        }
                        break;
 
-               case JAVA_MONITOREXIT:
+               case BC_monitorexit:
 #if defined(ENABLE_THREADS)
                        if (checksync) {
                                bte = builtintable_get_internal(LOCK_monitor_exit);
@@ -1392,7 +1391,7 @@ invoke_method:
 
                /* arithmetic instructions that may become builtin functions **********/
 
-               case JAVA_IDIV:
+               case BC_idiv:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_idiv);
                        OP_BUILTIN_ARITHMETIC(opcode, bte);
@@ -1405,7 +1404,7 @@ invoke_method:
 #endif
                        break;
 
-               case JAVA_IREM:
+               case BC_irem:
 #if !SUPPORT_DIVISION
                        bte = builtintable_get_internal(BUILTIN_irem);
                        OP_BUILTIN_ARITHMETIC(opcode, bte);
@@ -1418,7 +1417,7 @@ invoke_method:
 #endif
                        break;
 
-               case JAVA_LDIV:
+               case BC_ldiv:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_ldiv);
                        OP_BUILTIN_ARITHMETIC(opcode, bte);
@@ -1431,7 +1430,7 @@ invoke_method:
 #endif
                        break;
 
-               case JAVA_LREM:
+               case BC_lrem:
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
                        bte = builtintable_get_internal(BUILTIN_lrem);
                        OP_BUILTIN_ARITHMETIC(opcode, bte);
@@ -1444,7 +1443,7 @@ invoke_method:
 #endif
                        break;
 
-               case JAVA_FREM:
+               case BC_frem:
 #if defined(__I386__)
                        OP(opcode);
 #else
@@ -1453,7 +1452,7 @@ invoke_method:
 #endif
                        break;
 
-               case JAVA_DREM:
+               case BC_drem:
 #if defined(__I386__)
                        OP(opcode);
 #else
@@ -1462,7 +1461,7 @@ invoke_method:
 #endif
                        break;
 
-               case JAVA_F2I:
+               case BC_f2i:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_f2i);
@@ -1475,7 +1474,7 @@ invoke_method:
                        }
                        break;
 
-               case JAVA_F2L:
+               case BC_f2l:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_f2l);
@@ -1488,7 +1487,7 @@ invoke_method:
                        }
                        break;
 
-               case JAVA_D2I:
+               case BC_d2i:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_d2i);
@@ -1501,7 +1500,7 @@ invoke_method:
                        }
                        break;
 
-               case JAVA_D2L:
+               case BC_d2l:
 #if defined(__ALPHA__)
                        if (!opt_noieee) {
                                bte = builtintable_get_internal(BUILTIN_d2l);
@@ -1514,15 +1513,19 @@ invoke_method:
                        }
                        break;
 
+
                /* invalid opcodes ****************************************************/
 
                        /* check for invalid opcodes if the verifier is enabled */
 #if defined(ENABLE_VERIFIER)
-               case JAVA_BREAKPOINT:
+               case BC_breakpoint:
                        exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
                        return false;
 
-               case 186: /* unused opcode */
+
+               /* Unused opcodes ************************************************** */
+
+               case 186:
                case 203:
                case 204:
                case 205:
@@ -1585,7 +1588,7 @@ invoke_method:
                /* opcodes that don't require translation *****************************/
 
                default:
-                       /* straight-forward translation to ICMD */
+                       /* Straight-forward translation to HIR. */
                        OP(opcode);
                        break;
 
@@ -1741,23 +1744,23 @@ invoke_method:
                /* resolve instruction indices to basic blocks */
 
                switch (iptr->opc) {
-               case JAVA_IFEQ:
-               case JAVA_IFLT:
-               case JAVA_IFLE:
-               case JAVA_IFNE:
-               case JAVA_IFGT:
-               case JAVA_IFGE:
-               case JAVA_IFNULL:
-               case JAVA_IFNONNULL:
-               case JAVA_IF_ICMPEQ:
-               case JAVA_IF_ICMPNE:
-               case JAVA_IF_ICMPLT:
-               case JAVA_IF_ICMPGT:
-               case JAVA_IF_ICMPLE:
-               case JAVA_IF_ICMPGE:
-               case JAVA_IF_ACMPEQ:
-               case JAVA_IF_ACMPNE:
-               case JAVA_GOTO:
+               case ICMD_IFEQ:
+               case ICMD_IFLT:
+               case ICMD_IFLE:
+               case ICMD_IFNE:
+               case ICMD_IFGT:
+               case ICMD_IFGE:
+               case ICMD_IFNULL:
+               case ICMD_IFNONNULL:
+               case ICMD_IF_ICMPEQ:
+               case ICMD_IF_ICMPNE:
+               case ICMD_IF_ICMPLT:
+               case ICMD_IF_ICMPGT:
+               case ICMD_IF_ICMPLE:
+               case ICMD_IF_ICMPGE:
+               case ICMD_IF_ACMPEQ:
+               case ICMD_IF_ACMPNE:
+               case ICMD_GOTO:
                        BYTECODEINDEX_TO_BASICBLOCK(iptr->dst);
                        break;
 
@@ -1819,7 +1822,10 @@ invoke_method:
        {
                s4 nlocals = 0;
                s4 i;
+               s4 t;
+               s4 varindex;
                s4 *mapptr;
+               s4 *reversemap;
 
                mapptr = local_map;
 
@@ -1866,10 +1872,20 @@ invoke_method:
                MZERO(jd->var, varinfo, jd->varcount);
 
                /* set types of all locals in jd->var */
+               /* and fill the reverselocalmap       */
+
+               reversemap = DMNEW(s4, nlocals);
+
+               for (i = 0; i < m->maxlocals; i++)
+                       for (t=0; t<5; t++) {
+                               varindex = local_map[5*i + t];
+                               if (varindex != UNUSED) {
+                                       VAR(varindex)->type = t;
+                                       reversemap[varindex] = i;
+                               }
+                       }
 
-               for (mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
-                       if (*mapptr != UNUSED)
-                               VAR(*mapptr)->type = i%5;
+               jd->reverselocalmap = reversemap;
        }
 
        /* assign local variables to method variables */
@@ -1881,7 +1897,7 @@ invoke_method:
 
        /* allocate stack table */
 
-       jd->stack = DMNEW(stackelement, jd->stackcount);
+       jd->stack = DMNEW(stackelement_t, jd->stackcount);
 
        /* everything's ok */
 
index 6a37ef6ec0b9e9241b87f3661b70ad1c8f392702..b3fbe3042570bdce3ca4e330c5c29420e9cf20b9 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/patcher-common.c - 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.
 
@@ -48,6 +46,7 @@
 #include "vm/vm.h"                     /* for vm_abort */
 
 #include "vm/jit/code.h"
+#include "vm/jit/disass.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/patcher-common.h"
 
@@ -151,7 +150,8 @@ static patchref_t *patcher_list_find(codeinfo *code, u1 *pc)
 
        /* walk through all patcher references for the given codeinfo */
 
-       pr = list_first_unsynced(code->patchers);
+       pr = list_first(code->patchers);
+
        while (pr) {
 
 /*#define TRACE_PATCHER_FIND*/
@@ -162,7 +162,7 @@ static patchref_t *patcher_list_find(codeinfo *code, u1 *pc)
                if (pr->mpc == (ptrint) pc)
                        return pr;
 
-               pr = list_next_unsynced(code->patchers, pr);
+               pr = list_next(code->patchers, pr);
        }
 
        return NULL;
@@ -195,7 +195,7 @@ void patcher_add_patch_ref(jitdata *jd, functionptr patcher, voidptr ref,
        /* allocate patchref on heap (at least freed together with codeinfo) */
 
        pr = NEW(patchref_t);
-       list_add_first_unsynced(code->patchers, pr);
+       list_add_first(code->patchers, pr);
 
 #if defined(ENABLE_STATISTICS)
        if (opt_stat)
@@ -233,6 +233,27 @@ void patcher_add_patch_ref(jitdata *jd, functionptr patcher, voidptr ref,
 }
 
 
+/**
+ * Resolve all patchers in the current JIT run.
+ *
+ * @param jd JIT data-structure
+ */
+void patcher_resolve(jitdata* jd)
+{
+       codeinfo*   code;
+       patchref_t* pr;
+
+       /* Get required compiler data. */
+
+       code = jd->code;
+
+       for (pr = list_first(code->patchers); pr != NULL; pr = list_next(code->patchers, pr)) {
+               pr->mpc   += (intptr_t) code->entrypoint;
+               pr->datap  = (intptr_t) (pr->disp + code->entrypoint);
+       }
+}
+
+
 /* patcher_handler *************************************************************
 
    Handles the request to patch JIT code at the given patching
@@ -301,8 +322,17 @@ java_handle_t *patcher_handler(u1 *pc)
                                break;
 
                TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
-               TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) pr->patcher);
-               TRACE_PATCHER_INDENT; printf("\tmcodes before = "); for (i=0; i<5; i++) printf("0x%08x ", *((u4 *) pr->mpc + i)); printf("\n");
+               TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
+
+               TRACE_PATCHER_INDENT;
+               printf("\tmachine code before = ");
+
+# if defined(ENABLE_DISASSEMBLER)
+               disassinstr((void *) pr->mpc);
+# else
+               printf("disassembler disabled\n");
+# endif
+
                patcher_depth++;
                assert(patcher_depth > 0);
        }
@@ -320,7 +350,16 @@ java_handle_t *patcher_handler(u1 *pc)
        if (opt_DebugPatcher) {
                assert(patcher_depth > 0);
                patcher_depth--;
-               TRACE_PATCHER_INDENT; printf("\tmcodes after  = "); for (i=0; i<5; i++) printf("0x%08x ", *((u4 *) pr->mpc + i)); printf("\n");
+
+               TRACE_PATCHER_INDENT;
+               printf("\tmachine code after  = ");
+
+# if defined(ENABLE_DISASSEMBLER)
+               disassinstr((void *) pr->mpc);
+# else
+               printf("disassembler disabled\n");
+# endif
+
                if (result == false) {
                        TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
                }
index 6ee0aec65f1b3667f4caf9a6aa4e8d62c5d48c65..a103447976fe3f2bbc01f32f26343b180755e116 100644 (file)
@@ -71,6 +71,8 @@ void patcher_list_free(codeinfo *code);
 void patcher_add_patch_ref(jitdata *jd, functionptr patcher, voidptr ref,
                            s4 disp);
 
+void patcher_resolve(jitdata* jd);
+
 java_handle_t *patcher_handler(u1 *pc);
 
 
index 0ff53a68d00daa192d50791be0a5297c0bfce54b..d8e59bfa4957cc271a752439dc3524ccbcbc22a1 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/powerpc/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.
 ##
@@ -53,8 +51,11 @@ libarch_la_SOURCES = \
        codegen.h \
        $(DISASS_SOURCES) \
        emit.c \
+       patcher.c \
+       \
+       md-trap.h \
        md.c \
-       patcher.c
+       md.h
 
 libarch_la_LIBADD = \
        $(OS_DIR)/libmd.la
index f2c88abb2641e558ccb747aca03eb49b5e19b016..378a7279e180dbdd2ebf1dcc2dcb4894680a22dc 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/codegen.c - machine code generator for 32-bit PowerPC
 
-   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.
 
@@ -65,6 +63,7 @@
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
@@ -87,7 +86,6 @@ bool codegen_emit(jitdata *jd)
        codegendata        *cd;
        registerdata       *rd;
        s4                  len, s1, s2, s3, d, disp;
-       ptrint              a;
        varinfo            *var;
        basicblock         *bptr;
        instruction        *iptr;
@@ -99,7 +97,8 @@ bool codegen_emit(jitdata *jd)
        fieldinfo          *fi;
        unresolved_field   *uf;
        s4                  fieldtype;
-       s4                 varindex;
+       s4                  varindex;
+       int                 i;
 
        /* get required compiler data */
 
@@ -307,13 +306,13 @@ bool codegen_emit(jitdata *jd)
                /* get or test the lock object */
 
                if (m->flags & ACC_STATIC) {
-                       disp = dseg_add_address(cd, &m->class->object.header);
+                       disp = dseg_add_address(cd, &m->clazz->object.header);
                        M_ALD(REG_A0, REG_PV, disp);
                }
                else {
                        M_TST(REG_A0);
                        M_BNE(1);
-                       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
                }
 
                M_AST(REG_A0, REG_SP, s1 * 8);
@@ -478,16 +477,16 @@ bool codegen_emit(jitdata *jd)
                case ICMD_FCONST:     /* ...  ==> ..., constant                       */
 
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       a = dseg_add_float(cd, iptr->sx.val.f);
-                       M_FLD(d, REG_PV, a);
+                       disp = dseg_add_float(cd, iptr->sx.val.f);
+                       M_FLD(d, REG_PV, disp);
                        emit_store_dst(jd, iptr, d);
                        break;
                        
                case ICMD_DCONST:     /* ...  ==> ..., constant                       */
 
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       a = dseg_add_double(cd, iptr->sx.val.d);
-                       M_DLD(d, REG_PV, a);
+                       disp = dseg_add_double(cd, iptr->sx.val.d);
+                       M_DLD(d, REG_PV, disp);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -772,7 +771,7 @@ bool codegen_emit(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
 
                        /* XXX TODO: only do this if arithmetic check is really done! */
-                       M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
+                       M_IOR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
                        /* XXX could be optimized */
                        emit_arithmetic_check(cd, iptr, REG_ITMP3);
 
@@ -828,7 +827,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_AND_IMM(s2, 0x1f, REG_ITMP3);
+                       M_IAND_IMM(s2, 0x1f, REG_ITMP3);
                        M_SLL(s1, REG_ITMP3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -847,7 +846,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_AND_IMM(s2, 0x1f, REG_ITMP3);
+                       M_IAND_IMM(s2, 0x1f, REG_ITMP3);
                        M_SRA(s1, REG_ITMP3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -866,7 +865,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_AND_IMM(s2, 0x1f, REG_ITMP2);
+                       M_IAND_IMM(s2, 0x1f, REG_ITMP2);
                        M_SRL(s1, REG_ITMP2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -889,7 +888,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_AND(s1, s2, d);
+                       M_IAND(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -899,7 +898,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
-                               M_AND_IMM(s1, iptr->sx.val.i, d);
+                               M_IAND_IMM(s1, iptr->sx.val.i, d);
                        /*
                        else if (iptr->sx.val.i == 0xffffff) {
                                M_RLWINM(s1, 0, 8, 31, d);
@@ -907,7 +906,7 @@ bool codegen_emit(jitdata *jd)
                        */
                        else {
                                ICONST(REG_ITMP3, iptr->sx.val.i);
-                               M_AND(s1, REG_ITMP3, d);
+                               M_IAND(s1, REG_ITMP3, d);
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -917,10 +916,10 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
-                       M_AND(s1, s2, GET_LOW_REG(d));
+                       M_IAND(s1, s2, GET_LOW_REG(d));
                        s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
-                       M_AND(s1, s2, GET_HIGH_REG(d));
+                       M_IAND(s1, s2, GET_HIGH_REG(d));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -931,18 +930,18 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
                        if ((s3 >= 0) && (s3 <= 65535))
-                               M_AND_IMM(s1, s3, GET_LOW_REG(d));
+                               M_IAND_IMM(s1, s3, GET_LOW_REG(d));
                        else {
                                ICONST(REG_ITMP3, s3);
-                               M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
+                               M_IAND(s1, REG_ITMP3, GET_LOW_REG(d));
                        }
                        s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
                        s3 = iptr->sx.val.l >> 32;
                        if ((s3 >= 0) && (s3 <= 65535))
-                               M_AND_IMM(s1, s3, GET_HIGH_REG(d));
+                               M_IAND_IMM(s1, s3, GET_HIGH_REG(d));
                        else {
                                ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
-                               M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
+                               M_IAND(s1, REG_ITMP3, GET_HIGH_REG(d));
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -957,7 +956,7 @@ bool codegen_emit(jitdata *jd)
                        M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
                        if (iptr->sx.val.i >= 32768) {
                                M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
-                               M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
+                               M_IOR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
                                M_IADD(s1, REG_ITMP2, REG_ITMP2);
                        }
                        else {
@@ -978,7 +977,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_OR(s1, s2, d);
+                       M_IOR(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -988,10 +987,10 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
-                               M_OR_IMM(s1, iptr->sx.val.i, d);
+                               M_IOR_IMM(s1, iptr->sx.val.i, d);
                        else {
                                ICONST(REG_ITMP3, iptr->sx.val.i);
-                               M_OR(s1, REG_ITMP3, d);
+                               M_IOR(s1, REG_ITMP3, d);
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1001,10 +1000,10 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
-                       M_OR(s1, s2, GET_LOW_REG(d));
+                       M_IOR(s1, s2, GET_LOW_REG(d));
                        s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
-                       M_OR(s1, s2, GET_HIGH_REG(d));
+                       M_IOR(s1, s2, GET_HIGH_REG(d));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1015,18 +1014,18 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
                        if ((s3 >= 0) && (s3 <= 65535))
-                               M_OR_IMM(s1, s3, GET_LOW_REG(d));
+                               M_IOR_IMM(s1, s3, GET_LOW_REG(d));
                        else {
                                ICONST(REG_ITMP3, s3);
-                               M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
+                               M_IOR(s1, REG_ITMP3, GET_LOW_REG(d));
                        }
                        s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
                        s3 = iptr->sx.val.l >> 32;
                        if ((s3 >= 0) && (s3 <= 65535))
-                               M_OR_IMM(s1, s3, GET_HIGH_REG(d));
+                               M_IOR_IMM(s1, s3, GET_HIGH_REG(d));
                        else {
                                ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
-                               M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
+                               M_IOR(s1, REG_ITMP3, GET_HIGH_REG(d));
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1500,9 +1499,9 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                                               fi->class, disp);
+                                                                               fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -1546,9 +1545,9 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                                               fi->class, disp);
+                                                                               fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -1752,19 +1751,19 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
                        if (iptr->sx.val.l == 0) {
-                               M_OR_TST(s1, s2, REG_ITMP3);
+                               M_IOR_TST(s1, s2, REG_ITMP3);
                        }
                        else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
                                M_XOR_IMM(s2, 0, REG_ITMP2);
                                M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+                               M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
                        }
                        else {
                                ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
                                M_XOR(s1, REG_ITMP3, REG_ITMP1);
                                ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
                                M_XOR(s2, REG_ITMP3, REG_ITMP2);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+                               M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
                        }
                        emit_beq(cd, iptr->dst.block);
                        break;
@@ -1803,7 +1802,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
 /*                     if (iptr->sx.val.l == 0) { */
-/*                             M_OR(s1, s2, REG_ITMP3); */
+/*                             M_IOR(s1, s2, REG_ITMP3); */
 /*                             M_CMPI(REG_ITMP3, 0); */
 
 /*                     } else  */
@@ -1830,19 +1829,19 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
                        if (iptr->sx.val.l == 0) {
-                               M_OR_TST(s1, s2, REG_ITMP3);
+                               M_IOR_TST(s1, s2, REG_ITMP3);
                        }
                        else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
                                M_XOR_IMM(s2, 0, REG_ITMP2);
                                M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+                               M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
                        }
                        else {
                                ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
                                M_XOR(s1, REG_ITMP3, REG_ITMP1);
                                ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
                                M_XOR(s2, REG_ITMP3, REG_ITMP2);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+                               M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
                        }
                        emit_bne(cd, iptr->dst.block);
                        break;
@@ -1852,7 +1851,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
 /*                     if (iptr->sx.val.l == 0) { */
-/*                             M_OR(s1, s2, REG_ITMP3); */
+/*                             M_IOR(s1, s2, REG_ITMP3); */
 /*                             M_CMPI(REG_ITMP3, 0); */
 
 /*                     } else  */
@@ -2237,50 +2236,58 @@ nowperformreturn:
                        }
 
 gen_method:
-                       s3 = md->paramcount;
+                       i = md->paramcount;
 
-                       MCODECHECK((s3 << 1) + 64);
+                       MCODECHECK((i << 1) + 64);
 
-                       /* copy arguments to registers or stack location */
+                       /* Copy arguments to registers or stack location. */
 
-                       for (s3 = s3 - 1; s3 >= 0; s3--) {
-                               var = VAR(iptr->sx.s23.s2.args[s3]);
-                               d   = md->params[s3].regoff;
+                       for (i = i - 1; i >= 0; i--) {
+                               var = VAR(iptr->sx.s23.s2.args[i]);
+                               d   = md->params[i].regoff;
+
+                               /* Already pre-allocated? */
 
-                               /* Already Preallocated? */
                                if (var->flags & PREALLOC)
                                        continue;
 
-                               if (IS_INT_LNG_TYPE(var->type)) {
-                                       if (!md->params[s3].inmemory) {
-                                               if (IS_2_WORD_TYPE(var->type)) {
-                                                       s1 = emit_load(jd, iptr, var, d);
-                                                       M_LNGMOVE(s1, d);
-                                               }
-                                               else {
-                                                       s1 = emit_load(jd, iptr, var, d);
-                                                       M_INTMOVE(s1, d);
-                                               }
-                                       }
-                                       else {
-                                               if (IS_2_WORD_TYPE(var->type)) {
-                                                       s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
-                                                       M_LST(s1, REG_SP, d);
-                                               }
-                                               else {
-                                                       s1 = emit_load(jd, iptr, var, REG_ITMP1);
-                                                       M_IST(s1, REG_SP, d);
-                                               }
+                               if (!md->params[i].inmemory) {
+                                       s1 = emit_load(jd, iptr, var, d);
+
+                                       switch (var->type) {
+                                       case TYPE_INT:
+                                       case TYPE_ADR:
+                                               M_INTMOVE(s1, d);
+                                               break;
+
+                                       case TYPE_LNG:
+                                               M_LNGMOVE(s1, d);
+                                               break;
+
+                                       case TYPE_FLT:
+                                       case TYPE_DBL:
+                                               M_FLTMOVE(s1, d);
+                                               break;
                                        }
                                }
                                else {
-                                       if (!md->params[s3].inmemory) {
-                                               s1 = emit_load(jd, iptr, var, d);
-                                               M_FLTMOVE(s1, d);
-                                       }
-                                       else {
+                                       switch (var->type) {
+                                       case TYPE_INT:
+                                       case TYPE_ADR:
+                                               s1 = emit_load(jd, iptr, var, REG_ITMP1);
+                                               M_IST(s1, REG_SP, d);
+                                               break;
+
+                                       case TYPE_LNG:
+                                               s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
+                                               M_LST(s1, REG_SP, d);
+                                               break;
+
+                                       case TYPE_FLT:
+                                       case TYPE_DBL:
                                                s1 = emit_load(jd, iptr, var, REG_FTMP1);
                                                M_DST(s1, REG_SP, d);
+                                               break;
                                        }
                                }
                        }
@@ -2365,9 +2372,9 @@ gen_method:
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
+                                               sizeof(methodptr*) * lm->clazz->index;
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
 
                                /* implicit null-pointer check */
@@ -2386,26 +2393,31 @@ gen_method:
                                break;
                        }
 
-                       /* store return value */
+                       /* Store return value. */
 
-                       d = md->returntype.type;
+                       switch (md->returntype.type) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
+                               M_INTMOVE(REG_RESULT, s1);
+                               emit_store_dst(jd, iptr, s1);
+                               break;
 
-                       if (d != TYPE_VOID) {
-                               if (IS_INT_LNG_TYPE(d)) {
-                                       if (IS_2_WORD_TYPE(d)) {
-                                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
-                                               M_LNGMOVE(REG_RESULT_PACKED, s1);
-                                       }
-                                       else {
-                                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
-                                               M_INTMOVE(REG_RESULT, s1);
-                                       }
-                               }
-                               else {
-                                       s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
-                                       M_FLTMOVE(REG_FRESULT, s1);
-                               }
+                       case TYPE_LNG:
+                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+                               M_LNGMOVE(REG_RESULT_PACKED, s1);
+                               emit_store_dst(jd, iptr, s1);
+                               break;
+
+                       case TYPE_FLT:
+                       case TYPE_DBL:
+                               s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
+                               M_FLTMOVE(REG_FRESULT, s1);
                                emit_store_dst(jd, iptr, s1);
+                               break;
+
+                       case TYPE_VOID:
+                               break;
                        }
                        break;
 
@@ -2446,7 +2458,7 @@ gen_method:
                                                                                disp);
 
                                        M_ILD(REG_ITMP2, REG_PV, disp);
-                                       M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
+                                       M_IAND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
                                        emit_label_beq(cd, BRANCH_LABEL_2);
                                }
 
@@ -2607,7 +2619,7 @@ gen_method:
                                                                        iptr->sx.s23.s3.c.ref, disp);
 
                                M_ILD(REG_ITMP3, REG_PV, disp);
-                               M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
+                               M_IAND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
                                emit_label_beq(cd, BRANCH_LABEL_2);
                        }
 
@@ -2791,7 +2803,11 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        s4           s1, s2;
        int          disp;
 
-       /* get required compiler data */
+       /* Sanity check. */
+
+       assert(f != NULL);
+
+       /* Get required compiler data. */
 
        m    = jd->m;
        code = jd->code;
@@ -2903,51 +2919,58 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
                t = md->paramtypes[i].type;
 
-               if (IS_INT_LNG_TYPE(t)) {
-                       if (!md->params[i].inmemory) {
-                               s1 = md->params[i].regoff;
-                               s2 = nmd->params[j].regoff;
+               if (!md->params[i].inmemory) {
+                       s1 = md->params[i].regoff;
+                       s2 = nmd->params[j].regoff;
 
-                               if (!nmd->params[j].inmemory) {
-                                       if (IS_2_WORD_TYPE(t))
-                                               M_LNGMOVE(s1, s2);
-                                       else
-                                               M_INTMOVE(s1, s2);
-                               }
-                               else {
-                                       if (IS_2_WORD_TYPE(t))
-                                               M_LST(s1, REG_SP, s2);
-                                       else
-                                               M_IST(s1, REG_SP, s2);
-                               }
-                       }
-                       else {
-                               s1 = md->params[i].regoff + cd->stackframesize * 8;
-                               s2 = nmd->params[j].regoff;
+                       switch (t) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               if (!nmd->params[j].inmemory)
+                                       M_INTMOVE(s1, s2);
+                               else
+                                       M_IST(s1, REG_SP, s2);
+                               break;
 
-                               M_ILD(REG_ITMP1, REG_SP, s1);
-                               if (IS_2_WORD_TYPE(t))
-                                       M_ILD(REG_ITMP2, REG_SP, s1 + 4);
+                       case TYPE_LNG:
+                               if (!nmd->params[j].inmemory)
+                                       M_LNGMOVE(s1, s2);
+                               else
+                                       M_LST(s1, REG_SP, s2);
+                               break;
 
-                               M_IST(REG_ITMP1, REG_SP, s2);
-                               if (IS_2_WORD_TYPE(t))
-                                       M_IST(REG_ITMP2, REG_SP, s2 + 4);
+                       case TYPE_FLT:
+                       case TYPE_DBL:
+                               /* We only copy spilled float arguments, as the float
+                                  argument registers keep unchanged. */
+                               break;
                        }
                }
                else {
-                       /* We only copy spilled float arguments, as the float
-                          argument registers keep unchanged. */
+                       s1 = md->params[i].regoff + cd->stackframesize * 8;
+                       s2 = nmd->params[j].regoff;
 
-                       if (md->params[i].inmemory) {
-                               s1 = md->params[i].regoff + cd->stackframesize * 8;
-                               s2 = nmd->params[j].regoff;
+                       switch (t) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               M_ILD(REG_ITMP1, REG_SP, s1);
+                               M_IST(REG_ITMP1, REG_SP, s2);
+                               break;
 
+                       case TYPE_LNG:
+                               M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
+                               M_LST(REG_ITMP12_PACKED, REG_SP, s2);
+                               break;
+
+                       case TYPE_FLT:
                                M_DLD(REG_FTMP1, REG_SP, s1);
+                               M_FST(REG_FTMP1, REG_SP, s2);
+                               break;
 
-                               if (IS_2_WORD_TYPE(t))
-                                       M_DST(REG_FTMP1, REG_SP, s2);
-                               else
-                                       M_FST(REG_FTMP1, REG_SP, s2);
+                       case TYPE_DBL:
+                               M_DLD(REG_FTMP1, REG_SP, s1);
+                               M_DST(REG_FTMP1, REG_SP, s2);
+                               break;
                        }
                }
        }
index 2c02c3c589c0ffaa5a1202975bb868d24cc405c3..ea6f9843546d91b19d233bc4ddc1d7abc1c85215 100644 (file)
@@ -1,10 +1,8 @@
 /* src/vm/jit/powerpc/codegen.h - code generation macros and definitions for
                                   32-bit PowerPC
 
-   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.
 
     } while (0)
 
 
-/* instruction macros *********************************************************/
+/* machine instruction macros **************************************************
+
+   Argument order:
+
+   machine instruction macro:
+       Same order as for the mnemonic (d, s1, s2).
+
+   emit macro:
+       Same order as in the instruction encoding.
+
+*******************************************************************************/
+
+#define MI_and(rA,rS,rB)                M_OP3(31,  28, 0, 0, rS, rA, rB)
+#define MI_anddot(rA,rS,rB)             M_OP3(31,  28, 0, 1, rS, rA, rB)
+#define MI_andi(rA,rS,UIMM)             M_OP2_IMM(28, rS, rA, UIMM)
+#define MI_lwarx(rD,rA,rB)              M_OP3(31,  20, 0, 0, rD, rA, rB)
+#define MI_or(rA,rS,rB)                 M_OP3(31, 444, 0, 0, rS, rA, rB)
+#define MI_ordot(rA,rS,rB)              M_OP3(31, 444, 0, 1, rS, rA, rB)
+#define MI_ori(rA,rS,UIMM)              M_OP2_IMM(24, rS, rA, UIMM)
+#define MI_stwcxdot(rS,rA,rB)           M_OP3(31, 150, 0, 1, rS, rA, rB)
+#define MI_subf(rD,rA,rB)               M_OP3(31,  40, 0, 0, rD, rA, rB)
+#define MI_subfdot(rD,rA,rB)            M_OP3(31,  40, 0, 1, rD, rA, rB)
+#define MI_sync                         M_OP3(31, 598, 0, 0,  0,  0,  0)
+
+
+/* HIR macros ******************************************************************
+
+   Argument order:
+
+   HIR macro:
+       Default usage in CACAO (s1, s2, d).
+
+   machine instruction macro:
+       Same order as for the mnemonic (d, s1, s2).
+
+*******************************************************************************/
+
+/* integer instructions *******************************************************/
+
+#define M_IAND(a,b,d)                   MI_and(d, a, b)
+#define M_IAND_IMM(a,b,d)               MI_andi(d, a, b)
+#define M_IOR(a,b,d)                    MI_or(d, a, b)
+#define M_IOR_IMM(a,b,d)                MI_ori(d, a, b)
+#define M_IOR_TST(a,b,d)                MI_ordot(d, a, b)
+#define M_ISUB(a,b,d)                   MI_subf(d, b, a)
+#define M_ISUB_TST(a,b,d)               MI_subfdot(d, b, a)
+#define M_MOV(a,d)                      MI_or(d, a, a)
+#define M_NOP                           MI_ori(0, 0, 0)
+
 
-#define M_IADD(a,b,c)                   M_OP3(31, 266, 0, 0, c, a, b)
-#define M_IADD_IMM(a,b,c)               M_OP2_IMM(14, c, a, b)
 #define M_ADDC(a,b,c)                   M_OP3(31, 10, 0, 0, c, a, b)
+#define M_ADDE(a,b,c)                   M_OP3(31, 138, 0, 0, c, a, b)
 #define M_ADDIC(a,b,c)                  M_OP2_IMM(12, c, a, b)
 #define M_ADDICTST(a,b,c)               M_OP2_IMM(13, c, a, b)
-#define M_ADDE(a,b,c)                   M_OP3(31, 138, 0, 0, c, a, b)
-#define M_ADDZE(a,b)                    M_OP3(31, 202, 0, 0, b, a, 0)
+#define M_ADDIS(a,b,c)                  M_OP2_IMM(15, c, a, b)
 #define M_ADDME(a,b)                    M_OP3(31, 234, 0, 0, b, a, 0)
-#define M_ISUB(a,b,c)                   M_OP3(31, 40, 0, 0, c, b, a)
-#define M_ISUBTST(a,b,c)                M_OP3(31, 40, 0, 1, c, b, a)
-#define M_SUBC(a,b,c)                   M_OP3(31, 8, 0, 0, c, b, a)
-#define M_SUBIC(a,b,c)                  M_OP2_IMM(8, c, b, a)
-#define M_SUBE(a,b,c)                   M_OP3(31, 136, 0, 0, c, b, a)
-#define M_SUBZE(a,b)                    M_OP3(31, 200, 0, 0, b, a, 0)
-#define M_SUBME(a,b)                    M_OP3(31, 232, 0, 0, b, a, 0)
-
-#define M_AND(a,b,c)                    M_OP3(31, 28, 0, 0, a, c, b)
-#define M_AND_IMM(a,b,c)                M_OP2_IMM(28, a, c, b)
+#define M_ADDZE(a,b)                    M_OP3(31, 202, 0, 0, b, a, 0)
+#define M_ADDZE(a,b)                    M_OP3(31, 202, 0, 0, b, a, 0)
 #define M_ANDIS(a,b,c)                  M_OP2_IMM(29, a, c, b)
-#define M_OR(a,b,c)                     M_OP3(31, 444, 0, 0, a, c, b)
-#define M_OR_TST(a,b,c)                 M_OP3(31, 444, 0, 1, a, c, b)
-#define M_OR_IMM(a,b,c)                 M_OP2_IMM(24, a, c, b)
-#define M_ORIS(a,b,c)                   M_OP2_IMM(25, a, c, b)
-#define M_XOR(a,b,c)                    M_OP3(31, 316, 0, 0, a, c, b)
-#define M_XOR_IMM(a,b,c)                M_OP2_IMM(26, a, c, b)
-#define M_XORIS(a,b,c)                  M_OP2_IMM(27, a, c, b)
-
-#define M_SLL(a,b,c)                    M_OP3(31, 24, 0, 0, a, c, b)
-#define M_SRL(a,b,c)                    M_OP3(31, 536, 0, 0, a, c, b)
-#define M_SRA(a,b,c)                    M_OP3(31, 792, 0, 0, a, c, b)
-#define M_SRA_IMM(a,b,c)                M_OP3(31, 824, 0, 0, a, c, b)
-
+#define M_BEQ(a)                        M_BC(12, 2, a, 0, 0)
+#define M_BGE(a)                        M_BC(4,  0, a, 0, 0)
+#define M_BGT(a)                        M_BC(12, 1, a, 0, 0)
+#define M_BL(a)                         M_B(a, 0, 1)
+#define M_BLDU(a,b,c)                   M_OP2_IMM(34, a, b, c)
+#define M_BLE(a)                        M_BC(4,  1, a, 0, 0)
+#define M_BLT(a)                        M_BC(12, 0, a, 0, 0)
+#define M_BNAN(a)                       M_BC(12, 3, a, 0, 0)
+#define M_BNE(a)                        M_BC(4,  2, a, 0, 0)
+#define M_BR(a)                         M_B(a, 0, 0)
+#define M_BSEXT(a,b)                    M_OP3(31, 954, 0, 0, a, b, 0)
+#define M_BST(a,b,c)                    M_OP2_IMM(38, a, b, c)
+#define M_CMP(a,b)                      M_OP3(31, 0, 0, 0, 0, a, b)
+#define M_CMPI(a,b)                     M_OP2_IMM(11, 0, a, b)
+#define M_CMPU(a,b)                     M_OP3(31, 32, 0, 0, 0, a, b)
+#define M_CMPUI(a,b)                    M_OP2_IMM(10, 0, a, b)
+#define M_CZEXT(a,b)                    M_RLWINM(a,0,16,31,b)
+#define M_IADD(a,b,c)                   M_OP3(31, 266, 0, 0, c, a, b)
+#define M_IADD_IMM(a,b,c)               M_OP2_IMM(14, c, a, b)
+#define M_IDIV(a,b,c)                   M_OP3(31, 491, 0, 0, c, a, b)
 #define M_IMUL(a,b,c)                   M_OP3(31, 235, 0, 0, c, a, b)
 #define M_IMUL_IMM(a,b,c)               M_OP2_IMM(7, c, a, b)
-#define M_IDIV(a,b,c)                   M_OP3(31, 491, 0, 0, c, a, b)
-
+#define M_JSR                           M_OP3(19, 528, 0, 1, 20, 0, 0)
+#define M_LBZX(a,b,c)                   M_OP3(31, 87, 0, 0, a, b, c)
+#define M_LHAX(a,b,c)                   M_OP3(31, 343, 0, 0, a, b, c)
+#define M_LHZX(a,b,c)                   M_OP3(31, 279, 0, 0, a, b, c)
+#define M_LWZX(a,b,c)                   M_OP3(31, 23, 0, 0, a, b, c)
+#define M_MFCTR(a)                      M_OP3(31, 339, 0, 0, a, 9, 0)
+#define M_MFLR(a)                       M_OP3(31, 339, 0, 0, a, 8, 0)
+#define M_MFXER(a)                      M_OP3(31, 339, 0, 0, a, 1, 0)
+#define M_MTCTR(a)                      M_OP3(31, 467, 0, 0, a, 9, 0)
+#define M_MTLR(a)                       M_OP3(31, 467, 0, 0, a, 8, 0)
+#define M_MTXER(a)                      M_OP3(31, 467, 0, 0, a, 1, 0)
 #define M_NEG(a,b)                      M_OP3(31, 104, 0, 0, b, a, 0)
 #define M_NOT(a,b)                      M_OP3(31, 124, 0, 0, a, b, a)
-
-#define M_SUBFIC(a,b,c)                 M_OP2_IMM(8, c, a, b)
-#define M_SUBFZE(a,b)                   M_OP3(31, 200, 0, 0, b, a, 0)
+#define M_ORIS(a,b,c)                   M_OP2_IMM(25, a, c, b)
+#define M_RET                           M_OP3(19, 16, 0, 0, 20, 0, 0)
 #define M_RLWINM(a,b,c,d,e)             M_OP4(21, d, 0, a, e, b, c)
-#define M_ADDZE(a,b)                    M_OP3(31, 202, 0, 0, b, a, 0)
+#define M_RTS                           M_OP3(19, 528, 0, 0, 20, 0, 0)
+#define M_SLDU(a,b,c)                   M_OP2_IMM(40, a, b, c)
+#define M_SLL(a,b,c)                    M_OP3(31, 24, 0, 0, a, c, b)
 #define M_SLL_IMM(a,b,c)                M_RLWINM(a,b,0,31-(b),c)
+#define M_SRA(a,b,c)                    M_OP3(31, 792, 0, 0, a, c, b)
+#define M_SRA_IMM(a,b,c)                M_OP3(31, 824, 0, 0, a, c, b)
+#define M_SRL(a,b,c)                    M_OP3(31, 536, 0, 0, a, c, b)
 #define M_SRL_IMM(a,b,c)                M_RLWINM(a,32-(b),b,31,c)
-#define M_ADDIS(a,b,c)                  M_OP2_IMM(15, c, a, b)
-#define M_STFIWX(a,b,c)                 M_OP3(31, 983, 0, 0, a, b, c)
-#define M_LWZX(a,b,c)                   M_OP3(31, 23, 0, 0, a, b, c)
-#define M_LHZX(a,b,c)                   M_OP3(31, 279, 0, 0, a, b, c)
-#define M_LHAX(a,b,c)                   M_OP3(31, 343, 0, 0, a, b, c)
-#define M_LBZX(a,b,c)                   M_OP3(31, 87, 0, 0, a, b, c)
-#define M_LFSX(a,b,c)                   M_OP3(31, 535, 0, 0, a, b, c)
-#define M_LFDX(a,b,c)                   M_OP3(31, 599, 0, 0, a, b, c)
-#define M_STWX(a,b,c)                   M_OP3(31, 151, 0, 0, a, b, c)
-#define M_STHX(a,b,c)                   M_OP3(31, 407, 0, 0, a, b, c)
+#define M_SSEXT(a,b)                    M_OP3(31, 922, 0, 0, a, b, 0)
+#define M_SST(a,b,c)                    M_OP2_IMM(44, a, b, c)
 #define M_STBX(a,b,c)                   M_OP3(31, 215, 0, 0, a, b, c)
-#define M_STFSX(a,b,c)                  M_OP3(31, 663, 0, 0, a, b, c)
-#define M_STFDX(a,b,c)                  M_OP3(31, 727, 0, 0, a, b, c)
-
-#define M_STWU_INTERN(a,b,disp)         M_OP2_IMM(37,a,b,disp)
-
-#define M_STWU(a,b,disp) \
-    do { \
-        s4 lo = (disp) & 0x0000ffff; \
-        s4 hi = ((disp) >> 16); \
-        if (((disp) >= -32678) && ((disp) <= 32767)) { \
-            M_STWU_INTERN(a,b,lo); \
-        } else { \
-            M_ADDIS(REG_ZERO,hi,REG_ITMP3); \
-            M_OR_IMM(REG_ITMP3,lo,REG_ITMP3); \
-            M_STWUX(REG_SP,REG_SP,REG_ITMP3); \
-        } \
-    } while (0)
-
+#define M_STHX(a,b,c)                   M_OP3(31, 407, 0, 0, a, b, c)
 #define M_STWUX(a,b,c)                  M_OP3(31,183,0,0,a,b,c)
-
-#define M_LDAH(a,b,c)                   M_ADDIS(b, c, a)
-
+#define M_STWX(a,b,c)                   M_OP3(31, 151, 0, 0, a, b, c)
+#define M_SUBC(a,b,c)                   M_OP3(31, 8, 0, 0, c, b, a)
+#define M_SUBE(a,b,c)                   M_OP3(31, 136, 0, 0, c, b, a)
+#define M_SUBFIC(a,b,c)                 M_OP2_IMM(8, c, a, b)
+#define M_SUBFZE(a,b)                   M_OP3(31, 200, 0, 0, b, a, 0)
+#define M_SUBIC(a,b,c)                  M_OP2_IMM(8, c, b, a)
+#define M_SUBME(a,b)                    M_OP3(31, 232, 0, 0, b, a, 0)
+#define M_SUBZE(a,b)                    M_OP3(31, 200, 0, 0, b, a, 0)
 #define M_TRAP                          M_OP3(31, 4, 0, 0, 31, 0, 0)
 #define M_TRAPGEU(a,b)                  M_OP3(31, 4, 0, 0, 5, a, b)
-
-#define M_NOP                           M_OR_IMM(0, 0, 0)
-#define M_MOV(a,b)                      M_OR(a, a, b)
 #define M_TST(a)                        M_OP3(31, 444, 0, 1, a, a, a)
+#define M_XOR(a,b,c)                    M_OP3(31, 316, 0, 0, a, c, b)
+#define M_XORIS(a,b,c)                  M_OP2_IMM(27, a, c, b)
+#define M_XOR_IMM(a,b,c)                M_OP2_IMM(26, a, c, b)
 
-#define M_DADD(a,b,c)                   M_OP3(63, 21, 0, 0, c, a, b)
-#define M_FADD(a,b,c)                   M_OP3(59, 21, 0, 0, c, a, b)
-#define M_DSUB(a,b,c)                   M_OP3(63, 20, 0, 0, c, a, b)
-#define M_FSUB(a,b,c)                   M_OP3(59, 20, 0, 0, c, a, b)
-#define M_DMUL(a,b,c)                   M_OP4(63, 25, 0, c, a, 0, b)
-#define M_FMUL(a,b,c)                   M_OP4(59, 25, 0, c, a, 0, b)
-#define M_DDIV(a,b,c)                   M_OP3(63, 18, 0, 0, c, a, b)
-#define M_FDIV(a,b,c)                   M_OP3(59, 18, 0, 0, c, a, b)
-
-#define M_FABS(a,b)                     M_OP3(63, 264, 0, 0, b, 0, a)
-#define M_CVTDL(a,b)                    M_OP3(63, 14, 0, 0, b, 0, a)
-#define M_CVTDL_C(a,b)                  M_OP3(63, 15, 0, 0, b, 0, a)
-#define M_CVTDF(a,b)                    M_OP3(63, 12, 0, 0, b, 0, a)
-#define M_FMOV(a,b)                     M_OP3(63, 72, 0, 0, b, 0, a)
-#define M_FMOVN(a,b)                    M_OP3(63, 40, 0, 0, b, 0, a)
-#define M_DSQRT(a,b)                    M_OP3(63, 22, 0, 0, b, 0, a)
-#define M_FSQRT(a,b)                    M_OP3(59, 22, 0, 0, b, 0, a)
 
-#define M_FCMPU(a,b)                    M_OP3(63, 0, 0, 0, 0, a, b)
-#define M_FCMPO(a,b)                    M_OP3(63, 32, 0, 0, 0, a, b)
+#define M_LDAH(a,b,c)                   M_ADDIS(b, c, a)
+#define M_LDATST(a,b,c)                 M_ADDICTST(b, c, a)
+#define M_CLR(a)                        M_IADD_IMM(0, 0, a)
 
-#define M_BLDU(a,b,c)                   M_OP2_IMM(34, a, b, c)
-#define M_SLDU(a,b,c)                   M_OP2_IMM(40, a, b, c)
 
 #define M_ILD_INTERN(a,b,disp)          M_OP2_IMM(32,a,b,disp)
 
         } \
     } while (0)
 
-#define M_ALD_INTERN(a,b,disp)          M_ILD_INTERN(a,b,disp)
-#define M_ALD(a,b,disp)                 M_ILD(a,b,disp)
-
-#define M_BST(a,b,c)                    M_OP2_IMM(38, a, b, c)
-#define M_SST(a,b,c)                    M_OP2_IMM(44, a, b, c)
-
 #define M_IST_INTERN(a,b,disp)          M_OP2_IMM(36,a,b,disp)
 
 /* Stores with displacement overflow should only happen with PUTFIELD
         } \
     } while (0)
 
+#define M_STWU_INTERN(a,b,disp)         M_OP2_IMM(37,a,b,disp)
+
+#define M_STWU(a,b,disp) \
+    do { \
+        s4 lo = (disp) & 0x0000ffff; \
+        s4 hi = ((disp) >> 16); \
+        if (((disp) >= -32678) && ((disp) <= 32767)) { \
+            M_STWU_INTERN(a,b,lo); \
+        } else { \
+            M_ADDIS(REG_ZERO,hi,REG_ITMP3); \
+            M_IOR_IMM(REG_ITMP3,lo,REG_ITMP3); \
+            M_STWUX(REG_SP,REG_SP,REG_ITMP3); \
+        } \
+    } while (0)
+
+#define M_LDA_INTERN(a,b,c)             M_IADD_IMM(b, c, a)
+
+#define M_LDA(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            M_LDA_INTERN(a,b,lo); \
+        } else { \
+            M_ADDIS(b,hi,a); \
+            M_LDA_INTERN(a,a,lo); \
+        } \
+    } while (0)
+
+
+#define M_AADD(a,b,d)                   M_IADD(a, b, d)
+#define M_AADD_IMM(a,b,d)               M_IADD_IMM(a, b, d)
+#define M_ALD_INTERN(a,b,disp)          M_ILD_INTERN(a,b,disp)
+#define M_ALD(a,b,disp)                 M_ILD(a,b,disp)
 #define M_AST_INTERN(a,b,disp)          M_IST_INTERN(a,b,disp)
 #define M_AST(a,b,disp)                 M_IST(a,b,disp)
 
-#define M_BSEXT(a,b)                    M_OP3(31, 954, 0, 0, a, b, 0)
-#define M_SSEXT(a,b)                    M_OP3(31, 922, 0, 0, a, b, 0)
-#define M_CZEXT(a,b)                    M_RLWINM(a,0,16,31,b)
 
-#define M_BR(a)                         M_B(a, 0, 0)
-#define M_BL(a)                         M_B(a, 0, 1)
-#define M_RET                           M_OP3(19, 16, 0, 0, 20, 0, 0)
-#define M_JSR                           M_OP3(19, 528, 0, 1, 20, 0, 0)
-#define M_RTS                           M_OP3(19, 528, 0, 0, 20, 0, 0)
+/* floating point instructions ************************************************/
 
-#define M_CMP(a,b)                      M_OP3(31, 0, 0, 0, 0, a, b)
-#define M_CMPU(a,b)                     M_OP3(31, 32, 0, 0, 0, a, b)
-#define M_CMPI(a,b)                     M_OP2_IMM(11, 0, a, b)
-#define M_CMPUI(a,b)                    M_OP2_IMM(10, 0, a, b)
+#define M_CVTDF(a,b)                    M_OP3(63, 12, 0, 0, b, 0, a)
+#define M_CVTDL(a,b)                    M_OP3(63, 14, 0, 0, b, 0, a)
+#define M_CVTDL_C(a,b)                  M_OP3(63, 15, 0, 0, b, 0, a)
+#define M_DADD(a,b,c)                   M_OP3(63, 21, 0, 0, c, a, b)
+#define M_DDIV(a,b,c)                   M_OP3(63, 18, 0, 0, c, a, b)
+#define M_DMUL(a,b,c)                   M_OP4(63, 25, 0, c, a, 0, b)
+#define M_DSQRT(a,b)                    M_OP3(63, 22, 0, 0, b, 0, a)
+#define M_DSUB(a,b,c)                   M_OP3(63, 20, 0, 0, c, a, b)
+#define M_FABS(a,b)                     M_OP3(63, 264, 0, 0, b, 0, a)
+#define M_FADD(a,b,c)                   M_OP3(59, 21, 0, 0, c, a, b)
+#define M_FCMPO(a,b)                    M_OP3(63, 32, 0, 0, 0, a, b)
+#define M_FCMPU(a,b)                    M_OP3(63, 0, 0, 0, 0, a, b)
+#define M_FDIV(a,b,c)                   M_OP3(59, 18, 0, 0, c, a, b)
+#define M_FMOV(a,b)                     M_OP3(63, 72, 0, 0, b, 0, a)
+#define M_FMOVN(a,b)                    M_OP3(63, 40, 0, 0, b, 0, a)
+#define M_FMUL(a,b,c)                   M_OP4(59, 25, 0, c, a, 0, b)
+#define M_FSQRT(a,b)                    M_OP3(59, 22, 0, 0, b, 0, a)
+#define M_FSUB(a,b,c)                   M_OP3(59, 20, 0, 0, c, a, b)
+#define M_LFDX(a,b,c)                   M_OP3(31, 599, 0, 0, a, b, c)
+#define M_LFSX(a,b,c)                   M_OP3(31, 535, 0, 0, a, b, c)
+#define M_STFDX(a,b,c)                  M_OP3(31, 727, 0, 0, a, b, c)
+#define M_STFIWX(a,b,c)                 M_OP3(31, 983, 0, 0, a, b, c)
+#define M_STFSX(a,b,c)                  M_OP3(31, 663, 0, 0, a, b, c)
 
-#define M_BLT(a)                        M_BC(12, 0, a, 0, 0)
-#define M_BLE(a)                        M_BC(4,  1, a, 0, 0)
-#define M_BGT(a)                        M_BC(12, 1, a, 0, 0)
-#define M_BGE(a)                        M_BC(4,  0, a, 0, 0)
-#define M_BEQ(a)                        M_BC(12, 2, a, 0, 0)
-#define M_BNE(a)                        M_BC(4,  2, a, 0, 0)
-#define M_BNAN(a)                       M_BC(12, 3, a, 0, 0)
 
 #define M_FLD_INTERN(a,b,disp)          M_OP2_IMM(48,a,b,disp)
-#define M_DLD_INTERN(a,b,disp)          M_OP2_IMM(50,a,b,disp)
 
 #define M_FLD(a,b,disp) \
     do { \
         } \
     } while (0)
 
+#define M_DLD_INTERN(a,b,disp)          M_OP2_IMM(50,a,b,disp)
+
 #define M_DLD(a,b,disp) \
     do { \
         s4 lo = (short) (disp); \
     } while (0)
 
 #define M_FST_INTERN(a,b,disp)          M_OP2_IMM(52,a,b,disp)
-#define M_DST_INTERN(a,b,disp)          M_OP2_IMM(54,a,b,disp)
 
 #define M_FST(a,b,disp) \
     do { \
         } \
     } while (0)
 
+#define M_DST_INTERN(a,b,disp)          M_OP2_IMM(54,a,b,disp)
+
 #define M_DST(a,b,disp) \
     do { \
         s4 lo = (short) (disp); \
         } \
     } while (0)
 
-#define M_MFLR(a)                       M_OP3(31, 339, 0, 0, a, 8, 0)
-#define M_MFXER(a)                      M_OP3(31, 339, 0, 0, a, 1, 0)
-#define M_MFCTR(a)                      M_OP3(31, 339, 0, 0, a, 9, 0)
-#define M_MTLR(a)                       M_OP3(31, 467, 0, 0, a, 8, 0)
-#define M_MTXER(a)                      M_OP3(31, 467, 0, 0, a, 1, 0)
-#define M_MTCTR(a)                      M_OP3(31, 467, 0, 0, a, 9, 0)
-
-#define M_LDA_INTERN(a,b,c)             M_IADD_IMM(b, c, a)
-
-#define M_LDA(a,b,disp) \
-    do { \
-        s4 lo = (short) (disp); \
-        s4 hi = (short) (((disp) - lo) >> 16); \
-        if (hi == 0) { \
-            M_LDA_INTERN(a,b,lo); \
-        } else { \
-            M_ADDIS(b,hi,a); \
-            M_LDA_INTERN(a,a,lo); \
-        } \
-    } while (0)
-
-
-#define M_LDATST(a,b,c)                 M_ADDICTST(b, c, a)
-#define M_CLR(a)                        M_IADD_IMM(0, 0, a)
-#define M_AADD_IMM(a,b,c)               M_IADD_IMM(a, b, c)
-
 #endif /* _CODEGEN_H */
 
 
index 529b69354f9cfd38bf29db2fac765f18d1f3046b..783991af9aab3f00461445f2daca116524c2abe7 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/powerpc/darwin/md-abi.c - functions for PowerPC Darwin ABI
+/* src/vm/jit/powerpc/darwin/md-abi.c - PowerPC Darwin ABI
 
-   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,6 +32,7 @@
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
 
 #include "vmcore/descriptor.h"
 
@@ -394,7 +393,7 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t* stackslot)
 {
        methodinfo   *m;
        codeinfo     *code;
index 7a9e683727cecd4a5185a88a9f51327a997122d6..44b0f73d81afcd986dd97a9e6ec9ba96ae051287 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/darwin/md-os.c - machine dependent PowerPC Darwin 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,9 +35,7 @@
 #include "vm/jit/powerpc/codegen.h"
 #include "vm/jit/powerpc/darwin/md-abi.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
index 404055649273d4094da27a2e77ecf85de2a77e6b..bd7f1e4b1da0c800e1768f272fc154a7deca1fff 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/powerpc/disass.c - wrapper functions for GNU binutils disassembler
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas  Krall
-            Reinhard Grafl
-
-   Changes: Stefan Ring
-            Christian Thalinger
-
-
 */
 
 
 #include "config.h"
 
 #include <dis-asm.h>
+#include <stdint.h>
 #include <stdio.h>
 
-#include "vm/types.h"
-
 #include "vm/global.h"
+
 #include "vm/jit/disass.h"
 
 
index 238c4d8112245de01a6bfd00e3580a3940bd8869..65927bb8a8260ff856c2d51345e403f4cda7d747 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/emit.c - PowerPC 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.
 
@@ -50,6 +48,7 @@
 #include "vm/jit/jit.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/trace.h"
+#include "vm/jit/trap.h"
 
 #include "vmcore/options.h"
 
@@ -421,7 +420,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TST(reg);
                M_BNE(1);
-               M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARITHMETIC);
+               M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_ArithmeticException);
        }
 }
 
@@ -452,7 +451,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TST(REG_RESULT);
                M_BNE(1);
-               M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_ArrayStoreException);
        }
 }
 
@@ -479,7 +478,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
                default:
                        vm_abort("emit_classcast_check: unknown condition %d", condition);
                }
-               M_ALD_INTERN(s1, REG_ZERO, EXCEPTION_HARDWARE_CLASSCAST);
+               M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
        }
 }
 
@@ -495,7 +494,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TST(reg);
                M_BNE(1);
-               M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+               M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
        }
 }
 
@@ -511,7 +510,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TST(REG_RESULT);
                M_BNE(1);
-               M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);
+               M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -524,7 +523,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 
 void emit_trap_compiler(codegendata *cd)
 {
-       M_ALD_INTERN(REG_METHODPTR, REG_ZERO, EXCEPTION_HARDWARE_COMPILER);
+       M_ALD_INTERN(REG_METHODPTR, REG_ZERO, TRAP_COMPILER);
 }
 
 
@@ -541,9 +540,9 @@ uint32_t emit_trap(codegendata *cd)
        /* Get machine code which is patched back in later. The
           trap is 1 instruction word long. */
 
-       mcode = *((u4 *) cd->mcodeptr);
+       mcode = *((uint32_t *) cd->mcodeptr);
 
-       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_PATCHER);
+       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_PATCHER);
 
        return mcode;
 }
index fb7d8ae1e4fc93c8d7bb680eee104e75c030aa60..af175d4cac72d7a5fe22a199779de0200101537b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/linux/md-abi.c - functions for PowerPC Linux ABI
 
-   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,6 +33,7 @@
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
 
 #include "vmcore/descriptor.h"
 
@@ -402,12 +401,13 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
 {
        methodinfo   *m;
        codeinfo     *code;
        registerdata *rd;
        methoddesc   *md;
+       varinfo      *v;
 
        /* get required compiler data */
 
@@ -426,27 +426,32 @@ void md_return_alloc(jitdata *jd, stackptr stackslot)
                   has not to survive method invokations. */
 
                if (!(stackslot->flags & SAVEDVAR)) {
-                       VAR(stackslot->varnum)->flags = PREALLOC;
+                       v = VAR(stackslot->varnum);
+                       v->flags = PREALLOC;
 
-                       if (IS_INT_LNG_TYPE(md->returntype.type)) {
-                               if (!IS_2_WORD_TYPE(md->returntype.type)) {
-                                       if (rd->argintreguse < 1)
-                                               rd->argintreguse = 1;
+                       switch (md->returntype.type) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               if (rd->argintreguse < 1)
+                                       rd->argintreguse = 1;
 
-                                       VAR(stackslot->varnum)->vv.regoff = REG_RESULT;
-                               }
-                               else {
-                                       if (rd->argintreguse < 2)
-                                               rd->argintreguse = 2;
+                               v->vv.regoff = REG_RESULT;
+                               break;
 
-                                       VAR(stackslot->varnum)->vv.regoff = REG_RESULT_PACKED;
-                               }
-                       }
-                       else { /* float/double */
+                       case TYPE_LNG:
+                               if (rd->argintreguse < 2)
+                                       rd->argintreguse = 2;
+
+                               v->vv.regoff = REG_RESULT_PACKED;
+                               break;
+
+                       case TYPE_FLT:
+                       case TYPE_DBL:
                                if (rd->argfltreguse < 1)
                                        rd->argfltreguse = 1;
-
-                               VAR(stackslot->varnum)->vv.regoff = REG_FRESULT;
+                               
+                               v->vv.regoff = REG_FRESULT;
+                               break;
                        }
                }
        }
index f7c78127169267787b329349073101d6a7d0e7d1..beab97d872476f00447b035adfc4ce09943965b7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/linux/md-os.c - machine dependent PowerPC Linux 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/powerpc/md.h"
 #include "vm/jit/powerpc/linux/md-abi.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
+
 #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"
+
+#include "vmcore/system.h"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -110,7 +111,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                type = disp;
 
-               if (type == EXCEPTION_HARDWARE_COMPILER) {
+               if (type == TRAP_COMPILER) {
                        /* The XPC is the RA minus 4, because the RA points to the
                           instruction after the call. */
 
@@ -122,20 +123,17 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                   define is 0. */
 
                addr = _gregs[s1];
-               type = EXCEPTION_HARDWARE_NULLPOINTER;
-
-               if (addr != 0)
-                       vm_abort("md_signal_handler_sigsegv: faulting address is not NULL: addr=%p", addr);
+               type = addr;
        }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* Set registers. */
 
        switch (type) {
-       case EXCEPTION_HARDWARE_COMPILER:
+       case TRAP_COMPILER:
                if (p != NULL) {
                        _gregs[REG_PV] = (uintptr_t) p;
                        _gregs[PT_NIP] = (uintptr_t) p;
@@ -156,7 +154,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                /* fall-through */
 
-       case EXCEPTION_HARDWARE_PATCHER:
+       case TRAP_PATCHER:
                if (p == NULL)
                        break;
 
@@ -212,20 +210,20 @@ void md_signal_handler_sigtrap(int sig, siginfo_t *siginfo, void *_p)
 
        s1 = M_OP3_GET_A(mcode);
 
-       /* for now we only handle ArrayIndexOutOfBoundsException */
+       /* For now we only handle ArrayIndexOutOfBoundsException. */
 
-       type = EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS;
+       type = TRAP_ArrayIndexOutOfBoundsException;
        val  = _gregs[s1];
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
-       /* set registers */
+       /* Set registers. */
 
-       _gregs[REG_ITMP1_XPTR] = (intptr_t) p;
-       _gregs[REG_ITMP2_XPC]  = (intptr_t) xpc;
-       _gregs[PT_NIP]         = (intptr_t) asm_handle_exception;
+       _gregs[REG_ITMP1_XPTR] = (uintptr_t) p;
+       _gregs[REG_ITMP2_XPC]  = (uintptr_t) xpc;
+       _gregs[PT_NIP]         = (uintptr_t) asm_handle_exception;
 }
 
 
@@ -300,6 +298,88 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #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;
+       unsigned long *_gregs;
+       s4              i;
+
+       _uc = (ucontext_t *) context;
+
+#if defined(__UCLIBC__)
+#error Please port md_executionstate_read to __UCLIBC__
+#else
+       _mc    = _uc->uc_mcontext.uc_regs;
+       _gregs = _mc->gregs;
+#endif
+
+       /* 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];
+
+       /* 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));
+       system_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs));
+}
+
+
+/* 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;
+       unsigned long *_gregs;
+       s4              i;
+
+       _uc = (ucontext_t *) context;
+
+#if defined(__UCLIBC__)
+#error Please port md_executionstate_write to __UCLIBC__
+#else
+       _mc    = _uc->uc_mcontext.uc_regs;
+       _gregs = _mc->gregs;
+#endif
+
+       /* 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));
+       system_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;
+}
+
+
 /* md_critical_section_restart *************************************************
 
    Search the critical sections tree for a matching section and set
index 10cf5b6225546a09630902017fbc163e1b05108e..8c7ba6ea41c975433a55d1edf673a9d4993c804d 100644 (file)
@@ -1,20 +1,6 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline void
-atomic_add(int *mem, int val)
-{
-       int temp;
-
-  __asm__ __volatile__ ("\n\
-1:  lwarx  %0,0,%2 \n\
-    add    %0,%0,%1 \n\
-       stwcx. %0,0,%2 \n\
-       bne-   1b \n\
-"   : "=&r"(temp)
-    : "r"(val), "r"(mem) : "cr0", "memory");
-}
-
 static inline long compare_and_swap(long *p, long oldval, long newval)
 {
   long ret, temp;
@@ -34,7 +20,6 @@ static inline long compare_and_swap(long *p, long oldval, long newval)
 }
 
 #define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("sync" : : : "memory");
 #define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("isync" : : : "memory");
 #define MEMORY_BARRIER() __asm__ __volatile__ ( "sync" : : : "memory" );
 
diff --git a/src/vm/jit/powerpc/md-trap.h b/src/vm/jit/powerpc/md-trap.h
new file mode 100644 (file)
index 0000000..3e55235
--- /dev/null
@@ -0,0 +1,79 @@
+/* src/vm/jit/powerpc/md-trap.h - PowerPC hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (powerpc) the trap numbers are used as load
+ * displacements and thus must not be 4- or 8-byte aligned.
+ *
+ * NOTE: In trap_init() we have a check whether the offset of
+ * java_arrayheader.data[0] is greater than the largest displacement
+ * defined below.  Otherwise normal array loads/stores could trigger
+ * an exception.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    1
+
+enum {
+       TRAP_NullPointerException           = 0,
+       TRAP_ArithmeticException            = 1,
+       TRAP_ArrayIndexOutOfBoundsException = 2,
+       TRAP_ArrayStoreException            = 3,
+
+       /* Don't use 4 (could be a normal load offset). */
+
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+
+       /* Don't use 8 (could be a normal load offset). */
+
+       TRAP_COMPILER                       = 9,
+       TRAP_END
+};
+
+#endif /* _MD_TRAP_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 140a820e7d0616fc37c1c593d1ddd800d79d01c2..aa9caeb424cc5dba210566c91949ef7d161a8b6b 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/powerpc/netbsd/md-abi.c - functions for PowerPC NetBSD ABI
+/* src/vm/jit/powerpc/netbsd/md-abi.c - PowerPC NetBSD ABI
 
-   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: Christian Ullrich
-
 */
 
 
@@ -38,7 +30,9 @@
 
 #include "vm/descriptor.h"
 #include "vm/global.h"
+
 #include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
 
 
 #define _ALIGN(a)    do { if ((a) & 1) (a)++; } while (0)
@@ -207,7 +201,7 @@ void md_param_alloc(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t* stackslot)
 {
        methodinfo   *m;
        registerdata *rd;
index 3c9a3b1e587f500bd63d41a4238cb93f94f7dd0d..f87a1a99dc0a9b8c89fe739fffae0948071c1bb7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/patcher.c - PowerPC code patching 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.
 
@@ -249,8 +247,8 @@ bool patcher_get_putstatic(patchref_t *pr)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        PATCH_BACK_ORIGINAL_MCODE;
@@ -461,7 +459,7 @@ bool patcher_invokeinterface(patchref_t *pr)
        /* patch interfacetable index */
 
        disp = OFFSET(vftbl_t, interfacetable[0]) -
-               sizeof(methodptr*) * m->class->index;
+               sizeof(methodptr*) * m->clazz->index;
 
        /* XXX TWISTI: check displacement */
 
@@ -469,7 +467,7 @@ bool patcher_invokeinterface(patchref_t *pr)
 
        /* patch method offset */
 
-       disp = sizeof(methodptr) * (m - m->class->methods);
+       disp = sizeof(methodptr) * (m - m->clazz->methods);
 
        /* XXX TWISTI: check displacement */
 
index 53e98ecc1ba5b11187cea378df8eaa7b79e5e27d..4ec4826ae012a0be82dd536a09cc7311a3b4d282 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/powerpc64/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.
 ##
@@ -50,8 +48,11 @@ libarch_la_SOURCES = \
        codegen.h \
        $(DISASS_SOURCES) \
        emit.c \
+       patcher.c \
+       \
+       md-trap.h \
        md.c \
-       patcher.c
+       md.h
 
 libarch_la_LIBADD = \
        $(OS_DIR)/libmd.la
index dc80f322cf837a937e1146165c56f7e5f5c7489d..5c7daa42bdd70b2b6bfd1fb6f806b89cbf7dfefc 100644 (file)
@@ -85,7 +85,6 @@
 
 
 #define SPECIALMEMUSE
-/* #define HAS_4BYTE_STACKSLOT */
 /* #define SUPPORT_COMBINE_INTEGER_REGISTERS */
 
 
index 488acfe5ae78ad3ef04de3440a743fd37e4bbc89..f9cd0fbe63068332dbdb078ed0be244ac6659532 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc64/codegen.c - machine code generator for 64-bit PowerPC
 
-   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.
 
@@ -65,6 +63,7 @@
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
@@ -269,13 +268,13 @@ bool codegen_emit(jitdata *jd)
                /* get or test the lock object */
 
                if (m->flags & ACC_STATIC) {
-                       p = dseg_add_address(cd, &m->class->object.header);
+                       p = dseg_add_address(cd, &m->clazz->object.header);
                        M_ALD(REG_A0, REG_PV, p);
                }
                else {
                        M_TST(REG_A0);
                        M_BNE(1);
-                       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
                }
 
                M_AST(REG_A0, REG_SP, s1 * 8);                      /* rd->memuse * 8 */
@@ -1455,8 +1454,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, disp);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, disp);
                                }
                        }
 
@@ -1502,8 +1501,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, disp);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, disp);
                                }
                        }
 
@@ -2136,9 +2135,9 @@ gen_method:
 
                                } else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
+                                               sizeof(methodptr*) * lm->clazz->index;
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
 
                                /* implicit null-pointer check */
@@ -2589,6 +2588,10 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        code = jd->code;
        cd   = jd->cd;
 
+       /* Sanity check. */
+
+       assert(!code_is_leafmethod(code));
+
        /* set some variables */
 
        md = m->parseddesc;
index f20ca4a3eee350dce06be4208fdaa8584cc6a280..b2a5119ee15daed98a51cba959f36ab118e0b736 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc64/emit.c - PowerPC64 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.
 
@@ -46,6 +44,7 @@
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/trace.h"
+#include "vm/jit/trap.h"
 
 #include "vmcore/options.h"
 
@@ -505,19 +504,11 @@ void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt)
 void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
 {
        if (checkbounds) {
-#define SOFTEX 0
-#if SOFTEX
-               M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
-               M_CMPU(s2, REG_ITMP3);
-               codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
-               BRANCH_NOPS;
-#else
                M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
                M_CMPU(s2, REG_ITMP3);
                M_BLT(1);
                /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
-               M_LWZ(s2, REG_ZERO, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
-#endif
+               M_LWZ(s2, REG_ZERO, TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -534,7 +525,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
                M_TST(REG_RESULT);
                M_BNE(1);
                /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
-               M_LWZ(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_LWZ(REG_ZERO, REG_ZERO, TRAP_ArrayStoreException);
        }
 }
 
@@ -548,35 +539,13 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
 void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
 {
        if (INSTRUCTION_MUST_CHECK(iptr))       {
-       #if SOFTEX
-               M_TST(reg);
-               codegen_add_arithmeticexception_ref(cd);
-               BRANCH_NOPS;
-       #else
                M_TST(reg);
                M_BNE(1);
                /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
-               M_LWZ(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARITHMETIC);
-       #endif
+               M_LWZ(REG_ZERO, REG_ZERO, TRAP_ArithmeticException);
        }
 }
 
-#if 0
-/* emit_arraystore_check *******************************************************
-
-   Emit an ArrayStoreException check.
-
-*******************************************************************************/
-
-void emit_arraystore_check(codegendata *cd, instruction *iptr, s4 reg)
-{
-       if (INSTRUCTION_MUST_CHECK(iptr))       {
-               M_TST(REG_RESULT);
-               codegen_add_arraystoreexception_ref(cd);
-               BRANCH_NOPS;
-       }
-}
-#endif
 
 /* emit_classcast_check ********************************************************
 
@@ -587,27 +556,22 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr, s4 reg)
 void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
 {
        if (INSTRUCTION_MUST_CHECK(iptr))       {
-       #if SOFTEX
-               codegen_add_classcastexception_ref(cd, condition, s1);
-               BRANCH_NOPS;
-               M_NOP;
-       #else
                switch(condition)       {
-                       case BRANCH_LE:
-                               M_BGT(1);
-                               break;
-                       case BRANCH_EQ:
-                               M_BNE(1);
-                               break;
-                       case BRANCH_GT:
-                               M_BLE(1);
-                               break;
-                       default:
-                               vm_abort("emit_classcast_check: unknown condition %d", condition);
+               case BRANCH_LE:
+                       M_BGT(1);
+                       break;
+               case BRANCH_EQ:
+                       M_BNE(1);
+                       break;
+               case BRANCH_GT:
+                       M_BLE(1);
+                       break;
+               default:
+                       vm_abort("emit_classcast_check: unknown condition %d", condition);
                }
+
                /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
-               M_LWZ(s1, REG_ZERO, EXCEPTION_HARDWARE_CLASSCAST);
-       #endif
+               M_LWZ(s1, REG_ZERO, TRAP_ClassCastException);
        }
 }
 
@@ -624,7 +588,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
                M_TST(reg);
                M_BNE(1);
                /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
-               M_LWZ(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+               M_LWZ(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
        }
 }
 
@@ -637,16 +601,10 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
 void emit_exception_check(codegendata *cd, instruction *iptr)
 {
        if (INSTRUCTION_MUST_CHECK(iptr))       {
-       #if SOFTEX
-               M_CMPI(REG_RESULT, 0);
-               codegen_add_fillinstacktrace_ref(cd);
-               BRANCH_NOPS;
-       #else
                M_TST(REG_RESULT);
                M_BNE(1);
                /* ALD is 4 byte aligned, ILD 2, onyl LWZ is byte aligned */
-               M_LWZ(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);
-       #endif
+               M_LWZ(REG_ZERO, REG_ZERO, TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -659,7 +617,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 
 void emit_trap_compiler(codegendata *cd)
 {
-       M_LWZ(REG_METHODPTR, REG_ZERO, EXCEPTION_HARDWARE_COMPILER);
+       M_LWZ(REG_METHODPTR, REG_ZERO, TRAP_COMPILER);
 }
 
 
@@ -679,7 +637,7 @@ uint32_t emit_trap(codegendata *cd)
        mcode = *((uint32_t *) cd->mcodeptr);
 
        /* ALD is 4 byte aligned, ILD 2, only LWZ is byte aligned */
-       M_LWZ(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_PATCHER);
+       M_LWZ(REG_ZERO, REG_ZERO, TRAP_PATCHER);
 
        return mcode;
 }
index 3cb624189caa9c49636bd1fc73005cdac79b00ed..f1a054e122c6130ca8c6d3ae8516475b89e76714 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc64/linux/md-abi.c - functions for PowerPC64 Linux ABI
 
-   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,6 +34,7 @@
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
 
 #include "vmcore/descriptor.h"
 
@@ -290,7 +289,7 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
 {
        methodinfo   *m;
        codeinfo     *code;
index 771551676f370e7c922c57eb3d7fe504ffb54e80..8b292f1adb037876f59c8f3757c23618a66f88c6 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc64/linux/md-os.c - machine dependent PowerPC64 Linux 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,9 +35,7 @@
 #include "vm/jit/powerpc64/md.h"
 #include "vm/jit/powerpc64/linux/md-abi.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
@@ -52,6 +48,7 @@
 #endif
 
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -98,10 +95,10 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        val  = _mc->gp_regs[d];
 
        if (s1 == REG_ZERO) {
-               /* we use the exception type as load displacement */
+               /* We use the exception type as load displacement. */
                type = disp;
 
-               if (type == EXCEPTION_HARDWARE_COMPILER) {
+               if (type == TRAP_COMPILER) {
                        /* The XPC is the RA minus 1, because the RA points to the
                           instruction after the call. */
 
@@ -109,19 +106,19 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                }
        }
        else {
-               /* normal NPE */
+               /* Normal NPE. */
                addr = _mc->gp_regs[s1];
                type = (int) addr;
        }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* Set registers. */
 
        switch (type) {
-       case EXCEPTION_HARDWARE_COMPILER:
+       case TRAP_COMPILER:
                if (p != NULL) {
                        _mc->gp_regs[REG_PV] = (uintptr_t) p;
                        _mc->gp_regs[PT_NIP] = (uintptr_t) p;
@@ -142,7 +139,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                /* fall-through */
 
-       case EXCEPTION_HARDWARE_PATCHER:
+       case TRAP_PATCHER:
                if (p == NULL)
                        break;
 
index cb36c085d8588732b051c403dc1351791c2afc23..5e3390c19fd48fc58408b0545a781096f26ba28a 100644 (file)
@@ -20,7 +20,6 @@ static inline long compare_and_swap(long *p, long oldval, long newval)
 }
 
 #define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("sync" : : : "memory");
 #define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("isync" : : : "memory");
 #define MEMORY_BARRIER() __asm__ __volatile__ ( "sync" : : : "memory" );
 
diff --git a/src/vm/jit/powerpc64/md-trap.h b/src/vm/jit/powerpc64/md-trap.h
new file mode 100644 (file)
index 0000000..7e8c5b6
--- /dev/null
@@ -0,0 +1,79 @@
+/* src/vm/jit/powerpc64/md-trap.h - PowerPC64 hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (alpha) the trap numbers are used as load
+ * displacements and thus must not be 4- or 8-byte aligned.
+ *
+ * NOTE: In trap_init() we have a check whether the offset of
+ * java_arrayheader.data[0] is greater than the largest displacement
+ * defined below.  Otherwise normal array loads/stores could trigger
+ * an exception.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    1
+
+enum {
+       TRAP_NullPointerException           = 0,
+       TRAP_ArithmeticException            = 1,
+       TRAP_ArrayIndexOutOfBoundsException = 2,
+       TRAP_ArrayStoreException            = 3,
+
+       /* Don't use 4 (could be a normal load offset). */
+
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+
+       /* Don't use 8 (could be a normal load offset). */
+
+       TRAP_COMPILER                       = 9,
+       TRAP_END
+};
+
+#endif /* _MD_TRAP_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 4b5aab7190c7a19571f3afd0fe6f5f86e6c76dd3..3e8bc5c15edbb3c26b2375a9f17dfc4231f15129 100644 (file)
@@ -41,6 +41,7 @@
 #include "vm/global.h"
 
 #include "vm/jit/jit.h"
+#include "vm/jit/trap.h"
 
 
 /* md_init *********************************************************************
@@ -177,7 +178,7 @@ void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert)
                *(u4*)(savedmcode) = *(u4*)(pc);
 
                /* build the machine code for the patch */
-               mcode = (0x80000000 | (EXCEPTION_HARDWARE_PATCHER));
+               mcode = (0x80000000 | TRAP_PATCHER);
 
                /* write the new machine code */
                *(u4*)(pc) = (u4) mcode;
index b2ccfdeceb9c91ec385e3cf4a217125b4d6410e0..8f6f160ad37bf1e942993e94e7206f5df6121fd4 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc64/patcher.c - PowerPC64 code patching 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.
 
@@ -104,8 +102,8 @@ bool patcher_get_putstatic(patchref_t *pr)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        /* patch back original code */
@@ -335,7 +333,7 @@ bool patcher_invokeinterface(patchref_t *pr)
        /* patch interfacetable index */
 
        disp = OFFSET(vftbl_t, interfacetable[0]) -
-               sizeof(methodptr*) * m->class->index;
+               sizeof(methodptr*) * m->clazz->index;
 
        /* XXX TWISTI: check displacement */
 
@@ -343,7 +341,7 @@ bool patcher_invokeinterface(patchref_t *pr)
 
        /* patch method offset */
 
-       disp = sizeof(methodptr) * (m - m->class->methods);
+       disp = sizeof(methodptr) * (m - m->clazz->methods);
 
        /* XXX TWISTI: check displacement */
 
diff --git a/src/vm/jit/python.c b/src/vm/jit/python.c
new file mode 100644 (file)
index 0000000..025c11f
--- /dev/null
@@ -0,0 +1,1908 @@
+/* src/vm/jit/python.c - Python pass
+
+   Copyright (C) 2007, 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.
+
+   Note: this code is currently alpha and needs to be documented.
+
+   This code wraps the jitdata structure into a python object and
+   makes it possible to implement a compiler pass as python function.
+
+   The wrapping of cacao types to python objects is meant to be easy and
+   straight-forward.
+   Cacao structs a wrapped into a python ``wrapper'' object, the state of 
+   which consists of:
+
+    * A void pointer.
+       * A pointer to a class function (see class_func), which implements the
+         object's behaviour.
+
+   Arrays and collection-like data structures are wrapped into a python
+   ``iterator'' object, the state of wich consists of:
+
+    * A void pointer.
+       * Another void pointer that is the cursor.
+       * A pointer to a iterator function (see iterator_func) which implements
+         the iterator's behaviour.
+
+   Because in python field names are identified as strings, to avoid a lot
+   of string comparisons, we translate the field as early as possible into 
+   an integer constant. This is achieved using the field_map array.
+
+   We could have used a wrapper generator like swig, but we don't want to 
+   wrap the rather low level C api to python 1:1. When wrapping stuff, try
+   to do it rather high level and in a pythonic way. Examples:
+
+    * Bad: instruction.flags and cacao.FLAG_UNRESOLVED == 0
+       * Good: instruction.is_unresolved
+       * Bad: for i in range(0, bb.icount): instr = bb.instructions[i]
+       * Good: for instr in bb.instructions
+
+  Adding instructions or variables is currently problematic, because it 
+  requires to resize fixed sized arrays. Reallocating an array means that
+  all elements are possibly moved, their addresses are changed and the 
+  associated python object become invalid. Further, usually there is the 
+  need to add several instructions, which possibly results in several 
+  reallocations of the array. A good solution would be:
+
+   * Copy-on-write the array (ex. bptr->instructions) into a python list,
+     and put that list into the dictionnary of the parent object.
+   * When the python parent object is destroyed, recreate the array from the
+     list.
+   * From python, bptr.instructions will return either the wrapped array, or
+     the list from the dictionnary.
+
+*/
+
+#include <Python.h>
+#include <structmember.h>
+
+#include "vm/global.h"
+#include "vm/jit/python.h"
+#include "vm/jit/show.h"
+#if defined(ENABLE_THREADS)
+# include "threads/lock-common.h"
+#endif
+
+#if defined(ENABLE_THREADS)
+static java_object_t *python_global_lock;
+#endif
+
+/*
+ * Defs
+ */
+
+typedef struct root_state root_state;
+
+struct root_state {
+       jitdata *jd;
+       PyObject *object_cache;
+};
+
+typedef struct class_state class_state;
+
+struct class_state {
+       root_state *root;
+       void *vp;
+};
+
+union class_arg {
+       struct {
+               int is_method;
+               int field;
+               PyObject **result;
+       } get;
+       struct {
+               int field;
+               PyObject *value;
+       } set;
+       struct {
+               PyObject *args;
+               PyObject **result;
+       } call;
+       struct {
+               int method;
+               PyObject *args;
+               PyObject **result;
+       } method_call;
+       struct {
+               PyObject **result;
+       } str;
+       void *key;
+};
+
+typedef union class_arg class_arg;
+
+enum class_op {
+       CLASS_SET_FIELD,
+       CLASS_GET_FIELD,
+       CLASS_CALL,
+       CLASS_STR,
+       CLASS_METHOD_CALL
+};
+
+typedef enum class_op class_op;
+
+typedef int(*class_func)(class_op, class_state *, class_arg *);
+#define CLASS_FUNC(name) int name(class_op op, class_state *state, class_arg *arg)
+#define CLASS_FUNC_CALL(name) name(op, state, arg)
+
+struct iterator_state {
+       root_state *root;
+       void *data;
+       void *pos;
+};
+
+union iterator_arg {
+       struct {
+               PyObject **result;
+       } get;
+       struct {
+               unsigned int index;
+               PyObject **result;
+       } subscript;
+       int length;
+       struct {
+               unsigned int index;
+               PyObject *value;
+       } setitem;
+};
+
+typedef union iterator_arg iterator_arg;
+
+typedef struct iterator_state iterator_state;
+
+enum iterator_op {
+       ITERATOR_INIT,
+       ITERATOR_GET,
+       ITERATOR_FORWARD,
+       ITERATOR_END,
+       ITERATOR_SUBSCRIPT,
+       ITERATOR_LENGTH,
+       ITERATOR_SETITEM
+};
+
+typedef enum iterator_op iterator_op;
+
+typedef int(*iterator_func)(iterator_op op, iterator_state *state, iterator_arg *arg);
+#define ITERATOR_FUNC(name) int name (iterator_op op, iterator_state *state, iterator_arg *arg)
+#define ITERATOR_SUBSCRIPT_CHECK(end) if (arg->subscript.index >= (end)) return -1
+#define ITERATOR_SETITEM_CHECK(end) if (arg->setitem.index >= (end)) return -1
+
+typedef struct method_state method_state;
+
+struct method_state {
+       int method;
+       class_state *cstate;
+};
+
+struct field_map_entry {
+       const char *name;
+       int tag;
+};
+
+typedef struct field_map_entry field_map_entry;
+
+enum field {
+       F_BASIC_BLOCKS,
+       F_CALL_RETURN_TYPE,
+       F_CALL_ARGS,
+       F_CLASSREF,
+       F_CONTROL_FLOW,
+       F_CONTROL_FLOW_EX,
+       F_DATA_FLOW,
+       F_DATA_FLOW_EX,
+       F_DESCRIPTOR,
+       F_DOM_SUCCESSORS,
+       F_DOMINANCE_FRONTIER,
+       F_DST,
+       F_END,
+       F_EXCEPTION_HANDLER,
+       F_EXCEPTION_TABLE,
+       F_FIELD,
+       F_FIELD_TYPE,
+       F_HANDLER,
+       F_HAS_CALL_ARGS,
+       F_HAS_DST,
+       F_IDOM,
+       F_INDEX,
+       F_INSTRUCTIONS,
+       F_INTERFACE_MAP,
+       F_IN_VARS,
+       F_IS_CLASS_CONSTANT,
+       F_IS_IN_MEMORY,
+       F_IS_INOUT,
+       F_IS_LOCAL,
+       F_IS_PREALLOCATED,
+       F_IS_SAVED,
+       F_IS_TEMPORARY,
+       F_IS_UNRESOLVED,
+       F_LOCAL_METHODINFO,
+       F_KLASS,
+       F_LINE,
+       F_LOCAL_MAP,
+       F_METHOD,
+       F_NAME,
+       F_NAME_EX,
+       F_NR,
+       F_OFFSET,
+       F_OPCODE,
+       F_OPCODE_EX,
+       F_OUT_VARS,
+       F_PARAMS,
+       F_PARAM_TYPES,
+       F_PEI,
+       F_PEI_EX,
+       F_PREDECESSORS,
+       F_REACHED,
+       F_REGISTER_OFFSET,
+       F_RETURN_TYPE,
+       F_S,
+       F_SHOW,
+       F_SUCCESSORS,
+       F_START,
+       F_TYPE,
+       F_UNRESOLVED_FIELD,
+       F_UNUSED,
+       F_VARS
+};
+
+/* Keep it soreted alphabetically, so we can support binary search in future. */
+struct field_map_entry field_map[] = {
+       { "basic_blocks", F_BASIC_BLOCKS },
+       { "call_return_type", F_CALL_RETURN_TYPE },
+       { "call_args", F_CALL_ARGS },
+       { "classref", F_CLASSREF },
+       { "control_flow", F_CONTROL_FLOW },
+       { "control_flow_ex", F_CONTROL_FLOW_EX },
+       { "data_flow", F_DATA_FLOW },
+       { "data_flow_ex", F_DATA_FLOW_EX },
+       { "descriptor", F_DESCRIPTOR },
+       { "dom_successors", F_DOM_SUCCESSORS },
+       { "dominance_frontier", F_DOMINANCE_FRONTIER },
+       { "dst", F_DST },
+       { "end", F_END },
+       { "exception_handler", F_EXCEPTION_HANDLER },
+       { "exception_table", F_EXCEPTION_TABLE },
+       { "field", F_FIELD },
+       { "field_type", F_FIELD_TYPE },
+       { "handler", F_HANDLER },
+       { "has_call_args", F_HAS_CALL_ARGS },
+       { "has_dst", F_HAS_DST },
+       { "idom", F_IDOM, },
+       { "index", F_INDEX },
+       { "instructions", F_INSTRUCTIONS },
+       { "interface_map", F_INTERFACE_MAP },
+       { "in_vars", F_IN_VARS },
+       { "is_class_constant", F_IS_CLASS_CONSTANT },
+       { "is_inout", F_IS_INOUT },
+       { "is_in_memory", F_IS_IN_MEMORY },
+       { "is_local", F_IS_LOCAL },
+       { "is_preallocated", F_IS_PREALLOCATED },
+       { "is_saved", F_IS_SAVED },
+       { "is_temporary", F_IS_TEMPORARY },
+       { "is_unresolved", F_IS_UNRESOLVED },
+       { "klass", F_KLASS },
+       { "line", F_LINE },
+       { "local_map", F_LOCAL_MAP },
+       { "local_methodinfo", F_LOCAL_METHODINFO },
+       { "method", F_METHOD },
+       { "name", F_NAME },
+       { "name_ex", F_NAME_EX },
+       { "nr", F_NR },
+       { "offset", F_OFFSET },
+       { "opcode", F_OPCODE },
+       { "opcode_ex", F_OPCODE_EX },
+       { "out_vars", F_OUT_VARS },
+       { "params", F_PARAMS },
+       { "param_types", F_PARAM_TYPES },
+       { "pei", F_PEI },
+       { "pei_ex", F_PEI_EX },
+       { "predecessors", F_PREDECESSORS },
+       { "reached", F_REACHED },
+       { "register_offset", F_REGISTER_OFFSET },
+       { "return_type", F_RETURN_TYPE },
+       { "s", F_S },
+       { "show", F_SHOW },
+       { "start", F_START },
+       { "successors", F_SUCCESSORS },
+       { "type", F_TYPE },
+       { "unresolved_field", F_UNRESOLVED_FIELD },
+       { "unused", F_UNUSED },
+       { "vars", F_VARS },
+       { NULL, 0 }
+};
+
+int field_find(const char *key) {
+       field_map_entry *it;
+
+       for (it = field_map; it->name; ++it) {
+               if (strcmp(it->name, key) == 0) {
+                       return it->tag;
+               }
+       }
+
+       return -1;
+}
+
+/*
+ * Python
+ */
+
+typedef struct method method;
+
+struct method {
+       PyObject_HEAD;
+       class_func func;
+       method_state state;
+};
+
+PyObject *method_call(method *m, PyObject *args, PyObject *kw) {
+       class_arg arg;
+       PyObject *result = NULL;
+
+       arg.method_call.method = m->state.method;
+       arg.method_call.args = args;
+       arg.method_call.result = &result;
+
+       if (m->func(CLASS_METHOD_CALL, m->state.cstate, &arg) == -1) {
+               return NULL;
+       }
+
+       if (result == NULL) {
+               Py_INCREF(Py_None);
+               result = Py_None;
+       }
+
+       return result;
+}
+
+PyTypeObject method_type = {
+       PyObject_HEAD_INIT(NULL)
+       0, /* ob_size */
+       "method", /* tp_name */
+       sizeof(method), /* tp_basicsize */
+       0, /* tp_itemsize */
+       0, /* tp_dealloc */
+       0, /* tp_print */
+       0, /* tp_getattr */
+       0, /* tp_setattr */
+       0, /* tp_compare */
+       0, /* tp_repr */
+       0, /* tp_as_number */
+       0, /* tp_as_sequence */
+       0, /* tp_as_mapping */
+       0, /* tp_hash */
+       method_call, /* tp_call */
+       0, /* tp_str */
+       0, /* tp_getattro */
+       0, /* tp_setattro */
+       0, /* tp_as_buffer */
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+       0, /* tp_doc */
+       0, /* tp_traverse */
+       0, /* tp_clear */
+       0, /* tp_richcompare */
+       0, /* tp_weaklistoffset */
+       0, /* tp_iter */
+       0, /* tp_iternext */
+       0, /* tp_methods */
+       0, /* tp_members */
+       0, /* tp_getset */
+       0, /* tp_base */
+       0, /* tp_dict */
+       0, /* tp_descr_get */
+       0, /* tp_descr_set */
+       0, /* tp_dictoffset */
+       0, /* tp_init */
+       0, /* tp_alloc */
+       PyType_GenericNew, /* tp_new */
+};
+
+struct wrapper {
+       PyObject_HEAD
+       class_state state;
+       class_func func;
+       PyObject *dict;
+};
+
+typedef struct wrapper wrapper;
+
+PyObject *wrapper_getattr(wrapper *w, PyObject *fld) {
+       class_arg arg;
+       PyObject *result;
+
+       /* First, try generic getattr */
+
+       result = PyObject_GenericGetAttr(w, fld);
+
+       if (result != NULL) {
+               return result;
+       }
+
+       /* Exception is set here */
+
+       arg.get.field = field_find(PyString_AsString(fld));
+       if (arg.get.field == -1) {
+               goto failout;
+       }
+
+       arg.get.is_method = 0;
+       arg.get.result = &result;
+
+       if (w->func(CLASS_GET_FIELD, &w->state, &arg) == -1) {
+               goto failout;
+       }
+
+       if (arg.get.is_method) {
+               result = PyObject_CallObject((PyObject *)&method_type, NULL);
+               method *m = (method *)result;
+               m->func = w->func;
+               m->state.method = arg.get.field;
+               m->state.cstate = &w->state;
+       }
+
+       PyErr_Clear();
+
+       return result;
+
+failout:
+
+       return NULL;
+}
+
+int wrapper_setattr(wrapper *w, PyObject *fld, PyObject *value) {
+       class_arg arg;
+
+       arg.set.field = field_find(PyString_AsString(fld));
+       if (arg.set.field == -1) {
+               goto failout;
+       }
+       arg.set.value = value;
+
+       if (w->func(CLASS_SET_FIELD, &w->state, &arg) == -1) {
+               goto failout;
+       }
+
+       return 0;
+
+failout:
+
+       return PyObject_GenericSetAttr(w, fld, value);
+}
+
+extern PyTypeObject wrapper_type;
+
+inline void *wrapper_key(wrapper *w) {
+       return w->state.vp;
+}
+
+int wrapper_compare(wrapper *a, wrapper *b) {
+       void *keya, *keyb;
+       if (PyObject_TypeCheck(b, &wrapper_type)) {
+               keya = wrapper_key(a);
+               keyb = wrapper_key(b);
+               if (keya < keyb) {
+                       return -1;
+               } else if (keya > keyb) {
+                       return 1;
+               } else {
+                       return 0;
+               }
+       } else {
+               /* If classes differ, compare classes */
+               return PyObject_Compare(a->ob_type, b->ob_type);
+       }
+}
+
+long wrapper_hash(wrapper *a) {
+       return (long)wrapper_key(a);
+}
+
+PyObject *wrapper_call(wrapper *w, PyObject *args, PyObject *kw) {
+       class_arg arg;
+       PyObject *result;
+
+       arg.call.args = args;
+       arg.call.result = &result;
+
+       if (w->func(CLASS_CALL, &w->state, &arg) == -1) {
+               return NULL;
+       }
+
+       return result;
+}
+
+PyObject *wrapper_str(wrapper *w) {
+       class_arg arg;
+       PyObject *result;
+       arg.str.result = &result;
+       if (w->func(CLASS_STR, &w->state, &arg) == -1) {
+               return PyString_FromFormat("Wrapper(0x%p)", w->state.vp);
+       } else {
+               return result;
+       }
+}
+
+PyTypeObject wrapper_type = {
+       PyObject_HEAD_INIT(NULL)
+       0, /* ob_size */
+       "wrapper", /* tp_name */
+       sizeof(wrapper), /* tp_basicsize */
+       0, /* tp_itemsize */
+       0, /* tp_dealloc */
+       0, /* tp_print */
+       0, /* tp_getattr */
+       0, /* tp_setattr */
+       wrapper_compare, /* tp_compare */
+       wrapper_str, /* tp_repr */
+       0, /* tp_as_number */
+       0, /* tp_as_sequence */
+       0, /* tp_as_mapping */
+       wrapper_hash, /* tp_hash */
+       wrapper_call, /* tp_call */
+       wrapper_str, /* tp_str */
+       wrapper_getattr, /* tp_getattro */
+       wrapper_setattr, /* tp_setattro */
+       0, /* tp_as_buffer */
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+       0, /* tp_doc */
+       0, /* tp_traverse */
+       0, /* tp_clear */
+       0, /* tp_richcompare */
+       0, /* tp_weaklistoffset */
+       0, /* tp_iter */
+       0, /* tp_iternext */
+       0, /* tp_methods */
+       0, /* tp_members */
+       0, /* tp_getset */
+       0, /* tp_base */
+       0, /* tp_dict */
+       0, /* tp_descr_get */
+       0, /* tp_descr_set */
+       offsetof(wrapper, dict), /* tp_dictoffset */
+       0, /* tp_init */
+       0, /* tp_alloc */
+       PyType_GenericNew, /* tp_new */
+};
+
+struct iterator {
+       PyObject_HEAD
+       iterator_func func;
+       iterator_state state;
+};
+
+typedef struct iterator iterator;
+
+PyObject *iterator_iter(struct iterator *it) {
+       Py_INCREF(it);
+       return (PyObject *)it;
+}
+
+PyObject *iterator_iternext(struct iterator *it) {
+       PyObject *ret;
+       iterator_arg arg;
+
+       if (it->func(ITERATOR_END, &it->state, NULL)) {
+               return NULL;
+       } else {
+               arg.get.result = &ret;
+               it->func(ITERATOR_GET, &it->state, &arg);
+               it->func(ITERATOR_FORWARD, &it->state, NULL);
+               return ret;
+       }
+}
+
+PyObject *iterator_getitem(struct iterator *it, PyObject* item) {
+       iterator_arg arg;
+       PyObject *ret;
+
+       if (PyInt_Check(item)) {
+               arg.subscript.index = PyInt_AS_LONG(item);
+               arg.subscript.result = &ret;
+               if (index < 0) { 
+                       return NULL;
+               } else if (it->func(ITERATOR_SUBSCRIPT, &it->state, &arg) != -1) {
+                       return ret;
+               } else {
+                       return NULL;
+               }
+       } else {
+               return NULL;
+       }
+}
+
+int iterator_setitem(struct iterator *it, PyObject *item, PyObject *value) {
+       iterator_arg arg;
+       if (PyInt_Check(item)) {
+               arg.setitem.index = PyInt_AS_LONG(item);
+               arg.setitem.value = value;
+               if (it->func(ITERATOR_SETITEM, &it->state, &arg) != -1) {
+                       return 0;
+               } else {
+                       return -1;
+               }
+       } else {
+               return -1;
+       }
+}
+
+int iterator_length(struct iterator *it) {
+       iterator_arg arg;
+       if (it->func(ITERATOR_LENGTH, &it->state, &arg) == -1) {
+               return -1;
+       } else {
+               return arg.length;
+       }
+}
+
+PyMappingMethods iterator_mapping = {
+       iterator_length,
+       iterator_getitem,
+       iterator_setitem
+};
+
+PyTypeObject iterator_type = {
+       PyObject_HEAD_INIT(NULL)
+       0, /* ob_size */
+       "iterator", /* tp_name */
+       sizeof(iterator), /* tp_basicsize */
+       0, /* tp_itemsize */
+       0, /* tp_dealloc */
+       0, /* tp_print */
+       0, /* tp_getattr */
+       0, /* tp_setattr */
+       0, /* tp_compare */
+       0, /* tp_repr */
+       0, /* tp_as_number */
+       0, /* tp_as_sequence */
+       &iterator_mapping, /* tp_as_mapping */
+       0, /* tp_hash */
+       0, /* tp_call */
+       0, /* tp_str */
+       0, /* tp_getattro */
+       0, /* tp_setattro */
+       0, /* tp_as_buffer */
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+       0, /* tp_doc */
+       0, /* tp_traverse */
+       0, /* tp_clear */
+       0, /* tp_richcompare */
+       0, /* tp_weaklistoffset */
+       iterator_iter, /* tp_iter */
+       iterator_iternext, /* tp_iternext */
+       0, /* tp_methods */
+       0, /* tp_members */
+       0, /* tp_getset */
+       0, /* tp_base */
+       0, /* tp_dict */
+       0, /* tp_descr_get */
+       0, /* tp_descr_set */
+       0, /* tp_dictoffset */
+       0, /* tp_init */
+       0, /* tp_alloc */
+       PyType_GenericNew, /* tp_new */
+};
+
+/*
+ * Utils
+ */
+
+int set_s4(s4 *p, PyObject *o) {
+       if (PyInt_Check(o)) {
+               *p = PyInt_AsLong(o);   
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+int set_s4_flag(s4 *p, s4 flag, PyObject *o) {
+       if (o == Py_True) {
+               *p |= flag;
+               return 0;
+       } else if (o == Py_False) {
+               *p &= ~flag;
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+int get_int(PyObject **o, int p) {
+       *o = PyInt_FromLong(p);
+       return 0;
+}
+
+int get_string(PyObject **o, const char *str) {
+       *o = PyString_FromString(str);
+       return 0;
+}
+
+int get_obj(PyObject **res, class_func f, root_state *root, void *p) {
+       if (p == NULL) {
+               return get_none(res);
+       } else {
+               PyObject *key = PyInt_FromLong((long)p);
+               PyObject *o = PyDict_GetItem(root->object_cache, key);
+               if (o == NULL) {
+                       o = PyObject_CallObject((PyObject *)&wrapper_type, NULL);
+                       struct wrapper * w = (struct wrapper *)o;
+                       w->func = f;
+                       w->state.root = root;
+                       w->state.vp = p;
+                       PyDict_SetItem(root->object_cache, key, o);
+               } else {
+                       Py_INCREF(o);
+               }
+               *res = o;
+               return 0;
+       }
+}
+
+int get_true(PyObject **res) {
+       Py_INCREF(Py_True);
+       *res = Py_True;
+       return 0;
+}
+
+int get_false(PyObject **res) {
+       Py_INCREF(Py_False);
+       *res = Py_False;
+       return 0;
+}
+
+int get_none(PyObject **res) {
+       Py_INCREF(Py_None);
+       *res = Py_None;
+       return 0;
+}
+
+int get_bool(PyObject **res, int cond) {
+       return cond ? get_true(res) : get_false(res);
+}
+       
+int get_iter(PyObject **res, iterator_func f, root_state *root, void *p) {
+       PyObject *o = PyObject_CallObject((PyObject *)&iterator_type, NULL);
+       struct iterator * it = (struct iterator *)o;
+       it->func = f;
+       it->state.root = root;
+       it->state.data = p;
+       f(ITERATOR_INIT, &it->state, NULL);
+       *res = o;
+       return 0;
+}
+
+int add_const(PyObject *module, const char *name, int value) {
+       PyObject *pyvalue = PyInt_FromLong(value);
+       if (pyvalue != NULL) {
+               PyModule_AddObject(module, name, pyvalue);
+       }
+}
+
+void *get_vp(PyObject *o, class_func func) {
+       if (o->ob_type == &wrapper_type) {
+               if (((wrapper *)o)->func == func) {
+                       return ((wrapper *)o)->state.vp;
+               }
+       }
+       return NULL;
+}
+
+/*
+ * Implemnetation
+ */
+
+CLASS_FUNC(basicblock_func);
+CLASS_FUNC(classinfo_func);
+CLASS_FUNC(constant_classref_func);
+CLASS_FUNC(methodinfo_func);
+CLASS_FUNC(varinfo_func);
+
+int get_varinfo(PyObject **res, root_state *root, s4 index) {
+       return get_obj(res, varinfo_func, root, root->jd->var + index);
+}
+
+static inline int instruction_opcode_ex(instruction *iptr) {
+       if (iptr->opc == ICMD_BUILTIN) {
+               return iptr->sx.s23.s3.bte->opcode;
+       } else {
+               return iptr->opc;
+       }
+}
+
+ITERATOR_FUNC(call_args_iter_func) {
+       instruction *iptr = (instruction *)state->data;
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = iptr->sx.s23.s2.args;
+                       return 0;
+               case ITERATOR_LENGTH:
+                       arg->length = iptr->s1.argcount;
+                       return 0;
+               case ITERATOR_GET:
+                       /* return get_int(arg->get.result, *(int *)state->pos);*/
+                       return get_varinfo(arg->get.result, state->root, *(int *)state->pos);
+               case ITERATOR_END:
+                       return state->pos == iptr->sx.s23.s2.args + iptr->s1.argcount;
+               case ITERATOR_FORWARD:
+                       state->pos = ((int *)state->pos) + 1;
+                       return 0;
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(iptr->s1.argcount);
+                       return get_int(arg->subscript.result, iptr->sx.s23.s2.args[arg->subscript.index]);
+               case ITERATOR_SETITEM:
+                       ITERATOR_SETITEM_CHECK(iptr->s1.argcount);
+                       return set_s4(iptr->sx.s23.s2.args + arg->setitem.index, arg->setitem.value);
+       }
+       return -1;
+}
+
+CLASS_FUNC(fieldinfo_func) {
+       fieldinfo *fi = (fieldinfo *)state->vp;
+
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_TYPE:
+                                       return get_int(arg->get.result, fi->type);
+                               case F_OFFSET:
+                                       return get_int(arg->get.result, fi->offset);
+                               case F_NAME:
+                                       return get_string(arg->get.result, fi->name->text);
+                               case F_KLASS:
+                                       return get_obj(arg->get.result, classinfo_func, state->root, fi->clazz);
+                       }
+       }
+
+       return -1;
+}
+
+CLASS_FUNC(unresolved_field_func) {
+       unresolved_field *uf = (unresolved_field *)state->vp;
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_NAME:
+                                       return get_string(arg->get.result, uf->fieldref->name->text);
+                               case F_CLASSREF:
+                                       if (IS_FMIREF_RESOLVED(uf->fieldref)) {
+                                               return get_none(arg->get.result);
+                                       } else {
+                                               return get_obj(arg->get.result, constant_classref_func, state->root, uf->fieldref->p.classref);
+                                       }
+                               case F_DESCRIPTOR:
+                                       return get_string(arg->get.result, uf->fieldref->descriptor->text);
+                               case F_FIELD:
+                                       if (IS_FMIREF_RESOLVED(uf->fieldref)) {
+                                               return get_obj(arg->get.result, fieldinfo_func, state->root, uf->fieldref->p.field);
+                                       } else {
+                                               return get_none(arg->get.result);
+                                       }
+                               case F_IS_UNRESOLVED:
+                                       return get_bool(arg->get.result, !IS_FMIREF_RESOLVED(uf->fieldref));
+                       }
+       }
+       return -1;
+}
+
+static inline int instruction_num_s(instruction *iptr) {
+       switch (icmd_table[iptr->opc].dataflow) {
+               case DF_1_TO_0:
+               case DF_1_TO_1:
+               case DF_COPY:
+               case DF_MOVE:
+                       return 1;
+               case DF_2_TO_0:
+               case DF_2_TO_1:
+                       return 2;
+               case DF_3_TO_0:
+               case DF_3_TO_1:
+                       return 3;
+               default:
+                       return 0;
+       }
+}
+
+static inline s4 *instruction_get_s(instruction *iptr, int s) {
+       switch (s) {
+               case 0:
+                       return &(iptr->s1.varindex);
+               case 1:
+                       return &(iptr->sx.s23.s2.varindex);
+               case 2:
+                       return &(iptr->sx.s23.s3.varindex);
+       }
+}
+
+ITERATOR_FUNC(s_iter_func) {
+       instruction *iptr = (instruction *)state->data;
+       uintptr_t pos = (uintptr_t)state->pos;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = (void *)0;
+                       return 0;
+               case ITERATOR_LENGTH:
+                       arg->length = instruction_num_s(iptr);
+                       return 0;
+               case ITERATOR_GET:
+                       return get_varinfo(arg->get.result, state->root, 
+                               *instruction_get_s(iptr, pos));
+               case ITERATOR_END:
+                       return pos == instruction_num_s(iptr);
+               case ITERATOR_FORWARD:
+                       state->pos = (void *)(pos + 1);
+                       return 0;
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(3);
+                       return get_varinfo(arg->subscript.result, state->root, 
+                               *instruction_get_s(iptr, arg->subscript.index));
+               case ITERATOR_SETITEM:
+                       ITERATOR_SETITEM_CHECK(3);
+                       return set_s4(instruction_get_s(iptr, arg->setitem.index), 
+                               arg->setitem.value);
+       }
+       return -1;
+}
+
+CLASS_FUNC(instruction_func) {
+
+       instruction *iptr = (instruction *)state->vp;
+
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_OPCODE:
+                                       return get_int(arg->get.result, iptr->opc);
+                               case F_OPCODE_EX:
+                                       return get_int(arg->get.result, instruction_opcode_ex(iptr));
+                               case F_NAME:
+                                       return get_string(arg->get.result, icmd_table[iptr->opc].name);
+                               case F_NAME_EX:
+                                       return get_string(arg->get.result, icmd_table[instruction_opcode_ex(iptr)].name);
+                               case F_S:
+                                       return get_iter(arg->get.result, s_iter_func, state->root, iptr);       
+                               case F_DST:
+                                       return get_varinfo(arg->get.result, state->root, 
+                                               iptr->dst.varindex);
+                               case F_HAS_DST:
+                                       if (
+                                               (icmd_table[iptr->opc].dataflow == DF_INVOKE) ||
+                                               (icmd_table[iptr->opc].dataflow == DF_BUILTIN)
+                                       ) {
+                                               return get_bool(
+                                                       arg->get.result,
+                                                       instruction_call_site(iptr)->returntype.type != TYPE_VOID
+                                               );
+                                       }
+                                       return get_bool(arg->get.result, icmd_table[iptr->opc].dataflow >= DF_DST_BASE);
+                               case F_CALL_RETURN_TYPE:
+                                       return get_int(arg->get.result, instruction_call_site(iptr)->returntype.type);
+                               case F_CALL_ARGS:
+                                       return get_iter(arg->get.result, call_args_iter_func, state->root, iptr);       
+                               case F_HAS_CALL_ARGS:
+                                       return get_bool(arg->get.result,
+                                               icmd_table[iptr->opc].dataflow == DF_INVOKE ||
+                                               icmd_table[iptr->opc].dataflow == DF_BUILTIN ||
+                                               icmd_table[iptr->opc].dataflow == DF_N_TO_1
+                                       );
+                               case F_IS_UNRESOLVED:
+                                       return get_bool(arg->get.result, iptr->flags.bits & INS_FLAG_UNRESOLVED);
+                               case F_IS_CLASS_CONSTANT:
+                                       return get_bool(arg->get.result, iptr->flags.bits & INS_FLAG_CLASS);
+                               case F_KLASS:
+                                       return get_obj(arg->get.result, classinfo_func, state->root, iptr->sx.val.c.cls);
+                               case F_CLASSREF:
+                                       return get_obj(arg->get.result, constant_classref_func, state->root, iptr->sx.val.c.ref);
+                               case F_LOCAL_METHODINFO:
+                                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                                               return get_none(arg->get.result);
+                                       } else {        
+                                               return get_obj(arg->get.result, methodinfo_func, 
+                                                       state->root, iptr->sx.s23.s3.fmiref->p.method);
+                                       }
+                               case F_FIELD_TYPE:
+                                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                                               return get_int(arg->get.result,
+                                                       iptr->sx.s23.s3.uf->fieldref->parseddesc.fd->type);
+                                       } else {
+                                               return get_int(arg->get.result,
+                                                       iptr->sx.s23.s3.fmiref->p.field->type);
+                                       }
+                               case F_FIELD:
+                                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                                               return get_none(arg->get.result);
+                                       } else {
+                                               return get_obj(arg->get.result, fieldinfo_func, state->root, iptr->sx.s23.s3.fmiref->p.field);
+                                       }
+                                       break;
+                               case F_UNRESOLVED_FIELD:
+                                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                                               return get_obj(arg->get.result, unresolved_field_func, state->root, iptr->sx.s23.s3.uf);
+                                       } else {
+                                               return get_none(arg->get.result);
+                                       }
+                                       break;
+                               case F_LINE:
+                                       return get_int(arg->get.result, iptr->line);
+                               case F_PEI:
+                                       return get_bool(arg->get.result, icmd_table[iptr->opc].flags & ICMDTABLE_PEI);
+                               case F_PEI_EX:
+                                       return get_bool(arg->get.result, icmd_table[instruction_opcode_ex(iptr)].flags & ICMDTABLE_PEI);
+                               case F_DATA_FLOW:
+                                       return get_int(arg->get.result, icmd_table[iptr->opc].dataflow);
+                               case F_DATA_FLOW_EX:
+                                       return get_int(arg->get.result, icmd_table[instruction_opcode_ex(iptr)].dataflow);
+                               case F_CONTROL_FLOW:
+                                       return get_int(arg->get.result, icmd_table[iptr->opc].controlflow);
+                               case F_CONTROL_FLOW_EX:
+                                       return get_int(arg->get.result, icmd_table[instruction_opcode_ex(iptr)].controlflow);
+                               case F_SHOW:
+                                       arg->get.is_method = 1;
+                                       return 0;
+                       }
+               case CLASS_SET_FIELD:
+                       switch (arg->set.field) {
+                               case F_DST:
+                                       return set_s4(&(iptr->dst.varindex), arg->set.value);
+                               case F_OPCODE:
+                                       return set_s4(&(iptr->opc), arg->set.value);
+                       }
+               case CLASS_METHOD_CALL:
+                       switch (arg->method_call.method) {
+                               case F_SHOW:
+                                       show_icmd(state->root->jd, iptr, 1, SHOW_CFG);
+                                       return 0;
+                       }
+       }
+
+       return -1;
+}
+
+ITERATOR_FUNC(predecessors_iter_func) {
+       basicblock *bptr = (basicblock *)state->data;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = bptr->predecessors;
+                       return 0;
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, basicblock_func, state->root, *(basicblock **)state->pos);
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(bptr->predecessorcount);
+                       return get_obj(arg->subscript.result, basicblock_func, state->root, 
+                               bptr->predecessors[arg->subscript.index]);
+               case ITERATOR_END:
+                       return 
+                               (state->pos == (bptr->predecessors + bptr->predecessorcount)) ||
+                               (bptr->predecessorcount < 0);
+               case ITERATOR_FORWARD:
+                       state->pos = ((basicblock **)state->pos) + 1;
+                       return 0;
+               case ITERATOR_LENGTH:
+                       arg->length = bptr->predecessorcount;
+                       return 0;
+       }
+
+       return -1;
+}
+
+ITERATOR_FUNC(successors_iter_func) {
+       basicblock *bptr = (basicblock *)state->data;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = bptr->successors;
+                       return 0;
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, basicblock_func, state->root, *(basicblock **)state->pos);
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(bptr->successorcount);
+                       return get_obj(arg->subscript.result, basicblock_func, state->root, 
+                               bptr->successors[arg->subscript.index]);
+               case ITERATOR_END:
+                       return 
+                               (state->pos == (bptr->successors + bptr->successorcount)) || 
+                               (bptr->successorcount < 0);
+               case ITERATOR_FORWARD:
+                       state->pos = ((basicblock **)state->pos) + 1;
+                       return 0;
+               case ITERATOR_LENGTH:
+                       arg->length = bptr->successorcount;
+                       return 0;
+       }
+
+       return  -1;
+}
+
+ITERATOR_FUNC(dom_successors_iter_func) {
+       basicblock *bptr = (basicblock *)state->data;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = bptr->domsuccessors;
+                       return 0;
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, basicblock_func, state->root, *(basicblock **)state->pos);
+               case ITERATOR_END:
+                       return (state->pos == (bptr->domsuccessors + bptr->domsuccessorcount));
+               case ITERATOR_FORWARD:
+                       state->pos = ((basicblock **)state->pos) + 1;
+                       return 0;
+               case ITERATOR_LENGTH:
+                       arg->length = bptr->domsuccessorcount;
+                       return 0;
+       }
+
+       return  -1;
+}
+
+ITERATOR_FUNC(dominance_frontier_iter_func) {
+       basicblock *bptr = (basicblock *)state->data;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = bptr->domfrontier;
+                       return 0;
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, basicblock_func, state->root, *(basicblock **)state->pos);
+               case ITERATOR_END:
+                       return (state->pos == (bptr->domfrontier + bptr->domfrontiercount));
+               case ITERATOR_FORWARD:
+                       state->pos = ((basicblock **)state->pos) + 1;
+                       return 0;
+       }
+
+       return  -1;
+}
+
+ITERATOR_FUNC(instruction_iter_func) {
+       basicblock *bptr = (basicblock *)state->data;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = bptr->iinstr;
+                       return 0;
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, instruction_func, state->root, state->pos);
+               case ITERATOR_FORWARD:
+                       state->pos = ((instruction *)state->pos) + 1;
+                       return 0;
+               case ITERATOR_END:
+                       return state->pos == (bptr->iinstr + bptr->icount);
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(bptr->icount);
+                       return get_obj(arg->subscript.result, instruction_func, state->root, bptr->iinstr + arg->subscript.index);
+               case ITERATOR_LENGTH:
+                       arg->length = bptr->icount;
+                       return 0;
+       }
+       return -1;
+}
+
+ITERATOR_FUNC(in_vars_iter_func) {
+       basicblock *bptr = (basicblock *)state->data;
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = bptr->invars;
+                       return 0;
+               case ITERATOR_GET:
+                       return get_varinfo(arg->get.result, state->root, *(s4 *)(state->pos));
+               case ITERATOR_FORWARD:
+                       state->pos = ((s4 *)state->pos) + 1;
+                       return 0;
+               case ITERATOR_END:
+                       return state->pos == (bptr->invars + bptr->indepth);
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(bptr->icount);
+                       return get_varinfo(arg->subscript.result, state->root, bptr->invars[arg->subscript.index]);
+               case ITERATOR_LENGTH:
+                       arg->length = bptr->indepth;
+                       return 0;
+       }
+}
+
+ITERATOR_FUNC(out_vars_iter_func) {
+       basicblock *bptr = (basicblock *)state->data;
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = bptr->outvars;
+                       return 0;
+               case ITERATOR_GET:
+                       return get_varinfo(arg->get.result, state->root, *(s4 *)(state->pos));
+               case ITERATOR_FORWARD:
+                       state->pos = ((s4 *)state->pos) + 1;
+                       return 0;
+               case ITERATOR_END:
+                       return state->pos == (bptr->outvars + bptr->outdepth);
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(bptr->icount);
+                       return get_varinfo(arg->subscript.result, state->root, bptr->outvars[arg->subscript.index]);
+               case ITERATOR_LENGTH:
+                       arg->length = bptr->outdepth;
+                       return 0;
+       }
+}
+
+CLASS_FUNC(basicblock_func) {
+       basicblock *bptr = (basicblock *)state->vp;
+
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_INSTRUCTIONS:
+                                       return get_iter(arg->get.result, instruction_iter_func, state->root, bptr);
+                               case F_NR:
+                                       return get_int(arg->get.result, bptr->nr);
+                               case F_PREDECESSORS:
+                                       return get_iter(arg->get.result, predecessors_iter_func, state->root, bptr);
+                               case F_SUCCESSORS:
+                                       return get_iter(arg->get.result, successors_iter_func, state->root, bptr);
+                               case F_REACHED:
+                                       return get_bool(arg->get.result, bptr->flags >= BBREACHED);
+                               case F_EXCEPTION_HANDLER:
+                                       return get_bool(arg->get.result, bptr->type == BBTYPE_EXH);
+                               case F_IDOM:
+                                       return get_obj(arg->get.result, basicblock_func, state->root, bptr->idom);
+                               case F_DOM_SUCCESSORS:
+                                       return get_iter(arg->get.result, dom_successors_iter_func, state->root, bptr);
+                               case F_DOMINANCE_FRONTIER:
+                                       return get_iter(arg->get.result, dominance_frontier_iter_func, state->root, bptr);
+                               case F_IN_VARS:
+                                       return get_iter(arg->get.result, in_vars_iter_func, state->root, bptr);
+                               case F_OUT_VARS:
+                                       return get_iter(arg->get.result, in_vars_iter_func, state->root, bptr);
+                               case F_SHOW:
+                                       arg->get.is_method = 1;
+                                       return 0;
+                       }
+               case CLASS_STR:
+                       *arg->str.result = PyString_FromFormat("BB_%d", bptr->nr);
+                       return 0;
+               case CLASS_METHOD_CALL:
+                       switch (arg->method_call.method) {      
+                               case F_SHOW:
+                                       show_basicblock(state->root->jd, bptr, SHOW_CFG);
+                                       return 0;
+                       }
+       }
+
+       return -1;
+}
+
+ITERATOR_FUNC(basicblocks_iter_func) {
+       jitdata *jd = (jitdata *)state->data;
+       basicblock *bb;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = jd->basicblocks;
+                       return 0;       
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, basicblock_func, state->root, state->pos);
+               case ITERATOR_FORWARD:
+                       state->pos = ((basicblock *)(state->pos))->next;
+                       return 0;
+               case ITERATOR_END:
+                       return (state->pos == NULL);
+               case ITERATOR_SUBSCRIPT:
+                       for (bb = jd->basicblocks; bb != NULL; bb = bb->next) {
+                               if (bb->nr == arg->subscript.index) {
+                                       return get_obj(arg->subscript.result, basicblock_func, state->root, bb);
+                               }
+                       }
+                       return -1;
+       }
+
+       return -1;
+}
+
+CLASS_FUNC(classinfo_func) {
+       classinfo *c = (classinfo *)state->vp;
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_NAME:
+                                       return get_string(arg->get.result, c->name->text);
+                       }
+       }
+       return -1;
+}
+
+CLASS_FUNC(constant_classref_func) {
+       constant_classref *cr = (constant_classref *)state->vp;
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_NAME:
+                                       return get_string(arg->get.result, cr->name->text);
+                       }
+       }
+       return -1;
+}
+
+ITERATOR_FUNC(param_types_iter_func) {
+       methodinfo *m = (methodinfo *)state->data;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = m->parseddesc->paramtypes;
+                       return 0;
+               case ITERATOR_END:
+                       return state->pos == (m->parseddesc->paramtypes + m->parseddesc->paramcount);
+               case ITERATOR_FORWARD:
+                       state->pos = ((typedesc *)state->pos) + 1;
+                       return 0;
+               case ITERATOR_GET:
+                       return get_int(arg->get.result, ((typedesc *)state->pos)->type);
+               case ITERATOR_LENGTH:
+                       arg->length = m->parseddesc->paramcount;
+                       return 0;
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(m->parseddesc->paramcount);
+                       return get_int(arg->subscript.result, m->parseddesc->paramtypes[arg->subscript.index].type);
+       }
+
+       return -1;
+}
+
+ITERATOR_FUNC(params_iter_func) {
+
+       methodinfo *m = (methodinfo *)state->data;
+       /* param counter */
+       uint16_t p = (uintptr_t)(state->pos) & 0xFFFF;
+       /* local counter */
+       uint16_t l = ((uintptr_t)(state->pos) >> 16) & 0xFFFF;
+
+       int varnum;
+
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = (void *)0;
+                       return 0;
+               case ITERATOR_END:
+                       return p == m->parseddesc->paramcount;
+               case ITERATOR_FORWARD:
+                       l += (IS_2_WORD_TYPE(m->parseddesc->paramtypes[p].type) ? 2 : 1);
+                       p += 1;
+                       state->pos = (void *)(uintptr_t)((l << 16) | p);
+                       return 0;
+               case ITERATOR_GET:
+                       varnum = state->root->jd->local_map[(5 * l) + m->parseddesc->paramtypes[p].type];
+                       return get_varinfo(arg->get.result, state->root, varnum);
+       }
+               
+       return -1;
+}
+
+CLASS_FUNC(methodinfo_func) {
+       methodinfo *m = (methodinfo *)state->vp;
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_NAME:
+                                       return get_string(arg->get.result, m->name->text);
+                               case F_KLASS:
+                                       return get_obj(arg->get.result, classinfo_func, state->root, m->clazz);
+                               case F_PARAM_TYPES:
+                                       return get_iter(arg->get.result, param_types_iter_func, state->root, m);
+                               case F_PARAMS:
+                                       if (m == state->root->jd->m) {
+                                               return get_iter(arg->get.result, params_iter_func, state->root, m);
+                                       } else {
+                                               return get_none(arg->get.result);
+                                       }
+                               case F_RETURN_TYPE:
+                                       return get_int(arg->get.result, m->parseddesc->returntype.type);
+                               case F_SHOW:
+                                       if (m == state->root->jd->m) {
+                                               arg->get.is_method = 1;
+                                               return 0;
+                                       }
+                       }
+               case CLASS_METHOD_CALL:
+                       switch (arg->method_call.method) {
+                               case F_SHOW:
+                                       show_method(state->root->jd, SHOW_CFG);
+                                       return 0;
+                       }
+       }
+       return -1;
+}
+
+static inline PyObject *varinfo_str(jitdata *jd, int index, varinfo *v) {
+       char type = '?';
+       char kind = '?';
+
+       switch (v->type) {
+               case TYPE_INT: type = 'i'; break;
+               case TYPE_LNG: type = 'l'; break;
+               case TYPE_FLT: type = 'f'; break;
+               case TYPE_DBL: type = 'd'; break;
+               case TYPE_ADR: type = 'a'; break;
+               case TYPE_RET: type = 'r'; break;
+               default:       type = '?';
+       }
+
+       if (index < jd->localcount) {
+               kind = 'L';
+       }
+       else {
+               if (v->flags & PREALLOC) {
+                       kind = 'A';
+                       if (v->flags & INOUT) {
+                               /* PREALLOC is used to avoid allocation of TYPE_RET */
+                               if (v->type == TYPE_RET)
+                                       kind = 'i';
+                       }
+               }
+               else if (v->flags & INOUT)
+                       kind = 'I';
+               else
+                       kind = 'T';
+       }
+
+       if (index == -1) {
+               return PyString_FromString("UNUSED");
+       } else {
+               return PyString_FromFormat("%c%c%d", kind, type, index);
+       }
+}
+
+
+CLASS_FUNC(varinfo_func) {
+       jitdata *jd = state->root->jd;
+       varinfo *var = (varinfo *)state->vp;
+       int index = var - jd->var;
+
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_TYPE:
+                                       return get_int(arg->get.result, var->type);
+                               case F_IS_LOCAL:
+                                       return get_bool(arg->get.result, index < jd->localcount);
+                               case F_IS_PREALLOCATED:
+                                       return get_bool(
+                                               arg->get.result, 
+                                               (index >= jd->localcount) && (var->flags & PREALLOC)
+                                       );
+                               case F_IS_INOUT:
+                                       return get_bool(
+                                               arg->get.result, 
+                                               (index >= jd->localcount) && !(var->flags & PREALLOC) && (var->flags & INOUT)
+                                       );
+                               case F_IS_TEMPORARY:
+                                       return get_bool(
+                                               arg->get.result, 
+                                               (index >= jd->localcount) && !(var->flags & PREALLOC) && !(var->flags & INOUT)
+                                       );
+                               case F_IS_SAVED:
+                                       return get_bool(arg->get.result, var->flags & SAVEDVAR);
+                               case F_INDEX:
+                                       return get_int(arg->get.result, index);
+                               case F_UNUSED:
+                                       return get_bool(arg->get.result, index == UNUSED);
+                               case F_REGISTER_OFFSET:
+                                       return get_int(arg->get.result, var->vv.regoff);
+                               case F_IS_IN_MEMORY:
+                                       return get_bool(arg->get.result, var->flags & INMEMORY);
+                       }
+               case CLASS_SET_FIELD:
+                       switch (arg->set.field) {
+                               case F_TYPE:
+                                       return set_s4(&(var->type), arg->set.value);
+                               case F_IS_LOCAL:
+                                       if (PyBool_Check(arg->set.value)) {
+                                               if (arg->set.value == Py_True) {
+                                                       if (jd->localcount < (index + 1)) {
+                                                               jd->localcount = (index + 1);
+                                                       }
+                                               } else {
+                                                       if (jd->localcount > (index)) {
+                                                               jd->localcount = index;
+                                                       }
+                                               }
+                                               return 0;
+                                       }
+                                       break;
+                               case F_IS_SAVED:
+                                       if (PyBool_Check(arg->set.value)) {
+                                               if (arg->set.value == Py_True) {
+                                                       var->flags |= SAVEDVAR;
+                                               } else {
+                                                       var->flags &= ~SAVEDVAR;
+                                               }
+                                               return 0;
+                                       }
+                                       break;
+                               case F_IS_PREALLOCATED:
+                                       if (arg->set.value == Py_True) {
+                                               var->flags |= PREALLOC;
+                                               return 0;
+                                       }
+                                       break;
+                               case F_IS_INOUT:
+                                       if (arg->set.value == Py_True) {
+                                               var->flags &= ~PREALLOC;
+                                               var->flags |= INOUT;
+                                               return 0;
+                                       }
+                                       break;
+                               case F_IS_TEMPORARY:
+                                       if (arg->set.value == Py_True) {
+                                               var->flags &= ~PREALLOC;
+                                               var->flags &= ~INOUT;
+                                               return 0;
+                                       }
+                                       break;
+                               case F_REGISTER_OFFSET:
+                                       return set_s4(&(var->vv.regoff), arg->set.value);
+                               case F_IS_IN_MEMORY:
+                                       return set_s4_flags(&(var->flags), INMEMORY, arg->set.value);
+                       }
+               case CLASS_STR:
+                       *arg->str.result = varinfo_str(jd, index, var);
+                       return 0;
+
+       }
+       return -1;
+}
+
+int vars_grow(jitdata *jd, unsigned size) {
+       int newcount;
+       if (size > 16 * 1024) {
+               return 0;
+       }
+       if (size >= jd->varcount) {
+               newcount = 2 * jd->varcount;
+               if (size > newcount) {
+                       newcount = size;
+               }
+               jd->var = DMREALLOC(jd->var, varinfo, jd->varcount, newcount);
+               MZERO(jd->var + jd->varcount, varinfo, (newcount - jd->varcount));
+               jd->varcount = newcount;
+       }
+       return 1;
+}
+
+ITERATOR_FUNC(vars_iter_func) {
+       jitdata *jd = (jitdata *)state->data;
+       void *vp;
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = jd->var;
+                       return 0;
+               case ITERATOR_FORWARD:
+                       state->pos = ((varinfo *)state->pos) + 1;
+                       return 0;
+               case ITERATOR_END:
+                       return state->pos == (jd->var + jd->vartop);
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, varinfo_func, state->root, state->pos);
+               case ITERATOR_LENGTH:
+                       arg->length = jd->vartop;
+                       return 0;
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(jd->vartop);
+                       return get_obj(arg->subscript.result, varinfo_func, 
+                               state->root, jd->var + arg->subscript.index);
+               case ITERATOR_SETITEM:
+                       ITERATOR_SETITEM_CHECK(jd->vartop);
+                       vp = get_vp(arg->setitem.value, varinfo_func);
+                       if (vp) {
+                               jd->var[arg->setitem.index] = *(varinfo *)vp;
+                               return 0;
+                       }
+
+       }
+       return -1;
+}
+
+ITERATOR_FUNC(map_2_iter_func) {
+       int *arr = (int *)state->data;
+       switch (op) {
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(5);
+                       return get_int(arg->subscript.result, arr[arg->subscript.index]);
+               case ITERATOR_LENGTH:
+                       arg->length = 5;
+                       return 0;
+               case ITERATOR_SETITEM:
+                       ITERATOR_SETITEM_CHECK(5);
+                       return set_s4(arr + arg->subscript.index, arg->setitem.value);
+       }
+       return -1;
+}
+
+ITERATOR_FUNC(local_map_iter_func) {
+       jitdata *jd = (jitdata *)state->data;
+       switch (op) {
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(jd->maxlocals);
+                       return get_iter(arg->subscript.result, map_2_iter_func, state->root,
+                               jd->local_map + (5 * arg->subscript.index));
+       }
+       return -1;
+}
+
+ITERATOR_FUNC(interface_map_iter_func) {
+       jitdata *jd = (jitdata *)state->data;
+       switch (op) {
+               case ITERATOR_SUBSCRIPT:
+                       ITERATOR_SUBSCRIPT_CHECK(jd->maxinterfaces);
+                       return get_iter(arg->subscript.result, map_2_iter_func, state->root,
+                               jd->interface_map + (5 * arg->subscript.index));
+       }
+       return -1;
+}
+
+ITERATOR_FUNC(exception_entry_basic_blocks_iter_func) {
+       exception_entry *ee = (exception_entry *)state->data;
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = ee->start;
+                       return 0;
+               case ITERATOR_FORWARD:
+                       state->pos = ((basicblock *)state->pos)->next;
+                       return 0;
+               case ITERATOR_END:
+                       return state->pos == ee->end;
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, basicblock_func, state->root, state->pos);
+       }
+       return -1;
+}
+
+CLASS_FUNC(exception_entry_func) {
+       exception_entry *ee = (exception_entry *)state->vp;
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_START:
+                                       return get_obj(arg->get.result, basicblock_func, state->root, ee->start);
+                               case F_END:
+                                       return get_obj(arg->get.result, basicblock_func, state->root, ee->end);
+                               case F_HANDLER:
+                                       return get_obj(arg->get.result, basicblock_func, state->root, ee->handler);
+                               case F_BASIC_BLOCKS:
+                                       return get_iter(arg->get.result, exception_entry_basic_blocks_iter_func, state->root, ee);
+                       }
+                       break;
+       }
+       return -1;
+}
+
+ITERATOR_FUNC(exception_table_iter_func) {
+       jitdata *jd = (jitdata *)state->data;
+       switch (op) {
+               case ITERATOR_INIT:
+                       state->pos = jd->exceptiontable;
+                       return 0;
+               case ITERATOR_FORWARD:
+                       state->pos = ((exception_entry *)state->pos)->down;
+                       return 0;
+               case ITERATOR_END:
+                       return state->pos == NULL;
+               case ITERATOR_GET:
+                       return get_obj(arg->get.result, exception_entry_func, state->root, state->pos);
+       }
+       return -1;
+}
+
+CLASS_FUNC(jd_func) {
+       jitdata *jd = (jitdata *)state->vp;
+
+       switch (op) {
+               case CLASS_GET_FIELD:
+                       switch (arg->get.field) {
+                               case F_BASIC_BLOCKS:
+                                       return get_iter(arg->get.result, basicblocks_iter_func, state->root, jd);
+                               case F_METHOD:
+                                       return get_obj(arg->get.result, methodinfo_func, state->root, jd->m);
+                               case F_VARS:
+                                       return get_iter(arg->get.result, vars_iter_func, state->root, jd);
+                               case F_LOCAL_MAP:
+                                       return get_iter(arg->get.result, local_map_iter_func, state->root, jd);
+                               case F_INTERFACE_MAP:
+                                       return get_iter(arg->get.result, interface_map_iter_func, state->root, jd);
+                               case F_EXCEPTION_TABLE:
+                                       return get_iter(arg->get.result, exception_table_iter_func, state->root, jd);
+                       }
+       }
+
+       return -1;
+}
+
+void constants(PyObject *m) {
+       char buf[32];
+       char *pos;
+       int i;
+
+       /* icmds */
+
+       for (i = 0; i < sizeof(icmd_table) / sizeof(icmd_table[0]); ++i) {
+               snprintf(buf, sizeof(buf), "ICMD_%s", icmd_table[i].name);
+               pos = strchr(buf, ' ');
+               if (pos != NULL) {
+                       *pos = '\0';
+               }
+               add_const(m, buf, i);
+       }
+
+#      define c(x) add_const(m, #x, x)
+
+       /* types */
+
+       c(TYPE_INT);
+       c(TYPE_LNG);
+       c(TYPE_ADR);
+       c(TYPE_FLT);
+       c(TYPE_DBL);
+       c(TYPE_VOID);
+       c(UNUSED);
+
+       /* data flow */
+
+       c(DF_0_TO_0);
+       c(DF_1_TO_0);
+       c(DF_2_TO_0);
+       c(DF_3_TO_0);
+       c(DF_DST_BASE);
+       c(DF_0_TO_1);
+       c(DF_1_TO_1);
+       c(DF_2_TO_1);
+       c(DF_3_TO_1);
+       c(DF_N_TO_1);
+       c(DF_INVOKE);
+       c(DF_BUILTIN);
+       c(DF_COPY);
+       c(DF_MOVE);
+       c(DF_DUP);
+       c(DF_DUP_X1);
+       c(DF_DUP_X2);
+       c(DF_DUP2);
+       c(DF_DUP2_X1);
+       c(DF_DUP2_X2);
+       c(DF_SWAP);
+       c(DF_LOAD);
+       c(DF_STORE);
+       c(DF_IINC);
+       c(DF_POP);
+       c(DF_POP2);
+
+       /* control flow */
+
+       c(CF_NORMAL);
+       c(CF_IF);
+       c(CF_END_BASE);
+       c(CF_END);
+       c(CF_GOTO);
+       c(CF_TABLE);
+       c(CF_LOOKUP);
+       c(CF_JSR);
+       c(CF_RET);
+
+#      undef c
+}
+
+/*
+ * Pythonpass
+ */
+
+void pythonpass_init() {
+       PyObject *m;
+       
+       Py_Initialize();
+       PyEval_InitThreads();
+
+       if (PyType_Ready(&wrapper_type) < 0) return;
+       if (PyType_Ready(&iterator_type) < 0) return;
+       if (PyType_Ready(&method_type) < 0) return;
+
+       m = Py_InitModule3("cacao", NULL, NULL);
+       if (m != NULL) {
+               constants(m);
+       }
+
+#if defined(ENABLE_THREADS)
+       python_global_lock = NEW(java_object_t);
+       LOCK_INIT_OBJECT_LOCK(python_global_lock);
+#endif
+
+}
+
+void pythonpass_cleanup() {
+       Py_Finalize();
+}
+
+int pythonpass_run(jitdata *jd, const char *module, const char *function) {
+       PyObject *pymodname = NULL;
+       PyObject *pymod = NULL;
+       PyObject *pydict = NULL;
+       PyObject *pyfunc = NULL;
+       PyObject *pyargs = NULL;
+       PyObject *pyret = NULL;
+       PyObject *pyarg = NULL;
+       PyObject *objcache = NULL;
+       int success = 0;
+       root_state root;
+
+       LOCK_MONITOR_ENTER(python_global_lock);
+
+       pymodname = PyString_FromString(module);
+       pymod = PyImport_Import(pymodname);
+
+       root.jd = jd;
+       root.object_cache = objcache = PyDict_New();
+
+       if (pymod != NULL) {
+               pydict = PyModule_GetDict(pymod);
+               pyfunc = PyDict_GetItemString(pydict, function);
+               if (pyfunc != NULL && PyCallable_Check(pyfunc)) {
+                       pyargs = PyTuple_New(1);
+
+                       if (get_obj(&pyarg, jd_func, &root, jd) != -1) {
+                       }
+
+                       /* */
+
+                       PyTuple_SetItem(pyargs, 0, pyarg);
+
+                       pyret = PyObject_CallObject(pyfunc, pyargs);
+                       if (pyret == NULL) {
+                PyErr_Print();
+                       } else {
+                               success = 1;
+                       }
+               } else {
+                       if (PyErr_Occurred())
+                               PyErr_Print();
+               }
+       } else {
+               PyErr_Print();
+       }
+
+       Py_XDECREF(pymodname);
+       Py_XDECREF(pymod);
+       Py_XDECREF(pyargs);
+       Py_XDECREF(pyret);
+       Py_XDECREF(objcache);
+
+       LOCK_MONITOR_EXIT(python_global_lock);
+
+       return (success == 1 ? 1 : 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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vm/jit/python.h b/src/vm/jit/python.h
new file mode 100644 (file)
index 0000000..56a44d4
--- /dev/null
@@ -0,0 +1,50 @@
+/* src/vm/jit/python.h - Python pass
+
+   Copyright (C) 2007, 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 _VM_JIT_PYTHON_H
+#define _VM_JIT_PYTHON_H
+#if defined(ENABLE_PYTHON)
+
+#include "vm/jit/jit.h"
+
+void pythonpass_init();
+void pythonpass_cleanup();
+int pythonpass_run(jitdata *jd, const char *module, const char *function);
+
+#endif
+#endif
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index f734563619715334708d3dbbdf1fc757d7ecf73a..66e989f006371a76bb23070191d9531136cbc7cf 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/reg.h - register allocator 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.
 
@@ -57,7 +55,7 @@ struct varinfo {
                basicblock *retaddr;
        } vv;
 #if defined(ENABLE_VERIFIER)
-       typeinfo typeinfo;         /* type info for reference types              */
+       typeinfo_t typeinfo;       /* type info for reference types              */
 #endif
 };
 
index c0c7ea52adb38d855d5dc5bed3cc6a20bdc92a68..5895bec0688a9368f4e8491e57c582ef0bf5be16 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/replace.c - 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.
 
@@ -40,7 +38,7 @@
 
 #include "mm/memory.h"
 
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
@@ -49,6 +47,7 @@
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/disass.h"
+#include "vm/jit/executionstate.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/replace.h"
@@ -1851,9 +1850,9 @@ void replace_patch_future_calls(u1 *ra,
                obj = calleeframe->instance.a;
                vftbl = obj->vftbl;
 
-               assert(vftbl->class->vftbl == vftbl);
+               assert(vftbl->clazz->vftbl == vftbl);
 
-               DOLOG_SHORT( printf("\tclass: "); class_println(vftbl->class); );
+               DOLOG_SHORT( printf("\tclass: "); class_println(vftbl->clazz); );
 
                replace_patch_class(vftbl, calleem, oldentrypoint, entrypoint);
        }
@@ -2419,7 +2418,7 @@ sourcestate_t *replace_recover_source_state(rplpoint *rp,
 
        while (rp || sfi) {
 
-               DOLOG( replace_executionstate_println(es); );
+               DOLOG( executionstate_println(es); );
 
                /* if we are not at a replacement point, it is a native frame */
 
@@ -2702,7 +2701,7 @@ static void replace_build_execution_state(sourcestate_t *ss,
 
                        replace_push_activation_record(es, rp, prevframe, ss->frames);
 
-                       DOLOG( replace_executionstate_println(es); );
+                       DOLOG( executionstate_println(es); );
                }
 
                rp = ss->frames->torp;
@@ -2722,7 +2721,7 @@ static void replace_build_execution_state(sourcestate_t *ss,
 
                replace_write_executionstate(rp, es, ss, ss->frames->down == NULL);
 
-               DOLOG( replace_executionstate_println(es); );
+               DOLOG( executionstate_println(es); );
 
                if (rp->type == RPLPOINT_TYPE_CALL) {
                        parent = NULL;
@@ -2754,12 +2753,12 @@ static void replace_me(rplpoint *rp, executionstate_t *es)
        stackframeinfo_t    *sfi;
        sourcestate_t       *ss;
        sourceframe_t       *frame;
-       s4                   dumpsize;
        codeinfo            *origcode;
        rplpoint            *origrp;
 #if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
        threadobject        *thread;
 #endif
+       int32_t              dumpmarker;
 
        origcode = es->code;
        origrp   = rp;
@@ -2775,11 +2774,11 @@ static void replace_me(rplpoint *rp, executionstate_t *es)
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
 
-       /* get the stackframeinfo for the current thread */
+       /* Get the stackframeinfo for the current thread. */
 
-       sfi = STACKFRAMEINFO;
+       sfi = threads_get_current_stackframeinfo();
 
        /* recover source state */
 
@@ -2858,7 +2857,7 @@ static void replace_me(rplpoint *rp, executionstate_t *es)
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
 }
 
 
@@ -2903,16 +2902,20 @@ bool replace_me_wrapper(u1 *pc, void *context)
 
        if ((rp != NULL) && (rp->pc == pc) && (rp->flags & RPLPOINT_FLAG_ACTIVE)) {
 
+#if !defined(NDEBUG)
+               executionstate_sanity_check(context);
+#endif
+
                /* set codeinfo pointer in execution state */
 
                es.code = code;
 
                /* read execution state from current context */
 
-               md_replace_executionstate_read(&es, context);
+               md_executionstate_read(&es, context);
 
                DOLOG( printf("REPLACEMENT READ: ");
-                          replace_executionstate_println(&es); );
+                          executionstate_println(&es); );
 
                /* do the actual replacement */
 
@@ -2920,10 +2923,10 @@ bool replace_me_wrapper(u1 *pc, void *context)
 
                /* write execution state to current context */
 
-               md_replace_executionstate_write(&es, context);
+               md_executionstate_write(&es, context);
 
                DOLOG( printf("REPLACEMENT WRITE: ");
-                          replace_executionstate_println(&es); );
+                          executionstate_println(&es); );
 
                /* new code is entered after returning */
 
@@ -2946,9 +2949,11 @@ void replace_gc_from_native(threadobject *thread, u1 *pc, u1 *sp)
        executionstate_t *es;
        sourcestate_t    *ss;
 
-       /* get the stackframeinfo of this thread */
+       /* Get the stackframeinfo of this thread. */
+
        assert(thread == THREADOBJECT);
-       sfi = STACKFRAMEINFO;
+
+       sfi = threads_get_current_stackframeinfo();
 
        /* create the execution state */
        es = DNEW(executionstate_t);
@@ -3222,108 +3227,6 @@ void replace_show_replacement_points(codeinfo *code)
 #endif
 
 
-/* replace_executionstate_println **********************************************
-   Print execution state
-  
-   IN:
-       es...............the execution state to print
-  
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void replace_executionstate_println(executionstate_t *es)
-{
-       int i;
-       int slots;
-       stackslot_t *sp;
-       int extraslots;
-
-       if (!es) {
-               printf("(executionstate_t *)NULL\n");
-               return;
-       }
-
-       printf("executionstate_t:\n");
-       printf("\tpc = %p",(void*)es->pc);
-       printf("  sp = %p",(void*)es->sp);
-       printf("  pv = %p\n",(void*)es->pv);
-#if defined(ENABLE_DISASSEMBLER)
-       for (i=0; i<INT_REG_CNT; ++i) {
-               if (i%4 == 0)
-                       printf("\t");
-               else
-                       printf(" ");
-#if SIZEOF_VOID_P == 8
-               printf("%-3s = %016llx",abi_registers_integer_name[i],(unsigned long long)es->intregs[i]);
-#else
-               printf("%-3s = %08lx",abi_registers_integer_name[i],(unsigned long)es->intregs[i]);
-#endif
-               if (i%4 == 3)
-                       printf("\n");
-       }
-       for (i=0; i<FLT_REG_CNT; ++i) {
-               if (i%4 == 0)
-                       printf("\t");
-               else
-                       printf(" ");
-               printf("F%02d = %016llx",i,(unsigned long long)es->fltregs[i]);
-               if (i%4 == 3)
-                       printf("\n");
-       }
-# if defined(HAS_ADDRESS_REGISTER_FILE)
-       for (i=0; i<ADR_REG_CNT; ++i) {
-               if (i%4 == 0)
-                       printf("\t");
-               else
-                       printf(" ");
-               printf("A%02d = %016llx",i,(unsigned long long)es->adrregs[i]);
-               if (i%4 == 3)
-                       printf("\n");
-       }
-# endif
-#endif
-
-       sp = (stackslot_t *) es->sp;
-
-       extraslots = 2;
-
-       if (es->code) {
-               methoddesc *md = es->code->m->parseddesc;
-               slots = es->code->stackframesize;
-               extraslots = 1 + md->memuse;
-       }
-       else
-               slots = 0;
-
-
-       if (slots) {
-               printf("\tstack slots(+%d) at sp:", extraslots);
-               for (i=0; i<slots+extraslots; ++i) {
-                       if (i%4 == 0)
-                               printf("\n\t\t");
-                       printf("M%02d%c", i, (i >= slots) ? '(' : ' ');
-#ifdef HAS_4BYTE_STACKSLOT
-                       printf("%08lx",(unsigned long)*sp++);
-#else
-                       printf("%016llx",(unsigned long long)*sp++);
-#endif
-                       printf("%c", (i >= slots) ? ')' : ' ');
-               }
-               printf("\n");
-       }
-
-       printf("\tcode: %p", (void*)es->code);
-       if (es->code != NULL) {
-               printf(" stackframesize=%d ", es->code->stackframesize);
-               method_print(es->code->m);
-       }
-       printf("\n");
-
-       printf("\n");
-}
-#endif
-
 #if !defined(NDEBUG)
 static void java_value_print(s4 type, replace_val_t value)
 {
@@ -3340,9 +3243,9 @@ static void java_value_print(s4 type, replace_val_t value)
        if (type == TYPE_ADR && value.a != NULL) {
                obj = value.a;
                putchar(' ');
-               utf_display_printable_ascii_classname(obj->vftbl->class->name);
+               utf_display_printable_ascii_classname(obj->vftbl->clazz->name);
 
-               if (obj->vftbl->class == class_java_lang_String) {
+               if (obj->vftbl->clazz == class_java_lang_String) {
                        printf(" \"");
                        u = javastring_toutf(obj, false);
                        utf_display_printable_ascii(u);
@@ -3522,7 +3425,7 @@ void replace_sourcestate_println_short(sourcestate_t *ss)
 
                if (REPLACE_IS_NATIVE_FRAME(frame)) {
                        printf("NATIVE (pc %p size %d) ",
-                                       (void*)frame->nativepc, frame->nativeframesize);
+                                  (void*)frame->nativepc, frame->nativeframesize);
                        replace_stackframeinfo_println(frame->sfi);
                        continue;
                }
@@ -3562,6 +3465,7 @@ static void replace_stackframeinfo_println(stackframeinfo_t *sfi)
 }
 #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 1037494089415627dff83b2a26fc6f60d5c56783..752cd385f4c8f8a633638c33688272101c781511 100644 (file)
@@ -52,7 +52,6 @@
 
 typedef struct rplalloc rplalloc;
 typedef struct rplpoint rplpoint;
-typedef struct executionstate_t executionstate_t;
 typedef struct sourcestate_t sourcestate_t;
 typedef struct sourceframe_t sourceframe_t;
 typedef union  replace_val_t replace_val_t;
@@ -141,25 +140,7 @@ union replace_val_t {
 };
 
 
-/* An `executionsstate` represents the state of a thread as it reached */
-/* an replacement point or is about to enter one.                      */
-
-struct executionstate_t {
-       u1           *pc;                               /* program counter */
-       u1           *sp;                   /* stack pointer within method */
-       u1           *pv;                   /* procedure value. NULL means */
-                                           /* search the AVL tree         */
-
-       ptrint        intregs[INT_REG_CNT];             /* register values */
-       double        fltregs[FLT_REG_CNT];             /* register values */
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       ptrint        adrregs[ADR_REG_CNT];             /* register values */
-#endif
-
-       codeinfo     *code;            /* codeinfo corresponding to the pv */
-};
-
-
+       u1           *ra;                /* return address / link register */
 struct sourceframe_t {
        sourceframe_t *down;           /* source frame down the call chain */
 
@@ -272,7 +253,6 @@ bool replace_me_wrapper(u1 *pc, void *context);
 #if !defined(NDEBUG)
 void replace_show_replacement_points(codeinfo *code);
 void replace_replacement_point_println(rplpoint *rp, int depth);
-void replace_executionstate_println(executionstate_t *es);
 void replace_sourcestate_println(sourcestate_t *ss);
 void replace_sourcestate_println_short(sourcestate_t *ss);
 void replace_source_frame_println(sourceframe_t *frame);
@@ -284,11 +264,6 @@ void replace_source_frame_println(sourceframe_t *frame);
 void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert);
 #endif
 
-/* machine and OS dependent functions (code in ARCH_DIR/OS_DIR/md-os.c) */
-
-void md_replace_executionstate_read(executionstate_t *es, void *context);
-void md_replace_executionstate_write(executionstate_t *es, void *context);
-
 #endif /* defined(ENABLE_REPLACEMENT) */
 
 #endif /* _REPLACE_H */
index 5723b241c8ee4cac660b61ef0cc3bcb370851a8c..a9c16bd31a3ac1ae7e4da4f34928cd5eb28a5330 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/s390/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.
 ##
@@ -53,7 +51,9 @@ libarch_la_SOURCES = \
        \
        md-abi.c \
        md-abi.h \
-       md.c
+       md-trap.h \
+       md.c \
+       md.h
 
 $(srcdir)/asmpart.S: $(top_builddir)/config.h
 
index 1ec084914b51d266b2bdca94c431c77473074b80..f09c7c8046b21695a5f9851bf06b48408e8fee29 100644 (file)
 
 /* misc ***********************************************************************/
 
-/* #define HAS_4BYTE_STACKSLOT */
 #define SUPPORT_COMBINE_INTEGER_REGISTERS
 
 #define JIT_COMPILER_VIA_SIGNAL
index 48c31fb8af2aa5c2b755954690f7e7c2232b27c7..da8913a7abd56f83b2ce084e86661f714c479cde 100644 (file)
@@ -163,10 +163,10 @@ L_asm_vm_call_method_stack_copy_done:
        la    mptr, 2*4(s1)         /* load method pointer */
        l     pv, 0(mptr)           /* load procedure vector from method pointer */
        basr  ra, pv                /* call method */
-       lr    sp, s1                /* restore stack pointer */
 
 L_asm_vm_call_method_return:
 
+       lr    sp, s1                /* restore stack pointer */
        l     s0, 0*4(sp)           /* restore used callee saved registers */
        l     s1, 1*4(sp)
        l     %r12, 3*4(sp)
@@ -343,37 +343,12 @@ L_restore_done:
 #      undef FREGS
 #      undef OUT
 
-#if 0
-
-/* asm_abstractmethoderror *****************************************************
-
-   Creates and throws an AbstractMethodError.
-
-*******************************************************************************/
-
-asm_abstractmethoderror:
-       mov     sp,a0                       /* pass java sp                       */
-       add     $1*8,a0
-       mov     0*8(sp),a1                  /* pass exception address             */
-       sub     $3,a1
-       call    exceptions_asm_new_abstractmethoderror@PLT
-                                           /* exception pointer is return value  */
-       pop     xpc                         /* get exception address              */
-       sub     $3,xpc                      /* exception address is ra - 3        */
-       jmp     L_asm_handle_exception
-
-#endif
-
 /* Offset table for PIC calls, see CALL_PIC */
 
 L_offsets:
        .long  _GLOBAL_OFFSET_TABLE_ - L_offsets
 L_offset_builtin_throw_exception:
        .long  builtin_throw_exception@PLTOFF
-L_offset_jit_asm_compile:
-       .long  jit_asm_compile@PLTOFF
-L_offset_exceptions_get_and_clear_exception:
-       .long  exceptions_get_and_clear_exception@PLTOFF
 L_offset_md_handle_exception:
        .long  md_handle_exception@PLTOFF
 
index b0a1516f029a7cfbfc4eaa59d84c4ede7e936204..ccfa92cf86713a170a05b0159de8b0a4b56d385b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/s390/codegen.c - machine code generator for s390
 
-   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 <stdio.h>
 
+#include "vm/jit/s390/arch.h"
+#include "vm/jit/s390/codegen.h"
+#include "vm/jit/s390/emit.h"
+#include "vm/jit/s390/md-abi.h"
+
 #include "native/jni.h"
 #include "native/localref.h"
 #include "native/native.h"
 
 #include "mm/memory.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/lock-common.h"
-# include "threads/native/lock.h"
-#endif
+#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/global.h"
+#include "vm/types.h"
+#include "vm/stringlocal.h"
+#include "vm/vm.h"
+
 #include "vm/jit/abi.h"
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
-#include "vm/jit/s390/arch.h"
-#include "vm/jit/s390/codegen.h"
-#include "vm/jit/s390/emit.h"
-#include "vm/jit/s390/md-abi.h"
 #include "vm/jit/stacktrace.h"
-#include "vm/types.h"
-#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/jit/trap.h"
+
 
 /* DO__LOG generates a call to do__log. No registers are destroyed,
  * so you may use it anywhere. regs is an array containing all general
@@ -371,13 +371,13 @@ bool codegen_emit(jitdata *jd)
                /* decide which monitor enter function to call */
 
                if (m->flags & ACC_STATIC) {
-                       disp = dseg_add_address(cd, &m->class->object.header);
+                       disp = dseg_add_address(cd, &m->clazz->object.header);
                        M_ALD_DSEG(REG_A0, disp);
                }
                else {
                        M_TEST(REG_A0);
                        M_BNE(SZ_BRC + SZ_ILL);
-                       M_ILL(EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ILL(TRAP_NullPointerException);
                }
 
                disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
@@ -2004,10 +2004,10 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        PROFILE_CYCLE_STOP;
 
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
 
                                        PROFILE_CYCLE_START;
                                }
@@ -2056,9 +2056,9 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        PROFILE_CYCLE_STOP;
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, disp);
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, disp);
                                        PROFILE_CYCLE_START;
                                }
                        }
@@ -2181,7 +2181,7 @@ bool codegen_emit(jitdata *jd)
                        }
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               ((patchref_t *)list_first_unsynced(jd->code->patchers))->disp = (cd->mcodeptr - ref);
+                               ((patchref_t *)list_first(jd->code->patchers))->disp = (cd->mcodeptr - ref);
                        }
 
                        switch (fieldtype) {
@@ -2901,9 +2901,9 @@ gen_method:
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
+                                               sizeof(methodptr*) * lm->clazz->index;
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
 
                                /* Implicit null-pointer check */
index 51f74648f3e499ac082de57481d129329cefe2fe..9ac259c71ff7dc7482dd32e287c9999803ea023e 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/s390/emit.c - s390 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 <assert.h>
 #include <stdint.h>
 
+#include "vm/jit/s390/codegen.h"
+#include "vm/jit/s390/emit.h"
+#include "vm/jit/s390/md-abi.h"
+
 #include "mm/memory.h"
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+
+#include "threads/lock-common.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
+#include "vm/types.h"
+
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/trace.h"
-#include "vm/jit/s390/codegen.h"
-#include "vm/jit/s390/emit.h"
-#include "vm/jit/s390/md-abi.h"
-#include "vm/types.h"
+#include "vm/jit/trap.h"
+
 #include "vmcore/options.h"
 
+
 /* emit_load *******************************************************************
 
    Emits a possible load of an operand.
@@ -229,7 +232,7 @@ uint32_t emit_trap(codegendata *cd)
 
        mcode = *((u2 *) cd->mcodeptr);
 
-       M_ILL(EXCEPTION_HARDWARE_PATCHER);
+       M_ILL(TRAP_PATCHER);
 
        return mcode;
 }
@@ -685,11 +688,12 @@ void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt) {
        }
 }
 
-void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg) {
+void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
+{
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(reg);
                M_BNE(SZ_BRC + SZ_ILL);
-               M_ILL(EXCEPTION_HARDWARE_ARITHMETIC);
+               M_ILL(TRAP_ArithmeticException);
        }
 }
 
@@ -707,7 +711,7 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1,
                 */
                N_CL(s2, OFFSET(java_array_t, size), RN, s1);
         M_BLT(SZ_BRC + SZ_ILL);
-               M_ILL2(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+               M_ILL2(s2, TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -723,7 +727,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(REG_RESULT);
                M_BNE(SZ_BRC + SZ_ILL);
-               M_ILL(EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_ILL(TRAP_ArrayStoreException);
        }
 }
 
@@ -746,23 +750,25 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
                        default:
                                vm_abort("emit_classcast_check: unknown condition %d", condition);
                }
-               M_ILL2(s1, EXCEPTION_HARDWARE_CLASSCAST);
+               M_ILL2(s1, TRAP_ClassCastException);
        }
 }
 
-void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg) {
+void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
+{
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(reg);
                M_BNE(SZ_BRC + SZ_ILL);
-               M_ILL(EXCEPTION_HARDWARE_NULLPOINTER);
+               M_ILL(TRAP_NullPointerException);
        }
 }
 
-void emit_exception_check(codegendata *cd, instruction *iptr) {
+void emit_exception_check(codegendata *cd, instruction *iptr)
+{
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(REG_RESULT);
                M_BNE(SZ_BRC + SZ_ILL);
-               M_ILL(EXCEPTION_HARDWARE_EXCEPTION);
+               M_ILL(TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -808,7 +814,7 @@ void emit_restore_pv(codegendata *cd) {
 
 void emit_trap_compiler(codegendata *cd)
 {
-       M_ILL2(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+       M_ILL2(REG_METHODPTR, TRAP_COMPILER);
 }
 
 /*
index 2cbe506318be2eae6b05206391187b2e02df6099..b470961aa0d1eb754d90f88572da55afc08d8d67 100644 (file)
  *    Copyright (C) 1992, Linus Torvalds
  */
 
-#define __CS_LOOP(ptr, op_val, op_string) ({                           \
-       int old_val, new_val;                           \
-        __asm__ __volatile__("   l     %0,0(%3)\n"                     \
-                             "0: lr    %1,%0\n"                                \
-                             op_string "  %1,%4\n"                     \
-                             "   cs    %0,%1,0(%3)\n"                  \
-                             "   jl    0b"                             \
-                             : "=&d" (old_val), "=&d" (new_val),       \
-                              "=m" (*ptr)      \
-                            : "a" (ptr), "d" (op_val),                 \
-                              "m" (*ptr)       \
-                            : "cc", "memory" );                        \
-       new_val;                                                        \
-})
-
-static inline void
-atomic_add (volatile int *mem, int val)
-{
-       __CS_LOOP(mem, val, "ar");
-}
-
 static inline long
 compare_and_swap (volatile long *p, long oldval, long newval)
 {
@@ -73,7 +52,6 @@ compare_and_swap (volatile long *p, long oldval, long newval)
 
 /* TODO not sure if the following two can't be just empty. */
 
-#define MEMORY_BARRIER_BEFORE_ATOMIC() eieio()
 #define MEMORY_BARRIER_AFTER_ATOMIC() eieio()
 
 #endif
index fc9d3ac5fae2606eff7875da300e6214fb44aebf..99715c6e1a2f272d03597ea5750e42a426042755 100644 (file)
@@ -1,9 +1,7 @@
-/* src/vm/jit/x86_64/md-abi.c - functions for x86_64 Linux ABI
+/* src/vm/jit/s390/md-abi.c - s390 Linux ABI
 
-   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 "config.h"
 
 #include "vm/global.h"
+#include "vm/types.h"
+
 #include "vm/jit/jit.h"
+#include "vm/jit/stack.h"
+
 #include "vm/jit/s390/md-abi.h"
-#include "vm/types.h"
 
 #include "vmcore/descriptor.h"
 
 #include <assert.h>
 
+
 /* register descripton array **************************************************/
 
 s4 nregdescint[] = {
@@ -267,7 +264,7 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t* stackslot)
 {
        methodinfo   *m;
        codeinfo     *code;
diff --git a/src/vm/jit/s390/md-trap.h b/src/vm/jit/s390/md-trap.h
new file mode 100644 (file)
index 0000000..ac0fe08
--- /dev/null
@@ -0,0 +1,67 @@
+/* src/vm/jit/s390/md-trap.h - s390 hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (s390) we use illegal instructions as trap
+ * instructions.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    0
+
+enum {
+       TRAP_NullPointerException           = 0,
+       TRAP_ArithmeticException            = 1,
+       TRAP_ArrayIndexOutOfBoundsException = 2,
+       TRAP_ArrayStoreException            = 3,
+       TRAP_ClassCastException             = 4,
+       TRAP_CHECK_EXCEPTION                = 5,
+       TRAP_PATCHER                        = 6,
+       TRAP_COMPILER                       = 7
+};
+
+#endif /* _MD_TRAP_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 52c6bbc46e8da20b40dd077522dc3075ef33b53d..cce456454ae35d5a3fdf88c4a419bc05bb3d236f 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/s390/md.c - machine dependent s390 Linux functions
 
-   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.
 
 
 #include "vm/jit/s390/md-abi.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/threads-common.h"
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/abi.h"
 #include "vm/jit/methodheader.h"
+#include "vm/jit/methodtree.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
 #include "vmcore/options.h" /* XXX debug */
@@ -55,6 +52,7 @@
 
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/s390/codegen.h"
+#include "vm/jit/s390/md.h"
 
 
 /* prototypes *****************************************************************/
@@ -95,14 +93,15 @@ void md_dump_context(u1 *pc, mcontext_t *mc) {
 
        log_println("Program counter: 0x%08X", pc);
 
-       pv = codegen_get_pv_from_pc_nocheck(pc);
+       pv = methodtree_find_nocheck(pc);
+
        if (pv == NULL) {
                log_println("No java method found at location.");
        } else {
                m = (*(codeinfo **)(pv + CodeinfoPointer))->m;
                log_println(
                        "Java method: class %s, method %s, descriptor %s.",
-                       m->class->name->text, m->name->text, m->descriptor->text
+                       m->clazz->name->text, m->name->text, m->descriptor->text
                );
        }
 
@@ -124,11 +123,8 @@ void md_dump_context(u1 *pc, mcontext_t *mc) {
                log_println("\tf%d\t0x%016llX\t(double)%e\t(float)%f", i, freg.l, freg.fr.d, freg.fr.f);
        }
 
-#if defined(ENABLE_THREADS)
        log_println("Dumping the current stacktrace:");
-       threads_print_stacktrace();
-#endif
-
+       stacktrace_print_current();
 }
 
 /* md_signal_handler_sigsegv ***************************************************
@@ -187,20 +183,20 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        pv = (u1 *)_mc->gregs[REG_PV] - N_PV_OFFSET;
        sp = (u1 *)_mc->gregs[REG_SP];
        ra = xpc;
-       type = EXCEPTION_HARDWARE_NULLPOINTER;
+       type = TRAP_NullPointerException;
        val = 0;
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        if (p != NULL) {
-               _mc->gregs[REG_ITMP3_XPTR] = (intptr_t) p;
-               _mc->gregs[REG_ITMP1_XPC]  = (intptr_t) xpc;
-               _mc->psw.addr              = (intptr_t) asm_handle_exception;
+               _mc->gregs[REG_ITMP3_XPTR] = (uintptr_t) p;
+               _mc->gregs[REG_ITMP1_XPC]  = (uintptr_t) xpc;
+               _mc->psw.addr              = (uintptr_t) asm_handle_exception;
        }
        else {
-               _mc->psw.addr              = (intptr_t) xpc;
+               _mc->psw.addr              = (uintptr_t) xpc;
        }
 }
 
@@ -235,7 +231,7 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
                sp = (u1 *)_mc->gregs[REG_SP];
                val = (ptrint)_mc->gregs[reg];
 
-               if (EXCEPTION_HARDWARE_COMPILER == type) {
+               if (TRAP_COMPILER == type) {
                        /* The PV from the compiler stub is equal to the XPC. */
 
                        pv = xpc;
@@ -247,28 +243,28 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
                        xpc = ra - 2;
                }
 
-               /* Handle the type. */
+               /* Handle the trap. */
 
-               p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+               p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
-               if (EXCEPTION_HARDWARE_COMPILER == type) {
+               if (TRAP_COMPILER == type) {
                        if (NULL == p) {
-                               _mc->gregs[REG_ITMP3_XPTR] = (intptr_t) builtin_retrieve_exception();
-                               _mc->gregs[REG_ITMP1_XPC]  = (intptr_t) ra - 2;
-                               _mc->gregs[REG_PV]         = (intptr_t) md_codegen_get_pv_from_pc(ra);
-                               _mc->psw.addr              = (intptr_t) asm_handle_exception;
+                               _mc->gregs[REG_ITMP3_XPTR] = (uintptr_t) builtin_retrieve_exception();
+                               _mc->gregs[REG_ITMP1_XPC]  = (uintptr_t) ra - 2;
+                               _mc->gregs[REG_PV]         = (uintptr_t) md_codegen_get_pv_from_pc(ra);
+                               _mc->psw.addr              = (uintptr_t) asm_handle_exception;
                        } else {
-                               _mc->gregs[REG_PV]         = (intptr_t) p;
-                               _mc->psw.addr              = (intptr_t) p;
+                               _mc->gregs[REG_PV]         = (uintptr_t) p;
+                               _mc->psw.addr              = (uintptr_t) p;
                        }
                } else {
                        if (p != NULL) {
-                               _mc->gregs[REG_ITMP3_XPTR] = (intptr_t) p;
-                               _mc->gregs[REG_ITMP1_XPC]  = (intptr_t) xpc;
-                               _mc->psw.addr              = (intptr_t) asm_handle_exception;
+                               _mc->gregs[REG_ITMP3_XPTR] = (uintptr_t) p;
+                               _mc->gregs[REG_ITMP1_XPC]  = (uintptr_t) xpc;
+                               _mc->psw.addr              = (uintptr_t) asm_handle_exception;
                        }
                        else {
-                               _mc->psw.addr              = (intptr_t) xpc;
+                               _mc->psw.addr              = (uintptr_t) xpc;
                        }
                }
        } else {
@@ -337,16 +333,16 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
                        sp = (u1 *)_mc->gregs[REG_SP];
                        ra = xpc;
 
-                       type = EXCEPTION_HARDWARE_ARITHMETIC;
+                       type = TRAP_ArithmeticException;
                        val = 0;
 
-                       /* Handle the type. */
+                       /* Handle the trap. */
 
-                       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+                       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
-                       _mc->gregs[REG_ITMP3_XPTR] = (intptr_t) p;
-                       _mc->gregs[REG_ITMP1_XPC]  = (intptr_t) xpc;
-                       _mc->psw.addr              = (intptr_t) asm_handle_exception;
+                       _mc->gregs[REG_ITMP3_XPTR] = (uintptr_t) p;
+                       _mc->gregs[REG_ITMP1_XPC]  = (uintptr_t) xpc;
+                       _mc->psw.addr              = (uintptr_t) asm_handle_exception;
 
                        return;
                }
@@ -553,7 +549,7 @@ void md_handle_exception(int32_t *regs, int64_t *fregs, int32_t *out) {
 
                ++loops;
 
-               pv = codegen_get_pv_from_pc(xpc);
+               pv = methodtree_find(xpc);
 
                handler = exceptions_handle_exception((java_object_t *)xptr, xpc, pv, sp);
 
index cd9f977d33ea74a691cf10eae3a874f0218b29bf..1664cd4172cbfa4b9faa37f3394edc8f04e569ad 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/s390/md.h - machine dependent s390 Linux functions
 
-   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.
 
@@ -34,6 +32,7 @@
 #include <stdint.h>
 
 #include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
 
 
 /* md_stacktrace_get_returnaddress *********************************************
@@ -58,8 +57,7 @@ inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframe
 
 /* md_codegen_get_pv_from_pc ***************************************************
 
-   On this architecture just a wrapper function to
-   codegen_get_pv_from_pc.
+   On this architecture just a wrapper function to methodtree_find.
 
 *******************************************************************************/
 
@@ -70,7 +68,7 @@ inline static void *md_codegen_get_pv_from_pc(void *ra)
        /* Get the start address of the function which contains this
        address from the method table. */
 
-       pv = codegen_get_pv_from_pc(ra);
+       pv = methodtree_find(ra);
 
        return pv;
 }
index 63af568e0ec081f079d8b072497eb863fc8aa4c6..667aa07587c0f05db22fb65ce0ee78b20727c4c3 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/s390/patcher.c - s390 code patching functions
 
-   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.
 
@@ -90,8 +88,8 @@ bool patcher_get_putstatic(patchref_t *pr)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        PATCH_BACK_ORIGINAL_MCODE;
@@ -276,14 +274,14 @@ bool patcher_invokeinterface(patchref_t *pr)
        /* get interfacetable index */
 
        idx = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
-               sizeof(methodptr) * m->class->index);
+               sizeof(methodptr) * m->clazz->index);
 
        ASSERT_VALID_IMM(idx);
 
        /* get method offset */
 
        off =
-               (s4) (sizeof(methodptr) * (m - m->class->methods));
+               (s4) (sizeof(methodptr) * (m - m->clazz->methods));
 
        ASSERT_VALID_DISP(off);
 
index 61aadcbeb4e86a1b5dfb6ed79b9582cabc1d28c9..61f92565134ad65629e3c8a3e3ad239763a36d33 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/show.c - showing the intermediate representation
 
-   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 "vmcore/options.h"
 
 #if defined(ENABLE_DEBUG_FILTER)
-#      include <sys/types.h>
-#      include <regex.h>
-#      if defined(ENABLE_THREADS)
-#              include "threads/native/threads.h"
-#      else
-#              include "threads/none/threads.h"
-#      endif
+# include <sys/types.h>
+# include <regex.h>
+# include "threads/thread.h"
 #endif
 
+
 /* global variables ***********************************************************/
 
 #if defined(ENABLE_THREADS) && !defined(NDEBUG)
@@ -526,11 +521,23 @@ void show_basicblock(jitdata *jd, basicblock *bptr, int stage)
 
                printf("\n");
 
+               if (irstage >= SHOW_CFG) {
+                       printf("succs: %d [ ", bptr->successorcount);
+
+                       for (i = 0; i < bptr->successorcount; i++)
+                               printf("%d ", bptr->successors[i]->nr);
+
+                       printf("]\n");
+               }
+
                if (irstage >= SHOW_STACK) {
                        printf("IN:  ");
                        show_variable_array(jd, bptr->invars, bptr->indepth, irstage);
                        printf(" javalocals: ");
-                       show_javalocals_array(jd, bptr->javalocals, bptr->method->maxlocals, irstage);
+                       if (bptr->javalocals)
+                               show_javalocals_array(jd, bptr->javalocals, bptr->method->maxlocals, irstage);
+                       else
+                               printf("null");
                        printf("\n");
                }
 
@@ -1526,22 +1533,22 @@ void show_filters_apply(methodinfo *m) {
        int res;
        char *method_name;
        s4 len;
-       s4 dumpsize;
+       int32_t dumpmarker;
 
        /* compose full name of method */
 
        len = 
-               utf_bytes(m->class->name) +
+               utf_bytes(m->clazz->name) +
                1 +
                utf_bytes(m->name) +
                utf_bytes(m->descriptor) +
                1;
 
-       dumpsize = dump_size(); /* allocate memory */
+       DMARKER;
 
        method_name = DMNEW(char, len);
 
-       utf_cat_classname(method_name, m->class->name);
+       utf_cat_classname(method_name, m->clazz->name);
        strcat(method_name, ".");
        utf_cat(method_name, m->name);
        utf_cat(method_name, m->descriptor);
@@ -1566,8 +1573,7 @@ void show_filters_apply(methodinfo *m) {
 
        /* release memory */
 
-       dump_release(dumpsize); 
-
+       DRELEASE; 
 }
 
 #define STATE_IS_INITIAL() ((FILTERVERBOSECALLCTR[0] == 0) && (FILTERVERBOSECALLCTR[1] == 0))
index 3f0c8f47a557db2473658fbe2fa71e74458a1c51..38535c3a897ada405cecc2aae28f20f2a25f013a 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/sparc64/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.
 ##
@@ -59,7 +57,9 @@ libarch_la_SOURCES = \
        \
        md-abi.c \
        md-abi.h \
-       md.c
+       md-trap.h \
+       md.c \
+       md.h
 
 libarch_la_LIBADD = \
        $(OS_DIR)/libmd.la
index 42a0ee98f7afe5b9420a8986b5cbd0a892f6caca..d13339a8a8dc63c5d024de7e0d27b71d2f0ffc24 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
 
-   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.
 
@@ -250,7 +248,7 @@ bool codegen_emit(jitdata *jd)
                /* get correct lock object */
 
                if (m->flags & ACC_STATIC) {
-                       disp = dseg_add_address(cd, &m->class->object.header);
+                       disp = dseg_add_address(cd, &m->clazz->object.header);
                        M_ALD(REG_OUT0, REG_PV, disp);
                        disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
                        M_ALD(REG_ITMP3, REG_PV, disp);
@@ -261,7 +259,7 @@ bool codegen_emit(jitdata *jd)
                        M_BNEZ(REG_OUT0, 3);
                        disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
                        M_ALD(REG_ITMP3, REG_PV, disp);                   /* branch delay */
-                       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
                }
 
                M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
@@ -1623,8 +1621,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -1668,8 +1666,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -1714,8 +1712,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -2601,9 +2599,9 @@ gen_method:
                                } 
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
+                                               sizeof(methodptr*) * lm->clazz->index;
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
 
                                /* implicit null-pointer check */
index 28a2240560fb04875536bfc5a93abd7a94c08839..def530822aeb785a3f430854e37586925df4014a 100644 (file)
@@ -461,7 +461,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_BNEZ(reg, 3);
                M_NOP;
-               M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARITHMETIC);
+               M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_ArithmeticException);
        }
 }
 
@@ -479,7 +479,7 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1,
                M_CMP(s2, REG_ITMP3);
                M_XBULT(3);
                M_NOP;
-               M_ALD_INTERN(s2, REG_ZERO, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+               M_ALD_INTERN(s2, REG_ZERO, TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -495,7 +495,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_BNEZ(REG_RESULT_CALLER, 3);
                M_NOP;
-               M_ALD_INTERN(REG_RESULT_CALLER, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_ALD_INTERN(REG_RESULT_CALLER, REG_ZERO, TRAP_ArrayStoreException);
        }
 }
 
@@ -529,7 +529,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
                }
 
                M_NOP;
-               M_ALD_INTERN(s1, REG_ZERO, EXCEPTION_HARDWARE_CLASSCAST);
+               M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
        }
 }
 
@@ -545,7 +545,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_BNEZ(reg, 3);
                M_NOP;
-               M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+               M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
        }
 }
 
@@ -561,7 +561,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_BNEZ(REG_RESULT_CALLER, 3);
                M_NOP;
-               M_ALD_INTERN(REG_RESULT_CALLER, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);
+               M_ALD_INTERN(REG_RESULT_CALLER, REG_ZERO, TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -579,9 +579,9 @@ uint32_t emit_trap(codegendata *cd)
        /* Get machine code which is patched back in later. The
           trap is 1 instruction word long. */
 
-       mcode = *((u4 *) cd->mcodeptr);
+       mcode = *((uint32_t *) cd->mcodeptr);
 
-       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_PATCHER);
+       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_PATCHER);
 
        return mcode;
 }
index 75488dabf90d917e2e961e2b8f3fcce3bc823bcc..1144594771951d8f44736215ff77135dd490bdd8 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/sparc64/linux/md-os.c - machine dependent SPARC Linux 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.
 
 
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 
 typedef struct sigcontext sigcontext;
@@ -121,7 +121,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *info , void *_p)
 
        /* flush register windows? */
        
-       val   = md_get_reg_from_context(ctx, d);
+       val  = md_get_reg_from_context(ctx, d);
 
        /* check for special-load */
 
@@ -138,16 +138,16 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *info , void *_p)
                type = (int) addr;
        }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* set registers */
 
-       ctx->sigc_regs.u_regs[REG_ITMP2_XPTR] = (intptr_t) p;
-       ctx->sigc_regs.u_regs[REG_ITMP3_XPC]  = (intptr_t) xpc;
-       ctx->sigc_regs.tpc                    = (intptr_t) asm_handle_exception;
-       ctx->sigc_regs.tnpc                   = (intptr_t) asm_handle_exception + 4;
+       ctx->sigc_regs.u_regs[REG_ITMP2_XPTR] = (uintptr_t) p;
+       ctx->sigc_regs.u_regs[REG_ITMP3_XPC]  = (uintptr_t) xpc;
+       ctx->sigc_regs.tpc                    = (uintptr_t) asm_handle_exception;
+       ctx->sigc_regs.tnpc                   = (uintptr_t) asm_handle_exception + 4;
 }
 
 
index d9741b09ae8d420f9de3ffc56f6e314dbc7d4d87..cc07238e70a5f40efe1f8e913916325690fe44ff 100644 (file)
@@ -3,24 +3,6 @@
 
 #include "toolbox/logging.h"
 
-/*
-static inline void
-__attribute__ ((unused))
-atomic_add (volatile int *mem, int val)
-{
-    int temp;
-
-  __asm__ __volatile__ (
-    "1:\t"
-    "ldl_l  %1,%3\n\t"
-    "addl   %1,%2,%1\n\t"
-    "stl_c  %1,%0\n\t"
-    "beq    %1,1b\n\t"
-    : "=m"(*mem), "=&r"(temp)
-    : "r"(val), "m"(*mem));
-}
-*/
-
 static inline long
 __attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
@@ -39,7 +21,6 @@ compare_and_swap (volatile long *p, long oldval, long newval)
 }
 
 #define STORE_ORDER_BARRIER() __asm__ __volatile__ ("wmb" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
 #define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory");
 #define MEMORY_BARRIER() __asm__ __volatile__ ( \
                "membar 0x0F" : : : "memory" );
index 633e67e7a39f98eb9d9a9d189ebdbd40ae44d537..4afd70d7c8e8b337cafb4412071629ef70e26c0a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/sparc64/md-abi.c - functions for Sparc ABI
 
-   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.
 
@@ -33,6 +31,7 @@
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
 
 #include "vmcore/descriptor.h"
 
@@ -40,6 +39,7 @@
 #include "mm/memory.h"
 #include <assert.h>
 
+
 /* helper macros for allocation methods ***************************************/
 #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
 
@@ -293,7 +293,7 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t* stackslot)
 {
        /* XXX */
 }
diff --git a/src/vm/jit/sparc64/md-trap.h b/src/vm/jit/sparc64/md-trap.h
new file mode 100644 (file)
index 0000000..e069031
--- /dev/null
@@ -0,0 +1,79 @@
+/* src/vm/jit/sparc64/md-trap.h - SPARC64 hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (sparc64) the trap numbers are used as load
+ * displacements and thus must not be 4- or 8-byte aligned.
+ *
+ * NOTE: In trap_init() we have a check whether the offset of
+ * java_arrayheader.data[0] is greater than the largest displacement
+ * defined below.  Otherwise normal array loads/stores could trigger
+ * an exception.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    1
+
+enum {
+       TRAP_NullPointerException           = 0,
+       TRAP_ArithmeticException            = 1,
+       TRAP_ArrayIndexOutOfBoundsException = 2,
+       TRAP_ArrayStoreException            = 3,
+
+       /* Don't use 4 (could be a normal load offset). */
+
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+
+       /* Don't use 8 (could be a normal load offset). */
+
+       TRAP_COMPILER                       = 9,
+       TRAP_END
+};
+
+#endif /* _MD_TRAP_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 d20b2a793047d4c272bd6a1535f5d855c32839a7..576e710c918b8b8bf324722167953d0121066f21 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/mips/patcher.c - SPARC code patching 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.
 
@@ -193,8 +191,8 @@ bool patcher_get_putstatic(u1 *sp)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        /* patch the field value's address */
@@ -512,28 +510,28 @@ bool patcher_invokeinterface(u1 *sp)
 
                *((s4 *) (ra + 1 * 4)) |= 
                        (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
-                               sizeof(methodptr*) * m->class->index) & 0x00001fff);
+                               sizeof(methodptr*) * m->clazz->index) & 0x00001fff);
 
                /* patch method offset */
 
                *((s4 *) (ra + 2 * 4)) |=
-                       (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x00001fff);
+                       (s4) ((sizeof(methodptr) * (m - m->clazz->methods)) & 0x00001fff);
 
                /* synchronize instruction cache */
 
                md_icacheflush(ra + 1 * 4, 2 * 4);
        }
-else {
+       else {
                /* patch interfacetable index */
 
                *((s4 *) (sp + 3 * 8 + 4)) |=
                        (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
-                               sizeof(methodptr*) * m->class->index) & 0x00001fff);
+                               sizeof(methodptr*) * m->clazz->index) & 0x00001fff);
 
                /* patch method offset */
 
                *((s4 *) (ra + 2 * 4)) |=
-                       (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x00001fff);
+                       (s4) ((sizeof(methodptr) * (m - m->clazz->methods)) & 0x00001fff);
 
                /* synchronize instruction cache */
 
index 4d1f71d6c226b79c5dbf797785e476f86b4e66b7..81f191896fcc537fab491f57d8dae8609c441f93 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/sparc64/solaris/md-os.c - machine dependent SPARC Solaris 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/exceptions.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 
 ptrint md_get_reg_from_context(mcontext_t *_mc, u4 rindex)
@@ -134,20 +134,20 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
                /* This is a normal NPE: addr must be NULL and the NPE-type
                   define is 0. */
 
-               addr  = md_get_reg_from_context(_mc, s1);
+               addr = md_get_reg_from_context(_mc, s1);
                type = (int) addr;
        }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
-       /* set registers */
+       /* Set registers. */
 
-       _mc->gregs[REG_G2]  = (intptr_t) p;                     /* REG_ITMP2_XPTR */
-       _mc->gregs[REG_G3]  = (intptr_t) xpc;                    /* REG_ITMP3_XPC */
-       _mc->gregs[REG_PC]  = (intptr_t) asm_handle_exception;
-       _mc->gregs[REG_nPC] = (intptr_t) asm_handle_exception + 4;      
+       _mc->gregs[REG_G2]  = (uintptr_t) p;                    /* REG_ITMP2_XPTR */
+       _mc->gregs[REG_G3]  = (uintptr_t) xpc;                   /* REG_ITMP3_XPC */
+       _mc->gregs[REG_PC]  = (uintptr_t) asm_handle_exception;
+       _mc->gregs[REG_nPC] = (uintptr_t) asm_handle_exception + 4;     
 }
 
 
index 3825a0821bda23584e1d5339c4e6856ef0acfa8f..e692269d25bf2c6846b3dac13efe6597a0c8a94c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/stack.c - stack analysis
 
-   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.
 
@@ -118,7 +116,7 @@ typedef struct stackdata_t stackdata_t;
 
 struct stackdata_t {
     basicblock *bptr;             /* the current basic block being analysed   */
-    stackptr new;                 /* next free stackelement                   */
+    stackelement_t *new;          /* next free stackelement                   */
     s4 vartop;                    /* next free variable index                 */
     s4 localcount;                /* number of locals (at the start of var)   */
     s4 varcount;                  /* maximum number of variables expected     */
@@ -132,7 +130,7 @@ struct stackdata_t {
        bool repeat;                  /* if true, iterate the analysis again      */
        exception_entry **handlers;   /* exception handlers for the current block */
        exception_entry *extableend;  /* points to the last exception entry       */
-       stackelement exstack;         /* instack for exception handlers           */
+       stackelement_t exstack;         /* instack for exception handlers           */
 };
 
 
@@ -509,7 +507,7 @@ struct stackdata_t {
 /* forward declarations *******************************************************/
 
 static void stack_create_invars(stackdata_t *sd, basicblock *b, 
-                                                               stackptr curstack, int stackdepth);
+                                                               stackelement_t * curstack, int stackdepth);
 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
 
 #if defined(STACK_VERBOSE)
@@ -519,7 +517,7 @@ static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, 
-                                                                        stackptr curstack);
+                                                                        stackelement_t * curstack);
 #endif
 
 
@@ -744,9 +742,9 @@ static void stack_merge_locals(stackdata_t *sd, basicblock *b)
 *******************************************************************************/
 
 static void stack_create_invars(stackdata_t *sd, basicblock *b, 
-                                                               stackptr curstack, int stackdepth)
+                                                               stackelement_t * curstack, int stackdepth)
 {
-       stackptr sp;
+       stackelement_t * sp;
        int i;
        int index;
        varinfo *dv;
@@ -831,10 +829,10 @@ static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
 *******************************************************************************/
 
 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
-                                                                          stackptr curstack, int stackdepth)
+                                                                          stackelement_t * curstack, int stackdepth)
 {
        int i;
-       stackptr sp;
+       stackelement_t * sp;
        basicblock *orig;
        bool separable;
        varinfo *sv;
@@ -1068,9 +1066,9 @@ static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock
 
 *******************************************************************************/
 
-static stackptr stack_create_instack(stackdata_t *sd)
+static stackelement_t * stack_create_instack(stackdata_t *sd)
 {
-    stackptr sp;
+    stackelement_t * sp;
        int depth;
        int index;
 
@@ -1114,7 +1112,7 @@ static stackptr stack_create_instack(stackdata_t *sd)
 
 *******************************************************************************/
 
-static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth) 
+static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackelement_t * curstack, int stackdepth) 
 {
        assert(b != NULL);
 
@@ -1233,6 +1231,9 @@ static bool stack_reach_next_block(stackdata_t *sd)
                assert(iptr->opc == ICMD_NOP);
                iptr->opc = ICMD_GOTO;
                iptr->dst.block = tbptr;
+#if defined(STACK_VERBOSE)
+               if (iptr->line == 0) printf("goto with line 0 in L%03d\n", sd->bptr->nr);
+#endif
 
                if (tbptr->flags < BBFINISHED)
                        sd->repeat = true; /* XXX check if we really need to repeat */
@@ -1880,7 +1881,7 @@ bool stack_reanalyse_block(stackdata_t *sd)
 
 *******************************************************************************/
 
-static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp, 
+static void stack_change_to_tempvar(stackdata_t *sd, stackelement_t * sp, 
                                                                        instruction *ilimit)
 {
        s4 newindex;
@@ -2014,8 +2015,8 @@ bool stack_analyse(jitdata *jd)
        registerdata *rd;
        stackdata_t   sd;
        int           stackdepth;
-       stackptr      curstack;       /* current stack top                        */
-       stackptr      copy;
+       stackelement_t *curstack;       /* current stack top                        */
+       stackelement_t *copy;
        int           opcode;         /* opcode of current instruction            */
        int           i, varindex;
        int           javaindex;
@@ -2028,10 +2029,10 @@ bool stack_analyse(jitdata *jd)
        basicblock   *original;
        exception_entry *ex;
 
-       stackptr     *last_store_boundary;
-       stackptr      coalescing_boundary;
+       stackelement_t **last_store_boundary;
+       stackelement_t *coalescing_boundary;
 
-       stackptr      src1, src2, src3, src4, dst1, dst2;
+       stackelement_t *src1, *src2, *src3, *src4, *dst1, *dst2;
 
        branch_target_t *table;
        lookup_target_t *lookup;
@@ -2105,7 +2106,7 @@ bool stack_analyse(jitdata *jd)
        for (i = 0; i < m->maxstack * 5; i++)
                jd->interface_map[i].flags = UNUSED;
 
-       last_store_boundary = DMNEW(stackptr, m->maxlocals);
+       last_store_boundary = DMNEW(stackelement_t *, m->maxlocals);
 
        /* initialize flags and invars (none) of first block */
 
@@ -3179,16 +3180,17 @@ normal_ACONST:
 
                                        case ICMD_IINC:
                                                STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
-                                               last_store_boundary[iptr->s1.varindex] = sd.new;
+                                               javaindex = iptr->s1.varindex;
+                                               last_store_boundary[javaindex] = sd.new;
 
                                                iptr->s1.varindex = 
-                                                       jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
+                                                       jd->local_map[javaindex * 5 + TYPE_INT];
 
                                                copy = curstack;
                                                i = stackdepth - 1;
                                                while (copy) {
                                                        if ((copy->varkind == LOCALVAR) &&
-                                                               (copy->varnum == iptr->s1.varindex))
+                                                               (jd->reverselocalmap[copy->varnum] == javaindex))
                                                        {
                                                                assert(IS_LOCALVAR(copy));
                                                                SET_TEMPVAR(copy);
@@ -3265,9 +3267,8 @@ normal_ACONST:
                                                i = stackdepth - 2;
                                                while (copy) {
                                                        if ((copy->varkind == LOCALVAR) &&
-                                                               (copy->varnum == varindex))
+                                                               (jd->reverselocalmap[copy->varnum] == javaindex))
                                                        {
-                                                               copy->varkind = TEMPVAR;
                                                                assert(IS_LOCALVAR(copy));
                                                                SET_TEMPVAR(copy);
                                                        }
@@ -3297,7 +3298,7 @@ normal_ACONST:
 
                                                copy = sd.new; /* most recent stackslot created + 1 */
                                                while (--copy > curstack) {
-                                                       if (copy->varkind == LOCALVAR && copy->varnum == varindex)
+                                                       if (copy->varkind == LOCALVAR && jd->reverselocalmap[copy->varnum] == javaindex)
                                                                goto assume_conflict;
                                                }
 
@@ -3320,7 +3321,7 @@ normal_ACONST:
                                                /* revert the coalescing, if it has been done earlier */
 assume_conflict:
                                                if ((curstack->varkind == LOCALVAR)
-                                                       && (curstack->varnum == varindex))
+                                                       && (jd->reverselocalmap[curstack->varnum] == javaindex))
                                                {
                                                        assert(IS_LOCALVAR(curstack));
                                                        SET_TEMPVAR(curstack);
@@ -4747,13 +4748,13 @@ static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
        printf("\n");
 }
 
-static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackptr curstack)
+static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackelement_t *curstack)
 {
-       stackptr sp;
+       stackelement_t *sp;
        s4       i;
        s4       depth;
        varinfo *v;
-       stackptr *stack;
+       stackelement_t **stack;
 
        printf("    javalocals ");
        show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
@@ -4763,7 +4764,7 @@ static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackpt
                i++;
        depth = i;
 
-       stack = MNEW(stackptr, depth);
+       stack = MNEW(stackelement_t *, depth);
        for(sp = curstack; sp; sp = sp->prev)
                stack[--i] = sp;
 
index 2af166477e2e98c6358f6bdc976a8c5d869a1f3d..eceb2db2204fd84ca3b6256b58a5a471c9d559a9 100644 (file)
@@ -1,9 +1,7 @@
-/* vm/jit/stack.h - stack analysis header
+/* src/vm/jit/stack.h - stack analysis 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: Christian Ullrich
-                       Edwin Steiner
-
 */
 
 
 #ifndef _STACK_H
 #define _STACK_H
 
+/* forward typedefs ***********************************************************/
+
+typedef struct stackelement_t stackelement_t;
+
+
 #include "config.h"
 
+#include <stdint.h>
+
 #include "vm/types.h"
 
 #include "vm/exceptions.h"
 #include "vm/global.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/reg.h"
 
 
+/* stack element structure ****************************************************/
+
+/* flags */
+
+#define SAVEDVAR      1         /* variable has to survive method invocations */
+#define INMEMORY      2         /* variable stored in memory                  */
+#define SAVREG        4         /* allocated to a saved register              */
+#define ARGREG        8         /* allocated to an arg register               */
+#define PASSTHROUGH  32         /* stackslot was passed-through by an ICMD    */
+#define PREALLOC     64         /* preallocated var like for ARGVARS. Used    */
+                                /* with the new var system */
+#define INOUT    128            /* variable is an invar or/and an outvar      */
+
+#define IS_SAVEDVAR(x)    ((x) & SAVEDVAR)
+#define IS_INMEMORY(x)    ((x) & INMEMORY)
+
+
+/* variable kinds */
+
+#define UNDEFVAR   0            /* stack slot will become temp during regalloc*/
+#define TEMPVAR    1            /* stack slot is temp register                */
+#define STACKVAR   2            /* stack slot is numbered stack slot          */
+#define LOCALVAR   3            /* stack slot is local variable               */
+#define ARGVAR     4            /* stack slot is argument variable            */
+
+
+struct stackelement_t {
+       stackelement_t *prev;       /* pointer to next element towards bottom     */
+       instruction    *creator;    /* instruction that created this element      */
+       s4              type;       /* slot type of stack element                 */
+       s4              flags;      /* flags (SAVED, INMEMORY)                    */
+       s4              varkind;    /* kind of variable or register               */
+       s4              varnum;     /* number of variable                         */
+};
+
+
 /* macros used internally by analyse_stack ************************************/
 
 /*--------------------------------------------------*/
index e8d59d422a513669569c4c0aa59304362eb4cdbd..461c09d18f68d38ff92196ac1ad0f2daf64febab 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/stacktrace.c - machine independent stacktrace 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, 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/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_CLASSPATH_GNU)
+# include "native/include/gnu_classpath_Pointer.h"
 # include "native/include/java_lang_VMThrowable.h"
 #endif
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#else
-# include "threads/none/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "toolbox/logging.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 ***********************************************************/
-#if !defined(ENABLE_THREADS)
-stackframeinfo_t *_no_threads_stackframeinfo = NULL;
-#endif
 
 CYCLES_STATS_DECLARE(stacktrace_overhead        , 100, 1)
 CYCLES_STATS_DECLARE(stacktrace_fillInStackTrace, 40,  5000)
@@ -97,18 +93,15 @@ CYCLES_STATS_DECLARE(stacktrace_get_stack       , 40,  10000)
 
 void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra, u1 *xpc)
 {
-       stackframeinfo_t **psfi;
-       codeinfo          *code;
-#if !defined(__I386__) && !defined(__X86_64__) && !defined(__S390__) && !defined(__M68K__)
-       bool               isleafmethod;
-#endif
+       stackframeinfo_t *currentsfi;
+       codeinfo         *code;
 #if defined(ENABLE_JIT)
        s4                 framesize;
 #endif
 
-       /* get current stackframe info pointer */
+       /* Get current stackframe info. */
 
-       psfi = &STACKFRAMEINFO;
+       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). */
@@ -116,7 +109,7 @@ void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra
        if (pv == NULL) {
 #if defined(ENABLE_INTRP)
                if (opt_intrp)
-                       pv = codegen_get_pv_from_pc(ra);
+                       pv = methodtree_find(ra);
                else
 #endif
                        {
@@ -135,7 +128,7 @@ void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra
        code = code_get_codeinfo_for_pv(pv);
 
        /* XXX */
-/*     assert(m != NULL); */
+       /*      assert(m != NULL); */
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
@@ -154,14 +147,13 @@ void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra
 
                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. */
-
-               isleafmethod = *((s4 *) (pv + IsLeaf));
+               /* 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 (!isleafmethod) {
+               if ((code == NULL) || !code_is_leafmethod(code)) {
                        framesize = *((u4 *) (pv + FrameSize));
 
                        ra = md_stacktrace_get_returnaddress(sp, framesize);
@@ -183,7 +175,7 @@ void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra
 
        /* Fill new stackframeinfo structure. */
 
-       sfi->prev = *psfi;
+       sfi->prev = currentsfi;
        sfi->code = code;
        sfi->pv   = pv;
        sfi->sp   = sp;
@@ -203,7 +195,7 @@ void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra
 
        /* Store new stackframeinfo pointer. */
 
-       *psfi = sfi;
+       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
@@ -222,17 +214,11 @@ void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra
 
 void stacktrace_stackframeinfo_remove(stackframeinfo_t *sfi)
 {
-       stackframeinfo_t **psfi;
-
-       /* clear the native world flag for the current thread */
-       /* ATTENTION: Clear this flag _before_ removing the stackframe info */
+       /* Clear the native world flag for the current thread. */
+       /* ATTENTION: Clear this flag _before_ removing the stackframe info. */
 
        THREAD_NATIVEWORLD_EXIT;
 
-       /* get current stackframe info pointer */
-
-       psfi = &STACKFRAMEINFO;
-
 #if !defined(NDEBUG)
        if (opt_DebugStackFrameInfo) {
                log_start();
@@ -244,9 +230,9 @@ void stacktrace_stackframeinfo_remove(stackframeinfo_t *sfi)
        }
 #endif
 
-       /* restore the old pointer */
+       /* Set previous stackframe info. */
 
-       *psfi = sfi->prev;
+       threads_set_current_stackframeinfo(sfi->prev);
 }
 
 
@@ -282,18 +268,8 @@ static inline void stacktrace_stackframeinfo_fill(stackframeinfo_t *tmpsfi, stac
        tmpsfi->prev = sfi->prev;
 
 #if !defined(NDEBUG)
-       /* Print current method information. */
-
-       if (opt_DebugStackTrace) {
-               log_println("[stacktrace start]");
-               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();
-       }
+       if (opt_DebugStackTrace)
+               log_println("[stacktrace fill]");
 #endif
 }
 
@@ -360,7 +336,7 @@ static inline void stacktrace_stackframeinfo_next(stackframeinfo_t *tmpsfi)
 
 #if defined(ENABLE_INTRP)
        if (opt_intrp)
-               pv = codegen_get_pv_from_pc(ra);
+               pv = methodtree_find(ra);
        else
 #endif
                {
@@ -532,18 +508,20 @@ static int stacktrace_depth(stackframeinfo_t *sfi)
 
 /* stacktrace_get **************************************************************
 
-   Builds and returns a stacktrace from the current thread for and
-   returns the stacktrace structure wrapped in a Java byte-array to
-   not confuse the GC.
+   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(void)
+java_handle_bytearray_t *stacktrace_get(stackframeinfo_t *sfi)
 {
-       stackframeinfo_t        *sfi;
        stackframeinfo_t         tmpsfi;
        int                      depth;
        java_handle_bytearray_t *ba;
@@ -564,10 +542,6 @@ java_handle_bytearray_t *stacktrace_get(void)
        skip_fillInStackTrace = true;
        skip_init             = true;
 
-       /* Get the stacktrace depth of the current thread. */
-
-       sfi = STACKFRAMEINFO;
-
        depth = stacktrace_depth(sfi);
 
        if (depth == 0)
@@ -623,7 +597,7 @@ java_handle_bytearray_t *stacktrace_get(void)
                        /* For GNU Classpath we also need to skip
                           VMThrowable.fillInStackTrace(). */
 
-                       if ((m->class == class_java_lang_VMThrowable) &&
+                       if ((m->clazz == class_java_lang_VMThrowable) &&
                                (m->name  == utf_fillInStackTrace))
                                continue;
 #endif
@@ -639,8 +613,8 @@ java_handle_bytearray_t *stacktrace_get(void)
                   exception we are going to skipping them in stack trace. */
 
                if (skip_init == true) {
-                       if (m->name == utf_init) {
-/*                             throwable->is_a(method->method_holder())) { */
+                       if ((m->name == utf_init) &&
+                               (class_issubclass(m->clazz, class_java_lang_Throwable))) {
                                continue;
                        }
                        else {
@@ -683,6 +657,105 @@ 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_CLASSPATH_SUN)
+               /* 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.
@@ -693,12 +766,12 @@ return_NULL:
 
 *******************************************************************************/
 
-classloader *stacktrace_first_nonnull_classloader(void)
+classloader_t *stacktrace_first_nonnull_classloader(void)
 {
        stackframeinfo_t *sfi;
        stackframeinfo_t  tmpsfi;
        methodinfo       *m;
-       classloader      *cl;
+       classloader_t    *cl;
 
 #if !defined(NDEBUG)
        if (opt_DebugStackTrace)
@@ -707,7 +780,7 @@ classloader *stacktrace_first_nonnull_classloader(void)
 
        /* Get the stackframeinfo of the current thread. */
 
-       sfi = STACKFRAMEINFO;
+       sfi = threads_get_current_stackframeinfo();
 
        /* Iterate over the whole stack. */
 
@@ -716,7 +789,7 @@ classloader *stacktrace_first_nonnull_classloader(void)
                 stacktrace_stackframeinfo_next(&tmpsfi)) {
 
                m  = tmpsfi.code->m;
-               cl = class_get_classloader(m->class);
+               cl = class_get_classloader(m->clazz);
 
                if (cl != NULL)
                        return cl;
@@ -753,7 +826,7 @@ java_handle_objectarray_t *stacktrace_getClassContext(void)
                log_println("[stacktrace_getClassContext]");
 #endif
 
-       sfi = STACKFRAMEINFO;
+       sfi = threads_get_current_stackframeinfo();
 
        /* Get the depth of the current stack. */
 
@@ -801,7 +874,7 @@ java_handle_objectarray_t *stacktrace_getClassContext(void)
 
                /* Store the class in the array. */
 
-               data[i] = (java_object_t *) m->class;
+               data[i] = (java_object_t *) m->clazz;
 
                i++;
        }
@@ -847,7 +920,7 @@ classinfo *stacktrace_get_current_class(void)
 
        /* Get the stackframeinfo of the current thread. */
 
-       sfi = STACKFRAMEINFO;
+       sfi = threads_get_current_stackframeinfo();
 
        /* If the stackframeinfo is NULL then FindClass is called through
           the Invocation Interface and we return NULL */
@@ -867,16 +940,16 @@ classinfo *stacktrace_get_current_class(void)
 
                m = tmpsfi.code->m;
 
-               if (m->class == class_java_security_PrivilegedAction) {
+               if (m->clazz == class_java_security_PrivilegedAction) {
                        CYCLES_STATS_END(stacktrace_getCurrentClass);
 
                        return NULL;
                }
 
-               if (m->class != NULL) {
+               if (m->clazz != NULL) {
                        CYCLES_STATS_END(stacktrace_getCurrentClass);
 
-                       return m->class;
+                       return m->clazz;
                }
        }
 
@@ -921,7 +994,7 @@ java_handle_objectarray_t *stacktrace_get_stack(void)
 
        /* Get the stackframeinfo of the current thread. */
 
-       sfi = STACKFRAMEINFO;
+       sfi = threads_get_current_stackframeinfo();
 
        /* Get the depth of the current stack. */
 
@@ -974,7 +1047,7 @@ java_handle_objectarray_t *stacktrace_get_stack(void)
                /* NOTE: We use a LLNI-macro here, because a classinfo is not
                   a handle. */
 
-               LLNI_array_direct(classes, i) = (java_object_t *) m->class;
+               LLNI_array_direct(classes, i) = (java_object_t *) m->clazz;
 
                /* Store the name in the array. */
 
@@ -1000,6 +1073,51 @@ 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
@@ -1029,28 +1147,99 @@ void stacktrace_print(stacktrace_t *st)
 
                linenumber = linenumbertable_linenumber_for_pc(&m, ste->code, ste->pc);
 
-               printf("\tat ");
-               utf_display_printable_ascii_classname(m->class->name);
-               printf(".");
-               utf_display_printable_ascii(m->name);
-               utf_display_printable_ascii(m->descriptor);
+               stacktrace_print_entry(m, linenumber);
+       }
+}
 
-               if (m->flags & ACC_NATIVE) {
-                       puts("(Native Method)");
-               }
-               else {
-                       printf("(");
-                       utf_display_printable_ascii(m->class->sourcefile);
-                       printf(":%d)\n", 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;
        }
 
-       /* just to be sure */
+       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;
 
-       fflush(stdout);
+               /* 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
@@ -1064,9 +1253,12 @@ void stacktrace_print(stacktrace_t *st)
 void stacktrace_print_exception(java_handle_t *h)
 {
        java_lang_Throwable     *o;
+
 #if defined(WITH_CLASSPATH_GNU)
        java_lang_VMThrowable   *vmt;
 #endif
+
+       java_lang_Object        *backtrace;
        java_handle_bytearray_t *ba;
        stacktrace_t            *st;
 
@@ -1080,16 +1272,18 @@ void stacktrace_print_exception(java_handle_t *h)
 #if defined(WITH_CLASSPATH_GNU)
 
        LLNI_field_get_ref(o,   vmState, vmt);
-       LLNI_field_get_ref(vmt, vmData,  ba);
+       LLNI_field_get_ref(vmt, vmdata,  backtrace);
 
 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
 
-       LLNI_field_get_ref(o, backtrace, ba);
+       LLNI_field_get_ref(o, backtrace, backtrace);
 
 #else
 # error unknown classpath configuration
 #endif
 
+       ba = (java_handle_bytearray_t *) backtrace;
+
        /* Sanity check. */
 
        assert(ba != NULL);
index 00d76e346b7658017919bb1ac40baf5e0202e621..e21c348a1e17af5f8920c38ab9dcedbb88a642fd 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/stacktrace.h - header file for stacktrace 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -42,6 +40,8 @@ typedef struct stacktrace_t       stacktrace_t;
 
 #include "md-abi.h"
 
+#include "threads/thread.h"
+
 #include "vm/global.h"
 
 #include "vm/jit/code.h"
@@ -98,16 +98,24 @@ struct stacktrace_t {
 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(void);
+java_handle_bytearray_t   *stacktrace_get(stackframeinfo_t *sfi);
+java_handle_bytearray_t   *stacktrace_get_current(void);
 
 #if defined(ENABLE_JAVASE)
-classloader               *stacktrace_first_nonnull_classloader(void);
+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) */
index b75299404d4b8e012d5267debea8c53fe9de9e99..ba7599937487f3ceb34d7575f06a680ed9537bf1 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/trace.c - 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -39,7 +37,7 @@
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Throwable.h"
 
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
@@ -71,8 +69,7 @@ u4 _no_threads_tracejavacallcount= 0;
 
 *******************************************************************************/
 
-static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
-                                                                                       typedesc *paramtype, imm_union imu)
+static char *trace_java_call_print_argument(methodinfo *m, char *logtext, s4 *logtextlen, typedesc *paramtype, imm_union imu)
 {
        java_object_t *o;
        classinfo     *c;
@@ -111,14 +108,23 @@ static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
                sprintf(logtext + strlen(logtext), "0x%016lx", (ptrint) imu.l);
 #endif
 
-               /* cast to java.lang.Object */
+               /* 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 */
+               /* Check return argument for java.lang.Class or
+                  java.lang.String. */
 
                if (o != NULL) {
-                       if (o->vftbl->class == class_java_lang_String) {
+                       if (o->vftbl->clazz == class_java_lang_String) {
                                /* get java.lang.String object and the length of the
                                   string */
 
@@ -138,7 +144,7 @@ static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
                                strcat(logtext, "\")");
                        }
                        else {
-                               if (o->vftbl->class == class_java_lang_Class) {
+                               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 */
@@ -151,7 +157,7 @@ static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
                                        /* 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->class->name;
+                                       u = o->vftbl->clazz->name;
                                }
 
                                len = strlen(" (Class = \"") + utf_bytes(u) + strlen("\")");
@@ -192,9 +198,16 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
        imm_union   arg;
        char       *logtext;
        s4          logtextlen;
-       s4          dumpsize;
        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))
@@ -215,7 +228,7 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
                strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
                TRACEJAVACALLINDENT +
                strlen("called: ") +
-               ((m->class == NULL) ? strlen("NULL") : utf_bytes(m->class->name)) +
+               ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
                strlen(".") +
                utf_bytes(m->name) +
                utf_bytes(m->descriptor);
@@ -247,7 +260,7 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
 
        /* allocate memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        logtext = DMNEW(char, logtextlen);
 
@@ -263,8 +276,8 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
 
        strcpy(logtext + pos, "called: ");
 
-       if (m->class != NULL)
-               utf_cat_classname(logtext, m->class->name);
+       if (m->clazz != NULL)
+               utf_cat_classname(logtext, m->clazz->name);
        else
                strcat(logtext, "NULL");
        strcat(logtext, ".");
@@ -282,15 +295,13 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
        if (m->flags & ACC_NATIVE)         strcat(logtext, " NATIVE");
        if (m->flags & ACC_INTERFACE)      strcat(logtext, " INTERFACE");
        if (m->flags & ACC_ABSTRACT)       strcat(logtext, " ABSTRACT");
-       if (m->flags & ACC_METHOD_BUILTIN) strcat(logtext, " METHOD_BUILTIN");
 
        strcat(logtext, "(");
 
        for (i = 0; i < md->paramcount; ++i) {
                arg = argument_jitarray_load(md, i, arg_regs, stack);
-               logtext = trace_java_call_print_argument(
-                       logtext, &logtextlen, &md->paramtypes[i], arg
-               );
+               logtext = trace_java_call_print_argument(m, logtext, &logtextlen,
+                                                                                                &md->paramtypes[i], arg);
                if (i != (md->paramcount - 1)) {
                        strcat(logtext, ", ");
                }
@@ -302,7 +313,7 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        TRACEJAVACALLINDENT++;
 
@@ -323,10 +334,17 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
        methoddesc *md;
        char       *logtext;
        s4          logtextlen;
-       s4          dumpsize;
        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))
@@ -354,7 +372,7 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
                strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
                TRACEJAVACALLINDENT +
                strlen("finished: ") +
-               ((m->class == NULL) ? strlen("NULL") : utf_bytes(m->class->name)) +
+               ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
                strlen(".") +
                utf_bytes(m->name) +
                utf_bytes(m->descriptor) +
@@ -366,7 +384,7 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
 
        /* allocate memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        logtext = DMNEW(char, logtextlen);
 
@@ -381,8 +399,8 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
                logtext[pos++] = '\t';
 
        strcpy(logtext + pos, "finished: ");
-       if (m->class != NULL)
-               utf_cat_classname(logtext, m->class->name);
+       if (m->clazz != NULL)
+               utf_cat_classname(logtext, m->clazz->name);
        else
                strcat(logtext, "NULL");
        strcat(logtext, ".");
@@ -394,15 +412,15 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
                val = argument_jitreturn_load(md, return_regs);
 
                logtext =
-                       trace_java_call_print_argument(logtext, &logtextlen, &md->returntype, val);
+                       trace_java_call_print_argument(m, logtext, &logtextlen,
+                                                                                  &md->returntype, val);
        }
 
        log_text(logtext);
 
        /* release memory */
 
-       dump_release(dumpsize);
-
+       DRELEASE;
 }
 
 
@@ -416,14 +434,14 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
 {
        char *logtext;
        s4    logtextlen;
-       s4    dumpsize;
        codeinfo *code;
+       int32_t   dumpmarker;
 
        /* calculate message length */
 
        if (xptr) {
                logtextlen =
-                       strlen("Exception ") + utf_bytes(xptr->vftbl->class->name);
+                       strlen("Exception ") + utf_bytes(xptr->vftbl->clazz->name);
        } 
        else {
                logtextlen = strlen("Some Throwable");
@@ -433,7 +451,7 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
 
        if (m) {
                logtextlen +=
-                       utf_bytes(m->class->name) +
+                       utf_bytes(m->clazz->name) +
                        strlen(".") +
                        utf_bytes(m->name) +
                        utf_bytes(m->descriptor) +
@@ -446,10 +464,10 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
                logtextlen += strlen(")(0x12345678) at position 0x12345678 (");
 #endif
 
-               if (m->class->sourcefile == NULL)
+               if (m->clazz->sourcefile == NULL)
                        logtextlen += strlen("<NO CLASSFILE INFORMATION>");
                else
-                       logtextlen += utf_bytes(m->class->sourcefile);
+                       logtextlen += utf_bytes(m->clazz->sourcefile);
 
                logtextlen += strlen(":65536)");
 
@@ -462,13 +480,13 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
 
        /* allocate memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        logtext = DMNEW(char, logtextlen);
 
        if (xptr) {
                strcpy(logtext, "Exception ");
-               utf_cat_classname(logtext, xptr->vftbl->class->name);
+               utf_cat_classname(logtext, xptr->vftbl->clazz->name);
 
        } else {
                strcpy(logtext, "Some Throwable");
@@ -477,7 +495,7 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
        strcat(logtext, " thrown in ");
 
        if (m) {
-               utf_cat_classname(logtext, m->class->name);
+               utf_cat_classname(logtext, m->clazz->name);
                strcat(logtext, ".");
                utf_cat(logtext, m->name);
                utf_cat(logtext, m->descriptor);
@@ -518,10 +536,10 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
                                        (ptrint) code->entrypoint, (ptrint) pos);
 #endif
 
-                       if (m->class->sourcefile == NULL)
+                       if (m->clazz->sourcefile == NULL)
                                strcat(logtext, "<NO CLASSFILE INFORMATION>");
                        else
-                               utf_cat(logtext, m->class->sourcefile);
+                               utf_cat(logtext, m->clazz->sourcefile);
 
                        sprintf(logtext + strlen(logtext), ":%d)", 0);
                }
@@ -533,7 +551,7 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 }
 
 
@@ -549,7 +567,7 @@ void trace_exception_builtin(java_object_t *xptr)
        java_lang_String    *s;
        char                *logtext;
        s4                   logtextlen;
-       s4                   dumpsize;
+       int32_t              dumpmarker;
 
        t = (java_lang_Throwable *) xptr;
 
@@ -563,7 +581,7 @@ void trace_exception_builtin(java_object_t *xptr)
 
        if (t) {
                logtextlen +=
-                       utf_bytes(xptr->vftbl->class->name);
+                       utf_bytes(xptr->vftbl->clazz->name);
                if (s) {
                        logtextlen += strlen(": ") +
                                u2_utflength(LLNI_field_direct(s, value)->data 
@@ -577,14 +595,14 @@ void trace_exception_builtin(java_object_t *xptr)
 
        /* allocate memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        logtext = DMNEW(char, logtextlen);
 
        strcpy(logtext, "Builtin exception thrown: ");
 
        if (t) {
-               utf_cat_classname(logtext, xptr->vftbl->class->name);
+               utf_cat_classname(logtext, xptr->vftbl->clazz->name);
 
                if (s) {
                        char *buf;
@@ -603,7 +621,7 @@ void trace_exception_builtin(java_object_t *xptr)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 }
 
 
diff --git a/src/vm/jit/trap.c b/src/vm/jit/trap.c
new file mode 100644 (file)
index 0000000..d062952
--- /dev/null
@@ -0,0 +1,237 @@
+/* src/vm/jit/trap.c - hardware traps
+
+   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 machine dependent trap stuff. */
+
+#include "md-trap.h"
+
+#include "native/llni.h"
+
+#include "toolbox/logging.h"
+
+#include "vm/exceptions.h"
+#include "vm/vm.h"
+
+#include "vm/jit/code.h"
+#include "vm/jit/disass.h"
+#include "vm/jit/jit.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"
+
+
+/**
+ * Mmap the first memory page to support hardware exceptions and check
+ * the maximum hardware trap displacement on the architectures where
+ * it is required (TRAP_INSTRUCTION_IS_LOAD defined to 1).
+ */
+void trap_init(void)
+{
+#if !(defined(__ARM__) && defined(__LINUX__))
+       /* On arm-linux the first memory page can't be mmap'ed, as it
+          contains the exception vectors. */
+
+       int pagesize;
+
+       /* mmap a memory page at address 0x0, so our hardware-exceptions
+          work. */
+
+       pagesize = system_getpagesize();
+
+       (void) system_mmap_anonymous(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
+#endif
+
+       TRACESUBSYSTEMINITIALIZATION("trap_init");
+
+#if !defined(TRAP_INSTRUCTION_IS_LOAD)
+# error TRAP_INSTRUCTION_IS_LOAD is not defined in your md-trap.h
+#endif
+
+#if TRAP_INSTRUCTION_IS_LOAD == 1
+       /* Check if we get into trouble with our hardware-exceptions. */
+
+       if (TRAP_END > OFFSET(java_bytearray_t, data))
+               vm_abort("trap_init: maximum hardware trap displacement is greater than the array-data offset: %d > %d", TRAP_END, OFFSET(java_bytearray_t, data));
+#endif
+}
+
+
+/**
+ * Handles the signal which is generated by trap instructions, caught
+ * by a signal handler and calls the correct function.
+ *
+ * @param type trap number
+ * @param 
+ */
+void* trap_handle(int type, intptr_t val, void *pv, void *sp, void *ra, void *xpc, void *context)
+{
+       stackframeinfo_t  sfi;
+       int32_t           index;
+       java_handle_t    *o;
+       methodinfo       *m;
+       java_handle_t    *p;
+
+#if !defined(NDEBUG)
+       if (opt_TraceTraps)
+               log_println("[signal_handle: trap %d]", type);
+#endif
+       
+#if defined(ENABLE_VMLOG)
+       vmlog_cacao_signl_type(type);
+#endif
+
+       /* Prevent compiler warnings. */
+
+       o = NULL;
+       m = NULL;
+
+       /* wrap the value into a handle if it is a reference */
+       /* BEFORE: creating stackframeinfo */
+
+       switch (type) {
+       case TRAP_ClassCastException:
+               o = LLNI_WRAP((java_object_t *) val);
+               break;
+
+       case TRAP_COMPILER:
+               /* In this case the passed PV points to the compiler stub.  We
+                  get the methodinfo pointer here and set PV to NULL so
+                  stacktrace_stackframeinfo_add determines the PV for the
+                  parent Java method. */
+
+               m  = code_get_methodinfo_for_pv(pv);
+               pv = NULL;
+               break;
+
+       default:
+               /* do nothing */
+               break;
+       }
+
+       /* Fill and add a stackframeinfo. */
+
+       stacktrace_stackframeinfo_add(&sfi, pv, sp, ra, xpc);
+
+       switch (type) {
+       case TRAP_NullPointerException:
+               p = exceptions_new_nullpointerexception();
+               break;
+
+       case TRAP_ArithmeticException:
+               p = exceptions_new_arithmeticexception();
+               break;
+
+       case TRAP_ArrayIndexOutOfBoundsException:
+               index = (s4) val;
+               p = exceptions_new_arrayindexoutofboundsexception(index);
+               break;
+
+       case TRAP_ArrayStoreException:
+               p = exceptions_new_arraystoreexception();
+               break;
+
+       case TRAP_ClassCastException:
+               p = exceptions_new_classcastexception(o);
+               break;
+
+       case TRAP_CHECK_EXCEPTION:
+               p = exceptions_fillinstacktrace();
+               break;
+
+       case TRAP_PATCHER:
+#if defined(ENABLE_REPLACEMENT)
+               if (replace_me_wrapper(xpc, context)) {
+                       p = NULL;
+                       break;
+               }
+#endif
+               p = patcher_handler(xpc);
+               break;
+
+       case TRAP_COMPILER:
+               p = jit_compile_handle(m, sfi.pv, ra, (void *) val);
+               break;
+
+       default:
+               /* Let's try to get a backtrace. */
+
+               (void) methodtree_find(xpc);
+
+               /* If that does not work, print more debug info. */
+
+               log_println("signal_handle: unknown hardware exception type %d", type);
+
+#if SIZEOF_VOID_P == 8
+               log_println("PC=0x%016lx", xpc);
+#else
+               log_println("PC=0x%08x", xpc);
+#endif
+
+#if defined(ENABLE_DISASSEMBLER)
+               log_println("machine instruction at PC:");
+               disassinstr(xpc);
+#endif
+
+               vm_abort("Exiting...");
+
+               /* keep compiler happy */
+
+               p = NULL;
+       }
+
+       /* Remove stackframeinfo. */
+
+       stacktrace_stackframeinfo_remove(&sfi);
+
+       /* unwrap and return the exception object */
+       /* AFTER: removing stackframeinfo */
+
+       if (type == TRAP_COMPILER)
+               return p;
+       else
+               return LLNI_UNWRAP(p);
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of 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/trap.h b/src/vm/jit/trap.h
new file mode 100644 (file)
index 0000000..8eb295b
--- /dev/null
@@ -0,0 +1,58 @@
+/* src/vm/jit/trap.h - hardware traps
+
+   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 _TRAP_H
+#define _TRAP_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+/* Include machine dependent trap stuff. */
+
+#include "md-trap.h"
+
+
+/* function prototypes ********************************************************/
+
+void  trap_init(void);
+void* trap_handle(int type, intptr_t val, void *pv, void *sp, void *ra, void *xpc, void *context);
+
+#endif /* _TRAP_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 ef004ed72d50d6e03edc247db87b52c088efa1c0..d308d8b790817685de1712d188a6bb5c53787eb2 100644 (file)
@@ -476,7 +476,7 @@ case ICMD_ATHROW:
                                METHOD,
                                /* XXX make this more efficient, use class_java_lang_Throwable
                                 * directly */
-                               class_get_classref(METHOD->class,utf_java_lang_Throwable),
+                               class_get_classref(METHOD->clazz,utf_java_lang_Throwable),
                                &OP1->typeinfo);
                IPTR->flags.bits |= INS_FLAG_UNRESOLVED;
        }
@@ -534,7 +534,7 @@ case ICMD_RETURN:
 return_tail:
        TYPECHECK_COUNT(stat_ins_primitive_return);
 
-       if (STATE->initmethod && METHOD->class != class_java_lang_Object) {
+       if (STATE->initmethod && METHOD->clazz != class_java_lang_Object) {
                /* Check if the 'this' instance has been initialized. */
                LOG("Checking <init> marker");
 #if defined(TYPECHECK_VARIABLESBASED)
index 5ca682273764fd8b3c6713b834ff23fbec36730e..0cb2c610f7bbbc14e93c439d6d24c2e80f07786e 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck-builtins.inc - type checking for ICMD_BUILTIN
 
-   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.
 
                s4 i;
 #endif
 #if defined(TYPECHECK_STACKBASED)
-               typedescriptor *av;
+               typedescriptor_t *av;
 #endif
 
                /* verify a generic builtin call */
index a06c12da764078e5f02e08f5b7ccce2dca583496..5b559438aea9a19fee8fe5e551a133224e407a21 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck-common.c - shared verifier code
 
-   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: Edwin Steiner
-
-   Changes: 
-
 */
 
 
@@ -519,7 +511,7 @@ bool typecheck_init_locals(verifier_state *state, bool newthis)
                        if (state->initmethod && newthis)
                                TYPEINFO_INIT_NEWOBJECT(v->typeinfo, NULL);
                        else
-                               typeinfo_init_classinfo(&(v->typeinfo), state->m->class);
+                               typeinfo_init_classinfo(&(v->typeinfo), state->m->clazz);
                }
 
                skip = 1;
index ac91170dc7e9e4fa25d7d70e4ec44ce5c3d93899..fd3f6ab6fe631fdd42b242a38f639564314a3d1b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck-common.h - internal header for the type checker
 
-   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: Edwin Steiner
-
-   Changes:
-
 */
 
 
@@ -223,8 +215,8 @@ struct typecheck_jsr_t {
        bool         active;           /* true if this sub is currently active */
        char        *blockflags;   /* saved block flags when JSR was traversed */
        char        *usedlocals;       /* != 0 for each local used in this sub */
-       typedescriptor *retlocals;                   /* locals on the RET edge */
-       typedescriptor *retstack;                     /* stack on the RET edge */
+       typedescriptor_t *retlocals;                 /* locals on the RET edge */
+       typedescriptor_t *retstack;                   /* stack on the RET edge */
        s4              retdepth;               /* stack depth on the RET edge */
 };
 
@@ -248,9 +240,8 @@ typedef struct verifier_state {
        
        s4 numlocals;                         /* number of local variables */
        s4 validlocals;                /* number of Java-accessible locals */
-       s4 *reverselocalmap;
        
-       typedescriptor returntype;    /* return type of the current method */
+       typedescriptor_t returntype;  /* return type of the current method */
 
        s4 *savedindices;
        s4 *savedinvars;                            /* saved invar pointer */
@@ -268,11 +259,11 @@ typedef struct verifier_state {
 
        /* the following fields are used by the stackbased verifier only:  */
 
-       typedescriptor *locals;                 /* current local variables */
-       typedescriptor *startlocals;  /* locals at the start of each block */
-       typedescriptor *startstack;    /* stack at the start of each block */
-       s4             *indepth;                  /* stack depth at --''-- */
-       typedescriptor *stackceiling;      /* upper edge of verifier stack */
+       typedescriptor_t *locals;               /* current local variables */
+       typedescriptor_t *startlocals;/* locals at the start of each block */
+       typedescriptor_t *startstack;  /* stack at the start of each block */
+       s4               *indepth;                /* stack depth at --''-- */
+       typedescriptor_t *stackceiling;    /* upper edge of verifier stack */
 
        typecheck_jsr_t *topjsr;        /* most recently called subroutine */
        typecheck_jsr_t **jsrinfos;      /* subroutine info for each block */
index 845680236cf666a199fa82e0fc020170ffff6874..fe8fe1e28c4be087202d8f9e435f5f9d4c0dfb77 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck-fields.inc - type checking for field ICMDs
 
-   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: Edwin Steiner
-
-   Changes: 
-
 */
 
 
 {
        unresolved_field *uf;
        constant_FMIref *fieldref;
-       typeinfo *instanceti;
-       typeinfo *valueti;
+       typeinfo_t *instanceti;
+       typeinfo_t *valueti;
 #if !defined(TYPECHECK_TYPEINFERER)
        resolve_result_t result;
 #endif
@@ -74,7 +66,7 @@
                fi  = fieldref->p.field;
 
                result = resolve_field_verifier_checks(
-                               state->m, fieldref, fi->class, fi,
+                               state->m, fieldref, fi->clazz, fi,
                                instanceti, valueti,
                                (instance == NULL),
                                (value != NULL));
@@ -87,7 +79,7 @@
 
        if (result != resolveSucceeded) {
                if (!uf) {
-                       uf = resolve_create_unresolved_field(state->m->class
+                       uf = resolve_create_unresolved_field(state->m->clazz
                                        state->m, state->iptr);
                        if (!uf)
                                EXCEPTION;
                /* record the subtype constraints for this field access */
 
                if (!resolve_constrain_unresolved_field(
-                                       uf, state->m->class, state->m,
+                                       uf, state->m->clazz, state->m,
                                        instanceti, valueti))
                        EXCEPTION; /* XXX maybe wrap exception? */
 
                TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
                TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) && 
-                               !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,
+                               !state->iptr->sx.s23.s3.fmiref->p.field->clazz->initialized,
                                stat_ins_field_uninitialized);
        }
 #endif /* !defined(TYPECHECK_TYPEINFERER) */
 
        if (value == NULL) {
 #if defined(TYPECHECK_STACKBASED)
-               typedescriptor *dv;
+               typedescriptor_t *dv;
 
                if (IS_2_WORD_TYPE(fieldref->parseddesc.fd->type)) {
                        CHECK_STACK_SPACE(2);
index 2c30dc67d61708d1554d64db01fbe873c08e0b8a..609b45060e5199e71f8ee834561b662080514a3d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck-invoke.inc - type checking for invocations
 
-   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: Edwin Steiner
-
-
 */
 
 
@@ -49,7 +42,7 @@
        s4 argindex;                            /* argument variable index */
        varinfo *av;                                  /* argument variable */
 #else
-       typedescriptor *av;                         /* argument stack slot */
+       typedescriptor_t *av;                       /* argument stack slot */
 #endif
        int i;                                                  /* counter */
        resolve_result_t result;
@@ -81,7 +74,7 @@
 
        if (IS_FMIREF_RESOLVED(mref)) {
                mi = mref->p.method;
-               mclassname = mi->class->name;
+               mclassname = mi->clazz->name;
        }
        else {
                mi = NULL;
                                if (ins)
                                        initclass = ins[-1].sx.val.c;
                                else
-                                       initclass.cls = state->m->class;
+                                       initclass.cls = state->m->clazz;
                                LOGSTR("\t\tclass: "); LOGNAME(initclass); LOGNL;
                        }
                }
                        /* the current class is linked, so must be its superclass. thus we can be */
                        /* sure that resolving will be trivial.                                   */
                        if (mi) {
-                               cls = mi->class;
+                               cls = mi->clazz;
                        }
                        else {
                                if (!resolve_classref(state->m,mref->p.classref,resolveLazy,false,true,&cls))
 
                        /* if lazy resolving did not succeed, it's not one of the allowed classes */
                        /* otherwise we check it directly                                         */
-                       if (cls == NULL || (cls != state->m->class && cls != state->m->class->super)) {
+                       if (cls == NULL || (cls != state->m->clazz && cls != state->m->clazz->super)) {
                                TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
                        }
 
        /* impose loading constraints */
 
        if (result == resolveSucceeded) {
-               /* XXX state->m->class may have to be wrong when inlining */
-               if (!resolve_method_loading_constraints(state->m->class, mi))
+               /* XXX state->m->clazz may have to be wrong when inlining */
+               if (!resolve_method_loading_constraints(state->m->clazz, mi))
                        return false;
        }
 
                /* resolution must be deferred */
 
                if (!um) {
-                       um = resolve_create_unresolved_method(state->m->class, state->m,
+                       um = resolve_create_unresolved_method(state->m->clazz, state->m,
                                        mref, 
                                        invokestatic,
                                        invokespecial);
index c81b7a9eea7d3ef7688279c84433d2c36c5fd26f..871526463c2e5a0c9531ffa109ef6100c1006c76 100644 (file)
@@ -14,7 +14,7 @@
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 349 "src/vm/jit/verify/icmds.c"
+#              line 347 "src/vm/jit/verify/icmds.c"
   GENERATED    if (IPTR->flags.bits & INS_FLAG_CLASS) {
   GENERATED            /* a java.lang.Class reference */
   GENERATED            TYPEINFO_INIT_JAVA_LANG_CLASS(DST->typeinfo,IPTR->sx.val.c);
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 93 "src/vm/jit/verify/icmds.c"
+#              line 91 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_aload);
   GENERATED  
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 260 "src/vm/jit/verify/icmds.c"
+#              line 258 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 270 "src/vm/jit/verify/icmds.c"
+#              line 268 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 255 "src/vm/jit/verify/icmds.c"
+#              line 253 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_FLOAT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 250 "src/vm/jit/verify/icmds.c"
+#              line 248 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_DOUBLE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 115 "src/vm/jit/verify/icmds.c"
+#              line 113 "src/vm/jit/verify/icmds.c"
   GENERATED  
 #            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 239 "src/vm/jit/verify/icmds.c"
+#              line 237 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 245 "src/vm/jit/verify/icmds.c"
+#              line 243 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 265 "src/vm/jit/verify/icmds.c"
+#              line 263 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 108 "src/vm/jit/verify/icmds.c"
+#              line 106 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPEINFO_COPY(OP1->typeinfo, DST->typeinfo);
   GENERATED  
 #              line 479 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 296 "src/vm/jit/verify/icmds.c"
+#              line 294 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-3] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 306 "src/vm/jit/verify/icmds.c"
+#              line 304 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 291 "src/vm/jit/verify/icmds.c"
+#              line 289 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_FLOAT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-3] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 286 "src/vm/jit/verify/icmds.c"
+#              line 284 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_DOUBLE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 311 "src/vm/jit/verify/icmds.c"
+#              line 309 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we just check the basic input types and that the           */
   GENERATED    /* destination is an array of references. Assignability to    */
   GENERATED    /* the actual array must be checked at runtime, each time the */
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 275 "src/vm/jit/verify/icmds.c"
+#              line 273 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 281 "src/vm/jit/verify/icmds.c"
+#              line 279 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 301 "src/vm/jit/verify/icmds.c"
+#              line 299 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 704 "src/vm/jit/verify/icmds.c"
+#              line 676 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we pop 1 */
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 709 "src/vm/jit/verify/icmds.c"
+#              line 681 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we pop either 11 or 2 */
   GENERATED    if (IS_CAT1(stack[0]))
   GENERATED            CHECK_CAT1(stack[-1]);
   GENERATED    /* may use stack[0] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 724 "src/vm/jit/verify/icmds.c"
+#              line 696 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup 1 */
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 731 "src/vm/jit/verify/icmds.c"
+#              line 703 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup 1 */
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED    /* we skip 1 */
   GENERATED    /* may use stack[-2] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 742 "src/vm/jit/verify/icmds.c"
+#              line 714 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup 1 */
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED    /* we skip either 11 or 2 */
   GENERATED    /* may use stack[-1] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 755 "src/vm/jit/verify/icmds.c"
+#              line 727 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup either 11 or 2 */
   GENERATED    if (IS_CAT1(stack[0]))
   GENERATED            CHECK_CAT1(stack[-1]);
   GENERATED    /* may use stack[-2] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 764 "src/vm/jit/verify/icmds.c"
+#              line 736 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup either 11 or 2 */
   GENERATED    if (IS_CAT1(stack[0]))
   GENERATED            CHECK_CAT1(stack[-1]);
   GENERATED    /* may use stack[-3] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 778 "src/vm/jit/verify/icmds.c"
+#              line 750 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup either 11 or 2 */
   GENERATED    if (IS_CAT1(stack[0]))
   GENERATED            CHECK_CAT1(stack[-1]);
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 715 "src/vm/jit/verify/icmds.c"
+#              line 687 "src/vm/jit/verify/icmds.c"
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED    CHECK_CAT1(stack[-1]);
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 393 "src/vm/jit/verify/icmds.c"
+#              line 391 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 399 "src/vm/jit/verify/icmds.c"
+#              line 397 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 405 "src/vm/jit/verify/icmds.c"
+#              line 403 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 390 "src/vm/jit/verify/icmds.c"
+#              line 388 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 586 "src/vm/jit/verify/icmds.c"
+#              line 558 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    tbptr = IPTR->sx.s23.s3.jsrtarget.block;
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 607 "src/vm/jit/verify/icmds.c"
+#              line 579 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    CHECK_LOCAL_TYPE(IPTR->s1.varindex, TYPE_RET);
   GENERATED    if (!TYPEINFO_IS_PRIMITIVE(STATE->locals[IPTR->s1.varindex].typeinfo))
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 457 "src/vm/jit/verify/icmds.c"
+#              line 429 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 473 "src/vm/jit/verify/icmds.c"
+#              line 445 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 539 "src/vm/jit/verify/icmds.c"
+#              line 511 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_INT)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 544 "src/vm/jit/verify/icmds.c"
+#              line 516 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_LNG)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 549 "src/vm/jit/verify/icmds.c"
+#              line 521 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_FLT)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 554 "src/vm/jit/verify/icmds.c"
+#              line 526 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_DBL)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 514 "src/vm/jit/verify/icmds.c"
+#              line 486 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_areturn);
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("illegal instruction: ARETURN on non-reference");
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 559 "src/vm/jit/verify/icmds.c"
+#              line 531 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_VOID)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
   GENERATED  return_tail:
   GENERATED    TYPECHECK_COUNT(stat_ins_primitive_return);
   GENERATED  
-  GENERATED    if (STATE->initmethod && METHOD->class != class_java_lang_Object) {
+  GENERATED    if (STATE->initmethod && METHOD->clazz != class_java_lang_Object) {
   GENERATED            /* Check if the 'this' instance has been initialized. */
   GENERATED            LOG("Checking <init> marker");
   GENERATED  
   GENERATED    /* variable number of outslots! */
   GENERATED  
   GENERATED  
-#              line 158 "src/vm/jit/verify/icmds.c"
+#              line 156 "src/vm/jit/verify/icmds.c"
   GENERATED    stack = typecheck_stackbased_verify_fieldaccess(STATE, NULL, NULL, stack);
   GENERATED    if (stack == NULL)
   GENERATED            EXCEPTION;
   GENERATED    /* variable number of inslots! */
   GENERATED  
   GENERATED  
-#              line 140 "src/vm/jit/verify/icmds.c"
+#              line 138 "src/vm/jit/verify/icmds.c"
   GENERATED    CHECK_STACK_DEPTH(1);
   GENERATED    if (!IS_CAT1(stack[0])) {
   GENERATED            /* (stack depth >= 2 is guaranteed) */
   GENERATED    /* variable number of outslots! */
   GENERATED  
   GENERATED  
-#              line 151 "src/vm/jit/verify/icmds.c"
+#              line 149 "src/vm/jit/verify/icmds.c"
   GENERATED    CHECK_STACK_TYPE(stack[0], TYPE_ADR);
   GENERATED    stack = typecheck_stackbased_verify_fieldaccess(STATE, stack, NULL, stack-1);
   GENERATED    if (stack == NULL)
   GENERATED    /* variable number of inslots! */
   GENERATED  
   GENERATED  
-#              line 128 "src/vm/jit/verify/icmds.c"
+#              line 126 "src/vm/jit/verify/icmds.c"
   GENERATED    CHECK_STACK_DEPTH(2);
   GENERATED    if (!IS_CAT1(stack[0])) {
   GENERATED            CHECK_STACK_DEPTH(3);
   GENERATED    /* variable number of outslots! */
   GENERATED  
   GENERATED  
-#              line 630 "src/vm/jit/verify/icmds.c"
+#              line 602 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_invoke);
   GENERATED  
   GENERATED    INSTRUCTION_GET_METHODDESC(IPTR, md);
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 233 "src/vm/jit/verify/icmds.c"
+#              line 231 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY(OP1->typeinfo)
   GENERATED                    && OP1->typeinfo.typeclass.cls != pseudo_class_Arraystub)
   GENERATED            VERIFY_ERROR("illegal instruction: ARRAYLENGTH on non-array");
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 493 "src/vm/jit/verify/icmds.c"
+#              line 465 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_athrow);
   GENERATED    r = typeinfo_is_assignable_to_class(&OP1->typeinfo,
   GENERATED                    CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
   GENERATED                            METHOD,
   GENERATED                            /* XXX make this more efficient, use class_java_lang_Throwable
   GENERATED                             * directly */
-  GENERATED                            class_get_classref(METHOD->class,utf_java_lang_Throwable),
+  GENERATED                            class_get_classref(METHOD->clazz,utf_java_lang_Throwable),
   GENERATED                            &OP1->typeinfo);
   GENERATED            IPTR->flags.bits |= INS_FLAG_UNRESOLVED;
   GENERATED    }
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 367 "src/vm/jit/verify/icmds.c"
+#              line 365 "src/vm/jit/verify/icmds.c"
   GENERATED  
 #            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* returnAddress is not allowed */
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 379 "src/vm/jit/verify/icmds.c"
+#              line 377 "src/vm/jit/verify/icmds.c"
   GENERATED    /* returnAddress is not allowed */
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("Illegal instruction: INSTANCEOF on non-reference");
   GENERATED    /* variable number of inslots! */
   GENERATED  
   GENERATED  
-#              line 668 "src/vm/jit/verify/icmds.c"
+#              line 640 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!typecheck_stackbased_multianewarray(STATE, stack, stackfloor))
   GENERATED            EXCEPTION;
   GENERATED    stack -= (IPTR->s1.argcount - 1);
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 391 "src/vm/jit/verify/icmds.c"
+#              line 389 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* variable number of outslots! */
   GENERATED  
   GENERATED  
-#              line 684 "src/vm/jit/verify/icmds.c"
+#              line 656 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_builtin);
   GENERATED    if (!typecheck_stackbased_verify_builtin(STATE, stack, stackfloor))
   GENERATED            EXCEPTION;
index ac4377507fa248d44db0df275d8698b4f8587dbb..5141dd871d709db94a8f30996905284adc30e718 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck-stackbased.c - stack-based verifier
 
-   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.
 
@@ -47,7 +45,7 @@
 /* this #if runs over the whole file: */
 #if defined(ENABLE_VERIFIER)
 
-typedef typedescriptor verifier_slot_t;
+typedef typedescriptor_t verifier_slot_t;
 
 #if defined(TYPECHECK_VERBOSE)
 static void typecheck_stackbased_show_state(verifier_state *state,
@@ -152,15 +150,15 @@ static void typecheck_stackbased_show_state(verifier_state *state,
 
 /* XXX should reuse typevector code */
 static typecheck_result typecheck_stackbased_merge_locals(methodinfo *m,
-                                                                                                                 typedescriptor *dst,
-                                                                                                                 typedescriptor *y,
+                                                                                                                 typedescriptor_t *dst,
+                                                                                                                 typedescriptor_t *y,
                                                                                                                  int size)
 {
        bool changed = false;
        typecheck_result r;
 
-       typedescriptor *a = dst;
-       typedescriptor *b = y;
+       typedescriptor_t *a = dst;
+       typedescriptor_t *b = y;
        while (size--) {
                if (a->type != TYPE_VOID && a->type != b->type) {
                        a->type = TYPE_VOID;
@@ -201,14 +199,14 @@ static typecheck_result typecheck_stackbased_merge_locals(methodinfo *m,
 
 static typecheck_result typecheck_stackbased_merge(verifier_state *state,
                                                                                                   basicblock *destblock,
-                                                                                                  typedescriptor *stack,
+                                                                                                  typedescriptor_t *stack,
                                                                                                   s4 stackdepth)
 {
        s4 i;
        s4 destidx;
-       typedescriptor *stackfloor;
-       typedescriptor *sp;
-       typedescriptor *dp;
+       typedescriptor_t *stackfloor;
+       typedescriptor_t *sp;
+       typedescriptor_t *dp;
        typecheck_result r;
        bool changed = false;
 
@@ -268,7 +266,7 @@ static typecheck_result typecheck_stackbased_merge(verifier_state *state,
 
 static bool typecheck_stackbased_reach(verifier_state *state,
                                                                           basicblock *destblock,
-                                                                          typedescriptor *stack,
+                                                                          typedescriptor_t *stack,
                                                                           s4 stackdepth)
 {
        bool changed = false;
@@ -287,12 +285,12 @@ static bool typecheck_stackbased_reach(verifier_state *state,
 
                MCOPY(state->startstack + (destblock->nr * state->m->maxstack),
                          stack - (stackdepth - 1),
-                         typedescriptor,
+                         typedescriptor_t,
                          stackdepth);
 
                MCOPY(state->startlocals + (destblock->nr * state->numlocals),
                          state->locals,
-                         typedescriptor,
+                         typedescriptor_t,
                          state->numlocals);
 
                changed = true;
@@ -341,11 +339,11 @@ static bool typecheck_stackbased_reach(verifier_state *state,
 
 *******************************************************************************/
 
-static typedescriptor *typecheck_stackbased_verify_fieldaccess(
+static typedescriptor_t *typecheck_stackbased_verify_fieldaccess(
                verifier_state *state,
-               typedescriptor *instance,
-               typedescriptor *value,
-               typedescriptor *stack)
+               typedescriptor_t *instance,
+               typedescriptor_t *value,
+               typedescriptor_t *stack)
 {
        jitdata *jd;
 
@@ -368,12 +366,12 @@ throw_stack_overflow:
 }
 
 static bool typecheck_stackbased_verify_invocation(verifier_state *state,
-                                                                                                  typedescriptor *stack,
-                                                                                                  typedescriptor *stackfloor)
+                                                                                                  typedescriptor_t *stack,
+                                                                                                  typedescriptor_t *stackfloor)
 {
        s4 paramslots;
        methoddesc *md;
-       typedescriptor *dv;
+       typedescriptor_t *dv;
 
        /* check stack depth */
 
@@ -401,11 +399,11 @@ static bool typecheck_stackbased_verify_invocation(verifier_state *state,
 }
 
 static bool typecheck_stackbased_verify_builtin(verifier_state *state,
-                                                                                               typedescriptor *stack,
-                                                                                               typedescriptor *stackfloor)
+                                                                                               typedescriptor_t *stack,
+                                                                                               typedescriptor_t *stackfloor)
 {
        s4 paramslots;
-       typedescriptor *dv;
+       typedescriptor_t *dv;
 
        /* check stack depth */
 
@@ -440,16 +438,16 @@ throw_stack_type_error:
 }
 
 static bool typecheck_stackbased_multianewarray(verifier_state *state,
-                                                                                               typedescriptor *stack,
-                                                                                               typedescriptor *stackfloor)
+                                                                                               typedescriptor_t *stack,
+                                                                                               typedescriptor_t *stackfloor)
 {
        /* XXX recombine with verify_multianewarray */
 
        classinfo *arrayclass;
        arraydescriptor *desc;
        s4 i;
-       typedescriptor *sp;
-       typedescriptor *dst;
+       typedescriptor_t *sp;
+       typedescriptor_t *dst;
 
        /* destination slot */
 
@@ -532,9 +530,9 @@ static void typecheck_stackbased_add_jsr_caller(typecheck_jsr_t *jsr,
        jsr->callers = jc;
 }
 
-static typedescriptor *typecheck_stackbased_jsr(verifier_state *state,
-                                                                                               typedescriptor *stack,
-                                                                                               typedescriptor *stackfloor)
+static typedescriptor_t *typecheck_stackbased_jsr(verifier_state *state,
+                                                                                               typedescriptor_t *stack,
+                                                                                               typedescriptor_t *stackfloor)
 {
        typecheck_jsr_t *jsr;
        basicblock *tbptr;
@@ -559,7 +557,7 @@ static typedescriptor *typecheck_stackbased_jsr(verifier_state *state,
 
                /* copy the stack of the RET edge */
 
-               MCOPY(stackfloor, jsr->retstack, typedescriptor, jsr->retdepth);
+               MCOPY(stackfloor, jsr->retstack, typedescriptor_t, jsr->retdepth);
                stack = stackfloor + (jsr->retdepth - 1);
 
                /* copy variables that were used in the subroutine from the RET edge */
@@ -586,8 +584,8 @@ static typedescriptor *typecheck_stackbased_jsr(verifier_state *state,
                        jsr->start = tbptr;
                        jsr->usedlocals = DMNEW(char, state->numlocals);
                        MZERO(jsr->usedlocals, char, state->numlocals);
-                       jsr->retlocals = DMNEW(typedescriptor, state->numlocals);
-                       jsr->retstack = DMNEW(typedescriptor, state->m->maxstack);
+                       jsr->retlocals = DMNEW(typedescriptor_t, state->numlocals);
+                       jsr->retstack = DMNEW(typedescriptor_t, state->m->maxstack);
                        jsr->retdepth = 0;
                }
                else {
@@ -620,8 +618,8 @@ static typedescriptor *typecheck_stackbased_jsr(verifier_state *state,
 }
 
 static bool typecheck_stackbased_ret(verifier_state *state,
-                                                                        typedescriptor *stack,
-                                                                        typedescriptor *stackfloor)
+                                                                        typedescriptor_t *stack,
+                                                                        typedescriptor_t *stackfloor)
 {
        basicblock *tbptr;
        typecheck_jsr_caller_t *jsrcaller;
@@ -658,14 +656,14 @@ static bool typecheck_stackbased_ret(verifier_state *state,
 
        jsr->retblock = state->bptr;
        jsr->retdepth = (stack - stackfloor) + 1;
-       MCOPY(jsr->retstack, stackfloor, typedescriptor, jsr->retdepth);
-       MCOPY(jsr->retlocals, state->locals, typedescriptor, state->numlocals);
+       MCOPY(jsr->retstack, stackfloor, typedescriptor_t, jsr->retdepth);
+       MCOPY(jsr->retlocals, state->locals, typedescriptor_t, state->numlocals);
 
        /* invalidate the returnAddress used by this RET */
        /* XXX should we also invalidate the returnAddresses of JSRs that are skipped by this RET? */
 
        for (i=0; i<state->numlocals; ++i) {
-               typedescriptor *lc = &(jsr->retlocals[i]);
+               typedescriptor_t *lc = &(jsr->retlocals[i]);
                if (TYPE_IS_RETURNADDRESS(lc->type, lc->typeinfo))
                        if (TYPEINFO_RETURNADDRESS(lc->typeinfo) == tbptr) {
                                LOG1("invalidating returnAddress in local %d", i);
@@ -702,7 +700,7 @@ bool typecheck_stackbased(jitdata *jd)
        verifier_state state;
        basicblock *tbptr;
        exception_entry *ex;
-       typedescriptor exstack;
+       typedescriptor_t exstack;
        s4 skip = 0;
 
        DOLOG( show_method(jd, SHOW_PARSE); );
@@ -784,7 +782,7 @@ bool typecheck_stackbased(jitdata *jd)
                if (state.initmethod)
                        TYPEINFO_INIT_NEWOBJECT(dst->typeinfo, NULL);
                else
-                       typeinfo_init_classinfo(&(dst->typeinfo), state.m->class);
+                       typeinfo_init_classinfo(&(dst->typeinfo), state.m->clazz);
 
                skip = 1;
     }
@@ -981,11 +979,11 @@ throw_stack_category_error:
 
 #if defined(TYPECHECK_VERBOSE)
 static void typecheck_stackbased_show_state(verifier_state *state,
-                                                                                       typedescriptor *stack,
-                                                                                       typedescriptor *stackfloor,
+                                                                                       typedescriptor_t *stack,
+                                                                                       typedescriptor_t *stackfloor,
                                                                                        bool showins)
 {
-       typedescriptor *sp;
+       typedescriptor_t *sp;
        s4 i;
 
        LOGSTR1("stackdepth %d stack [", (stack - stackfloor) + 1);
index e707f2e0d9e5741c298ff91db685e4bb1bac32e4..553bc1421b78fded26782037f5b0fe83adb779b5 100644 (file)
@@ -15,7 +15,7 @@
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 355 "src/vm/jit/verify/icmds.c"
+#              line 347 "src/vm/jit/verify/icmds.c"
   GENERATED    if (IPTR->flags.bits & INS_FLAG_CLASS) {
   GENERATED            /* a java.lang.Class reference */
   GENERATED            TYPEINFO_INIT_JAVA_LANG_CLASS(DST->typeinfo,IPTR->sx.val.c);
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 90 "src/vm/jit/verify/icmds.c"
+#              line 82 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_stack);
   GENERATED    COPYTYPE(IPTR->s1, IPTR->dst);
   GENERATED    DST->type = OP1->type;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 89 "src/vm/jit/verify/icmds.c"
+#              line 81 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_stack);
   GENERATED    COPYTYPE(IPTR->s1, IPTR->dst);
   GENERATED    DST->type = OP1->type;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 99 "src/vm/jit/verify/icmds.c"
+#              line 91 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_aload);
   GENERATED  
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 121 "src/vm/jit/verify/icmds.c"
+#              line 113 "src/vm/jit/verify/icmds.c"
   GENERATED  
 #            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 114 "src/vm/jit/verify/icmds.c"
+#              line 106 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPEINFO_COPY(OP1->typeinfo, DST->typeinfo);
   GENERATED  
 #              line 356 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 414 "src/vm/jit/verify/icmds.c"
+#              line 406 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 396 "src/vm/jit/verify/icmds.c"
+#              line 388 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 587 "src/vm/jit/verify/icmds.c"
+#              line 553 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPEINFO_INIT_RETURNADDRESS(DST->typeinfo, BPTR->next);
   GENERATED    REACH(IPTR->sx.s23.s3.jsrtarget);
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 604 "src/vm/jit/verify/icmds.c"
+#              line 570 "src/vm/jit/verify/icmds.c"
   GENERATED  
 #            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* check returnAddress variable */
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 463 "src/vm/jit/verify/icmds.c"
+#              line 429 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 479 "src/vm/jit/verify/icmds.c"
+#              line 445 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 230 "src/vm/jit/verify/icmds.c"
+#              line 222 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!handle_fieldaccess(state, NULL, NULL))
   GENERATED            return false;
   GENERATED    maythrow = true;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 224 "src/vm/jit/verify/icmds.c"
+#              line 216 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!handle_fieldaccess(state, VAROP(iptr->s1), NULL))
   GENERATED            return false;
   GENERATED    maythrow = true;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 626 "src/vm/jit/verify/icmds.c"
+#              line 592 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_invoke);
   GENERATED    if (!handle_invocation(state))
   GENERATED            EXCEPTION;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 373 "src/vm/jit/verify/icmds.c"
+#              line 365 "src/vm/jit/verify/icmds.c"
   GENERATED  
 #            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* returnAddress is not allowed */
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 669 "src/vm/jit/verify/icmds.c"
+#              line 635 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!handle_multianewarray(STATE))
   GENERATED            EXCEPTION;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 684 "src/vm/jit/verify/icmds.c"
+#              line 650 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_builtin);
   GENERATED    if (!handle_builtin(state))
   GENERATED            EXCEPTION;
index d982267cadc7e899a09606ce3b215e49c642aed6..a4f32b8a42a6665e4021071fadc1f544794c3121 100644 (file)
@@ -15,7 +15,7 @@
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 355 "src/vm/jit/verify/icmds.c"
+#              line 347 "src/vm/jit/verify/icmds.c"
   GENERATED    if (IPTR->flags.bits & INS_FLAG_CLASS) {
   GENERATED            /* a java.lang.Class reference */
   GENERATED            TYPEINFO_INIT_JAVA_LANG_CLASS(DST->typeinfo,IPTR->sx.val.c);
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 90 "src/vm/jit/verify/icmds.c"
+#              line 82 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_stack);
   GENERATED    COPYTYPE(IPTR->s1, IPTR->dst);
   GENERATED    DST->type = OP1->type;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 89 "src/vm/jit/verify/icmds.c"
+#              line 81 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_stack);
   GENERATED    COPYTYPE(IPTR->s1, IPTR->dst);
   GENERATED    DST->type = OP1->type;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 99 "src/vm/jit/verify/icmds.c"
+#              line 91 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_aload);
   GENERATED  
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 266 "src/vm/jit/verify/icmds.c"
+#              line 258 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 276 "src/vm/jit/verify/icmds.c"
+#              line 268 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 261 "src/vm/jit/verify/icmds.c"
+#              line 253 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_FLOAT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 256 "src/vm/jit/verify/icmds.c"
+#              line 248 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_DOUBLE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 121 "src/vm/jit/verify/icmds.c"
+#              line 113 "src/vm/jit/verify/icmds.c"
   GENERATED  
 #            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 245 "src/vm/jit/verify/icmds.c"
+#              line 237 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 251 "src/vm/jit/verify/icmds.c"
+#              line 243 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 271 "src/vm/jit/verify/icmds.c"
+#              line 263 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 114 "src/vm/jit/verify/icmds.c"
+#              line 106 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPEINFO_COPY(OP1->typeinfo, DST->typeinfo);
   GENERATED  
 #              line 493 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 414 "src/vm/jit/verify/icmds.c"
+#              line 406 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 302 "src/vm/jit/verify/icmds.c"
+#              line 294 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 312 "src/vm/jit/verify/icmds.c"
+#              line 304 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 297 "src/vm/jit/verify/icmds.c"
+#              line 289 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_FLOAT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 292 "src/vm/jit/verify/icmds.c"
+#              line 284 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_DOUBLE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 317 "src/vm/jit/verify/icmds.c"
+#              line 309 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we just check the basic input types and that the           */
   GENERATED    /* destination is an array of references. Assignability to    */
   GENERATED    /* the actual array must be checked at runtime, each time the */
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 281 "src/vm/jit/verify/icmds.c"
+#              line 273 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 287 "src/vm/jit/verify/icmds.c"
+#              line 279 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 307 "src/vm/jit/verify/icmds.c"
+#              line 299 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 396 "src/vm/jit/verify/icmds.c"
+#              line 388 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 587 "src/vm/jit/verify/icmds.c"
+#              line 553 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPEINFO_INIT_RETURNADDRESS(DST->typeinfo, BPTR->next);
   GENERATED    REACH(IPTR->sx.s23.s3.jsrtarget);
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 604 "src/vm/jit/verify/icmds.c"
+#              line 570 "src/vm/jit/verify/icmds.c"
   GENERATED  
 #            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* check returnAddress variable */
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 463 "src/vm/jit/verify/icmds.c"
+#              line 429 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 479 "src/vm/jit/verify/icmds.c"
+#              line 445 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 545 "src/vm/jit/verify/icmds.c"
+#              line 511 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_INT)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 550 "src/vm/jit/verify/icmds.c"
+#              line 516 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_LNG)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 555 "src/vm/jit/verify/icmds.c"
+#              line 521 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_FLT)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 560 "src/vm/jit/verify/icmds.c"
+#              line 526 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_DBL)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 520 "src/vm/jit/verify/icmds.c"
+#              line 486 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_areturn);
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("illegal instruction: ARETURN on non-reference");
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 565 "src/vm/jit/verify/icmds.c"
+#              line 531 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_VOID)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
   GENERATED  return_tail:
   GENERATED    TYPECHECK_COUNT(stat_ins_primitive_return);
   GENERATED  
-  GENERATED    if (STATE->initmethod && METHOD->class != class_java_lang_Object) {
+  GENERATED    if (STATE->initmethod && METHOD->clazz != class_java_lang_Object) {
   GENERATED            /* Check if the 'this' instance has been initialized. */
   GENERATED            LOG("Checking <init> marker");
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 230 "src/vm/jit/verify/icmds.c"
+#              line 222 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!handle_fieldaccess(state, NULL, NULL))
   GENERATED            return false;
   GENERATED    maythrow = true;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 176 "src/vm/jit/verify/icmds.c"
+#              line 168 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!handle_fieldaccess(state, NULL, VAROP(iptr->s1)))
   GENERATED            return false;
   GENERATED    maythrow = true;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 224 "src/vm/jit/verify/icmds.c"
+#              line 216 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!handle_fieldaccess(state, VAROP(iptr->s1), NULL))
   GENERATED            return false;
   GENERATED    maythrow = true;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 170 "src/vm/jit/verify/icmds.c"
+#              line 162 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!handle_fieldaccess(state, VAROP(iptr->s1), VAROP(iptr->sx.s23.s2)))
   GENERATED            return false;
   GENERATED    maythrow = true;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 626 "src/vm/jit/verify/icmds.c"
+#              line 592 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_invoke);
   GENERATED    if (!handle_invocation(state))
   GENERATED            EXCEPTION;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 239 "src/vm/jit/verify/icmds.c"
+#              line 231 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY(OP1->typeinfo)
   GENERATED                    && OP1->typeinfo.typeclass.cls != pseudo_class_Arraystub)
   GENERATED            VERIFY_ERROR("illegal instruction: ARRAYLENGTH on non-array");
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 499 "src/vm/jit/verify/icmds.c"
+#              line 465 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_athrow);
   GENERATED    r = typeinfo_is_assignable_to_class(&OP1->typeinfo,
   GENERATED                    CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
   GENERATED                            METHOD,
   GENERATED                            /* XXX make this more efficient, use class_java_lang_Throwable
   GENERATED                             * directly */
-  GENERATED                            class_get_classref(METHOD->class,utf_java_lang_Throwable),
+  GENERATED                            class_get_classref(METHOD->clazz,utf_java_lang_Throwable),
   GENERATED                            &OP1->typeinfo);
   GENERATED            IPTR->flags.bits |= INS_FLAG_UNRESOLVED;
   GENERATED    }
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 373 "src/vm/jit/verify/icmds.c"
+#              line 365 "src/vm/jit/verify/icmds.c"
   GENERATED  
 #            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* returnAddress is not allowed */
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 385 "src/vm/jit/verify/icmds.c"
+#              line 377 "src/vm/jit/verify/icmds.c"
   GENERATED    /* returnAddress is not allowed */
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("Illegal instruction: INSTANCEOF on non-reference");
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 669 "src/vm/jit/verify/icmds.c"
+#              line 635 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!handle_multianewarray(STATE))
   GENERATED            EXCEPTION;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 326 "src/vm/jit/verify/icmds.c"
+#              line 318 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 331 "src/vm/jit/verify/icmds.c"
+#              line 323 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 336 "src/vm/jit/verify/icmds.c"
+#              line 328 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 342 "src/vm/jit/verify/icmds.c"
+#              line 334 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 347 "src/vm/jit/verify/icmds.c"
+#              line 339 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
   GENERATED    maythrow = true;
   GENERATED  
   GENERATED  
-#              line 203 "src/vm/jit/verify/icmds.c"
+#              line 195 "src/vm/jit/verify/icmds.c"
   GENERATED    /* XXX this mess will go away with const operands */
   GENERATED    INSTRUCTION_GET_FIELDREF(state->iptr, fieldref);
   GENERATED    constvalue.type = fieldref->parseddesc.fd->type;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 182 "src/vm/jit/verify/icmds.c"
+#              line 174 "src/vm/jit/verify/icmds.c"
   GENERATED    /* XXX this mess will go away with const operands */
   GENERATED    INSTRUCTION_GET_FIELDREF(state->iptr, fieldref);
   GENERATED    constvalue.type = fieldref->parseddesc.fd->type;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 684 "src/vm/jit/verify/icmds.c"
+#              line 650 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_builtin);
   GENERATED    if (!handle_builtin(state))
   GENERATED            EXCEPTION;
index 3b89744d3d3e8fc9219324bcb94c756f137f47b8..e679e952645e0c5ca947763a544f71c797179272 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck.c - typechecking (part of bytecode verification)
 
-   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.
 
@@ -422,7 +420,7 @@ static void typecheck_invalidate_locals(verifier_state *state, s4 index, bool tw
        s4 *localmap = jd->local_map;
        varinfo *vars = jd->var;
 
-       javaindex = state->reverselocalmap[index];
+       javaindex = jd->reverselocalmap[index];
 
        /* invalidate locals of two-word type at index javaindex-1 */
 
@@ -681,8 +679,6 @@ bool typecheck(jitdata *jd)
        codegendata    *cd;
        varinfo        *savedlocals;
        verifier_state  state;             /* current state of the verifier */
-       s4              i;
-       s4              t;
 
        /* collect statistics */
 
@@ -744,18 +740,12 @@ bool typecheck(jitdata *jd)
     if (state.initmethod) 
                state.numlocals++; /* VERIFIER_EXTRA_LOCALS */
 
-       state.reverselocalmap = DMNEW(s4, state.validlocals);
-       for (i=0; i<jd->maxlocals; ++i)
-               for (t=0; t<5; ++t) {
-                       s4 varindex = jd->local_map[5*i + t];
-                       if (varindex >= 0)
-                               state.reverselocalmap[varindex] = i;
-               }
-
        DOLOG(
+               s4 i;
+               s4 t;
                LOG("reverselocalmap:");
                for (i=0; i<state.validlocals; ++i) {
-                       LOG2("    %i => javaindex %i", i, state.reverselocalmap[i]);
+                       LOG2("    %i => javaindex %i", i, jd->reverselocalmap[i]);
                });
 
     /* allocate the buffer of active exception handlers */
index b3313cea5bfc6e584994f6a2057bf03309aa2d53..f31c4c958b982eb569f296cd29ec59b05dff3e94 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typeinfo.c - type system used by the type checker
 
-   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.
 
@@ -193,7 +191,7 @@ typevector_checkretaddr(varinfo *vec,int index)
 *******************************************************************************/
 
 void
-typevector_store(varinfo *vec,int index,int type,typeinfo *info)
+typevector_store(varinfo *vec,int index,int type,typeinfo_t *info)
 {
        TYPEINFO_ASSERT(vec);
 
@@ -214,7 +212,7 @@ typevector_store(varinfo *vec,int index,int type,typeinfo *info)
 *******************************************************************************/
 
 void
-typevector_store_retaddr(varinfo *vec,int index,typeinfo *info)
+typevector_store_retaddr(varinfo *vec,int index,typeinfo_t *info)
 {
        TYPEINFO_ASSERT(vec);
        TYPEINFO_ASSERT(TYPEINFO_IS_PRIMITIVE(*info));
@@ -347,7 +345,7 @@ typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size)
 *******************************************************************************/
 
 bool
-typeinfo_is_array(typeinfo *info)
+typeinfo_is_array(typeinfo_t *info)
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_ARRAY(*info);
@@ -366,7 +364,7 @@ typeinfo_is_array(typeinfo *info)
 *******************************************************************************/
 
 bool
-typeinfo_is_primitive_array(typeinfo *info,int arraytype)
+typeinfo_is_primitive_array(typeinfo_t *info,int arraytype)
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_PRIMITIVE_ARRAY(*info,arraytype);
@@ -385,7 +383,7 @@ typeinfo_is_primitive_array(typeinfo *info,int arraytype)
 *******************************************************************************/
 
 bool
-typeinfo_is_array_of_refs(typeinfo *info)
+typeinfo_is_array_of_refs(typeinfo_t *info)
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_ARRAY_OF_REFS(*info);
@@ -490,7 +488,7 @@ classinfo_implements_interface(classinfo *cls,classinfo *interf)
 *******************************************************************************/
 
 static typecheck_result
-mergedlist_implements_interface(typeinfo_mergedlist *merged,
+mergedlist_implements_interface(typeinfo_mergedlist_t *merged,
                                 classinfo *interf)
 {
     int i;
@@ -540,7 +538,7 @@ mergedlist_implements_interface(typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 static typecheck_result
-merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
+merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist_t *merged,
                             classinfo *interf)
 {
        typecheck_result r;
@@ -587,7 +585,7 @@ merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 static typecheck_result
-merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
+merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist_t *merged,
                classinfo *cls)
 {
     int i;
@@ -652,7 +650,7 @@ merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 typecheck_result
-typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
+typeinfo_is_assignable_to_class(typeinfo_t *value,classref_or_classinfo dest)
 {
        classref_or_classinfo c;
     classinfo *cls;
@@ -745,7 +743,7 @@ typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
                arraydescriptor *arraydesc = dest.cls->vftbl->arraydesc;
                int dimension = arraydesc->dimension;
                classinfo *elementclass = (arraydesc->elementvftbl)
-                       ? arraydesc->elementvftbl->class : NULL;
+                       ? arraydesc->elementvftbl->clazz : NULL;
                        
         /* We are assigning to an array type. */
         if (!TYPEINFO_IS_ARRAY(*value))
@@ -838,7 +836,7 @@ typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
 *******************************************************************************/
 
 typecheck_result
-typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
+typeinfo_is_assignable(typeinfo_t *value,typeinfo_t *dest)
 {
        TYPEINFO_ASSERT(value);
        TYPEINFO_ASSERT(dest);
@@ -869,11 +867,11 @@ typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
 *******************************************************************************/
 
 void
-typeinfo_init_classinfo(typeinfo *info, classinfo *c)
+typeinfo_init_classinfo(typeinfo_t *info, classinfo *c)
 {
        if ((info->typeclass.cls = c)->vftbl->arraydesc) {
                if (c->vftbl->arraydesc->elementvftbl)
-                       info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->class;
+                       info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->clazz;
                else
                        info->elementclass.any = NULL;
                info->dimension = c->vftbl->arraydesc->dimension;
@@ -904,7 +902,7 @@ typeinfo_init_classinfo(typeinfo *info, classinfo *c)
 *******************************************************************************/
 
 bool
-typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
+typeinfo_init_class(typeinfo_t *info,classref_or_classinfo c)
 {
        char *utf_ptr;
        int len;
@@ -975,7 +973,7 @@ typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
 *******************************************************************************/
 
 bool
-typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
+typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo_t *info)
 {
        TYPEINFO_ASSERT(desc);
 
@@ -1033,9 +1031,9 @@ typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
 *******************************************************************************/
 
 bool
-typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
+typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo_t *infobuf,
                               int buflen,bool twoword,
-                              u1 *returntype,typeinfo *returntypeinfo)
+                              u1 *returntype,typeinfo_t *returntypeinfo)
 {
        int i;
     int args = 0;
@@ -1099,7 +1097,7 @@ typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
 *******************************************************************************/
 
 bool
-typedescriptor_init_from_typedesc(typedescriptor *td,
+typedescriptor_init_from_typedesc(typedescriptor_t *td,
                                                                  typedesc *desc)
 {
        TYPEINFO_ASSERT(td);
@@ -1188,7 +1186,7 @@ typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
                                                                         methoddesc *desc,
                                                                         int buflen, int startindex,
                                                                         s4 *map,
-                                                                        typedescriptor *returntype)
+                                                                        typedescriptor_t *returntype)
 {
        s4 i;
     s4 varindex;
@@ -1264,10 +1262,10 @@ typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
 *******************************************************************************/
 
 int
-typedescriptors_init_from_methoddesc(typedescriptor *td,
+typedescriptors_init_from_methoddesc(typedescriptor_t *td,
                                                                         methoddesc *desc,
                                                                         int buflen,bool twoword,int startindex,
-                                                                        typedescriptor *returntype)
+                                                                        typedescriptor_t *returntype)
 {
        int i;
     int args = 0;
@@ -1321,9 +1319,9 @@ typedescriptors_init_from_methoddesc(typedescriptor *td,
 *******************************************************************************/
 
 bool
-typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
+typeinfo_init_component(typeinfo_t *srcarray,typeinfo_t *dst)
 {
-       typeinfo_mergedlist *merged;
+       typeinfo_mergedlist_t *merged;
 
        TYPEINFO_ASSERT(srcarray);
        TYPEINFO_ASSERT(dst);
@@ -1369,7 +1367,7 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
 
                comp = srcarray->typeclass.cls->vftbl->arraydesc->componentvftbl;
                if (comp)
-                       typeinfo_init_classinfo(dst,comp->class);
+                       typeinfo_init_classinfo(dst,comp->clazz);
                else
                        TYPEINFO_INIT_PRIMITIVE(*dst);
        }
@@ -1394,7 +1392,7 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
 *******************************************************************************/
 
 void
-typeinfo_clone(typeinfo *src,typeinfo *dest)
+typeinfo_clone(typeinfo_t *src,typeinfo_t *dest)
 {
     int count;
     classref_or_classinfo *srclist,*destlist;
@@ -1431,7 +1429,7 @@ typeinfo_clone(typeinfo *src,typeinfo *dest)
 *******************************************************************************/
 
 void
-typeinfo_free(typeinfo *info)
+typeinfo_free(typeinfo_t *info)
 {
     TYPEINFO_FREEMERGED_IF_ANY(info->merged);
     info->merged = NULL;
@@ -1445,7 +1443,7 @@ typeinfo_free(typeinfo *info)
 
 static
 void
-typeinfo_merge_error(methodinfo *m,char *str,typeinfo *x,typeinfo *y) {
+typeinfo_merge_error(methodinfo *m,char *str,typeinfo_t *x,typeinfo_t *y) {
 #ifdef TYPEINFO_VERBOSE
     fprintf(stderr,"Error in typeinfo_merge: %s\n",str);
     fprintf(stderr,"Typeinfo x:\n");
@@ -1462,7 +1460,7 @@ typeinfo_merge_error(methodinfo *m,char *str,typeinfo *x,typeinfo *y) {
 /* Returns: true if dest was changed (currently always true). */
 static
 bool
-typeinfo_merge_two(typeinfo *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
+typeinfo_merge_two(typeinfo_t *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
 {
        TYPEINFO_ASSERT(dest);
     TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
@@ -1486,10 +1484,10 @@ typeinfo_merge_two(typeinfo *dest,classref_or_classinfo clsx,classref_or_classin
 /* Returns: true if dest was changed. */
 static
 bool
-typeinfo_merge_add(typeinfo *dest,typeinfo_mergedlist *m,classref_or_classinfo cls)
+typeinfo_merge_add(typeinfo_t *dest,typeinfo_mergedlist_t *m,classref_or_classinfo cls)
 {
     int count;
-    typeinfo_mergedlist *newmerged;
+    typeinfo_mergedlist_t *newmerged;
     classref_or_classinfo *mlist,*newlist;
 
     count = m->count;
@@ -1543,12 +1541,12 @@ typeinfo_merge_add(typeinfo *dest,typeinfo_mergedlist *m,classref_or_classinfo c
 /* Returns: true if dest was changed. */
 static
 bool
-typeinfo_merge_mergedlists(typeinfo *dest,typeinfo_mergedlist *x,
-                           typeinfo_mergedlist *y)
+typeinfo_merge_mergedlists(typeinfo_t *dest,typeinfo_mergedlist_t *x,
+                           typeinfo_mergedlist_t *y)
 {
     int count = 0;
     int countx,county;
-    typeinfo_mergedlist *temp,*result;
+    typeinfo_mergedlist_t *temp,*result;
     classref_or_classinfo *clsx,*clsy,*newlist;
 
     /* count the elements that will be in the resulting list */
@@ -1667,15 +1665,15 @@ typeinfo_merge_mergedlists(typeinfo *dest,typeinfo_mergedlist *x,
 *******************************************************************************/
 
 static typecheck_result
-typeinfo_merge_nonarrays(typeinfo *dest,
+typeinfo_merge_nonarrays(typeinfo_t *dest,
                          classref_or_classinfo *result,
                          classref_or_classinfo x,classref_or_classinfo y,
-                         typeinfo_mergedlist *mergedx,
-                         typeinfo_mergedlist *mergedy)
+                         typeinfo_mergedlist_t *mergedx,
+                         typeinfo_mergedlist_t *mergedy)
 {
        classref_or_classinfo t;
     classinfo *tcls,*common;
-    typeinfo_mergedlist *tmerged;
+    typeinfo_mergedlist_t *tmerged;
     bool changed;
        typecheck_result r;
        utf *xname;
@@ -1724,7 +1722,7 @@ typeinfo_merge_nonarrays(typeinfo *dest,
 
 #ifdef TYPEINFO_VERBOSE
        {
-               typeinfo dbgx,dbgy;
+               typeinfo_t dbgx,dbgy;
                fprintf(stderr,"merge_nonarrays:\n");
                fprintf(stderr,"    ");if(IS_CLASSREF(x))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,xname);fprintf(stderr,"\n");
                fprintf(stderr,"    ");if(IS_CLASSREF(y))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,yname);fprintf(stderr,"\n");
@@ -1913,10 +1911,10 @@ merge_with_simple_x:
 *******************************************************************************/
 
 typecheck_result
-typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y)
+typeinfo_merge(methodinfo *m,typeinfo_t *dest,typeinfo_t* y)
 {
-    typeinfo *x;
-    typeinfo *tmp;
+    typeinfo_t *x;
+    typeinfo_t *tmp;
     classref_or_classinfo common;
     classref_or_classinfo elementclass;
     int dimension;
@@ -2154,11 +2152,11 @@ typeinfo_test_compare(classref_or_classinfo *a,classref_or_classinfo *b)
 }
 
 static void
-typeinfo_test_parse(typeinfo *info,char *str)
+typeinfo_test_parse(typeinfo_t *info,char *str)
 {
     int num;
     int i;
-    typeinfo *infobuf;
+    typeinfo_t *infobuf;
     u1 *typebuf;
     int returntype;
     utf *desc = utf_new_char(str);
@@ -2166,7 +2164,7 @@ typeinfo_test_parse(typeinfo *info,char *str)
     num = typeinfo_count_method_args(desc,false);
     if (num) {
         typebuf = DMNEW(u1,num);
-        infobuf = DMNEW(typeinfo,num);
+        infobuf = DMNEW(typeinfo_t,num);
         
         typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
                                        &returntype,info);
@@ -2195,7 +2193,7 @@ typeinfo_test_parse(typeinfo *info,char *str)
 #define TYPEINFO_TEST_BUFLEN  4000
 
 static bool
-typeinfo_equal(typeinfo *x,typeinfo *y)
+typeinfo_equal(typeinfo_t *x,typeinfo_t *y)
 {
     int i;
     
@@ -2222,9 +2220,9 @@ typeinfo_equal(typeinfo *x,typeinfo *y)
 }
 
 static void
-typeinfo_testmerge(typeinfo *a,typeinfo *b,typeinfo *result,int *failed)
+typeinfo_testmerge(typeinfo_t *a,typeinfo_t *b,typeinfo_t *result,int *failed)
 {
-    typeinfo dest;
+    typeinfo_t dest;
     bool changed,changed_should_be;
        typecheck_result r;
 
@@ -2268,7 +2266,7 @@ typeinfo_testmerge(typeinfo *a,typeinfo *b,typeinfo *result,int *failed)
 
 #if 0
 static void
-typeinfo_inc_dimension(typeinfo *info)
+typeinfo_inc_dimension(typeinfo_t *info)
 {
     if (info->dimension++ == 0) {
         info->elementtype = ARRAYTYPE_OBJECT;
@@ -2287,7 +2285,7 @@ typeinfo_testrun(char *filename)
     char bufa[TYPEINFO_TEST_BUFLEN];
     char bufb[TYPEINFO_TEST_BUFLEN];
     char bufc[TYPEINFO_TEST_BUFLEN];
-    typeinfo a,b,c;
+    typeinfo_t a,b,c;
     int maxdim;
     int failed = 0;
     FILE *file = fopen(filename,"rt");
@@ -2356,7 +2354,7 @@ typeinfo_test()
 
 #if 0
 void
-typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc)
+typeinfo_init_from_fielddescriptor(typeinfo_t *info,char *desc)
 {
     typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
 }
@@ -2384,7 +2382,7 @@ typeinfo_print_class(FILE *file,classref_or_classinfo c)
 }
 
 void
-typeinfo_print(FILE *file,typeinfo *info,int indent)
+typeinfo_print(FILE *file,typeinfo_t *info,int indent)
 {
     int i;
     char ind[TYPEINFO_MAXINDENT + 1];
@@ -2462,7 +2460,7 @@ typeinfo_print(FILE *file,typeinfo *info,int indent)
 }
 
 void
-typeinfo_print_short(FILE *file,typeinfo *info)
+typeinfo_print_short(FILE *file,typeinfo_t *info)
 {
     int i;
     instruction *ins;
@@ -2514,7 +2512,7 @@ typeinfo_print_short(FILE *file,typeinfo *info)
 }
 
 void
-typeinfo_print_type(FILE *file,int type,typeinfo *info)
+typeinfo_print_type(FILE *file,int type,typeinfo_t *info)
 {
     switch (type) {
       case TYPE_VOID: fprintf(file,"V"); break;
@@ -2533,7 +2531,7 @@ typeinfo_print_type(FILE *file,int type,typeinfo *info)
 }
 
 void
-typedescriptor_print(FILE *file,typedescriptor *td)
+typedescriptor_print(FILE *file,typedescriptor_t *td)
 {
        typeinfo_print_type(file,td->type,&(td->typeinfo));
 }
index 10125f12cd620f368e1fa803f98910c21427d49c..e35214928f421996efb3fd6f0d1e835c6bca2288 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typeinfo.h - type system used by the type checker
 
-   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.
 
@@ -29,9 +27,9 @@
 
 /* resolve typedef cycles *****************************************************/
 
-typedef struct typeinfo typeinfo;
-typedef struct typeinfo_mergedlist typeinfo_mergedlist;
-typedef struct typedescriptor typedescriptor;
+typedef struct typeinfo            typeinfo_t;
+typedef struct typeinfo_mergedlist typeinfo_mergedlist_t;
+typedef struct typedescriptor      typedescriptor_t;
 
 #include "config.h"
 #include "vm/types.h"
@@ -234,7 +232,7 @@ typedef enum {
 struct typeinfo {
        classref_or_classinfo  typeclass;
        classref_or_classinfo  elementclass; /* valid if dimension>0 */ /* various uses! */
-       typeinfo_mergedlist   *merged;
+       typeinfo_mergedlist_t *merged;
        u1                     dimension;
        u1                     elementtype;  /* valid if dimension>0           */
 };
@@ -249,7 +247,7 @@ struct typeinfo_mergedlist {
 /* storing types in the signature of a method                            */
 
 struct typedescriptor {
-       typeinfo        typeinfo; /* valid if type == TYPE_ADR               */
+       typeinfo_t      typeinfo; /* valid if type == TYPE_ADR               */
        u1              type;     /* basic type (TYPE_INT, ...)              */
 };
 
@@ -267,10 +265,10 @@ struct typedescriptor {
     ((size) * sizeof(varinfo)) 
 
 #define DNEW_TYPEVECTOR(size)                                          \
-    ((varinfo*)dump_alloc(TYPEVECTOR_SIZE(size)))
+    ((varinfo *) DMNEW(uint8_t, TYPEVECTOR_SIZE(size)))
 
 #define DMNEW_TYPEVECTOR(num,size)                                             \
-    ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size)))
+    ((void *) DMNEW(uint8_t, (num) * TYPEVECTOR_SIZE(size)))
 
 #define MGET_TYPEVECTOR(array,index,size) \
     ((varinfo*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
@@ -278,9 +276,9 @@ struct typedescriptor {
 /* internally used macros ***************************************************/
 
 /* internal, don't use this explicitly! */
-#define TYPEINFO_ALLOCMERGED(mergedlist,count)                  \
-    do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc(        \
-            sizeof(typeinfo_mergedlist)                         \
+#define TYPEINFO_ALLOCMERGED(mergedlist,count)                                 \
+    do {(mergedlist) = (typeinfo_mergedlist_t *) DMNEW(uint8_t,        \
+            sizeof(typeinfo_mergedlist_t)                       \
             + ((count)-1)*sizeof(classinfo*));} while(0)
 
 /* internal, don't use this explicitly! */
@@ -440,8 +438,8 @@ bool typevector_checkreference(varinfo *set,int index);
 bool typevector_checkretaddr(varinfo *set,int index);
 
 /* element write access */
-void typevector_store(varinfo *set,int index,int type,typeinfo *info);
-void typevector_store_retaddr(varinfo *set,int index,typeinfo *info);
+void typevector_store(varinfo *set,int index,int type,typeinfo_t *info);
+void typevector_store_retaddr(varinfo *set,int index,typeinfo_t *info);
 bool typevector_init_object(varinfo *set,void *ins,classref_or_classinfo initclass,int size);
 
 /* vector functions */
@@ -451,12 +449,12 @@ typecheck_result typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size
 
 /* inquiry functions (read-only) ********************************************/
 
-bool typeinfo_is_array(typeinfo *info);
-bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
-bool typeinfo_is_array_of_refs(typeinfo *info);
+bool typeinfo_is_array(typeinfo_t *info);
+bool typeinfo_is_primitive_array(typeinfo_t *info,int arraytype);
+bool typeinfo_is_array_of_refs(typeinfo_t *info);
 
-typecheck_result typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
-typecheck_result typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest);
+typecheck_result typeinfo_is_assignable(typeinfo_t *value,typeinfo_t *dest);
+typecheck_result typeinfo_is_assignable_to_class(typeinfo_t *value,classref_or_classinfo dest);
 
 /* initialization functions *************************************************/
 
@@ -468,38 +466,38 @@ typecheck_result typeinfo_is_assignable_to_class(typeinfo *value,classref_or_cla
  *     >= 0.............ok,
  *     -1...............an exception has been thrown.
  */
-void typeinfo_init_classinfo(typeinfo *info,classinfo *c);
-bool typeinfo_init_class(typeinfo *info,classref_or_classinfo c);
-bool typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
+void typeinfo_init_classinfo(typeinfo_t *info,classinfo *c);
+bool typeinfo_init_class(typeinfo_t *info,classref_or_classinfo c);
+bool typeinfo_init_component(typeinfo_t *srcarray,typeinfo_t *dst);
 
-bool typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info);
+bool typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo_t *info);
 bool typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,
-                                   typeinfo *infobuf,
+                                   typeinfo_t *infobuf,
                                    int buflen,bool twoword,
-                                   u1 *returntype,typeinfo *returntypeinfo);
-bool  typedescriptor_init_from_typedesc(typedescriptor *td,
+                                   u1 *returntype,typeinfo_t *returntypeinfo);
+bool  typedescriptor_init_from_typedesc(typedescriptor_t *td,
                                                                            typedesc *desc);
 bool  typeinfo_init_varinfo_from_typedesc(varinfo *var,
                                                                            typedesc *desc);
-int  typedescriptors_init_from_methoddesc(typedescriptor *td,
+int  typedescriptors_init_from_methoddesc(typedescriptor_t *td,
                                                                                  methoddesc *desc,
                                                                                  int buflen,bool twoword,int startindex,
-                                                                                 typedescriptor *returntype);
+                                                                                 typedescriptor_t *returntype);
 bool typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
                                                                                  methoddesc *desc,
                                                                                  int buflen, int startindex,
                                                                                  s4 *map,
-                                                                                 typedescriptor *returntype);
+                                                                                 typedescriptor_t *returntype);
 
-void typeinfo_clone(typeinfo *src,typeinfo *dest);
+void typeinfo_clone(typeinfo_t *src,typeinfo_t *dest);
 
 /* freeing memory ***********************************************************/
 
-void typeinfo_free(typeinfo *info);
+void typeinfo_free(typeinfo_t *info);
 
 /* functions for merging types **********************************************/
 
-typecheck_result typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y);
+typecheck_result typeinfo_merge(methodinfo *m,typeinfo_t *dest,typeinfo_t* y);
 
 /* debugging helpers ********************************************************/
 
@@ -509,10 +507,10 @@ typecheck_result typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y);
 
 void typeinfo_test();
 void typeinfo_print_class(FILE *file,classref_or_classinfo c);
-void typeinfo_print(FILE *file,typeinfo *info,int indent);
-void typeinfo_print_short(FILE *file,typeinfo *info);
-void typeinfo_print_type(FILE *file,int type,typeinfo *info);
-void typedescriptor_print(FILE *file,typedescriptor *td);
+void typeinfo_print(FILE *file,typeinfo_t *info,int indent);
+void typeinfo_print_short(FILE *file,typeinfo_t *info);
+void typeinfo_print_type(FILE *file,int type,typeinfo_t *info);
+void typedescriptor_print(FILE *file,typedescriptor_t *td);
 void typevector_print(FILE *file,varinfo *vec,int size);
 
 #endif /* TYPEINFO_DEBUG */
index 528e9d14bcf487543a85f49c60614f180c88f02d..839f39c7bcef3faf045f13b81974c4071f50968f 100644 (file)
@@ -1,9 +1,7 @@
 ## src/vm/jit/x86_64/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.
 ##
@@ -58,7 +56,9 @@ libarch_la_SOURCES = \
        \
        md-abi.c \
        md-abi.h \
-       md.c
+       md-trap.h \
+       md.c \
+       md.h
 
 libarch_la_LIBADD = \
        $(OS_DIR)/libmd.la
index c83eb000bc98129ab89b2b191cbc9a995708fb16..8e5429847a68e936f9029e53c07d3c543bafce65 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
 
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
+   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
@@ -149,9 +149,9 @@ L_asm_vm_call_method_stack_copy_done:
        mov     (0*8+256)(mptr),itmp3       /* load PV                            */
        call    *itmp3
 
+L_asm_vm_call_method_return:
        mov     s0,sp                       /* restore SP                         */
 
-L_asm_vm_call_method_return:
        mov     0*8(sp),%rbx                /* restore callee saved registers     */
        mov     1*8(sp),s0
        mov     2*8(sp),s1
@@ -203,7 +203,7 @@ L_asm_handle_exception_stack_loop:
        mov     t0,4*8(sp)                  /* save maybe-leaf flag               */
 
        mov     xpc,a0                      /* exception pc                       */
-       call    codegen_get_pv_from_pc@PLT
+       call    methodtree_find@PLT
        mov     v0,2*8(sp)                  /* save data segment pointer          */
         
        mov     0*8(sp),a0                  /* pass exception pointer             */
index e53ccd6c41fd83ceec365f4bfa8ca518a635dcf3..a93f42b5234c24d7bb0165d0663931ecb6419925 100644 (file)
@@ -67,6 +67,7 @@
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
@@ -264,12 +265,12 @@ bool codegen_emit(jitdata *jd)
                /* decide which monitor enter function to call */
 
                if (m->flags & ACC_STATIC) {
-                       M_MOV_IMM(&m->class->object.header, REG_A0);
+                       M_MOV_IMM(&m->clazz->object.header, REG_A0);
                }
                else {
                        M_TEST(REG_A0);
                        M_BNE(8);
-                       M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ALD_MEM(REG_A0, TRAP_NullPointerException);
                }
 
                M_AST(REG_A0, REG_SP, s1 * 8);
@@ -1750,11 +1751,11 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        PROFILE_CYCLE_STOP;
 
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                                                 fi->class, 0);
+                                                                                 fi->clazz, 0);
 
                                        PROFILE_CYCLE_START;
                                }
@@ -1805,11 +1806,11 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        PROFILE_CYCLE_STOP;
 
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                                                 fi->class, 0);
+                                                                                 fi->clazz, 0);
 
                                        PROFILE_CYCLE_START;
                                }
@@ -1861,11 +1862,11 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        PROFILE_CYCLE_STOP;
 
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
-                                                                                 fi->class, 0);
+                                                                                 fi->clazz, 0);
 
                                        PROFILE_CYCLE_START;
                                }
@@ -2432,9 +2433,9 @@ gen_method:
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr) * lm->class->index;
+                                               sizeof(methodptr) * lm->clazz->index;
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
 
                                /* implicit null-pointer check */
index 6ce0eb3a3a4bc87c77bee2977932abece1314850..60e5f342d83933740c4e97524b90ef24aaf7622d 100644 (file)
@@ -39,8 +39,6 @@
 
 #include "threads/lock-common.h"
 
-#include "vm/exceptions.h"
-
 #include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
@@ -50,6 +48,7 @@
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 #include "vm/jit/trace.h"
+#include "vm/jit/trap.h"
 
 #include "vmcore/options.h"
 
@@ -115,38 +114,11 @@ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
        s4            disp;
-#if 0
-       s4            s;
-       u2            opcode;
-#endif
 
        /* get required compiler data */
 
        cd = jd->cd;
 
-#if 0
-       /* do we have to generate a conditional move? */
-
-       if ((iptr != NULL) && (iptr->opc & ICMD_CONDITION_MASK)) {
-               /* the passed register d is actually the source register */
-
-               s = d;
-
-               /* Only pass the opcode to codegen_reg_of_var to get the real
-                  destination register. */
-
-               opcode = iptr->opc & ICMD_OPCODE_MASK;
-
-               /* get the real destination register */
-
-               d = codegen_reg_of_var(rd, opcode, dst, REG_ITMP1);
-
-               /* and emit the conditional move */
-
-               emit_cmovxx(cd, iptr, s, d);
-       }
-#endif
-
        if (IS_INMEMORY(dst->flags)) {
                COUNT_SPILLS;
 
@@ -338,7 +310,7 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(reg);
                M_BNE(8);
-               M_ALD_MEM(reg, EXCEPTION_HARDWARE_ARITHMETIC);
+               M_ALD_MEM(reg, TRAP_ArithmeticException);
        }
 }
 
@@ -355,7 +327,7 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1,
         M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
         M_ICMP(REG_ITMP3, s2);
                M_BULT(8);
-               M_ALD_MEM(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+               M_ALD_MEM(s2, TRAP_ArrayIndexOutOfBoundsException);
        }
 }
 
@@ -371,7 +343,7 @@ void emit_arraystore_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(REG_RESULT);
                M_BNE(8);
-               M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_ARRAYSTORE);
+               M_ALD_MEM(REG_RESULT, TRAP_ArrayStoreException);
        }
 }
 
@@ -398,7 +370,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r
                default:
                        vm_abort("emit_classcast_check: unknown condition %d", condition);
                }
-               M_ALD_MEM(s1, EXCEPTION_HARDWARE_CLASSCAST);
+               M_ALD_MEM(s1, TRAP_ClassCastException);
        }
 }
 
@@ -414,7 +386,7 @@ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(reg);
                M_BNE(8);
-               M_ALD_MEM(reg, EXCEPTION_HARDWARE_NULLPOINTER);
+               M_ALD_MEM(reg, TRAP_NullPointerException);
        }
 }
 
@@ -430,7 +402,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
        if (INSTRUCTION_MUST_CHECK(iptr)) {
                M_TEST(REG_RESULT);
                M_BNE(8);
-               M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_EXCEPTION);
+               M_ALD_MEM(REG_RESULT, TRAP_CHECK_EXCEPTION);
        }
 }
 
@@ -443,7 +415,7 @@ void emit_exception_check(codegendata *cd, instruction *iptr)
 
 void emit_trap_compiler(codegendata *cd)
 {
-       M_ALD_MEM(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+       M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
 }
 
 
@@ -1388,12 +1360,12 @@ void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
 
 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
        if (IS_IMM8(imm)) {
-               emit_rex(1,(basereg),0,0);
+               emit_rex(1,0,0,(basereg));
                *(cd->mcodeptr++) = 0x83;
                emit_membase(cd, (basereg),(disp),(opc));
                emit_imm8((imm));
        } else {
-               emit_rex(1,(basereg),0,0);
+               emit_rex(1,0,0,(basereg));
                *(cd->mcodeptr++) = 0x81;
                emit_membase(cd, (basereg),(disp),(opc));
                emit_imm32((imm));
@@ -1403,12 +1375,12 @@ void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp)
 
 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
        if (IS_IMM8(imm)) {
-               emit_rex(0,(basereg),0,0);
+               emit_rex(0,0,0,(basereg));
                *(cd->mcodeptr++) = 0x83;
                emit_membase(cd, (basereg),(disp),(opc));
                emit_imm8((imm));
        } else {
-               emit_rex(0,(basereg),0,0);
+               emit_rex(0,0,0,(basereg));
                *(cd->mcodeptr++) = 0x81;
                emit_membase(cd, (basereg),(disp),(opc));
                emit_imm32((imm));
index 0f0f74f51e72e3e845688e8b0fac8a8e4737c6a1..6e4a2b227853841547c3ab343db497ff64399165 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/x86_64/freebsd/md-os.c - machine dependent x86_64 FreeBSD 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.
 
@@ -31,9 +29,7 @@
 #include <stdlib.h>
 #include <ucontext.h>
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/signallocal.h"
 
index fae1c417f7a688b915f2514821dfb0686869de46..8b8bf32d51f1a44dc0e920b70370ba58d2dd31b5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/x86_64/linux/md-os.c - machine dependent x86_64 Linux 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.
 
 #include "vm/jit/x86_64/codegen.h"
 #include "vm/jit/x86_64/md.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
 #include "vm/signallocal.h"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
+#include "vm/jit/trap.h"
 #include "vm/jit/stacktrace.h"
 
 
@@ -155,7 +152,7 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 
                val = _mc->gregs[d];
 
-               if (type == EXCEPTION_HARDWARE_COMPILER) {
+               if (type == TRAP_COMPILER) {
                        /* The PV from the compiler stub is equal to the XPC. */
 
                        pv = xpc;
@@ -178,17 +175,17 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
        else {
                /* this was a normal NPE */
 
-               type = EXCEPTION_HARDWARE_NULLPOINTER;
+               type = TRAP_NullPointerException;
                val  = 0;
        }
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* Set registers. */
 
-       if (type == EXCEPTION_HARDWARE_COMPILER) {
+       if (type == TRAP_COMPILER) {
                if (p == NULL) {
                        o = builtin_retrieve_exception();
 
@@ -240,14 +237,14 @@ void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
        xpc = (u1 *) _mc->gregs[REG_RIP];
        ra  = xpc;                          /* return address is equal to xpc     */
 
-       /* this is an ArithmeticException */
+       /* This is an ArithmeticException. */
 
-       type = EXCEPTION_HARDWARE_ARITHMETIC;
+       type = TRAP_ArithmeticException;
        val  = 0;
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* set registers */
 
@@ -288,12 +285,12 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
 
        /* This is a patcher. */
 
-       type = EXCEPTION_HARDWARE_PATCHER;
+       type = TRAP_PATCHER;
        val  = 0;
 
-       /* Handle the type. */
+       /* Handle the trap. */
 
-       p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+       p = trap_handle(type, val, pv, sp, ra, xpc, _p);
 
        /* set registers */
 
@@ -364,14 +361,13 @@ void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
 #endif
 
 
-/* md_replace_executionstate_read **********************************************
+/* md_executionstate_read ******************************************************
 
-   Read the given context into an executionstate for Replacement.
+   Read the given context into an executionstate.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_read(executionstate_t *es, void *context)
+void md_executionstate_read(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
@@ -382,7 +378,7 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
        _mc = &_uc->uc_mcontext;
 
        /* read special registers */
-       es->pc = (u1 *) _mc->gregs[REG_RSP];
+       es->pc = (u1 *) _mc->gregs[REG_RIP];
        es->sp = (u1 *) _mc->gregs[REG_RSP];
        es->pv = NULL;
 
@@ -434,17 +430,15 @@ void md_replace_executionstate_read(executionstate_t *es, void *context)
        for (i = 0; i < FLT_REG_CNT; i++)
                es->fltregs[i] = 0xdeadbeefdeadbeefL;
 }
-#endif
 
 
-/* md_replace_executionstate_write *********************************************
+/* md_executionstate_write *****************************************************
 
-   Write the given executionstate back to the context for Replacement.
+   Write the given executionstate back to the context.
 
 *******************************************************************************/
 
-#if defined(ENABLE_REPLACEMENT)
-void md_replace_executionstate_write(executionstate_t *es, void *context)
+void md_executionstate_write(executionstate_t *es, void *context)
 {
        ucontext_t *_uc;
        mcontext_t *_mc;
@@ -502,7 +496,6 @@ void md_replace_executionstate_write(executionstate_t *es, void *context)
        _mc->gregs[REG_RIP] = (ptrint) es->pc;
        _mc->gregs[REG_RSP] = (ptrint) es->sp;
 }
-#endif
 
 
 /* md_critical_section_restart *************************************************
index 8e863822f58c46459772b2bb4da5992d49820019..3afe548ebb8c5d1698bec4faac90f51cfa056717 100644 (file)
@@ -1,15 +1,6 @@
 #ifndef _MACHINE_INSTR_H
 #define _MACHINE_INSTR_H
 
-static inline void
-__attribute__ ((unused))
-atomic_add (volatile int *mem, int val)
-{
-  __asm__ __volatile__ ("lock; addl %1,%0"
-                                               : "=m" (*mem) 
-                                               : "ir" (val), "m" (*mem));
-}
-
 static inline long
 __attribute__ ((unused))
 compare_and_swap (volatile long *p, long oldval, long newval)
@@ -23,8 +14,7 @@ compare_and_swap (volatile long *p, long oldval, long newval)
 }
 
 #define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("" : : : "memory");
+#define MEMORY_BARRIER_AFTER_ATOMIC() /* nothing */
 #define MEMORY_BARRIER() __asm__ __volatile__ ( \
                "mfence" : : : "memory" );
 
index 95b1c1e785432c116411a30255dc065a49b52a88..9ae511b14cf585da2310a9ee858cabc74953fd4b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/x86_64/md-abi.c - functions for x86_64 Linux ABI
 
-   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,6 +32,7 @@
 
 #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"
 
@@ -226,7 +225,7 @@ void md_param_alloc_native(methoddesc *md)
 
 *******************************************************************************/
 
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
 {
        methodinfo   *m;
        codeinfo     *code;
diff --git a/src/vm/jit/x86_64/md-trap.h b/src/vm/jit/x86_64/md-trap.h
new file mode 100644 (file)
index 0000000..6493e35
--- /dev/null
@@ -0,0 +1,79 @@
+/* src/vm/jit/x86_64/md-trap.h - x86_64 hardware traps
+
+   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_TRAP_H
+#define _MD_TRAP_H
+
+#include "config.h"
+
+
+/**
+ * Trap number defines.
+ *
+ * On this architecture (x86_64) the trap numbers are used as load
+ * displacements and thus must not be 4- or 8-byte aligned.
+ *
+ * NOTE: In trap_init() we have a check whether the offset of
+ * java_arrayheader.data[0] is greater than the largest displacement
+ * defined below.  Otherwise normal array loads/stores could trigger
+ * an exception.
+ */
+
+#define TRAP_INSTRUCTION_IS_LOAD    1
+
+enum {
+       TRAP_NullPointerException           = 0,
+       TRAP_ArithmeticException            = 1,
+       TRAP_ArrayIndexOutOfBoundsException = 2,
+       TRAP_ArrayStoreException            = 3,
+
+       /* Don't use 4 (could be a normal load offset). */
+
+       TRAP_ClassCastException             = 5,
+       TRAP_CHECK_EXCEPTION                = 6,
+       TRAP_PATCHER                        = 7,
+
+       /* Don't use 8 (could be a normal load offset). */
+
+       TRAP_COMPILER                       = 9,
+       TRAP_END
+};
+
+#endif /* _MD_TRAP_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 ffe59b44c3930022f15dac9be0452f324fb7e996..f60e9720f6ba583088a9c6257c161879b7ed3439 100644 (file)
@@ -1,9 +1,6 @@
-/* src/vm/jit/x86_64/md.c - machine dependent x86_64 functions
+/* src/vm/jit/x86_64/md.h - 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
 
    This file is part of CACAO.
 
@@ -34,6 +31,7 @@
 #include <stdint.h>
 
 #include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
 
 
 /* inline functions ***********************************************************/
@@ -60,8 +58,7 @@ inline static void *md_stacktrace_get_returnaddress(void *sp, int32_t stackframe
 
 /* md_codegen_get_pv_from_pc ***************************************************
 
-   On this architecture just a wrapper function to
-   codegen_get_pv_from_pc.
+   On this architecture this is just a wrapper to methodtree_find.
 
 *******************************************************************************/
 
@@ -70,9 +67,9 @@ inline static void *md_codegen_get_pv_from_pc(void *ra)
        void *pv;
 
        /* Get the start address of the function which contains this
-       address from the method table. */
+       address from the method tree. */
 
-       pv = codegen_get_pv_from_pc(ra);
+       pv = methodtree_find(ra);
 
        return pv;
 }
index 61a328e0bd1f929e55477a2cb49b54153ba9ab36..2ab929aaf413c546d722f315c9e416adf84140df 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/x86_64/patcher.c - x86_64 code patching 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.
 
@@ -218,8 +216,8 @@ bool patcher_get_putstatic(patchref_t *pr)
 
        /* check if the field's class is initialized */
 
-       if (!(fi->class->state & CLASS_INITIALIZED))
-               if (!initialize_class(fi->class))
+       if (!(fi->clazz->state & CLASS_INITIALIZED))
+               if (!initialize_class(fi->clazz))
                        return false;
 
        PATCH_BACK_ORIGINAL_MCODE;
@@ -470,12 +468,12 @@ bool patcher_invokeinterface(patchref_t *pr)
 
        *((int32_t *) (ra + 3 + 3)) =
                (int32_t) (OFFSET(vftbl_t, interfacetable[0]) -
-                                  sizeof(methodptr) * m->class->index);
+                                  sizeof(methodptr) * m->clazz->index);
 
        /* patch method offset */
 
        *((int32_t *) (ra + 3 + 7 + 3)) =
-               (int32_t) (sizeof(methodptr) * (m - m->class->methods));
+               (int32_t) (sizeof(methodptr) * (m - m->clazz->methods));
 
        return true;
 }
index 2dca6379e71da87bbd025a530adb60441c3db887..89fbf6139eaf76b9fa9c6946b8e545c6c44b4863 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit_interface.h - prototypes of jit functions used in vm/ 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.
 
@@ -36,8 +34,6 @@
 
 void code_free_code_of_method(methodinfo *m);
 
-methodinfo *code_get_methodinfo_for_pv(u1 *pv);
-
 u1       *codegen_generate_stub_compiler(methodinfo *m);
 codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f);
 
index 88e532c85c9146d45c6c5fa7e5c3b69878554981..c544b96fe4142e15e8d918fec010aaef927e0224 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/package.c - Java boot-package 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.
 
@@ -68,6 +66,8 @@ static list_t *list_package = NULL;
 
 void package_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("package_init");
+
        /* create the properties list */
 
        list_package = list_create(OFFSET(list_package_entry_t, linkage));
index b9f6466f22f9794b7b6b8214b6feff4c33532e44..ca55726f1f6a50d1ed18793c2047f5f1ff65e6ac 100644 (file)
@@ -1,9 +1,7 @@
 /* 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
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -249,6 +247,11 @@ imm_union primitive_unbox(java_handle_t *o)
        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);
index b7cbefc33d1ca6bab96bd6d7fc1ca441bca7d16e..9f763f6f3ef5a6a3ca2863c915af768a3a7dc16d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/properties.c - 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 <unistd.h>
 #include <sys/utsname.h>
 
-#if defined(WITH_JRE_LAYOUT)
-# include <libgen.h>
-#endif
-
 #include "vm/types.h"
 
 #include "mm/memory.h"
@@ -60,6 +54,7 @@
 #include "vmcore/class.h"
 #include "vmcore/method.h"
 #include "vmcore/options.h"
+#include "vmcore/system.h"
 
 
 /* internal property structure ************************************************/
@@ -87,6 +82,8 @@ static list_t *list_properties = NULL;
 
 void properties_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("properties_init");
+
        list_properties = list_create(OFFSET(list_properties_entry_t, linkage));
 }
 
@@ -124,7 +121,7 @@ void properties_set(void)
 # endif
 #endif
 
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
        /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
 
        p = MNEW(char, 4096);
@@ -132,20 +129,24 @@ void properties_set(void)
        if (readlink("/proc/self/exe", p, 4095) == -1)
                vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
 
-       /* Get the path of the current executable. */
+       /* We have a path like:
 
-       p = dirname(p);
+          /path/to/executable/bin/java
 
-# if defined(WITH_CLASSPATH_GNU)
+          or
+          
+          /path/to/executeable/jre/bin/java
 
-       /* Set java.home. */
+          Now let's strip two levels. */
 
-       len = strlen(p) + strlen("/..") + strlen("0");
+       p = system_dirname(p);
+       p = system_dirname(p);
 
-       java_home = MNEW(char, len);
+# if defined(WITH_CLASSPATH_GNU)
 
-       strcpy(java_home, p);
-       strcat(java_home, "/..");
+       /* Set java.home. */
+
+       java_home = strdup(p);
 
        /* Set the path to Java core native libraries. */
 
@@ -166,27 +167,26 @@ void properties_set(void)
 
        len =
                strlen(p) +
-               strlen("/../jre/lib/"JAVA_ARCH"/server/libjvm.so") +
+               strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
                strlen("0");
 
        java_home = MNEW(char, len);
 
        strcpy(java_home, p);
-       strcat(java_home, "/../jre/lib/"JAVA_ARCH"/server/libjvm.so");
+       strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
 
        /* Check if that libjvm.so exists. */
 
-       if (access(java_home, F_OK) == 0) {
+       if (system_access(java_home, F_OK) == 0) {
                /* Yes, we add /jre to java.home. */
 
                strcpy(java_home, p);
-               strcat(java_home, "/../jre");
+               strcat(java_home, "/jre");
        }
        else {
                /* No, java.home is parent directory. */
 
                strcpy(java_home, p);
-               strcat(java_home, "/..");
        }
 
        /* Set the path to Java core native libraries. */
@@ -237,7 +237,7 @@ void properties_set(void)
                strcpy(boot_class_path, p);
        }
        else {
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
 # if defined(WITH_CLASSPATH_GNU)
 
                len =
@@ -584,8 +584,8 @@ void properties_add(char *key, char *value)
 
        /* search for the entry */
 
-       for (pe = list_first_unsynced(list_properties); pe != NULL;
-                pe = list_next_unsynced(list_properties, pe)) {
+       for (pe = list_first(list_properties); pe != NULL;
+                pe = list_next(list_properties, pe)) {
                if (strcmp(pe->key, key) == 0) {
                        /* entry was found, replace the value */
 
@@ -615,7 +615,7 @@ void properties_add(char *key, char *value)
        pe->key   = key;
        pe->value = value;
 
-       list_add_last_unsynced(list_properties, pe);
+       list_add_last(list_properties, pe);
 }
 
 
@@ -629,8 +629,8 @@ char *properties_get(char *key)
 {
        list_properties_entry_t *pe;
 
-       for (pe = list_first_unsynced(list_properties); pe != NULL;
-                pe = list_next_unsynced(list_properties, pe)) {
+       for (pe = list_first(list_properties); pe != NULL;
+                pe = list_next(list_properties, pe)) {
                if (strcmp(pe->key, key) == 0)
                        return pe->value;
        }
@@ -732,10 +732,11 @@ void properties_dump(void)
        list_t                  *l;
        list_properties_entry_t *pe;
 
+       /* For convenience. */
+
        l = list_properties;
 
-       for (pe = list_first_unsynced(l); pe != NULL;
-                pe = list_next_unsynced(l, pe)) {
+       for (pe = list_first(l); pe != NULL; pe = list_next(l, pe)) {
                log_println("[properties_dump: key=%s, value=%s]", pe->key, pe->value);
        }
 }
index 3f60dbc57be8dff3fd12ff98584f0e51842cd7f3..b125bdefc2d4e590d608cb88be502d0419186a2d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/resolve.c - resolving classes/interfaces/fields/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.
 
 
 /*#define RESOLVE_VERBOSE*/
 
+/* resolve_handle_pending_exception ********************************************
+
+   Convert a pending ClassNotFoundException into a
+   NoClassDefFoundError if requested.
+
+   See: hotspot/src/share/vm/classfile/systemDictionary.cpp
+   (handle_resolution_exception)
+
+   ARGUMENTS:
+       classname .... name of the class currently resolved
+       throwError ... if true throw a NoClassDefFoundError instead of
+                      a ClassNotFoundException
+
+*******************************************************************************/
+
+void resolve_handle_pending_exception(bool throwError)
+{
+       java_handle_t *e;
+
+       /* Get the current exception. */
+
+       e = exceptions_get_exception();
+
+       if (e != NULL) {
+               if (throwError == true) {
+                       /* Convert ClassNotFoundException to
+                          NoClassDefFoundError. */
+
+                       if (builtin_instanceof(e, class_java_lang_ClassNotFoundException)) {
+                               /* Clear exception, because we are calling Java code
+                                  again. */
+
+                               exceptions_clear_exception();
+
+                               /* create new error */
+
+                               exceptions_throw_noclassdeffounderror_cause(e);
+                       }
+                       else {
+                               return;
+                       }
+               }
+               else {
+                       /* An exception conversion was not requested.  Simply
+                          return. */
+
+                       return;
+               }
+       }
+}
+
+
 /******************************************************************************/
 /* CLASS RESOLUTION                                                           */
 /******************************************************************************/
@@ -177,14 +227,8 @@ bool resolve_class_from_name(classinfo *referer,
                if (cls == NULL) {
                        cls = load_class_from_classloader(classname, referer->classloader);
 
-                       if (cls == NULL) {
-                               /* If the exception is a ClassNotFoundException,
-                                  convert it to a NoClassDefFoundError. */
-
-                               exceptions_classnotfoundexception_to_noclassdeffounderror();
-
+                       if (cls == NULL)
                                return false;
-                       }
                }
        }
 
@@ -281,7 +325,7 @@ bool resolve_classref(methodinfo *refmethod,
  
    Resolve a symbolic class reference if necessary
 
-   NOTE: If given, refmethod->class is used as the referring class.
+   NOTE: If given, refmethod->clazz is used as the referring class.
          Otherwise, cls.ref->referer is used.
 
    IN:
@@ -340,10 +384,10 @@ bool resolve_classref_or_classinfo(methodinfo *refmethod,
                /* being the same, so the referer usually is cls.ref->referer.    */
                /* There is one important case where it is not: When we do a      */
                /* deferred assignability check to a formal argument of a method, */
-               /* we must use refmethod->class (the caller's class) to resolve   */
+               /* we must use refmethod->clazz (the caller's class) to resolve   */
                /* the type of the formal argument.                               */
 
-               referer = (refmethod) ? refmethod->class : cls.ref->referer;
+               referer = (refmethod) ? refmethod->clazz : cls.ref->referer;
 
                if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
                                                                         mode, checkaccess, link, &c))
@@ -522,7 +566,7 @@ static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
                                                                                          resolve_err_t error)
 {
        classinfo        *subclass;
-       typeinfo          subti;
+       typeinfo_t          subti;
        typecheck_result  r;
        char             *msg;
        s4                msglen;
@@ -656,7 +700,7 @@ check_again:
 
 #if defined(ENABLE_VERIFIER)
 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
-                                                                                                       typeinfo *subtinfo,
+                                                                                                       typeinfo_t *subtinfo,
                                                                                                        classref_or_classinfo supertype,
                                                                                                        resolve_err_t error)
 {
@@ -694,7 +738,7 @@ static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
 
        if (supertype.cls == class_java_lang_Object
                || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
-                       && refmethod->class->classloader == NULL))
+                       && refmethod->clazz->classloader == NULL))
        {
                return resolveSucceeded;
        }
@@ -1058,8 +1102,8 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
                                                                                           constant_FMIref *fieldref,
                                                                                           classinfo *container,
                                                                                           fieldinfo *fi,
-                                                                                          typeinfo *instanceti,
-                                                                                          typeinfo *valueti,
+                                                                                          typeinfo_t *instanceti,
+                                                                                          typeinfo_t *valueti,
                                                                                           bool isstatic,
                                                                                           bool isput)
 {
@@ -1078,10 +1122,10 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
 
        /* get the classinfos and the field type */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
-       declarer = fi->class;
+       declarer = fi->clazz;
        assert(declarer);
        assert(referer->state & CLASS_LINKED);
 
@@ -1135,8 +1179,8 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
        /* instance type                                                          */
 
        if (instanceti) {
-               typeinfo *insttip;
-               typeinfo tinfo;
+               typeinfo_t *insttip;
+               typeinfo_t tinfo;
 
                /* The instanceslot must contain a reference to a non-array type */
 
@@ -1163,7 +1207,7 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
                                return resolveFailed;
                        }
 
-                       /* XXX check that class of field == refmethod->class */
+                       /* XXX check that class of field == refmethod->clazz */
                        initclass = referer; /* XXX classrefs */
                        assert(initclass->state & CLASS_LINKED);
 
@@ -1257,7 +1301,7 @@ resolve_result_t resolve_field_lazy(methodinfo *refmethod,
 
        /* the class containing the reference */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
        /* check if the field itself is already resolved */
@@ -1350,13 +1394,13 @@ bool resolve_field(unresolved_field *ref,
 
        /* the class containing the reference */
 
-       referer = ref->referermethod->class;
+       referer = ref->referermethod->clazz;
        assert(referer);
 
        /* check if the field itself is already resolved */
        if (IS_FMIREF_RESOLVED(ref->fieldref)) {
                fi = ref->fieldref->p.field;
-               container = fi->class;
+               container = fi->clazz;
                goto resolved_the_field;
        }
 
@@ -1419,7 +1463,7 @@ resolved_the_field:
                if (checkresult != resolveSucceeded)
                        return (bool) checkresult;
 
-               declarer = fi->class;
+               declarer = fi->clazz;
                assert(declarer);
                assert(declarer->state & CLASS_LOADED);
                assert(declarer->state & CLASS_LINKED);
@@ -1524,10 +1568,10 @@ methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
 
        /* get referer and declarer classes */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
-       declarer = mi->class;
+       declarer = mi->clazz;
        assert(declarer);
        assert(referer->state & CLASS_LINKED);
 
@@ -1607,10 +1651,10 @@ resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
 
        /* get the classinfos and the method descriptor */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
-       declarer = mi->class;
+       declarer = mi->clazz;
        assert(declarer);
 
        /* check static */
@@ -1684,18 +1728,18 @@ resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
 #if defined(ENABLE_VERIFIER)
 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
                                                                                                         methodinfo *mi,
-                                                                                                        typeinfo *instanceti,
+                                                                                                        typeinfo_t *instanceti,
                                                                                                         bool invokespecial)
 {
-       typeinfo         tinfo;
-       typeinfo        *tip;
+       typeinfo_t         tinfo;
+       typeinfo_t        *tip;
        resolve_result_t result;
 
        if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
        {   /* XXX clean up */
                instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
                classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
-                                                                        : CLASSREF_OR_CLASSINFO(refmethod->class);
+                                                                        : CLASSREF_OR_CLASSINFO(refmethod->clazz);
                tip = &tinfo;
                if (!typeinfo_init_class(tip, initclass))
                        return false;
@@ -1706,20 +1750,20 @@ resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
 
        result = resolve_lazy_subtype_checks(refmethod,
                                                                                 tip,
-                                                                                CLASSREF_OR_CLASSINFO(mi->class),
+                                                                                CLASSREF_OR_CLASSINFO(mi->clazz),
                                                                                 resolveLinkageError);
        if (result != resolveSucceeded)
                return result;
 
        /* check protected access */
 
-       /* XXX use other `declarer` than mi->class? */
+       /* XXX use other `declarer` than mi->clazz? */
        if (((mi->flags & ACC_PROTECTED) != 0)
-                       && !SAME_PACKAGE(mi->class, refmethod->class))
+                       && !SAME_PACKAGE(mi->clazz, refmethod->clazz))
        {
                result = resolve_lazy_subtype_checks(refmethod,
                                tip,
-                               CLASSREF_OR_CLASSINFO(refmethod->class),
+                               CLASSREF_OR_CLASSINFO(refmethod->clazz),
                                resolveIllegalAccessError);
                if (result != resolveSucceeded)
                        return result;
@@ -1820,9 +1864,9 @@ resolve_result_t resolve_method_param_type_checks_stackbased(
                methodinfo *refmethod, 
                methodinfo *mi,
                bool invokestatic, 
-               typedescriptor *stack)
+               typedescriptor_t *stack)
 {
-       typedescriptor  *param;
+       typedescriptor_t  *param;
        resolve_result_t result;
        methoddesc      *md;
        typedesc        *paramtypes;
@@ -1901,7 +1945,7 @@ bool resolve_method_loading_constraints(classinfo *referer,
                                /* the method definition. Since container is the same as, */
                                /* or a subclass of declarer, we also constrain declarer  */
                                /* by transitivity of loading constraints.                */
-                               name = mi->class->name;
+                               name = mi->clazz->name;
                        }
                        else {
                                name = paramtypes[i].classref->name;
@@ -1910,7 +1954,7 @@ bool resolve_method_loading_constraints(classinfo *referer,
                        /* The caller (referer) and the callee (container) must agree */
                        /* on the types of the parameters.                            */
                        if (!classcache_add_constraint(referer->classloader,
-                                                                                  mi->class->classloader, name))
+                                                                                  mi->clazz->classloader, name))
                                return false; /* exception */
                }
        }
@@ -1921,7 +1965,7 @@ bool resolve_method_loading_constraints(classinfo *referer,
                /* The caller (referer) and the callee (container) must agree */
                /* on the return type.                                        */
                if (!classcache_add_constraint(referer->classloader,
-                                       mi->class->classloader,
+                                       mi->clazz->classloader,
                                        md->returntype.classref->name))
                        return false; /* exception */
        }
@@ -1969,7 +2013,7 @@ resolve_result_t resolve_method_lazy(methodinfo *refmethod,
 
        /* the class containing the reference */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
        /* check if the method itself is already resolved */
@@ -2083,14 +2127,14 @@ bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **re
 
        /* the class containing the reference */
 
-       referer = ref->referermethod->class;
+       referer = ref->referermethod->clazz;
        assert(referer);
 
        /* check if the method itself is already resolved */
 
        if (IS_FMIREF_RESOLVED(ref->methodref)) {
                mi = ref->methodref->p.method;
-               container = mi->class;
+               container = mi->clazz;
                goto resolved_the_method;
        }
 
@@ -2174,7 +2218,7 @@ resolved_the_method:
                if (!resolve_method_loading_constraints(referer, mi))
                        return false;
 
-               declarer = mi->class;
+               declarer = mi->clazz;
                assert(declarer);
                assert(referer->state & CLASS_LINKED);
 
@@ -2265,7 +2309,7 @@ methodinfo * resolve_method_eager(unresolved_method *ref)
 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
                                                                                                 methodinfo *refmethod,
                                                                                                 unresolved_subtype_set *stset,
-                                                                                                typeinfo *tinfo,
+                                                                                                typeinfo_t *tinfo,
                                                                                                 utf *declaredclassname)
 {
        int count;
@@ -2369,7 +2413,7 @@ empty_set:
 #ifdef ENABLE_VERIFIER
 unresolved_class * create_unresolved_class(methodinfo *refmethod,
                                                                                   constant_classref *classref,
-                                                                                  typeinfo *valuetype)
+                                                                                  typeinfo_t *valuetype)
 {
        unresolved_class *ref;
 
@@ -2502,12 +2546,12 @@ unresolved_field * resolve_create_unresolved_field(classinfo *referer,
 bool resolve_constrain_unresolved_field(unresolved_field *ref,
                                                                                classinfo *referer, 
                                                                                methodinfo *refmethod,
-                                                                           typeinfo *instanceti,
-                                                                           typeinfo *valueti)
+                                                                           typeinfo_t *instanceti,
+                                                                           typeinfo_t *valueti)
 {
        constant_FMIref *fieldref;
        int type;
-       typeinfo tinfo;
+       typeinfo_t tinfo;
        typedesc *fd;
 
        assert(ref);
@@ -2533,7 +2577,7 @@ bool resolve_constrain_unresolved_field(unresolved_field *ref,
 
        /* record subtype constraints for the instance type, if any */
        if (instanceti) {
-               typeinfo *insttip;
+               typeinfo_t *insttip;
 
                /* The instanceslot must contain a reference to a non-array type */
                if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
@@ -2562,8 +2606,8 @@ bool resolve_constrain_unresolved_field(unresolved_field *ref,
                                                "accessing field of uninitialized object");
                                return false;
                        }
-                       /* XXX check that class of field == refmethod->class */
-                       initclass = refmethod->class; /* XXX classrefs */
+                       /* XXX check that class of field == refmethod->clazz */
+                       initclass = refmethod->clazz; /* XXX classrefs */
                        assert(initclass->state & CLASS_LOADED);
                        assert(initclass->state & CLASS_LINKED);
 
@@ -2671,13 +2715,13 @@ unresolved_method * resolve_create_unresolved_method(classinfo *referer,
 #if defined(ENABLE_VERIFIER)
 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
                                                                                                  methodinfo *refmethod,
-                                                                                                 typeinfo *instanceti,
+                                                                                                 typeinfo_t *instanceti,
                                                                                                  bool invokespecial)
 {
        constant_FMIref   *methodref;
        constant_classref *instanceref;
-       typeinfo           tinfo;
-       typeinfo          *tip;
+       typeinfo_t           tinfo;
+       typeinfo_t          *tip;
 
        assert(ref);
        methodref = ref->methodref;
@@ -2685,7 +2729,7 @@ bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
 
        /* XXX clean this up */
        instanceref = IS_FMIREF_RESOLVED(methodref)
-               ? class_get_self_classref(methodref->p.method->class)
+               ? class_get_self_classref(methodref->p.method->clazz)
                : methodref->p.classref;
 
 #ifdef RESOLVE_VERBOSE
@@ -2700,7 +2744,7 @@ bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
        {   /* XXX clean up */
                instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
                classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
-                                                                        : CLASSREF_OR_CLASSINFO(refmethod->class);
+                                                                        : CLASSREF_OR_CLASSINFO(refmethod->clazz);
                tip = &tinfo;
                if (!typeinfo_init_class(tip, initclass))
                        return false;
@@ -2709,7 +2753,7 @@ bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
                tip = instanceti;
        }
 
-       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
+       if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
                                &(ref->instancetypes),tip,instanceref->name))
                return false;
 
@@ -2778,7 +2822,7 @@ bool resolve_constrain_unresolved_method_params(jitdata *jd,
                                        UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
                        }
                        assert(ref->paramconstraints);
-                       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
+                       if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
                                                ref->paramconstraints + i,&(param->typeinfo),
                                                md->paramtypes[i+instancecount].classref->name))
                                return false;
@@ -2813,10 +2857,10 @@ bool resolve_constrain_unresolved_method_params(jitdata *jd,
 bool resolve_constrain_unresolved_method_params_stackbased(
                unresolved_method *ref,
                methodinfo *refmethod,
-               typedescriptor *stack)
+               typedescriptor_t *stack)
 {
        constant_FMIref *methodref;
-       typedescriptor *param;
+       typedescriptor_t *param;
        methoddesc *md;
        int i,j;
        int type;
@@ -2853,7 +2897,7 @@ bool resolve_constrain_unresolved_method_params_stackbased(
                                        UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
                        }
                        assert(ref->paramconstraints);
-                       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
+                       if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
                                                ref->paramconstraints + i - instancecount,&(param->typeinfo),
                                                md->paramtypes[i].classref->name))
                                return false;
@@ -3036,7 +3080,7 @@ void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
        fprintf(file,"unresolved_field(%p):\n",(void *)ref);
        if (ref) {
                fprintf(file,"    referer   : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
+               utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
                fprintf(file,"    refmethod : ");
                utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
                fprintf(file,"    refmethodd: ");
@@ -3074,7 +3118,7 @@ void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
        fprintf(file,"unresolved_method(%p):\n",(void *)ref);
        if (ref) {
                fprintf(file,"    referer   : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
+               utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
                fprintf(file,"    refmethod : ");
                utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
                fprintf(file,"    refmethodd: ");
index b38b80b7606a3a35117920be3c0f02c3caab607d..68138206815c9566209c982953dc879e64c11799 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/resolve.h - resolving classes/interfaces/fields/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.
 
@@ -114,8 +112,11 @@ struct unresolved_method {
 #define UNRESOLVED_SUBTYPE_SET_EMTPY(stset) \
        do { (stset).subtyperefs = NULL; } while(0)
 
+
 /* function prototypes ********************************************************/
 
+void resolve_handle_pending_exception(bool throwError);
+
 bool resolve_class_from_name(classinfo* referer,methodinfo *refmethod,
                                                utf *classname,
                                                resolve_mode_t mode,
@@ -167,7 +168,7 @@ methodinfo * resolve_method_eager(unresolved_method *ref);
 #ifdef ENABLE_VERIFIER
 unresolved_class * create_unresolved_class(methodinfo *refmethod,
                                                constant_classref *classref,
-                                               typeinfo *valuetype);
+                                               typeinfo_t *valuetype);
 #endif
 
 unresolved_field *resolve_create_unresolved_field(classinfo *referer,
@@ -196,16 +197,16 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
                                                                                           constant_FMIref *fieldref,
                                                                                           classinfo *container,
                                                                                           fieldinfo *fi,
-                                                                                          typeinfo *instanceti,
-                                                                                          typeinfo *valueti,
+                                                                                          typeinfo_t *instanceti,
+                                                                                          typeinfo_t *valueti,
                                                                                           bool isstatic,
                                                                                           bool isput);
 
 bool resolve_constrain_unresolved_field(unresolved_field *ref,
                                                                                classinfo *referer, 
                                                                                methodinfo *refmethod,
-                                                                           typeinfo *instanceti,
-                                                                           typeinfo *valueti);
+                                                                           typeinfo_t *instanceti,
+                                                                           typeinfo_t *valueti);
 
 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
                                                                                                constant_FMIref *methodref,
@@ -214,7 +215,7 @@ resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
 
 resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
                                                                                                         methodinfo *mi,
-                                                                                                        typeinfo *instanceti,
+                                                                                                        typeinfo_t *instanceti,
                                                                                                         bool invokespecial);
 
 resolve_result_t resolve_method_param_type_checks(jitdata *jd, 
@@ -227,14 +228,14 @@ resolve_result_t resolve_method_param_type_checks_stackbased(
                methodinfo *refmethod, 
                methodinfo *mi,
                bool invokestatic, 
-               typedescriptor *stack);
+               typedescriptor_t *stack);
 
 bool resolve_method_loading_constraints(classinfo *referer,
                                                                                methodinfo *mi);
 
 bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
                                                                                                  methodinfo *refmethod,
-                                                                                                 typeinfo *instanceti,
+                                                                                                 typeinfo_t *instanceti,
                                                                                                  bool invokespecial);
 
 bool resolve_constrain_unresolved_method_params(jitdata *jd,
@@ -245,7 +246,7 @@ bool resolve_constrain_unresolved_method_params(jitdata *jd,
 bool resolve_constrain_unresolved_method_params_stackbased(
                unresolved_method *ref,
                methodinfo *refmethod,
-               typedescriptor *stack);
+               typedescriptor_t *stack);
 
 #endif /* defined(ENABLE_VERIFIER) */
 
index 5d32fb4db306c67be5627028976740ccd0451d9d..39e1c6b22455211b34828b3d7cf93159b7736b32 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/signal.c - 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.
 
@@ -28,7 +26,6 @@
 #include "config.h"
 
 #include <assert.h>
-#include <errno.h>
 #include <signal.h>
 #include <stdint.h>
 #include <stdlib.h>
 /* If we compile with -ansi on darwin, <sys/types.h> is not
  included. So let's do it here. */
 # include <sys/types.h>
+# include <sys/utsname.h>
 #endif
 
 #include "arch.h"
 
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/threads-common.h"
-#else
-# include "threads/none/threads.h"
-#endif
-
-#include "toolbox/logging.h"
+#include "threads/thread.h"
 
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
 #include "vm/vm.h"
 
-#include "vm/jit/codegen-common.h"
-#include "vm/jit/disass.h"
-#include "vm/jit/patcher-common.h"
-
 #include "vmcore/options.h"
 
 #if defined(ENABLE_STATISTICS)
@@ -84,6 +68,8 @@ bool signal_init(void)
 #if !defined(__CYGWIN__)
        sigset_t mask;
 
+       TRACESUBSYSTEMINITIALIZATION("signal_init");
+
 #if defined(__LINUX__) && defined(ENABLE_THREADS)
        /* XXX Remove for exact-GC. */
        if (threads_pthreads_implementation_nptl) {
@@ -94,22 +80,22 @@ bool signal_init(void)
           this thread. */
 
        if (sigemptyset(&mask) != 0)
-               vm_abort("signal_init: sigemptyset failed: %s", strerror(errno));
+               vm_abort_errno("signal_init: sigemptyset failed");
 
 #if !defined(WITH_CLASSPATH_SUN)
        /* Let OpenJDK handle SIGINT itself. */
 
        if (sigaddset(&mask, SIGINT) != 0)
-               vm_abort("signal_init: sigaddset failed: %s", strerror(errno));
+               vm_abort_errno("signal_init: sigaddset failed");
 #endif
 
 #if !defined(__FREEBSD__)
        if (sigaddset(&mask, SIGQUIT) != 0)
-               vm_abort("signal_init: sigaddset failed: %s", strerror(errno));
+               vm_abort_errno("signal_init: sigaddset failed");
 #endif
 
        if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
-               vm_abort("signal_init: sigprocmask failed: %s", strerror(errno));
+               vm_abort_errno("signal_init: sigprocmask failed");
 
 #if defined(__LINUX__) && defined(ENABLE_THREADS)
        /* XXX Remove for exact-GC. */
@@ -165,7 +151,36 @@ bool signal_init(void)
 # if defined(ENABLE_INTRP)
        }
 # endif
-#endif /* !defined(ENABLE_INTRP) */
+
+#if defined(__DARWIN__)
+       do {
+               struct utsname name;
+               kern_return_t kr;
+
+               /* Check if we're on 10.4 (Tiger/8.x) or earlier */
+               if (uname(&name) != 0) 
+                       break;
+
+               /* Make sure the string is large enough */
+               /* Check the major number (ascii comparison) */
+               /* Verify that we're not looking at '10.' by checking for a trailing period. */
+               if (name.release[0] == '\0' || name.release[0] > '8' || name.release[1] != '.')
+                       break;
+
+               /* Reset CrashReporter's task signal handler */
+               kr = task_set_exception_ports(mach_task_self(),
+                                                                         EXC_MASK_BAD_ACCESS
+#  if defined(__I386__)
+                                                                         | EXC_MASK_BAD_INSTRUCTION
+#endif
+                                                                         , MACH_PORT_NULL,
+                                                                         EXCEPTION_STATE_IDENTITY,
+                                                                         MACHINE_THREAD_STATE);
+
+               assert(kr == KERN_SUCCESS);
+       } while (false);
+#endif
+#endif /* !defined(ENABLE_JIT) */
 
 #if defined(ENABLE_THREADS)
        /* SIGHUP handler for threads_thread_interrupt */
@@ -208,144 +223,13 @@ void signal_register_signal(int signum, functionptr handler, int flags)
        function = (void (*)(int, siginfo_t *, void *)) handler;
 
        if (sigemptyset(&act.sa_mask) != 0)
-               vm_abort("signal_register_signal: sigemptyset failed: %s",
-                                strerror(errno));
+               vm_abort_errno("signal_register_signal: sigemptyset failed");
 
        act.sa_sigaction = function;
        act.sa_flags     = flags;
 
        if (sigaction(signum, &act, NULL) != 0)
-               vm_abort("signal_register_signal: sigaction failed: %s",
-                                strerror(errno));
-}
-
-
-/* signal_handle ***************************************************************
-
-   Handles the signal caught by a signal handler and calls the correct
-   function.
-
-*******************************************************************************/
-
-void *signal_handle(int type, intptr_t val,
-                                       void *pv, void *sp, void *ra, void *xpc, void *context)
-{
-       stackframeinfo_t  sfi;
-       int32_t           index;
-       java_handle_t    *o;
-       methodinfo       *m;
-       java_handle_t    *p;
-
-       /* Prevent compiler warnings. */
-
-       o = NULL;
-       m = NULL;
-
-       /* wrap the value into a handle if it is a reference */
-       /* BEFORE: creating stackframeinfo */
-
-       switch (type) {
-       case EXCEPTION_HARDWARE_CLASSCAST:
-               o = LLNI_WRAP((java_object_t *) val);
-               break;
-
-       case EXCEPTION_HARDWARE_COMPILER:
-               /* In this case the passed PV points to the compiler stub.  We
-                  get the methodinfo pointer here and set PV to NULL so
-                  stacktrace_stackframeinfo_add determines the PV for the
-                  parent Java method. */
-
-               m  = code_get_methodinfo_for_pv(pv);
-               pv = NULL;
-               break;
-
-       default:
-               /* do nothing */
-               break;
-       }
-
-       /* Fill and add a stackframeinfo. */
-
-       stacktrace_stackframeinfo_add(&sfi, pv, sp, ra, xpc);
-
-       switch (type) {
-       case EXCEPTION_HARDWARE_NULLPOINTER:
-               p = exceptions_new_nullpointerexception();
-               break;
-
-       case EXCEPTION_HARDWARE_ARITHMETIC:
-               p = exceptions_new_arithmeticexception();
-               break;
-
-       case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
-               index = (s4) val;
-               p = exceptions_new_arrayindexoutofboundsexception(index);
-               break;
-
-       case EXCEPTION_HARDWARE_ARRAYSTORE:
-               p = exceptions_new_arraystoreexception();
-               break;
-
-       case EXCEPTION_HARDWARE_CLASSCAST:
-               p = exceptions_new_classcastexception(o);
-               break;
-
-       case EXCEPTION_HARDWARE_EXCEPTION:
-               p = exceptions_fillinstacktrace();
-               break;
-
-       case EXCEPTION_HARDWARE_PATCHER:
-#if defined(ENABLE_REPLACEMENT)
-               if (replace_me_wrapper(xpc, context)) {
-                       p = NULL;
-                       break;
-               }
-#endif
-               p = patcher_handler(xpc);
-               break;
-
-       case EXCEPTION_HARDWARE_COMPILER:
-               p = jit_compile_handle(m, sfi.pv, ra, (void *) val);
-               break;
-
-       default:
-               /* Let's try to get a backtrace. */
-
-               codegen_get_pv_from_pc(xpc);
-
-               /* If that does not work, print more debug info. */
-
-               log_println("signal_handle: unknown hardware exception type %d", type);
-
-#if SIZEOF_VOID_P == 8
-               log_println("PC=0x%016lx", xpc);
-#else
-               log_println("PC=0x%08x", xpc);
-#endif
-
-#if defined(ENABLE_DISASSEMBLER)
-               log_println("machine instruction at PC:");
-               disassinstr(xpc);
-#endif
-
-               vm_abort("Exiting...");
-
-               /* keep compiler happy */
-
-               p = NULL;
-       }
-
-       /* Remove stackframeinfo. */
-
-       stacktrace_stackframeinfo_remove(&sfi);
-
-       /* unwrap and return the exception object */
-       /* AFTER: removing stackframeinfo */
-
-       if (type == EXCEPTION_HARDWARE_COMPILER)
-               return p;
-       else
-               return LLNI_UNWRAP(p);
+               vm_abort_errno("signal_register_signal: sigaction failed");
 }
 
 
@@ -366,25 +250,25 @@ static void signal_thread(void)
        t = THREADOBJECT;
 
        if (sigemptyset(&mask) != 0)
-               vm_abort("signal_thread: sigemptyset failed: %s", strerror(errno));
+               vm_abort_errno("signal_thread: sigemptyset failed");
 
 #if !defined(WITH_CLASSPATH_SUN)
        /* Let OpenJDK handle SIGINT itself. */
 
        if (sigaddset(&mask, SIGINT) != 0)
-               vm_abort("signal_thread: sigaddset failed: %s", strerror(errno));
+               vm_abort_errno("signal_thread: sigaddset failed");
 #endif
 
 #if !defined(__FREEBSD__)
        if (sigaddset(&mask, SIGQUIT) != 0)
-               vm_abort("signal_thread: sigaddset failed: %s", strerror(errno));
+               vm_abort_errno("signal_thread: sigaddset failed");
 #endif
 
        for (;;) {
                /* just wait for a signal */
 
 #if defined(ENABLE_THREADS)
-               threads_thread_state_waiting(t);
+               thread_set_state_waiting(t);
 #endif
 
                /* XXX We don't check for an error here, although the man-page
@@ -393,11 +277,11 @@ static void signal_thread(void)
                   revisit this code with our new exact-GC. */
 
 /*             if (sigwait(&mask, &sig) != 0) */
-/*                     vm_abort("signal_thread: sigwait failed: %s", strerror(errno)); */
+/*                     vm_abort_errno("signal_thread: sigwait failed"); */
                (void) sigwait(&mask, &sig);
 
 #if defined(ENABLE_THREADS)
-               threads_thread_state_runnable(t);
+               thread_set_state_runnable(t);
 #endif
 
                /* Handle the signal. */
index 2c9450e547e351f3c94210397f94a0b8d4944949..7d4e70e38944a5f12f940842618ddd10b22e9be1 100644 (file)
@@ -40,9 +40,6 @@
 bool  signal_init(void);
 void  signal_register_signal(int signum, functionptr handler, int flags);
 
-void *signal_handle(int type, intptr_t val,
-                                       void *pv, void *sp, void *ra, void *xpc, void *context);
-
 void  signal_thread_handler(int sig);
 bool  signal_start_thread(void);
 
index 98063bb62ddd2c69e5b1954697a6bb7da1bf047c..f24e411e021c0c35c86777787ab5dbf063f56f98 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/string.c - java.lang.String related 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.
 
@@ -29,6 +27,8 @@
 
 #include <assert.h>
 
+#include "vmcore/system.h"
+
 #include "vm/types.h"
 
 #include "vm/global.h"
@@ -85,6 +85,8 @@ typedef java_lang_String heapstring_t;
 
 bool string_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("string_init");
+
        /* create string (javastring) hashtable */
 
        hashtable_create(&hashtable_string, HASHTABLE_STRING_SIZE);
@@ -228,7 +230,8 @@ java_handle_t *javastring_safe_new_from_utf8(const char *text)
        s4 nbytes;
        s4 len;
 
-       assert(text);
+       if (text == NULL)
+               return NULL;
 
        /* Get number of bytes. We need this to completely emulate the messy */
        /* behaviour of the RI. :(                                           */
@@ -709,6 +712,9 @@ java_object_t *literalstring_new(utf *u)
 
 *******************************************************************************/
 
+#if 0
+/* TWISTI This one is currently not used. */
+
 static void literalstring_free(java_object_t* string)
 {
        heapstring_t     *s;
@@ -723,6 +729,7 @@ static void literalstring_free(java_object_t* string)
        /* dispose memory of java-characterarray */
        FREE(a, sizeof(java_chararray_t) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
 }
+#endif
 
 
 /* javastring_intern ***********************************************************
@@ -755,13 +762,13 @@ java_handle_t *javastring_intern(java_handle_t *s)
 }
 
 
-/* javastring_print ************************************************************
+/* javastring_fprint ***********************************************************
 
-   Print the given Java string.
+   Print the given Java string to the given stream.
 
 *******************************************************************************/
 
-void javastring_print(java_handle_t *s)
+void javastring_fprint(java_handle_t *s, FILE *stream)
 {
        java_lang_String        *so;
        java_handle_chararray_t *value;
@@ -778,7 +785,7 @@ void javastring_print(java_handle_t *s)
 
        for (i = offset; i < offset + count; i++) {
                c = LLNI_array_direct(value, i);
-               putchar(c);
+               fputc(c, stream);
        }
 }
 
index 1aa4579e5024f4f4e1e0e5021036ac256304533b..74ffc2366b44bb0cb93c23e433569aed3b861af7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/stringlocal.h - string 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.
 
@@ -32,6 +30,9 @@ typedef struct literalstring literalstring;
 
 
 #include "config.h"
+
+#include "vmcore/system.h"
+
 #include "vm/types.h"
 
 #include "toolbox/hashtable.h"
@@ -85,7 +86,7 @@ utf *javastring_toutf(java_handle_t *string, bool isclassname);
 java_object_t *literalstring_new(utf *u);
 
 java_handle_t *javastring_intern(java_handle_t *s);
-void           javastring_print(java_handle_t *s);
+void           javastring_fprint(java_handle_t *s, FILE *stream);
 
 #endif /* _STRINGLOCAL_H */
 
index e1d7dafb2b76e01841113d728e3119865fb4249e..ea79bcc71946caef7fadd6fa1f59dd49e9eb0432 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/vm.c - VM startup and shutdown 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,7 @@
 
 #include "vm/jit/abi-asm.h"
 
+#include "mm/codememory.h"
 #include "mm/gc-common.h"
 #include "mm/memory.h"
 
 
 #include "native/vm/nativevm.h"
 
-#include "threads/threads-common.h"
+#include "threads/lock-common.h"
+#include "threads/mutex.h"
+#include "threads/threadlist.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
 
 #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/methodtree.h"
 
 #if defined(ENABLE_PROFILING)
 # include "vm/jit/optimizing/profile.h"
 
 #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"
@@ -121,7 +132,8 @@ _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
 s4 vms = 0;                             /* number of VMs created              */
 
 bool vm_initializing = false;
-bool vm_exiting = false;
+bool vm_created      = false;
+bool vm_exiting      = false;
 
 char      *mainstring = NULL;
 classinfo *mainclass = NULL;
@@ -165,6 +177,9 @@ enum {
 
        OPT_EA,
        OPT_DA,
+       OPT_EA_NOARG,
+       OPT_DA_NOARG,
+    
 
        OPT_ESA,
        OPT_DSA,
@@ -231,19 +246,6 @@ enum {
        OPT_LSRA,
 #endif
 
-#if defined(ENABLE_INLINING)
-       OPT_INLINING,
-#if !defined(NDEBUG)
-       OPT_INLINE_LOG,
-#endif
-#if defined(ENABLE_INLINING_DEBUG)
-       OPT_INLINE_DEBUG_ALL,
-       OPT_INLINE_DEBUG_END,
-       OPT_INLINE_DEBUG_MIN,
-       OPT_INLINE_DEBUG_MAX,
-#endif /* defined(ENABLE_INLINING_DEBUG) */
-#endif /* defined(ENABLE_INLINING) */
-
 #if defined(ENABLE_INTRP)
        /* interpreter options */
 
@@ -301,8 +303,13 @@ opt_struct opts[] = {
 
        { "ea:",               true,  OPT_EA },
        { "da:",               true,  OPT_DA },
-       { "ea",                false, OPT_EA },
-       { "da",                false, 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 },
@@ -342,9 +349,12 @@ opt_struct opts[] = {
 #if defined(ENABLE_IFCONV)
        { "ifconv",            false, OPT_IFCONV },
 #endif
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+#if defined(ENABLE_LSRA)
        { "lsra",              false, OPT_LSRA },
 #endif
+#if  defined(ENABLE_SSA)
+       { "lsra",              true, OPT_LSRA },
+#endif
 
 #if defined(ENABLE_INTRP)
        /* interpreter options */
@@ -389,21 +399,6 @@ opt_struct opts[] = {
        { "Xprof",             false, OPT_PROF },
 #endif
 
-       /* inlining options */
-
-#if defined(ENABLE_INLINING)
-#if defined(ENABLE_INLINING_DEBUG)
-       { "ia",                false, OPT_INLINE_DEBUG_ALL },
-       { "ii",                true,  OPT_INLINE_DEBUG_MIN },
-       { "im",                true,  OPT_INLINE_DEBUG_MAX },
-       { "ie",                true,  OPT_INLINE_DEBUG_END },
-#endif /* defined(ENABLE_INLINING_DEBUG) */
-#if !defined(NDEBUG)
-       { "il",                false, OPT_INLINE_LOG },
-#endif
-       { "i",                 false, OPT_INLINING },
-#endif /* defined(ENABLE_INLINING) */
-
        /* keep these at the end of the list */
 
 #if !defined(NDEBUG)
@@ -561,19 +556,6 @@ static void XXusage(void)
 #endif
        puts("      (d)atasegment          data segment listing");
 
-#if defined(ENABLE_INLINING)
-       puts("    -i                       activate inlining");
-#if !defined(NDEBUG)
-       puts("    -il                      log inlining");
-#endif
-#if defined(ENABLE_INLINING_DEBUG)
-       puts("    -ia                      use inlining for all methods");
-       puts("    -ii <size>               set minimum size for inlined result");
-       puts("    -im <size>               set maximum size for inlined result");
-       puts("    -ie <number>             stop inlining after the given number of roots");
-#endif /* defined(ENABLE_INLINING_DEBUG) */
-#endif /* defined(ENABLE_INLINING) */
-
 #if defined(ENABLE_IFCONV)
        puts("    -ifconv                  use if-conversion");
 #endif
@@ -581,7 +563,9 @@ static void XXusage(void)
        puts("    -lsra                    use linear scan register allocation");
 #endif
 #if defined(ENABLE_SSA)
-       puts("    -lsra                    use linear scan register allocation (with 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");
@@ -604,22 +588,12 @@ static void XXusage(void)
 static void version(bool opt_exit)
 {
        puts("java version \""JAVA_VERSION"\"");
-       puts("CACAO version "VERSION"");
-
-       puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,");
-       puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
-       puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
-       puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
+       puts("CACAO version "VERSION"\n");
 
-       puts("This program is free software; you can redistribute it and/or");
-       puts("modify it under the terms of the GNU General Public License as");
-       puts("published by the Free Software Foundation; either version 2, or (at");
-       puts("your option) any later version.\n");
-
-       puts("This program is distributed in the hope that it will be useful, but");
-       puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
-       puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
-       puts("General Public License for more details.");
+       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 */
 
@@ -661,7 +635,7 @@ static void vm_printconfig(void)
        printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
        printf("  stack size                     : %d\n", STACK_SIZE);
 
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
        /* When we're building with JRE-layout, the default paths are the
           same as the runtime paths. */
 #else
@@ -788,10 +762,6 @@ bool vm_create(JavaVMInitArgs *vm_args)
        jdwp = agentbypath = false;
 #endif
 
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_init(vm_args);
-#endif
-
 #if defined(ENABLE_JNI)
        /* Check the JNI version requested. */
 
@@ -827,8 +797,16 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
        /* 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. */
@@ -1213,41 +1191,37 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        break;
 #endif
 
-#if defined(ENABLE_INLINING)
-#if defined(ENABLE_INLINING_DEBUG)
-               case OPT_INLINE_DEBUG_ALL:
-                       opt_inline_debug_all = true;
-                       break;
-               case OPT_INLINE_DEBUG_END:
-                       opt_inline_debug_end_counter = atoi(opt_arg);
-                       break;
-               case OPT_INLINE_DEBUG_MIN:
-                       opt_inline_debug_min_size = atoi(opt_arg);
-                       break;
-               case OPT_INLINE_DEBUG_MAX:
-                       opt_inline_debug_max_size = atoi(opt_arg);
-                       break;
-#endif /* defined(ENABLE_INLINING_DEBUG) */
-#if !defined(NDEBUG)
-               case OPT_INLINE_LOG:
-                       opt_inline_debug_log = true;
-                       break;
-#endif /* !defined(NDEBUG) */
-
-               case OPT_INLINING:
-                       opt_inlining = true;
-                       break;
-#endif /* defined(ENABLE_INLINING) */
-
 #if defined(ENABLE_IFCONV)
                case OPT_IFCONV:
                        opt_ifconv = true;
                        break;
 #endif
 
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+#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
 
@@ -1275,6 +1249,18 @@ bool vm_create(JavaVMInitArgs *vm_args)
 #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;
@@ -1429,10 +1415,16 @@ bool vm_create(JavaVMInitArgs *vm_args)
        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 */
@@ -1456,8 +1448,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
        /* AFTER: threads_preinit */
 
-       if (!utf8_init())
-               vm_abort("vm_create: utf8_init failed");
+       utf8_init();
 
        /* AFTER: thread_preinit */
 
@@ -1485,11 +1476,10 @@ bool vm_create(JavaVMInitArgs *vm_args)
        if (!classcache_init())
                vm_abort("vm_create: classcache_init failed");
 
-       /* initialize the memory subsystem (must be done _after_
-          threads_preinit) */
+       /* Initialize the code memory management. */
+       /* AFTER: threads_preinit */
 
-       if (!memory_init())
-               vm_abort("vm_create: memory_init failed");
+       codememory_init();
 
        /* initialize the finalizer stuff (must be done _after_
           threads_preinit) */
@@ -1497,9 +1487,15 @@ bool vm_create(JavaVMInitArgs *vm_args)
        if (!finalizer_init())
                vm_abort("vm_create: finalizer_init failed");
 
-       /* initializes jit compiler */
+       /* Initialize the JIT compiler. */
 
        jit_init();
+       code_init();
+       methodtree_init();
+
+#if defined(ENABLE_PYTHON)
+       pythonpass_init();
+#endif
 
        /* BEFORE: loader_preinit */
 
@@ -1520,8 +1516,11 @@ bool vm_create(JavaVMInitArgs *vm_args)
        /* AFTER: loader_init, linker_init */
 
        primitive_postinit();
+       method_init();
 
-       exceptions_init();
+#if defined(ENABLE_JIT)
+       trap_init();
+#endif
 
        if (!builtin_init())
                vm_abort("vm_create: builtin_init failed");
@@ -1535,8 +1534,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
        /* Register the native methods implemented in the VM. */
        /* BEFORE: threads_init */
 
-       if (!nativevm_preinit())
-               vm_abort("vm_create: nativevm_preinit failed");
+       nativevm_preinit();
 
 #if defined(ENABLE_JNI)
        /* Initialize the JNI subsystem (must be done _before_
@@ -1555,16 +1553,19 @@ bool vm_create(JavaVMInitArgs *vm_args)
                vm_abort("vm_create: localref_table_init failed");
 #endif
 
+       /* Iinitialize some important system classes. */
+       /* BEFORE: threads_init */
+
+       initialize_init();
+
 #if defined(ENABLE_THREADS)
-       if (!threads_init())
-               vm_abort("vm_create: threads_init failed");
+       threads_init();
 #endif
 
        /* Initialize the native VM subsystem. */
        /* AFTER: threads_init (at least for SUN's classes) */
 
-       if (!nativevm_init())
-               vm_abort("vm_create: nativevm_init failed");
+       nativevm_init();
 
 #if defined(ENABLE_PROFILING)
        /* initialize profiling */
@@ -1627,21 +1628,20 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 #endif
 
-       /* increment the number of VMs */
+       /* Increment the number of VMs. */
 
        vms++;
 
-       /* initialization is done */
+       /* Initialization is done, VM is created.. */
 
+       vm_created      = true;
        vm_initializing = false;
 
-#if !defined(NDEBUG)
        /* Print the VM configuration after all stuff is set and the VM is
           initialized. */
 
        if (opt_PrintConfig)
                vm_printconfig();
-#endif
 
        /* everything's ok */
 
@@ -1665,8 +1665,12 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
        s4                         oalength;
        utf                       *u;
        java_handle_t             *s;
-       s4                         status;
-       s4                         i;
+       int                        status;
+       int                        i;
+
+#if defined(ENABLE_THREADS)
+       threadobject              *t;
+#endif
 
 #if !defined(NDEBUG)
        if (compileall) {
@@ -1792,11 +1796,21 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
                status = 1;
        }
 
-       /* unload the JavaVM */
+#if defined(ENABLE_THREADS)
+    /* Detach the main thread so that it appears to have ended when
+          the application's main method exits. */
+
+       t = thread_get_current();
+
+       if (!threads_detach_thread(t))
+               vm_abort("vm_run: Could not detach main thread.");
+#endif
+
+       /* Destroy the JavaVM. */
 
        (void) vm_destroy(vm);
 
-       /* and exit */
+       /* And exit. */
 
        vm_exit(status);
 }
@@ -1808,13 +1822,30 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 
 *******************************************************************************/
 
-s4 vm_destroy(JavaVM *vm)
+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 (!threads_attach_current_thread(&args, false))
+               return 1;
+
+       /* Wait until we are the last non-daemon thread. */
+
        threads_join_all_threads();
 #endif
 
-       /* everything's ok */
+       /* VM is gone. */
+
+       vm_created = false;
+
+       /* Everything is ok. */
 
        return 0;
 }
@@ -1896,9 +1927,9 @@ void vm_shutdown(s4 status)
 #if defined(ENABLE_JVMTI)
        /* terminate cacaodbgserver */
        if (dbgcom!=NULL) {
-               pthread_mutex_lock(&dbgcomlock);
+               mutex_lock(&dbgcomlock);
                dbgcom->running=1;
-               pthread_mutex_unlock(&dbgcomlock);
+               mutex_unlock(&dbgcomlock);
                jvmti_cacaodbgserver_quit();
        }       
 #endif
@@ -1972,13 +2003,16 @@ void vm_exit_handler(void)
 
    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 */
+       /* Print the log message. */
 
        log_start();
 
@@ -1988,9 +2022,63 @@ void vm_abort(const char *text, ...)
 
        log_finish();
 
-       /* now abort the VM */
+       /* Now abort the VM. */
 
-       abort();
+       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);
 }
 
 
@@ -2156,7 +2244,8 @@ static char *vm_get_mainclass_from_jar(char *mainstring)
        o = vm_call_method(m, o, s);
 
        if (o == NULL) {
-               exceptions_print_stacktrace();
+               fprintf(stderr, "Failed to load Main-Class manifest attribute from\n");
+               fprintf(stderr, "%s\n", mainstring);
                return NULL;
        }
 
@@ -2379,21 +2468,21 @@ VM_CALL_METHOD(_double, double)
 type vm_call_method##name##_valist(methodinfo *m, java_handle_t *o,     \
                                                                   va_list ap)                          \
 {                                                                       \
-       int32_t   dumpsize;                                                 \
        uint64_t *array;                                                    \
        type      value;                                                    \
+       int32_t   dumpmarker;                                               \
                                                                         \
        if (m->code == NULL)                                                \
                if (!jit_compile(m))                                            \
                        return 0;                                                   \
                                                                         \
        THREAD_NATIVEWORLD_EXIT;                                            \
+       DMARKER;                                                            \
                                                                         \
-       dumpsize = dump_size();                                             \
        array = argument_vmarray_from_valist(m, o, ap);                     \
        value = vm_call##name##_array(m, array);                            \
-       dump_release(dumpsize);                                             \
                                                                         \
+       DRELEASE;                                                           \
        THREAD_NATIVEWORLD_ENTER;                                           \
                                                                         \
        return value;                                                       \
@@ -2417,21 +2506,21 @@ VM_CALL_METHOD_VALIST(_double, double)
 type vm_call_method##name##_jvalue(methodinfo *m, java_handle_t *o,     \
                                                           const jvalue *args)                  \
 {                                                                       \
-       int32_t   dumpsize;                                                 \
        uint64_t *array;                                                    \
        type      value;                                                    \
+       int32_t   dumpmarker;                                               \
                                                                         \
        if (m->code == NULL)                                                \
                if (!jit_compile(m))                                            \
                        return 0;                                                   \
                                                                         \
        THREAD_NATIVEWORLD_EXIT;                                            \
+       DMARKER;                                                            \
                                                                         \
-       dumpsize = dump_size();                                             \
        array = argument_vmarray_from_jvalue(m, o, args);                   \
        value = vm_call##name##_array(m, array);                            \
-       dump_release(dumpsize);                                             \
                                                                         \
+       DRELEASE;                                                           \
        THREAD_NATIVEWORLD_ENTER;                                           \
                                                                         \
        return value;                                                       \
@@ -2454,11 +2543,15 @@ VM_CALL_METHOD_JVALUE(_double, double)
 java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
                                                                                  java_handle_objectarray_t *params)
 {
-       int32_t        dumpsize;
        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 */
 
@@ -2472,7 +2565,7 @@ java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* Fill the argument array from a object-array. */
 
@@ -2481,7 +2574,7 @@ java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
        if (array == NULL) {
                /* release dump area */
 
-               dump_release(dumpsize);
+               DRELEASE;
 
                /* enter the nativeworld again */
 
@@ -2527,7 +2620,7 @@ java_handle_t *vm_call_method_objectarray(methodinfo *m, java_handle_t *o,
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        /* enter the nativeworld again */
 
index f96107e7cbf95b3d0e0b06f1f90acc7160a1d91d..8a786cd835ba5ad054abf98ece0263c066ead71b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/vm.h - basic JVM 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.
 
@@ -31,6 +29,7 @@
 #include "config.h"
 
 #include <stdarg.h>
+#include <stdint.h>
 
 #include "vm/types.h"
 
@@ -48,6 +47,7 @@ extern _Jv_JavaVM *_Jv_jvm;
 extern _Jv_JNIEnv *_Jv_env;
 
 extern bool vm_initializing;
+extern bool vm_created;
 extern bool vm_exiting;
 
 extern char      *mainstring;
@@ -72,6 +72,8 @@ 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 */
index ad5993cc50b8e3f5ef4bf3efe2e63d025cd78100..4d7021d4d86e670586df7b86b25096ad7e9e8c8d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/annotation.c - 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
+   Copyright (C) 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -267,7 +265,7 @@ bool annotation_load_method_attribute_annotationdefault(
        assert(m != NULL);
 
        LLNI_classinfo_field_get(
-               m->class, method_annotationdefaults, annotationdefaults);
+               m->clazz, method_annotationdefaults, annotationdefaults);
 
        if (!annotation_load_attribute_body(
                        cb, &annotationdefault,
@@ -276,7 +274,7 @@ bool annotation_load_method_attribute_annotationdefault(
        }
 
        if (annotationdefault != NULL) {
-               slot = m - m->class->methods;
+               slot = m - m->clazz->methods;
                annotationdefaults = annotation_bytearrays_insert(
                                annotationdefaults, slot, annotationdefault);
 
@@ -285,7 +283,7 @@ bool annotation_load_method_attribute_annotationdefault(
                }
 
                LLNI_classinfo_field_set(
-                       m->class, method_annotationdefaults, annotationdefaults);
+                       m->clazz, method_annotationdefaults, annotationdefaults);
        }
 
        return true;
@@ -331,7 +329,7 @@ bool annotation_load_method_attribute_runtimevisibleparameterannotations(
        assert(m != NULL);
 
        LLNI_classinfo_field_get(
-               m->class, method_parameterannotations, parameterannotations);
+               m->clazz, method_parameterannotations, parameterannotations);
 
        if (!annotation_load_attribute_body(
                        cb, &annotations,
@@ -340,7 +338,7 @@ bool annotation_load_method_attribute_runtimevisibleparameterannotations(
        }
 
        if (annotations != NULL) {
-               slot = m - m->class->methods;
+               slot = m - m->clazz->methods;
                parameterannotations = annotation_bytearrays_insert(
                                parameterannotations, slot, annotations);
 
@@ -349,7 +347,7 @@ bool annotation_load_method_attribute_runtimevisibleparameterannotations(
                }
 
                LLNI_classinfo_field_set(
-                       m->class, method_parameterannotations, parameterannotations);
+                       m->clazz, method_parameterannotations, parameterannotations);
        }
 
        return true;
@@ -429,8 +427,7 @@ bool annotation_load_class_attribute_runtimevisibleannotations(
                return false;
        }
 
-       LLNI_classinfo_field_set(
-               cb->class, annotations, (java_handle_t*)annotations);
+       LLNI_classinfo_field_set(cb->clazz, annotations, (java_handle_t*)annotations);
 
        return true;
 }
@@ -483,7 +480,7 @@ bool annotation_load_method_attribute_runtimevisibleannotations(
        assert(m != NULL);
 
        LLNI_classinfo_field_get(
-               m->class, method_annotations, method_annotations);
+               m->clazz, method_annotations, method_annotations);
 
        if (!annotation_load_attribute_body(
                        cb, &annotations,
@@ -492,7 +489,7 @@ bool annotation_load_method_attribute_runtimevisibleannotations(
        }
 
        if (annotations != NULL) {
-               slot = m - m->class->methods;
+               slot = m - m->clazz->methods;
                method_annotations = annotation_bytearrays_insert(
                                method_annotations, slot, annotations);
 
@@ -501,7 +498,7 @@ bool annotation_load_method_attribute_runtimevisibleannotations(
                }
                
                LLNI_classinfo_field_set(
-                       m->class, method_annotations, method_annotations);
+                       m->clazz, method_annotations, method_annotations);
        }
 
        return true;
@@ -557,7 +554,7 @@ bool annotation_load_field_attribute_runtimevisibleannotations(
        assert(f != NULL);
 
        LLNI_classinfo_field_get(
-               f->class, field_annotations, field_annotations);
+               f->clazz, field_annotations, field_annotations);
 
        if (!annotation_load_attribute_body(
                        cb, &annotations,
@@ -566,7 +563,7 @@ bool annotation_load_field_attribute_runtimevisibleannotations(
        }
 
        if (annotations != NULL) {
-               slot = f - f->class->fields;
+               slot = f - f->clazz->fields;
                field_annotations = annotation_bytearrays_insert(
                                field_annotations, slot, annotations);
 
@@ -575,7 +572,7 @@ bool annotation_load_field_attribute_runtimevisibleannotations(
                }
 
                LLNI_classinfo_field_set(
-                       f->class, field_annotations, field_annotations);
+                       f->clazz, field_annotations, field_annotations);
        }
 
        return true;
index 1e5d2f30480be57d3dc19c1921c682cbb1a1b209..bccb4d5d12909cad41ffe18b5dd241c31f75ddb5 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/class.c - class related 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 "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 */
+/* Important system classes. */
 
 classinfo *class_java_lang_Object;
 classinfo *class_java_lang_Class;
@@ -90,6 +99,12 @@ 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_CLASSPATH_SUN)
 classinfo *class_sun_reflect_MagicAccessorImpl;
 #endif
@@ -117,6 +132,12 @@ classinfo *class_java_security_PrivilegedAction;
 classinfo *class_java_util_Vector;
 classinfo *class_java_util_HashMap;
 
+# if defined(WITH_CLASSPATH_GNU)
+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)
@@ -292,7 +313,7 @@ void class_postset_header_vftbl(void)
 
 *******************************************************************************/
 
-classinfo *class_define(utf *name, classloader *cl, int32_t length, const uint8_t *data, java_handle_t *pd)
+classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
 {
        classinfo   *c;
        classinfo   *r;
@@ -324,7 +345,7 @@ classinfo *class_define(utf *name, classloader *cl, int32_t length, const uint8_
 
        cb = NEW(classbuffer);
 
-       cb->class = c;
+       cb->clazz = c;
        cb->size  = length;
        cb->data  = data;
        cb->pos   = cb->data;
@@ -402,7 +423,7 @@ static bool class_load_attribute_sourcefile(classbuffer *cb)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* check buffer size */
 
@@ -464,7 +485,7 @@ static bool class_load_attribute_enclosingmethod(classbuffer *cb)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* check buffer size */
 
@@ -537,7 +558,7 @@ bool class_load_attributes(classbuffer *cb)
        uint16_t               flags;
        int                    i, j;
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* get attributes count */
 
@@ -841,8 +862,8 @@ void class_free(classinfo *c)
 
 *******************************************************************************/
 
-static classinfo *get_array_class(utf *name,classloader *initloader,
-                                                                                       classloader *defloader,bool link)
+static classinfo *get_array_class(utf *name,classloader_t *initloader,
+                                                                                       classloader_t *defloader,bool link)
 {
        classinfo *c;
        
@@ -882,16 +903,16 @@ static classinfo *get_array_class(utf *name,classloader *initloader,
 
 classinfo *class_array_of(classinfo *component, bool link)
 {
-       classloader       *cl;
+       classloader_t     *cl;
     s4                 namelen;
     char              *namebuf;
        utf               *u;
        classinfo         *c;
-       s4                 dumpsize;
+       int32_t            dumpmarker;
 
        cl = component->classloader;
 
-       dumpsize = dump_size();
+       DMARKER;
 
     /* Assemble the array class name */
     namelen = component->name->blength;
@@ -917,7 +938,7 @@ classinfo *class_array_of(classinfo *component, bool link)
 
        c = get_array_class(u, cl, cl, link);
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return c;
 }
@@ -934,10 +955,10 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
 {
     s4 namelen;
     char *namebuf;
-       s4 dumpsize;
        classinfo *c;
+       int32_t    dumpmarker;
 
-       dumpsize = dump_size();
+       DMARKER;
 
        if (dim < 1) {
                log_text("Invalid array dimension requested");
@@ -968,7 +989,7 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
                                                element->classloader,
                                                link);
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return c;
 }
@@ -1096,13 +1117,13 @@ constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *r
 {
     s4 namelen;
     char *namebuf;
-       s4 dumpsize;
        constant_classref *cr;
+       int32_t            dumpmarker;
 
        assert(ref);
        assert(dim >= 1 && dim <= 255);
 
-       dumpsize = dump_size();
+       DMARKER;
 
     /* Assemble the array class name */
     namelen = ref->name->blength;
@@ -1125,7 +1146,7 @@ constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *r
 
     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return cr;
 }
@@ -1582,6 +1603,59 @@ bool class_isanysubclass(classinfo *sub, classinfo *super)
 }
 
 
+/* 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
@@ -1607,7 +1681,7 @@ classinfo *class_get_componenttype(classinfo *c)
                return NULL;
        
        if (ad->arraytype == ARRAYTYPE_OBJECT)
-               component = ad->componentvftbl->class;
+               component = ad->componentvftbl->clazz;
        else
                component = primitive_class_get_by_type(ad->arraytype);
                
@@ -1703,6 +1777,210 @@ java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOn
 }
 
 
+/**
+ * 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,
@@ -1781,6 +2059,117 @@ classinfo *class_get_enclosingclass(classinfo *c)
 }
 
 
+/**
+ * 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.
index 6d4ab0627e096a5498d8253cfa7c293415dd692e..2bd79593c9cd54f28e7f8f78a43b671fedbf45d2 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/class.h - class related functions 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.
 
@@ -45,6 +43,7 @@ typedef struct castinfo       castinfo;
 #include "toolbox/list.h"
 
 #include "vm/global.h"
+#include "vm/stringlocal.h"
 
 #if defined(ENABLE_JAVASE)
 # include "vmcore/annotation.h"
@@ -159,7 +158,7 @@ struct classinfo {                /* class structure                          */
 
 #endif
 #endif
-       classloader *classloader;       /* NULL for bootstrap classloader         */
+       classloader_t *classloader;       /* NULL for bootstrap classloader         */
 
 #if defined(ENABLE_JAVASE)
 # if defined(WITH_CLASSPATH_SUN)
@@ -205,7 +204,7 @@ struct castinfo {
 
 /* frequently used classes ****************************************************/
 
-/* important system classes */
+/* Important system classes. */
 
 extern classinfo *class_java_lang_Object;
 extern classinfo *class_java_lang_Class;
@@ -219,6 +218,12 @@ 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_CLASSPATH_GNU)
 extern classinfo *class_java_lang_VMSystem;
 extern classinfo *class_java_lang_VMThread;
@@ -253,6 +258,12 @@ extern classinfo *class_java_security_PrivilegedAction;
 extern classinfo *class_java_util_Vector;
 extern classinfo *class_java_util_HashMap;
 
+# if defined(WITH_CLASSPATH_GNU)
+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)
@@ -294,6 +305,25 @@ 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.
@@ -391,9 +421,9 @@ static inline bool class_is_memberclass(classinfo *c)
 
 *******************************************************************************/
 
-static inline classloader *class_get_classloader(classinfo *c)
+static inline classloader_t *class_get_classloader(classinfo *c)
 {
-       classloader *cl;
+       classloader_t *cl;
 
        cl = c->classloader;
 
@@ -427,7 +457,7 @@ static inline classinfo *class_get_superclass(classinfo *c)
 
 classinfo *class_create_classinfo(utf *u);
 void       class_postset_header_vftbl(void);
-classinfo *class_define(utf *name, classloader *cl, int32_t length, const uint8_t *data, java_handle_t *pd);
+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);
@@ -480,25 +510,27 @@ 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_primitive(classinfo *c);
-bool                       class_is_anonymousclass(classinfo *c);
-bool                       class_is_array(classinfo *c);
-bool                       class_is_interface(classinfo *c);
-bool                       class_is_localclass(classinfo *c);
-bool                       class_is_memberclass(classinfo *c);
+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               *class_get_classloader(classinfo *c);
+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);
index 91e51a3919e693cb503786cd3c2b18a2778fa19c..76fc8255f7b7832f9584e6caa0e101e516d4536b 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/classcache.c - loaded class cache and loading constraints
 
-   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.
 
@@ -41,6 +39,7 @@
 #include "vm/exceptions.h"
 
 #include "vmcore/classcache.h"
+#include "vmcore/options.h"
 #include "vmcore/utf8.h"
 
 
@@ -253,6 +252,8 @@ static void classcache_remove_class_entry(classcache_name_entry *en,
 
 bool classcache_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("classcache_init");
+
        /* create the hashtable */
 
        hashtable_create(&hashtable_classcache, CLASSCACHE_INIT_SIZE);
@@ -285,7 +286,7 @@ bool classcache_init(void)
 *******************************************************************************/
 
 static classcache_loader_entry * classcache_new_loader_entry(
-                                                                       classloader * loader,
+                                                                       classloader_t * loader,
                                                                        classcache_loader_entry * next)
 {
        classcache_loader_entry *lden;
@@ -571,7 +572,7 @@ static classcache_name_entry *classcache_new_name(utf *name)
    
 *******************************************************************************/
 
-classinfo *classcache_lookup(classloader *initloader, utf *classname)
+classinfo *classcache_lookup(classloader_t *initloader, utf *classname)
 {
        classcache_name_entry *en;
        classcache_class_entry *clsen;
@@ -623,7 +624,7 @@ classinfo *classcache_lookup(classloader *initloader, utf *classname)
    
 *******************************************************************************/
 
-classinfo *classcache_lookup_defined(classloader *defloader, utf *classname)
+classinfo *classcache_lookup_defined(classloader_t *defloader, utf *classname)
 {
        classcache_name_entry *en;
        classcache_class_entry *clsen;
@@ -669,7 +670,7 @@ classinfo *classcache_lookup_defined(classloader *defloader, utf *classname)
    
 *******************************************************************************/
 
-classinfo *classcache_lookup_defined_or_initiated(classloader *loader, 
+classinfo *classcache_lookup_defined_or_initiated(classloader_t *loader, 
                                                                                                  utf *classname)
 {
        classcache_name_entry *en;
@@ -737,7 +738,7 @@ classinfo *classcache_lookup_defined_or_initiated(classloader *loader,
    
 *******************************************************************************/
 
-classinfo *classcache_store(classloader *initloader, classinfo *cls,
+classinfo *classcache_store(classloader_t *initloader, classinfo *cls,
                                                        bool mayfree)
 {
        classcache_name_entry *en;
@@ -1003,7 +1004,7 @@ return_success:
 
 static classcache_class_entry * classcache_find_loader(
                                                                        classcache_name_entry * entry,
-                                                                       classloader * loader)
+                                                                       classloader_t * loader)
 {
        classcache_class_entry *clsen;
        classcache_loader_entry *lden;
@@ -1162,8 +1163,8 @@ void classcache_free(void)
 *******************************************************************************/
 
 #if defined(ENABLE_VERIFIER)
-bool classcache_add_constraint(classloader * a,
-                                                          classloader * b,
+bool classcache_add_constraint(classloader_t * a,
+                                                          classloader_t * b,
                                                           utf * classname)
 {
        classcache_name_entry *en;
@@ -1280,8 +1281,8 @@ bool classcache_add_constraint(classloader * a,
 *******************************************************************************/
 
 #if defined(ENABLE_VERIFIER)
-bool classcache_add_constraints_for_params(classloader * a,
-                                                                                  classloader * b,
+bool classcache_add_constraints_for_params(classloader_t * a,
+                                                                                  classloader_t * b,
                                                                                   methodinfo *m)
 {
        methoddesc *md;
index bd89d1475a50bd0a7d5af649f54727bffbaf6697..bbdba5c521a34ededf30ebc339207f113bb23e6c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/classcache.h - loaded class cache and loading constraints
 
-   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.
 
@@ -113,7 +111,7 @@ struct classcache_class_entry
 
 struct classcache_loader_entry
 {
-       classloader              *loader;     /* class loader object              */
+       classloader_t            *loader;     /* class loader object              */
        classcache_loader_entry  *next;       /* next loader entry in the list    */
 };
 
@@ -129,17 +127,17 @@ typedef void (*classcache_foreach_functionptr_t)(classinfo *, void *);
 bool classcache_init(void);
 void classcache_free(void);
 
-classinfo * classcache_lookup(classloader *initloader,utf *classname);
-classinfo * classcache_lookup_defined(classloader *defloader,utf *classname);
-classinfo * classcache_lookup_defined_or_initiated(classloader *loader,utf *classname);
+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 *initloader,classinfo *cls,bool mayfree);
+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 *a,classloader *b,utf *classname);
-bool classcache_add_constraints_for_params(classloader *a,classloader *b,
+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
 
index 9d476e271274c5a54f2d95d3781f525c37fdde0b..f49e05012ca116c88db8721d6bb48fc3382098d2 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/descriptor.c - 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -70,7 +68,7 @@ struct classref_hash_entry {
 struct descriptor_hash_entry {
        descriptor_hash_entry *hashlink;
        utf                   *desc;
-       parseddesc             parseddesc;
+       parseddesc_t           parseddesc;
        s2                     paramslots; /* number of params, LONG/DOUBLE counted as 2 */
 };
 
index 7128d1b34dc386f14ba8c58d41240a2a5ce7137d..00c0680e9e61e29d2fec4365dad1e0f614fa1c99 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/field.c - field 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.
 
@@ -74,9 +72,9 @@ bool field_load(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
 
        /* Get class. */
 
-       c = cb->class;
+       c = cb->clazz;
 
-       f->class = c;
+       f->clazz = c;
 
        /* Get access flags. */
 
@@ -363,7 +361,7 @@ classinfo *field_get_type(fieldinfo *f)
                /* load the class of the field-type with the field's
                   classloader */
 
-               c = load_class_from_classloader(u, f->class->classloader);
+               c = load_class_from_classloader(u, f->clazz->classloader);
        }
        else {
                c = primitive_class_get_by_type(td->decltype);
@@ -412,7 +410,7 @@ java_handle_bytearray_t *field_get_annotations(fieldinfo *f)
        java_handle_t           *field_annotations;  /* array of unparsed  */
                       /* annotations of all fields of the declaring class */
 
-       c           = f->class;
+       c           = f->clazz;
        slot        = f - c->fields;
        annotations = NULL;
 
@@ -477,13 +475,17 @@ void field_print(fieldinfo *f)
                return;
        }
 
-       utf_display_printable_ascii_classname(f->class->name);
+       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
 
index 4f9dcd121ffe8076674a1ba7c0c12f9679a3da36..32c3871c4a54e968702a43d120dcdfb5b4f761e1 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/field.h - field functions 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.
 
@@ -53,7 +51,7 @@ struct fieldinfo {          /* field of a class                                 */
        /*          value as CLASSREF_PSEUDO_VFTBL! This is used to check whether */
        /*          a constant_FMIref has been resolved.                          */
 
-       classinfo *class;     /* needed by typechecker. Could be optimized        */
+       classinfo *clazz;     /* needed by typechecker. Could be optimized        */
                              /* away by using constant_FMIref instead of         */
                              /* fieldinfo throughout the compiler.               */
 
index 2a49a630fedfd154b3ccf4bd162b911fd3d11484..e8b985aad4891065d335bea85195f6081964781d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/linker.c - class linker 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.
 
@@ -83,7 +81,7 @@ classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool c
 #endif
 
 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
-#define INLINELOG(code)  do { if (opt_inline_debug_log) { code } } while (0)
+#define INLINELOG(code)  do { if (opt_TraceInlining) { code } } while (0)
 #else
 #define INLINELOG(code)
 #endif
@@ -132,6 +130,8 @@ struct dummy_alignment_double_t {
 
 void linker_preinit(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("linker_preinit");
+
        /* Check for if alignment for long and double matches what we
           assume for the current architecture. */
 
@@ -196,6 +196,8 @@ void linker_preinit(void)
 
 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. */
@@ -277,6 +279,16 @@ void linker_init(void)
                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 */
 
@@ -293,6 +305,17 @@ void linker_init(void)
        if (!link_class(class_java_lang_reflect_Method))
                vm_abort("linker_init: linking failed");
 
+# if defined(WITH_CLASSPATH_GNU)
+       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");
 
@@ -466,8 +489,8 @@ static bool linker_overwrite_method(methodinfo *mg,
        classinfo *cg;
        classinfo *cs;
 
-       cg = mg->class;
-       cs = ms->class;
+       cg = mg->clazz;
+       cs = ms->clazz;
 
        /* overriding a final method is illegal */
 
@@ -764,7 +787,7 @@ static classinfo *link_class_intern(classinfo *c)
                                        MCOPY(am, im, methodinfo, 1);
 
                                        am->vftblindex  = (vftbllength++);
-                                       am->class       = c;
+                                       am->clazz       = c;
                                        am->flags      |= ACC_MIRANDA;
 
                                noabstractmethod2:
@@ -805,7 +828,7 @@ static classinfo *link_class_intern(classinfo *c)
                                         (interfacetablelength - 1) * (interfacetablelength > 1));
 
        c->vftbl                = v;
-       v->class                = c;
+       v->clazz                = c;
        v->vftbllength          = vftbllength;
        v->interfacetablelength = interfacetablelength;
        v->arraydesc            = arraydesc;
index 35a2950a7b4378c1fc6bec4498b97b082c40632d..ad95bcccc824c6c9129e7a6bbcf84896cbc6c003 100644 (file)
@@ -102,7 +102,7 @@ typedef struct primitivetypeinfo primitivetypeinfo;
 
 struct _vftbl {
        methodptr   *interfacetable[1];    /* interface table (access via macro)  */
-       classinfo   *class;                /* class, the vtbl belongs to          */
+       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              */
index 24d2d8fb81a756663aad9649b9a13142c6a61f4c..c664b12eaf7f5c9e96ce1c8a13c0090540114763 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/loader.c - class loader 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.
 
@@ -100,7 +98,11 @@ 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;
@@ -139,6 +141,8 @@ void loader_preinit(void)
  
 void loader_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("loader_init");
+
        /* Load primitive-type wrapping classes. */
 
        assert(vm_initializing == true);
@@ -193,28 +197,35 @@ void loader_init(void)
                load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
 #endif
 
-       /* Some classes which may be used often. */
+       /* Important system exceptions. */
 
-#if defined(ENABLE_JAVASE)
-       class_java_lang_StackTraceElement =
-               load_class_bootstrap(utf_java_lang_StackTraceElement);
+       class_java_lang_Exception  = load_class_bootstrap(utf_java_lang_Exception);
 
-       class_java_lang_reflect_Constructor =
-               load_class_bootstrap(utf_java_lang_reflect_Constructor);
+       class_java_lang_ClassNotFoundException =
+               load_class_bootstrap(utf_java_lang_ClassNotFoundException);
 
-       class_java_lang_reflect_Field =
-               load_class_bootstrap(utf_java_lang_reflect_Field);
+       class_java_lang_RuntimeException =
+               load_class_bootstrap(utf_java_lang_RuntimeException);
 
-       class_java_lang_reflect_Method =
-               load_class_bootstrap(utf_java_lang_reflect_Method);
+       /* Some classes which may be used often. */
 
-       class_java_security_PrivilegedAction =
-               load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
+#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_CLASSPATH_GNU)
+       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_util_HashMap = 
-               load_class_bootstrap(utf_new_char("java/util/HashMap"));
+       class_java_security_PrivilegedAction   = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
 
-       class_java_util_Vector     = load_class_bootstrap(utf_java_util_Vector);
+       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_CLASSPATH_SUN)
        class_sun_reflect_MagicAccessorImpl =
@@ -247,7 +258,7 @@ void loader_init(void)
 
 *******************************************************************************/
 
-classloader *loader_hashtable_classloader_add(java_handle_t *cl)
+classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
 {
        hashtable_classloader_entry *cle;
        u4   key;
@@ -330,7 +341,7 @@ classloader *loader_hashtable_classloader_add(java_handle_t *cl)
 
 *******************************************************************************/
 
-classloader *loader_hashtable_classloader_find(java_handle_t *cl)
+classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
 {
        hashtable_classloader_entry *cle;
        u4   key;
@@ -534,7 +545,7 @@ static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
        u1 *cptags;
        voidptr *cpinfos;
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* number of entries in the constant_pool table plus one */
        if (!suck_check_classbuffer_size(cb, 2))
@@ -926,7 +937,7 @@ bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* check remaining bytecode */
 
@@ -976,7 +987,7 @@ classinfo *load_class_from_sysloader(utf *name)
 {
        methodinfo    *m;
        java_handle_t *clo;
-       classloader   *cl;
+       classloader_t *cl;
        classinfo     *c;
 
        assert(class_java_lang_Object);
@@ -1019,7 +1030,7 @@ classinfo *load_class_from_sysloader(utf *name)
 
 *******************************************************************************/
 
-classinfo *load_class_from_classloader(utf *name, classloader *cl)
+classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
 {
        java_handle_t *o;
        classinfo     *c;
@@ -1391,7 +1402,7 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
 
        /* Get the classbuffer's class. */
 
-       c = cb->class;
+       c = cb->clazz;
 
        if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
                return false;
@@ -1639,8 +1650,10 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
                /* XXX This should be done better. */
                tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
 
-               if (tc == NULL)
+               if (tc == NULL) {
+                       resolve_handle_pending_exception(true);
                        return false;
+               }
 
                /* Interfaces are not allowed as super classes. */
 
@@ -1674,8 +1687,10 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
                /* XXX This should be done better. */
                tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
 
-               if (tc == NULL)
+               if (tc == NULL) {
+                       resolve_handle_pending_exception(true);
                        return false;
+               }
 
                /* Detect circularity. */
 
@@ -1715,7 +1730,7 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
                methodinfo *m = &c->methods[i];
                m->parseddesc =
                        descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
-                                                                                                       m->flags, class_get_self_classref(m->class));
+                                                                                                       m->flags, class_get_self_classref(m->clazz));
                if (!m->parseddesc)
                        return false;
 
@@ -1932,12 +1947,12 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
 classinfo *load_class_from_classbuffer(classbuffer *cb)
 {
        classinfo *c;
-       int32_t    dumpsize;
        bool       result;
+       int32_t    dumpmarker;
 
        /* Get the classbuffer's class. */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* Check if the class is already loaded. */
 
@@ -1956,7 +1971,7 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
 
        /* Mark start of dump memory area. */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* Class is currently loading. */
 
@@ -1968,7 +1983,7 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
 
        /* Release dump area. */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        /* An error occurred. */
 
@@ -2018,7 +2033,7 @@ classinfo *load_class_from_classbuffer(classbuffer *cb)
 
 *******************************************************************************/
 
-classinfo *load_newly_created_array(classinfo *c, classloader *loader)
+classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
 {
        classinfo         *comp = NULL;
        methodinfo        *clone;
@@ -2160,7 +2175,7 @@ classinfo *load_newly_created_array(classinfo *c, classloader *loader)
        clone->name       = utf_clone;
        clone->descriptor = utf_void__java_lang_Object;
        clone->parseddesc = clonedesc;
-       clone->class      = c;
+       clone->clazz      = c;
 
        /* parse the descriptor to get the register allocation */
 
index 09c233d3ecbe045174dec17dc7a6bbe0b029c0b7..faa9ba5cfc3321a9b398a9c60d540947a6c80902 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/loader.h - class loader 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.
 
@@ -100,10 +98,10 @@ typedef struct {            /* NameAndType (Field or Method)                  */
 /* classbuffer ****************************************************************/
 
 struct classbuffer {
-       classinfo *class;                   /* pointer to classinfo structure     */
-       u1        *data;                    /* pointer to byte code               */
-       s4         size;                    /* size of the byte code              */
-       u1        *pos;                     /* current read position              */
+       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)       */
 };
 
@@ -133,9 +131,9 @@ struct hashtable_classloader_entry {
 *******************************************************************************/
 
 #if defined(ENABLE_HANDLES)
-typedef hashtable_classloader_entry classloader;
+typedef hashtable_classloader_entry classloader_t;
 #else
-typedef java_object_t classloader;
+typedef java_object_t               classloader_t;
 #endif
 
 
@@ -145,8 +143,8 @@ void loader_preinit(void);
 void loader_init(void);
 
 /* classloader management functions */
-classloader *loader_hashtable_classloader_add(java_handle_t *cl);
-classloader *loader_hashtable_classloader_find(java_handle_t *cl);
+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);
 
@@ -161,12 +159,12 @@ void loader_close(void);
 
 /* class loading functions */
 classinfo *load_class_from_sysloader(utf *name);
-classinfo *load_class_from_classloader(utf *name, classloader *cl);
+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 *loader);
+classinfo *load_newly_created_array(classinfo *c, classloader_t *loader);
 
 #endif /* _LOADER_H */
 
index 19c0592cfed2fce2013b34c2da5655439e8cef5f..393ad44728396b57ca6a1053e69340eb08874ed8 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/method.c - method 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.
 
@@ -44,7 +42,9 @@
 #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/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_inline_debug_log) { code } } while (0)
+#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
@@ -112,7 +143,7 @@ bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        LOCK_INIT_OBJECT_LOCK(&(m->header));
 
@@ -123,7 +154,7 @@ bool method_load(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
 
        /* all fields of m have been zeroed in load_class_from_classbuffer */
 
-       m->class = c;
+       m->clazz = c;
        
        if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
                return false;
@@ -595,9 +626,9 @@ methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
        /* Get the method from the virtual function table.  Is this an
           interface method? */
 
-       if (m->class->flags & ACC_INTERFACE) {
-               pmptr = vftbl->interfacetable[-(m->class->index)];
-               mptr  = pmptr[(m - m->class->methods)];
+       if (m->clazz->flags & ACC_INTERFACE) {
+               pmptr = vftbl->interfacetable[-(m->clazz->index)];
+               mptr  = pmptr[(m - m->clazz->methods)];
        }
        else {
                mptr = vftbl->table[m->vftblindex];
@@ -831,7 +862,7 @@ java_handle_bytearray_t *method_get_annotations(methodinfo *m)
        java_handle_t *method_annotations; /* all methods' unparsed annotations */
                                           /* of the declaring class            */
 
-       c           = m->class;
+       c           = m->clazz;
        slot        = m - c->methods;
        annotations = NULL;
 
@@ -879,7 +910,7 @@ java_handle_bytearray_t *method_get_parameterannotations(methodinfo *m)
                                                    /* parameter annotations of */
                                                    /* the declaring class      */
 
-       c                    = m->class;
+       c                    = m->clazz;
        slot                 = m - c->methods;
        parameterAnnotations = NULL;
 
@@ -928,7 +959,7 @@ java_handle_bytearray_t *method_get_annotationdefault(methodinfo *m)
                                                  /* annotation default values of */
                                                  /* the declaring class          */
 
-       c                 = m->class;
+       c                 = m->clazz;
        slot              = m - c->methods;
        annotationDefault = NULL;
 
@@ -1085,8 +1116,8 @@ void method_print(methodinfo *m)
                return;
        }
 
-       if (m->class != NULL)
-               utf_display_printable_ascii_classname(m->class->name);
+       if (m->clazz != NULL)
+               utf_display_printable_ascii_classname(m->clazz->name);
        else
                printf("NULL");
        printf(".");
index e954d99ca0623e7471cffe218b1121b201df6fcf..34b529ba2d3b34d294f6a9f24ff6650e81903968 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/method.h - method functions 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.
 
@@ -75,7 +73,7 @@ struct methodinfo {                 /* method structure                       */
 
        methoddesc   *parseddesc;       /* parsed descriptor                      */
                             
-       classinfo    *class;            /* class, the method belongs to           */
+       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          */
@@ -156,8 +154,23 @@ struct lineinfo {
 };
 
 
+/* 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);
index e3addda71440b93b140d45a02e68afe852911053..e9ae46fbcd763f25f93db60501fea452229bb28d 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/options.c - contains global options
 
-   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"
 
-#include <errno.h>
+#include <limits.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 
-#if defined(HAVE_STRING_H)
-# include <string.h>
-#endif
-
-#include <limits.h>
-
 #include "mm/memory.h"
 
 #include "native/jni.h"
@@ -45,6 +37,7 @@
 #include "vm/vm.h"
 
 #include "vmcore/options.h"
+#include "vmcore/system.h"
 
 
 /* command line option ********************************************************/
@@ -121,22 +114,6 @@ bool opt_prof_bb = false;
 #endif
 
 
-/* inlining options ***********************************************************/
-
-#if defined(ENABLE_INLINING)
-bool opt_inlining = false;
-#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-s4 opt_inline_debug_min_size = 0;
-s4 opt_inline_debug_max_size = INT_MAX;
-s4 opt_inline_debug_end_counter = INT_MAX;
-bool opt_inline_debug_all = false;
-#endif /* defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG) */
-#if !defined(NDEBUG)
-bool opt_inline_debug_log = false;
-#endif /* !defined(NDEBUG) */
-#endif /* defined(ENABLE_INLINING) */
-
-
 /* optimization options *******************************************************/
 
 #if defined(ENABLE_IFCONV)
@@ -146,6 +123,10 @@ bool opt_ifconv = false;
 #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 ********************************************************/
@@ -171,42 +152,65 @@ const char *opt_filter_show_method = 0;
 
 /* NOTE: For better readability keep these alpha-sorted. */
 
-int      opt_DebugExceptions           = 0;
-int      opt_DebugFinalizer            = 0;
-int      opt_DebugLocalReferences      = 0;
-int      opt_DebugLocks                = 0;
-int      opt_DebugPackage              = 0;
-int      opt_DebugPatcher              = 0;
-int      opt_DebugProperties           = 0;
-int32_t  opt_DebugStackFrameInfo       = 0;
-int      opt_DebugStackTrace           = 0;
-int      opt_DebugThreads              = 0;
+/* 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;
+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;
+int      opt_DisassembleStubs             = 0;
 #endif
 #if defined(ENABLE_GC_CACAO)
-int32_t  opt_GCDebugRootSet            = 0;
-int32_t  opt_GCStress                  = 0;
-#endif
-int32_t  opt_MaxPermSize               = 0;
-int32_t  opt_PermSize                  = 0;
-int      opt_PrintConfig               = 0;
-int32_t  opt_ProfileGCMemoryUsage      = 0;
-int32_t  opt_ProfileMemoryUsage        = 0;
-FILE    *opt_ProfileMemoryUsageGNUPlot = NULL;
+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
-int32_t  opt_ThreadStackSize           = 0;
-int      opt_TraceCompilerCalls        = 0;
-int32_t  opt_TraceExceptions           = 0;
-int32_t  opt_TraceJavaCalls            = 0;
-int32_t  opt_TraceJNICalls             = 0;
-int32_t  opt_TraceJVMCalls             = 0;
-int32_t  opt_TraceLinkClass            = 0;
+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)
-int32_t  opt_TraceReplacement          = 0;
+int      opt_TraceReplacement             = 0;
 #endif
+int      opt_TraceSubsystemInitialization = 0;
+int      opt_TraceTraps                   = 0;
 
 
 enum {
@@ -215,6 +219,16 @@ enum {
 };
 
 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_DebugLocalReferences,
@@ -228,65 +242,105 @@ enum {
        OPT_DisassembleStubs,
        OPT_GCDebugRootSet,
        OPT_GCStress,
-       OPT_MaxPermSize,
-       OPT_PermSize,
+       OPT_Inline,
+       OPT_InlineAll,
+       OPT_InlineCount,
+       OPT_InlineMaxSize,
+       OPT_InlineMinSize,
        OPT_PrintConfig,
        OPT_ProfileGCMemoryUsage,
        OPT_ProfileMemoryUsage,
        OPT_ProfileMemoryUsageGNUPlot,
        OPT_TestReplacement,
-       OPT_ThreadStackSize,
        OPT_TraceCompilerCalls,
        OPT_TraceExceptions,
+       OPT_TraceHPI,
+       OPT_TraceInlining,
        OPT_TraceJavaCalls,
        OPT_TraceJNICalls,
        OPT_TraceJVMCalls,
+       OPT_TraceJVMCallsVerbose,
        OPT_TraceLinkClass,
-       OPT_TraceReplacement
+       OPT_TraceReplacement,
+       OPT_TraceSubsystemInitialization,
+       OPT_TraceTraps,
+       OPT_Vmlog,
+       OPT_VmlogStrings,
+       OPT_VmlogIgnore
 };
 
 
 option_t options_XX[] = {
-       { "DebugExceptions",           OPT_DebugExceptions,           OPT_TYPE_BOOLEAN, "debug exceptions" },
-       { "DebugFinalizer",            OPT_DebugFinalizer,            OPT_TYPE_BOOLEAN, "debug finalizer thread" },
-       { "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" },
+       /* 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" },
+       { "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" },
+       { "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
-       { "MaxPermSize",               OPT_MaxPermSize,               OPT_TYPE_VALUE,   "not implemented" },
-       { "PermSize",                  OPT_PermSize,                  OPT_TYPE_VALUE,   "not implemented" },
-       { "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" },
+       { "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
-       { "ThreadStackSize",           OPT_ThreadStackSize,           OPT_TYPE_VALUE,   "TODO" },
-       { "TraceCompilerCalls",        OPT_TraceCompilerCalls,        OPT_TYPE_BOOLEAN, "trace JIT compiler calls" },
-       { "TraceExceptions",           OPT_TraceExceptions,           OPT_TYPE_BOOLEAN, "trace Exception throwing" },
-       { "TraceJavaCalls",            OPT_TraceJavaCalls,            OPT_TYPE_BOOLEAN, "trace Java method calls" },
-       { "TraceJNICalls",             OPT_TraceJNICalls,             OPT_TYPE_BOOLEAN, "trace JNI method calls" },
-       { "TraceJVMCalls",             OPT_TraceJVMCalls,             OPT_TYPE_BOOLEAN, "TODO" },
-       { "TraceLinkClass",            OPT_TraceLinkClass,            OPT_TYPE_BOOLEAN, "trace class linking" },
+       { "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)" },
+       { "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 }
+       { NULL,                           -1,                               -1,               NULL }
 };
 
 
@@ -296,10 +350,10 @@ option_t options_XX[] = {
 
 *******************************************************************************/
 
-s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
+int options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
 {
        char *option;
-       s4    i;
+       int   i;
 
        if (opt_index >= vm_args->nOptions)
                return OPT_DONE;
@@ -329,13 +383,7 @@ s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
                                opt_index++;
 
                                if (opt_index < vm_args->nOptions) {
-
-#if defined(HAVE_STRDUP)
-                                       opt_arg = strdup(vm_args->options[opt_index].optionString);
-#else
-# error !HAVE_STRDUP
-#endif
-
+                                       opt_arg = system_strdup(vm_args->options[opt_index].optionString);
                                        opt_index++;
                                        return opts[i].value;
                                }
@@ -349,18 +397,12 @@ s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
                                 * parameter with no argument starting with same letter as param with argument
                                 * but named after that one, ouch! */
 
-                               size_t l = strlen(opts[i].name);
+                               size_t l = system_strlen(opts[i].name);
 
-                               if (strlen(option + 1) > l) {
+                               if (system_strlen(option + 1) > l) {
                                        if (memcmp(option + 1, opts[i].name, l) == 0) {
                                                opt_index++;
-
-#if defined(HAVE_STRDUP)
-                                               opt_arg = strdup(option + 1 + l);
-#else
-# error !HAVE_STRDUP
-#endif
-
+                                               opt_arg = system_strdup(option + 1 + l);
                                                return opts[i].value;
                                        }
                                }
@@ -385,18 +427,27 @@ static void options_xxusage(void)
        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 = strlen("    -XX:+") + strlen(opt->name);
+                       length = system_strlen("    -XX:+") + system_strlen(opt->name);
                        break;
+
                case OPT_TYPE_VALUE:
                        printf("%s=<value>", opt->name);
-                       length = strlen("    -XX:") + strlen(opt->name) + strlen("=<value>");
+                       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.
@@ -415,7 +466,7 @@ static void options_xxusage(void)
 
                /* Check documentation length. */
 
-               length = strlen(opt->doc);
+               length = system_strlen(opt->doc);
 
                if (length < (80 - 29)) {
                        printf("%s", opt->doc);
@@ -502,7 +553,7 @@ void options_xx(JavaVMInitArgs *vm_args)
                end = strchr(start, '=');
 
                if (end == NULL) {
-                       length = strlen(start);
+                       length = system_strlen(start);
                        value  = NULL;
                }
                else {
@@ -537,6 +588,28 @@ void options_xx(JavaVMInitArgs *vm_args)
                /* 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;
@@ -593,14 +666,32 @@ void options_xx(JavaVMInitArgs *vm_args)
                        break;
 #endif
 
-               case OPT_MaxPermSize:
-                       /* currently ignored */
+#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_PermSize:
-                       /* currently ignored */
+               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;
@@ -609,14 +700,14 @@ void options_xx(JavaVMInitArgs *vm_args)
                        if (value == NULL)
                                opt_ProfileGCMemoryUsage = 5;
                        else
-                               opt_ProfileGCMemoryUsage = atoi(value);
+                               opt_ProfileGCMemoryUsage = system_atoi(value);
                        break;
 
                case OPT_ProfileMemoryUsage:
                        if (value == NULL)
                                opt_ProfileMemoryUsage = 5;
                        else
-                               opt_ProfileMemoryUsage = atoi(value);
+                               opt_ProfileMemoryUsage = system_atoi(value);
 
 # if defined(ENABLE_STATISTICS)
                        /* we also need statistics */
@@ -634,7 +725,7 @@ void options_xx(JavaVMInitArgs *vm_args)
                        file = fopen(filename, "w");
 
                        if (file == NULL)
-                               vm_abort("options_xx: fopen failed: %s", strerror(errno));
+                               vm_abort_errno("options_xx: fopen failed");
 
                        opt_ProfileMemoryUsageGNUPlot = file;
                        break;
@@ -645,10 +736,6 @@ void options_xx(JavaVMInitArgs *vm_args)
                        break;
 #endif
 
-               case OPT_ThreadStackSize:
-                       /* currently ignored */
-                       break;
-
                case OPT_TraceCompilerCalls:
                        opt_TraceCompilerCalls = enable;
                        break;
@@ -657,6 +744,19 @@ void options_xx(JavaVMInitArgs *vm_args)
                        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;
@@ -670,6 +770,10 @@ void options_xx(JavaVMInitArgs *vm_args)
                        opt_TraceJVMCalls = enable;
                        break;
 
+               case OPT_TraceJVMCallsVerbose:
+                       opt_TraceJVMCallsVerbose = enable;
+                       break;
+
                case OPT_TraceLinkClass:
                        opt_TraceLinkClass = enable;
                        break;
@@ -679,7 +783,36 @@ void options_xx(JavaVMInitArgs *vm_args)
                        if (value == NULL)
                                opt_TraceReplacement = 1;
                        else
-                               opt_TraceReplacement = atoi(value);
+                               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
 
index 54ee97de5483bbf213492d32696e408d83ede790..ca4e09666c6ab77c0eab2078ee93a508260f1a72 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/options.h - define global options extern
 
-   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.
 
@@ -135,22 +133,6 @@ extern bool opt_prof;
 extern bool opt_prof_bb;
 #endif
 
-/* inlining options ***********************************************************/
-
-#if defined(ENABLE_INLINING)
-extern bool opt_inlining;
-#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-extern s4 opt_inline_debug_min_size;
-extern s4 opt_inline_debug_max_size;
-extern s4 opt_inline_debug_end_counter;
-extern bool opt_inline_debug_all;
-#endif /* defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG) */
-#if !defined(NDEBUG)
-extern bool opt_inline_debug_log;
-#endif /* !defined(NDEBUG) */
-#endif /* defined(ENABLE_INLINING) */
-
-
 /* optimization options *******************************************************/
 
 #if defined(ENABLE_IFCONV)
@@ -160,7 +142,10 @@ extern bool opt_ifconv;
 #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 ********************************************************/
 
@@ -186,6 +171,16 @@ extern const char *opt_filter_show_method;
 
 /* 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;
 extern int      opt_DebugLocalReferences;
@@ -193,42 +188,69 @@ extern int      opt_DebugLocks;
 extern int      opt_DebugPatcher;
 extern int      opt_DebugPackage;
 extern int      opt_DebugProperties;
-extern int32_t  opt_DebugStackFrameInfo;
+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 int32_t  opt_GCDebugRootSet;
-extern int32_t  opt_GCStress;
+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 int32_t  opt_MaxPermSize;
-extern int32_t  opt_PermSize;
 extern int      opt_PrintConfig;
-extern int32_t  opt_ProfileGCMemoryUsage;
-extern int32_t  opt_ProfileMemoryUsage;
+extern int      opt_ProfileGCMemoryUsage;
+extern int      opt_ProfileMemoryUsage;
 extern FILE    *opt_ProfileMemoryUsageGNUPlot;
 #if defined(ENABLE_REPLACEMENT)
 extern int      opt_TestReplacement;
 #endif
-extern int32_t  opt_ThreadStackSize;
 extern int      opt_TraceCompilerCalls;
-extern int32_t  opt_TraceExceptions;
-extern int32_t  opt_TraceJavaCalls;
-extern int32_t  opt_TraceJNICalls;
-extern int32_t  opt_TraceJVMCalls;
-extern int32_t  opt_TraceLinkClass;
+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 int32_t  opt_TraceReplacement;
+extern int      opt_TraceReplacement;
 #endif
+extern int      opt_TraceSubsystemInitialization;
+extern int      opt_TraceTraps;
 
 
 /* function prototypes ********************************************************/
 
-s4   options_get(opt_struct *opts, JavaVMInitArgs *vm_args);
+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 */
 
 
index 1434b5d8ef4fa907dad53c51163a14196d561186..d55da764fd0195ed21235a2fb98759318fc8d792 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/primitivecore.c - core functions for 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
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -35,6 +33,7 @@
 #include "vm/vm.h"
 
 #include "vmcore/class.h"
+#include "vmcore/options.h"
 #include "vmcore/utf8.h"
 
 
@@ -96,6 +95,8 @@ void primitive_init(void)
        classinfo *ac;
        int        i;
 
+       TRACESUBSYSTEMINITIALIZATION("primitive_init");
+
        /* Load and link primitive-type classes and array-classes. */
 
        for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
@@ -210,6 +211,8 @@ void primitive_postinit(void)
        classinfo *c;
        int        i;
 
+       TRACESUBSYSTEMINITIALIZATION("primitive_postinit");
+
        assert(class_java_lang_Class);
        assert(class_java_lang_Class->vftbl);
 
index 6d2eec40590fb2213742b3abb910445bf6dc2b00..6ac233618293bbebde516c81cc4574a9df1fe234 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/references.h - references to classes/fields/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.
 
@@ -51,13 +49,13 @@ typedef union classref_or_classinfo {
 } classref_or_classinfo;
 
 
-/* parseddesc *****************************************************************/
+/* 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;
+} parseddesc_t;
 
 
 #include "config.h"
@@ -93,16 +91,16 @@ typedef union parseddesc {
 
 /* constant_FMIref ************************************************************/
 
-struct constant_FMIref{     /* Fieldref, Methodref and InterfaceMethodref     */
+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 parseddesc;  /* parsed descriptor                              */
+       utf         *name;       /* field/method/interfacemethod name             */
+       utf         *descriptor; /* field/method/intfmeth. type descriptor string */
+       parseddesc_t parseddesc; /* parsed descriptor                             */
 };
 
 
@@ -135,12 +133,12 @@ struct constant_FMIref{     /* Fieldref, Methodref and InterfaceMethodref     */
 
 /* macro for accessing the class name of a method reference                   */
 #define METHODREF_CLASSNAME(fmiref) \
-       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.method->class->name \
+       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.method->clazz->name \
                                                                : (fmiref)->p.classref->name)
 
 /* macro for accessing the class name of a method reference                   */
 #define FIELDREF_CLASSNAME(fmiref) \
-       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.field->class->name \
+       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.field->clazz->name \
                                                                : (fmiref)->p.classref->name)
 
 /* initialize a constant_classref with referer `ref` and name `classname`     */
index e5b93389a4d93b9ba5eb62d1bf85d5fa47696a75..40ee97e40a91467257d2dbaa2ad95f5b34fae662 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/stackmap.c - 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
+   Copyright (C) 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -411,7 +409,7 @@ bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* allocate stack map structure */
 
index 1f3638a550d6ca3c8a0ed7c30f77fb2666e396e7..933ceab0074736a8990945aaebec65e7aaf63436 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/suck.c - 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -28,8 +26,6 @@
 #include "config.h"
 
 #include <assert.h>
-#include <dirent.h>
-#include <sys/stat.h>
 #include <stdlib.h>
 
 #include "vm/types.h"
@@ -51,6 +47,7 @@
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
 #include "vmcore/suck.h"
+#include "vmcore/system.h"
 #include "vmcore/zip.h"
 
 
@@ -68,6 +65,8 @@ list_t *list_classpath_entries;
 
 bool suck_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("suck_init");
+
        list_classpath_entries = list_create(OFFSET(list_classpath_entry, linkage));
 
        /* everything's ok */
@@ -280,7 +279,7 @@ void suck_add_from_property(char *key)
 
                        /* scan the directory found for zip/jar files */
 
-                       n = scandir(path, &namelist, scandir_filter, alphasort);
+                       n = system_scandir(path, &namelist, scandir_filter, alphasort);
 
                        /* On error, just continue, this should be ok. */
 
@@ -354,7 +353,7 @@ 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)->class, "Truncated class file");
+               exceptions_throw_classformaterror(cb->clazz, "Truncated class file");
                return false;
        }
 #endif /* ENABLE_VERIFIER */
@@ -556,12 +555,12 @@ classbuffer *suck_start(classinfo *c)
                        strcpy(path, lce->path);
                        strcat(path, filename);
 
-                       classfile = fopen(path, "r");
+                       classfile = system_fopen(path, "r");
 
                        if (classfile) {                                   /* file exists */
-                               if (!stat(path, &buffer)) {            /* read classfile data */
+                               if (!system_stat(path, &buffer)) {     /* read classfile data */
                                        cb = NEW(classbuffer);
-                                       cb->class = c;
+                                       cb->clazz = c;
                                        cb->size  = buffer.st_size;
                                        cb->data  = MNEW(u1, cb->size);
                                        cb->pos   = cb->data;
@@ -569,7 +568,8 @@ classbuffer *suck_start(classinfo *c)
 
                                        /* read class data */
 
-                                       len = fread(cb->data, 1, cb->size, classfile);
+                                       len = system_fread((void *) cb->data, 1, cb->size,
+                                                                          classfile);
 
                                        if (len != buffer.st_size) {
                                                suck_stop(cb);
@@ -579,7 +579,7 @@ classbuffer *suck_start(classinfo *c)
 
                                        /* close the class file */
 
-                                       fclose(classfile);
+                                       system_fclose(classfile);
                                }
                        }
 
index 8ead090863db63aa163626100140eedc569c392f..be474a9ef92a2c2632a9dcb77f965afa95b5c1a8 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vmcore/system.c - system (OS) functions
 
    Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
index 2579e6675f237239210fa8b311be080023985537..2f416d162ea27f2edad0d06a3eca7e5a8e671290 100644 (file)
@@ -1,7 +1,7 @@
 /* src/vmcore/system.h - system (OS) functions
 
-   Copyright (C) 2007
-   CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 /* 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_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
 # 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)
@@ -59,6 +129,62 @@ inline static void *system_calloc(size_t nmemb, size_t size)
 #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 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 void system_free(void *ptr)
 {
 #if defined(HAVE_FREE)
@@ -68,6 +194,33 @@ inline static void system_free(void *ptr)
 #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)
@@ -77,6 +230,42 @@ inline static int system_getpagesize(void)
 #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)
@@ -104,6 +293,33 @@ inline static void *system_memset(void *s, int c, size_t n)
 #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)
@@ -113,6 +329,109 @@ inline static void *system_realloc(void *ptr, size_t size)
 #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 *))
+#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 ********************************************************/
 
index 7b8c242a1051d3a13618cfee1c3993f889874db9..9cb1f1109dbb7d292c32b3f63efb6d1cdf7e2abd 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/utf8.c - utf8 string 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.
 
@@ -108,6 +106,7 @@ 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;
@@ -132,6 +131,13 @@ 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_CLASSPATH_GNU)
+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
 
@@ -160,6 +166,8 @@ 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;
@@ -210,6 +218,7 @@ 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;
 
@@ -224,8 +233,10 @@ utf *array_packagename;
 
 *******************************************************************************/
 
-bool utf8_init(void)
+void utf8_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("utf8_init");
+
        /* create utf8 hashtable */
 
        hashtable_utf = NEW(hashtable);
@@ -347,6 +358,9 @@ bool utf8_init(void)
        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");
 
@@ -378,6 +392,13 @@ bool utf8_init(void)
 
        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_CLASSPATH_GNU)
+       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
 
@@ -393,19 +414,21 @@ bool utf8_init(void)
        utf_Signature                  = utf_new_char("Signature");
        utf_StackMapTable              = utf_new_char("StackMapTable");
 
-#if defined(ENABLE_ANNOTATIONS)
+# 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
 #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");
@@ -469,6 +492,9 @@ bool utf8_init(void)
        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 =
@@ -477,10 +503,6 @@ bool utf8_init(void)
        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>");
-
-       /* everything's ok */
-
-       return true;
 }
 
 
index 86cb1c349000873155edccca7b35d352ba354ae7..c2fd69bee10495c123bd6d484fc6c43ee43835f4 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/utf8.h - utf8 string 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.
 
@@ -104,6 +102,7 @@ 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;
@@ -128,6 +127,13 @@ 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_CLASSPATH_GNU)
+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
 
@@ -156,6 +162,8 @@ 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;
@@ -206,6 +214,7 @@ 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;
 
@@ -217,7 +226,7 @@ extern utf *array_packagename;
 /* function prototypes ********************************************************/
 
 /* initialize the utf8 subsystem */
-bool utf8_init(void);
+void utf8_init(void);
 
 u4 utf_hashkey(const char *text, u4 length);
 u4 utf_full_hashkey(const char *text, u4 length);
index d0a9f397c7536770ab79c46606cb20a0e4ccc6ac..c3644e22cc543e3ba6aa5e5ef0f05606437efc9a 100644 (file)
@@ -1,9 +1,7 @@
 /* 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -435,7 +433,7 @@ classbuffer *zip_get(list_classpath_entry *lce, classinfo *c)
 
        cb = NEW(classbuffer);
 
-       cb->class = c;
+       cb->clazz = c;
        cb->size  = htzfe->uncompressedsize;
        cb->data  = outdata;
        cb->pos   = outdata;
diff --git a/tests/A2.java b/tests/A2.java
deleted file mode 100644 (file)
index c79e2d3..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-public class A2 {
-static A a2 = new A();
-static int myZero;
-
-}
-
-
diff --git a/tests/AA.java b/tests/AA.java
deleted file mode 100644 (file)
index 0f2ecbc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-public class AA
-{
-static int xx;
-
-public void f9() {
-  int x = 1;
-}
-public static void main(String[] s) {
-AA2 a;
-DD d = new DD();
-EE e = new EE();
-int x = 1;
-
-for (int i=1;i<5;i++) {
-xx = 5;
-if (x==1)
-  a=d;
-else
-  a=e;
-a.f();
-
-
-}
-}
-}
diff --git a/tests/AA1.java b/tests/AA1.java
deleted file mode 100644 (file)
index d51b96a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-public class AA1 extends AA
-{
-public void f() {
-  int x = 3;
-}
-}
diff --git a/tests/AA2.java b/tests/AA2.java
deleted file mode 100644 (file)
index 3649622..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-public class AA2 extends AA1
-{
-public void f3() {
-  int x = 3;
-}
-}
diff --git a/tests/BB.java b/tests/BB.java
deleted file mode 100644 (file)
index d58e253..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-public class BB extends AA 
-{
-public void f() {
-  int x = 2;
-  GG g = new GG();
-}
-}
diff --git a/tests/C.java b/tests/C.java
deleted file mode 100644 (file)
index fd982e7..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-class C extends A {
-static int cx = 1;
-
-void m1( ) {ax = 100; cx=1;
-}
-
-public static void main(String[] s) {
-  A a;
-  B b = new B();
-  a=b;
-  b.m1();
-  b.m2();
-  cx++;
-//  System.out.println("Hello World"));
-//  System.out.println("C: "+ ax +"; B: "+b.ax +"; A: "+a.ax);
- } 
-}
-
diff --git a/tests/C2.java b/tests/C2.java
deleted file mode 100644 (file)
index abe17b7..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-class C2 extends A {
-int cx;
-void m1( ) {ax = 100; cx=1;
-//D d = new D();
-}
-public static void main(String[] s) {
-  A a;
-  B b;
-  int i=1;
-if (i==1)
-  a = new A();
-else
-  a = new D();
-
-  a.m1();
-  a.m2();
- } 
-}
-
diff --git a/tests/C3.java b/tests/C3.java
deleted file mode 100644 (file)
index 0ba2d9d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-class C3 extends A {
-int cx;
-void m1( ) {ax = 100; cx=1;
-}
-public static void main(String[] s) {
-  A a = A2.a2;
-  B b = new B();
-  int x = A2.myZero;
-  a=b;
-  b.m1();
-  b.m2();
-
-//  System.out.println("Hello World"));
-//  System.out.println("C: "+ ax +"; B: "+b.ax +"; A: "+a.ax);
- } 
-}
-
-
diff --git a/tests/CC.java b/tests/CC.java
deleted file mode 100644 (file)
index 1896ab3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-public class CC extends AA2
-{
-public void f() {
-  int x = 3;
-}
-}
diff --git a/tests/D.java b/tests/D.java
deleted file mode 100644 (file)
index 0447487..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-class D extends A {
-int ax = 133;
-
-void m1( ) {ax = ax + 10; 
-  // System.out.println("In D.m1: "+ax);
-  }
-
-B m3( ) {
-B b = new B();
-b.bx++;
-return b;
-}
-}
diff --git a/tests/DD.java b/tests/DD.java
deleted file mode 100644 (file)
index 1d1f109..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-public class DD extends CC 
-{
-public void f2() {
-  int x = 4;
-}
-}
diff --git a/tests/EE.java b/tests/EE.java
deleted file mode 100644 (file)
index 3c2b06c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-public class EE extends CC
-{
-public void f2() {
-  int x = 6;
-}
-}
diff --git a/tests/GG.java b/tests/GG.java
deleted file mode 100644 (file)
index 30c2a9c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-public class GG extends BB
-{
-public void f() {
-  int x = 5;
-}
-}
diff --git a/tests/HI2.java b/tests/HI2.java
deleted file mode 100644 (file)
index 57bb837..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-public class HI2 {
-   public   static int max1(int i, int j) {
-   
-   if (i > j)
-     return i;
-   else
-     return j;
-   }
-
-   public static void main(String[] args) {
-      int i;
-      int j;
-      int k;
-      for (i=0; i<10; i++) {
-       j = (i*2)-5;
-       k = max1(i, j);
-       }
-   }
-}
diff --git a/tests/II.java b/tests/II.java
deleted file mode 100644 (file)
index 211775d..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-interface II{
-public void foo();
-public void foo2();
-}
diff --git a/tests/IIAA.java b/tests/IIAA.java
deleted file mode 100644 (file)
index 4fb53da..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-class IIAA implements II {
-int xx;
-int yy;
-int zz;
-
-public void foo( ) {
-  int j = xx;
-}
-
-public void foo2( ) {
-  int j = zz;
-}
-
-public void bar ( ) {
-yy=0;
-zz=1;
-}
-}
diff --git a/tests/IIBB.java b/tests/IIBB.java
deleted file mode 100644 (file)
index 593b25f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-class IIBB extends IIAA  {
-public void foo() {
-  yy=0;
-  zz=0;
-  int j= zz;
-}
-
-public void bar ( ) {
-  yy=1;
-}
-}
diff --git a/tests/IICC.java b/tests/IICC.java
deleted file mode 100644 (file)
index 3c2ffc1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-class IICC extends IIAA {
-public void foo( ) {
-  this.bar(); 
-}
-}
diff --git a/tests/IIexample.java b/tests/IIexample.java
deleted file mode 100644 (file)
index bad5aa4..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-class IIexample {
-public static void main (String[] args) {
-ff();
-gg();
-}
-
-static void ff() {
-II i1 = new IIBB();
-i1.foo();
-}
-
-static void gg() {
-//II i2 = new IICC();
-II i2 = new IIBB();  // so unique
-i2.foo();
-}
-
-}
index f5ff483c20ceeb27ec2e454ee3ff0b9d0f377ebc..277918f423c702ee7df7f02d74eef0a42e7e1a33 100644 (file)
@@ -1,9 +1,7 @@
 ## tests/Makefile.am
 ##
-## 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.
 ##
 ## 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
-##
-## Changes:
 
-## Process this file with automake to produce Makefile.in
 
-SUBDIRS = regression
+JAVA     = LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(top_builddir)/src/cacao/cacao
+JAVACMD  = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
 
-EXTRA_DIST = \
-       hello.java \
-       prop.java \
-       x.java \
-       x.output \
-       TestBase.java \
-       TestArrayClasses.java \
-       TestArrayClasses.output \
-       BasicToStrings.java \
-       BasicToStrings.output \
-       GCBench.java \
-       JavaPerformance.java \
-       param_test.java \
-       exception_restore_registers.java
-
-JAVA = $(top_builddir)/src/cacao/cacao
+SUBDIRS = \
+       regression
 
-checkall: x.tst TestArrayClasses.tst BasicToStrings.tst param_test.tst exception_restore_registers.tst
+EXTRA_DIST = \
+       $(srcdir)/*.java
 
-%.tst:
-       $(JAVAC) $*.java
-       sh Test.sh $(JAVA) $*
-#      $(JAVA) $* > $*.thisoutput
-#      diff --brief $*.output $*.thisoutput
-       $(RM) $*.thisoutput
-       $(RM) $*.this2output
+CLEANFILES = \
+       *.class
 
-%.tstrun:
-       $(JAVAC) $*.java
-       $(JAVA) $*
+build:
+       $(JAVACCMD) -d . $(srcdir)/*.java
 
 
 ## Local variables:
diff --git a/tests/n.java b/tests/n.java
deleted file mode 100644 (file)
index e2ea205..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-public class n implements a {
-       public void do_a () { };
-       public void do_a2 () { };
-       public void do_b () { };
-       }
-       
\ No newline at end of file
diff --git a/tests/regression/HelloWorld.java b/tests/regression/HelloWorld.java
deleted file mode 100644 (file)
index ab1fd58..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-public class HelloWorld {
-    public static void main(String[] argv) {
-        System.out.println("OK");
-    }
-}
index 0056d2b1704efc387485e271364a41e9b0a345b4..1481cac0bbb04c5f1a577c87fb544c79a10d9cd2 100644 (file)
@@ -1,9 +1,7 @@
 ## tests/regression/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.
 ##
 
 
 SUBDIRS = \
-       codepatching \
+       assertion \
+       bugzilla \
        jasmin \
+       junit \
        native \
        resolving
 
-JAVA      = $(top_builddir)/src/cacao/cacao
-
-if WITH_CLASSPATH_GNU
-JAVAFLAGS = -Xbootclasspath:$(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
-else
-JAVAFLAGS = -Xbootclasspath:$(CLASSPATH_CLASSES)
-endif
+JAVA     = $(top_builddir)/src/cacao/cacao
+JAVACMD  = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -source 1.5 -target 1.5 -nowarn -bootclasspath $(BOOTCLASSPATH)
 
 SOURCE_FILES = \
-       $(srcdir)/HelloWorld.java \
        $(srcdir)/jctest.java \
        $(srcdir)/fptest.java \
        $(srcdir)/fp.java \
        $(srcdir)/extest.java \
-       $(srcdir)/clinitexception.java \
        $(srcdir)/LoadDisplacementOverflow.java \
        $(srcdir)/FieldDisplacementOverflow.java \
        $(srcdir)/StackDisplacementOverflow.java \
@@ -58,7 +52,6 @@ EXTRA_DIST = \
        fptest.output \
        fp.output\
        extest.2output \
-       clinitexception.2output \
        LoadDisplacementOverflow.output \
        FieldDisplacementOverflow.output \
        StackDisplacementOverflow.output \
@@ -69,34 +62,27 @@ CLEANFILES = \
        *.class \
        *.thisoutput
 
-SIMPLE_JAVA_TESTS = \
-       HelloWorld
-
 OUTPUT_JAVA_TESTS = \
        jctest \
        fptest \
        fp \
        extest \
        \
-       clinitexception \
        LoadDisplacementOverflow \
        FieldDisplacementOverflow \
        StackDisplacementOverflow \
        MinimalClassReflection \
        TestAnnotations
 
-check: build $(SIMPLE_JAVA_TESTS) $(OUTPUT_JAVA_TESTS)
+check: build run
 
 build:
-       @$(JAVAC) -d . $(SOURCE_FILES)
-
-$(SIMPLE_JAVA_TESTS):
-       @echo "$@: "
-       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(JAVA) $(JAVAFLAGS) $@
+       $(JAVACCMD) -d . $(SOURCE_FILES)
 
+run: $(OUTPUT_JAVA_TESTS)
 
 $(OUTPUT_JAVA_TESTS):
-       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVA) $(JAVAFLAGS)" $@ $(srcdir)
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD)" $@ $(srcdir)
 
 
 ## Local variables:
index 6b4734a9beff4f62657020ba24fdf5b5f3d4678e..b5fe76035d1e7d93d72ed7a6b3da70826d3f38b0 100644 (file)
@@ -1,10 +1,8 @@
 /* tests/regression/TestAnnotations.java - checks correct functionality of the
    annotation API
 
-   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,
-   TU Wien
+   Copyright (C) 2007, 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: Mathias Panzenböck
-
 */
 
 import java.lang.annotation.Annotation;
diff --git a/tests/regression/assertion/Makefile.am b/tests/regression/assertion/Makefile.am
new file mode 100644 (file)
index 0000000..19a3306
--- /dev/null
@@ -0,0 +1,156 @@
+## tests/regression/assertion/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.
+
+
+JAVA     = $(top_builddir)/src/cacao/cacao
+JAVACMD  = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH) -source 1.5 -target 1.5
+
+SOURCE_FILES = \
+       $(srcdir)/testassertions.java \
+       $(srcdir)/packagetest/testassertions.java
+
+EXTRA_DIST = \
+       $(SOURCE_FILES) \
+       Test.sh \
+       \
+       enabled.output \
+       disabled.output
+
+CLEANFILES = \
+       *.class \
+       *.thisoutput \
+       packagetest/*.class
+
+ASSERTION_TESTS = \
+       EA_TEST1 \
+       EA_TEST2 \
+       EA_PACKAGE_TEST1 \
+       EA_PACKAGE_TEST2 \
+       EA_PACKAGE_TEST3 \
+       EA_PACKAGE_TEST4 \
+       EA_PACKAGE_TEST5 \
+       DA_PACKAGE_TEST1 \
+       DA_PACKAGE_TEST2 \
+       DA_PACKAGE_TEST3 \
+       DA_PACKAGE_TEST4 \
+       DA_PACKAGE_TEST5 \
+       EA_CLASS_TEST1 \
+       EA_CLASS_TEST2 \
+       EA_CLASS_TEST3 \
+       EA_CLASS_TEST4 \
+       EA_CLASS_TEST5 \
+       DA_CLASS_TEST1 \
+       DA_CLASS_TEST2 \
+       DA_CLASS_TEST3 \
+       DA_CLASS_TEST4 \
+       DA_CLASS_TEST5 \
+       ESA_TEST1 \
+       ESA_TEST2
+
+check: build run
+
+build:
+       $(JAVACCMD) -d . $(SOURCE_FILES)
+
+run: $(ASSERTION_TESTS)
+
+EA_TEST1:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -ea" testassertions eatest1 enabled $(srcdir)
+
+EA_TEST2:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -enableassertions" testassertions eatest2 enabled $(srcdir)
+
+EA_PACKAGE_TEST1:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -da -ea:packagetest..." packagetest.testassertions eapackagetest1 enabled $(srcdir)
+
+EA_PACKAGE_TEST2:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -disableassertions -ea:packagetest..." packagetest.testassertions eapackagetest2 enabled $(srcdir)
+
+EA_PACKAGE_TEST3:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -disableassertions -enableassertions:packagetest..." packagetest.testassertions eapackagetest3 enabled $(srcdir)
+
+EA_PACKAGE_TEST4:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -enableassertions:packagetest... -disableassertions " packagetest.testassertions eapackagetest4 enabled $(srcdir)
+
+EA_PACKAGE_TEST5:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -da -enableassertions:packagetest..." packagetest.testassertions eapackagetest5 enabled $(srcdir)
+
+EA_CLASS_TEST1:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -da -ea:testassertions" testassertions eaclasstest1 enabled $(srcdir)
+
+EA_CLASS_TEST2:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -disableassertions -ea:testassertions" testassertions eaclasstest2 enabled $(srcdir)
+
+EA_CLASS_TEST3:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -disableassertions -enableassertions:testassertions" testassertions eaclasstest3 enabled $(srcdir)
+
+EA_CLASS_TEST4:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -enableassertions:testassertions -disableassertions " testassertions eaclasstest4 enabled $(srcdir)
+
+EA_CLASS_TEST5:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -da -enableassertions:testassertions" testassertions eaclasstest5 enabled $(srcdir)
+
+DA_PACKAGE_TEST1:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -da:packagetest... -ea" packagetest.testassertions dapackagetest1 disabled $(srcdir)
+
+DA_PACKAGE_TEST2:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -disableassertions:packagetest... -ea" packagetest.testassertions dapackagetest2 disabled $(srcdir)
+
+DA_PACKAGE_TEST3:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -disableassertions:packagetest... -enableassertions" packagetest.testassertions dapackagetest3 disabled $(srcdir)
+
+DA_PACKAGE_TEST4:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -enableassertions -disableassertions:packagetest... " packagetest.testassertions dapackagetest4 disabled $(srcdir)
+
+DA_PACKAGE_TEST5:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -da:packagetest... -enableassertions" packagetest.testassertions dapackagetest5 disabled $(srcdir)
+
+DA_CLASS_TEST1:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -ea -da:testassertions" testassertions daclasstest1 disabled $(srcdir)
+
+DA_CLASS_TEST2:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -enableassertions -da:testassertions" testassertions daclasstest2 disabled $(srcdir)
+
+DA_CLASS_TEST3:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -enableassertions -disableassertions:testassertions" testassertions daclasstest3 disabled $(srcdir)
+
+DA_CLASS_TEST4:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -disableassertions:testassertions -enableassertions " testassertions daclasstest4 disabled $(srcdir)
+
+DA_CLASS_TEST5:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -ea -disableassertions:testassertions" testassertions daclasstest5 disabled $(srcdir)
+
+ESA_TEST1:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -esa" testassertions esatest1 disabled $(srcdir)
+
+ESA_TEST2:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD) -enablesystemassertions" testassertions esatest2 disabled $(srcdir)
+
+
+## Local variables:
+## mode: Makefile
+## indent-tabs-mode: t
+## c-basic-offset: 4
+## tab-width: 8
+## compile-command: "automake --add-missing"
+## End:
diff --git a/tests/regression/assertion/Test.sh b/tests/regression/assertion/Test.sh
new file mode 100644 (file)
index 0000000..6494a8d
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+JAVA=$1
+CLASS=$2
+TESTNAME=$3
+TEST=$4
+SRCDIR=$5
+
+echo -n "$TESTNAME: "
+
+$JAVA $CLASS > $TEST.thisoutput 2>&1
+
+if [ $? -eq "0" ]; then
+    # no Error returned
+    if [ -f $SRCDIR/$TEST.2output ]; then
+        # Error should have been returned
+        echo "OK, but wrong return value: $?"
+        head $TEST.thisoutput
+        exit
+    fi
+       
+    cmp -s $SRCDIR/$TEST.output $TEST.thisoutput
+
+    if [ $? -eq "0" ]; then
+        echo "OK"
+    else
+        echo "FAILED"
+        diff -u $SRCDIR/$TEST.output $TEST.thisoutput
+    fi
+
+else
+    # Error returned
+    if [ ! -f $SRCDIR/$TEST.2output ]; then
+        # No Error should have been returned
+        echo "FAILED, but wrong return value: $?"
+        head $TEST.this2output
+        exit
+    fi
+
+    cmp -s $SRCDIR/$TEST.2output $TEST.thisoutput
+
+    if [ $? -eq "0" ]; then
+        echo "OK"
+    else
+        echo "FAILED"
+        diff -u $SRCDIR/$TEST.2output $TEST.thisoutput
+    fi
+fi             
+
+rm -f $TEST.thisoutput
diff --git a/tests/regression/assertion/disabled.output b/tests/regression/assertion/disabled.output
new file mode 100644 (file)
index 0000000..eb9ab7b
--- /dev/null
@@ -0,0 +1 @@
+Assertions disabled!
diff --git a/tests/regression/assertion/enabled.output b/tests/regression/assertion/enabled.output
new file mode 100644 (file)
index 0000000..a3c75af
--- /dev/null
@@ -0,0 +1 @@
+Assertions enabled!
diff --git a/tests/regression/assertion/packagetest/testassertions.java b/tests/regression/assertion/packagetest/testassertions.java
new file mode 100644 (file)
index 0000000..643444e
--- /dev/null
@@ -0,0 +1,36 @@
+/* tests/regression/native/testassertions.java - assertion testing\r
+\r
+   Copyright (C) 2007\r
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO\r
+\r
+   This file is part of CACAO.\r
+\r
+   This program is free software; you can redistribute it and/or\r
+   modify it under the terms of the GNU General Public License as\r
+   published by the Free Software Foundation; either version 2, or (at\r
+   your option) any later version.\r
+\r
+   This program is distributed in the hope that it will be useful, but\r
+   WITHOUT ANY WARRANTY; without even the implied warranty of\r
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+   General Public License for more details.\r
+\r
+   You should have received a copy of the GNU General Public License\r
+   along with this program; if not, write to the Free Software\r
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r
+   02110-1301, USA.\r
+\r
+*/\r
+\r
+package packagetest;\r
+\r
+public class testassertions {\r
+    public static void main(String[] args) {\r
+        try {\r
+            assert 1 == 2;\r
+            System.out.println("Assertions disabled!");\r
+        } catch (AssertionError ae) {\r
+            System.out.println("Assertions enabled!");\r
+        }\r
+    }\r
+}\r
diff --git a/tests/regression/assertion/testassertions.java b/tests/regression/assertion/testassertions.java
new file mode 100644 (file)
index 0000000..5657851
--- /dev/null
@@ -0,0 +1,34 @@
+/* tests/regression/native/testassertions.java - assertion testing\r
+\r
+   Copyright (C) 2007\r
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO\r
+\r
+   This file is part of CACAO.\r
+\r
+   This program is free software; you can redistribute it and/or\r
+   modify it under the terms of the GNU General Public License as\r
+   published by the Free Software Foundation; either version 2, or (at\r
+   your option) any later version.\r
+\r
+   This program is distributed in the hope that it will be useful, but\r
+   WITHOUT ANY WARRANTY; without even the implied warranty of\r
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+   General Public License for more details.\r
+\r
+   You should have received a copy of the GNU General Public License\r
+   along with this program; if not, write to the Free Software\r
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r
+   02110-1301, USA.\r
+\r
+*/\r
+\r
+public class testassertions {\r
+    public static void main(String[] args) {\r
+        try {\r
+            assert 1 == 2;\r
+            System.out.println("Assertions disabled!");\r
+        } catch (AssertionError ae) {\r
+            System.out.println("Assertions enabled!");\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/tests/regression/bugzilla/All.java b/tests/regression/bugzilla/All.java
new file mode 100644 (file)
index 0000000..e5fcac1
--- /dev/null
@@ -0,0 +1,54 @@
+/* tests/regression/bugzilla/All.java - runs all CACAO regression unit tests
+
+   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 junit.framework.*;
+import junit.textui.*;
+
+public class All extends TestCase {
+    /**
+     * Runs all CACAO regression unit tests using
+     * junit.textui.TestRunner
+     */
+    public static void main(String[] args) {
+        Test s = suite();
+        TestRunner.run(s);
+    }
+
+    /**
+     * Collects all CACAO regression unit tests as one suite
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite("CACAO Regression Unit Tests");
+
+        // Add your test here.
+
+        suite.addTest(new TestSuite(PR52.class));
+        suite.addTest(new TestSuite(PR57.class));
+        suite.addTest(new TestSuite(PR58.class));
+        suite.addTest(new TestSuite(PR65.class));
+
+        return suite;
+    }
+}
diff --git a/tests/regression/bugzilla/Makefile.am b/tests/regression/bugzilla/Makefile.am
new file mode 100644 (file)
index 0000000..b22e5a2
--- /dev/null
@@ -0,0 +1,49 @@
+## tests/regression/bugzilla/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.
+
+
+JAVA     = LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(top_builddir)/src/cacao/cacao
+JAVACMD  = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
+
+EXTRA_DIST = \
+       $(srcdir)/*.java
+
+CLEANFILES = \
+       *.class
+
+check: build run
+
+build:
+       $(JAVACCMD) -classpath /usr/share/java/junit4.jar -d . $(srcdir)/*.java
+
+run:
+       $(JAVACMD) -classpath /usr/share/java/junit4.jar:. org.junit.runner.JUnitCore All
+
+
+## Local variables:
+## mode: Makefile
+## indent-tabs-mode: t
+## c-basic-offset: 4
+## tab-width: 8
+## compile-command: "automake --add-missing"
+## End:
diff --git a/tests/regression/bugzilla/PR52.java b/tests/regression/bugzilla/PR52.java
new file mode 100644 (file)
index 0000000..fae85f1
--- /dev/null
@@ -0,0 +1,44 @@
+/* tests/regression/bugzilla/PR52.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 junit.framework.*;
+import junit.textui.*;
+
+import java.security.*;
+
+public class PR52 extends TestCase {
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    public static Test suite() {
+        return new TestSuite(PR52.class);
+    }
+
+    public void test() {
+        // This one only triggers with GNU Classpath.
+        AccessController.getContext();
+    }
+}
diff --git a/tests/regression/bugzilla/PR57.java b/tests/regression/bugzilla/PR57.java
new file mode 100644 (file)
index 0000000..b8a960f
--- /dev/null
@@ -0,0 +1,46 @@
+/* tests/regression/bugzilla/PR57.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 junit.framework.*;
+import junit.textui.*;
+
+public class PR57 extends TestCase {
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    public static Test suite() {
+        return new TestSuite(PR57.class);
+    }
+
+    public void test() {
+        try {
+            Class.forName("x");
+            fail("Should throw ClassNotFoundException");
+        }
+        catch (ClassNotFoundException success) {
+        }
+    }
+}
diff --git a/tests/regression/bugzilla/PR58.java b/tests/regression/bugzilla/PR58.java
new file mode 100644 (file)
index 0000000..d70281c
--- /dev/null
@@ -0,0 +1,79 @@
+/* tests/regression/bugzilla/PR58.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 junit.framework.*;
+import junit.textui.*;
+
+import java.io.*;
+
+public class PR58 extends TestCase {
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    public static Test suite() {
+        return new TestSuite(PR58.class);
+    }
+
+    class x extends y {}
+    class y {}
+
+    public void testSuperClass() {
+        // Delete the class file which is extended.
+        new File("PR58$y.class").delete();
+
+        try {
+            Class.forName("PR58$x");
+            fail("Should throw NoClassDefFoundError");
+        }
+        catch (ClassNotFoundException error) {
+            fail("Unexpected exception: " + error);
+        }
+        catch (NoClassDefFoundError success) {
+            // Check if the cause is correct.
+            assertTrue(success.getCause() instanceof ClassNotFoundException);
+        }
+    }
+
+    interface i {}
+    class j implements i {}
+
+    public void testSuperInterface() {
+        // Delete the interface file which is implemented.
+        new File("PR58$i.class").delete();
+
+        try {
+            Class.forName("PR58$j");
+            fail("Should throw NoClassDefFoundError");
+        }
+        catch (ClassNotFoundException error) {
+            fail("Unexpected exception: " + error);
+        }
+        catch (NoClassDefFoundError success) {
+            // Check if the cause is correct.
+            assertTrue(success.getCause() instanceof ClassNotFoundException);
+        }
+    }
+}
diff --git a/tests/regression/bugzilla/PR65.java b/tests/regression/bugzilla/PR65.java
new file mode 100644 (file)
index 0000000..b8a5ef1
--- /dev/null
@@ -0,0 +1,46 @@
+/* tests/regression/bugzilla/PR65.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 junit.framework.*;
+import junit.textui.*;
+
+public class PR65 extends TestCase {
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    public static Test suite() {
+        return new TestSuite(PR65.class);
+    }
+
+    public void test() {
+        try {
+            Object o = new int[2][1];
+            Number[][] na = (Number[][]) o;
+            fail("Should throw ClassCastException");
+        } catch (ClassCastException success) {
+        }
+    }
+}
diff --git a/tests/regression/clinitexception.2output b/tests/regression/clinitexception.2output
deleted file mode 100644 (file)
index 9f6a360..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Exception in thread "main" java.lang.ExceptionInInitializerError
-   <<No stacktrace available>>
-Caused by: java.lang.RuntimeException
-   at clinitexception.<clinit>(clinitexception.java:4)
diff --git a/tests/regression/clinitexception.java b/tests/regression/clinitexception.java
deleted file mode 100644 (file)
index aa75bc4..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-public class clinitexception {
-    static {
-        if (true)
-            throw new RuntimeException();
-    }
-
-    public static void main(String[] argv) {
-    }
-}
diff --git a/tests/regression/codepatching/Makefile.am b/tests/regression/codepatching/Makefile.am
deleted file mode 100644 (file)
index 98712de..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-## tests/regression/codepatching/Makefile.am
-##
-## 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
-
-
-JAVA      = $(top_builddir)/src/cacao/cacao
-
-if WITH_CLASSPATH_GNU
-JAVAFLAGS = -Xbootclasspath:$(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
-else
-JAVAFLAGS = -Xbootclasspath:$(CLASSPATH_CLASSES)
-endif
-
-SOURCE_FILES = \
-       $(srcdir)/aastoreconstClass.java \
-       $(srcdir)/checkcastC.java \
-       $(srcdir)/checkcastI.java \
-       $(srcdir)/getfieldD.java \
-       $(srcdir)/getfieldF.java \
-       $(srcdir)/getfieldI.java \
-       $(srcdir)/getfieldJ.java \
-       $(srcdir)/getfieldL.java \
-       $(srcdir)/getstaticD.java \
-       $(srcdir)/getstaticF.java \
-       $(srcdir)/getstaticI.java \
-       $(srcdir)/getstaticJ.java \
-       $(srcdir)/getstaticL.java \
-       $(srcdir)/instanceofC.java \
-       $(srcdir)/instanceofI.java \
-       $(srcdir)/invokespecial.java \
-       $(srcdir)/invokestatic.java \
-       $(srcdir)/multianewarray.java \
-       $(srcdir)/newarray.java \
-       $(srcdir)/putfieldD.java \
-       $(srcdir)/putfieldF.java \
-       $(srcdir)/putfieldI.java \
-       $(srcdir)/putfieldJ.java \
-       $(srcdir)/putfieldL.java \
-       $(srcdir)/putfieldconstC.java \
-       $(srcdir)/putfieldconstD.java \
-       $(srcdir)/putfieldconstF.java \
-       $(srcdir)/putfieldconstI.java \
-       $(srcdir)/putfieldconstJ.java \
-       $(srcdir)/putfieldconstL.java \
-       $(srcdir)/putstaticD.java \
-       $(srcdir)/putstaticF.java \
-       $(srcdir)/putstaticI.java \
-       $(srcdir)/putstaticJ.java \
-       $(srcdir)/putstaticL.java \
-       $(srcdir)/putstaticconstC.java \
-       $(srcdir)/putstaticconstD.java \
-       $(srcdir)/putstaticconstF.java \
-       $(srcdir)/putstaticconstI.java \
-       $(srcdir)/putstaticconstJ.java \
-       $(srcdir)/putstaticconstL.java \
-       $(srcdir)/test.java
-
-EXTRA_DIST = \
-       $(SOURCE_FILES)
-
-MAINCLASS = \
-       test.class
-
-CLASSES = \
-       aastoreconstClass.class \
-       checkcastC.class \
-       checkcastI.class \
-       getfieldD.class \
-       getfieldF.class \
-       getfieldI.class \
-       getfieldJ.class \
-       getfieldL.class \
-       getstaticD.class \
-       getstaticF.class \
-       getstaticI.class \
-       getstaticJ.class \
-       getstaticL.class \
-       instanceofC.class \
-       instanceofI.class \
-       invokespecial.class \
-       invokestatic.class \
-       multianewarray.class \
-       newarray.class \
-       putfieldD.class \
-       putfieldF.class \
-       putfieldI.class \
-       putfieldJ.class \
-       putfieldL.class \
-       putfieldconstC.class \
-       putfieldconstD.class \
-       putfieldconstF.class \
-       putfieldconstI.class \
-       putfieldconstJ.class \
-       putfieldconstL.class \
-       putstaticD.class \
-       putstaticF.class \
-       putstaticI.class \
-       putstaticJ.class \
-       putstaticL.class \
-       putstaticconstC.class \
-       putstaticconstD.class \
-       putstaticconstF.class \
-       putstaticconstI.class \
-       putstaticconstJ.class \
-       putstaticconstL.class
-
-CLEANFILES = \
-       *.class
-
-check: build
-       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(JAVA) $(JAVAFLAGS) test
-
-build:
-       @$(JAVAC) -nowarn -d . $(SOURCE_FILES)
-
-remove:
-       $(RM) $(CLASSES)
-
-
-## Local variables:
-## mode: Makefile
-## indent-tabs-mode: t
-## c-basic-offset: 4
-## tab-width: 8
-## compile-command: "automake --add-missing"
-## End:
diff --git a/tests/regression/codepatching/aastoreconstClass.java b/tests/regression/codepatching/aastoreconstClass.java
deleted file mode 100644 (file)
index bd11a04..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class aastoreconstClass {
-}
-
diff --git a/tests/regression/codepatching/checkcastC.java b/tests/regression/codepatching/checkcastC.java
deleted file mode 100644 (file)
index 06e4d53..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-public class checkcastC {
-}
diff --git a/tests/regression/codepatching/checkcastI.java b/tests/regression/codepatching/checkcastI.java
deleted file mode 100644 (file)
index 39137be..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-public interface checkcastI {
-}
diff --git a/tests/regression/codepatching/getfieldD.java b/tests/regression/codepatching/getfieldD.java
deleted file mode 100644 (file)
index 0462af9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getfieldD {
-    public double d = 789.012;
-}
diff --git a/tests/regression/codepatching/getfieldF.java b/tests/regression/codepatching/getfieldF.java
deleted file mode 100644 (file)
index aa3f23e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getfieldF {
-    public float f = 123.456F;
-}
diff --git a/tests/regression/codepatching/getfieldI.java b/tests/regression/codepatching/getfieldI.java
deleted file mode 100644 (file)
index 90fa2c4..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getfieldI {
-    public int i = 123;
-}
diff --git a/tests/regression/codepatching/getfieldJ.java b/tests/regression/codepatching/getfieldJ.java
deleted file mode 100644 (file)
index d022d08..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getfieldJ {
-    public long l = 1234567890123L;
-}
diff --git a/tests/regression/codepatching/getfieldL.java b/tests/regression/codepatching/getfieldL.java
deleted file mode 100644 (file)
index 18392a8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getfieldL {
-    public Object o = null;
-}
diff --git a/tests/regression/codepatching/getstaticD.java b/tests/regression/codepatching/getstaticD.java
deleted file mode 100644 (file)
index 15620a7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getstaticD {
-    public static double d = 789.012;
-}
diff --git a/tests/regression/codepatching/getstaticF.java b/tests/regression/codepatching/getstaticF.java
deleted file mode 100644 (file)
index 64a610d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getstaticF {
-    public static float f = 123.456F;
-}
diff --git a/tests/regression/codepatching/getstaticI.java b/tests/regression/codepatching/getstaticI.java
deleted file mode 100644 (file)
index c08fbb9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getstaticI {
-    public static int i = 123;
-}
diff --git a/tests/regression/codepatching/getstaticJ.java b/tests/regression/codepatching/getstaticJ.java
deleted file mode 100644 (file)
index 49b7275..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getstaticJ {
-    public static long l = 1234567890123L;
-}
diff --git a/tests/regression/codepatching/getstaticL.java b/tests/regression/codepatching/getstaticL.java
deleted file mode 100644 (file)
index c2e0355..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class getstaticL {
-    public static Object o = null;
-}
diff --git a/tests/regression/codepatching/instanceofC.java b/tests/regression/codepatching/instanceofC.java
deleted file mode 100644 (file)
index d4d9857..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-public class instanceofC {
-}
diff --git a/tests/regression/codepatching/instanceofI.java b/tests/regression/codepatching/instanceofI.java
deleted file mode 100644 (file)
index 6cf5671..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-public interface instanceofI {
-}
diff --git a/tests/regression/codepatching/invokespecial.java b/tests/regression/codepatching/invokespecial.java
deleted file mode 100644 (file)
index 9f1885a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-public class invokespecial {
-    public invokespecial() {
-        System.out.println("OK");
-    }
-}
diff --git a/tests/regression/codepatching/invokestatic.java b/tests/regression/codepatching/invokestatic.java
deleted file mode 100644 (file)
index 9aaeb50..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-public class invokestatic {
-    public static void sub() {
-        System.out.println("OK");
-    }
-}
diff --git a/tests/regression/codepatching/multianewarray.java b/tests/regression/codepatching/multianewarray.java
deleted file mode 100644 (file)
index 1573d48..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-public class multianewarray {
-}
diff --git a/tests/regression/codepatching/newarray.java b/tests/regression/codepatching/newarray.java
deleted file mode 100644 (file)
index 5f116d0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-public class newarray {
-}
diff --git a/tests/regression/codepatching/putfieldD.java b/tests/regression/codepatching/putfieldD.java
deleted file mode 100644 (file)
index a7b28f7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldD {
-    public double d;
-}
diff --git a/tests/regression/codepatching/putfieldF.java b/tests/regression/codepatching/putfieldF.java
deleted file mode 100644 (file)
index 85d9f2b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldF {
-    public float f;
-}
diff --git a/tests/regression/codepatching/putfieldI.java b/tests/regression/codepatching/putfieldI.java
deleted file mode 100644 (file)
index 6af25d1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldI {
-    public int i;
-}
diff --git a/tests/regression/codepatching/putfieldJ.java b/tests/regression/codepatching/putfieldJ.java
deleted file mode 100644 (file)
index 6b2db7e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldJ {
-    public long l;
-}
diff --git a/tests/regression/codepatching/putfieldL.java b/tests/regression/codepatching/putfieldL.java
deleted file mode 100644 (file)
index 75b3ecc..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldL {
-    public Object o;
-}
diff --git a/tests/regression/codepatching/putfieldconstC.java b/tests/regression/codepatching/putfieldconstC.java
deleted file mode 100644 (file)
index e62abd6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldconstC {
-    public Class c;
-}
diff --git a/tests/regression/codepatching/putfieldconstD.java b/tests/regression/codepatching/putfieldconstD.java
deleted file mode 100644 (file)
index 3cb4478..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldconstD {
-    public double d;
-}
diff --git a/tests/regression/codepatching/putfieldconstF.java b/tests/regression/codepatching/putfieldconstF.java
deleted file mode 100644 (file)
index 49c07db..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldconstF {
-    public float f;
-}
diff --git a/tests/regression/codepatching/putfieldconstI.java b/tests/regression/codepatching/putfieldconstI.java
deleted file mode 100644 (file)
index 062271a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldconstI {
-    public int i;
-}
diff --git a/tests/regression/codepatching/putfieldconstJ.java b/tests/regression/codepatching/putfieldconstJ.java
deleted file mode 100644 (file)
index a38325d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldconstJ {
-    public long l;
-}
diff --git a/tests/regression/codepatching/putfieldconstL.java b/tests/regression/codepatching/putfieldconstL.java
deleted file mode 100644 (file)
index 3d00829..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putfieldconstL {
-    public Object o;
-}
diff --git a/tests/regression/codepatching/putstaticD.java b/tests/regression/codepatching/putstaticD.java
deleted file mode 100644 (file)
index 49f2010..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticD {
-    public static double d;
-}
diff --git a/tests/regression/codepatching/putstaticF.java b/tests/regression/codepatching/putstaticF.java
deleted file mode 100644 (file)
index 08cc3bc..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticF {
-    public static float f;
-}
diff --git a/tests/regression/codepatching/putstaticI.java b/tests/regression/codepatching/putstaticI.java
deleted file mode 100644 (file)
index 39a18ca..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticI {
-    public static int i;
-}
diff --git a/tests/regression/codepatching/putstaticJ.java b/tests/regression/codepatching/putstaticJ.java
deleted file mode 100644 (file)
index 8a3cfc5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticJ {
-    public static long l;
-}
diff --git a/tests/regression/codepatching/putstaticL.java b/tests/regression/codepatching/putstaticL.java
deleted file mode 100644 (file)
index f8e8dee..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticL {
-    public static Object o;
-}
diff --git a/tests/regression/codepatching/putstaticconstC.java b/tests/regression/codepatching/putstaticconstC.java
deleted file mode 100644 (file)
index 358614b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticconstC {
-    public static Class c;
-}
diff --git a/tests/regression/codepatching/putstaticconstD.java b/tests/regression/codepatching/putstaticconstD.java
deleted file mode 100644 (file)
index 219909d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticconstD {
-    public static double d;
-}
diff --git a/tests/regression/codepatching/putstaticconstF.java b/tests/regression/codepatching/putstaticconstF.java
deleted file mode 100644 (file)
index 454c0c3..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticconstF {
-    public static float f;
-}
diff --git a/tests/regression/codepatching/putstaticconstI.java b/tests/regression/codepatching/putstaticconstI.java
deleted file mode 100644 (file)
index 7038a51..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticconstI {
-    public static int i;
-}
diff --git a/tests/regression/codepatching/putstaticconstJ.java b/tests/regression/codepatching/putstaticconstJ.java
deleted file mode 100644 (file)
index 00409d0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticconstJ {
-    public static long l;
-}
diff --git a/tests/regression/codepatching/putstaticconstL.java b/tests/regression/codepatching/putstaticconstL.java
deleted file mode 100644 (file)
index 45e97dd..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-public class putstaticconstL {
-    public static Object o;
-}
diff --git a/tests/regression/codepatching/test.java b/tests/regression/codepatching/test.java
deleted file mode 100644 (file)
index aba4d5e..0000000
+++ /dev/null
@@ -1,763 +0,0 @@
-public class test extends Thread {
-    static boolean doit = true;
-
-    public static void main(String[] argv) {
-        int threadcount = 1;
-
-        if (argv.length > 0) {
-            for (int i = 0; i < argv.length; i++) {
-                if (argv[i].equals("--help")) {
-                    usage();
-
-                } else if (argv[i].equals("skip")) {
-                    doit = false;
-
-                } else {
-                    threadcount = Integer.valueOf(argv[i]).intValue();
-                }
-            }
-        }
-
-        System.out.println("Running with " + threadcount + " threads.");
-
-        for (int i = 0; i < threadcount; i++) {
-            new test().start();
-        }
-    }
-
-    static void usage() {
-        System.out.println("test [number of threads] [skip]");
-        System.exit(1);
-    }
-
-    public test() {
-    }
-
-    public void start() {
-        run();
-    }
-
-    public void run() {
-        invokestatic();
-
-        getstatic();
-        putstatic();
-        putstaticconst();
-
-        getfield();
-        putfield();
-        putfieldconst();
-
-        newarray();
-        multianewarray();
-
-        invokespecial();
-
-        checkcast();
-        _instanceof();
-
-        aastoreconst();
-    }
-
-
-    final private static void invokestatic() {
-        try {
-            p("invokestatic: ");
-            if (doit)
-                invokestatic.sub();
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-
-    private void getstatic() {
-        try {
-            p("getstatic (I): ");
-            if (doit)
-                check(getstaticI.i, 123);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("getstatic (J): ");
-            if (doit)
-                check(getstaticJ.l, 1234567890123L);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("getstatic (F): ");
-            if (doit)
-                check(getstaticF.f, 123.456F);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("getstatic (D): ");
-            if (doit)
-                check(getstaticD.d, 789.012);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("getstatic (L): ");
-            if (doit)
-                check(getstaticL.o, null);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void putstatic() {
-        try {
-            p("putstatic (I): ");
-            if (doit) {
-                int i = 123;
-                putstaticI.i = i;
-                check(putstaticI.i, i);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstatic (J): ");
-            if (doit) {
-                long l = 1234567890123L;
-                putstaticJ.l = l;
-                check(putstaticJ.l, l);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstatic (F): ");
-            if (doit) {
-                float f = 123.456F;
-                putstaticF.f = f;
-                check(putstaticF.f, f);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstatic (D): ");
-            if (doit) {
-                double d = 789.012;
-                putstaticD.d = d;
-                check(putstaticD.d, d);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-
-        try {
-            p("putstatic (L): ");
-            if (doit) {
-                Object o = null;
-                putstaticL.o = o;
-                check(putstaticL.o, o);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void putstaticconst() {
-        try {
-            p("putstaticconst (I): ");
-            if (doit) {
-                putstaticconstI.i = 123;
-                check(putstaticconstI.i, 123);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst (J): ");
-            if (doit) {
-                putstaticconstJ.l = 1234567890123L;
-                check(putstaticconstJ.l, 1234567890123L);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst (F): ");
-            if (doit) {
-                putstaticconstF.f = 123.456F;
-                check(putstaticconstF.f, 123.456F);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst (D): ");
-            if (doit) {
-                putstaticconstD.d = 789.012;
-                check(putstaticconstD.d, 789.012);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst zero (I): ");
-            if (doit) {
-                putstaticconstI.i = 0;
-                check(putstaticconstI.i, 0);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst zero (J): ");
-            if (doit) {
-                putstaticconstJ.l = 0L;
-                check(putstaticconstJ.l, 0L);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst zero (F): ");
-            if (doit) {
-                putstaticconstF.f = 0.0F;
-                check(putstaticconstF.f, 0.0F);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst zero (D): ");
-            if (doit) {
-                putstaticconstD.d = 0.0;
-                check(putstaticconstD.d, 0.0);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst zero (L): ");
-            if (doit) {
-                putstaticconstL.o = null;
-                check(putstaticconstL.o, null);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putstaticconst unresolved class: ");
-            if (doit) {
-                putstaticconstC.c = putstaticconstC.class;
-                check(putstaticconstC.c, Class.forName("putstaticconstC"));
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        } catch (ClassNotFoundException t) {
-            failed(t);
-        }
-    }
-
-    private void getfield() {
-        try {
-            p("getfield (I): ");
-            if (doit)
-                check(new getfieldI().i, 123);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("getfield (J): ");
-            if (doit)
-                check(new getfieldJ().l, 1234567890123L);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("getfield (F): ");
-            if (doit)
-                check(new getfieldF().f, 123.456F);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("getfield (D): ");
-            if (doit)
-                check(new getfieldD().d, 789.012);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("getfield (L): ");
-            if (doit)
-                check(new getfieldL().o, null);
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void putfield() {
-        try {
-            p("putfield (I): ");
-            if (doit) {
-                putfieldI pfi = new putfieldI();
-                int i = 123;
-                pfi.i = i;
-                check(pfi.i, i);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfield (J): ");
-            if (doit) {
-                putfieldJ pfj = new putfieldJ();
-                long l = 1234567890123L;
-                pfj.l = l;
-                check(pfj.l, l);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfield (F): ");
-            if (doit) {
-                putfieldF pff = new putfieldF();
-                float f = 123.456F;
-                pff.f = f;
-                check(pff.f, f);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfield (D): ");
-            if (doit) {
-                putfieldD pfd = new putfieldD();
-                double d = 789.012;
-                pfd.d = d;
-                check(pfd.d, d);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfield (L): ");
-            if (doit) {
-                putfieldL pfl = new putfieldL();
-                Object o = null;
-                pfl.o = o;
-                check(pfl.o, o);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void putfieldconst() {
-        try {
-            p("putfieldconst (I): ");
-            if (doit) {
-                putfieldconstI pfci = new putfieldconstI();
-                pfci.i = 123;
-                check(pfci.i, 123);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-        try {
-            p("putfieldconst (J): ");
-            if (doit) {
-                putfieldconstJ pfcj = new putfieldconstJ();
-                pfcj.l = 1234567890123L;
-                check(pfcj.l, 1234567890123L);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfieldconst (F): ");
-            if (doit) {
-                putfieldconstF pfcf = new putfieldconstF();
-                pfcf.f = 123.456F;
-                check(pfcf.f, 123.456F);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-        try {
-            p("putfieldconst (D): ");
-            if (doit) {
-                putfieldconstD pfcd = new putfieldconstD();
-                pfcd.d = 789.012;
-                check(pfcd.d, 789.012);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfieldconst zero (I): ");
-            if (doit) {
-                putfieldconstI pfci = new putfieldconstI();
-                pfci.i = 0;
-                check(pfci.i, 0);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-        try {
-            p("putfieldconst zero (J): ");
-            if (doit) {
-                putfieldconstJ pfcj = new putfieldconstJ();
-                pfcj.l = 0L;
-                check(pfcj.l, 0L);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfieldconst zero (F): ");
-            if (doit) {
-                putfieldconstF pfcf = new putfieldconstF();
-                pfcf.f = 0.0F;
-                check(pfcf.f, 0.0F);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-        try {
-            p("putfieldconst zero (D): ");
-            if (doit) {
-                putfieldconstD pfcd = new putfieldconstD();
-                pfcd.d = 0.0;
-                check(pfcd.d, 0.0);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfieldconst zero (L): ");
-            if (doit) {
-                putfieldconstL pfcl = new putfieldconstL();
-                pfcl.o = null;
-                check(pfcl.o, null);
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("putfieldconst unresolved class: ");
-            if (doit) {
-                putfieldconstC pfcc = new putfieldconstC();
-                pfcc.c = putfieldconstC.class;
-                check(pfcc.c, Class.forName("putfieldconstC"));
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        } catch (ClassNotFoundException t) {
-            failed(t);
-        }
-    }
-
-    private void newarray() {
-        try {
-            p("newarray: ");
-            if (doit) {
-                newarray[] na = new newarray[1];
-            }
-            ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void multianewarray() {
-        try {
-            p("multianewarray: ");
-            if (doit) {
-                multianewarray[][] ma = new multianewarray[1][1];
-            }
-            ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void invokespecial() {
-        try {
-            p("invokespecial: ");
-            if (doit)
-                new invokespecial();
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void checkcast() {
-        Object o = new Object();
-
-        // class
-        try {
-            p("checkcast class: ");
-            if (doit) {
-                checkcastC cc = (checkcastC) o;
-                failed();
-            } else
-                ok();
-        } catch (ClassCastException e) {
-            ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        // interface
-        try {
-            p("checkcast interface: ");
-            if (doit) {
-                checkcastI ci = (checkcastI) o;
-                failed();
-            } else
-                ok();
-        } catch (ClassCastException e) {
-            ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-
-        // array
-
-        Object[] oa = new Object[1];
-
-        try {
-            p("checkcast class array: ");
-            if (doit) {
-                checkcastC[] cca = (checkcastC[]) oa;
-                failed();
-            } else
-                ok();
-        } catch (ClassCastException e) {
-            ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void _instanceof() {
-        Object o = new Object();
-
-        try {
-            p("instanceof class: ");
-            if (doit)
-                if (o instanceof instanceofC)
-                    failed();
-                else
-                    ok();
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-        try {
-            p("instanceof interface: ");
-            if (doit)
-                if (o instanceof instanceofI)
-                    failed();
-                else
-                    ok();
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-
-
-        // array
-
-        Object[] oa = new Object[1];
-
-        try {
-            p("instanceof class array: ");
-            if (doit)
-                if (oa instanceof instanceofC[])
-                    failed();
-                else
-                    ok();
-            else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        }
-    }
-
-    private void aastoreconst() {
-        Class[] ca = new Class[1];
-
-        try {
-            p("aastoreconst of unresolved class != NULL: ");
-            if (doit) {
-                ca[0] = aastoreconstClass.class;
-
-                if (ca[0] != null)
-                    ok();
-                else
-                    failed();
-
-                p("aastoreconst of unresolved correct value: ");
-                check(ca[0],Class.forName("aastoreconstClass"));
-            } else
-                ok();
-        } catch (NoClassDefFoundError t) {
-            failed(t);
-        } catch (ClassNotFoundException t) {
-            failed(t);
-        }
-    }
-
-    private static final void ok() {
-        pln("OK");
-    }
-
-    private static final void failed() {
-        pln("FAILED");
-    }
-
-    private static final void failed(Throwable t) {
-        pln("FAILED: " + t);
-    }
-
-    private static final void check(int a, int b) {
-        if (a == b)
-            ok();
-        else
-            pln("FAILED: " + a + " != " + b + " (0x" + Integer.toHexString(a) + " != 0x" + Integer.toHexString(b) + ")");
-    }
-
-    private static final void check(long a, long b) {
-        if (a == b)
-            ok();
-        else
-            pln("FAILED: " + a + " != " + b + " (0x" + Long.toHexString(a) + " != 0x" + Long.toHexString(b) + ")");
-    }
-
-    private static final void check(float a, float b) {
-        if (a == b)
-            ok();
-        else
-            pln("FAILED: " + a + " != " + b);
-    }
-
-    private static final void check(double a, double b) {
-        if (a == b)
-            ok();
-        else
-            pln("FAILED: " + a + " != " + b);
-    }
-
-    private static final void check(Object a, Object b) {
-        if (a == b)
-            ok();
-        else
-            pln("FAILED: " + a + " != " + b);
-    }
-
-    private static final void p(String s) {
-        System.out.print(s);
-    }
-
-    private static final void pln(String s) {
-        System.out.println(s);
-    }
-}
-
-// vim: et ts=4 sw=4
-
index ffbba1ce031308c45fc1dd167df300a99f665586..81cbc3ae3f65f27b54584d62bff9e51062111e5e 100644 (file)
@@ -1,9 +1,7 @@
 ## tests/regression/jasmin/Makefile.am
 ##
-## 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.
 ##
 ## 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
-##          Edwin Steiner
-## Process this file with automake to produce Makefile.in
-
-JAVA      = $(top_builddir)/src/cacao/cacao
-
-if WITH_CLASSPATH_GNU
-JAVAFLAGS = -Xbootclasspath:$(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
-else
-JAVAFLAGS = -Xbootclasspath:$(CLASSPATH_CLASSES)
-endif
-
-JASMIN_TESTS = \
-       $(srcdir)/test_coalesce_simple_store.j \
-       $(srcdir)/test_dup2.j \
-       $(srcdir)/test_dup2_x1.j \
-       $(srcdir)/test_dup2_x2.j \
-       $(srcdir)/test_dup.j \
-       $(srcdir)/test_dup_x1.j \
-       $(srcdir)/test_dup_x1_interface_slots.j \
-       $(srcdir)/test_dup_x2.j \
-       $(srcdir)/test_dup_x2_interface_slots.j \
-       $(srcdir)/test_dup_x2_to_dup_x1.j \
-       $(srcdir)/test.j \
-       $(srcdir)/test_iinc.j \
-       $(srcdir)/test_load_store_conflict_by_exception.j \
-       $(srcdir)/test_load_store_conflict_by_exception_not_thrown.j \
-       $(srcdir)/test_load_store_conflict.j \
-       $(srcdir)/test_load_store_conflict_via_dup.j \
-       $(srcdir)/test_load_store_conflict_via_swap.j \
-       $(srcdir)/test_many_dup.j \
-       $(srcdir)/test_many_dup_x1.j \
-       $(srcdir)/test_many_dup_x2.j \
-       $(srcdir)/test_many_dup2.j \
-       $(srcdir)/test_many_dup2_x1.j \
-       $(srcdir)/test_many_dup2_x2.j \
-       $(srcdir)/test_many_monitors.j \
-       $(srcdir)/test_many_swap.j \
-       $(srcdir)/test_no_store_load_conflict.j \
-       $(srcdir)/test_no_store_store_conflict.j \
-       $(srcdir)/test_nullpointerexception_monitorexit.j \
-       $(srcdir)/test_simple_load_store.j \
-       $(srcdir)/test_store_load_conflict.j \
-       $(srcdir)/test_store_store_conflict_2.j \
-       $(srcdir)/test_store_store_conflict.j \
-       $(srcdir)/test_swap_interface_slots.j \
-       $(srcdir)/test_swap.j \
-       $(srcdir)/test_swap_locals.j \
-       $(srcdir)/test_verify_fail_aload_retaddress.j \
-       $(srcdir)/test_verify_fail_areturn_wrong_reftype.j \
-       $(srcdir)/test_verify_fail_athrow_wrong_reftype.j \
-       $(srcdir)/test_verify_fail_athrow_wrong_reftype_unresolved.j \
-       $(srcdir)/test_verify_fail_backward_with_new_on_stack.j \
-       $(srcdir)/test_verify_fail_double_local_index.j \
-       $(srcdir)/test_verify_fail_double_overwritten.j \
-       $(srcdir)/test_verify_fail_getfield_basic_type_instance.j \
-       $(srcdir)/test_verify_fail_getfield_basic_type_lookup.j \
-       $(srcdir)/test_verify_fail_getfield_basic_type_value.j \
-       $(srcdir)/test_verify_fail_handler_bad_local.j \
-       $(srcdir)/test_verify_fail_init_nullpointer.j \
-       $(srcdir)/test_verify_fail_invoke_basic_type.j \
-       $(srcdir)/test_verify_fail_invoke_return_basic_type.j \
-       $(srcdir)/test_verify_fail_ireturn_wrong_type.j \
-       $(srcdir)/test_verify_fail_jsr_called_with_different_stackdepths.j \
-       $(srcdir)/test_verify_fail_jsr_exceptions.j \
-       $(srcdir)/test_verify_fail_jsr_handler_in_sub.j \
-       $(srcdir)/test_verify_fail_jsr_merge_subroutines.j \
-       $(srcdir)/test_verify_fail_jsr_merge_subroutines_via_stack.j \
-       $(srcdir)/test_verify_fail_jsr_polymorphic_pop.j \
-       $(srcdir)/test_verify_fail_load_wrong_type.j \
-       $(srcdir)/test_verify_fail_load_wrong_type_within_block.j \
-       $(srcdir)/test_verify_fail_local_index.j \
-       $(srcdir)/test_verify_fail_long_local_index.j \
-       $(srcdir)/test_verify_fail_long_local.j \
-       $(srcdir)/test_verify_fail_long_overwritten.j \
-       $(srcdir)/test_verify_fail_merge_different_new_objects.j \
-       $(srcdir)/test_verify_fail_merge_init_nullpointer.j \
-       $(srcdir)/test_verify_fail_putfield_basic_type_instance.j \
-       $(srcdir)/test_verify_fail_putfield_basic_type_lookup.j \
-       $(srcdir)/test_verify_fail_putfield_basic_type_value.j \
-       $(srcdir)/test_verify_fail_putfieldconst_basic_type_instance.j \
-       $(srcdir)/test_verify_fail_putfieldconst_basic_type_value.j \
-       $(srcdir)/test_verify_fail_putstatic_basic_type_value.j \
-       $(srcdir)/test_verify_fail_putstaticconst_basic_type_value.j \
-       $(srcdir)/test_verify_fail_retaddr_as_object.j \
-       $(srcdir)/test_verify_fail_ret_bad_type.j \
-       $(srcdir)/test_verify_fail_ret_uninit_var.j \
-       $(srcdir)/test_verify_fail_split_local.j \
-       $(srcdir)/test_verify_ok_jsr_handler_in_sub2.j \
-       $(srcdir)/test_verify_ok_jsr_improper_nesting.j \
-       $(srcdir)/test_verify_ok_jsr.j \
-       $(srcdir)/test_verify_ok_jsr_multiple_blocks.j \
-       $(srcdir)/test_verify_ok_jsr_pop.j \
-       $(srcdir)/test_verify_ok_jsr_push.j \
-       $(srcdir)/test_verify_ok_jsr_subroutine_loops_to_start.j \
-       $(srcdir)/test_verify_ok_jsr_swap.j \
-       $(srcdir)/test_verify_ok_jsr_through_variable.j \
-       $(srcdir)/test_verify_ok_local_as_retaddr_and_reference.j \
-       $(srcdir)/test_verify_ok_overwrite_local_type.j \
-       $(srcdir)/test_verify_ok_untyped_local.j \
-       $(srcdir)/test_verify_unspecced_ok_backward_with_new_in_local.j \
-       $(srcdir)/test_verify_unspecced_ok_backward_with_new_on_stack.j \
-       $(srcdir)/test_verify_unspecced_ok_new_in_local_within_try.j
 
 
+JAVA     = LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(top_builddir)/src/cacao/cacao
+JAVACMD  = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
 
 EXTRA_DIST = \
        $(srcdir)/runtest \
        $(srcdir)/show \
-       $(JASMIN_TESTS)
+       $(srcdir)/*.j
 
 CLEANFILES = \
        *.class \
        TESTLOG TESTEXPECT TESTOUT TESTERR TESTSIA
 
-check:
-       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs JAVA="$(JAVA)" JAVAFLAGS="$(JAVAFLAGS)" $(srcdir)/runtest $(JASMIN_TESTS)
+check: build run
+
+build:
+       $(JAVACMD) -cp /usr/share/java/jasmin-sable.jar jasmin.Main $(srcdir)/*.j
+
+run:
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs JAVA="$(top_builddir)/src/cacao/cacao -Xbootclasspath:$(BOOTCLASSPATH)" $(srcdir)/runtest $(srcdir)/*.j
+
 
 ## Local variables:
 ## mode: Makefile
index 438d321609bd131cdd71f5a5f5aeb97b7e6efda5..729632210901e918933d292e7d007dfda7020d16 100755 (executable)
@@ -44,19 +44,7 @@ if [ "$1" = "--color" ] ; then
        ECHOFLAGS='-e'
 fi
 
-if [ -z "$JASMIN_JAR" ] ; then
-       JASMIN_JAR=/usr/share/java/jasmin-sable.jar
-fi
-
-if [ ! -r "$JASMIN_JAR" ] ; then
-       echo >&2 "$0: warning: jasmin .jar is not available at $JASMIN_JAR"
-       exit 0
-fi
-
-JASMIN="$JAVA $JAVAFLAGS -cp $JASMIN_JAR jasmin.Main"
-
 echo "java command: $JAVA $JAVAFLAGS"
-echo "jasmin command: $JASMIN"
 
 while [ -n "$1" ]
 do
@@ -72,10 +60,6 @@ do
        EXPECTSTATUS=0
        CHECKICMD=0
 
-       # compile the test
-
-    $JASMIN "$TEST" || exit 2
-
        if grep 'ERROR:' "$TEST" >/dev/null ; then
                EXPECTSTATUS=1
                EXPECTERROR=$(grep 'ERROR:.*' "$TEST" | sed 's,.*ERROR:[ \t]*,,')
@@ -88,7 +72,7 @@ do
 
        # run the test
 
-    $TIMEOUTRUN $JAVA $JAVAFLAGS "$TESTBASENAME" >"$TESTOUT" 2>"$TESTERR"
+       $TIMEOUTRUN $JAVA $JAVAFLAGS "$TESTBASENAME" >"$TESTOUT" 2>"$TESTERR"
        TESTSTATUS=$?
 
        if [ $TESTSTATUS -ne $EXPECTSTATUS ] ; then
diff --git a/tests/regression/jasmin/test_load_store_conflict_different_types.j b/tests/regression/jasmin/test_load_store_conflict_different_types.j
new file mode 100644 (file)
index 0000000..57a04ff
--- /dev/null
@@ -0,0 +1,66 @@
+.class public test_load_store_conflict_different_types
+.super java/lang/Object
+
+; ======================================================================
+
+.method public <init>()V
+   aload_0
+   invokenonvirtual java/lang/Object/<init>()V
+   return
+.end method
+
+; ======================================================================
+
+.method public static checkI(I)V
+       .limit locals 1
+       .limit stack 10
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       iload_0
+       invokevirtual java/io/PrintStream/println(I)V
+       return
+.end method
+
+.method public static checkString(Ljava/lang/String;)V
+       .limit locals 1
+       .limit stack 10
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       aload_0
+       invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
+       return
+.end method
+
+; ======================================================================
+
+.method public static main([Ljava/lang/String;)V
+       .limit stack 3
+       .limit locals 3
+
+       ldc 35
+       istore 1
+    ldc 42
+    istore 2
+
+       aload 0
+       ifnull force_basic_block_boundary
+
+       ; --------------------------------------------------
+
+       iload 1  ; loads 35
+       ldc "Sepp"
+       astore 1
+       istore 2 ; stores 35
+
+       ; --------------------------------------------------
+
+       aload 1
+       invokestatic test_load_store_conflict_different_types/checkString(Ljava/lang/String;)V
+       ; OUTPUT: Sepp
+
+       iload 2
+       invokestatic test_load_store_conflict_different_types/checkI(I)V
+       ; OUTPUT: 35
+
+force_basic_block_boundary:
+
+       return
+.end method
diff --git a/tests/regression/jasmin/test_verify_fail_jsr_multiple_returns.j b/tests/regression/jasmin/test_verify_fail_jsr_multiple_returns.j
deleted file mode 100644 (file)
index 89c5f12..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-.class public test_verify_fail_jsr_multiple_returns
-.super java/lang/Object
-
-; ======================================================================
-
-.method public <init>()V
-   aload_0
-   invokenonvirtual java/lang/Object/<init>()V
-   return
-.end method
-
-; ======================================================================
-
-.method public static check(I)V
-       .limit locals 1
-       .limit stack 10
-       getstatic java/lang/System/out Ljava/io/PrintStream;
-       iload_0
-       invokevirtual java/io/PrintStream/println(I)V
-       return
-.end method
-
-.method public static check(Ljava/lang/String;)V
-       .limit locals 1
-       .limit stack 10
-       getstatic java/lang/System/out Ljava/io/PrintStream;
-       aload_0
-       invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
-       return
-.end method
-
-; ======================================================================
-
-.method public static main([Ljava/lang/String;)V
-       .limit stack 2
-       .limit locals 4
-
-       ldc 0
-       istore 1
-
-       aload 0
-       ifnull force_basic_block_boundary
-
-       ; --------------------------------------------------
-
-       jsr sbr_1
-
-       jsr sbr_1
-
-       ; --------------------------------------------------
-
-force_basic_block_boundary:
-
-       iload 1
-       invokestatic test_verify_fail_jsr_multiple_returns/check(I)V
-
-       return
-
-sbr_1:
-       astore 2
-       ldc "one"
-       invokestatic test_verify_fail_jsr_multiple_returns/check(Ljava/lang/String;)V
-       jsr sbr_2
-       ldc "one-B"
-       invokestatic test_verify_fail_jsr_multiple_returns/check(Ljava/lang/String;)V
-       iinc 1 1
-       ret 2
-
-sbr_2:
-       astore 3
-       ldc "two"
-       invokestatic test_verify_fail_jsr_multiple_returns/check(Ljava/lang/String;)V
-       iload 1
-       ifne second_time
-       ret 3
-
-second_time:
-       ret 2
-       ; ERROR: VerifyError
-
-.end method
-
diff --git a/tests/regression/jasmin/test_verify_fail_jsr_multiple_returns.j-no b/tests/regression/jasmin/test_verify_fail_jsr_multiple_returns.j-no
new file mode 100644 (file)
index 0000000..89c5f12
--- /dev/null
@@ -0,0 +1,82 @@
+.class public test_verify_fail_jsr_multiple_returns
+.super java/lang/Object
+
+; ======================================================================
+
+.method public <init>()V
+   aload_0
+   invokenonvirtual java/lang/Object/<init>()V
+   return
+.end method
+
+; ======================================================================
+
+.method public static check(I)V
+       .limit locals 1
+       .limit stack 10
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       iload_0
+       invokevirtual java/io/PrintStream/println(I)V
+       return
+.end method
+
+.method public static check(Ljava/lang/String;)V
+       .limit locals 1
+       .limit stack 10
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       aload_0
+       invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
+       return
+.end method
+
+; ======================================================================
+
+.method public static main([Ljava/lang/String;)V
+       .limit stack 2
+       .limit locals 4
+
+       ldc 0
+       istore 1
+
+       aload 0
+       ifnull force_basic_block_boundary
+
+       ; --------------------------------------------------
+
+       jsr sbr_1
+
+       jsr sbr_1
+
+       ; --------------------------------------------------
+
+force_basic_block_boundary:
+
+       iload 1
+       invokestatic test_verify_fail_jsr_multiple_returns/check(I)V
+
+       return
+
+sbr_1:
+       astore 2
+       ldc "one"
+       invokestatic test_verify_fail_jsr_multiple_returns/check(Ljava/lang/String;)V
+       jsr sbr_2
+       ldc "one-B"
+       invokestatic test_verify_fail_jsr_multiple_returns/check(Ljava/lang/String;)V
+       iinc 1 1
+       ret 2
+
+sbr_2:
+       astore 3
+       ldc "two"
+       invokestatic test_verify_fail_jsr_multiple_returns/check(Ljava/lang/String;)V
+       iload 1
+       ifne second_time
+       ret 3
+
+second_time:
+       ret 2
+       ; ERROR: VerifyError
+
+.end method
+
diff --git a/tests/regression/jasmin/test_verify_fail_jsr_recursion.j b/tests/regression/jasmin/test_verify_fail_jsr_recursion.j
deleted file mode 100644 (file)
index 7c38932..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-.class public test_verify_fail_jsr_recursion
-.super java/lang/Object
-
-; ======================================================================
-
-.method public <init>()V
-   aload_0
-   invokenonvirtual java/lang/Object/<init>()V
-   return
-.end method
-
-; ======================================================================
-
-.method public static check(I)V
-       .limit locals 1
-       .limit stack 10
-       getstatic java/lang/System/out Ljava/io/PrintStream;
-       iload_0
-       invokevirtual java/io/PrintStream/println(I)V
-       return
-.end method
-
-; ======================================================================
-
-.method public static main([Ljava/lang/String;)V
-       .limit stack 2
-       .limit locals 4
-
-       ldc 0
-       istore 1
-
-       aload 0
-       ifnull force_basic_block_boundary
-
-       ; --------------------------------------------------
-
-       jsr sbr_1
-       jsr sbr_1
-
-       ; --------------------------------------------------
-
-force_basic_block_boundary:
-
-       iload 1
-       invokestatic test_verify_fail_jsr_recursion/check(I)V
-
-       return
-
-sbr_1:
-       astore 2
-       iload 1
-       invokestatic test_verify_fail_jsr_recursion/check(I)V
-       iload 1
-       ifne  second_time
-       iinc 1 1
-       jsr sbr_1
-       ; ERROR: VerifyError
-
-second_time:
-       ret 2
-
-.end method
-
diff --git a/tests/regression/jasmin/test_verify_fail_jsr_recursion.j-no b/tests/regression/jasmin/test_verify_fail_jsr_recursion.j-no
new file mode 100644 (file)
index 0000000..7c38932
--- /dev/null
@@ -0,0 +1,63 @@
+.class public test_verify_fail_jsr_recursion
+.super java/lang/Object
+
+; ======================================================================
+
+.method public <init>()V
+   aload_0
+   invokenonvirtual java/lang/Object/<init>()V
+   return
+.end method
+
+; ======================================================================
+
+.method public static check(I)V
+       .limit locals 1
+       .limit stack 10
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       iload_0
+       invokevirtual java/io/PrintStream/println(I)V
+       return
+.end method
+
+; ======================================================================
+
+.method public static main([Ljava/lang/String;)V
+       .limit stack 2
+       .limit locals 4
+
+       ldc 0
+       istore 1
+
+       aload 0
+       ifnull force_basic_block_boundary
+
+       ; --------------------------------------------------
+
+       jsr sbr_1
+       jsr sbr_1
+
+       ; --------------------------------------------------
+
+force_basic_block_boundary:
+
+       iload 1
+       invokestatic test_verify_fail_jsr_recursion/check(I)V
+
+       return
+
+sbr_1:
+       astore 2
+       iload 1
+       invokestatic test_verify_fail_jsr_recursion/check(I)V
+       iload 1
+       ifne  second_time
+       iinc 1 1
+       jsr sbr_1
+       ; ERROR: VerifyError
+
+second_time:
+       ret 2
+
+.end method
+
diff --git a/tests/regression/jasmin/test_verify_fail_jsr_recursion_terminates.j b/tests/regression/jasmin/test_verify_fail_jsr_recursion_terminates.j
deleted file mode 100644 (file)
index 02cde40..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-.class public test_verify_fail_jsr_recursion_terminates
-.super java/lang/Object
-
-; ======================================================================
-
-.method public <init>()V
-   aload_0
-   invokenonvirtual java/lang/Object/<init>()V
-   return
-.end method
-
-; ======================================================================
-
-.method public static check(I)V
-       .limit locals 1
-       .limit stack 10
-       getstatic java/lang/System/out Ljava/io/PrintStream;
-       iload_0
-       invokevirtual java/io/PrintStream/println(I)V
-       return
-.end method
-
-.method public static check(Ljava/lang/String;)V
-       .limit locals 1
-       .limit stack 10
-       getstatic java/lang/System/out Ljava/io/PrintStream;
-       aload_0
-       invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
-       return
-.end method
-
-; ======================================================================
-
-.method public static main([Ljava/lang/String;)V
-       .limit stack 2
-       .limit locals 4
-
-       ldc 0
-       istore 1
-
-       aload 0
-       ifnull force_basic_block_boundary
-
-       ; --------------------------------------------------
-
-       jsr sbr_1
-       jsr sbr_1
-
-       ; --------------------------------------------------
-
-force_basic_block_boundary:
-
-       iload 1
-       invokestatic test_verify_fail_jsr_recursion_terminates/check(I)V
-
-       return
-
-sbr_1:
-       ldc "entry"
-       invokestatic test_verify_fail_jsr_recursion_terminates/check(Ljava/lang/String;)V
-       iload 1
-       ifne second_time
-
-       astore 2
-       ldc "first"
-       invokestatic test_verify_fail_jsr_recursion_terminates/check(Ljava/lang/String;)V
-       iinc 1 1
-       jsr sbr_1
-       ; ERROR: VerifyError
-       ret 2
-
-second_time:
-       astore 3
-       ldc "second"
-       invokestatic test_verify_fail_jsr_recursion_terminates/check(Ljava/lang/String;)V
-       ret 3
-
-.end method
-
diff --git a/tests/regression/jasmin/test_verify_fail_jsr_recursion_terminates.j-no b/tests/regression/jasmin/test_verify_fail_jsr_recursion_terminates.j-no
new file mode 100644 (file)
index 0000000..02cde40
--- /dev/null
@@ -0,0 +1,79 @@
+.class public test_verify_fail_jsr_recursion_terminates
+.super java/lang/Object
+
+; ======================================================================
+
+.method public <init>()V
+   aload_0
+   invokenonvirtual java/lang/Object/<init>()V
+   return
+.end method
+
+; ======================================================================
+
+.method public static check(I)V
+       .limit locals 1
+       .limit stack 10
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       iload_0
+       invokevirtual java/io/PrintStream/println(I)V
+       return
+.end method
+
+.method public static check(Ljava/lang/String;)V
+       .limit locals 1
+       .limit stack 10
+       getstatic java/lang/System/out Ljava/io/PrintStream;
+       aload_0
+       invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
+       return
+.end method
+
+; ======================================================================
+
+.method public static main([Ljava/lang/String;)V
+       .limit stack 2
+       .limit locals 4
+
+       ldc 0
+       istore 1
+
+       aload 0
+       ifnull force_basic_block_boundary
+
+       ; --------------------------------------------------
+
+       jsr sbr_1
+       jsr sbr_1
+
+       ; --------------------------------------------------
+
+force_basic_block_boundary:
+
+       iload 1
+       invokestatic test_verify_fail_jsr_recursion_terminates/check(I)V
+
+       return
+
+sbr_1:
+       ldc "entry"
+       invokestatic test_verify_fail_jsr_recursion_terminates/check(Ljava/lang/String;)V
+       iload 1
+       ifne second_time
+
+       astore 2
+       ldc "first"
+       invokestatic test_verify_fail_jsr_recursion_terminates/check(Ljava/lang/String;)V
+       iinc 1 1
+       jsr sbr_1
+       ; ERROR: VerifyError
+       ret 2
+
+second_time:
+       astore 3
+       ldc "second"
+       invokestatic test_verify_fail_jsr_recursion_terminates/check(Ljava/lang/String;)V
+       ret 3
+
+.end method
+
diff --git a/tests/regression/junit/All.java b/tests/regression/junit/All.java
new file mode 100644 (file)
index 0000000..15a5523
--- /dev/null
@@ -0,0 +1,52 @@
+/* tests/regression/junit/All.java - runs all CACAO regression unit tests
+
+   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 junit.framework.*;
+import junit.textui.*;
+
+public class All extends TestCase {
+    /**
+     * Runs all CACAO regression unit tests using
+     * junit.textui.TestRunner
+     */
+    public static void main(String[] args) {
+        Test s = suite();
+        TestRunner.run(s);
+    }
+
+    /**
+     * Collects all CACAO regression unit tests as one suite.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite("CACAO Regression Unit Tests");
+
+        // Add your test here.
+
+        suite.addTest(new TestSuite(TestPatcher.class));
+        suite.addTest(new TestSuite(TestExceptionInStaticClassInitializer.class));
+
+        return suite;
+    }
+}
diff --git a/tests/regression/junit/Makefile.am b/tests/regression/junit/Makefile.am
new file mode 100644 (file)
index 0000000..d43942e
--- /dev/null
@@ -0,0 +1,49 @@
+## tests/regression/junit/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.
+
+
+JAVA     = LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(top_builddir)/src/cacao/cacao
+JAVACMD  = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -source 1.5 -target 1.5 -nowarn -bootclasspath $(BOOTCLASSPATH)
+
+EXTRA_DIST = \
+       $(srcdir)/*.java
+
+CLEANFILES = \
+       *.class
+
+check: build run
+
+build:
+       $(JAVACCMD) -classpath /usr/share/java/junit4.jar -d . $(srcdir)/*.java
+
+run:
+       $(JAVACMD) -classpath /usr/share/java/junit4.jar:. org.junit.runner.JUnitCore All
+
+
+## Local variables:
+## mode: Makefile
+## indent-tabs-mode: t
+## c-basic-offset: 4
+## tab-width: 8
+## compile-command: "automake --add-missing"
+## End:
diff --git a/tests/regression/junit/TestExceptionInStaticClassInitializer.java b/tests/regression/junit/TestExceptionInStaticClassInitializer.java
new file mode 100644 (file)
index 0000000..e6cc93e
--- /dev/null
@@ -0,0 +1,66 @@
+/* tests/regression/bugzilla/TestExceptionInStaticClassInitializer.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 junit.framework.*;
+import junit.textui.*;
+
+public class TestExceptionInStaticClassInitializer extends TestCase {
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    public static Test suite() {
+        return new TestSuite(TestExceptionInStaticClassInitializer.class);
+    }
+
+    public void test() {
+        try {
+            TestExceptionInStaticClassInitializer_x.i = 1;
+            fail("Should throw ExceptionInInitializerError");
+        }
+        catch (ExceptionInInitializerError success) {
+            Throwable cause = success.getCause();
+
+            assertTrue("Cause should be RuntimeException but is " + cause.getClass(), cause.getClass() == RuntimeException.class);
+
+            StackTraceElement[] ste = cause.getStackTrace();
+
+            assertTrue("Linenumber should be " + LINE + " but is " + ste[0].getLineNumber(), ste[0].getLineNumber() == LINE);
+        }
+    }
+
+    // This linenumber must be the one from...
+    final static int LINE = 64;
+}
+
+class TestExceptionInStaticClassInitializer_x {
+    static int i;
+
+    static {
+        if (true)
+            // ...the following line.
+            throw new RuntimeException();
+    }
+}
diff --git a/tests/regression/junit/TestPatcher.java b/tests/regression/junit/TestPatcher.java
new file mode 100644 (file)
index 0000000..8417608
--- /dev/null
@@ -0,0 +1,650 @@
+/* tests/regression/bugzilla/TestPatcher.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 junit.framework.*;
+import junit.textui.*;
+
+import java.io.*;
+
+public class TestPatcher extends TestCase {
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    public static Test suite() {
+        return new TestSuite(TestPatcher.class);
+    }
+
+    static boolean doit = true;
+
+    final static int    i = 123;
+    final static long   l = 1234567890123L;
+    final static float  f = 123.456F;
+    final static double d = 789.012;
+    final static Object o = new Object();
+
+    public void testNormal() {
+        invokestatic();
+        invokespecial();
+
+        getstatic();
+        putstatic();
+        putstaticconst();
+
+        getfield();
+        putfield();
+        putfieldconst();
+
+        newarray();
+        multianewarray();
+
+        checkcast();
+        _instanceof();
+
+        aastoreconst();
+    }
+
+    public void testWithoutClasses() {
+        // Delete all classes.
+        //new File("TestPatcher$invokestatic.class").delete();
+
+        invokestatic();
+        invokespecial();
+
+        getstatic();
+        putstatic();
+        putstaticconst();
+
+        getfield();
+        putfield();
+        putfieldconst();
+
+        newarray();
+        multianewarray();
+
+        checkcast();
+        _instanceof();
+
+        aastoreconst();
+    }
+
+    private void invokestatic() {
+        try {
+            if (doit)
+                invokestatic.sub();
+        } catch (NoClassDefFoundError e) {
+            fail(e.toString());
+        }
+    }
+
+    private void getstatic() {
+        try {
+            if (doit)
+                assertTrue(getstaticI.i + " != " + i, getstaticI.i == i);
+        } catch (NoClassDefFoundError e) {
+            fail(e.toString());
+        }
+
+        try {
+            if (doit)
+                assertTrue(getstaticJ.l + " != " + l, getstaticJ.l == l);
+        } catch (NoClassDefFoundError e) {
+            fail(e.toString());
+        }
+
+        try {
+            if (doit)
+                assertTrue(getstaticF.f + " != " + f, getstaticF.f == f);
+        } catch (NoClassDefFoundError e) {
+            fail(e.toString());
+        }
+
+        try {
+            if (doit)
+                assertTrue(getstaticD.d + " != " + d, getstaticD.d == d);
+        } catch (NoClassDefFoundError e) {
+            fail(e.toString());
+        }
+
+        try {
+            if (doit)
+                assertTrue(getstaticL.o + " != null", getstaticL.o == null);
+        } catch (NoClassDefFoundError e) {
+            fail(e.toString());
+        }
+    }
+
+    private void putstatic() {
+        try {
+            if (doit) {
+                putstaticI.i = i;
+                assertTrue(putstaticI.i + " != " + i, putstaticI.i == i);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticJ.l = l;
+                assertTrue(putstaticJ.l + " != " + l, putstaticJ.l == l);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticF.f = f;
+                assertTrue(putstaticF.f + " != " + f, putstaticF.f == f);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticD.d = d;
+                assertTrue(putstaticD.d + " != " + d, putstaticD.d == d);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+
+        try {
+            if (doit) {
+                putstaticL.o = o;
+                assertTrue(putstaticL.o + " != " + o, putstaticL.o == o);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+    }
+
+    private void putstaticconst() {
+        try {
+            if (doit) {
+                putstaticconstI.i = i;
+                assertTrue(putstaticconstI.i + " != " + i, putstaticconstI.i == i);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstJ.l = l;
+                assertTrue(putstaticconstJ.l + " != " + l, putstaticconstJ.l == l);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstF.f = f;
+                assertTrue(putstaticconstF.f + " != " + f, putstaticconstF.f == f);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstD.d = d;
+                assertTrue(putstaticconstD.d + " != " + d, putstaticconstD.d == d);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstI.i = 0;
+                assertTrue(putstaticconstI.i + " != " + 0, putstaticconstI.i == 0);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstJ.l = 0L;
+                assertTrue(putstaticconstJ.l + " != " + 0L, putstaticconstJ.l == 0L);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstF.f = 0.0F;
+                assertTrue(putstaticconstF.f + " != " + 0.0F, putstaticconstF.f == 0.0F);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstD.d = 0.0;
+                assertTrue(putstaticconstD.d + " != " + 0.0, putstaticconstD.d == 0.0);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstL.o = null;
+                assertTrue(putstaticconstL.o + " != " + null, putstaticconstL.o == null);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putstaticconstC.c = putstaticconstC.class;
+                assertTrue(putstaticconstC.c + " != " + Class.forName("TestPatcher$putstaticconstC"), putstaticconstC.c == Class.forName("TestPatcher$putstaticconstC"));
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        } catch (ClassNotFoundException t) {
+            fail(t.toString());
+        }
+    }
+
+    private void getfield() {
+        try {
+            if (doit)
+                assertTrue(new getfieldI().i + " != " + i, new getfieldI().i == i);
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit)
+                assertTrue(new getfieldJ().l + " != " + l, new getfieldJ().l == l);
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit)
+                assertTrue(new getfieldF().f + " != " + f, new getfieldF().f == f);
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit)
+                assertTrue(new getfieldD().d + " != " + d, new getfieldD().d == d);
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit)
+                assertTrue(new getfieldL().o + " != " + null, new getfieldL().o == null);
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+    }
+
+    private void putfield() {
+        try {
+            if (doit) {
+                TestPatcher.putfieldI pfi = new TestPatcher.putfieldI();
+                pfi.i = i;
+                assertTrue(pfi.i + " != " + i, pfi.i == i);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldJ pfj = new putfieldJ();
+                pfj.l = l;
+                assertTrue(pfj.l + " != " + l, pfj.l == l);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldF pff = new putfieldF();
+                pff.f = f;
+                assertTrue(pff.f + " != " + f, pff.f == f);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldD pfd = new putfieldD();
+                pfd.d = d;
+                assertTrue(pfd.d + " != " + d, pfd.d == d);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldL pfl = new putfieldL();
+                pfl.o = o;
+                assertTrue(pfl.o + " != " + o, pfl.o == o);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+    }
+
+    private void putfieldconst() {
+        try {
+            if (doit) {
+                putfieldconstI pfci = new putfieldconstI();
+                pfci.i = i;
+                assertTrue(pfci.i + " != " + i, pfci.i == i);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+        try {
+            if (doit) {
+                putfieldconstJ pfcj = new putfieldconstJ();
+                pfcj.l = l;
+                assertTrue(pfcj.l + " != " + l, pfcj.l == l);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldconstF pfcf = new putfieldconstF();
+                pfcf.f = f;
+                assertTrue(pfcf.f + " != " + f, pfcf.f == f);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+        try {
+            if (doit) {
+                putfieldconstD pfcd = new putfieldconstD();
+                pfcd.d = d;
+                assertTrue(pfcd.d + " != " + d, pfcd.d == d);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldconstI pfci = new putfieldconstI();
+                pfci.i = 0;
+                assertTrue(pfci.i + " != " + 0, pfci.i == 0);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+        try {
+            if (doit) {
+                putfieldconstJ pfcj = new putfieldconstJ();
+                pfcj.l = 0L;
+                assertTrue(pfcj.l + " != " + 0L, pfcj.l == 0L);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldconstF pfcf = new putfieldconstF();
+                pfcf.f = 0.0F;
+                assertTrue(pfcf.f + " != " + 0.0F, pfcf.f == 0.0F);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+        try {
+            if (doit) {
+                putfieldconstD pfcd = new putfieldconstD();
+                pfcd.d = 0.0;
+                assertTrue(pfcd.d + " != " + 0.0, pfcd.d == 0.0);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldconstL pfcl = new putfieldconstL();
+                pfcl.o = null;
+                assertTrue(pfcl.o + " != " + null, pfcl.o == null);
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit) {
+                putfieldconstC pfcc = new putfieldconstC();
+                pfcc.c = putfieldconstC.class;
+                assertTrue(pfcc.c + " != " + Class.forName("TestPatcher$putfieldconstC"), pfcc.c == Class.forName("TestPatcher$putfieldconstC"));
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        } catch (ClassNotFoundException t) {
+            fail(t.toString());
+        }
+    }
+
+    private void newarray() {
+        try {
+            if (doit) {
+                newarray[] na = new newarray[1];
+                na[0] = null;
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+    }
+
+    private void multianewarray() {
+        try {
+            if (doit) {
+                multianewarray[][] ma = new multianewarray[1][1];
+                ma[0][0] = null;
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+    }
+
+    private void invokespecial() {
+        try {
+            if (doit)
+                new invokespecial();
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+    }
+
+    private void checkcast() {
+        Object o = new Object();
+
+        // class
+        try {
+            if (doit) {
+                checkcastC cc = (checkcastC) o;
+                fail();
+            }
+        } catch (ClassCastException success) {
+            // This is OK.
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        // interface
+        try {
+            if (doit) {
+                checkcastI ci = (checkcastI) o;
+                fail();
+            }
+        } catch (ClassCastException success) {
+            // This is OK.
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+
+        // array
+        Object[] oa = new Object[1];
+
+        try {
+            if (doit) {
+                checkcastC[] cca = (checkcastC[]) oa;
+                fail();
+            }
+        } catch (ClassCastException e) {
+            // This is OK.
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+    }
+
+    private void _instanceof() {
+        Object o = new Object();
+
+        try {
+            if (doit)
+                if (o instanceof instanceofC)
+                    fail();
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+        try {
+            if (doit)
+                if (o instanceof instanceofI)
+                    fail();
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+
+
+        // array
+        Object[] oa = new Object[1];
+
+        try {
+            if (doit)
+                if (oa instanceof instanceofC[])
+                    fail();
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        }
+    }
+
+    private void aastoreconst() {
+        Class[] ca = new Class[1];
+
+        try {
+            if (doit) {
+                ca[0] = aastoreconstClass.class;
+
+                if (ca[0] == null)
+                    fail();
+
+                assertTrue(ca[0] + " != " + Class.forName("TestPatcher$aastoreconstClass") , ca[0] == Class.forName("TestPatcher$aastoreconstClass"));
+            }
+        } catch (NoClassDefFoundError t) {
+            fail(t.toString());
+        } catch (ClassNotFoundException t) {
+            fail(t.toString());
+        }
+    }
+
+    static class invokestatic  { static void sub() {} }
+    static class invokespecial { void invokespecial() {} }
+
+    static class getstaticI { static int    i = TestPatcher.i; }
+    static class getstaticJ { static long   l = TestPatcher.l; }
+    static class getstaticF { static float  f = TestPatcher.f; }
+    static class getstaticD { static double d = TestPatcher.d; }
+    static class getstaticL { static Object o = null; }
+
+    static class putstaticI { static int    i; }
+    static class putstaticJ { static long   l; }
+    static class putstaticF { static float  f; }
+    static class putstaticD { static double d; }
+    static class putstaticL { static Object o; }
+
+    static class putstaticconstI { static int    i; }
+    static class putstaticconstJ { static long   l; }
+    static class putstaticconstF { static float  f; }
+    static class putstaticconstD { static double d; }
+    static class putstaticconstL { static Object o; }
+    static class putstaticconstC { static Class<putstaticconstC> c; }
+
+    static class getfieldI { int    i = TestPatcher.i; }
+    static class getfieldJ { long   l = TestPatcher.l; }
+    static class getfieldF { float  f = TestPatcher.f; }
+    static class getfieldD { double d = TestPatcher.d; }
+    static class getfieldL { Object o = null; }
+
+    static class putfieldI { int    i; }
+    static class putfieldJ { long   l; }
+    static class putfieldF { float  f; }
+    static class putfieldD { double d; }
+    static class putfieldL { Object o; }
+
+    static class putfieldconstI { int    i; }
+    static class putfieldconstJ { long   l; }
+    static class putfieldconstF { float  f; }
+    static class putfieldconstD { double d; }
+    static class putfieldconstL { Object o; }
+    static class putfieldconstC { Class<putfieldconstC> c; }
+
+    static class newarray {}
+    static class multianewarray {}
+
+    static class instanceofC {}
+    static interface instanceofI {}
+
+    static class checkcastC {}
+    static interface checkcastI {}
+
+    static class aastoreconstClass {}
+}
index 408a13e49105237cb1a0dfea5e5a7a062b71cd18..8a0d134dc1b15c2516cee04546917db0f56072f0 100644 (file)
@@ -1,9 +1,7 @@
 ## src/tests/regression/native/Makefile.am
 ##
-## 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.
 ##
 ## 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
 
 
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR) -I$(top_builddir)
 
-JAVA      = $(top_builddir)/src/cacao/cacao
-
-if WITH_CLASSPATH_GNU
-JAVAFLAGS = -Xbootclasspath:$(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
-else
-JAVAFLAGS = -Xbootclasspath:$(CLASSPATH_CLASSES)
-endif
-
-JAVAH     = @CACAOH@
+JAVA     = $(top_builddir)/src/cacao/cacao
+JAVAH    = $(CACAOH)
+JAVACMD  = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
+JAVAHCMD = $(JAVAH) -bootclasspath $(BOOTCLASSPATH)
 
 SOURCE_FILES = \
        checkjni.java \
@@ -68,10 +58,10 @@ TESTNAMES = \
 check: $(TESTNAMES)
 
 $(TESTNAMES) $(NOTESTNAMES):
-       @$(JAVAC) -nowarn -d . $(srcdir)/$@.java
-       @$(JAVAH) $@
-       @$(CC) -shared $(AM_CPPFLAGS) $(CFLAGS) $(srcdir)/$@.c -o lib$@.so -fPIC
-       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs:. $(SHELL) $(srcdir)/../Test.sh "$(JAVA) $(JAVAFLAGS)" $@ $(srcdir)
+       @$(JAVACCMD) -d . $(srcdir)/$@.java
+       @$(JAVAHCMD) $@
+       @$(CC) -shared $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(srcdir)/$@.c -o lib$@.so -fPIC
+       @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs:. $(SHELL) $(srcdir)/../Test.sh "$(JAVACMD)" $@ $(srcdir)
 
 
 ## Local variables:
index 91f45fcfeaa1c88eb1a6cd4006fd5a0312f6ae0d..34bcb1fd14e0e33ff3e76df37d1433d8c10374cc 100644 (file)
@@ -1,9 +1,7 @@
 ## tests/regression/resolving/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
+## Copyright (C) 2007, 2008
+## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 ##
 ## This file is part of CACAO.
 ##
@@ -28,6 +26,10 @@ SUBDIRS = \
        classes2 \
        classes3
 
+JAVA     = $(top_builddir)/src/cacao/cacao
+JAVACMD  = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
+
 HARNESS_SOURCE_FILES = \
        $(srcdir)/TestController.java \
        $(srcdir)/TestLoader.java
@@ -61,17 +63,8 @@ EXTRA_DIST = $(HARNESS_SOURCE_FILES) $(TEST_SOURCE_FILES)
 CLEANFILES = \
        *.class
 
-JAVA      = $(top_builddir)/src/cacao/cacao
-
-if WITH_CLASSPATH_GNU
-JAVAFLAGS = -Xbootclasspath:$(top_builddir)/src/lib/classes/:$(CLASSPATH_CLASSES)
-else
-JAVAFLAGS = -Xbootclasspath:$(CLASSPATH_CLASSES)
-endif
-
 check: $(HARNESS_CLASS_FILES)
-       @for t in $(TEST_NAMES) ; do echo "TEST $$t" ; { $(JAVAC) -d . -classpath . $(srcdir)/$$t.java && LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(JAVA) $(JAVAFLAGS) $$t ; } || exit 1 ; done
+       @for t in $(TEST_NAMES) ; do echo "TEST $$t" ; { $(JAVACCMD) -d . -classpath . $(srcdir)/$$t.java && LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(JAVACMD) $$t ; } || exit 1 ; done
 
 $(HARNESS_CLASS_FILES): $(HARNESS_SOURCE_FILES)
-       $(JAVAC) -d . $(HARNESS_SOURCE_FILES)
-
+       $(JAVACCMD) -d . $(HARNESS_SOURCE_FILES)
index 478482c46451d76d5166f6f786cacb7197cdb2b8..8bd181a0472dcdfffb439889e1aaf151ac66409a 100644 (file)
@@ -31,6 +31,10 @@ public class TestController {
                 && ((loader2_ == ld2) || ((loader2_ != null) && (ld2 != null) && loader2_.equals(ld2)))
                 && class_.equals(cls);
         }
+
+        public String toString() {
+            return tag_ + ": " + loader1_ + " " + loader2_ + " class=" + class_;
+        }
     }
 
     public void setReportClassIDs(boolean rep) {
@@ -63,18 +67,24 @@ public class TestController {
         expect("loaded", loader, "<" + classname + ">");
     }
 
-    public void expectDelegationAndDefinition(ClassLoader loader1, ClassLoader loader2, String classname) {
+    public void expectDelegation(ClassLoader loader1, ClassLoader loader2, String classname) {
         expect("requested", loader1, classname);
         expect("delegated", loader1, loader2, classname);
         expect("requested", loader2, classname);
+    }
+
+    public void expectDelegationDefinition(ClassLoader loader1, ClassLoader loader2, String classname) {
         expect("defined", loader2, "<" + classname + ">");
         expect("loaded", loader1, "<" + classname + ">");
     }
 
+    public void expectDelegationAndDefinition(ClassLoader loader1, ClassLoader loader2, String classname) {
+        expectDelegation(loader1, loader2, classname);
+        expectDelegationDefinition(loader1, loader2, classname);
+    }
+
     public void expectDelegationAndFound(ClassLoader loader1, ClassLoader loader2, String classname) {
-        expect("requested", loader1, classname);
-        expect("delegated", loader1, loader2, classname);
-        expect("requested", loader2, classname);
+        expectDelegation(loader1, loader2, classname);
         expect("found", loader2, "<" + classname + ">");
         expect("loaded", loader1, "<" + classname + ">");
     }
@@ -92,6 +102,11 @@ public class TestController {
         fail(message + ": " + tag + " " + ld1 + " " + ld2 + " class=" + cls);
     }
 
+    void fail(String message, String tag, String ld1, String ld2, String cls, Expectation exp) {
+        fail(message + ": " + tag + " " + ld1 + " " + ld2 + " class=" + cls
+             + " (expected " + exp.toString() + ")");
+    }
+
     void ok(String tag, String ld1, String ld2, String cls) {
         ok(tag + " " + ld1 + " " + ld2 + " class=" + cls);
     }
@@ -143,7 +158,7 @@ public class TestController {
                 ok(tag, ld1, ld2, cls);
             }
             else {
-                fail("unexpected", tag, ld1, ld2, cls);
+                fail("unmatched", tag, ld1, ld2, cls, exp);
             }
         }
     }
index 875dd9da090bdec2131a6ba1bb449312aebf7b01..f58cc17fc767f5fd67a4884d682a5b83a9a5dc9e 100644 (file)
@@ -25,29 +25,29 @@ public class test_instance_subtype_violated {
         ld3.addParentDelegation("java.lang.String");
 
 
-        // loading BarPassFoo
+        // loading and linking BarPassFoo
         ct.expect("requested", ld2, "BarPassFoo");
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
         ct.expect("defined", ld2, "<BarPassFoo>");
         ct.expect("loaded", ld2, "<BarPassFoo>");
 
         Class cls = ct.loadClass(ld2, "BarPassFoo");
 
-        // linking BarPassFoo
-        ct.expectLoadFromSystem(ld2, "java.lang.Object");
-
         // executing BarPassFoo.passDerivedFooInstance: new DerivedFoo
-        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+        ct.expectDelegation(ld2, ld3, "DerivedFoo");
 
         // linking (ld3, DerivedFoo)
         ct.expect("requested", ld3, "Foo");
-        ct.expect("defined", ld3, "<Foo>");
         ct.expectLoadFromSystem(ld3, "java.lang.Object");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectDelegationDefinition(ld2, ld3, "DerivedFoo");
 
         // resolving Foo.virtualId
         // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
-        ct.expectDelegationAndDefinition(ld2, ld1, "Foo");
+        ct.expectDelegation(ld2, ld1, "Foo");
         // ...linking (ld2, Foo) == (ld1, Foo)
         ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        ct.expectDelegationDefinition(ld2, ld1, "Foo");
 
         // the subtype constraint ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is violated
         ct.expect("exception", "java.lang.LinkageError", "<BarPassFoo>");
index e4c734be4accab7ad379b894a4d42c0822aab95a..7d9c184d3d0d0f8e5998301167b5d5e6ca98ac84 100644 (file)
@@ -18,24 +18,23 @@ public class test_param_loading_constraint_violated {
         ld2.addParentDelegation("java.lang.String");
 
 
-        // loading BarPassFoo
+        // loading & linking BarPassFoo
         ct.expect("requested", ld2, "BarPassFoo");
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
         ct.expect("defined", ld2, "<BarPassFoo>");
         ct.expect("loaded", ld2, "<BarPassFoo>");
 
         Class cls = ct.loadClass(ld2, "BarPassFoo");
 
-        // linking BarPassFoo
-        ct.expectLoadFromSystem(ld2, "java.lang.Object");
-
         // executing BarPassFoo.passit: new Foo
         ct.expect("requested", ld2, "Foo");
         ct.expect("defined", ld2, "<Foo>");
 
         // executing BarPassFoo.passit: new BarUseFoo
-        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+        ct.expectDelegation(ld2, ld1, "BarUseFoo");
         // ...linking BarUseFoo
         ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        ct.expectDelegationDefinition(ld2, ld1, "BarUseFoo");
 
         // resolving Foo.virtualId() from BarUseFoo
         ct.expect("requested", ld1, "Foo");
index 8ed0ec8967e778ede60d6f9ebbaaa16f940ce7a9..c98066079d58881bb736aadf39c55f204442e264 100644 (file)
@@ -25,29 +25,29 @@ public class test_param_loading_constraint_violated_derived {
         ld3.addParentDelegation("java.lang.String");
 
 
-        // loading BarPassFoo
+        // loading & linking BarPassFoo
         ct.expect("requested", ld2, "BarPassFoo");
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
         ct.expect("defined", ld2, "<BarPassFoo>");
         ct.expect("loaded", ld2, "<BarPassFoo>");
 
         Class cls = ct.loadClass(ld2, "BarPassFoo");
 
-        // linking BarPassFoo
-        ct.expectLoadFromSystem(ld2, "java.lang.Object");
-
         // executing BarPassFoo.passDerivedFoo: new DerivedFoo
-        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+        ct.expectDelegation(ld2, ld3, "DerivedFoo");
 
         // linking (ld3, DerivedFoo)
         ct.expect("requested", ld3, "Foo");
-        ct.expect("defined", ld3, "<Foo>");
         ct.expectLoadFromSystem(ld3, "java.lang.Object");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectDelegationDefinition(ld2, ld3, "DerivedFoo");
 
         // executing BarPassFoo.passit: new BarUseFoo
-        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+        ct.expectDelegation(ld2, ld1, "BarUseFoo");
 
         // linking BarUseFoo
         ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        ct.expectDelegationDefinition(ld2, ld1, "BarUseFoo");
 
         // resolving BarUseFoo.useFoo
         // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
index 254feda96d5b9118bda6040df03d74cd403a5659..7118c76d0ffe087bbc50599247fca15e7409e40f 100644 (file)
@@ -25,27 +25,27 @@ public class test_param_subtype_violated {
         ld3.addParentDelegation("java.lang.String");
 
 
-        // loading BarPassFoo
+        // loading & linking BarPassFoo
         ct.expect("requested", ld2, "BarPassFoo");
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
         ct.expect("defined", ld2, "<BarPassFoo>");
         ct.expect("loaded", ld2, "<BarPassFoo>");
 
         Class cls = ct.loadClass(ld2, "BarPassFoo");
 
-        // linking BarPassFoo
-        ct.expectLoadFromSystem(ld2, "java.lang.Object");
-
         // executing BarPassFoo.passDerivedFoo: new DerivedFoo
-        ct.expectDelegationAndDefinition(ld2, ld3, "DerivedFoo");
+        ct.expectDelegation(ld2, ld3, "DerivedFoo");
         // ...linking (ld3, DerivedFoo)
         ct.expect("requested", ld3, "Foo");
-        ct.expect("defined", ld3, "<Foo>");
         ct.expectLoadFromSystem(ld3, "java.lang.Object");
+        ct.expect("defined", ld3, "<Foo>");
+        ct.expectDelegationDefinition(ld2, ld3, "DerivedFoo");
 
         // executing BarPassFoo.passDerivedFoo: new BarUseFoo
-        ct.expectDelegationAndDefinition(ld2, ld1, "BarUseFoo");
+        ct.expectDelegation(ld2, ld1, "BarUseFoo");
         // ...linking BarUseFoo
         ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        ct.expectDelegationDefinition(ld2, ld1, "BarUseFoo");
 
         // resolving BarUseFoo.useFoo
         // the deferred subtype check ((ld2, DerivedFoo) subtypeof (ld2, Foo)) is done
index cec4f66ec8f1de7c8ae0d114c1d4c3eb7ab60456..ee4660897789a59733f2345c55583a20c321c62a 100644 (file)
@@ -17,22 +17,21 @@ public class test_return_subtype_ok {
         ld2.addParentDelegation("java.lang.Object");
         ld2.addParentDelegation("java.lang.String");
 
-        // loading BarPassFoo
+        // loading & linking BarPassFoo
         ct.expect("requested", ld2, "BarPassFoo");
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
         ct.expect("defined", ld2, "<BarPassFoo>");
         ct.expect("loaded", ld2, "<BarPassFoo>");
 
         Class cls = ct.loadClass(ld2, "BarPassFoo");
 
-        // linking BarPassFoo
-        ct.expectLoadFromSystem(ld2, "java.lang.Object");
-
         // executing createDerivedFoo
-        ct.expectDelegationAndDefinition(ld2, ld1, "DerivedFoo");
+        ct.expectDelegation(ld2, ld1, "DerivedFoo");
         // ...linking (ld2, DerivedFoo)
         ct.expect("requested", ld1, "Foo");
-        ct.expect("defined", ld1, "<Foo>");
         ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        ct.expect("defined", ld1, "<Foo>");
+        ct.expectDelegationDefinition(ld2, ld1, "DerivedFoo");
 
         ct.checkStringGetter(cls, "getDerivedFoo", "no exception");
         ct.expectEnd();
index f2dfb9c13fa08b8bb5c478219a0d4411f6a1150d..7b0f9a228333ce8cfa882a9a94bda8f47ef5a9d2 100644 (file)
@@ -17,22 +17,21 @@ public class test_return_subtype_violated {
         ld2.addParentDelegation("java.lang.Object");
         ld2.addParentDelegation("java.lang.String");
 
-        // loading BarPassFoo
+        // loading & linking BarPassFoo
         ct.expect("requested", ld2, "BarPassFoo");
+        ct.expectLoadFromSystem(ld2, "java.lang.Object");
         ct.expect("defined", ld2, "<BarPassFoo>");
         ct.expect("loaded", ld2, "<BarPassFoo>");
 
         Class cls = ct.loadClass(ld2, "BarPassFoo");
 
-        // linking BarPassFoo
-        ct.expectLoadFromSystem(ld2, "java.lang.Object");
-
         // executing createDerivedFoo
-        ct.expectDelegationAndDefinition(ld2, ld1, "DerivedFoo");
+        ct.expectDelegation(ld2, ld1, "DerivedFoo");
         // ...linking (ld2, DerivedFoo)
         ct.expect("requested", ld1, "Foo");
-        ct.expect("defined", ld1, "<Foo>");
         ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        ct.expect("defined", ld1, "<Foo>");
+        ct.expectDelegationDefinition(ld2, ld1, "DerivedFoo");
 
         ct.checkStringGetter(cls, "getDerivedFoo", "no exception");
         ct.expectEnd();
index 8893a7f5484a15a5e4d468157d814f1f189a0433..9371090633c09e45f86b8de4a0648c1763da2670 100644 (file)
@@ -18,20 +18,19 @@ public class test_retval_loading_constraint_violated {
         ld2.addParentDelegation("java.lang.String");
 
 
-        // loading BarUseFoo
+        // loading & linking BarUseFoo
         ct.expect("requested", ld1, "BarUseFoo");
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
         ct.expect("defined", ld1, "<BarUseFoo>");
         ct.expect("loaded", ld1, "<BarUseFoo>");
 
         Class cls = ct.loadClass(ld1, "BarUseFoo");
 
-        // linking BarUseFoo
-        ct.expectLoadFromSystem(ld1, "java.lang.Object");
-
         // executing BarUseFoo.useReturnedFoo: new BarPassFoo
-        ct.expectDelegationAndDefinition(ld1, ld2, "BarPassFoo");
+        ct.expectDelegation(ld1, ld2, "BarPassFoo");
         // ...linking BarPassFoo
         ct.expectLoadFromSystem(ld2, "java.lang.Object");
+        ct.expectDelegationDefinition(ld1, ld2, "BarPassFoo");
 
         // resolving BarPassFoo.createFoo
         ct.expect("requested", ld2, "Foo");
index 30ca610095c69a1f85da41d8aa54f82819584c73..be1e7b3fa83e618a95dca0c6d7523ef4adec4de3 100644 (file)
@@ -6,14 +6,14 @@ public class test_simple_lazy_load {
         TestLoader ld1 = new TestLoader(ClassLoader.getSystemClassLoader(), "ld1", ct);
 
         ld1.addClassfile("BarUseFoo", "classes1/BarUseFoo.class");
+        ld1.addParentDelegation("java.lang.Object");
+
         ct.expect("requested", ld1, "BarUseFoo");
+        ct.expectLoadFromSystem(ld1, "java.lang.Object");
         ct.expect("defined", ld1, "<BarUseFoo>");
         ct.expect("loaded", ld1, "<BarUseFoo>");
-        Class cls = ct.loadClass(ld1, "BarUseFoo");
-        ct.expectEnd();
 
-        ld1.addParentDelegation("java.lang.Object");
-        ct.expectLoadFromSystem(ld1, "java.lang.Object");
+        Class cls = ct.loadClass(ld1, "BarUseFoo");
         ct.checkClassId(cls, "classes1/BarUseFoo");
         ct.expectEnd();
 
diff --git a/tests/scribble.java b/tests/scribble.java
deleted file mode 100644 (file)
index 21dfac6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-import java.applet.*;
-import java.awt.*;
-
-public class scribble extends Applet {
-   private int last_x=0;
-   private int last_y=0;
-
-
-    public void init()
-    {
-       this.setBackground(Color.white);
-    }
-
-
-    public boolean mouseDown(Event e, int x, int y)
-    {
-       last_x = x; last_y=y; 
-       return true;
-    }
-
-    public boolean mouseDrag(Event e, int x, int y)
-    {
-       Graphics g = getGraphics();
-       g.setColor (Color.black);
-       g.drawLine(last_x,last_y,x,y);
-       last_x=x; last_y=y;
-       return true;
-    }
-}
diff --git a/tests/threads/threadInterrupt.java b/tests/threads/threadInterrupt.java
new file mode 100644 (file)
index 0000000..cbff113
--- /dev/null
@@ -0,0 +1,78 @@
+// This test has been added because of a bug in CACAO that allowed threads
+// blocked inside monitorenter to be interrupted. In the presence of the bug,
+// the program would not exit.
+//
+// The bug has been fixed as part of the sable lock implementation.
+// hg revision 2988182011bb ff (Wed Feb 06 18:46:34 2008 +0100)
+
+public class threadInterrupt {
+       public static class firstthread implements Runnable {
+               private threadInterrupt s;
+
+               public firstthread(threadInterrupt s_) {
+                       s = s_;
+               }
+               public void run() {
+                       try {
+                               synchronized (s.o1) {
+                                       System.out.println("first thread!");
+                                       Thread.sleep(500);
+                                       System.out.println("interrupting");
+                                       s.t2.interrupt();
+                                       System.out.println("leaving");
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public static class secondthread implements Runnable {
+               private threadInterrupt s;
+
+               public secondthread(threadInterrupt s_) {
+                       s = s_;
+               }
+               public void run() {
+                       try {
+                               Thread.sleep(250);
+                               synchronized (s.o1) {
+                                       System.out.println("second thread!");
+                                       s.o1.wait();
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public Object o1 = new Object();
+       public Thread t1 = null;
+       public Thread t2 = null;
+
+       public static void main(String args[]) {
+               System.out.println("should exit with java.lang.InterruptedException");
+               threadInterrupt s = new threadInterrupt();
+               firstthread r1 = new firstthread(s);
+               secondthread r2 = new secondthread(s);
+
+               s.t1 = new Thread(r1, "a");
+               s.t2 = new Thread(r2, "b");
+               s.t1.start();
+               s.t2.start();
+       }
+}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: java
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/tests/threads/waitAndInterrupt.java b/tests/threads/waitAndInterrupt.java
new file mode 100644 (file)
index 0000000..6a1ac0b
--- /dev/null
@@ -0,0 +1,205 @@
+// This should run forever. If it stops, that's a good indication for a bug in
+// the VM.
+//
+// This test grew a bit more elaborate than anticipated...
+// It verifies that the JVM handles properly the case of a thread being
+// interrupted and notified at the same time.
+
+public class waitAndInterrupt {
+       private class semaphore {
+               private int v;
+               public semaphore(int v) {
+                       this.v = v;
+               }
+               public synchronized void semwait() {
+                       while (v == 0)
+                               try {
+                                       wait();
+                               } catch (InterruptedException e) {
+                               }
+                       v--;
+               }
+               public synchronized void sempost() {
+                       if (v == 0)
+                               notify();
+                       v++;
+               }
+       }
+
+       public static class firstthread implements Runnable {
+               private waitAndInterrupt s;
+
+               public firstthread(waitAndInterrupt s_) {
+                       s = s_;
+               }
+               public void run() {
+                       boolean iAmFirst = Thread.currentThread() == s.t1;
+                       try {
+                               int i = 0;
+                               int count_not = 0;
+                               int count_int = 0;
+                               for (;;) {
+                                       if (iAmFirst) {
+                                               if (++i == 100) {
+                                                       i = 0;
+                                                       System.out.println(Thread.currentThread().getName() + " still running, notified " + Integer.toString(count_not) + ", interrupted " + Integer.toString(count_int));
+                                               }
+                                               synchronized (s) {
+                                                       s.sem1.sempost();
+                                                       try {
+                                                               while (!s.notified)
+                                                                       s.wait();
+                                                               try {
+                                                                       s.wait();
+                                                               } catch (InterruptedException e) {
+                                                                       s.notify(); // wake t2
+                                                               }
+                                                               count_not++;
+                                                       } catch (InterruptedException e) {
+                                                               count_int++;
+                                                       }
+                                               }
+
+                                               s.sem5.sempost();
+                                               s.sem8.semwait();
+                                       } else {
+                                               s.sem1.semwait();
+                                               if (++i == 100) {
+                                                       i = 0;
+                                                       System.out.println(Thread.currentThread().getName() + " still running");
+                                               }
+                                               synchronized (s) {
+                                                       s.sem2.sempost();
+                                                       try {
+                                                               while (!s.notified)
+                                                                       s.wait();
+                                                               s.notified = false;
+                                                               count_not++;
+                                                       } catch (InterruptedException e) {
+                                                               count_int++;
+                                                       }
+                                               }
+
+                                               s.sem6.sempost();
+                                       }
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public static class otherthread implements Runnable {
+               private waitAndInterrupt s;
+
+               public otherthread(waitAndInterrupt s_) {
+                       s = s_;
+               }
+               public void run() {
+                       boolean iAmFirst = Thread.currentThread() == s.t3;
+                       try {
+                               int i = 0;
+                               for (;;) {
+                                       if (iAmFirst) {
+                                               s.sem3.semwait();
+                                               if (++i == 100) {
+                                                       i = 0;
+                                                       System.out.println(Thread.currentThread().getName() + " still running");
+                                               }
+                                               synchronized (s) {
+                                                       s.sem4.sempost();
+                                               }
+                                               s.t1.interrupt();
+                                               s.sem5.semwait();
+                                       } else {
+                                               s.sem4.semwait();
+                                               if (++i == 100) {
+                                                       i = 0;
+                                                       System.out.println(Thread.currentThread().getName() + " still running");
+                                               }
+                                               synchronized (s) {
+                                                       if (s.notified)
+                                                               System.out.println("shouldn't happen (1)");
+                                                       s.notified = true;
+                                                       s.notify();
+                                               }
+                                               s.sem6.semwait();
+                                       }
+                                       s.sem7.sempost();
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public static class controlthread implements Runnable {
+               private waitAndInterrupt s;
+
+               public controlthread(waitAndInterrupt s_) {
+                       s = s_;
+               }
+               public void run() {
+                       try {
+                               for (;;) {
+                                       s.sem2.semwait();
+                                       synchronized (s) {
+                                       }
+                                       s.sem3.sempost();
+                                       s.sem7.semwait();
+                                       s.sem7.semwait();
+                                       s.sem8.sempost(); // wake first
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public Thread t1 = null;
+       public Thread t2 = null;
+       public Thread t3 = null;
+       public Thread t4 = null;
+       public semaphore sem1 = new semaphore(0);
+       public semaphore sem2 = new semaphore(0);
+       public semaphore sem3 = new semaphore(0);
+       public semaphore sem4 = new semaphore(0);
+       public semaphore sem5 = new semaphore(0);
+       public semaphore sem6 = new semaphore(0);
+       public semaphore sem7 = new semaphore(0);
+       public semaphore sem8 = new semaphore(0);
+       public boolean notified = false;
+
+       public static void main(String args[]) {
+               waitAndInterrupt s = new waitAndInterrupt();
+               firstthread r1 = new firstthread(s);
+               firstthread r2 = new firstthread(s);
+               otherthread r3 = new otherthread(s);
+               controlthread r5 = new controlthread(s);
+
+               s.t1 = new Thread(r1, "a");
+               s.t2 = new Thread(r2, "b");
+               s.t3 = new Thread(r3, "c");
+               s.t4 = new Thread(r3, "d");
+               Thread t5 = new Thread(r5, "e");
+               s.t1.start();
+               s.t2.start();
+               s.t3.start();
+               s.t4.start();
+               t5.start();
+       }
+}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: java
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/tests/weakref.java b/tests/weakref.java
new file mode 100644 (file)
index 0000000..547c8e5
--- /dev/null
@@ -0,0 +1,71 @@
+import java.lang.ref.*;
+import java.util.HashSet;
+
+class weakref {
+       class OtherThread extends Thread {
+               public volatile boolean quitNow = false;
+               private final ReferenceQueue q;
+               private final HashSet h;
+               public OtherThread(ReferenceQueue q, HashSet h) {
+                       this.q = q;
+                       this.h = h;
+               }
+               public void run() {
+                       while (!quitNow) {
+                               try {
+                                       MyRef r = (MyRef) q.remove();
+                                       h.remove(r);
+                                       System.out.println("Integer: " + Integer.toString(r.val));
+                               } catch (InterruptedException e) {
+                               }
+                       }
+               }
+       }
+
+       class MyRef extends WeakReference {
+               public final int val;
+               MyRef(Object o, ReferenceQueue q, int val) {
+                       super(o, q);
+                       this.val = val;
+               }
+       }
+
+       private void test() {
+               System.out.println("This should print a long list of Integers if weak references are working.");
+               ReferenceQueue q = new ReferenceQueue();
+               HashSet h = new HashSet();
+               OtherThread t = new OtherThread(q, h);
+               t.start();
+               for (int i=0; i<1000000; i++) {
+                       Object o = new Integer(i);
+                       Reference r = new MyRef(o, q, i);
+                       h.add(r);
+               }
+               Runtime.getRuntime().gc();
+               try {
+                       Thread.sleep(1000);
+                       t.quitNow = true;
+                       t.interrupt();
+                       t.join();
+               } catch (InterruptedException e) {
+               }
+       }
+
+       public static void main(String[] args) {
+               new weakref().test();
+       }
+}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: java
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */