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
* 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)
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;
;;
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
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(cacao, 0.98+svn, cacao@cacaojvm.org)
+AC_INIT(cacao, 0.99rc5, cacao@cacaojvm.org)
AC_CONFIG_SRCDIR(src/cacao/cacao.c)
AC_CANONICAL_HOST
AC_PREREQ(2.59)
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])
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])
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])
dnl Now we check for jre-layout so we can skip some checks that are
dnl not required.
-AC_CHECK_WITH_JRE_LAYOUT
+AC_CHECK_ENABLE_JRE_LAYOUT
AC_CHECK_WITH_CLASSPATH_PREFIX
AC_CHECK_WITH_CLASSPATH_CLASSES
-if test x"${WITH_JRE_LAYOUT}" = "xno"; then
+if test x"${ENABLE_JRE_LAYOUT}" = "xno"; then
AC_CHECK_WITH_CLASSPATH_LIBDIR
fi
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
[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]
[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]
[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]
-# 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@
-# 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
@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@
#ifndef _VMLOG_CACAO_H_
#define _VMLOG_CACAO_H_
-#include <threads/native/threads.h>
-
void vmlog_cacao_init_options(void);
void vmlog_cacao_set_prefix(const char *arg);
## 02110-1301, USA.
-SUBDIRS = handbook
+SUBDIRS = \
+ doxygen \
+ handbook
-dist_noinst_DATA = assertions.tex 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 \
--- /dev/null
+# 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
--- /dev/null
+## 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:
dnl m4/cacaoh.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
AC_MSG_CHECKING(which cacaoh to use (for crosscompilation))
AC_ARG_WITH([cacaoh],
[AS_HELP_STRING(--with-cacaoh,which cacaoh to use [[default=$(top_builddir)/src/cacaoh/cacaoh]])],
- [CACAOH="${withval}"
- ENABLE_CACAOH=no
- ],
- [CACAOH=["\$(top_builddir)/src/cacaoh/cacaoh"
- ENABLE_CACAOH=yes
- ]])
+ [CACAOH="${withval}"],
+ [CACAOH=["\$(top_builddir)/src/cacaoh/cacaoh"]])
AC_MSG_RESULT(${CACAOH})
AC_SUBST(CACAOH)
-AM_CONDITIONAL([ENABLE_CACAOH], test x"${ENABLE_CACAOH}" = "xyes")
])
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}
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)
])
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}
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/include/linux,*:CLASSPATH_PREFIX/include)]])],
+ [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}/include/linux
+ WITH_JNI_MD_H=${CLASSPATH_PREFIX}/jdk/src/solaris/javavm/export
;;
*)
WITH_JNI_MD_H=${CLASSPATH_PREFIX}/include
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=CLASSPATH_PREFIX/include]])],
+ [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}],
- [WITH_JNI_H=${CLASSPATH_PREFIX}/include])
+ [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
--- /dev/null
+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])
+])
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
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})
])
DIST_SUBDIRS = \
cacao \
cacaoh \
+ classes \
fdlibm \
- lib \
mm \
native \
scripts \
vm \
vmcore
-if ENABLE_THREADS
-THREADS_DIR = \
- threads
-endif
-
-if ENABLE_CACAOH
-CACAOH_DIR = \
- cacaoh
-endif
-
# DON'T CHANGE THIS ORDER!!!
SUBDIRS = \
toolbox \
vmcore \
- $(CACAOH_DIR) \
- lib \
+ cacaoh \
+ classes \
native \
fdlibm \
mm \
- $(THREADS_DIR) \
+ threads \
vm \
cacao \
scripts
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
$(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
/* 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.
# include <ltdl.h>
#endif
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
# include <errno.h>
# include <libgen.h>
# include <unistd.h>
#if defined(ENABLE_JVMTI)
# include "native/jvmti/jvmti.h"
# include "native/jvmti/cacaodbg.h"
+# include "threads/mutex.h"
#endif
#include "vm/vm.h"
/* 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);
(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
## 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.
##
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) */
/* 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 "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 ***********************************************************/
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;
}
}
-methodinfo *code_get_methodinfo_for_pv(u1 *pv)
+methodinfo *code_get_methodinfo_for_pv(void *pv)
{
return NULL;
}
/* heap ***********************************************************************/
-void *heap_alloc_uncollectable(uint32_t bytelength)
+void *heap_alloc_uncollectable(size_t bytelength)
{
return calloc(bytelength, 1);
}
}
+/* 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();
{
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, ...)
/* 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.
/* 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: ");
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);
if (!(m->flags & ACC_STATIC)) {
fprintf(file, ", struct ");
- printID(m->class->name);
+ printID(m->clazz->name);
fprintf(file, "* this");
} else {
--- /dev/null
+## 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:
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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();
+}
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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 >= 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 >= 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 >= 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 >= 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);
+ }
+
+}
--- /dev/null
+/* 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);
+
+}
--- /dev/null
+/* 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);
+
+}
--- /dev/null
+/* 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();
+
+}
--- /dev/null
+/* 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);
+ }
+ }
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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();
+
+}
--- /dev/null
+/* 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 "<modifier> <classname>(<paramtypes>)
+ * throws <exceptions>", 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();
+ }
+
+}
--- /dev/null
+/* 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 "<modifiers> <type>
+ * <class>.<fieldname>".<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();
+ }
+
+}
--- /dev/null
+/* 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 "<modifiers> <returntype>
+ * <methodname>(<paramtypes>) throws <exceptions>", 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();
+ }
+
+}
--- /dev/null
+/* 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><public|protected|private> 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;
+ }
+}
--- /dev/null
+/* 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();
+
+}
--- /dev/null
+/* 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();
+
+}
--- /dev/null
+/* 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();
+
+}
+
--- /dev/null
+/* 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();
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
+++ /dev/null
-## 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/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_JAVA_FILES_GNU_ANNOTATIONS = \
- $(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_JAVA_FILES_CLDC1_1 = \
- $(top_srcdir)/src/lib/cldc1.1/com/sun/cldchi/jvm/FileDescriptor.java
-
-BOOTCLASSPATH = $(top_builddir)/src/lib/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:
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* 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();
-}
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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);
-
-}
+++ /dev/null
-/* 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();
-
-}
+++ /dev/null
-/* 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);
- }
- }
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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();
-
-}
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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 "<modifier> <classname>(<paramtypes>)
- * throws <exceptions>", 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();
-}
+++ /dev/null
-/* 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 "<modifiers> <type>
- * <class>.<fieldname>".<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();
-}
+++ /dev/null
-/* 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 "<modifiers> <returntype>
- * <methodname>(<paramtypes>) throws <exceptions>", 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();
-}
+++ /dev/null
-/* 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();
-}
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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();
- }
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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();
-}
+++ /dev/null
-/*
- * 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);
- }
-}
## 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.
##
#include "config.h"
-#include "vm/types.h"
+
+#include <stdint.h>
#if defined(ENABLE_THREADS) && defined(__LINUX__)
#define GC_LINUX_THREADS
*******************************************************************************/
-void gc_init(u4 heapmaxsize, u4 heapstartsize)
+void gc_init(size_t heapmaxsize, size_t heapstartsize)
{
size_t heapcurrentsize;
}
-void *heap_alloc_uncollectable(u4 size)
+void *heap_alloc_uncollectable(size_t size)
{
void *p;
/* clear allocated memory region */
- MSET(p, 0, u1, size);
+ MSET(p, 0, uint8_t, size);
return p;
}
*******************************************************************************/
-void *heap_alloc(u4 size, u4 references, methodinfo *finalizer, bool collect)
+void *heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect)
{
void *p;
#if defined(ENABLE_RT_TIMING)
/* clear allocated memory region */
- MSET(p, 0, u1, size);
+ MSET(p, 0, uint8_t, size);
RT_TIMING_GET_TIME(time_end);
RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_GC_ALLOC);
}
-s8 gc_get_heap_size(void)
+int64_t gc_get_heap_size(void)
{
return GC_get_heap_size();
}
-s8 gc_get_free_bytes(void)
+int64_t gc_get_free_bytes(void)
{
return GC_get_free_bytes();
}
*******************************************************************************/
-s8 gc_get_total_bytes(void)
+int64_t gc_get_total_bytes(void)
{
return GC_get_total_bytes();
}
-s8 gc_get_max_heap_size(void)
+int64_t gc_get_max_heap_size(void)
{
return GC_get_max_heap_size();
}
#include "vm/types.h"
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "compact.h"
#include "copy.h"
#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");
}
#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;
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);
/* 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.
#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"
-/* 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.
#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;
}
}
- fe = list_next_unsynced(final_list, fe);
+ fe = list_next(final_list, fe);
}
#endif /*defined(GCCONF_FINALIZER)*/
#include "mm/memory.h"
#include "threads/threadlist.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
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)
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 */
}
/* 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 */
}
/* 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 */
-/* 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.
#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"
#include <sys/mman.h> /* REMOVEME */
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "mm/codememory.h"
#include "mm/memory.h"
#include "mm/dumpmemory.h"
#include "mm/memory.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "vmcore/options.h"
/* 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.
#define _GC_COMMON_H
#include "config.h"
-#include "vm/types.h"
#include <stdint.h>
/* function prototypes ********************************************************/
-void gc_init(u4 heapmaxsize, u4 heapstartsize);
+void gc_init(size_t heapmaxsize, size_t heapstartsize);
-void *heap_alloc_uncollectable(u4 size);
-void *heap_alloc(u4 size, u4 references, methodinfo *finalizer, bool collect);
-void heap_free(void *p);
+void* heap_alloc_uncollectable(size_t size);
+void* heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect);
+void heap_free(void *p);
#if defined(ENABLE_GC_CACAO)
-void heap_init_objectheader(java_object_t *o, u4 size);
-s4 heap_get_hashcode(java_object_t *o);
+void heap_init_objectheader(java_object_t *o, uint32_t size);
+int32_t heap_get_hashcode(java_object_t *o);
-void gc_reference_register(java_object_t **ref, int32_t reftype);
-void gc_reference_unregister(java_object_t **ref);
+void gc_reference_register(java_object_t **ref, int32_t reftype);
+void gc_reference_unregister(java_object_t **ref);
-void gc_weakreference_register(java_object_t **ref, int32_t reftype);
-void gc_weakreference_unregister(java_object_t **ref);
+void gc_weakreference_register(java_object_t **ref, int32_t reftype);
+void gc_weakreference_unregister(java_object_t **ref);
#endif
-void gc_call(void);
-s8 gc_get_heap_size(void);
-s8 gc_get_free_bytes(void);
-s8 gc_get_total_bytes(void);
-s8 gc_get_max_heap_size(void);
-void gc_invoke_finalizers(void);
-void gc_finalize_all(void);
-void *gc_out_of_memory(size_t bytes_requested);
+void gc_call(void);
+int64_t gc_get_heap_size(void);
+int64_t gc_get_free_bytes(void);
+int64_t gc_get_total_bytes(void);
+int64_t gc_get_max_heap_size(void);
+void gc_invoke_finalizers(void);
+void gc_finalize_all(void);
+void* gc_out_of_memory(size_t bytes_requested);
/* inlined functions **********************************************************/
#endif
}
-
#endif /* _GC_COMMON_H */
#include "native/native.h"
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
}
-void *mem_alloc(s4 size)
+void *mem_alloc(int32_t size)
{
void *m;
}
-void *mem_realloc(void *src, s4 len1, s4 len2)
+void *mem_realloc(void *src, int32_t len1, int32_t len2)
{
void *dst;
}
-void mem_free(void *m, s4 size)
+void mem_free(void *m, int32_t size)
{
if (!m) {
if (size == 0)
#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)))
void *memory_checked_alloc(size_t size);
-void *memory_cnew(s4 size);
-void memory_cfree(void *p, s4 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);
## 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.
##
## 02110-1301, USA.
+JAVAH = $(CACAOH)
+JAVAHCMD = $(JAVAH) -bootclasspath $(BOOTCLASSPATH)
+
COMMON_HEADER_FILES = \
java_lang_Class.h \
java_lang_Object.h \
gnu_classpath_Pointer.h \
gnu_classpath_Pointer32.h \
gnu_classpath_Pointer64.h \
+ gnu_java_lang_VMCPStringBuilder.h \
java_lang_VMObject.h \
+ java_lang_reflect_VMConstructor.h \
+ java_lang_reflect_VMField.h \
+ java_lang_reflect_VMMethod.h \
java_nio_DirectByteBufferImpl.h
if ENABLE_ANNOTATIONS
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:
#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
# 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/reflect.h"
#endif
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
}
-/* _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
{
#if defined(ENABLE_JAVASE)
utf *u;
- classloader *cl;
+ classloader_t *cl;
classinfo *c;
java_lang_Class *co;
*******************************************************************************/
-jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
+jclass jni_FindClass(JNIEnv *env, const char *name)
{
#if defined(ENABLE_JAVASE)
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. */
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;
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;
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 */
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);
}
*******************************************************************************/
-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();
-
- 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. */
+ TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
- (void) vm_call_method(m, o);
- }
+ exceptions_print_stacktrace();
}
*******************************************************************************/
-void _Jv_JNI_ExceptionClear(JNIEnv *env)
+void jni_ExceptionClear(JNIEnv *env)
{
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
exceptions_clear_exception();
}
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);
}
*******************************************************************************/
-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
*******************************************************************************/
-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
{ \
intern ret; \
\
- STATISTICS(jniinvokation()); \
+ TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
\
LLNI_CRITICAL_START; \
\
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; \
\
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);
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);
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);
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);
{
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);
{
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);
java_handle_t *a;
jsize size;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
a = (java_handle_t *) array;
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)
{ \
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; \
\
{ \
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; \
\
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;
+
+ TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
- ba = (java_handle_bytearray_t *) array;
+ if (isCopy != NULL) {
+ *isCopy = JNI_FALSE;
+ }
+
+ LLNI_CRITICAL_START;
- /* do the same as Kaffe does */
+ h = (java_handle_t*) array;
+ a = (java_array_t*) LLNI_UNWRAP(h);
+ ad = a->objheader.vftbl->arraydesc;
- bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
+ /* Sanity check. */
- return (void *) bp;
+ assert(ad != NULL);
+
+ data = (void*) (((intptr_t) a) + ad->dataoffset);
+
+ return data;
}
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;
}
# 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));
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)
jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
{
- int32_t status;
+ int status;
TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
+ if (vm_created == false)
+ return JNI_ERR;
+
status = vm_destroy(vm);
return status;
*******************************************************************************/
-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 (result == true) {
+ *p_env = _Jv_env;
+
+ return JNI_OK;
+ }
- if (!threads_attach_current_thread(vm_aargs, false))
- return JNI_ERR;
+ vm_aargs = (JavaVMAttachArgs *) thr_args;
- if (!localref_table_init())
- return JNI_ERR;
+ 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;
jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
{
- STATISTICS(jniinvokation());
+ int result;
- return jni_attach_current_thread(p_env, thr_args, false);
+ 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 result;
}
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. */
if (!localref_table_destroy())
return JNI_ERR;
- if (!threads_detach_thread(thread))
+ if (!threads_detach_thread(t))
return JNI_ERR;
#endif
{
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;
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;
}
_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,
_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,
_Jv_JNI_GetStringRegion,
_Jv_JNI_GetStringUTFRegion,
- _Jv_JNI_GetPrimitiveArrayCritical,
- _Jv_JNI_ReleasePrimitiveArrayCritical,
+ jni_GetPrimitiveArrayCritical,
+ jni_ReleasePrimitiveArrayCritical,
_Jv_JNI_GetStringCritical,
_Jv_JNI_ReleaseStringCritical,
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 */
/* 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"
#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>
*******************************************************************************/
jthread jvmti_get_current_thread() {
- return (jthread)(threads_get_current_threadobject())->o.thread;
+ return (jthread)(thread_get_current)->o.thread;
}
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);
/* add breakpoint*/
if (jvmtibrkpt->brk[sysbrk].count > 0) {
jvmtibrkpt->brk[sysbrk].count++;
- pthread_mutex_unlock(&dbgcomlock);
+ mutex_unlock(&dbgcomlock);
return;
}
dbgcom->addbrkpt = true;
} 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;
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)
/* todo: set breakpoint */
/* jvmtibrkpt.brk[jvmtibrkpt.num].orig = */
jvmtibrkpt->num++;
- pthread_mutex_unlock(&dbgcomlock);
+ mutex_unlock(&dbgcomlock);
fprintf (stderr,"add brk done\n");
}
*******************************************************************************/
void jvmti_cacaodbgserver_quit(){
- pthread_mutex_lock(&dbgcomlock);
+ mutex_lock(&dbgcomlock);
dbgcom->running--;
if (dbgcom->running == 0) {
__asm__ ("cacaodbgserver_quit:");
wait(NULL);
dbgcom = NULL;
}
- pthread_mutex_unlock(&dbgcomlock);
+ mutex_unlock(&dbgcomlock);
}
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;
}
}
}
- pthread_mutex_unlock(&dbgcomlock);
+ mutex_unlock(&dbgcomlock);
/* let cacaodbgserver get ready */
sleep(1);
} else {
dbgcom->running++;
- pthread_mutex_unlock(&dbgcomlock);
+ mutex_unlock(&dbgcomlock);
}
}
/* 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>
bool jvmti; /* jvmti agent */
-extern pthread_mutex_t dbgcomlock;
+extern mutex_t dbgcomlock;
jvmtiEnv* jvmti_new_environment();
void jvmti_set_phase(jvmtiPhase p);
/* 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.
#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"
#include "boehm-gc/include/gc.h"
#if defined(ENABLE_THREADS)
-#include "threads/native/threads.h"
#include <sched.h>
#include <pthread.h>
#endif
typedef struct _environment environment;
static environment *envs=NULL;
-pthread_mutex_t dbgcomlock;
+mutex_t dbgcomlock;
extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
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 */
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);
#if defined(ENABLE_THREADS)
- pthread_mutex_lock(&lock_global_pool_lock);
+ mutex_lock(&lock_global_pool_lock);
lrp=lock_global_pool;
lrp=lrp->header.next;
}
- pthread_mutex_unlock(&lock_global_pool_lock);
+ mutex_unlock(&lock_global_pool_lock);
#endif
/* 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.
#include <assert.h>
-#include "threads/threads-common.h"
+#include "threads/thread.h"
/* LLNI critical sections ******************************************************
/* 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
(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
#include "native/localref.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
/* some forward declarations **************************************************/
+#if !defined(NDEBUG)
static bool localref_check_uncleared();
+#endif
/* localref_table_init *********************************************************
/* 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;
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 */
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(" ... ");
/* 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) */
#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 */
*******************************************************************************/
#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 */
#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 */
*******************************************************************************/
-int native_library_load(JNIEnv *env, utf *name, classloader *cl)
+int native_library_load(JNIEnv *env, utf *name, classloader_t *cl)
{
#if defined(ENABLE_LTDL)
lt_dlhandle handle;
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 */
};
#if defined(ENABLE_LTDL)
lt_dlhandle native_library_open(utf *filename);
void native_library_close(lt_dlhandle handle);
-void native_library_add(utf *filename, classloader *loader, lt_dlhandle handle);
-hashtable_library_name_entry *native_library_find(utf *filename, classloader *loader);
-int native_library_load(JNIEnv *env, utf *name, classloader *cl);
+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);
reflect.c \
reflect.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
nativevm.c \
nativevm.h \
$(REFLECT_SOURCES) \
- \
- java_lang_Class.c \
- java_lang_Class.h \
- $(JAVA_LANG_REFLECT_CONSTRUCTOR_SOURCES) \
- $(JAVA_LANG_REFLECT_METHOD_SOURCES) \
$(SUN_MISC_UNSAFE_SOURCES)
libnativevm_la_LIBADD = \
/* 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.
#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 ************************************/
*/
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);
}
* 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);
}
* 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);
}
*/
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);
}
#include "native/include/java_lang_Thread.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
*/
JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_Thread_currentThread(JNIEnv *env, jclass clazz)
{
- java_lang_Thread *thread;
+ java_lang_Thread *to;
- thread = (java_lang_Thread *) threads_get_current_object();
+ to = (java_lang_Thread *) thread_get_current_object();
- return thread;
+ return to;
}
## 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
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 \
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 \
/* 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.
#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 ************************************/
*/
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;
}
*/
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;
*/
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;
}
/* 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.
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;
/* 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 */
-/* 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;
}
* 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:
+ */
-/* 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"
* 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;
* 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;
* 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;
-/* 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"
#include "native/include/gnu_classpath_jdwp_VMVirtualMachine.h"
#include "native/jvmti/jvmti.h"
#include "native/jvmti/VMjdwp.h"
-#include <string.h>
/*
* 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;
}
* 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;
* 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;
* 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))
* 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);
* 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))) {
* 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;
}
* 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 */
}
--- /dev/null
+/* 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:
+ */
/* 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.
#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 },
};
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... */
* 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!");
* 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;
}
* 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;
}
/* 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.
#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 },
};
* 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);
}
* 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);
}
* 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;
*/
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);
}
* 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;
* 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;
}
* 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;
}
* 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;
}
*/
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);
* 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);
}
*/
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
*/
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;
}
*/
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;
}
#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"
/* 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 },
};
* 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)
{
utf *utfname;
classinfo *c;
- classloader *loader;
+ classloader_t *loader;
java_lang_Class *o;
#if defined(ENABLE_JVMTI)
* 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;
* 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;
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" */
* 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;
* 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;
*/
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? */
#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
*/
JNIEXPORT int32_t JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *libname, java_lang_ClassLoader *loader)
{
- classloader *cl;
- utf *name;
+ classloader_t *cl;
+ utf *name;
cl = loader_hashtable_classloader_add((java_handle_t *) loader);
/* 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"
/* 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 },
};
* 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);
* 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;
#include "native/include/java_lang_Thread.h"
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "vm/exceptions.h"
#include "vm/stringlocal.h"
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
JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, java_lang_VMThread *this)
{
#if defined(ENABLE_THREADS)
- java_lang_Thread *thread;
- threadobject *t;
-
- LLNI_field_get_ref(this, thread, thread);
+ java_handle_t *h;
+ threadobject *t;
- t = (threadobject *) LLNI_field_direct(thread, vmThread)->vmdata;
+ h = (java_handle_t *) this;
+ t = thread_get_thread(h);
- return threads_thread_has_been_interrupted(t);
+ return thread_is_interrupted(t);
#else
return 0;
#endif
JNIEXPORT void JNICALL Java_java_lang_VMThread_suspend(JNIEnv *env, java_lang_VMThread *this)
{
#if defined(ENABLE_THREADS)
- java_lang_Thread *thread;
-
- LLNI_field_get_ref(this, thread, thread);
-
/* TODO Should we implement this or is it obsolete? */
#endif
}
JNIEXPORT void JNICALL Java_java_lang_VMThread_resume(JNIEnv *env, java_lang_VMThread *this)
{
#if defined(ENABLE_THREADS)
- java_lang_Thread *thread;
-
- LLNI_field_get_ref(this, thread, thread);
-
/* TODO Should we implement this or is it obsolete? */
#endif
}
JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, java_lang_VMThread *this, int32_t priority)
{
#if defined(ENABLE_THREADS)
- java_lang_Thread *thread;
- threadobject *t;
-
- LLNI_field_get_ref(this, thread, thread);
+ java_handle_t *h;
+ threadobject *t;
- t = (threadobject *) LLNI_field_direct(thread, vmThread)->vmdata;
+ h = (java_handle_t *) this;
+ t = thread_get_thread(h);
threads_set_thread_priority(t->tid, priority);
#endif
JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeStop(JNIEnv *env, java_lang_VMThread *this, java_lang_Throwable *t)
{
#if defined(ENABLE_THREADS)
- java_lang_Thread *thread;
-
- LLNI_field_get_ref(this, thread, thread);
-
/* TODO Should we implement this or is it obsolete? */
#endif
}
*/
JNIEXPORT java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv *env, jclass clazz)
{
- java_lang_Thread *thread;
+ java_lang_Thread *to;
- thread = (java_lang_Thread *) threads_get_current_object();
+ to = (java_lang_Thread *) thread_get_current_object();
- return thread;
+ return to;
}
JNIEXPORT int32_t JNICALL Java_java_lang_VMThread_interrupted(JNIEnv *env, jclass clazz)
{
#if defined(ENABLE_THREADS)
- return threads_check_if_interrupted_and_reset();
+ 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
JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMThread_getState(JNIEnv *env, java_lang_VMThread *this)
{
#if defined(ENABLE_THREADS)
- java_lang_Thread *thread;
- threadobject *t;
- utf *u;
- java_handle_t *o;
-
- LLNI_field_get_ref(this, thread, thread);
-
- t = (threadobject *) LLNI_field_direct(thread, vmThread)->vmdata;
+ 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;
+ }
- u = threads_thread_get_state(t);
o = javastring_new(u);
return (java_lang_String *) o;
#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"
*/
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_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;
}
*/
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);
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. */
/* 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;
}
/* 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;
+++ /dev/null
-/* 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:
- */
+++ /dev/null
-/* 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:
- */
+++ /dev/null
-/* 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:
- */
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
+++ /dev/null
-/* 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:
- */
+++ /dev/null
-/* 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:
- */
+++ /dev/null
-/* 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:
- */
+++ /dev/null
-/* 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:
- */
+++ /dev/null
-/* 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:
- */
+++ /dev/null
-/* 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:
- */
#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();
_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();
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)
_Jv_java_lang_Throwable_init();
#else
-
# error unknown Java configuration
-
#endif
-
- /* everything's ok */
-
- return true;
}
*******************************************************************************/
-bool nativevm_init(void)
+void nativevm_init(void)
{
#if defined(ENABLE_JAVASE)
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)
/* nothing to do */
#else
-
# error unknown Java configuration
-
#endif
-
- /* everything's ok */
-
- return true;
}
/* 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();
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();
void _Jv_sun_misc_Unsafe_init();
# else
-
# error unknown classpath configuration
-
# endif
#elif defined(ENABLE_JAVAME_CLDC1_1)
void _Jv_java_lang_Throwable_init();
#else
-
# error unknown Java configuration
-
#endif
#endif /* _NATIVEVM_H */
/* 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);
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);
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
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);
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
}
+/* 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 *********************************************
/* 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.
*/
+#ifndef _REFLECT_H
+#define _REFLECT_H
+
#include "config.h"
#include <stdint.h>
#include "native/jni.h"
#include "native/native.h"
-/* keep this order of the native includes */
+/* Keep this order of the native includes. */
#include "native/include/java_lang_String.h"
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(
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
## 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.
##
libnativevmcore.la
libnativevmcore_la_SOURCES = \
+ hpi.c \
+ hpi.h \
jvm.c
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
#include "native/include/sun_reflect_ConstantPool.h"
#endif
-#include "native/vm/java_lang_Class.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/threadlist.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
#include "toolbox/list.h"
#if !defined(NDEBUG)
-# define TRACEJVMCALLS(...) \
- do { \
- if (opt_TraceJVMCalls || opt_TraceJVMCallsVerbose) { \
- log_println(__VA_ARGS__); \
- } \
+# 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) \
} \
} while (0)
-# define PRINTJVMWARNINGS(...)
+# define PRINTJVMWARNINGS(x)
/* do { \ */
/* if (opt_PrintJVMWarnings) { \ */
-/* log_println(__VA_ARGS__); \ */
+/* log_println x; \ */
/* } \ */
/* } while (0) */
#else
-# define TRACEJVMCALLS(...)
+# define TRACEJVMCALLS(x)
+# define TRACEJVMCALLSENTER(x)
+# define TRACEJVMCALLSEXIT(x)
# define TRACEJVMCALLSVERBOSE(x)
-# define PRINTJVMWARNINGS(...)
+# define PRINTJVMWARNINGS(x)
#endif
jlong JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored)
{
- TRACEJVMCALLS("JVM_CurrentTimeMillis(env=%p, ignored=%p)", env, ignored);
+ TRACEJVMCALLS(("JVM_CurrentTimeMillis(env=%p, ignored=%p)", env, ignored));
return (jlong) builtin_currenttimemillis();
}
jlong JVM_NanoTime(JNIEnv *env, jclass ignored)
{
- TRACEJVMCALLS("JVM_NanoTime(env=%p, ignored=%p)", env, ignored);
+ TRACEJVMCALLS(("JVM_NanoTime(env=%p, ignored=%p)", env, ignored));
return (jlong) builtin_nanotime();
}
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;
void JVM_Halt(jint code)
{
- TRACEJVMCALLS("JVM_Halt(code=%d)", code);
+ TRACEJVMCALLS(("JVM_Halt(code=%d)", code));
/* vm_exit(code); */
vm_shutdown(code);
void JVM_GC(void)
{
- TRACEJVMCALLS("JVM_GC()");
+ TRACEJVMCALLS(("JVM_GC()"));
gc_call();
}
jlong JVM_TotalMemory(void)
{
- TRACEJVMCALLS("JVM_TotalMemory()");
+ TRACEJVMCALLS(("JVM_TotalMemory()"));
return gc_get_heap_size();
}
jlong JVM_FreeMemory(void)
{
- TRACEJVMCALLS("JVM_FreeMemory()");
+ TRACEJVMCALLS(("JVM_FreeMemory()"));
return gc_get_free_bytes();
}
jlong JVM_MaxMemory(void)
{
- TRACEJVMCALLS("JVM_MaxMemory()");
+ TRACEJVMCALLS(("JVM_MaxMemory()"));
return gc_get_max_heap_size();
}
jint JVM_ActiveProcessorCount(void)
{
- TRACEJVMCALLS("JVM_ActiveProcessorCount()");
+ TRACEJVMCALLS(("JVM_ActiveProcessorCount()"));
return system_processors_online();
}
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;
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(t, backtrace, ba);
+ LLNI_field_get_ref(to, backtrace, o);
+
+ ba = (java_handle_bytearray_t *) o;
if (ba == NULL)
return 0;
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 */
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 */
/* 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;
}
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);
}
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();
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;
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;
jobject JVM_Clone(JNIEnv* env, jobject handle)
{
- TRACEJVMCALLS("JVM_Clone(env=%p, handle=%p)", env, handle);
+ TRACEJVMCALLS(("JVM_Clone(env=%p, handle=%p)", env, handle));
return (jobject) builtin_clone(env, (java_handle_t *) handle);
}
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"));
}
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"));
}
jint JVM_GetLastErrorString(char *buf, int len)
{
- const char *s;
- int n;
-
- if (errno == 0) {
- return 0;
- }
- else {
- s = strerror(errno);
- n = strlen(s);
-
- if (n >= len)
- n = len - 1;
-
- strncpy(buf, s, n);
+ TRACEJVMCALLS(("JVM_GetLastErrorString(buf=%p, len=%d", buf, len));
- buf[n] = '\0';
-
- return n;
- }
+ return hpi_system->GetLastErrorString(buf, len);
}
char *JVM_NativePath(char *path)
{
- TRACEJVMCALLS("JVM_NativePath(path=%s)", path);
-
- /* XXX is this correct? */
+ TRACEJVMCALLS(("JVM_NativePath(path=%s)", path));
- return path;
+ return hpi_file->NativePath(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;
}
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);
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"));
}
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);
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);
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);
jstring JVM_GetClassName(JNIEnv *env, jclass cls)
{
- TRACEJVMCALLS("JVM_GetClassName(env=%p, cls=%p)", env, cls);
+ classinfo* c;
- return (jstring) _Jv_java_lang_Class_getName((java_lang_Class *) cls);
+ TRACEJVMCALLS(("JVM_GetClassName(env=%p, cls=%p)", env, cls));
+
+ c = LLNI_classinfo_unwrap(cls);
+
+ return (jstring) class_get_classname(c);
}
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);
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;
}
{
classinfo *c;
- TRACEJVMCALLS("JVM_IsInterface(env=%p, cls=%p)", env, cls);
+ TRACEJVMCALLS(("JVM_IsInterface(env=%p, cls=%p)", env, cls));
c = LLNI_classinfo_unwrap(cls);
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);
{
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);
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;
- TRACEJVMCALLS("JVM_DoPrivileged(env=%p, cls=%p, action=%p, context=%p, wrapException=%d)", env, cls, action, context, wrapException);
+ 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();
/* 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;
}
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
{
classinfo *c;
- TRACEJVMCALLS("JVM_IsArrayClass(env=%p, cls=%p)", env, cls);
+ TRACEJVMCALLS(("JVM_IsArrayClass(env=%p, cls=%p)", env, cls));
c = LLNI_classinfo_unwrap(cls);
{
classinfo *c;
- TRACEJVMCALLS("JVM_IsPrimitiveClass(env=%p, cls=%p)", env, cls);
+ TRACEJVMCALLS(("JVM_IsPrimitiveClass(env=%p, cls=%p)", env, cls));
c = LLNI_classinfo_unwrap(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);
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);
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);
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);
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);
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();
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();
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();
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();
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();
jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly)
{
- TRACEJVMCALLS("JVM_GetClassDeclaredFields(env=%p, ofClass=%p, publicOnly=%d)", env, 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);
- return (jobjectArray) _Jv_java_lang_Class_getDeclaredFields((java_lang_Class *) ofClass, publicOnly);
+ oa = class_get_declaredfields(c, publicOnly);
+
+ return (jobjectArray) oa;
}
jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)
{
- TRACEJVMCALLS("JVM_GetClassDeclaredMethods(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly);
+ classinfo *c;
+ java_handle_objectarray_t *oa;
- return (jobjectArray) _Jv_java_lang_Class_getDeclaredMethods((java_lang_Class *) ofClass, publicOnly);
+ 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;
}
jobjectArray JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)
{
- TRACEJVMCALLS("JVM_GetClassDeclaredConstructors(env=%p, ofClass=%p, publicOnly=%d)", env, 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) _Jv_java_lang_Class_getDeclaredConstructors((java_lang_Class *) ofClass, publicOnly);
+ return (jobjectArray) oa;
}
{
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);
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(
{
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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"));
{
int result;
- TRACEJVMCALLS("JVM_Open(fname=%s, flags=%d, mode=%d)", fname, flags, mode);
+ TRACEJVMCALLS(("JVM_Open(fname=%s, flags=%d, mode=%d)", fname, flags, mode));
- result = system_open(fname, flags, mode);
+ result = hpi_file->Open(fname, flags, mode);
if (result >= 0) {
return result;
jint JVM_Close(jint fd)
{
- TRACEJVMCALLS("JVM_Close(fd=%d)", fd);
+ TRACEJVMCALLS(("JVM_Close(fd=%d)", fd));
- return system_close(fd);
+ return hpi_file->Close(fd);
}
jint JVM_Read(jint fd, char *buf, jint nbytes)
{
- TRACEJVMCALLS("JVM_Read(fd=%d, buf=%p, nbytes=%d)", fd, buf, nbytes);
+ TRACEJVMCALLS(("JVM_Read(fd=%d, buf=%p, nbytes=%d)", fd, buf, nbytes));
- return system_read(fd, buf, nbytes);
+ return (jint) hpi_file->Read(fd, buf, nbytes);
}
jint JVM_Write(jint fd, char *buf, jint nbytes)
{
- TRACEJVMCALLS("JVM_Write(fd=%d, buf=%s, nbytes=%d)", fd, buf, nbytes);
+ TRACEJVMCALLS(("JVM_Write(fd=%d, buf=%s, nbytes=%d)", fd, buf, nbytes));
- return system_write(fd, buf, nbytes);
+ return (jint) hpi_file->Write(fd, buf, nbytes);
}
jint JVM_Available(jint fd, jlong *pbytes)
{
-#if defined(FIONREAD)
- int bytes;
- int result;
+ TRACEJVMCALLS(("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes));
- TRACEJVMCALLS("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes);
-
- *pbytes = 0;
-
- result = ioctl(fd, FIONREAD, &bytes);
-
- if (result < 0)
- return 0;
-
- *pbytes = bytes;
-
- return 1;
-#else
-# error FIONREAD not defined
-#endif
+ return hpi_file->Available(fd, 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) system_lseek(fd, (off_t) offset, whence);
+ return hpi_file->Seek(fd, (off_t) offset, 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 system_ftruncate(fd, length);
+ return hpi_file->SetLength(fd, length);
}
jint JVM_Sync(jint fd)
{
- TRACEJVMCALLS("JVM_Sync(fd=%d)", fd);
+ TRACEJVMCALLS(("JVM_Sync(fd=%d)", fd));
- return system_fsync(fd);
+ return hpi_file->Sync(fd);
}
void JVM_StartThread(JNIEnv* env, jobject jthread)
{
- TRACEJVMCALLS("JVM_StartThread(env=%p, jthread=%p)", env, jthread);
+ TRACEJVMCALLS(("JVM_StartThread(env=%p, jthread=%p)", env, jthread));
threads_thread_start((java_handle_t *) jthread);
}
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 = threadlist_first(); t != NULL; t = threadlist_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. */
java_handle_t *h;
threadobject *t;
- TRACEJVMCALLS("JVM_SetThreadPriority(env=%p, jthread=%p, prio=%d)", env, jthread, prio);
+ TRACEJVMCALLS(("JVM_SetThreadPriority(env=%p, jthread=%p, prio=%d)", env, jthread, prio));
h = (java_handle_t *) jthread;
-
- /* XXX this is just a quick hack */
-
- for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
- if (t->object == h)
- break;
- }
+ t = thread_get_thread(h);
/* The threadobject is null when a thread is created in Java. The
priority is set later during startup. */
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();
}
void JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis)
{
- TRACEJVMCALLS("JVM_Sleep(env=%p, threadClass=%p, millis=%ld)", env, threadClass, millis);
+ TRACEJVMCALLS(("JVM_Sleep(env=%p, threadClass=%p, millis=%ld)", env, threadClass, millis));
threads_sleep(millis, 0);
}
TRACEJVMCALLSVERBOSE(("JVM_CurrentThread(env=%p, threadClass=%p)", env, threadClass));
- o = threads_get_current_object();
+ o = thread_get_current_object();
return (jobject) o;
}
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);
}
{
java_handle_t *h;
threadobject *t;
+ jboolean interrupted;
- TRACEJVMCALLS("JVM_IsInterrupted(env=%p, jthread=%p, clear_interrupted=%d)", env, jthread, clear_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);
- /* XXX do something with clear_interrupted */
+ interrupted = thread_is_interrupted(t);
- /* XXX this is just a quick hack */
+ if (interrupted && clear_interrupted)
+ thread_set_interrupted(t, false);
- for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
- if (t->object == h)
- break;
- }
-
- return threads_thread_has_been_interrupted(t);
+ return interrupted;
}
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;
jobjectArray JVM_GetClassContext(JNIEnv *env)
{
- TRACEJVMCALLS("JVM_GetClassContext(env=%p)", env);
+ TRACEJVMCALLS(("JVM_GetClassContext(env=%p)", env));
return (jobjectArray) stacktrace_getClassContext();
}
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((java_handle_t *) name, false);
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();
{
java_handle_t *a;
- TRACEJVMCALLS("JVM_GetArrayLength(arr=%p)", arr);
+ TRACEJVMCALLS(("JVM_GetArrayLength(arr=%p)", arr));
a = (java_handle_t *) arr;
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;
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;
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();
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;
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();
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((java_handle_t *) ia);
+ /* We check here for exceptions thrown in array_length_get,
+ otherwise these exceptions get overwritten by the following
+ IllegalArgumentException. */
+
+ if (length < 0)
+ return NULL;
+
+ if ((length <= 0) || (length > /* MAX_DIM */ 255)) {
+ exceptions_throw_illegalargumentexception();
+ return NULL;
+ }
+
+ /* XXX This is just a quick hack to get it working. */
+
dims = MNEW(long, length);
for (i = 0; i < length; i++) {
jint JVM_InitializeSocketLibrary()
{
- log_println("JVM_InitializeSocketLibrary: IMPLEMENT ME!");
+ TRACEJVMCALLS(("JVM_InitializeSocketLibrary()"));
- return 0;
+ return hpi_initialize_socket_library();
}
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 system_socket(domain, type, protocol);
}
jint JVM_SocketClose(jint fd)
{
- TRACEJVMCALLS("JVM_SocketClose(fd=%d)", fd);
+ TRACEJVMCALLS(("JVM_SocketClose(fd=%d)", fd));
return system_close(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 system_shutdown(fd, howto);
}
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 system_listen(fd, 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 system_connect(fd, him, 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 system_accept(fd, him, (socklen_t *) len);
}
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 system_getsockname(fd, him, (socklen_t *) len);
}
int bytes;
int result;
- TRACEJVMCALLS("JVM_SocketAvailable(fd=%d, pbytes=%p)", fd, pbytes);
+ TRACEJVMCALLS(("JVM_SocketAvailable(fd=%d, pbytes=%p)", fd, pbytes));
*pbytes = 0;
jint JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen)
{
- TRACEJVMCALLS("JVM_GetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%p)", fd, level, optname, optval, optlen);
+ TRACEJVMCALLS(("JVM_GetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%p)", fd, level, optname, optval, optlen));
return system_getsockopt(fd, level, optname, optval, (socklen_t *) optlen);
}
jint JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen)
{
- TRACEJVMCALLS("JVM_SetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%d)", fd, level, optname, optval, optlen);
+ TRACEJVMCALLS(("JVM_SetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%d)", fd, level, optname, optval, optlen));
return system_setsockopt(fd, level, optname, optval, optlen);
}
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 system_gethostname(name, namelen);
+ return result;
}
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;
}
void JVM_UnloadLibrary(void* handle)
{
- TRACEJVMCALLS("JVM_UnloadLibrary(handle=%p)", handle);
+ TRACEJVMCALLS(("JVM_UnloadLibrary(handle=%p)", handle));
native_library_close(handle);
}
{
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;
}
jboolean JVM_IsSupportedJNIVersion(jint version)
{
- TRACEJVMCALLS("JVM_IsSupportedJNIVersion(version=%d)", version);
+ TRACEJVMCALLS(("JVM_IsSupportedJNIVersion(version=%d)", version));
return jni_version_check(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);
}
{
java_object_t *o;
- TRACEJVMCALLS("JVM_RawMonitorCreate()");
+ TRACEJVMCALLS(("JVM_RawMonitorCreate()"));
o = NEW(java_object_t);
JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon)
{
- TRACEJVMCALLS("JVM_RawMonitorDestroy(mon=%p)", mon);
+ TRACEJVMCALLS(("JVM_RawMonitorDestroy(mon=%p)", mon));
FREE(mon, java_object_t);
}
JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon)
{
- TRACEJVMCALLS("JVM_RawMonitorEnter(mon=%p)", mon);
+ TRACEJVMCALLS(("JVM_RawMonitorEnter(mon=%p)", mon));
(void) lock_monitor_enter((java_object_t *) mon);
JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon)
{
- TRACEJVMCALLS("JVM_RawMonitorExit(mon=%p)", mon);
+ TRACEJVMCALLS(("JVM_RawMonitorExit(mon=%p)", mon));
(void) lock_monitor_exit((java_object_t *) mon);
}
jobject JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)
{
- TRACEJVMCALLS("JVM_InvokeMethod(env=%p, method=%p, obj=%p, args0=%p)", env, method, obj, args0);
+ java_lang_reflect_Method *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;
- return (jobject) _Jv_java_lang_reflect_Method_invoke((java_lang_reflect_Method *) method, (java_lang_Object *) obj, (java_handle_objectarray_t *) args0);
+ 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)
{
- TRACEJVMCALLS("JVM_NewInstanceFromConstructor(env=%p, c=%p, args0=%p)", env, c, 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;
- return (jobject) _Jv_java_lang_reflect_Constructor_newInstance(env, (java_lang_reflect_Constructor *) c, (java_handle_objectarray_t *) args0);
+ 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;
}
jboolean JVM_SupportsCX8()
{
- TRACEJVMCALLS("JVM_SupportsCX8()");
+ TRACEJVMCALLS(("JVM_SupportsCX8()"));
/* IMPLEMENT ME */
void *JVM_GetManagement(jint version)
{
- TRACEJVMCALLS("JVM_GetManagement(version=%d)", version);
+ TRACEJVMCALLS(("JVM_GetManagement(version=%d)", version));
/* TODO We current don't support the management interface. */
methodinfo *m;
java_handle_objectarray_t *oa;
- TRACEJVMCALLS("JVM_GetEnclosingMethodInfo(env=%p, ofClass=%p)", env, ofClass);
+ TRACEJVMCALLS(("JVM_GetEnclosingMethodInfo(env=%p, ofClass=%p)", env, ofClass));
c = LLNI_classinfo_unwrap(ofClass);
if (oa == NULL)
return NULL;
- array_objectarray_element_set(oa, 0, (java_handle_t *) LLNI_classinfo_wrap(m->class));
+ 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));
{
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
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;
{
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;
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)
#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"
#include "vm/initialize.h"
#include "vm/stringlocal.h"
+#include "vmcore/system.h"
#include "vmcore/utf8.h"
{ "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 },
{ "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 },
};
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;
}
}
+#if 0
+/* OpenJDK 7 */
+
/*
* Class: sun/misc/Unsafe
* Method: setMemory
/* XXX Not sure this is correct. */
- MSET(p, value, uint8_t, length);
+ system_memset(p, value, length);
}
src = (void *) (((uint8_t *) srcBase) + srcOffset);
dest = (void *) (((uint8_t *) destBase) + destOffset);
- MCOPY(dest, src, uint8_t, length);
+ system_memcpy(dest, src, length);
+}
+#else
+/*
+ * Class: sun/misc/Unsafe
+ * Method: setMemory
+ * Signature: (JJB)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t bytes, int32_t value)
+{
+ size_t length;
+ void *p;
+
+ length = (size_t) bytes;
+
+ if ((length != (uint64_t) bytes) || (bytes < 0)) {
+ exceptions_throw_illegalargumentexception();
+ return;
+ }
+
+ p = (void *) (intptr_t) address;
+
+ /* XXX Not sure this is correct. */
+
+ system_memset(p, value, length);
}
+/*
+ * Class: sun/misc/Unsafe
+ * Method: copyMemory
+ * Signature: (JJJ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t srcAddress, int64_t destAddress, int64_t bytes)
+{
+ size_t length;
+ void *src;
+ void *dest;
+
+ if (bytes == 0)
+ return;
+
+ length = (size_t) bytes;
+
+ if ((length != (uint64_t) bytes) || (bytes < 0)) {
+ exceptions_throw_illegalargumentexception();
+ return;
+ }
+
+ src = (void *) (intptr_t) srcAddress;
+ dest = (void *) (intptr_t) destAddress;
+
+ system_memcpy(dest, src, length);
+}
+#endif
+
+
/*
* Class: sun/misc/Unsafe
* Method: freeMemory
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);
*/
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;
*/
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;
}
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
}
* 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
}
}
+/*
+ * 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
*/
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;
+ UNSAFE_GET_VOLATILE(int32_t);
+}
- p = (volatile int32_t *) (((uint8_t *) o) + offset);
- 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);
}
*/
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);
}
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 \
+ mutex.h \
threadlist.c \
threadlist.h \
- threads-common.c \
- threads-common.h
+ thread.c \
+ thread.h
+else
+libthreads_la_SOURCES =
+endif
libthreads_la_LIBADD = \
$(THREAD_LIB)
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 {
#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
--- /dev/null
+/* 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:
+ */
+++ /dev/null
-## 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:
+++ /dev/null
-/* 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:
- */
+++ /dev/null
-/* src/threads/native/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/threadlist.h"
-#include "threads/threads-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 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)
-{
- int result;
- 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 */
-
- result = pthread_mutex_init(&(lr->mutex), NULL);
- if (result != 0)
- vm_abort_errnum(result, "lock_record_new: pthread_mutex_init failed");
-
- 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)
-{
- int result;
-
- DEBUGLOCKS(("[lock_record_free : lr=%p]", (void *) lr));
-
- /* Destroy the mutex. */
-
- result = pthread_mutex_destroy(&(lr->mutex));
- if (result != 0)
- vm_abort_errnum(result, "lock_record_free: pthread_mutex_destroy failed");
-
-#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;
-}
-
-
-/*============================================================================*/
-/* 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);
- 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));
-}
-
-
-static threadobject *threads_lookup_thread_id(int index)
-{
- threadobject *t;
-
- threads_list_lock();
-
- for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
- if (t->state == THREAD_STATE_NEW)
- continue;
- if (t->index == index)
- break;
- }
-
- threads_list_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;
-
- pthread_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;
-
- pthread_mutex_unlock(&t_other->flc_lock);
-}
-
-static void notify_flc_waiters(threadobject *t, java_handle_t *o)
-{
- threadobject *current;
-
- pthread_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(¤t->flc_cond);
-
- current = current->flc_next;
- }
-
- t->flc_list = NULL;
- t->flc_bit = false;
- pthread_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;
- 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 = 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_unsynced(l); w != NULL; w = list_next_unsynced(l, w)) {
- /* signal the waiting thread */
-
- waitingthread = w->thread;
-
- /* We must skip threads which have already been notified or
- interrupted. They will remove themselves from the list. */
-
- if (waitingthread->signaled || waitingthread->interrupted)
- 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. 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. */
-
- 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;
- }
-
- /* 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:
- */
+++ /dev/null
-/* src/threads/native/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 "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:
- */
+++ /dev/null
-/* src/threads/native/threads.c - native threads support
-
- 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/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/threadlist.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__)
-# include <semaphore.h>
-#endif
-# if defined(__LINUX__)
-# define GC_LINUX_THREADS
-# elif defined(__IRIX__)
-# define GC_IRIX_THREADS
-# elif defined(__DARWIN__)
-# define GC_DARWIN_THREADS
-# endif
-# if defined(ENABLE_GC_BOEHM)
-# include "mm/boehm-gc/include/gc.h"
-# endif
-
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/cacaodbg.h"
-#endif
-
-#if defined(__DARWIN__)
-/* Darwin has no working semaphore implementation. This one is taken
- from Boehm-GC. */
-
-/*
- This is a very simple semaphore implementation for darwin. It
- is implemented in terms of pthreads calls so it isn't async signal
- safe. This isn't a problem because signals aren't used to
- suspend threads on darwin.
-*/
-
-static int sem_init(sem_t *sem, int pshared, int value)
-{
- if (pshared)
- assert(0);
-
- sem->value = value;
-
- 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 = 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)
-{
- pthread_mutex_lock(&suspend_ack_lock);
- pthread_cond_broadcast(&suspend_cond);
- pthread_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__)
- 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
-
-#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 = 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 */
-
- 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_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 */
-
- result = pthread_mutex_init(&t->flc_lock, NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
-
- result = pthread_cond_init(&t->flc_cond, NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
-
- result = pthread_mutex_init(&(t->waitmutex), NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
-
- result = pthread_cond_init(&(t->waitcond), NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
-
- result = pthread_mutex_init(&(t->suspendmutex), NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
-
- 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. */
-
- result = pthread_mutex_destroy(&(t->flc_lock));
-
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
-
- result = pthread_cond_destroy(&(t->flc_cond));
-
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
-
- result = pthread_mutex_destroy(&(t->waitmutex));
-
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
-
- result = pthread_cond_destroy(&(t->waitcond));
-
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
-
- result = pthread_mutex_destroy(&(t->suspendmutex));
-
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
-
- result = pthread_cond_destroy(&(t->suspendcond));
-
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
-}
-#endif
-
-
-/* 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)
-{
- int result;
-
- result = pthread_mutex_init(&stopworldlock, NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
-
- /* initialize exit mutex and condition (on exit we join all
- threads) */
-
- result = pthread_mutex_init(&mutex_join, NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
-
- 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 */
-
- result = pthread_mutex_init(&mutex_gc, NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
-#endif
-
- /* initialize the threads-list mutex */
-
- result = pthread_mutex_init(&mutex_threads_list, NULL);
- if (result != 0)
- vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
-
-#if !defined(HAVE___THREAD)
- result = pthread_key_create(&threads_current_threadobject_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_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)
-{
- int result;
-
- result = pthread_mutex_lock(&mutex_threads_list);
-
- if (result != 0)
- vm_abort_errnum(result, "threads_list_lock: pthread_mutex_lock failed");
-}
-
-
-/* threads_list_unlock *********************************************************
-
- Leave the threads list mutex.
-
-*******************************************************************************/
-
-void threads_list_unlock(void)
-{
- int result;
-
- result = pthread_mutex_unlock(&mutex_threads_list);
-
- if (result != 0)
- vm_abort_errnum(result, "threads_list_unlock: pthread_mutex_unlock failed");
-}
-
-
-/* threads_mutex_gc_lock *******************************************************
-
- Enter the global GC mutex.
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-void threads_mutex_gc_lock(void)
-{
- int result;
-
- result = pthread_mutex_lock(&mutex_gc);
-
- if (result != 0)
- vm_abort_errnum(result, "threads_mutex_gc_lock: pthread_mutex_lock failed");
-}
-#endif
-
-
-/* threads_mutex_gc_unlock *****************************************************
-
- Leave the global GC mutex.
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-void threads_mutex_gc_unlock(void)
-{
- int result;
-
- result = pthread_mutex_unlock(&mutex_gc);
-
- if (result != 0)
- vm_abort_errnum(result, "threads_mutex_gc_unlock: pthread_mutex_unlock failed");
-}
-#endif
-
-/* threads_mutex_join_lock *****************************************************
-
- Enter the join mutex.
-
-*******************************************************************************/
-
-void threads_mutex_join_lock(void)
-{
- int result;
-
- result = pthread_mutex_lock(&mutex_join);
-
- if (result != 0)
- vm_abort_errnum(result, "threads_mutex_join_lock: pthread_mutex_lock failed");
-}
-
-
-/* threads_mutex_join_unlock ***************************************************
-
- Leave the join mutex.
-
-*******************************************************************************/
-
-void threads_mutex_join_unlock(void)
-{
- int result;
-
- result = pthread_mutex_unlock(&mutex_join);
-
- if (result != 0)
- vm_abort_errnum(result, "threads_mutex_join_unlock: pthread_mutex_unlock failed");
-}
-
-
-/* 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;
-
- TRACESUBSYSTEMINITIALIZATION("threads_init");
-
- /* 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 = threadlist_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_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_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 = threadlist_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 (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 */
-
- 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);
- }
- }
-
- t->sleeping = false;
-
- /* release the waitmutex */
-
- pthread_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. */
-
- 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;
-
- pthread_mutex_lock(&thread->waitmutex);
-
- /* get interrupted flag */
-
- intr = thread->interrupted;
-
- /* reset interrupted flag */
-
- thread->interrupted = false;
-
- pthread_mutex_unlock(&thread->waitmutex);
-
- 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);
-
- threads_wait_with_timeout(thread, &wakeupTime);
-
- wasinterrupted = threads_check_if_interrupted_and_reset();
-
- 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:
- */
+++ /dev/null
-/* src/threads/native/threads.h - native 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 _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
-
- /* 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;
- pthread_mutex_t flc_lock; /* controlling access to these fields */
- pthread_cond_t flc_cond;
-
- /* 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 */
- 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 ***********************************************************/
-
-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);
-
-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);
-
-void 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:
- */
## 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:
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
+++ /dev/null
-/* src/threads/none/threads.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 _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
-
-
-/* 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
-
-
-/* inline functions ***********************************************************/
-
-inline static stackframeinfo_t *threads_get_current_stackframeinfo(void)
-{
- return _no_threads_stackframeinfo;
-}
-
-inline static void threads_get_current_stackframeinfo(stackframeinfo_t *sfi)
-{
- _no_threads_stackframeinfo = sfi;
-}
-
-#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:
- */
--- /dev/null
+## 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:
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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(¤t->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:
+ */
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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__)
+# include <semaphore.h>
+#endif
+# if defined(__LINUX__)
+# define GC_LINUX_THREADS
+# elif defined(__IRIX__)
+# define GC_IRIX_THREADS
+# elif defined(__DARWIN__)
+# define GC_DARWIN_THREADS
+# endif
+# if defined(ENABLE_GC_BOEHM)
+# include "mm/boehm-gc/include/gc.h"
+# endif
+
+#if defined(ENABLE_JVMTI)
+#include "native/jvmti/cacaodbg.h"
+#endif
+
+#if defined(__DARWIN__)
+/* Darwin has no working semaphore implementation. This one is taken
+ from Boehm-GC. */
+
+/*
+ This is a very simple semaphore implementation for darwin. It
+ is implemented in terms of pthreads calls so it isn't async signal
+ safe. This isn't a problem because signals aren't used to
+ suspend threads on darwin.
+*/
+
+static int sem_init(sem_t *sem, int pshared, int value)
+{
+ if (pshared)
+ assert(0);
+
+ sem->value = value;
+
+ mutex_init(&sem->mutex);
+
+ if (pthread_cond_init(&sem->cond, NULL) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int sem_post(sem_t *sem)
+{
+ mutex_lock(&sem->mutex);
+
+ sem->value++;
+
+ if (pthread_cond_signal(&sem->cond) < 0) {
+ mutex_unlock(&sem->mutex);
+ return -1;
+ }
+
+ mutex_unlock(&sem->mutex);
+
+ return 0;
+}
+
+static int sem_wait(sem_t *sem)
+{
+ mutex_lock(&sem->mutex);
+
+ while (sem->value == 0) {
+ pthread_cond_wait(&sem->cond, &sem->mutex);
+ }
+
+ sem->value--;
+
+ mutex_unlock(&sem->mutex);
+
+ return 0;
+}
+
+static int sem_destroy(sem_t *sem)
+{
+ if (pthread_cond_destroy(&sem->cond) < 0)
+ return -1;
+
+ mutex_destroy(&sem->mutex);
+
+ return 0;
+}
+#endif /* defined(__DARWIN__) */
+
+
+/* internally used constants **************************************************/
+
+/* CAUTION: Do not change these values. Boehm GC code depends on them. */
+#define STOPWORLD_FROM_GC 1
+#define STOPWORLD_FROM_CLASS_NUMBERING 2
+
+
+/* startupinfo *****************************************************************
+
+ Struct used to pass info from threads_start_thread to
+ threads_startup_thread.
+
+******************************************************************************/
+
+typedef struct {
+ threadobject *thread; /* threadobject for this thread */
+ functionptr function; /* function to run in the new thread */
+ sem_t *psem; /* signals when thread has been entered */
+ /* in the thread list */
+ sem_t *psem_first; /* signals when pthread_create has returned */
+} startupinfo;
+
+
+/* prototypes *****************************************************************/
+
+static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
+
+
+/******************************************************************************/
+/* GLOBAL VARIABLES */
+/******************************************************************************/
+
+/* the thread object of the current thread */
+/* This is either a thread-local variable defined with __thread, or */
+/* a thread-specific value stored with key threads_current_threadobject_key. */
+#if defined(HAVE___THREAD)
+__thread threadobject *thread_current;
+#else
+pthread_key_t thread_current_key;
+#endif
+
+/* global mutex for stop-the-world */
+static mutex_t stopworldlock;
+
+#if defined(ENABLE_GC_CACAO)
+/* global mutex for the GC */
+static mutex_t mutex_gc;
+#endif
+
+/* global mutex and condition for joining threads on exit */
+static mutex_t mutex_join;
+static pthread_cond_t cond_join;
+
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
#include "mm/memory.h"
+#include "threads/mutex.h"
#include "threads/threadlist.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/list.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;
{
TRACESUBSYSTEMINITIALIZATION("threadlist_init");
+ /* Initialize the thread list mutex. */
+
+ mutex_init(&threadlist_mutex);
+
/* Initialize the thread lists. */
list_thread = list_create(OFFSET(threadobject, 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.
void threadlist_add(threadobject *t)
{
- list_add_last_unsynced(list_thread, t);
+ list_add_last(list_thread, t);
}
void threadlist_remove(threadobject *t)
{
- list_remove_unsynced(list_thread, t);
+ list_remove(list_thread, t);
}
{
threadobject *t;
- t = list_first_unsynced(list_thread);
+ t = list_first(list_thread);
return t;
}
-/* threads_list_next ***********************************************************
+/* threadlist_next *************************************************************
Return the next entry in the thread list.
{
threadobject *next;
- next = list_next_unsynced(list_thread, t);
+ next = list_next(list_thread, t);
return next;
}
void threadlist_free_add(threadobject *t)
{
- list_add_last_unsynced(list_thread_free, t);
+ list_add_last(list_thread_free, t);
}
void threadlist_free_remove(threadobject *t)
{
- list_remove_unsynced(list_thread_free, t);
+ list_remove(list_thread_free, t);
}
{
threadobject *t;
- t = list_first_unsynced(list_thread_free);
+ t = list_first(list_thread_free);
return t;
}
threadobject *t;
int nondaemons;
- /* Lock the threads lists. */
+ /* Lock the thread lists. */
- threads_list_lock();
+ threadlist_lock();
nondaemons = 0;
for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
- if (!(t->flags & THREAD_FLAG_DAEMON))
+ if (!thread_is_daemon(t))
nondaemons++;
}
- /* Unlock the threads lists. */
+ /* Unlock the thread lists. */
- threads_list_unlock();
+ threadlist_unlock();
return nondaemons;
}
{
thread_index_t *ti;
- ti = list_first_unsynced(list_thread_index_free);
+ ti = list_first(list_thread_index_free);
return ti;
}
ti->index = index;
- list_add_last_unsynced(list_thread_index_free, ti);
+ list_add_last(list_thread_index_free, ti);
}
static inline void threadlist_index_remove(thread_index_t *ti)
{
- list_remove_unsynced(list_thread_index_free, ti);
+ list_remove(list_thread_index_free, ti);
FREE(ti, thread_index_t);
#include <stdint.h>
-#include "threads/threads-common.h"
+#include "threads/thread.h"
/* function prototypes ********************************************************/
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 */
+++ /dev/null
-/* src/threads/threads-common.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/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/threadlist.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 ***********************************************************/
-
-#if defined(__LINUX__)
-/* XXX Remove for exact-GC. */
-bool threads_pthreads_implementation_nptl;
-#endif
-
-
-/* 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 = 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);
-}
-
-
-/* threads_thread_new **********************************************************
-
- Allocates and initializes an internal thread data-structure and
- adds it to the threads list.
-
-*******************************************************************************/
-
-threadobject *threads_thread_new(void)
-{
- int32_t index;
- threadobject *t;
-
- /* lock the threads-lists */
-
- threads_list_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 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)
-{
- /* Lock the threads lists. */
-
- threads_list_lock();
-
- /* Remove the thread from the thread-list. */
-
- threadlist_remove(t);
-
- /* Add the thread index to the free list. */
-
- threadlist_index_add(t->index);
-
- /* Add the thread data structure to the free list. */
-
- threads_thread_set_object(t, NULL);
-
- threadlist_free_add(t);
-
- /* 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_get_current_object **************************************************
-
- Return the Java object of the current thread.
-
- RETURN VALUE:
- the Java object
-
-*******************************************************************************/
-
-#include "native/include/java_lang_ThreadGroup.h"
-
-java_object_t *threads_get_current_object(void)
-{
-#if defined(ENABLE_THREADS)
- threadobject *t;
-# if defined(ENABLE_JAVASE)
- java_lang_ThreadGroup *group;
-# endif
-#endif
- java_lang_Thread *o;
-
-#if defined(ENABLE_THREADS)
- t = THREADOBJECT;
- o = threads_thread_get_object(t);
-
-# if defined(ENABLE_JAVASE)
- /* TODO Do we really need this code? Or should we check, when we
- create the threads, that all of them have a group? */
- /* TWISTI No, we don't need this code! We need to allocate a
- ThreadGroup before we initialize the main thread. */
-
- LLNI_field_get_ref(o, 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)
- vm_abort("unable to create ThreadGroup");
-
- LLNI_field_set_ref(o, group, group);
- }
-# endif
-#else
- /* We just return a fake java.lang.Thread object, otherwise we get
- NullPointerException's in GNU Classpath. */
-
- o = builtin_new(class_java_lang_Thread);
-#endif
-
- return o;
-}
-
-
-/* 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 = 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");
- threads_thread_print_info(t);
- printf("\n");
-
- /* Print trace of thread. */
-
- threads_thread_print_stacktrace(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 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(sfi);
-
- if (ba != NULL) {
- /* We need a critical section here as we use the byte-array
- data pointer directly. */
-
- LLNI_CRITICAL_START;
-
- st = (stacktrace_t *) LLNI_array_data(ba);
-
- /* Print stacktrace. */
-
- stacktrace_print(st);
-
- LLNI_CRITICAL_END;
- }
- else {
- puts("\t<<No stacktrace available>>");
- fflush(stdout);
- }
-}
-
-
-/* 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:
- */
+++ /dev/null
-/* src/threads/threads-common.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 _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_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);
-java_object_t *threads_get_current_object(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_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 /* _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:
- */
/* 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"
*******************************************************************************/
-list_t *list_create(s4 nodeoffset)
+list_t *list_create(int nodeoffset)
{
list_t *l;
*******************************************************************************/
-list_t *list_create_dump(s4 nodeoffset)
+list_t *list_create_dump(int nodeoffset)
{
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;
l->first = ln;
}
- /* increase number of elements */
+ /* Increase number of elements. */
l->size++;
}
*******************************************************************************/
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;
l->first = ln;
}
- /* increase number of elements */
+ /* Increase number of elements. */
l->size++;
}
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;
if (l->last == ln)
l->last = newln;
- /* increase number of elements */
+ /* Increase number of elements. */
l->size++;
-
- LOCK_MONITOR_EXIT(l);
}
*******************************************************************************/
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;
ln->next = NULL;
ln->prev = NULL;
- /* decrease number of elements */
+ /* Decrease number of elements. */
l->size--;
}
{
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;
}
{
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;
}
*******************************************************************************/
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;
}
*******************************************************************************/
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;
}
/* 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.
#define _LIST_H
#include "config.h"
-#include "vm/types.h"
+
+#include <stdint.h>
#include "vm/global.h"
#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 */
/* 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)
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);
/* 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.
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:
*******************************************************************************/
-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 ") +
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 ");
return true;
}
+#endif
/* access_check_method *********************************************************
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:
*******************************************************************************/
-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) +
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);
return true;
}
+#endif
/*
/* 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.
#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 */
imm_union value;
java_handle_t *o;
+ if (a == NULL) {
+ exceptions_throw_nullpointerexception();
+ return NULL;
+ }
+
v = LLNI_vftbl_direct(a);
type = v->arraydesc->arraytype;
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;
vftbl_t *v;
int type;
+ if (a == NULL) {
+ exceptions_throw_nullpointerexception();
+ return;
+ }
+
v = LLNI_vftbl_direct(a);
type = v->arraydesc->arraytype;
\
size = LLNI_array_size(a); \
\
- if ((index < 0) || (index > size)) { \
+ if ((index < 0) || (index >= size)) { \
exceptions_throw_arrayindexoutofboundsexception(); \
return (type) 0; \
} \
size = LLNI_array_size(a);
- if ((index < 0) || (index > size)) {
+ if ((index < 0) || (index >= size)) {
exceptions_throw_arrayindexoutofboundsexception();
return NULL;
}
\
size = LLNI_array_size(a); \
\
- if ((index < 0) || (index > size)) { \
+ if ((index < 0) || (index >= size)) { \
exceptions_throw_arrayindexoutofboundsexception(); \
return; \
} \
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;
}
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)
if (a == NULL) {
exceptions_throw_nullpointerexception();
- return 0;
+ return -1;
}
LLNI_class_get(a, c);
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);
list_assertion_names = list_create(OFFSET(assertion_name_t, linkage));
}
- list_add_last_unsynced(list_assertion_names, item);
+ list_add_last(list_assertion_names, item);
}
#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"
*******************************************************************************/
-s4 builtin_instanceof(java_handle_t *o, classinfo *class)
+bool builtin_instanceof(java_handle_t *o, classinfo *class)
{
classinfo *c;
*******************************************************************************/
-s4 builtin_checkcast(java_handle_t *o, classinfo *class)
+bool builtin_checkcast(java_handle_t *o, classinfo *class)
{
classinfo *c;
*******************************************************************************/
-static s4 builtin_descriptorscompatible(arraydescriptor *desc,
- arraydescriptor *target)
+static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target)
{
if (desc == target)
return 1;
/* {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)*/
(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)
/* {desc has higher dimension than target} */
return class_isanysubclass(pseudo_class_Arraystub,
- target->elementvftbl->class);
+ target->elementvftbl->clazz);
}
*******************************************************************************/
-s4 builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
+bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
{
arraydescriptor *desc;
*******************************************************************************/
-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;
*******************************************************************************/
-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;
*******************************************************************************/
-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;
*******************************************************************************/
-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;
vftbl_t *valuevftbl;
int32_t baseval;
uint32_t diffval;
- int result;
+ bool result;
if (o == NULL)
return 1;
/* 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;
/* 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;
*******************************************************************************/
-java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass)
+java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
{
arraydescriptor *desc;
s4 dataoffset;
*******************************************************************************/
-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));
}
*******************************************************************************/
-java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass)
+java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
{
classinfo *arrayclass;
*******************************************************************************/
#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); \
/* 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. */
/* 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.
* 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);
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,
/* 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"
#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"
#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
-
- TRACESUBSYSTEMINITIALIZATION("exceptions_init");
-
- /* 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.
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
}
+/* 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.
}
+/* 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
}
-/* 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
void exceptions_throw_classnotfoundexception(utf *name)
{
- exceptions_throw_utf_utf(utf_java_lang_ClassNotFoundException, name);
+ exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
}
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");
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: ");
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")
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: ");
}
-/* 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
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
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);
+ }
}
/* 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);
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);
#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"
/* 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.
#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 */
#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;
/* 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
/* 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 */
## 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.
##
STACK_SOURCES = \
stack.c \
stack.h
+
+TRAP_SOURCES = \
+ trap.c \
+ trap.h
endif
if ENABLE_REPLACEMENT
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 \
stacktrace.c \
stacktrace.h \
trace.c \
- trace.h
+ trace.h \
+ $(TRAP_SOURCES)
libjit_la_SOURCES += \
cfg.c \
/* 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 ****************************************************************/
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 */
/* 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? */
void liveness_setup(jitdata *jd) {
int i, icount, b_index;
- stackptr src;
+ stackelement_t* src;
methodinfo *m;
lsradata *ls;
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;
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;
int i, p, t;
methoddesc *md;
#ifdef LV_DEBUG_CHECK
- stackptr s;
+ stackelement_t* s;
#endif
methodinfo *m;
registerdata *rd;
}
-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 */
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;
}
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;
/* 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.
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
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
#if defined(LSRA_DEBUG_CHECK)
methodinfo *m;
int b_index;
- stackptr in,out;
+ stackelement_t* in,out;
int ind, outd;
#endif
}
}
-struct stackslot *lsra_make_ss(stackptr s, int bb_index)
+struct stackslot *lsra_make_ss(stackelement_t* s, int bb_index)
{
struct stackslot *ss;
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? */
}
}
-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 */
#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;
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;
}
#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,
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;
/* 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
-
*/
struct stackslot {
- stackptr s;
+ stackelement_t* s;
int bb;
struct stackslot *next;
};
/* 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.
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;
## 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.
##
## 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
\
md-abi.c \
md-abi.h \
+ md-trap.h \
md.c \
md.h
/* 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_SSA)
# include "vm/jit/optimizing/lsra.h"
/* 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);
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);
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);
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);
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);
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);
}
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);
}
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);
}
}
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 */
/* 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.
#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"
#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"
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
/* 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;
}
/* 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 ***************************************************
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. */
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;
/* fall-through */
- case EXCEPTION_HARDWARE_PATCHER:
+ case TRAP_PATCHER:
if (p == NULL)
break;
#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;
* the _mc->sc_fpregs[i] can cause invalid conversions. */
assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs));
- memcpy(&es->fltregs, &_mc->sc_fpregs, sizeof(_mc->sc_fpregs));
+ 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;
* the _mc->sc_fpregs[i] can cause invalid conversions. */
assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs));
- memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs));
+ system_memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs));
/* write special registers */
_mc->sc_pc = (ptrint) es->pc;
_mc->sc_regs[REG_PV] = (ptrint) es->pv;
_mc->sc_regs[REG_RA] = (ptrint) es->ra;
}
-#endif
/* md_critical_section_restart *************************************************
#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)
}
#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" );
/* 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.
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;
/* src/vm/jit/alpha/md-asm.h - assembler defines for Alpha 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:
-
*/
/* save and restore macros ****************************************************/
-#define SAVE_RETURN_REGISTERS(off) \
- stq v0,(0+(off))*8(sp) ; \
- stt fv0,(1+(off))*8(sp) ;
-
-#define RESTORE_RETURN_REGISTERS(off) \
- ldq v0,(0+(off))*8(sp) ; \
- ldt fv0,(1+(off))*8(sp) ;
-
#define SAVE_ARGUMENT_REGISTERS(off) \
stq a0,(0+(off))*8(sp) ; \
stq a1,(1+(off))*8(sp) ; \
--- /dev/null
+/* 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:
+ */
/* 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.
#include "config.h"
-#include <assert.h>
#include <stdint.h>
#include <ucontext.h>
#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 ***********************************************************/
*(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;
/* 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.
/* 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;
/* 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);
\
md-abi.c \
md-abi.h \
+ md-trap.h \
md.c \
md.h
/* 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.
* *
*******************************************************************************/
-.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
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
/* 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.
/* 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 {
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);
}
}
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);
}
}
}
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 */
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,
/* 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)); */
/******************************************************************************/
#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
/* 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.
#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 */
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);
}
}
{
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);
}
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);
}
}
{
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TST(REG_RESULT, REG_RESULT);
- M_TRAPEQ(0, EXCEPTION_HARDWARE_ARRAYSTORE);
+ M_TRAPEQ(0, TRAP_ArrayStoreException);
}
}
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:
{
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TST(REG_RESULT, REG_RESULT);
- M_TRAPEQ(0, EXCEPTION_HARDWARE_EXCEPTION);
+ M_TRAPEQ(0, TRAP_CHECK_EXCEPTION);
}
}
/* 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;
}
-/* 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.
#include "config.h"
-#include <assert.h>
#include <stdint.h>
#include "vm/types.h"
#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 ***************************************************
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;
}
#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;
}
}
#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
#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;
}
#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" );
/* 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.
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
{
methodinfo *m;
codeinfo *code;
--- /dev/null
+/* 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:
+ */
/* 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.
/* 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;
/* 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 */
branch_target_t *table;
lookup_target_t *lookup;
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;
iptr--;
}
+ 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:
bptr->successorcount += 2;
tbptr = iptr->dst.block;
- ntbptr = bptr->next;
-
tbptr->predecessorcount++;
- ntbptr->predecessorcount++;
+
+ if (has_fallthrough) {
+ ntbptr = bptr->next;
+ ntbptr->predecessorcount++;
+ }
break;
case CF_JSR:
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;
}
}
iptr--;
}
+ 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:
cfg_allocate_successors(bptr);
cfg_insert_successors(bptr, tbptr);
- cfg_insert_successors(bptr, ntbptr);
+ if (has_fallthrough) {
+ cfg_insert_successors(bptr, ntbptr);
+ }
cfg_allocate_predecessors(tbptr);
- cfg_allocate_predecessors(ntbptr);
+ if (has_fallthrough) {
+ cfg_allocate_predecessors(ntbptr);
+ }
cfg_insert_predecessors(tbptr, bptr);
- cfg_insert_predecessors(ntbptr, bptr);
+ if (has_fallthrough) {
+ cfg_insert_predecessors(ntbptr, bptr);
+ }
break;
case CF_JSR:
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;
}
/* 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));
}
Return the codeinfo for the compilation unit that contains the
given PC.
- IN:
+ ARGUMENTS:
pc...............machine code position
RETURN VALUE:
*******************************************************************************/
-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);
}
*******************************************************************************/
-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;
*******************************************************************************/
-methodinfo *code_get_methodinfo_for_pv(u1 *pv)
+methodinfo *code_get_methodinfo_for_pv(void *pv)
{
codeinfo *code;
/* 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.
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 */
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)
/* 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);
#include "native/include/java_lang_Class.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#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 ****************************************************************
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) */
-
- }
-
}
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 */
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);
}
#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 */
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
#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 */
#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 */
{
codeinfo *code;
codegendata *cd;
- list_t *list;
+ list_t *l;
critical_section_ref_t *csr;
critical_section_node_t *csn;
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);
#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.
#endif
s4 alignedmcodelen;
jumpref *jr;
- patchref_t *pr;
u1 *epoint;
s4 alignedlen;
/* 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 */
}
#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 */
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(".");
#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 */
/* Return a wrapped classinfo for static methods. */
if (m->flags & ACC_STATIC)
- return (java_handle_t *) LLNI_classinfo_wrap(m->class);
+ return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
else
return NULL;
}
#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__)
#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 */
};
-/* methodtree_element *********************************************************/
-
-typedef struct methodtree_element methodtree_element;
-
-struct methodtree_element {
- u1 *startpc;
- u1 *endpc;
-};
-
-
/* function prototypes ********************************************************/
void codegen_init(void);
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);
/* 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.
/* 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. */
/* 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);
}
/* 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);
}
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
\
md-abi.c \
md-abi.h \
+ md-trap.h \
md.c \
md.h
/* 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.
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 */
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 */
/* 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.
#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"
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 + 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);
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);
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);
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);
}
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;
}
/* 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
/* 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
#define builtin_d2i _builtin_d2i
#define builtin_d2l _builtin_d2l
+#define asm_get_cycle_count _asm_get_cycle_count
+
#endif /* _MD_ASM_H */
/* 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/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/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"
((d == 5) ? _ss->ebp :
((d == 6) ? _ss->esi : _ss->edi))))));
- if (type == EXCEPTION_HARDWARE_COMPILER) {
+ if (type == TRAP_COMPILER) {
/* The PV from the compiler stub is equal to the XPC. */
pv = xpc;
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. */
- if (type == EXCEPTION_HARDWARE_COMPILER) {
+ if (type == TRAP_COMPILER) {
if (p == NULL) {
o = builtin_retrieve_exception();
}
}
else {
- _ss->eax = (intptr_t) p;
- _ss->ecx = (intptr_t) xpc;
- _ss->eip = (intptr_t) asm_handle_exception;
+ _ss->eax = (uintptr_t) p;
+ _ss->ecx = (uintptr_t) xpc; /* REG_ITMP2_XPC */
+ _ss->eip = (uintptr_t) asm_handle_exception;
}
}
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 = trap_handle(type, val, pv, sp, ra, xpc, _p);
- p = signal_handle(type, val, pv, sp, ra, xpc, _p);
+ /* Set registers. */
- _ss->eax = (intptr_t) p;
- _ss->ecx = (intptr_t) xpc;
- _ss->eip = (intptr_t) asm_handle_exception;
+ _ss->eax = (uintptr_t) p;
+ _ss->ecx = (uintptr_t) xpc; /* REG_ITMP2_XPC */
+ _ss->eip = (uintptr_t) asm_handle_exception;
}
xpc = (u1 *) _ss->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) {
- _ss->eax = (intptr_t) p;
- _ss->ecx = (intptr_t) xpc;
- _ss->eip = (intptr_t) asm_handle_exception;
+ _ss->eax = (uintptr_t) p;
+ _ss->ecx = (uintptr_t) xpc; /* REG_ITMP2_XPC */
+ _ss->eip = (uintptr_t) asm_handle_exception;
}
}
-/* 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;
+ ucontext_t *_uc;
+ mcontext_t _mc;
i386_thread_state_t *_ss;
- s4 i;
+ int i;
_uc = (ucontext_t *) context;
- _mc = &_uc->uc_mcontext;
+ _mc = _uc->uc_mcontext;
_ss = &_mc->ss;
/* read special registers */
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.
+ 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;
- i386_thread_state_t *_ss;
- s4 i;
+ ucontext_t* _uc;
+ mcontext_t _mc;
+ i386_thread_state_t* _ss;
+ int i;
_uc = (ucontext_t *) context;
- _mc = &_uc->uc_mcontext;
+ _mc = _uc->uc_mcontext;
_ss = &_mc->ss;
/* write integer registers */
_ss->eip = (ptrint) es->pc;
_ss->esp = (ptrint) es->sp;
}
-#endif
/* md_critical_section_restart *************************************************
/* 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.
#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"
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(reg);
M_BNE(6);
- M_ALD_MEM(reg, EXCEPTION_HARDWARE_ARITHMETIC);
+ M_ALD_MEM(reg, TRAP_ArithmeticException);
}
}
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);
}
}
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);
}
}
default:
vm_abort("emit_classcast_check: unknown condition %d", condition);
}
- M_ALD_MEM(s1, EXCEPTION_HARDWARE_CLASSCAST);
+ M_ALD_MEM(s1, TRAP_ClassCastException);
}
}
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(reg);
M_BNE(6);
- M_ALD_MEM(reg, EXCEPTION_HARDWARE_NULLPOINTER);
+ M_ALD_MEM(reg, TRAP_NullPointerException);
}
}
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);
}
}
void emit_trap_compiler(codegendata *cd)
{
- M_ALD_MEM(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+ M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
}
/* 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 ***************************************************
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;
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();
}
}
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;
}
}
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;
}
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;
}
}
#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;
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;
_mc->gregs[REG_EIP] = (ptrint) es->pc;
_mc->gregs[REG_ESP] = (ptrint) es->sp;
}
-#endif
/* md_critical_section_restart *************************************************
#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)
}
#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() /* nothing */
#define MEMORY_BARRIER_AFTER_ATOMIC() /* nothing */
#define MEMORY_BARRIER() __asm__ __volatile__ ( \
"lock; add $0, 0(%%esp)" : : : "memory" );
/* 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.
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
{
/* nothing */
}
--- /dev/null
+/* 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:
+ */
/* 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.
#include <stdint.h>
#include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
/* inline functions ***********************************************************/
/* md_codegen_get_pv_from_pc ***************************************************
On this architecture just a wrapper function to
- codegen_get_pv_from_pc.
+ methodtree_find.
*******************************************************************************/
/* 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;
}
/* 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.
/* 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;
/* 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;
}
/* 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.
#include "mm/memory.h"
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
/* call parse pass */
- DOLOG( log_message_class("Parsing ", m->class) );
+ DOLOG( log_message_class("Parsing ", m->clazz) );
if (!parse(jd)) {
return false;
}
}
+#if 0
static void inline_add_blocknr_reference(inline_node *iln, s4 *nrp)
{
inline_target_ref *ref;
ref->next = iln->refs;
iln->refs = ref;
}
+#endif
static void inline_block_translation(inline_node *iln, basicblock *o_bptr, basicblock *n_bptr)
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;
}
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 {
+#if 0
static void debug_dump_inline_context(inline_node *iln)
{
assert(iln->indent);
printf("%sinline_context @%p: \n",
iln->indent, (void*)iln->ctx);
}
+#endif
static void dump_inline_tree(inline_node *iln, s4 blocknr)
/* 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"
/* 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 */
/* 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);
}
-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
#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);
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);
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);
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);
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);
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);
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);
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);
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);
#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));
}
#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));
}
#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));
}
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);
}
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) {
/* for static methods, pass class pointer */
if (m->flags & ACC_STATIC)
- *pvalues++ = &m->class;
+ *pvalues++ = &m->clazz;
/* pass parameter to native function */
/* 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
-
*/
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);
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);
#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"
/* 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"
# ifndef USE_FAKE_ATOMIC_INSTRUCTIONS
# include "machine-instr.h"
# else
-# include "threads/native/generic-primitives.h"
+# include "threads/posix/generic-primitives.h"
# endif
#endif
/* 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.
/* 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 */
/* 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 */
/* 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;
}
#include "toolbox/logging.h"
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
#include "vm/global.h"
#include "vm/initialize.h"
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 */
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
# endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
#if defined(ENABLE_SSA)
/* allocate registers */
- if ((opt_lsra) /*&& strcmp(jd->m->name->text, "findClass") != 0*/) {
+ if ((opt_lsra) /*&& (strcmp(jd->m->name->text, "findClass") == 0 || jd->exceptiontablelength == 0)*/) {
jd->ls = DNEW(lsradata);
jd->ls = NULL;
ssa(jd);
/* 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.
/* 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;
#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/verify/typeinfo.h"
-#include "vmcore/descriptor.h"
#include "vmcore/method.h"
#include "vmcore/references.h"
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 */
/* >= 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) */
};
-/* 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 {
- 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 */
-};
-
/* macros for accessing variables *********************************************
Use VAROP for s1, s2, s3 and dst operands (eg. VAROP(iptr->s1)),
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;
/* 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). */
le->linenumber = linenumber;
le->mpc = cd->mcodeptr - cd->mcodebase;
- list_add_last_unsynced(cd->linenumbers, le);
+ list_add_first(cd->linenumbers, le);
}
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;
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);
le->linenumber = (-1);
le->mpc = insinfo->startmpc;
- list_add_last_unsynced(cd->linenumbers, le);
+ list_add_first(cd->linenumbers, le);
}
/* 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"
/* 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;
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
*/
/* 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 */
emit.c \
patcher.c \
\
+ md-trap.h \
md.c \
md.h
/* 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.
#include <stdint.h>
#include "md-abi.h"
-#include "md-os.h"
#include "vm/types.h"
#include "vm/jit/m68k/codegen.h"
#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"
/* 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);
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);
}
}
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);
}
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);
(void) dseg_add_unique_s4(cd, 0); /* IntSave */
(void) dseg_add_unique_s4(cd, 0); /* FltSave */
- /* print call trace */
-#if 0
-#if !defined(NDEBUG)
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
- emit_verbosecall_enter(jd);
- }
-#endif
-#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) */
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;
}
/* call the native function */
+ M_AMOV_IMM(f, REG_ATMP2);
M_JSR(REG_ATMP2);
/* save return value */
default: assert(0);
}
-#if 0
- /* print call trace */
-#if ! defined(NDEBUG)
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
- emit_verbosecall_exit(jd);
- }
-#endif
-#endif
+
/* remove native stackframe info */
/* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
/* should never be reached from within jit code*/
M_JSR_IMM(0);
-
- /* generate patcher stub call code */
- emit_patcher_traps(jd);
}
#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 **************************************************************************
*
*******************************************************************************/
-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;
vm_abort("emit_classcast_check: unknown condition %d", condition);
}
M_TRAP_SETREGISTER(s1);
- M_TRAP(EXCEPTION_HARDWARE_CLASSCAST);
+ M_TRAP(TRAP_ClassCastException);
}
}
M_ICMP(s2, REG_ITMP3);
M_BHI(4);
M_TRAP_SETREGISTER(s2);
- M_TRAP(EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+ M_TRAP(TRAP_ArrayIndexOutOfBoundsException);
}
}
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);
}
}
Emit a NullPointerException check.
*******************************************************************************/
+
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
{
if (INSTRUCTION_MUST_CHECK(iptr)) {
* invocation at the beginning of codegen.c */
M_ATST(reg);
M_BNE(2);
- M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
+ M_TRAP(TRAP_NullPointerException);
}
}
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_ITST(reg);
M_BNE(2);
- M_TRAP(EXCEPTION_HARDWARE_ARITHMETIC);
+ M_TRAP(TRAP_ArithmeticException);
}
}
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);
}
}
void emit_trap_compiler(codegendata *cd)
{
M_TRAP_SETREGISTER(REG_METHODPTR);
- M_TRAP(EXCEPTION_HARDWARE_COMPILER);
+ M_TRAP(TRAP_COMPILER);
}
mcode = *((uint32_t *) cd->mcodeptr);
- M_TRAP(EXCEPTION_HARDWARE_PATCHER);
+ M_TRAP(TRAP_PATCHER);
return mcode;
}
-## 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)
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
/* 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.
%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
-/* 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>
* 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;
void *p;
actual_mcontext_t *_mc;
actual_ucontext_t *_uc;
-
+ int type;
_uc = (actual_ucontext_t*)_p;
_mc = &_uc->uc_mcontext;
/* 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.
* 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;
/* 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 */
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.
+++ /dev/null
-/* 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:
- */
#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" );
--- /dev/null
+/* 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:
+ */
#include <stdint.h>
#include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
/* md_stacktrace_get_returnaddress *********************************************
/* 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.
*******************************************************************************/
{
void *pv;
- pv = codegen_get_pv_from_pc(ra);
+ pv = methodtree_find(ra);
return pv;
}
/* 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.
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 */
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;
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
\
md-abi.c \
md-abi.h \
+ md-trap.h \
md.c \
md.h
/* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
- Copyright (C) 1996-2005, 2006, 2007, 2008 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
ast a0,4*8(sp) /* save method PV */
#if SIZEOF_VOID_P == 8
- sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
- sdc1 fss1,6*8(sp)
- sdc1 fss2,7*8(sp)
- sdc1 fss3,8*8(sp)
- sdc1 fss4,9*8(sp)
- sdc1 fss5,10*8(sp)
+ s.d fss0,5*8(sp) /* save non JavaABI saved flt registers */
+ s.d fss1,6*8(sp)
+ s.d fss2,7*8(sp)
+ s.d fss3,8*8(sp)
+ s.d fss4,9*8(sp)
+ s.d fss5,10*8(sp)
#endif
move t0,a1 /* address of data structure */
ld a6,6*8(t0)
ld a7,7*8(t0)
- ldc1 fa0,8*8(t0)
- ldc1 fa1,9*8(t0)
- ldc1 fa2,10*8(t0)
- ldc1 fa3,11*8(t0)
- ldc1 fa4,12*8(t0)
- ldc1 fa5,13*8(t0)
- ldc1 fa6,14*8(t0)
- ldc1 fa7,15*8(t0)
+ l.d fa0,8*8(t0)
+ l.d fa1,9*8(t0)
+ l.d fa2,10*8(t0)
+ l.d fa3,11*8(t0)
+ l.d fa4,12*8(t0)
+ l.d fa5,13*8(t0)
+ l.d fa6,14*8(t0)
+ l.d fa7,15*8(t0)
#else /* SIZEOF_VOID_P == 8 */
# endif
# if !defined(ENABLE_SOFT_FLOAT)
- ldc1 fa0,4*8(t0)
- ldc1 fa1,5*8(t0)
+ l.d fa0,4*8(t0)
+ l.d fa1,5*8(t0)
# endif
#endif /* SIZEOF_VOID_P == 8 */
ald s0,3*8(sp)
#if SIZEOF_VOID_P == 8
- ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
- ldc1 fss1,6*8(sp)
- ldc1 fss2,7*8(sp)
- ldc1 fss3,8*8(sp)
- ldc1 fss4,9*8(sp)
- ldc1 fss5,10*8(sp)
+ l.d fss0,5*8(sp) /* restore non JavaABI saved flt regs */
+ l.d fss1,6*8(sp)
+ l.d fss2,7*8(sp)
+ l.d fss3,8*8(sp)
+ l.d fss4,9*8(sp)
+ l.d fss5,10*8(sp)
#endif
aaddiu sp,sp,12*8 /* free stack space */
jr t3 /* jump to save position */
#if SIZEOF_VOID_P == 8
- ldc1 fs0,-4*8(t1)
- ldc1 fs1,-3*8(t1)
- ldc1 fs2,-2*8(t1)
- ldc1 fs3,-1*8(t1)
+ l.d fs0,-4*8(t1)
+ l.d fs1,-3*8(t1)
+ l.d fs2,-2*8(t1)
+ l.d fs3,-1*8(t1)
#else /* SIZEOF_VOID_P == 8 */
# if !defined(ENABLE_SOFT_FLOAT)
- ldc1 fs0,-4*8(t1)
- ldc1 fs1,-3*8(t1)
- ldc1 fs2,-2*8(t1)
- ldc1 fs3,-1*8(t1)
- ldc1 fs4,-1*8(t1)
- ldc1 fs5,-1*8(t1)
+ l.d fs0,-4*8(t1)
+ l.d fs1,-3*8(t1)
+ l.d fs2,-2*8(t1)
+ l.d fs3,-1*8(t1)
+ l.d fs4,-1*8(t1)
+ l.d fs5,-1*8(t1)
# endif /* !defined(ENABLE_SOFT_FLOAT) */
#endif /* SIZEOF_VOID_P == 8 */
compare_and_swap:
1:
+#if defined(__GNUC__)
+ .set mips2
+#endif
all v0,0(a0)
+#if defined(__GNUC__)
+ .set mips0
+#endif
bne v0,a1,2f
move t0,a2
+#if defined(__GNUC__)
+ .set mips2
+#endif
asc t0,0(a0)
+#if defined(__GNUC__)
+ .set mips0
+#endif
beqz t0,1b
2:
+#if defined(__GNUC__)
+ .set mips2
+#endif
sync
+#if defined(__GNUC__)
+ .set mips0
+#endif
j ra
.end compare_and_swap
/* 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.
#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"
/* 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);
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);
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);
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);
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);
}
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 */
/* 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.
#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"
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);
}
}
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);
}
}
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);
}
}
}
M_NOP;
- M_ALD_INTERN(s1, REG_ZERO, EXCEPTION_HARDWARE_CLASSCAST);
+ M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
}
}
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);
}
}
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);
}
}
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);
}
/* 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;
}
/* 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.
#include "vm/signallocal.h"
#include "vm/jit/asmpart.h"
+#include "vm/jit/executionstate.h"
#include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
/* md_init *********************************************************************
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;
xpc = xpc - 4;
break;
}
+# else
+ xpc = (u1 *) (ptrint) _mc->pc;
+# endif
#else
xpc = (u1 *) (ptrint) _gregs[CTX_EPC];
#endif
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. */
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__)
/* 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. */
}
+/**
+ * Read the given context into an executionstate.
+ *
+ * @param es execution state
+ * @param context machine context
+ */
+void md_executionstate_read(executionstate_t* es, void* context)
+{
+ ucontext_t* _uc;
+ mcontext_t* _mc;
+ greg_t* _gregs;
+ int i;
+
+ vm_abort("md_executionstate_read: PLEASE REVISE ME!");
+
+ _uc = (ucontext_t*) context;
+ _mc = &_uc->uc_mcontext;
+
+#if defined(__UCLIBC__)
+ _gregs = _mc->gpregs;
+#else
+ _gregs = _mc->gregs;
+#endif
+
+ /* Read special registers. */
+
+ /* In glibc's ucontext.h the registers are defined as long long,
+ even for MIPS32, so we cast them. This is not the case for
+ uClibc. */
+
+#if defined(__UCLIBC__)
+ es->pc = _gregs[CTX_EPC];
+#else
+ es->pc = (void*) (uintptr_t) _mc->pc;
+#endif
+
+ es->sp = (void*) (uintptr_t) _gregs[REG_SP];
+ es->pv = (void*) (uintptr_t) _gregs[REG_PV];
+ es->ra = (void*) (uintptr_t) _gregs[REG_RA];
+
+ /* 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.fp_r) == sizeof(es->fltregs));
+ system_memcpy(&es->fltregs, &_mc->fpregs.fp_r, sizeof(_mc->fpregs.fp_r));
+}
+
+
+/**
+ * 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)
+{
+ ucontext_t* _uc;
+ mcontext_t* _mc;
+ greg_t* _gregs;
+ int i;
+
+ vm_abort("md_executionstate_write: PLEASE REVISE ME!");
+
+ _uc = (ucontext_t *) context;
+ _mc = &_uc->uc_mcontext;
+
+ /* 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.fp_r) == sizeof(es->fltregs));
+ system_memcpy(&_mc->fpregs.fp_r, &es->fltregs, sizeof(_mc->fpregs.fp_r));
+
+ /* Write special registers. */
+
+#if defined(__UCLIBC__)
+ _gregs[CTX_EPC] = es->pc;
+#else
+ _mc->pc = (uintptr_t) es->pc;
+#endif
+
+ _gregs[REG_SP] = (uintptr_t) es->sp;
+ _gregs[REG_PV] = (uintptr_t) es->pv;
+ _gregs[REG_RA] = (uintptr_t) es->ra;
+}
+
+
/* md_critical_section_restart *************************************************
Search the critical sections tree for a matching section and set
* 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)
#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()
/* 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.
#include "config.h"
#include <stdarg.h>
+#include <stdint.h>
#include "vm/types.h"
#include "vm/global.h"
#include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
#include "vmcore/descriptor.h"
#include "vmcore/method.h"
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
{
methodinfo *m;
methoddesc *md;
/* src/vm/jit/mips/md-asm.h - assembler defines for MIPS 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:
-
*/
#if SIZEOF_VOID_P == 8
-#define SAVE_RETURN_REGISTERS(off) \
- sd v0,(0+(off))*8(sp) ; \
- sdc1 fv0,(1+(off))*8(sp) ;
-
-#define RESTORE_RETURN_REGISTERS(off) \
- ld v0,(0+(off))*8(sp) ; \
- ldc1 fv0,(1+(off))*8(sp) ;
-
-
#define SAVE_ARGUMENT_REGISTERS(off) \
sd a0,(0+(off))*8(sp) ; \
sd a1,(1+(off))*8(sp) ; \
sd a6,(6+(off))*8(sp) ; \
sd a7,(7+(off))*8(sp) ; \
\
- sdc1 fa0,(8+(off))*8(sp) ; \
- sdc1 fa1,(9+(off))*8(sp) ; \
- sdc1 fa2,(10+(off))*8(sp); \
- sdc1 fa3,(11+(off))*8(sp); \
- sdc1 fa4,(12+(off))*8(sp); \
- sdc1 fa5,(13+(off))*8(sp); \
- sdc1 fa6,(14+(off))*8(sp); \
- sdc1 fa7,(15+(off))*8(sp);
+ s.d fa0,(8+(off))*8(sp) ; \
+ s.d fa1,(9+(off))*8(sp) ; \
+ s.d fa2,(10+(off))*8(sp); \
+ s.d fa3,(11+(off))*8(sp); \
+ s.d fa4,(12+(off))*8(sp); \
+ s.d fa5,(13+(off))*8(sp); \
+ s.d fa6,(14+(off))*8(sp); \
+ s.d fa7,(15+(off))*8(sp);
#define RESTORE_ARGUMENT_REGISTERS(off) \
ld a0,(0+(off))*8(sp) ; \
ld a6,(6+(off))*8(sp) ; \
ld a7,(7+(off))*8(sp) ; \
\
- ldc1 fa0,(8+(off))*8(sp); \
- ldc1 fa1,(9+(off))*8(sp); \
- ldc1 fa2,(10+(off))*8(sp); \
- ldc1 fa3,(11+(off))*8(sp); \
- ldc1 fa4,(12+(off))*8(sp); \
- ldc1 fa5,(13+(off))*8(sp); \
- ldc1 fa6,(14+(off))*8(sp); \
- ldc1 fa7,(15+(off))*8(sp);
+ l.d fa0,(8+(off))*8(sp); \
+ l.d fa1,(9+(off))*8(sp); \
+ l.d fa2,(10+(off))*8(sp); \
+ l.d fa3,(11+(off))*8(sp); \
+ l.d fa4,(12+(off))*8(sp); \
+ l.d fa5,(13+(off))*8(sp); \
+ l.d fa6,(14+(off))*8(sp); \
+ l.d fa7,(15+(off))*8(sp);
#define SAVE_TEMPORARY_REGISTERS(off) \
sd t3,(3+(off))*8(sp) ; \
sd t4,(4+(off))*8(sp) ; \
\
- sdc1 ft3,(5+(off))*8(sp) ; \
- sdc1 ft4,(6+(off))*8(sp) ; \
- sdc1 ft5,(7+(off))*8(sp) ; \
- sdc1 ft6,(8+(off))*8(sp) ; \
- sdc1 ft7,(9+(off))*8(sp) ; \
- sdc1 ft8,(10+(off))*8(sp) ; \
- sdc1 ft9,(11+(off))*8(sp) ; \
- sdc1 ft10,(12+(off))*8(sp) ; \
- sdc1 ft11,(13+(off))*8(sp) ; \
- sdc1 ft12,(14+(off))*8(sp) ; \
- sdc1 ft13,(15+(off))*8(sp) ; \
- sdc1 ft14,(16+(off))*8(sp) ; \
- sdc1 ft15,(17+(off))*8(sp) ; \
- sdc1 ft16,(18+(off))*8(sp) ; \
- sdc1 ft17,(19+(off))*8(sp) ; \
- sdc1 ft18,(20+(off))*8(sp) ;
+ s.d ft3,(5+(off))*8(sp) ; \
+ s.d ft4,(6+(off))*8(sp) ; \
+ s.d ft5,(7+(off))*8(sp) ; \
+ s.d ft6,(8+(off))*8(sp) ; \
+ s.d ft7,(9+(off))*8(sp) ; \
+ s.d ft8,(10+(off))*8(sp) ; \
+ s.d ft9,(11+(off))*8(sp) ; \
+ s.d ft10,(12+(off))*8(sp) ; \
+ s.d ft11,(13+(off))*8(sp) ; \
+ s.d ft12,(14+(off))*8(sp) ; \
+ s.d ft13,(15+(off))*8(sp) ; \
+ s.d ft14,(16+(off))*8(sp) ; \
+ s.d ft15,(17+(off))*8(sp) ; \
+ s.d ft16,(18+(off))*8(sp) ; \
+ s.d ft17,(19+(off))*8(sp) ; \
+ s.d ft18,(20+(off))*8(sp) ;
#define RESTORE_TEMPORARY_REGISTERS(off) \
ld t0,(0+(off))*8(sp) ; \
ld t3,(3+(off))*8(sp) ; \
ld t4,(4+(off))*8(sp) ; \
\
- ldc1 ft3,(5+(off))*8(sp) ; \
- ldc1 ft4,(6+(off))*8(sp) ; \
- ldc1 ft5,(7+(off))*8(sp) ; \
- ldc1 ft6,(8+(off))*8(sp) ; \
- ldc1 ft7,(9+(off))*8(sp) ; \
- ldc1 ft8,(10+(off))*8(sp) ; \
- ldc1 ft9,(11+(off))*8(sp) ; \
- ldc1 ft10,(12+(off))*8(sp) ; \
- ldc1 ft11,(13+(off))*8(sp) ; \
- ldc1 ft12,(14+(off))*8(sp) ; \
- ldc1 ft13,(15+(off))*8(sp) ; \
- ldc1 ft14,(16+(off))*8(sp) ; \
- ldc1 ft15,(17+(off))*8(sp) ; \
- ldc1 ft16,(18+(off))*8(sp) ; \
- ldc1 ft17,(19+(off))*8(sp) ; \
- ldc1 ft18,(20+(off))*8(sp) ;
+ l.d ft3,(5+(off))*8(sp) ; \
+ l.d ft4,(6+(off))*8(sp) ; \
+ l.d ft5,(7+(off))*8(sp) ; \
+ l.d ft6,(8+(off))*8(sp) ; \
+ l.d ft7,(9+(off))*8(sp) ; \
+ l.d ft8,(10+(off))*8(sp) ; \
+ l.d ft9,(11+(off))*8(sp) ; \
+ l.d ft10,(12+(off))*8(sp) ; \
+ l.d ft11,(13+(off))*8(sp) ; \
+ l.d ft12,(14+(off))*8(sp) ; \
+ l.d ft13,(15+(off))*8(sp) ; \
+ l.d ft14,(16+(off))*8(sp) ; \
+ l.d ft15,(17+(off))*8(sp) ; \
+ l.d ft16,(18+(off))*8(sp) ; \
+ l.d ft17,(19+(off))*8(sp) ; \
+ l.d ft18,(20+(off))*8(sp) ;
#else /* SIZEOF_VOID_P == 8 */
-#define SAVE_RETURN_REGISTERS(off) \
- sw v0,(0+(off))*4(sp) ; \
- sw v1,(1+(off))*4(sp) ; \
- sdc1 fv0,(2+(off))*4(sp) ;
-
-#define RESTORE_RETURN_REGISTERS(off) \
- lw v0,(0+(off))*4(sp) ; \
- lw v1,(1+(off))*4(sp) ; \
- ldc1 fv0,(2+(off))*4(sp) ;
-
-
#define SAVE_ARGUMENT_REGISTERS(off) \
sw a0,(0+(off))*4(sp) ; \
sw a1,(1+(off))*4(sp) ; \
sw a2,(2+(off))*4(sp) ; \
sw a3,(3+(off))*4(sp) ; \
- sdc1 fa0,(4+(off))*4(sp) ; \
- sdc1 fa1,(6+(off))*4(sp) ;
+ s.d fa0,(4+(off))*4(sp) ; \
+ s.d fa1,(6+(off))*4(sp) ;
#define RESTORE_ARGUMENT_REGISTERS(off) \
lw a0,(0+(off))*4(sp) ; \
lw a1,(1+(off))*4(sp) ; \
lw a2,(2+(off))*4(sp) ; \
lw a3,(3+(off))*4(sp) ; \
- ldc1 fa0,(4+(off))*4(sp) ; \
- ldc1 fa1,(6+(off))*4(sp) ;
+ l.d fa0,(4+(off))*4(sp) ; \
+ l.d fa1,(6+(off))*4(sp) ;
#define SAVE_TEMPORARY_REGISTERS(off) \
sw t5,(5+(off))*4(sp) ; \
sw t6,(6+(off))*4(sp) ; \
sw t7,(7+(off))*4(sp) ; \
- sdc1 ft0,(8+(off))*4(sp) ; \
- sdc1 ft1,(10+(off))*4(sp) ; \
- sdc1 ft2,(12+(off))*4(sp) ; \
- sdc1 ft3,(14+(off))*4(sp) ;
+ s.d ft0,(8+(off))*4(sp) ; \
+ s.d ft1,(10+(off))*4(sp) ; \
+ s.d ft2,(12+(off))*4(sp) ; \
+ s.d ft3,(14+(off))*4(sp) ;
#define RESTORE_TEMPORARY_REGISTERS(off) \
lw t0,(0+(off))*4(sp) ; \
lw t5,(5+(off))*4(sp) ; \
lw t6,(6+(off))*4(sp) ; \
lw t7,(7+(off))*4(sp) ; \
- ldc1 ft0,(8+(off))*4(sp) ; \
- ldc1 ft1,(10+(off))*4(sp) ; \
- ldc1 ft2,(12+(off))*4(sp) ; \
- ldc1 ft3,(14+(off))*4(sp) ;
+ l.d ft0,(8+(off))*4(sp) ; \
+ l.d ft1,(10+(off))*4(sp) ; \
+ l.d ft2,(12+(off))*4(sp) ; \
+ l.d ft3,(14+(off))*4(sp) ;
#endif /* SIZEOF_VOID_P == 8 */
--- /dev/null
+/* 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:
+ */
/* 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.
/* 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;
*((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 */
/* 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"
int *itnr;
bool found;
- fprintf(stderr, "%s/%s: \n", jd->m->class->name->text, jd->m->name->text);
+ 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) {
/* 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
-
- $Id: lifetimes.c $
-
*/
+
#include <stdio.h>
#include <stdlib.h>
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
-/* 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
-
-
*/
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 *);
/* src/vm/jit/optimizing/lsra.inc - linear scan register allocator
- Copyright (C) 2005, 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- Institut f. Computersprachen - TU Wien
+ Copyright (C) 2005, 2006, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
- Contact: cacao@complang.tuwien.ac.at
-
- Authors: Christian Ullrich
+*/
- $Id: lsra.c $
-*/
#include "config.h"
#include <stdio.h>
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
#if defined(LSRA_DEBUG_CHECK)
#if 0
int b_index;
- stackptr in,out;
+ stackelement_t* in,out;
int ind, outd;
#endif
#endif
#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);
+ 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)
#include "mm/memory.h"
#include "threads/threadlist.h"
-#include "threads/threads-common.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"
/* lock the threads lists */
- threads_list_lock();
+ threadlist_lock();
/* iterate over all started threads */
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 */
/* unlock the threads lists */
- threads_list_unlock();
+ threadlist_unlock();
}
}
#endif
/* src/vm/jit/optimizing/recompile.c - recompilation system
Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "mm/memory.h"
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/list.h"
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);
#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);
+ 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)
#ifdef SSA_DEBUG_VERBOSE
if (compileverbose)
printf("dce: %s %s:at BB %3i II %3i NOP-<%s\n",
- m->class->name->text, m->name->text,
+ m->clazz->name->text, m->name->text,
lt->def->b_index, lt->def->iindex,
icmd_table[iptr->opc].name);
#endif
TODO
- * Adapt for exception handling
+ * 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 "toolbox/list.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)
-#define show_basicblock(...) do { if (getenv("VERB")) show_basicblock(__VA_ARGS__); } while (0)
+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
/*
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)
+ 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->subbasicblocks) {
bptr->subbasicblocks = DNEW(basicblock);
ass(bptr->subbasicblocks, bptr);
+ bptr->subbasicblocks->subbasicblocks = NULL;
bptr->subbasicblocks->next = NULL;
}
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;
}
/* assigned in caller */
ee->start = from;
- ee->end = from->next;
+ /* 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;
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;
}
}
}
+ /* XXX
+ <------------------->
+ <---><--><--->missing */
if (firstee) {
lastee->next = ite->next;
lastee->down = ite->down;
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");
printf("=============== [ after ] =========================\n");
show_method(jd, 3);
printf("=============== [ /after ] =========================\n");
+
+ do_verbose = 0;
}
void eliminate_subbasicblocks(jitdata *jd) {
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;
}
/*
#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);
+ 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->class->name->text,"fp")==0)
+ if (strcmp(jd->m->clazz->name->text,"fp")==0)
if (strcmp(jd->m->name->text,"testfloat")==0)
# if defined(SSA_DEBUG_VERBOSE)
if (compileverbose)
/* 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.
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;
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;
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;
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;
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;
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;
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;
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;
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)
}
}
else {
- um = resolve_create_unresolved_method(m->class, m, fmi,
+ um = resolve_create_unresolved_method(m->clazz, m, fmi,
(opcode == BC_invokestatic),
(opcode == BC_invokespecial));
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;
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;
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;
{
s4 nlocals = 0;
s4 i;
+ s4 t;
+ s4 varindex;
s4 *mapptr;
+ s4 *reversemap;
mapptr = local_map;
MZERO(jd->var, varinfo, jd->varcount);
/* set types of all locals in jd->var */
+ /* and fill the reverselocalmap */
- for (mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
- if (*mapptr != UNUSED)
- VAR(*mapptr)->type = i%5;
+ 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;
+ }
+ }
+
+ jd->reverselocalmap = reversemap;
}
/* assign local variables to method variables */
/* allocate stack table */
- jd->stack = DMNEW(stackelement, jd->stackcount);
+ jd->stack = DMNEW(stackelement_t, jd->stackcount);
/* everything's ok */
#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"
/* 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*/
if (pr->mpc == (ptrint) pc)
return pr;
- pr = list_next_unsynced(code->patchers, pr);
+ pr = list_next(code->patchers, pr);
}
return NULL;
/* 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)
}
+/**
+ * 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
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 *) (intptr_t) 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("\tmachine code before = ");
+
+# if defined(ENABLE_DISASSEMBLER)
+ disassinstr((void *) pr->mpc);
+# else
+ printf("disassembler disabled\n");
+# endif
+
patcher_depth++;
assert(patcher_depth > 0);
}
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");
}
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);
emit.c \
patcher.c \
\
+ md-trap.h \
md.c \
md.h
#include "native/native.h"
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#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"
/* 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);
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);
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);
}
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 */
-/* 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.
#include "vm/global.h"
#include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
#include "vmcore/descriptor.h"
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t* stackslot)
{
methodinfo *m;
codeinfo *code;
/* 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.
#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"
/* 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.
#include "vm/jit/jit.h"
#include "vm/jit/replace.h"
#include "vm/jit/trace.h"
+#include "vm/jit/trap.h"
#include "vmcore/options.h"
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
/* 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;
}
/* 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.
#include "vm/global.h"
#include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
#include "vmcore/descriptor.h"
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
{
methodinfo *m;
codeinfo *code;
/* 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 ***************************************************
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. */
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;
/* fall-through */
- case EXCEPTION_HARDWARE_PATCHER:
+ case TRAP_PATCHER:
if (p == NULL)
break;
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;
}
#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;
_uc = (ucontext_t *) context;
#if defined(__UCLIBC__)
-#error Please port md_replace_executionstate_read to __UCLIBC__
+#error Please port md_executionstate_read to __UCLIBC__
#else
_mc = _uc->uc_mcontext.uc_regs;
_gregs = _mc->gregs;
* the _mc->fpregs[i] can cause invalid conversions. */
assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs));
- memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs));
+ system_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.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;
_uc = (ucontext_t *) context;
#if defined(__UCLIBC__)
-#error Please port md_replace_executionstate_read to __UCLIBC__
+#error Please port md_executionstate_write to __UCLIBC__
#else
_mc = _uc->uc_mcontext.uc_regs;
_gregs = _mc->gregs;
* the _mc->fpregs[i] can cause invalid conversions. */
assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs));
- memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs));
+ system_memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs));
/* write special registers */
_gregs[PT_NIP] = (ptrint) es->pc;
_gregs[REG_PV] = (ptrint) es->pv;
_gregs[PT_LNK] = (ptrint) es->ra;
}
-#endif
/* md_critical_section_restart *************************************************
#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;
}
#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" );
--- /dev/null
+/* 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:
+ */
-/* 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
-
*/
#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)
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t* stackslot)
{
methodinfo *m;
registerdata *rd;
/* 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.
/* 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;
/* patch interfacetable index */
disp = OFFSET(vftbl_t, interfacetable[0]) -
- sizeof(methodptr*) * m->class->index;
+ sizeof(methodptr*) * m->clazz->index;
/* XXX TWISTI: check displacement */
/* patch method offset */
- disp = sizeof(methodptr) * (m - m->class->methods);
+ disp = sizeof(methodptr) * (m - m->clazz->methods);
/* XXX TWISTI: check displacement */
emit.c \
patcher.c \
\
+ md-trap.h \
md.c \
md.h
/* 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.
#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"
/* 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 */
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);
}
}
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);
}
}
} 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 */
/* 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.
#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"
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);
}
}
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);
}
}
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 ********************************************************
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);
}
}
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);
}
}
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);
}
}
void emit_trap_compiler(codegendata *cd)
{
- M_LWZ(REG_METHODPTR, REG_ZERO, EXCEPTION_HARDWARE_COMPILER);
+ M_LWZ(REG_METHODPTR, REG_ZERO, TRAP_COMPILER);
}
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;
}
/* 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.
#include "vm/global.h"
#include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
#include "vmcore/descriptor.h"
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
{
methodinfo *m;
codeinfo *code;
/* 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.
#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"
#endif
#include "vm/jit/stacktrace.h"
+#include "vm/jit/trap.h"
/* md_signal_handler_sigsegv ***************************************************
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. */
}
}
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;
/* fall-through */
- case EXCEPTION_HARDWARE_PATCHER:
+ case TRAP_PATCHER:
if (p == NULL)
break;
}
#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" );
--- /dev/null
+/* 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:
+ */
#include "vm/global.h"
#include "vm/jit/jit.h"
+#include "vm/jit/trap.h"
/* md_init *********************************************************************
*(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;
/* 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.
/* 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 */
/* patch interfacetable index */
disp = OFFSET(vftbl_t, interfacetable[0]) -
- sizeof(methodptr*) * m->class->index;
+ sizeof(methodptr*) * m->clazz->index;
/* XXX TWISTI: check displacement */
/* patch method offset */
- disp = sizeof(methodptr) * (m - m->class->methods);
+ disp = sizeof(methodptr) * (m - m->clazz->methods);
/* XXX TWISTI: check displacement */
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->class);
+ return get_obj(arg->get.result, classinfo_func, state->root, fi->clazz);
}
}
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->class);
+ 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:
/* 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.
basicblock *retaddr;
} vv;
#if defined(ENABLE_VERIFIER)
- typeinfo typeinfo; /* type info for reference types */
+ typeinfo_t typeinfo; /* type info for reference types */
#endif
};
#include "mm/memory.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
#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"
#if !defined(NDEBUG)
static void java_value_print(s4 type, replace_val_t value);
static void replace_stackframeinfo_println(stackframeinfo_t *sfi);
-static void replace_sanity_check_read_write(void *context);
#endif
#if !defined(NDEBUG)
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);
}
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 */
replace_push_activation_record(es, rp, prevframe, ss->frames);
- DOLOG( replace_executionstate_println(es); );
+ DOLOG( executionstate_println(es); );
}
rp = ss->frames->torp;
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;
if ((rp != NULL) && (rp->pc == pc) && (rp->flags & RPLPOINT_FLAG_ACTIVE)) {
#if !defined(NDEBUG)
- replace_sanity_check_read_write(context);
+ executionstate_sanity_check(context);
#endif
/* set codeinfo pointer in execution state */
/* 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 */
/* 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 */
#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 ",(void*)es->pv);
- printf(" ra = %p\n",(void*)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 = %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);
- if (code_is_leafmethod(es->code))
- printf(" leaf");
- }
- printf("\n");
-
- printf("\n");
-}
-#endif
-
#if !defined(NDEBUG)
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);
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;
}
#endif
-/* replace_sanity_check_read_write *********************************************
-
- Perform some sanity checks for the md_replace_executionstate_read
- and md_replace_executionstate_write functions.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-static void replace_sanity_check_read_write(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 */
-
- memcpy(&reference, context, MINIMUM_CONTEXT_SIZE);
-
- /* different poisons */
-
- memset(&es1, 0xc9, sizeof(executionstate_t));
- memset(&es2, 0xb5, sizeof(executionstate_t));
- memset(&es3, 0x6f, sizeof(executionstate_t));
-
- md_replace_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_replace_executionstate_write(&es2, context);
-
- /* Read it again, Sam! */
-
- md_replace_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
-
-
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where
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;
};
-/* 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 */
u1 *ra; /* return address / link register */
-
- 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 */
-};
-
-
struct sourceframe_t {
sourceframe_t *down; /* source frame down the call chain */
#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);
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 */
\
md-abi.c \
md-abi.h \
+ md-trap.h \
md.c \
md.h
/* 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
/* 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);
N_L(
GET_LOW_REG(d) /* maybe itmp3 */,
- OFFSET(java_intarray_t, data[0]) + 4,
+ OFFSET(java_longarray_t, data[0]) + 4,
REG_ITMP2, s1 /* maybe itmp1 */
);
N_L(
GET_HIGH_REG(d) /* maybe itmp1 */,
- OFFSET(java_intarray_t, data[0]),
+ OFFSET(java_longarray_t, data[0]),
REG_ITMP2, s1 /* maybe itmp1 */
);
M_INTMOVE(s2, REG_ITMP2);
M_SLL_IMM(3, REG_ITMP2); /* scale index by 8 */
- N_LD(d, OFFSET(java_floatarray_t, data[0]), REG_ITMP2, s1);
+ N_LD(d, OFFSET(java_doublearray_t, data[0]), REG_ITMP2, s1);
emit_store_dst(jd, iptr, d);
break;
M_SLL_IMM(3, REG_ITMP2);
s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
- N_ST(s3, OFFSET(java_intarray_t, data[0]), REG_ITMP2, s1);
+ N_ST(s3, OFFSET(java_longarray_t, data[0]), REG_ITMP2, s1);
s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
- N_ST(s3, OFFSET(java_intarray_t, data[0]) + 4, REG_ITMP2, s1);
+ N_ST(s3, OFFSET(java_longarray_t, data[0]) + 4, REG_ITMP2, s1);
break;
case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
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;
}
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;
}
}
}
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) {
}
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 */
/* 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.
mcode = *((u2 *) cd->mcodeptr);
- M_ILL(EXCEPTION_HARDWARE_PATCHER);
+ M_ILL(TRAP_PATCHER);
return mcode;
}
}
}
-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);
}
}
*/
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);
}
}
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(REG_RESULT);
M_BNE(SZ_BRC + SZ_ILL);
- M_ILL(EXCEPTION_HARDWARE_ARRAYSTORE);
+ M_ILL(TRAP_ArrayStoreException);
}
}
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);
}
}
void emit_trap_compiler(codegendata *cd)
{
- M_ILL2(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+ M_ILL2(REG_METHODPTR, TRAP_COMPILER);
}
/*
* 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)
{
/* 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
-/* 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[] = {
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t* stackslot)
{
methodinfo *m;
codeinfo *code;
--- /dev/null
+/* 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:
+ */
/* 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/executionstate.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 */
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
);
}
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 ***************************************************
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;
}
}
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;
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 {
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;
}
#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!");
+}
+
+
+/**
+ * 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 defined(ENABLE_THREADS)
void md_critical_section_restart(ucontext_t *_uc)
{
++loops;
- pv = codegen_get_pv_from_pc(xpc);
+ pv = methodtree_find(xpc);
handler = exceptions_handle_exception((java_object_t *)xptr, xpc, pv, sp);
/* 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.
#include <stdint.h>
#include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
/* md_stacktrace_get_returnaddress *********************************************
/* 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.
*******************************************************************************/
/* 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;
}
/* 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.
/* 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;
/* 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);
#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)
/* 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) +
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);
\
md-abi.c \
md-abi.h \
+ md-trap.h \
md.c \
md.h
/* 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.
/* 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);
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);
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);
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);
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);
}
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 */
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);
}
}
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);
}
}
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);
}
}
}
M_NOP;
- M_ALD_INTERN(s1, REG_ZERO, EXCEPTION_HARDWARE_CLASSCAST);
+ M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
}
}
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);
}
}
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);
}
}
/* 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;
}
/* 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;
/* flush register windows? */
- val = md_get_reg_from_context(ctx, d);
+ val = md_get_reg_from_context(ctx, d);
/* check for special-load */
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;
}
#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)
}
#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" );
/* 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.
#include "vm/global.h"
#include "vm/jit/abi.h"
+#include "vm/jit/stack.h"
#include "vmcore/descriptor.h"
#include "mm/memory.h"
#include <assert.h>
+
/* helper macros for allocation methods ***************************************/
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t* stackslot)
{
/* XXX */
}
--- /dev/null
+/* 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:
+ */
/* 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.
/* 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 */
*((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 */
/* 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)
/* 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;
}
/* 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.
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 */
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 */
};
/* 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)
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
*******************************************************************************/
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;
*******************************************************************************/
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;
*******************************************************************************/
-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;
*******************************************************************************/
-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);
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 */
*******************************************************************************/
-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;
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;
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;
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 */
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);
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);
}
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;
}
/* 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);
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);
i++;
depth = i;
- stack = MNEW(stackptr, depth);
+ stack = MNEW(stackelement_t *, depth);
for(sp = curstack; sp; sp = sp->prev)
stack[--i] = sp;
-/* 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 ************************************/
/*--------------------------------------------------*/
# 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)
CYCLES_STATS_DECLARE(stacktrace_get, 40, 5000)
CYCLES_STATS_DECLARE(stacktrace_getClassContext , 40, 5000)
CYCLES_STATS_DECLARE(stacktrace_getCurrentClass , 40, 5000)
if (pv == NULL) {
#if defined(ENABLE_INTRP)
if (opt_intrp)
- pv = codegen_get_pv_from_pc(ra);
+ pv = methodtree_find(ra);
else
#endif
{
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
}
#if defined(ENABLE_INTRP)
if (opt_intrp)
- pv = codegen_get_pv_from_pc(ra);
+ pv = methodtree_find(ra);
else
#endif
{
/* 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
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 {
}
+/* 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.
*******************************************************************************/
-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)
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;
/* Store the class in the array. */
- data[i] = (java_object_t *) m->class;
+ data[i] = (java_object_t *) m->clazz;
i++;
}
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;
}
}
/* 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. */
#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
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. */
- fflush(stdout);
+ code = tmpsfi.code;
+ m = code->m;
+
+ /* Get the line number. */
+
+ linenumber = linenumbertable_linenumber_for_pc(&m, code, tmpsfi.xpc);
+
+ stacktrace_print_entry(m, linenumber);
+ }
+}
+
+
+/* stacktrace_print_of_thread **************************************************
+
+ Print the current stacktrace of the given thread.
+
+ ARGUMENTS:
+ t ... thread
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS)
+void stacktrace_print_of_thread(threadobject *t)
+{
+ stackframeinfo_t *sfi;
+ stackframeinfo_t tmpsfi;
+ codeinfo *code;
+ methodinfo *m;
+ int32_t linenumber;
+
+ /* Build a stacktrace for the passed thread. */
+
+ sfi = t->_stackframeinfo;
+
+ if (sfi == NULL) {
+ puts("\t<<No stacktrace available>>");
+ fflush(stdout);
+ return;
+ }
+
+ for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi);
+ stacktrace_stackframeinfo_end_check(&tmpsfi) == false;
+ stacktrace_stackframeinfo_next(&tmpsfi)) {
+ /* Get the methodinfo. */
+
+ code = tmpsfi.code;
+ m = code->m;
+
+ /* Get the line number. */
+
+ linenumber = linenumbertable_linenumber_for_pc(&m, code, tmpsfi.xpc);
+
+ stacktrace_print_entry(m, linenumber);
+ }
}
+#endif
/* stacktrace_print_exception **************************************************
#if defined(WITH_CLASSPATH_GNU)
java_lang_VMThrowable *vmt;
- gnu_classpath_Pointer *backtrace;
-#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
- java_lang_Object *backtrace;
#endif
+ java_lang_Object *backtrace;
java_handle_bytearray_t *ba;
stacktrace_t *st;
#if defined(WITH_CLASSPATH_GNU)
LLNI_field_get_ref(o, vmState, vmt);
- LLNI_field_get_ref(vmt, vmData, backtrace);
+ LLNI_field_get_ref(vmt, vmdata, backtrace);
#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
/* src/vm/jit/stacktrace.h - header file for stacktrace generation
Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "md-abi.h"
+#include "threads/thread.h"
+
#include "vm/global.h"
#include "vm/jit/code.h"
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) */
#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"
*******************************************************************************/
-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;
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 */
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 */
/* 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("\")");
s4 pos;
int32_t dumpmarker;
+ /* We don't trace builtin functions here because the argument
+ passing happens via the native ABI and does not fit these
+ functions. */
+
+ if (method_is_builtin(m))
+ return;
+
#if defined(ENABLE_DEBUG_FILTER)
if (!show_filters_test_verbosecall_enter(m))
return;
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);
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, ".");
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, ", ");
}
imm_union val;
int32_t dumpmarker;
+ /* We don't trace builtin functions here because the argument
+ passing happens via the native ABI and does not fit these
+ functions. */
+
+ if (method_is_builtin(m))
+ return;
+
#if defined(ENABLE_DEBUG_FILTER)
if (!show_filters_test_verbosecall_exit(m))
return;
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) +
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, ".");
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);
if (xptr) {
logtextlen =
- strlen("Exception ") + utf_bytes(xptr->vftbl->class->name);
+ strlen("Exception ") + utf_bytes(xptr->vftbl->clazz->name);
}
else {
logtextlen = strlen("Some Throwable");
if (m) {
logtextlen +=
- utf_bytes(m->class->name) +
+ utf_bytes(m->clazz->name) +
strlen(".") +
utf_bytes(m->name) +
utf_bytes(m->descriptor) +
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)");
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");
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);
(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);
}
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
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;
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
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;
}
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)
/* 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 */
/* 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:
-
*/
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;
/* 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:
-
*/
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 */
};
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 */
/* 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 */
/* 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
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));
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);
/* 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
-
-
*/
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;
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);
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;
/* 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.
/* 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,
/* 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;
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;
static bool typecheck_stackbased_reach(verifier_state *state,
basicblock *destblock,
- typedescriptor *stack,
+ typedescriptor_t *stack,
s4 stackdepth)
{
bool changed = false;
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;
*******************************************************************************/
-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;
}
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 */
}
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 */
}
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 */
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;
/* 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 */
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 {
}
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;
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);
verifier_state state;
basicblock *tbptr;
exception_entry *ex;
- typedescriptor exstack;
+ typedescriptor_t exstack;
s4 skip = 0;
DOLOG( show_method(jd, SHOW_PARSE); );
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;
}
#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);
# 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;
# 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;
/* 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.
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 */
codegendata *cd;
varinfo *savedlocals;
verifier_state state; /* current state of the verifier */
- s4 i;
- s4 t;
/* collect statistics */
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 */
/* 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.
*******************************************************************************/
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);
*******************************************************************************/
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));
*******************************************************************************/
bool
-typeinfo_is_array(typeinfo *info)
+typeinfo_is_array(typeinfo_t *info)
{
TYPEINFO_ASSERT(info);
return TYPEINFO_IS_ARRAY(*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);
*******************************************************************************/
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);
*******************************************************************************/
static typecheck_result
-mergedlist_implements_interface(typeinfo_mergedlist *merged,
+mergedlist_implements_interface(typeinfo_mergedlist_t *merged,
classinfo *interf)
{
int i;
*******************************************************************************/
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;
*******************************************************************************/
static typecheck_result
-merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
+merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist_t *merged,
classinfo *cls)
{
int i;
*******************************************************************************/
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;
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))
*******************************************************************************/
typecheck_result
-typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
+typeinfo_is_assignable(typeinfo_t *value,typeinfo_t *dest)
{
TYPEINFO_ASSERT(value);
TYPEINFO_ASSERT(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;
*******************************************************************************/
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;
*******************************************************************************/
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);
*******************************************************************************/
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;
*******************************************************************************/
bool
-typedescriptor_init_from_typedesc(typedescriptor *td,
+typedescriptor_init_from_typedesc(typedescriptor_t *td,
typedesc *desc)
{
TYPEINFO_ASSERT(td);
methoddesc *desc,
int buflen, int startindex,
s4 *map,
- typedescriptor *returntype)
+ typedescriptor_t *returntype)
{
s4 i;
s4 varindex;
*******************************************************************************/
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;
*******************************************************************************/
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);
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);
}
*******************************************************************************/
void
-typeinfo_clone(typeinfo *src,typeinfo *dest)
+typeinfo_clone(typeinfo_t *src,typeinfo_t *dest)
{
int count;
classref_or_classinfo *srclist,*destlist;
*******************************************************************************/
void
-typeinfo_free(typeinfo *info)
+typeinfo_free(typeinfo_t *info)
{
TYPEINFO_FREEMERGED_IF_ANY(info->merged);
info->merged = NULL;
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");
/* 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);
/* 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;
/* 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 */
*******************************************************************************/
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;
#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");
*******************************************************************************/
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;
}
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);
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);
#define TYPEINFO_TEST_BUFLEN 4000
static bool
-typeinfo_equal(typeinfo *x,typeinfo *y)
+typeinfo_equal(typeinfo_t *x,typeinfo_t *y)
{
int i;
}
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;
#if 0
static void
-typeinfo_inc_dimension(typeinfo *info)
+typeinfo_inc_dimension(typeinfo_t *info)
{
if (info->dimension++ == 0) {
info->elementtype = ARRAYTYPE_OBJECT;
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");
#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));
}
}
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];
}
void
-typeinfo_print_short(FILE *file,typeinfo *info)
+typeinfo_print_short(FILE *file,typeinfo_t *info)
{
int i;
instruction *ins;
}
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;
}
void
-typedescriptor_print(FILE *file,typedescriptor *td)
+typedescriptor_print(FILE *file,typedescriptor_t *td)
{
typeinfo_print_type(file,td->type,&(td->typeinfo));
}
/* 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.
/* 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"
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 */
};
/* 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, ...) */
};
/* internal, don't use this explicitly! */
#define TYPEINFO_ALLOCMERGED(mergedlist,count) \
- do {(mergedlist) = (typeinfo_mergedlist *) DMNEW(uint8_t, \
- sizeof(typeinfo_mergedlist) \
+ do {(mergedlist) = (typeinfo_mergedlist_t *) DMNEW(uint8_t, \
+ sizeof(typeinfo_mergedlist_t) \
+ ((count)-1)*sizeof(classinfo*));} while(0)
/* internal, don't use this explicitly! */
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 */
/* 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 *************************************************/
* >= 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 ********************************************************/
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 */
\
md-abi.c \
md-abi.h \
+ md-trap.h \
md.c \
md.h
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 */
#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"
/* 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);
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;
}
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;
}
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;
}
}
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 */
#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"
#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"
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(reg);
M_BNE(8);
- M_ALD_MEM(reg, EXCEPTION_HARDWARE_ARITHMETIC);
+ M_ALD_MEM(reg, TRAP_ArithmeticException);
}
}
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);
}
}
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);
}
}
default:
vm_abort("emit_classcast_check: unknown condition %d", condition);
}
- M_ALD_MEM(s1, EXCEPTION_HARDWARE_CLASSCAST);
+ M_ALD_MEM(s1, TRAP_ClassCastException);
}
}
if (INSTRUCTION_MUST_CHECK(iptr)) {
M_TEST(reg);
M_BNE(8);
- M_ALD_MEM(reg, EXCEPTION_HARDWARE_NULLPOINTER);
+ M_ALD_MEM(reg, TRAP_NullPointerException);
}
}
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);
}
}
void emit_trap_compiler(codegendata *cd)
{
- M_ALD_MEM(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+ M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
}
/* 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.
#include <stdlib.h>
#include <ucontext.h>
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "threads/thread.h"
#include "vm/signallocal.h"
/* 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"
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;
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();
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 */
/* 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 */
#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;
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;
_mc->gregs[REG_RIP] = (ptrint) es->pc;
_mc->gregs[REG_RSP] = (ptrint) es->sp;
}
-#endif
/* md_critical_section_restart *************************************************
#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)
}
#define STORE_ORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory");
-#define MEMORY_BARRIER_BEFORE_ATOMIC() /* nothing */
#define MEMORY_BARRIER_AFTER_ATOMIC() /* nothing */
#define MEMORY_BARRIER() __asm__ __volatile__ ( \
"mfence" : : : "memory" );
/* 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.
#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"
*******************************************************************************/
-void md_return_alloc(jitdata *jd, stackptr stackslot)
+void md_return_alloc(jitdata *jd, stackelement_t *stackslot)
{
methodinfo *m;
codeinfo *code;
--- /dev/null
+/* 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:
+ */
-/* 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.
#include <stdint.h>
#include "vm/jit/codegen-common.h"
+#include "vm/jit/methodtree.h"
/* inline functions ***********************************************************/
/* 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.
*******************************************************************************/
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;
}
/* 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.
/* 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;
*((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;
}
/* 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.
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);
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);
# 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);
strcpy(boot_class_path, p);
}
else {
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
# if defined(WITH_CLASSPATH_GNU)
len =
/* 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 */
pe->key = key;
pe->value = value;
- list_add_last_unsynced(list_properties, pe);
+ list_add_last(list_properties, pe);
}
{
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;
}
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);
}
}
/* 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 */
/******************************************************************************/
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;
- }
}
}
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:
/* 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))
resolve_err_t error)
{
classinfo *subclass;
- typeinfo subti;
+ typeinfo_t subti;
typecheck_result r;
char *msg;
s4 msglen;
#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)
{
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;
}
constant_FMIref *fieldref,
classinfo *container,
fieldinfo *fi,
- typeinfo *instanceti,
- typeinfo *valueti,
+ typeinfo_t *instanceti,
+ typeinfo_t *valueti,
bool isstatic,
bool isput)
{
/* 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);
/* 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 */
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);
/* the class containing the reference */
- referer = refmethod->class;
+ referer = refmethod->clazz;
assert(referer);
/* check if the field itself is already resolved */
/* 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;
}
if (checkresult != resolveSucceeded)
return (bool) checkresult;
- declarer = fi->class;
+ declarer = fi->clazz;
assert(declarer);
assert(declarer->state & CLASS_LOADED);
assert(declarer->state & CLASS_LINKED);
/* 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);
/* 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 */
#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;
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;
methodinfo *refmethod,
methodinfo *mi,
bool invokestatic,
- typedescriptor *stack)
+ typedescriptor_t *stack)
{
- typedescriptor *param;
+ typedescriptor_t *param;
resolve_result_t result;
methoddesc *md;
typedesc *paramtypes;
/* 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;
/* 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 */
}
}
/* 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 */
}
/* the class containing the reference */
- referer = refmethod->class;
+ referer = refmethod->clazz;
assert(referer);
/* check if the method itself is already resolved */
/* 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;
}
if (!resolve_method_loading_constraints(referer, mi))
return false;
- declarer = mi->class;
+ declarer = mi->clazz;
assert(declarer);
assert(referer->state & CLASS_LINKED);
static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
methodinfo *refmethod,
unresolved_subtype_set *stset,
- typeinfo *tinfo,
+ typeinfo_t *tinfo,
utf *declaredclassname)
{
int count;
#ifdef ENABLE_VERIFIER
unresolved_class * create_unresolved_class(methodinfo *refmethod,
constant_classref *classref,
- typeinfo *valuetype)
+ typeinfo_t *valuetype)
{
unresolved_class *ref;
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);
/* 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)) {
"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);
#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;
/* 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
{ /* 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;
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;
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;
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;
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;
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: ");
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: ");
/* 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.
#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,
#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,
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,
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,
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,
bool resolve_constrain_unresolved_method_params_stackbased(
unresolved_method *ref,
methodinfo *refmethod,
- typedescriptor *stack);
+ typedescriptor_t *stack);
#endif /* defined(ENABLE_VERIFIER) */
#include "config.h"
#include <assert.h>
-#include <errno.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
#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)
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. */
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;
-
-#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 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");
}
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
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. */
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);
#include <assert.h>
+#include "vmcore/system.h"
+
#include "vm/types.h"
#include "vm/global.h"
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. :( */
}
-/* 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;
for (i = offset; i < offset + count; i++) {
c = LLNI_array_direct(value, i);
- putchar(c);
+ fputc(c, stream);
}
}
/* 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.
#include "config.h"
+
+#include "vmcore/system.h"
+
#include "vm/types.h"
#include "toolbox/hashtable.h"
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 */
#include "native/vm/nativevm.h"
#include "threads/lock-common.h"
+#include "threads/mutex.h"
#include "threads/threadlist.h"
-#include "threads/threads-common.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/python.h"
#endif
+#include "vm/jit/trap.h"
+
#include "vmcore/classcache.h"
#include "vmcore/options.h"
#include "vmcore/statistics.h"
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;
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
/* AFTER: threads_preinit */
- if (!utf8_init())
- vm_abort("vm_create: utf8_init failed");
+ utf8_init();
/* AFTER: thread_preinit */
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();
/* 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");
/* 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_
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 */
}
#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 */
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) {
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);
}
*******************************************************************************/
-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;
}
#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
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;
}
extern _Jv_JNIEnv *_Jv_env;
extern bool vm_initializing;
+extern bool vm_created;
extern bool vm_exiting;
extern char *mainstring;
/* 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.
assert(m != NULL);
LLNI_classinfo_field_get(
- m->class, method_annotationdefaults, annotationdefaults);
+ m->clazz, method_annotationdefaults, annotationdefaults);
if (!annotation_load_attribute_body(
cb, &annotationdefault,
}
if (annotationdefault != NULL) {
- slot = m - m->class->methods;
+ slot = m - m->clazz->methods;
annotationdefaults = annotation_bytearrays_insert(
annotationdefaults, slot, annotationdefault);
}
LLNI_classinfo_field_set(
- m->class, method_annotationdefaults, annotationdefaults);
+ m->clazz, method_annotationdefaults, annotationdefaults);
}
return true;
assert(m != NULL);
LLNI_classinfo_field_get(
- m->class, method_parameterannotations, parameterannotations);
+ m->clazz, method_parameterannotations, parameterannotations);
if (!annotation_load_attribute_body(
cb, &annotations,
}
if (annotations != NULL) {
- slot = m - m->class->methods;
+ slot = m - m->clazz->methods;
parameterannotations = annotation_bytearrays_insert(
parameterannotations, slot, annotations);
}
LLNI_classinfo_field_set(
- m->class, method_parameterannotations, parameterannotations);
+ m->clazz, method_parameterannotations, parameterannotations);
}
return true;
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;
}
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,
}
if (annotations != NULL) {
- slot = m - m->class->methods;
+ slot = m - m->clazz->methods;
method_annotations = annotation_bytearrays_insert(
method_annotations, slot, annotations);
}
LLNI_classinfo_field_set(
- m->class, method_annotations, method_annotations);
+ m->clazz, method_annotations, method_annotations);
}
return true;
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,
}
if (annotations != NULL) {
- slot = f - f->class->fields;
+ slot = f - f->clazz->fields;
field_annotations = annotation_bytearrays_insert(
field_annotations, slot, annotations);
}
LLNI_classinfo_field_set(
- f->class, field_annotations, field_annotations);
+ f->clazz, field_annotations, field_annotations);
}
return true;
#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;
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
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)
*******************************************************************************/
-classinfo *class_define(utf *name, classloader *cl, int32_t length, 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;
cb = NEW(classbuffer);
- cb->class = c;
+ cb->clazz = c;
cb->size = length;
cb->data = data;
cb->pos = cb->data;
/* get classinfo */
- c = cb->class;
+ c = cb->clazz;
/* check buffer size */
/* get classinfo */
- c = cb->class;
+ c = cb->clazz;
/* check buffer size */
uint16_t flags;
int i, j;
- c = cb->class;
+ c = cb->clazz;
/* get attributes count */
*******************************************************************************/
-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;
classinfo *class_array_of(classinfo *component, bool link)
{
- classloader *cl;
+ classloader_t *cl;
s4 namelen;
char *namebuf;
utf *u;
}
+/* 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
return NULL;
if (ad->arraytype == ARRAYTYPE_OBJECT)
- component = ad->componentvftbl->class;
+ component = ad->componentvftbl->clazz;
else
component = primitive_class_get_by_type(ad->arraytype);
}
+/**
+ * Return an array of declared constructors of the given class.
+ *
+ * @param c class to get the constructors of
+ * @param publicOnly show only public fields
+ *
+ * @return array of java.lang.reflect.Constructor
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
+{
+ methodinfo* m;
+ java_handle_objectarray_t* oa;
+ java_handle_t* rc;
+ int count;
+ int index;
+ int i;
+
+ /* Determine number of constructors. */
+
+ count = 0;
+
+ for (i = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+ (m->name == utf_init))
+ count++;
+ }
+
+ /* Create array of constructors. */
+
+ oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
+
+ if (oa == NULL)
+ return NULL;
+
+ /* Get the constructors and store them in the array. */
+
+ for (i = 0, index = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+ (m->name == utf_init)) {
+ /* Create Constructor object. This is actualy a
+ java_lang_reflect_Constructor pointer, but we use a
+ java_handle_t here, because we don't have the header
+ available when building vmcore. */
+
+ rc = reflect_constructor_new(m);
+
+ /* Store object into array. */
+
+ array_objectarray_element_set(oa, index, rc);
+ index++;
+ }
+ }
+
+ return oa;
+}
+#endif
+
+
+/* class_get_declaredfields ****************************************************
+
+ Return an array of declared fields of the given class.
+
+ ARGUMENTS:
+ c ............ class to get the fields of
+ publicOnly ... show only public fields
+
+ RETURN:
+ array of java.lang.reflect.Field
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
+{
+ java_handle_objectarray_t *oa;
+ fieldinfo *f;
+ java_handle_t *h;
+ int count;
+ int index;
+ int i;
+
+ /* Determine number of fields. */
+
+ count = 0;
+
+ for (i = 0; i < c->fieldscount; i++)
+ if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
+ count++;
+
+ /* Create array of fields. */
+
+ oa = builtin_anewarray(count, class_java_lang_reflect_Field);
+
+ if (oa == NULL)
+ return NULL;
+
+ /* Get the fields and store them in the array. */
+
+ for (i = 0, index = 0; i < c->fieldscount; i++) {
+ f = &(c->fields[i]);
+
+ if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
+ /* Create Field object. This is actualy a
+ java_lang_reflect_Field pointer, but we use a
+ java_handle_t here, because we don't have the header
+ available when building vmcore. */
+
+ h = reflect_field_new(f);
+
+ /* Store object into array. */
+
+ array_objectarray_element_set(oa, index, h);
+ index++;
+ }
+ }
+
+ return oa;
+}
+#endif
+
+
+/* class_get_declaredmethods ***************************************************
+
+ Return an array of declared methods of the given class.
+
+ ARGUMENTS:
+ c ............ class to get the methods of
+ publicOnly ... show only public methods
+
+ RETURN:
+ array of java.lang.reflect.Method
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
+{
+ java_handle_objectarray_t *oa; /* result: array of Method-objects */
+ methodinfo *m; /* the current method to be represented */
+ java_handle_t *h;
+ int count;
+ int index;
+ int i;
+
+ /* JOWENN: array classes do not declare methods according to mauve
+ test. It should be considered, if we should return to my old
+ clone method overriding instead of declaring it as a member
+ function. */
+
+ if (class_is_array(c))
+ return builtin_anewarray(0, class_java_lang_reflect_Method);
+
+ /* Determine number of methods. */
+
+ count = 0;
+
+ for (i = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+ ((m->name != utf_init) && (m->name != utf_clinit)) &&
+ !(m->flags & ACC_MIRANDA))
+ count++;
+ }
+
+ /* Create array of methods. */
+
+ oa = builtin_anewarray(count, class_java_lang_reflect_Method);
+
+ if (oa == NULL)
+ return NULL;
+
+ /* Get the methods and store them in the array. */
+
+ for (i = 0, index = 0; i < c->methodscount; i++) {
+ m = &(c->methods[i]);
+
+ if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+ ((m->name != utf_init) && (m->name != utf_clinit)) &&
+ !(m->flags & ACC_MIRANDA)) {
+ /* Create method object. This is actualy a
+ java_lang_reflect_Method pointer, but we use a
+ java_handle_t here, because we don't have the header
+ available when building vmcore. */
+
+ h = reflect_method_new(m);
+
+ /* Store object into array. */
+
+ array_objectarray_element_set(oa, index, h);
+ index++;
+ }
+ }
+
+ return oa;
+}
+#endif
+
+
/* class_get_declaringclass ****************************************************
If the class or interface given is a member of another class,
}
+/**
+ * Return the 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.
*******************************************************************************/
-methodinfo *class_get_enclosingmethod(classinfo *c)
+methodinfo *class_get_enclosingmethod_raw(classinfo *c)
{
constant_nameandtype *cn;
classinfo *ec;
}
+/**
+ * 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.
#include "toolbox/list.h"
#include "vm/global.h"
+#include "vm/stringlocal.h"
#if defined(ENABLE_JAVASE)
# include "vmcore/annotation.h"
#endif
#endif
- classloader *classloader; /* NULL for bootstrap classloader */
+ classloader_t *classloader; /* NULL for bootstrap classloader */
#if defined(ENABLE_JAVASE)
# if defined(WITH_CLASSPATH_SUN)
/* frequently used classes ****************************************************/
-/* important system classes */
+/* Important system classes. */
extern classinfo *class_java_lang_Object;
extern classinfo *class_java_lang_Class;
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;
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)
/* inline functions ***********************************************************/
+/**
+ * Returns the classname of the class, where slashes ('/') are
+ * replaced by dots ('.').
+ *
+ * @param c class to get name of
+ * @return classname
+ */
+inline static java_handle_t* class_get_classname(classinfo* c)
+{
+ java_handle_t *s;
+
+ /* Create a java string. */
+
+ s = javastring_new_slash_to_dot(c->name);
+
+ return s;
+}
+
+
/* class_is_primitive **********************************************************
Checks if the given class is a primitive class.
*******************************************************************************/
-static inline classloader *class_get_classloader(classinfo *c)
+static inline classloader_t *class_get_classloader(classinfo *c)
{
- classloader *cl;
+ classloader_t *cl;
cl = c->classloader;
classinfo *class_create_classinfo(utf *u);
void class_postset_header_vftbl(void);
-classinfo *class_define(utf *name, classloader *cl, int32_t length, 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);
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);
-methodinfo *class_get_enclosingmethod(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);
*******************************************************************************/
static classcache_loader_entry * classcache_new_loader_entry(
- classloader * loader,
+ classloader_t * loader,
classcache_loader_entry * next)
{
classcache_loader_entry *lden;
*******************************************************************************/
-classinfo *classcache_lookup(classloader *initloader, utf *classname)
+classinfo *classcache_lookup(classloader_t *initloader, utf *classname)
{
classcache_name_entry *en;
classcache_class_entry *clsen;
*******************************************************************************/
-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;
*******************************************************************************/
-classinfo *classcache_lookup_defined_or_initiated(classloader *loader,
+classinfo *classcache_lookup_defined_or_initiated(classloader_t *loader,
utf *classname)
{
classcache_name_entry *en;
*******************************************************************************/
-classinfo *classcache_store(classloader *initloader, classinfo *cls,
+classinfo *classcache_store(classloader_t *initloader, classinfo *cls,
bool mayfree)
{
classcache_name_entry *en;
static classcache_class_entry * classcache_find_loader(
classcache_name_entry * entry,
- classloader * loader)
+ classloader_t * loader)
{
classcache_class_entry *clsen;
classcache_loader_entry *lden;
*******************************************************************************/
#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;
*******************************************************************************/
#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;
/* 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.
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 */
};
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
/* 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.
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 */
};
/* Get class. */
- c = cb->class;
+ c = cb->clazz;
- f->class = c;
+ f->clazz = c;
/* Get access flags. */
/* 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);
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;
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(" ");
/* 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.
/* 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. */
vm_abort("linker_init: linking failed");
#endif
+ /* Important system exceptions. */
+
+ if (!link_class(class_java_lang_Exception))
+ vm_abort("linker_init: linking failed");
+
+ if (!link_class(class_java_lang_ClassNotFoundException))
+ vm_abort("linker_init: linking failed");
+
+ if (!link_class(class_java_lang_RuntimeException))
+ vm_abort("linker_init: linking failed");
/* some classes which may be used more often */
if (!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");
classinfo *cg;
classinfo *cs;
- cg = mg->class;
- cs = ms->class;
+ cg = mg->clazz;
+ cs = ms->clazz;
/* overriding a final method is illegal */
MCOPY(am, im, methodinfo, 1);
am->vftblindex = (vftbllength++);
- am->class = c;
+ am->clazz = c;
am->flags |= ACC_MIRANDA;
noabstractmethod2:
(interfacetablelength - 1) * (interfacetablelength > 1));
c->vftbl = v;
- v->class = c;
+ v->clazz = c;
v->vftbllength = vftbllength;
v->interfacetablelength = interfacetablelength;
v->arraydesc = arraydesc;
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 */
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_util_HashMap =
- load_class_bootstrap(utf_new_char("java/util/HashMap"));
+ 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);
- class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
+# 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_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
+
+ class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
+ class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
# if defined(WITH_CLASSPATH_SUN)
class_sun_reflect_MagicAccessorImpl =
*******************************************************************************/
-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;
*******************************************************************************/
-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;
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))
/* get classinfo */
- c = cb->class;
+ c = cb->clazz;
/* check remaining bytecode */
{
methodinfo *m;
java_handle_t *clo;
- classloader *cl;
+ classloader_t *cl;
classinfo *c;
assert(class_java_lang_Object);
*******************************************************************************/
-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;
/* Get the classbuffer's class. */
- c = cb->class;
+ c = cb->clazz;
if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
return false;
/* 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. */
/* 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. */
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;
/* Get the classbuffer's class. */
- c = cb->class;
+ c = cb->clazz;
/* Check if the class is already loaded. */
*******************************************************************************/
-classinfo *load_newly_created_array(classinfo *c, classloader *loader)
+classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
{
classinfo *comp = NULL;
methodinfo *clone;
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 */
/* classbuffer ****************************************************************/
struct classbuffer {
- classinfo *class; /* pointer to classinfo structure */
+ 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 */
*******************************************************************************/
#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
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);
/* 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 */
/* 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.
#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)
#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
/* get classinfo */
- c = cb->class;
+ c = cb->clazz;
LOCK_INIT_OBJECT_LOCK(&(m->header));
/* 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;
/* 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];
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;
/* parameter annotations of */
/* the declaring class */
- c = m->class;
+ c = m->clazz;
slot = m - c->methods;
parameterAnnotations = NULL;
/* annotation default values of */
/* the declaring class */
- c = m->class;
+ c = m->clazz;
slot = m - c->methods;
annotationDefault = NULL;
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(".");
/* 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.
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 */
};
+/* 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);
#include "config.h"
-#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
/* 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;
-int 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)
-int opt_GCDebugRootSet = 0;
-int opt_GCStress = 0;
+int opt_GCDebugRootSet = 0;
+int opt_GCStress = 0;
#endif
#if defined(ENABLE_INLINING)
-int opt_Inline = 0;
+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_MaxPermSize = 0;
-int opt_PermSize = 0;
-int opt_PrintConfig = 0;
-int opt_ProfileGCMemoryUsage = 0;
-int opt_ProfileMemoryUsage = 0;
-FILE *opt_ProfileMemoryUsageGNUPlot = NULL;
+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;
+int opt_TestReplacement = 0;
#endif
-int opt_ThreadStackSize = 0;
-int opt_TraceCompilerCalls = 0;
-int opt_TraceExceptions = 0;
+int opt_TraceCompilerCalls = 0;
+int opt_TraceExceptions = 0;
+int opt_TraceHPI = 0;
#if defined(ENABLE_INLINING) && !defined(NDEBUG)
-int opt_TraceInlining = 0;
+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;
+int opt_TraceJavaCalls = 0;
+int opt_TraceJNICalls = 0;
+int opt_TraceJVMCalls = 0;
+int opt_TraceJVMCallsVerbose = 0;
+int opt_TraceLinkClass = 0;
#if defined(ENABLE_REPLACEMENT)
-int opt_TraceReplacement = 0;
+int opt_TraceReplacement = 0;
#endif
-int opt_TraceSubsystemInitialization = 0;
+int opt_TraceSubsystemInitialization = 0;
+int opt_TraceTraps = 0;
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,
OPT_InlineCount,
OPT_InlineMaxSize,
OPT_InlineMinSize,
- OPT_MaxPermSize,
- OPT_PermSize,
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_TraceLinkClass,
OPT_TraceReplacement,
OPT_TraceSubsystemInitialization,
+ OPT_TraceTraps,
OPT_Vmlog,
OPT_VmlogStrings,
OPT_VmlogIgnore
option_t options_XX[] = {
+ /* Options which must always be available (production options in
+ HotSpot). */
+
+ { "MaxDirectMemorySize", OPT_MaxDirectMemorySize, OPT_TYPE_VALUE, "Maximum total size of NIO direct-buffer allocations" },
+ { "MaxPermSize", OPT_MaxPermSize, OPT_TYPE_VALUE, "not implemented" },
+ { "PermSize", OPT_PermSize, OPT_TYPE_VALUE, "not implemented" },
+ { "ThreadStackSize", OPT_ThreadStackSize, OPT_TYPE_VALUE, "TODO" },
+
+ /* Debugging options which can be turned off. */
+
{ "DebugExceptions", OPT_DebugExceptions, OPT_TYPE_BOOLEAN, "debug exceptions" },
{ "DebugFinalizer", OPT_DebugFinalizer, OPT_TYPE_BOOLEAN, "debug finalizer thread" },
{ "DebugLocalReferences", OPT_DebugLocalReferences, OPT_TYPE_BOOLEAN, "print debug information for local reference tables" },
{ "InlineMinSize", OPT_InlineMinSize, OPT_TYPE_VALUE, "minimum size for inlined result" },
#endif
#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" },
#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" },
+ { "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
{ "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" },
*******************************************************************************/
-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;
/* Process the option. */
switch (opt->value) {
+
+ /* Options which must always be available (production options
+ in HotSpot). */
+
+ case OPT_MaxDirectMemorySize:
+ opt_MaxDirectMemorySize = system_atoi(value);
+ break;
+
+ case OPT_MaxPermSize:
+ /* Currently ignored. */
+ break;
+
+ case OPT_PermSize:
+ /* Currently ignored. */
+ break;
+
+ case OPT_ThreadStackSize:
+ /* currently ignored */
+ break;
+
+ /* Debugging options which can be turned off. */
+
case OPT_DebugExceptions:
opt_DebugExceptions = enable;
break;
case OPT_InlineCount:
if (value != NULL)
- opt_InlineCount = atoi(value);
+ opt_InlineCount = system_atoi(value);
break;
case OPT_InlineMaxSize:
if (value != NULL)
- opt_InlineMaxSize = atoi(value);
+ opt_InlineMaxSize = system_atoi(value);
break;
case OPT_InlineMinSize:
if (value != NULL)
- opt_InlineMinSize = atoi(value);
+ opt_InlineMinSize = system_atoi(value);
break;
#endif
#endif
- case OPT_MaxPermSize:
- /* currently ignored */
- break;
-
- case OPT_PermSize:
- /* currently ignored */
- break;
-
case OPT_PrintConfig:
opt_PrintConfig = enable;
break;
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 */
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;
break;
#endif
- case OPT_ThreadStackSize:
- /* currently ignored */
- break;
-
case OPT_TraceCompilerCalls:
opt_TraceCompilerCalls = enable;
break;
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 = atoi(value);
+ opt_TraceInlining = system_atoi(value);
break;
#endif
if (value == NULL)
opt_TraceReplacement = 1;
else
- opt_TraceReplacement = atoi(value);
+ opt_TraceReplacement = system_atoi(value);
break;
#endif
opt_TraceSubsystemInitialization = enable;
break;
+ case OPT_TraceTraps:
+ opt_TraceTraps = enable;
+ break;
+
#if defined(ENABLE_VMLOG)
case OPT_Vmlog:
if (value == NULL)
/* NOTE: For better readability keep these alpha-sorted. */
-extern int opt_DebugExceptions;
-extern int opt_DebugFinalizer;
-extern int opt_DebugLocalReferences;
-extern int opt_DebugLocks;
-extern int opt_DebugPatcher;
-extern int opt_DebugPackage;
-extern int opt_DebugProperties;
-extern int opt_DebugStackFrameInfo;
-extern int opt_DebugStackTrace;
-extern int opt_DebugThreads;
+/* 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;
+extern int opt_DebugLocks;
+extern int opt_DebugPatcher;
+extern int opt_DebugPackage;
+extern int opt_DebugProperties;
+extern int opt_DebugStackFrameInfo;
+extern int opt_DebugStackTrace;
+extern int opt_DebugThreads;
#if defined(ENABLE_DISASSEMBLER)
-extern int opt_DisassembleStubs;
+extern int opt_DisassembleStubs;
#endif
#if defined(ENABLE_GC_CACAO)
-extern int opt_GCDebugRootSet;
-extern int opt_GCStress;
+extern int opt_GCDebugRootSet;
+extern int opt_GCStress;
#endif
#if defined(ENABLE_INLINING)
-extern int opt_Inline;
+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;
+extern int opt_InlineAll;
+extern int opt_InlineCount;
+extern int opt_InlineMaxSize;
+extern int opt_InlineMinSize;
#endif
#endif
-extern int opt_MaxPermSize;
-extern int opt_PermSize;
-extern int opt_PrintConfig;
-extern int opt_ProfileGCMemoryUsage;
-extern int opt_ProfileMemoryUsage;
-extern FILE *opt_ProfileMemoryUsageGNUPlot;
+extern int opt_PrintConfig;
+extern int opt_ProfileGCMemoryUsage;
+extern int opt_ProfileMemoryUsage;
+extern FILE *opt_ProfileMemoryUsageGNUPlot;
#if defined(ENABLE_REPLACEMENT)
-extern int opt_TestReplacement;
+extern int opt_TestReplacement;
#endif
-extern int opt_ThreadStackSize;
-extern int opt_TraceCompilerCalls;
-extern int opt_TraceExceptions;
+extern int opt_TraceCompilerCalls;
+extern int opt_TraceExceptions;
+extern int opt_TraceHPI;
#if defined(ENABLE_INLINING) && !defined(NDEBUG)
-extern int opt_TraceInlining;
+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;
+extern int opt_TraceJavaCalls;
+extern int opt_TraceJNICalls;
+extern int opt_TraceJVMCalls;
+extern int opt_TraceJVMCallsVerbose;
+extern int opt_TraceLinkClass;
#if defined(ENABLE_REPLACEMENT)
-extern int opt_TraceReplacement;
+extern int opt_TraceReplacement;
#endif
-extern int opt_TraceSubsystemInitialization;
+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);
/* 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.
} 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"
/* 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 */
};
/* 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` */
/* 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.
/* get classinfo */
- c = cb->class;
+ c = cb->clazz;
/* allocate stack map structure */
{
#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 */
if (classfile) { /* file exists */
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;
# include <fcntl.h>
#endif
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
# if defined(HAVE_LIBGEN_H)
# include <libgen.h>
# endif
#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)
#endif
}
-#if defined(WITH_JRE_LAYOUT)
+#if defined(ENABLE_JRE_LAYOUT)
inline static char *system_dirname(char *path)
{
#if defined(HAVE_DIRNAME)
#endif
}
+#if defined(__LINUX__)
inline static int system_scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
+#elif defined(__IRIX__)
+inline static int system_scandir(const char *dir, struct dirent ***namelist, int(*filter)(dirent_t *), int(*compar)(dirent_t **, dirent_t **))
+#else
+inline static int system_scandir(const char *dir, struct dirent ***namelist, int(*filter)(struct dirent *), int(*compar)(const void *, const void *))
+#endif
{
#if defined(HAVE_SCANDIR)
return scandir(dir, namelist, filter, compar);
#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)
utf *utf_java_lang_InterruptedException;
utf *utf_java_lang_NegativeArraySizeException;
utf *utf_java_lang_NullPointerException;
+utf *utf_java_lang_RuntimeException;
utf *utf_java_lang_StringIndexOutOfBoundsException;
utf *utf_java_lang_reflect_InvocationTargetException;
utf *utf_java_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
utf *utf_clinit; /* <clinit> */
utf *utf_clone; /* clone */
utf *utf_finalize; /* finalize */
+utf *utf_invoke;
+utf *utf_main;
utf *utf_run; /* run */
utf *utf_add;
utf *utf_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;
*******************************************************************************/
-bool utf8_init(void)
+void utf8_init(void)
{
TRACESUBSYSTEMINITIALIZATION("utf8_init");
utf_java_lang_NullPointerException =
utf_new_char("java/lang/NullPointerException");
+ utf_java_lang_RuntimeException =
+ utf_new_char("java/lang/RuntimeException");
+
utf_java_lang_StringIndexOutOfBoundsException =
utf_new_char("java/lang/StringIndexOutOfBoundsException");
utf_java_lang_reflect_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
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");
utf_java_lang_Thread_java_lang_Throwable__V =
utf_new_char("(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
+ utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V =
+ utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
+
utf_java_lang_Throwable__void = utf_new_char("(Ljava/lang/Throwable;)V");
utf_java_lang_Throwable__java_lang_Throwable =
utf_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;
}
/* 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.
extern utf *utf_java_lang_InterruptedException;
extern utf *utf_java_lang_NegativeArraySizeException;
extern utf *utf_java_lang_NullPointerException;
+extern utf *utf_java_lang_RuntimeException;
extern utf *utf_java_lang_StringIndexOutOfBoundsException;
extern utf *utf_java_lang_reflect_InvocationTargetException;
extern utf *utf_java_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
extern utf *utf_clinit;
extern utf *utf_clone;
extern utf *utf_finalize;
+extern utf *utf_invoke;
+extern utf *utf_main;
extern utf *utf_run;
extern utf *utf_add;
extern utf *utf_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;
/* 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);
/* 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.
cb = NEW(classbuffer);
- cb->class = c;
+ cb->clazz = c;
cb->size = htzfe->uncompressedsize;
cb->data = outdata;
cb->pos = outdata;
+++ /dev/null
-public class A2 {
-static A a2 = new A();
-static int myZero;
-
-}
-
-
+++ /dev/null
-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();
-
-
-}
-}
-}
+++ /dev/null
-public class AA1 extends AA
-{
-public void f() {
- int x = 3;
-}
-}
+++ /dev/null
-public class AA2 extends AA1
-{
-public void f3() {
- int x = 3;
-}
-}
+++ /dev/null
-public class BB extends AA
-{
-public void f() {
- int x = 2;
- GG g = new GG();
-}
-}
+++ /dev/null
-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);
- }
-}
-
+++ /dev/null
-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();
- }
-}
-
+++ /dev/null
-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);
- }
-}
-
-
+++ /dev/null
-public class CC extends AA2
-{
-public void f() {
- int x = 3;
-}
-}
+++ /dev/null
-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;
-}
-}
+++ /dev/null
-public class DD extends CC
-{
-public void f2() {
- int x = 4;
-}
-}
+++ /dev/null
-public class EE extends CC
-{
-public void f2() {
- int x = 6;
-}
-}
+++ /dev/null
-public class GG extends BB
-{
-public void f() {
- int x = 5;
-}
-}
+++ /dev/null
-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);
- }
- }
-}
+++ /dev/null
-interface II{
-public void foo();
-public void foo2();
-}
+++ /dev/null
-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;
-}
-}
+++ /dev/null
-class IIBB extends IIAA {
-public void foo() {
- yy=0;
- zz=0;
- int j= zz;
-}
-
-public void bar ( ) {
- yy=1;
-}
-}
+++ /dev/null
-class IICC extends IIAA {
-public void foo( ) {
- this.bar();
-}
-}
+++ /dev/null
-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();
-}
-
-}
## 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:
+++ /dev/null
-
-public class n implements a {
- public void do_a () { };
- public void do_a2 () { };
- public void do_b () { };
- }
-
\ No newline at end of file
+++ /dev/null
-public class HelloWorld {
- public static void main(String[] argv) {
- System.out.println("OK");
- }
-}
SUBDIRS = \
assertion \
- codepatching \
+ bugzilla \
jasmin \
+ junit \
native \
resolving
-JAVA = $(top_builddir)/src/cacao/cacao
-BOOTCLASSPATH = $(top_builddir)/src/lib/classes:$(CLASSPATH_CLASSES)
-JAVACMD = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
-JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
+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 \
fptest.output \
fp.output\
extest.2output \
- clinitexception.2output \
LoadDisplacementOverflow.output \
FieldDisplacementOverflow.output \
StackDisplacementOverflow.output \
*.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:
- @$(JAVACCMD) -d . $(SOURCE_FILES)
+ $(JAVACCMD) -d . $(SOURCE_FILES)
-$(SIMPLE_JAVA_TESTS):
- @echo "$@: "
- @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(JAVACMD) $@
+run: $(OUTPUT_JAVA_TESTS)
$(OUTPUT_JAVA_TESTS):
@LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(SHELL) $(srcdir)/Test.sh "$(JAVACMD)" $@ $(srcdir)
## 02110-1301, USA.
-JAVA = $(top_builddir)/src/cacao/cacao
-BOOTCLASSPATH = $(top_builddir)/src/lib/classes:$(CLASSPATH_CLASSES)
-JAVACMD = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
-JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
+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 \
ESA_TEST1 \
ESA_TEST2
-check: build $(ASSERTION_TESTS)
+check: build run
build:
- @$(JAVACCMD) -d . $(SOURCE_FILES)
+ $(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)
--- /dev/null
+/* 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;
+ }
+}
--- /dev/null
+## 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:
--- /dev/null
+/* 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();
+ }
+}
--- /dev/null
+/* 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) {
+ }
+ }
+}
--- /dev/null
+/* 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);
+ }
+ }
+}
--- /dev/null
+/* 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;
+ na[0][0] = null;
+ fail("Should throw ClassCastException");
+ } catch (ClassCastException success) {
+ }
+ }
+}
+++ /dev/null
-Exception in thread "main" java.lang.ExceptionInInitializerError
- <<No stacktrace available>>
-Caused by: java.lang.RuntimeException
- at clinitexception.<clinit>(clinitexception.java:4)
+++ /dev/null
-public class clinitexception {
- static {
- if (true)
- throw new RuntimeException();
- }
-
- public static void main(String[] argv) {
- }
-}
+++ /dev/null
-## tests/regression/codepatching/Makefile.am
-##
-## Copyright (C) 1996-2005, 2006, 2008
-## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-##
-## This file is part of CACAO.
-##
-## This program is free software; you can redistribute it and/or
-## modify it under the terms of the GNU General Public License as
-## published by the Free Software Foundation; either version 2, or (at
-## your option) any later version.
-##
-## This program is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-## 02110-1301, USA.
-
-
-JAVA = $(top_builddir)/src/cacao/cacao
-BOOTCLASSPATH = $(top_builddir)/src/lib/classes:$(CLASSPATH_CLASSES)
-JAVACMD = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
-JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
-
-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
-
-build:
- @$(JAVACCMD) -d . $(SOURCE_FILES)
-
-check: build
- @LD_LIBRARY_PATH=$(top_builddir)/src/cacao/.libs $(JAVACMD) test
-
-remove:
- $(RM) $(CLASSES)
-
-
-## Local variables:
-## mode: Makefile
-## indent-tabs-mode: t
-## c-basic-offset: 4
-## tab-width: 8
-## compile-command: "automake --add-missing"
-## End:
+++ /dev/null
-public class aastoreconstClass {
-}
-
+++ /dev/null
-public class checkcastC {
-}
+++ /dev/null
-public interface checkcastI {
-}
+++ /dev/null
-public class getfieldD {
- public double d = 789.012;
-}
+++ /dev/null
-public class getfieldF {
- public float f = 123.456F;
-}
+++ /dev/null
-public class getfieldI {
- public int i = 123;
-}
+++ /dev/null
-public class getfieldJ {
- public long l = 1234567890123L;
-}
+++ /dev/null
-public class getfieldL {
- public Object o = null;
-}
+++ /dev/null
-public class getstaticD {
- public static double d = 789.012;
-}
+++ /dev/null
-public class getstaticF {
- public static float f = 123.456F;
-}
+++ /dev/null
-public class getstaticI {
- public static int i = 123;
-}
+++ /dev/null
-public class getstaticJ {
- public static long l = 1234567890123L;
-}
+++ /dev/null
-public class getstaticL {
- public static Object o = null;
-}
+++ /dev/null
-public class instanceofC {
-}
+++ /dev/null
-public interface instanceofI {
-}
+++ /dev/null
-public class invokespecial {
- public invokespecial() {
- System.out.println("OK");
- }
-}
+++ /dev/null
-public class invokestatic {
- public static void sub() {
- System.out.println("OK");
- }
-}
+++ /dev/null
-public class multianewarray {
-}
+++ /dev/null
-public class newarray {
-}
+++ /dev/null
-public class putfieldD {
- public double d;
-}
+++ /dev/null
-public class putfieldF {
- public float f;
-}
+++ /dev/null
-public class putfieldI {
- public int i;
-}
+++ /dev/null
-public class putfieldJ {
- public long l;
-}
+++ /dev/null
-public class putfieldL {
- public Object o;
-}
+++ /dev/null
-public class putfieldconstC {
- public Class c;
-}
+++ /dev/null
-public class putfieldconstD {
- public double d;
-}
+++ /dev/null
-public class putfieldconstF {
- public float f;
-}
+++ /dev/null
-public class putfieldconstI {
- public int i;
-}
+++ /dev/null
-public class putfieldconstJ {
- public long l;
-}
+++ /dev/null
-public class putfieldconstL {
- public Object o;
-}
+++ /dev/null
-public class putstaticD {
- public static double d;
-}
+++ /dev/null
-public class putstaticF {
- public static float f;
-}
+++ /dev/null
-public class putstaticI {
- public static int i;
-}
+++ /dev/null
-public class putstaticJ {
- public static long l;
-}
+++ /dev/null
-public class putstaticL {
- public static Object o;
-}
+++ /dev/null
-public class putstaticconstC {
- public static Class c;
-}
+++ /dev/null
-public class putstaticconstD {
- public static double d;
-}
+++ /dev/null
-public class putstaticconstF {
- public static float f;
-}
+++ /dev/null
-public class putstaticconstI {
- public static int i;
-}
+++ /dev/null
-public class putstaticconstJ {
- public static long l;
-}
+++ /dev/null
-public class putstaticconstL {
- public static Object o;
-}
+++ /dev/null
-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
-
## 02110-1301, USA.
-JAVA = $(top_builddir)/src/cacao/cacao
-BOOTCLASSPATH = $(top_builddir)/src/lib/classes:$(CLASSPATH_CLASSES)
-JAVACMD = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
-JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
-
-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="$(JAVACMD)" $(srcdir)/runtest $(JASMIN_TESTS)
+check: build run
+
+build:
+ $(JAVACMD) -cp /usr/share/java/cup.jar:/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
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
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]*,,')
# run the test
- $TIMEOUTRUN $JAVA $JAVAFLAGS "$TESTBASENAME" >"$TESTOUT" 2>"$TESTERR"
+ $TIMEOUTRUN $JAVA $JAVAFLAGS "$TESTBASENAME" >"$TESTOUT" 2>"$TESTERR"
TESTSTATUS=$?
if [ $TESTSTATUS -ne $EXPECTSTATUS ] ; then
--- /dev/null
+.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
+++ /dev/null
-.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
-
--- /dev/null
+.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
+
+++ /dev/null
-.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
-
--- /dev/null
+.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
+
+++ /dev/null
-.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
-
--- /dev/null
+.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
+
--- /dev/null
+/* 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;
+ }
+}
--- /dev/null
+## 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:
--- /dev/null
+/* 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();
+ }
+}
--- /dev/null
+/* 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 {}
+}
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
-JAVAH = $(CACAOH)
-BOOTCLASSPATH = $(top_builddir)/src/lib/classes:$(CLASSPATH_CLASSES)
-JAVACMD = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
-JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
-JAVAHCMD = $(JAVAH) -bootclasspath $(BOOTCLASSPATH)
+JAVA = $(top_builddir)/src/cacao/cacao
+JAVAH = $(CACAOH)
+JAVACMD = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
+JAVAHCMD = $(JAVAH) -bootclasspath $(BOOTCLASSPATH)
SOURCE_FILES = \
checkjni.java \
$(TESTNAMES) $(NOTESTNAMES):
@$(JAVACCMD) -d . $(srcdir)/$@.java
@$(JAVAHCMD) $@
- @$(CC) -shared $(AM_CPPFLAGS) $(CFLAGS) $(srcdir)/$@.c -o lib$@.so -fPIC
+ @$(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)
classes2 \
classes3
-JAVA = $(top_builddir)/src/cacao/cacao
-BOOTCLASSPATH = $(top_builddir)/src/lib/classes:$(CLASSPATH_CLASSES)
-JAVACMD = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
-JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
+JAVA = $(top_builddir)/src/cacao/cacao
+JAVACMD = $(JAVA) -Xbootclasspath:$(BOOTCLASSPATH)
+JAVACCMD = $(JAVAC) -bootclasspath $(BOOTCLASSPATH)
HARNESS_SOURCE_FILES = \
$(srcdir)/TestController.java \
+++ /dev/null
-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;
- }
-}
+// 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;
+// 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.
--- /dev/null
+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:
+ */