Merge branch 'jdk7'

This commit is contained in:
Joel Dice 2012-05-11 16:41:18 -06:00
commit f0152f1d33
22 changed files with 595 additions and 224 deletions

View File

@ -408,7 +408,6 @@ Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
if (not exists(chars)) {
int fd = OPEN(chars, O_CREAT | O_WRONLY | O_EXCL, 0600);
if (fd == -1) {
fprintf(stderr, "errno %d\n", errno);
if (errno != EEXIST) {
throwNewErrno(e, "java/io/IOException");
}

View File

@ -0,0 +1,13 @@
/* Copyright (c) 2012, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.lang;
public class ReflectiveOperationException extends Exception { }

View File

@ -11,7 +11,8 @@ public final class Unsafe {
public native long allocateMemory(long bytes);
public native void setMemory(long address, long count, byte value);
public native void setMemory
(Object base, long offset, long count, byte value);
public native void freeMemory(long address);

View File

@ -115,8 +115,13 @@ ifneq ($(openjdk),)
else
options := $(options)-openjdk
test-executable = $(shell pwd)/$(executable-dynamic)
library-path = \
$(library-path-variable)=$(build):$(openjdk)/jre/lib/$(openjdk-arch)
ifeq ($(build-platform),darwin)
library-path = \
$(library-path-variable)=$(build):$(openjdk)/jre/lib
else
library-path = \
$(library-path-variable)=$(build):$(openjdk)/jre/lib/$(openjdk-arch)
endif
javahome = "$$($(native-path) "$(openjdk)/jre")"
endif
@ -308,9 +313,11 @@ ifeq ($(platform),darwin)
endif
version-script-flag =
lflags = $(common-lflags) -ldl -framework CoreFoundation
lflags = $(common-lflags) -ldl -framework CoreFoundation \
-Wl,-compatibility_version,1.0.0
ifneq ($(arch),arm)
lflags += -framework CoreServices
lflags += -framework CoreServices -framework SystemConfiguration \
-framework Security
endif
ifeq ($(bootimage),true)
bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx
@ -376,10 +383,9 @@ ifeq ($(platform),windows)
so-suffix = .dll
exe-suffix = .exe
lflags = -L$(lib) $(common-lflags) -lws2_32 -mwindows -mconsole
lflags = -L$(lib) $(common-lflags) -lws2_32 -liphlpapi -mwindows -mconsole
cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500
ifeq (,$(filter mingw32 cygwin,$(build-platform)))
openjdk-extra-cflags += -I$(src)/openjdk/caseSensitive
cxx = x86_64-w64-mingw32-g++ -m32
@ -417,6 +423,8 @@ ifeq ($(platform),windows)
strip = x86_64-w64-mingw32-strip
inc = "$(win64)/include"
lib = "$(win64)/lib"
else
shared += -Wl,--add-stdcall-alias
endif
endif
@ -1003,6 +1011,18 @@ $(openjdk-objects): $(build)/openjdk/%-openjdk.o: $(openjdk-src)/%.c \
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
sed 's/^static jclass ia_class;//' < $(<) > $(build)/openjdk/$(notdir $(<))
ifeq ($(ios),true)
sed \
-e 's/^#ifndef __APPLE__/#if 1/' \
-e 's/^#ifdef __APPLE__/#if 0/' \
< "$(openjdk-src)/solaris/native/java/lang/ProcessEnvironment_md.c" \
> $(build)/openjdk/ProcessEnvironment_md.c
sed \
-e 's/^#ifndef __APPLE__/#if 1/' \
-e 's/^#ifdef __APPLE__/#if 0/' \
< "$(openjdk-src)/solaris/native/java/lang/UNIXProcess_md.c" \
> $(build)/openjdk/UNIXProcess_md.c
endif
$(cc) -fPIC $(openjdk-extra-cflags) $(openjdk-cflags) \
$(optimization-cflags) -w -c $(build)/openjdk/$(notdir $(<)) \
$(call output,$(@))
@ -1033,6 +1053,42 @@ ifeq ($(platform),windows)
< "$(openjdk-src)/windows/native/java/net/NetworkInterface.h" \
> $(build)/openjdk/NetworkInterface.h
echo 'static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);' >> $(build)/openjdk/NetworkInterface.h
endif
ifeq ($(platform),darwin)
mkdir -p $(build)/openjdk/netinet
for file in \
/usr/include/netinet/ip.h \
/usr/include/netinet/in_systm.h \
/usr/include/netinet/ip_icmp.h \
/usr/include/netinet/in_var.h \
/usr/include/netinet/icmp6.h \
/usr/include/netinet/ip_var.h; do \
if [ ! -f "$(build)/openjdk/netinet/$$(basename $${file})" ]; then \
ln "$${file}" "$(build)/openjdk/netinet/$$(basename $${file})"; \
fi; \
done
mkdir -p $(build)/openjdk/netinet6
for file in \
/usr/include/netinet6/in6_var.h; do \
if [ ! -f "$(build)/openjdk/netinet6/$$(basename $${file})" ]; then \
ln "$${file}" "$(build)/openjdk/netinet6/$$(basename $${file})"; \
fi; \
done
mkdir -p $(build)/openjdk/net
for file in \
/usr/include/net/if_arp.h; do \
if [ ! -f "$(build)/openjdk/net/$$(basename $${file})" ]; then \
ln "$${file}" "$(build)/openjdk/net/$$(basename $${file})"; \
fi; \
done
mkdir -p $(build)/openjdk/sys
for file in \
/usr/include/sys/kern_event.h \
/usr/include/sys/sys_domain.h; do \
if [ ! -f "$(build)/openjdk/sys/$$(basename $${file})" ]; then \
ln "$${file}" "$(build)/openjdk/sys/$$(basename $${file})"; \
fi; \
done
endif
@touch $(@)
@ -1044,6 +1100,7 @@ $(openjdk-jar-dep):
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/rt.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/jsse.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/jce.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/charsets.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/ext/sunjce_provider.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/resources.jar")")
@touch $(@)

View File

@ -45,7 +45,6 @@ openjdk-sources = \
$(openjdk-src)/share/native/java/util/zip/CRC32.c \
$(openjdk-src)/share/native/java/util/zip/Deflater.c \
$(openjdk-src)/share/native/java/util/zip/Inflater.c \
$(openjdk-src)/share/native/java/util/zip/ZipEntry.c \
$(openjdk-src)/share/native/java/util/zip/ZipFile.c \
$(openjdk-src)/share/native/java/util/zip/zip_util.c \
$(openjdk-src)/share/native/sun/management/VMManagementImpl.c \
@ -76,6 +75,7 @@ openjdk-headers-classes = \
java.lang.Double \
java.lang.Float \
java.lang.Integer \
java.lang.Long \
java.lang.Object \
java.lang.Package \
java.lang.Runtime \
@ -124,7 +124,7 @@ openjdk-headers-classes = \
sun.net.spi.DefaultProxySelector \
sun.nio.ch.FileKey \
sun.nio.ch.FileChannelImpl \
sun.nio.ch.FileDispatcher \
sun.nio.ch.FileDispatcherImpl \
sun.nio.ch.DatagramChannelImpl \
sun.nio.ch.DatagramDispatcher \
sun.nio.ch.IOStatus \
@ -173,6 +173,7 @@ endif
ifeq ($(platform),windows)
openjdk-sources += \
$(openjdk-src)/windows/native/common/jni_util_md.c \
$(openjdk-src)/windows/native/java/io/canonicalize_md.c \
$(openjdk-src)/windows/native/java/io/Console_md.c \
$(openjdk-src)/windows/native/java/io/FileDescriptor_md.c \
@ -193,7 +194,6 @@ ifeq ($(platform),windows)
$(openjdk-src)/windows/native/java/net/Inet6AddressImpl.c \
$(openjdk-src)/windows/native/java/net/NetworkInterface.c \
$(openjdk-src)/windows/native/java/net/NetworkInterface_winXP.c \
$(openjdk-src)/windows/native/java/net/NetworkInterface_win9x.c \
$(openjdk-src)/windows/native/java/net/SocketInputStream.c \
$(openjdk-src)/windows/native/java/net/SocketOutputStream.c \
$(openjdk-src)/windows/native/java/util/WindowsPreferences.c \
@ -203,7 +203,7 @@ ifeq ($(platform),windows)
$(openjdk-src)/windows/native/sun/nio/ch/DatagramChannelImpl.c \
$(openjdk-src)/windows/native/sun/nio/ch/DatagramDispatcher.c \
$(openjdk-src)/windows/native/sun/nio/ch/FileChannelImpl.c \
$(openjdk-src)/windows/native/sun/nio/ch/FileDispatcher.c \
$(openjdk-src)/windows/native/sun/nio/ch/FileDispatcherImpl.c \
$(openjdk-src)/windows/native/sun/nio/ch/FileKey.c \
$(openjdk-src)/windows/native/sun/nio/ch/IOUtil.c \
$(openjdk-src)/windows/native/sun/nio/ch/Net.c \
@ -211,6 +211,7 @@ ifeq ($(platform),windows)
$(openjdk-src)/windows/native/sun/nio/ch/SocketChannelImpl.c \
$(openjdk-src)/windows/native/sun/nio/ch/SocketDispatcher.c \
$(openjdk-src)/windows/native/sun/nio/ch/WindowsSelectorImpl.c \
$(openjdk-src)/windows/native/sun/nio/fs/WindowsNativeDispatcher.c \
$(openjdk-src)/windows/native/sun/security/provider/WinCAPISeedGenerator.c
openjdk-headers-classes += \
@ -218,6 +219,7 @@ ifeq ($(platform),windows)
java.lang.ProcessImpl \
sun.io.Win32ErrorMode \
sun.nio.ch.WindowsSelectorImpl \
sun.nio.fs.WindowsNativeDispatcher \
openjdk-cflags += \
"-I$(openjdk-src)/windows/javavm/export" \
@ -228,6 +230,9 @@ ifeq ($(platform),windows)
"-I$(openjdk-src)/windows/native/sun/nio/ch" \
"-I$(openjdk-src)/windows/javavm/include" \
"-I$(root)/win32/include" \
-DLOCALE_SNAME=0x0000005c \
-DLOCALE_SISO3166CTRYNAME2=0x00000068 \
-DLOCALE_SISO639LANGNAME2=0x00000067 \
-D_JNI_IMPLEMENTATION_ \
-D_JAVASOFT_WIN32_TYPEDEF_MD_H_ \
-Ds6_words=_s6_words \
@ -235,6 +240,7 @@ ifeq ($(platform),windows)
else
openjdk-sources += \
$(openjdk-src)/solaris/native/common/jdk_util_md.c \
$(openjdk-src)/solaris/native/common/jni_util_md.c \
$(openjdk-src)/solaris/native/java/io/canonicalize_md.c \
$(openjdk-src)/solaris/native/java/io/Console_md.c \
$(openjdk-src)/solaris/native/java/io/FileDescriptor_md.c \
@ -265,30 +271,26 @@ else
$(openjdk-src)/solaris/native/sun/nio/ch/DatagramChannelImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/DatagramDispatcher.c \
$(openjdk-src)/solaris/native/sun/nio/ch/FileChannelImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/FileDispatcher.c \
$(openjdk-src)/solaris/native/sun/nio/ch/FileDispatcherImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/FileKey.c \
$(openjdk-src)/solaris/native/sun/nio/ch/IOUtil.c \
$(openjdk-src)/solaris/native/sun/nio/ch/Net.c \
$(openjdk-src)/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/SocketChannelImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/SocketDispatcher.c \
$(openjdk-src)/solaris/native/sun/nio/ch/EPollArrayWrapper.c \
$(openjdk-src)/solaris/native/sun/nio/ch/PollArrayWrapper.c \
$(openjdk-src)/solaris/native/sun/nio/ch/InheritedChannel.c \
$(openjdk-src)/solaris/native/sun/nio/ch/NativeThread.c \
ifeq ($(platform),linux)
openjdk-sources += \
$(openjdk-src)/solaris/native/java/net/linux_close.c
endif
$(openjdk-src)/solaris/native/sun/nio/fs/UnixNativeDispatcher.c \
openjdk-headers-classes += \
java.net.PlainDatagramSocketImpl \
java.io.UnixFileSystem \
sun.nio.ch.InheritedChannel \
sun.nio.ch.EPollArrayWrapper \
sun.nio.fs.UnixNativeDispatcher \
openjdk-cflags += "-I$(openjdk-src)/solaris/javavm/export" \
openjdk-cflags += \
"-I$(openjdk-src)/solaris/javavm/export" \
"-I$(openjdk-src)/solaris/native/common" \
"-I$(openjdk-src)/solaris/native/java/io" \
"-I$(openjdk-src)/solaris/native/java/lang" \
@ -297,10 +299,45 @@ else
"-I$(openjdk-src)/solaris/native/sun/management" \
"-I$(openjdk-src)/solaris/native/sun/nio/ch" \
"-I$(openjdk-src)/solaris/javavm/include" \
"-I$(openjdk-src)/solaris/hpi/include"
"-I$(openjdk-src)/solaris/hpi/include" \
"-I$(openjdk-src)/solaris/native/common/deps"
ifeq ($(platform),linux)
openjdk-sources += \
$(openjdk-src)/solaris/native/java/net/linux_close.c \
$(openjdk-src)/solaris/native/common/deps/syscalls_fp.c \
$(openjdk-src)/solaris/native/common/deps/gconf2/gconf_fp.c \
$(openjdk-src)/solaris/native/common/deps/glib2/gio_fp.c \
$(openjdk-src)/solaris/native/sun/nio/ch/EPollArrayWrapper.c
openjdk-headers-classes += \
sun.nio.ch.EPollArrayWrapper
openjdk-cflags += \
"-I$(openjdk-src)/solaris/native/common/deps/glib2" \
"-I$(openjdk-src)/solaris/native/common/deps/gconf2" \
$(shell pkg-config --cflags glib-2.0) \
$(shell pkg-config --cflags gconf-2.0)
endif
ifeq ($(platform),darwin)
openjdk-sources += \
$(openjdk-src)/solaris/native/java/net/bsd_close.c
ifeq ($(ios),true)
openjdk-local-sources += \
$(src)/openjdk/my_java_props_macosx.c
else
openjdk-sources += \
$(openjdk-src)/solaris/native/java/lang/java_props_macosx.c
endif
openjdk-cflags += \
-DMACOSX
endif
endif
openjdk-local-sources = \
openjdk-local-sources += \
$(src)/openjdk/my_net_util.c \
$(src)/openjdk/my_management.c

View File

@ -11,6 +11,7 @@
-keep class java.lang.System {
private static void initializeSystemClass();
public static void setProperties(java.util.Properties);
}
-keep class java.lang.ClassLoader {
@ -33,6 +34,11 @@
-keep class java.util.Properties {
public java.lang.Object setProperty(java.lang.String, java.lang.String);
public java.lang.String getProperty(java.lang.String);
}
-keep class java.util.Hashtable {
public java.lang.Object remove(java.lang.Object);
}
-keep class avian.OpenJDK {

View File

@ -220,11 +220,11 @@ features beyond that subset, you may want to tell Avian to use
OpenJDK's class library instead. To do so, specify the directory
where OpenJDK is installed, e.g.:
$ make openjdk=/usr/lib/jvm/java-6-openjdk
$ make openjdk=/usr/lib/jvm/java-7-openjdk
This will build Avian as a conventional JVM (e.g. libjvm.so) which
loads its boot class library and native libraries (e.g. libjava.so)
from /usr/lib/jvm/java-6-openjdk/jre at runtime. To run an
from /usr/lib/jvm/java-7-openjdk/jre at runtime. To run an
application in this configuration, you'll need to make sure the VM is
in your library search path. For example:
@ -235,8 +235,8 @@ in your library search path. For example:
Alternatively, you can enable a stand-alone build using OpenJDK by
specifying the location of the OpenJDK source code, e.g.:
$ make openjdk=$(pwd)/../jdk6/build/linux-amd64/j2sdk-image \
openjdk-src=$(pwd)/../jdk6/jdk/src
$ make openjdk=$(pwd)/../jdk7/build/linux-amd64/j2sdk-image \
openjdk-src=$(pwd)/../jdk7/jdk/src
You must ensure that the path specified for openjdk-src does not have
any spaces in it; make gets confused when dependency paths include
@ -260,7 +260,9 @@ an LZMA-enabled version:
You can reduce the size futher for embedded builds by using ProGuard
and the supplied openjdk.pro configuration file (see "Embedding with
ProGuard and a Boot Image" below). Also see app.mk in
ProGuard and a Boot Image" below). Note that you'll still need to use
vm.pro in that case -- openjdk.pro just adds additional constraints
specific to the OpenJDK port. Also see app.mk in
git://oss.readytalk.com/avian-swt-examples.git for an example of using
Avian, OpenJDK, ProGuard, and UPX in concert.
@ -269,49 +271,42 @@ it on various OSes:
Debian-based Linux:
# conventional build:
apt-get install openjdk-6-jdk
make openjdk=/usr/lib/jvm/java-6-openjdk test
apt-get install openjdk-7-jdk
make openjdk=/usr/lib/jvm/java-7-openjdk test
# stand-alone build:
apt-get install openjdk-6-jdk
apt-get source openjdk-6-jdk
apt-get build-dep openjdk-6-jdk
(cd openjdk-6-6b18-1.8.3 && ./debian/rules patch)
make openjdk=/usr/lib/jvm/java-6-openjdk \
openjdk-src=$(pwd)/openjdk-6-6b18-1.8.3/build/openjdk/jdk/src \
apt-get install openjdk-7-jdk
apt-get source openjdk-7-jdk
apt-get build-dep openjdk-7-jdk
(cd openjdk-7-7~b147-2.0 && dpkg-buildpackage)
make openjdk=/usr/lib/jvm/java-7-openjdk \
openjdk-src=$(pwd)/openjdk-7-7~b147-2.0/build/openjdk/jdk/src \
test
Mac OS X:
# Prerequisite: install MacPorts (http://www.macports.org/)
sudo port selfupdate
# Prerequisite: build OpenJDK 7 according to
# https://wikis.oracle.com/display/OpenJDK/Mac+OS+X+Port
# conventional build:
sudo port install openjdk6
make openjdk=/opt/local/share/java/openjdk6 test
make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image test
# stand-alone build:
sudo port fetch openjdk6
sudo port patch openjdk6
make openjdk=/opt/local/share/java/openjdk6 \
openjdk-src=/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_java_openjdk6/work/jdk/src \
test
make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image \
openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test
Windows (Cygwin):
# Prerequisite: build OpenJDK 7 according to
# http://weblogs.java.net/blog/simonis/archive/2011/10/28/yaojowbi-yet-another-openjdk-windows-build-instruction
# conventional build:
# Prerequisite: download and install the latest Windows OpenJDK
# build from http://www.openscg.com/se/openjdk/
make openjdk=/cygdrive/c/OpenSCG/openjdk-6.21 test
make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image test
# stand-alone build:
# Prerequisite: install OpenSCG build as above, plus the
# corresponding source bundle from
# http://download.java.net/openjdk/jdk6/promoted/, e.g.:
wget http://download.java.net/openjdk/jdk6/promoted/b21/openjdk-6-src-b21-20_jan_2011.tar.gz
mkdir openjdk
(cd openjdk && tar xzf ../openjdk-6-src-b21-20_jan_2011.tar.gz)
make openjdk=/cygdrive/c/OpenSCG/openjdk-6.21 \
openjdk-src=$(pwd)/openjdk/jdk/src \
test
make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image \
openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test
Currently, only OpenJDK 7 is supported. Later versions might work,
but have not yet been tested.
Installing
@ -364,7 +359,7 @@ method. Note the bootJar function, which will be called by the VM to
get a handle to the embedded jar. We tell the VM about this jar by
setting the boot classpath to "[bootJar]".
$ cat >main.cpp <<EOF
$ cat >embedded-jar-main.cpp <<EOF
#include "stdint.h"
#include "jni.h"
@ -445,14 +440,15 @@ EOF
on Linux:
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
-D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o
-D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o
on Mac OS X:
$ g++ -I$JAVA_HOME/include -D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o
$ g++ -I$JAVA_HOME/include -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp \
-o main.o
on Windows:
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/win32 \
-D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o
-D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o
Step 5: Link the objects produced above to produce the final
executable, and optionally strip its symbols.
@ -547,10 +543,18 @@ EOF
Step 5: Run ProGuard with stage1 as input and stage2 as output.
$ java -jar ../../proguard4.6/lib/proguard.jar \
-injars stage1 -outjars stage2 @../vm.pro @hello.pro
-dontusemixedcaseclassnames -injars stage1 -outjars stage2 \
@../vm.pro @hello.pro
(note: pass -dontusemixedcaseclassnames to ProGuard when building on
systems with case-insensitive filesystems such as Windows and OS X)
(note: The -dontusemixedcaseclassnames option is only needed when
building on systems with case-insensitive filesystems such as Windows
and OS X. Also, you'll need to add -ignorewarnings if you use the
OpenJDK class library since the openjdk-src build does not include all
the JARs from OpenJDK, and thus ProGuard will not be able to resolve
all referenced classes. If you actually plan to use such classes at
runtime, you'll need to add them to stage1 before running ProGuard.
Finally, you'll need to add @../openjdk.pro to the above command when
using the OpenJDK library.)
Step 6: Build the boot and code images.
@ -575,7 +579,7 @@ If our application loaded resources such as images and properties
files via the classloader, we would also need to embed the jar file
containing them. See the previous example for instructions.
$ cat >main.cpp <<EOF
$ cat >bootimage-main.cpp <<EOF
#include "stdint.h"
#include "jni.h"
@ -670,7 +674,7 @@ main(int ac, const char** av)
EOF
$ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \
-D_JNI_IMPLEMENTATION_ -c main.cpp -o main.o
-D_JNI_IMPLEMENTATION_ -c bootimage-main.cpp -o main.o
Step 8: Link the objects produced above to produce the final
executable, and optionally strip its symbols.

View File

@ -27,7 +27,7 @@ using namespace avian::tools;
namespace {
const unsigned HeapCapacity = 256 * 1024 * 1024;
const unsigned HeapCapacity = 512 * 1024 * 1024;
const unsigned TargetFixieSizeInBytes = 8 + (TargetBytesPerWord * 2);
const unsigned TargetFixieSizeInWords = ceiling
@ -504,10 +504,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
}
if (fieldFlags(t, field) & ACC_STATIC) {
unsigned excess = (targetStaticOffset % targetSize)
% TargetBytesPerWord;
if (excess) {
targetStaticOffset += TargetBytesPerWord - excess;
while (targetStaticOffset % targetSize) {
++ targetStaticOffset;
}
buildStaticOffset = fieldOffset(t, field);
@ -1289,6 +1287,9 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
const char* bootimageStart, const char* bootimageEnd,
const char* codeimageStart, const char* codeimageEnd)
{
setRoot(t, Machine::OutOfMemoryError,
make(t, type(t, Machine::OutOfMemoryErrorType)));
Zone zone(t->m->system, t->m->heap, 64 * 1024);
class MyCompilationHandler : public Processor::CompilationHandler {
@ -1956,14 +1957,18 @@ main(int ac, const char** av)
// in a branch instruction for the target architecture (~32MB on
// PowerPC and ARM). When that limitation is removed, we'll be able
// to specify a capacity as large as we like here:
#if (defined ARCH_x86_64) || (defined ARCH_x86_32)
const unsigned CodeCapacity = 128 * 1024 * 1024;
#else
const unsigned CodeCapacity = 30 * 1024 * 1024;
#endif
uint8_t* code = static_cast<uint8_t*>(h->allocate(CodeCapacity));
BootImage image;
p->initialize(&image, code, CodeCapacity);
Machine* m = new (h->allocate(sizeof(Machine))) Machine
(s, h, f, 0, p, c, 0, 0, 0, 0);
(s, h, f, 0, p, c, 0, 0, 0, 0, 128 * 1024);
Thread* t = p->makeThread(m, 0, 0);
enter(t, Thread::ActiveState);

View File

@ -353,13 +353,22 @@ Avian_sun_misc_Unsafe_freeMemory
extern "C" JNIEXPORT void JNICALL
Avian_sun_misc_Unsafe_setMemory
(Thread*, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{
int64_t p; memcpy(&p, arguments + 1, 8);
int64_t count; memcpy(&count, arguments + 3, 8);
int8_t v = arguments[5];
object base = reinterpret_cast<object>(arguments[1]);
int64_t offset; memcpy(&offset, arguments + 2, 8);
int64_t count; memcpy(&count, arguments + 4, 8);
int8_t value = arguments[6];
memset(reinterpret_cast<int8_t*>(p), v, count);
PROTECT(t, base);
ACQUIRE(t, t->m->referenceLock);
if (base) {
memset(&cast<int8_t>(base, offset), value, count);
} else {
memset(reinterpret_cast<int8_t*>(offset), value, count);
}
}
// NB: The following primitive get/put methods are only used by the

View File

@ -54,6 +54,12 @@ class MyClasspath : public Classpath {
root(t, Machine::BootLoader), 0, 0, group, 0);
}
virtual void
clearInterrupted(Thread*)
{
// ignore
}
virtual void
runThread(Thread* t)
{

View File

@ -120,6 +120,16 @@ void
runOnLoadIfFound(Thread* t, System::Library* library)
{
void* p = library->resolve("JNI_OnLoad");
#ifdef PLATFORM_WINDOWS
if (p == 0) {
p = library->resolve("_JNI_OnLoad@8");
if (p == 0) {
p = library->resolve("JNI_OnLoad@8");
}
}
#endif
if (p) {
jint (JNICALL * JNI_OnLoad)(Machine*, void*);
memcpy(&JNI_OnLoad, &p, sizeof(void*));

View File

@ -344,6 +344,9 @@ makeClassNameString(Thread* t, object name)
void
interceptFileOperations(Thread*);
void
clearInterrupted(Thread*);
class MyClasspath : public Classpath {
public:
static const unsigned BufferSize = 1024;
@ -410,6 +413,8 @@ class MyClasspath : public Classpath {
sb.append(javaHome);
#ifdef PLATFORM_WINDOWS
sb.append("/bin");
#elif defined __APPLE__
sb.append("/lib");
#elif defined ARCH_x86_64
sb.append("/lib/amd64");
#else
@ -435,9 +440,14 @@ class MyClasspath : public Classpath {
PROTECT(t, class_);
object name = makeClassNameString(t, getClassName(t, class_));
PROTECT(t, name);
return vm::makeJclass
(t, 0, 0, name, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, class_);
object c = allocate(t, FixedSizeOfJclass, true);
setObjectClass(t, c, type(t, Machine::JclassType));
set(t, c, JclassName, name);
set(t, c, JclassVmClass, class_);
return c;
}
virtual object
@ -499,6 +509,12 @@ class MyClasspath : public Classpath {
return thread;
}
virtual void
clearInterrupted(Thread* t)
{
local::clearInterrupted(t);
}
virtual void
runThread(Thread* t)
{
@ -546,31 +562,61 @@ class MyClasspath : public Classpath {
expect(t, loadLibrary(t, libraryPath, "java", true, true));
#endif // not AVIAN_OPENJDK_SRC
object constructor = resolveMethod
{ object class_ = resolveClass
(t, root(t, Machine::BootLoader), "java/util/Properties", true,
Machine::NoClassDefFoundErrorType);
PROTECT(t, class_);
object instance = makeNew(t, class_);
PROTECT(t, instance);
object constructor = resolveMethod(t, class_, "<init>", "()V");
t->m->processor->invoke(t, constructor, instance);
t->m->processor->invoke
(t, root(t, Machine::BootLoader), "java/lang/System",
"setProperties", "(Ljava/util/Properties;)V", 0, instance);
}
{ object constructor = resolveMethod
(t, type(t, Machine::ClassLoaderType), "<init>",
"(Ljava/lang/ClassLoader;)V");
PROTECT(t, constructor);
PROTECT(t, constructor);
t->m->processor->invoke(t, constructor, root(t, Machine::BootLoader), 0);
t->m->processor->invoke(t, constructor, root(t, Machine::BootLoader), 0);
t->m->processor->invoke
(t, constructor, root(t, Machine::AppLoader),
root(t, Machine::BootLoader));
t->m->processor->invoke
(t, constructor, root(t, Machine::AppLoader),
root(t, Machine::BootLoader));
}
object scl = resolveField
(t, type(t, Machine::ClassLoaderType), "scl", "Ljava/lang/ClassLoader;");
{ object assertionLock = resolveField
(t, type(t, Machine::ClassLoaderType), "assertionLock",
"Ljava/lang/Object;");
PROTECT(t, scl);
set(t, root(t, Machine::BootLoader), fieldOffset(t, assertionLock),
root(t, Machine::BootLoader));
}
object sclSet = resolveField
(t, type(t, Machine::ClassLoaderType), "sclSet", "Z");
{ object scl = resolveField
(t, type(t, Machine::ClassLoaderType), "scl",
"Ljava/lang/ClassLoader;");
set(t, classStaticTable(t, type(t, Machine::ClassLoaderType)),
fieldOffset(t, scl), root(t, Machine::AppLoader));
PROTECT(t, scl);
cast<uint8_t>(classStaticTable(t, type(t, Machine::ClassLoaderType)),
fieldOffset(t, sclSet)) = true;
object sclSet = resolveField
(t, type(t, Machine::ClassLoaderType), "sclSet", "Z");
set(t, classStaticTable(t, type(t, Machine::ClassLoaderType)),
fieldOffset(t, scl), root(t, Machine::AppLoader));
cast<uint8_t>(classStaticTable(t, type(t, Machine::ClassLoaderType)),
fieldOffset(t, sclSet)) = true;
}
t->m->processor->invoke
(t, root(t, Machine::BootLoader), "java/lang/System",
@ -1313,15 +1359,17 @@ getZipFileEntry(Thread* t, object method, uintptr_t* arguments)
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
if (file->region) {
THREAD_RUNTIME_ARRAY(t, char, p, stringLength(t, path) + 2);
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
THREAD_RUNTIME_ARRAY(t, char, p, byteArrayLength(t, path) + 2);
memcpy(RUNTIME_ARRAY_BODY(p), &byteArrayBody(t, path, 0),
byteArrayLength(t, path));
RUNTIME_ARRAY_BODY(p)[byteArrayLength(t, path)] = 0;
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
if (addSlash) {
RUNTIME_ARRAY_BODY(p)[stringLength(t, path)] = '/';
RUNTIME_ARRAY_BODY(p)[stringLength(t, path) + 1] = 0;
RUNTIME_ARRAY_BODY(p)[byteArrayLength(t, path)] = '/';
RUNTIME_ARRAY_BODY(p)[byteArrayLength(t, path) + 1] = 0;
}
return reinterpret_cast<int64_t>(find(file, p, stringLength(t, path)));
return reinterpret_cast<int64_t>(find(file, p, byteArrayLength(t, path)));
} else {
int64_t entry = longValue
(t, t->m->processor->invoke
@ -1335,6 +1383,43 @@ getZipFileEntry(Thread* t, object method, uintptr_t* arguments)
}
}
int64_t JNICALL
getZipFileEntryBytes(Thread* t, object method, uintptr_t* arguments)
{
int64_t peer; memcpy(&peer, arguments, 8);
int type = arguments[2];
ZipFile::Entry* entry = reinterpret_cast<ZipFile::Entry*>(peer);
if (entry->start) {
switch (type) {
case 0: { // name
unsigned nameLength = fileNameLength(entry->start);
object array = makeByteArray(t, nameLength + 1);
memcpy(&byteArrayBody(t, array, 0), fileName(entry->start), nameLength);
byteArrayBody(t, array, nameLength) = 0;
return reinterpret_cast<int64_t>(array);
} break;
case 1: { // extra
return 0;
} break;
case 2: { // comment
return 0;
} break;
default: abort(t);
}
return compressedSize(entry->start);
} else {
return reinterpret_cast<int64_t>
(t->m->processor->invoke
(t, nativeInterceptOriginal
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
0, entry->entry, type));
}
}
int64_t JNICALL
getNextZipFileEntry(Thread* t, object method, uintptr_t* arguments)
{
@ -1462,6 +1547,8 @@ freeZipFileEntry(Thread* t, object method, uintptr_t* arguments)
(t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))),
0, file->file, entry->entry);
}
t->m->heap->free(entry, sizeof(ZipFile::Entry));
}
int64_t JNICALL
@ -1669,7 +1756,7 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
loadLibrary
(t, static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
RUNTIME_ARRAY_BODY(n), not absolute, false);
RUNTIME_ARRAY_BODY(n), not absolute, true);
}
// only safe to call during bootstrap when there's only one thread
@ -1698,6 +1785,15 @@ intercept(Thread* t, object c, const char* name, const char* spec,
object runtimeData = getMethodRuntimeData(t, m);
set(t, runtimeData, MethodRuntimeDataNative, native);
} else {
// If we can't find the method, just ignore it, since ProGuard may
// have stripped it out as unused. Otherwise, the code below can
// be uncommented for debugging purposes.
// fprintf(stderr, "unable to find %s%s in %s\n",
// name, spec, &byteArrayBody(t, className(t, c), 0));
// abort(t);
}
}
@ -1765,60 +1861,6 @@ interceptFileOperations(Thread* t)
}
}
{ object zipEntryClass = resolveClass
(t, root(t, Machine::BootLoader), "java/util/zip/ZipEntry", false);
if (zipEntryClass) {
PROTECT(t, zipEntryClass);
object zipEntryNameField = findFieldInClass2
(t, zipEntryClass, "name", "Ljava/lang/String;");
if (zipEntryNameField) {
cp->zipEntryNameField = fieldOffset(t, zipEntryNameField);
object zipEntryTimeField = findFieldInClass2
(t, zipEntryClass, "time", "J");
if (zipEntryTimeField) {
cp->zipEntryTimeField = fieldOffset(t, zipEntryTimeField);
object zipEntryCrcField = findFieldInClass2
(t, zipEntryClass, "crc", "J");
if (zipEntryCrcField) {
cp->zipEntryCrcField = fieldOffset(t, zipEntryCrcField);
object zipEntrySizeField = findFieldInClass2
(t, zipEntryClass, "size", "J");
if (zipEntrySizeField) {
cp->zipEntrySizeField = fieldOffset(t, zipEntrySizeField);
object zipEntryCsizeField = findFieldInClass2
(t, zipEntryClass, "csize", "J");
if (zipEntryCsizeField) {
cp->zipEntryCsizeField = fieldOffset(t, zipEntryCsizeField);
object zipEntryMethodField = findFieldInClass2
(t, zipEntryClass, "method", "I");
if (zipEntryMethodField) {
cp->zipEntryMethodField = fieldOffset
(t, zipEntryMethodField);
intercept(t, zipEntryClass, "initFields", "(J)V",
voidPointer(initializeZipEntryFields));
}
}
}
}
}
}
}
}
{ object zipFileClass = resolveClass
(t, root(t, Machine::BootLoader), "java/util/zip/ZipFile", false);
@ -1831,19 +1873,22 @@ interceptFileOperations(Thread* t)
if (zipFileJzfileField) {
cp->zipFileJzfileField = fieldOffset(t, zipFileJzfileField);
intercept(t, zipFileClass, "open", "(Ljava/lang/String;IJ)J",
intercept(t, zipFileClass, "open", "(Ljava/lang/String;IJZ)J",
voidPointer(openZipFile));
intercept(t, zipFileClass, "getTotal", "(J)I",
voidPointer(getZipFileEntryCount));
intercept(t, zipFileClass, "getEntry", "(JLjava/lang/String;Z)J",
intercept(t, zipFileClass, "getEntry", "(J[BZ)J",
voidPointer(getZipFileEntry));
intercept(t, zipFileClass, "getEntryBytes", "(JI)[B",
voidPointer(getZipFileEntryBytes));
intercept(t, zipFileClass, "getNextEntry", "(JI)J",
voidPointer(getNextZipFileEntry));
intercept(t, zipFileClass, "getMethod", "(J)I",
intercept(t, zipFileClass, "getEntryMethod", "(J)I",
voidPointer(getZipFileEntryMethod));
intercept(t, zipFileClass, "freeEntry", "(JJ)V",
@ -1852,10 +1897,10 @@ interceptFileOperations(Thread* t)
intercept(t, zipFileClass, "read", "(JJJ[BII)I",
voidPointer(readZipFileEntry));
intercept(t, zipFileClass, "getCSize", "(J)J",
intercept(t, zipFileClass, "getEntryCSize", "(J)J",
voidPointer(getZipFileEntryCompressedSize));
intercept(t, zipFileClass, "getSize", "(J)J",
intercept(t, zipFileClass, "getEntrySize", "(J)J",
voidPointer(getZipFileEntryUncompressedSize));
intercept(t, zipFileClass, "getZipMessage", "(J)Ljava/lang/String;",
@ -2176,6 +2221,14 @@ interruptLock(Thread* t, object thread)
return threadInterruptLock(t, thread);
}
void
clearInterrupted(Thread* t)
{
monitorAcquire(t, local::interruptLock(t, t->javaThread));
threadInterrupted(t, t->javaThread) = false;
monitorRelease(t, local::interruptLock(t, t->javaThread));
}
bool
pipeAvailable(int fd, int* available)
{
@ -2271,6 +2324,24 @@ Avian_sun_misc_Unsafe_registerNatives
// ignore
}
extern "C" JNIEXPORT void
Avian_sun_misc_Perf_registerNatives
(Thread*, object, uintptr_t*)
{
// ignore
}
extern "C" JNIEXPORT int64_t
Avian_sun_misc_Perf_createLong
(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<int64_t>
(t->m->processor->invoke
(t, resolveMethod
(t, root(t, Machine::BootLoader), "java/nio/ByteBuffer", "allocate",
"(I)Ljava/nio/ByteBuffer;"), 0, 8));
}
extern "C" JNIEXPORT int64_t
Avian_sun_misc_Unsafe_addressSize
(Thread*, object, uintptr_t*)
@ -2520,13 +2591,20 @@ Avian_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_getBoolean
Avian_sun_misc_Unsafe_getByte
(Thread*, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[1]);
int64_t offset; memcpy(&offset, arguments + 2, 8);
return cast<uint8_t>(o, offset);
return cast<int8_t>(o, offset);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_getBoolean
(Thread* t, object method, uintptr_t* arguments)
{
return Avian_sun_misc_Unsafe_getByte(t, method, arguments);
}
extern "C" JNIEXPORT void JNICALL
@ -2576,6 +2654,13 @@ Avian_sun_misc_Unsafe_putObjectVolatile
storeLoadMemoryBarrier();
}
extern "C" JNIEXPORT void JNICALL
Avian_sun_misc_Unsafe_putOrderedObject
(Thread* t, object method, uintptr_t* arguments)
{
Avian_sun_misc_Unsafe_putObjectVolatile(t, method, arguments);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_compareAndSwapInt
(Thread*, object, uintptr_t* arguments)
@ -2671,12 +2756,15 @@ Avian_sun_misc_Unsafe_park
if (time <= 0) {
return;
}
} else {
time /= 1000 * 1000;
} else if (time) {
// if not absolute, interpret time as nanoseconds, but make sure
// it doesn't become zero when we convert to milliseconds, since
// zero is interpreted as infinity below
time = (time / (1000 * 1000)) + 1;
}
monitorAcquire(t, local::interruptLock(t, t->javaThread));
while (time > 0
while (time >= 0
and (not (threadUnparked(t, t->javaThread)
or monitorWait
(t, local::interruptLock(t, t->javaThread), time))))
@ -2684,11 +2772,41 @@ Avian_sun_misc_Unsafe_park
int64_t now = t->m->system->now();
time -= now - then;
then = now;
if (time == 0) {
break;
}
}
threadUnparked(t, t->javaThread) = false;
monitorRelease(t, local::interruptLock(t, t->javaThread));
}
extern "C" JNIEXPORT void JNICALL
Avian_sun_misc_Unsafe_copyMemory
(Thread* t, object, uintptr_t* arguments)
{
object srcBase = reinterpret_cast<object>(arguments[1]);
int64_t srcOffset; memcpy(&srcOffset, arguments + 2, 8);
object dstBase = reinterpret_cast<object>(arguments[4]);
int64_t dstOffset; memcpy(&dstOffset, arguments + 5, 8);
int64_t count; memcpy(&count, arguments + 7, 8);
PROTECT(t, srcBase);
PROTECT(t, dstBase);
ACQUIRE(t, t->m->referenceLock);
void* src = srcBase
? &cast<uint8_t>(srcBase, srcOffset)
: reinterpret_cast<uint8_t*>(srcOffset);
void* dst = dstBase
? &cast<uint8_t>(dstBase, dstOffset)
: reinterpret_cast<uint8_t*>(dstOffset);
memcpy(dst, src, count);
}
extern "C" JNIEXPORT void JNICALL
Avian_sun_misc_Unsafe_monitorEnter
(Thread* t, object, uintptr_t* arguments)
@ -2877,22 +2995,22 @@ jvmInitProperties(Thread* t, uintptr_t* arguments)
GetCurrentDirectory(MAX_PATH, buffer);
local::setProperty(t, method, *properties, "user.dir", buffer);
#else
#else // not PLATFORM_WINDOWS
local::setProperty(t, method, *properties, "line.separator", "\n");
local::setProperty(t, method, *properties, "file.separator", "/");
local::setProperty(t, method, *properties, "path.separator", ":");
# ifdef __APPLE__
local::setProperty(t, method, *properties, "os.name", "Mac OS X");
# else
# else // not __APPLE__
local::setProperty(t, method, *properties, "os.name", "Linux");
# endif
# endif // not __APPLE__
local::setProperty(t, method, *properties, "java.io.tmpdir", "/tmp");
local::setProperty(t, method, *properties, "user.home", getenv("HOME"));
char buffer[PATH_MAX];
local::setProperty(t, method, *properties, "user.dir",
getcwd(buffer, PATH_MAX));
#endif
#endif // not PLATFORM_WINDOWS
local::setProperty(t, method, *properties, "java.protocol.handler.pkgs",
"avian");
@ -2908,6 +3026,11 @@ jvmInitProperties(Thread* t, uintptr_t* arguments)
(t, method, *properties, "sun.boot.library.path",
static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath);
local::setProperty
(t, method, *properties, "sun.boot.class.path",
static_cast<Finder*>
(systemClassLoaderFinder(t, root(t, Machine::BootLoader)))->path());
local::setProperty(t, method, *properties, "file.encoding", "ASCII");
#ifdef ARCH_x86_32
local::setProperty(t, method, *properties, "os.arch", "x86");
@ -3074,7 +3197,7 @@ jvmFillInStackTrace(Thread* t, uintptr_t* arguments)
{
jobject throwable = reinterpret_cast<jobject>(arguments[0]);
object trace = getTrace(t, 1);
object trace = getTrace(t, 2);
set(t, *throwable, ThrowableTrace, trace);
return 1;
@ -3244,9 +3367,8 @@ jvmInterrupt(Thread* t, uintptr_t* arguments)
Thread* p = reinterpret_cast<Thread*>(threadPeer(t, *thread));
if (p) {
interrupt(t, p);
} else {
threadInterrupted(t, *thread) = true;
}
threadInterrupted(t, *thread) = true;
monitorRelease(t, local::interruptLock(t, *thread));
return 1;
@ -3768,10 +3890,9 @@ EXPORT(JVM_FindClassFromClassLoader)(Thread* t, const char* name,
}
extern "C" JNIEXPORT jclass JNICALL
EXPORT(JVM_FindClassFromBootLoader)(Thread* t, const char* name,
jboolean throwError)
JVM_FindClassFromBootLoader(Thread* t, const char* name)
{
return EXPORT(JVM_FindClassFromClassLoader)(t, name, false, 0, throwError);
return EXPORT(JVM_FindClassFromClassLoader)(t, name, false, 0, false);
}
extern "C" JNIEXPORT jclass JNICALL
@ -4199,9 +4320,9 @@ jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
}
object method = makeJmethod
(t, true, *c, i, name, returnType, parameterTypes, exceptionTypes,
(t, true, 0, *c, i, name, returnType, parameterTypes, exceptionTypes,
methodFlags(t, vmMethod), signature, 0, annotationTable, 0,
annotationDefault, 0, 0, 0, 0, 0);
annotationDefault, 0, 0, 0);
assert(t, ai < objectArrayLength(t, array));
@ -4288,8 +4409,8 @@ jvmGetClassDeclaredFields(Thread* t, uintptr_t* arguments)
}
object field = makeJfield
(t, true, *c, i, name, type, fieldFlags
(t, vmField), signature, 0, annotationTable, 0, 0, 0, 0, 0, 0);
(t, true, 0, *c, i, name, type, fieldFlags
(t, vmField), signature, 0, annotationTable, 0, 0, 0, 0);
assert(t, ai < objectArrayLength(t, array));
@ -4379,8 +4500,8 @@ jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
}
object method = makeJconstructor
(t, true, *c, i, parameterTypes, exceptionTypes, methodFlags
(t, vmMethod), signature, 0, annotationTable, 0, 0, 0, 0, 0);
(t, true, 0, *c, i, parameterTypes, exceptionTypes, methodFlags
(t, vmMethod), signature, 0, annotationTable, 0, 0, 0, 0);
assert(t, ai < objectArrayLength(t, array));
@ -5152,9 +5273,11 @@ jboolean JNICALL
GetBoolAttribute(Thread* t, jmmBoolAttribute attribute)
{
const unsigned JMM_THREAD_CPU_TIME = 24;
const unsigned JMM_THREAD_ALLOCATED_MEMORY = 25;
switch (attribute) {
case JMM_THREAD_CPU_TIME:
case JMM_THREAD_ALLOCATED_MEMORY:
return false;
default:
@ -5237,13 +5360,19 @@ extern "C" JNIEXPORT jobjectArray JNICALL
EXPORT(JVM_GetThreadStateNames)(JNIEnv*, jint, jintArray) { abort(); }
extern "C" JNIEXPORT void JNICALL
EXPORT(JVM_GetVersionInfo)(JNIEnv*, local::jvm_version_info*, size_t)
{ abort(); }
EXPORT(JVM_GetVersionInfo)(JNIEnv*, local::jvm_version_info* info, size_t size)
{
memset(info, 0, size);
info->jvm_version = 0x01070000;
}
extern "C" JNIEXPORT jboolean JNICALL
EXPORT(JVM_CX8Field)(JNIEnv*, jobject*, jfieldID*, jlong, jlong)
{ abort(); }
extern "C" JNIEXPORT void JNICALL
EXPORT(JVM_SetNativeThreadName)(JNIEnv*, jobject, jstring) { abort(); }
} // namespace local
} // namespace

View File

@ -612,7 +612,7 @@ class MyStackWalker: public Processor::StackWalker {
}
void next() {
expect(t, count_ <= StackSizeInWords);
expect(t, count_ <= stackSizeInWords(t));
switch (state) {
case Continuation:
@ -6237,8 +6237,10 @@ truncateIntArray(Thread* t, object array, unsigned length)
PROTECT(t, array);
object newArray = makeIntArray(t, length);
memcpy(&intArrayBody(t, newArray, 0), &intArrayBody(t, array, 0),
length * 4);
if (length) {
memcpy(&intArrayBody(t, newArray, 0), &intArrayBody(t, array, 0),
length * 4);
}
return newArray;
}
@ -6251,8 +6253,10 @@ truncateArray(Thread* t, object array, unsigned length)
PROTECT(t, array);
object newArray = makeArray(t, length);
memcpy(&arrayBody(t, newArray, 0), &arrayBody(t, array, 0),
length * BytesPerWord);
if (length) {
memcpy(&arrayBody(t, newArray, 0), &arrayBody(t, array, 0),
length * BytesPerWord);
}
return newArray;
}
@ -6265,9 +6269,11 @@ truncateLineNumberTable(Thread* t, object table, unsigned length)
PROTECT(t, table);
object newTable = makeLineNumberTable(t, length);
memcpy(&lineNumberTableBody(t, newTable, 0),
&lineNumberTableBody(t, table, 0),
length * sizeof(uint64_t));
if (length) {
memcpy(&lineNumberTableBody(t, newTable, 0),
&lineNumberTableBody(t, table, 0),
length * sizeof(uint64_t));
}
return newTable;
}
@ -8325,7 +8331,7 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
uintptr_t stackLimit = t->stackLimit;
uintptr_t stackPosition = reinterpret_cast<uintptr_t>(&t);
if (stackLimit == 0) {
t->stackLimit = stackPosition - StackSizeInBytes;
t->stackLimit = stackPosition - t->m->stackSizeInBytes;
} else if (stackPosition < stackLimit) {
throwNew(t, Machine::StackOverflowErrorType);
}

View File

@ -40,7 +40,7 @@ class Thread: public vm::Thread {
unsigned sp;
int frame;
object code;
uintptr_t stack[StackSizeInWords];
uintptr_t stack[0];
};
inline void
@ -50,7 +50,7 @@ pushObject(Thread* t, object o)
fprintf(stderr, "push object %p at %d\n", o, t->sp);
}
assert(t, t->sp + 1 < StackSizeInWords / 2);
assert(t, t->sp + 1 < stackSizeInWords(t) / 2);
t->stack[(t->sp * 2) ] = ObjectTag;
t->stack[(t->sp * 2) + 1] = reinterpret_cast<uintptr_t>(o);
++ t->sp;
@ -63,7 +63,7 @@ pushInt(Thread* t, uint32_t v)
fprintf(stderr, "push int %d at %d\n", v, t->sp);
}
assert(t, t->sp + 1 < StackSizeInWords / 2);
assert(t, t->sp + 1 < stackSizeInWords(t) / 2);
t->stack[(t->sp * 2) ] = IntTag;
t->stack[(t->sp * 2) + 1] = v;
++ t->sp;
@ -156,7 +156,7 @@ peekObject(Thread* t, unsigned index)
index);
}
assert(t, index < StackSizeInWords / 2);
assert(t, index < stackSizeInWords(t) / 2);
assert(t, t->stack[index * 2] == ObjectTag);
return *reinterpret_cast<object*>(t->stack + (index * 2) + 1);
}
@ -170,7 +170,7 @@ peekInt(Thread* t, unsigned index)
index);
}
assert(t, index < StackSizeInWords / 2);
assert(t, index < stackSizeInWords(t) / 2);
assert(t, t->stack[index * 2] == IntTag);
return t->stack[(index * 2) + 1];
}
@ -226,7 +226,7 @@ inline object*
pushReference(Thread* t, object o)
{
if (o) {
expect(t, t->sp + 1 < StackSizeInWords / 2);
expect(t, t->sp + 1 < stackSizeInWords(t) / 2);
pushObject(t, o);
return reinterpret_cast<object*>(t->stack + ((t->sp - 1) * 2) + 1);
} else {
@ -405,7 +405,7 @@ checkStack(Thread* t, object method)
+ codeMaxLocals(t, methodCode(t, method))
+ FrameFootprint
+ codeMaxStack(t, methodCode(t, method))
> StackSizeInWords / 2))
> stackSizeInWords(t) / 2))
{
throwNew(t, Machine::StackOverflowErrorType);
}
@ -2879,7 +2879,7 @@ class MyProcessor: public Processor {
virtual vm::Thread*
makeThread(Machine* m, object javaThread, vm::Thread* parent)
{
Thread* t = new (m->heap->allocate(sizeof(Thread)))
Thread* t = new (m->heap->allocate(sizeof(Thread) + m->stackSizeInBytes))
Thread(m, javaThread, parent);
t->init();
return t;
@ -2996,7 +2996,7 @@ class MyProcessor: public Processor {
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> StackSizeInWords / 2))
> stackSizeInWords(t) / 2))
{
throwNew(t, Machine::StackOverflowErrorType);
}
@ -3020,7 +3020,7 @@ class MyProcessor: public Processor {
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> StackSizeInWords / 2))
> stackSizeInWords(t) / 2))
{
throwNew(t, Machine::StackOverflowErrorType);
}
@ -3043,7 +3043,7 @@ class MyProcessor: public Processor {
or t->state == Thread::ExclusiveState);
if (UNLIKELY(t->sp + parameterFootprint(vmt, methodSpec, false)
> StackSizeInWords / 2))
> stackSizeInWords(t) / 2))
{
throwNew(t, Machine::StackOverflowErrorType);
}

View File

@ -3269,6 +3269,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
local::JavaVMInitArgs* a = static_cast<local::JavaVMInitArgs*>(args);
unsigned heapLimit = 0;
unsigned stackLimit = 0;
const char* bootLibrary = 0;
const char* classpath = 0;
const char* javaHome = AVIAN_JAVA_HOME;
@ -3285,6 +3286,8 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
const char* p = a->options[i].optionString + 2;
if (strncmp(p, "mx", 2) == 0) {
heapLimit = local::parseSize(p + 2);
} else if (strncmp(p, "ss", 2) == 0) {
stackLimit = local::parseSize(p + 2);
} else if (strncmp(p, BOOTCLASSPATH_PREPEND_OPTION ":",
sizeof(BOOTCLASSPATH_PREPEND_OPTION)) == 0)
{
@ -3327,6 +3330,8 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
}
if (heapLimit == 0) heapLimit = 128 * 1024 * 1024;
if (stackLimit == 0) stackLimit = 128 * 1024;
if (classpath == 0) classpath = ".";
@ -3377,9 +3382,9 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
*(argumentPointer++) = a->options[i].optionString;
}
*m = new (h->allocate(sizeof(Machine)))
Machine
(s, h, bf, af, p, c, properties, propertyCount, arguments, a->nOptions);
*m = new (h->allocate(sizeof(Machine))) Machine
(s, h, bf, af, p, c, properties, propertyCount, arguments, a->nOptions,
stackLimit);
*t = p->makeThread(*m, 0, 0);

View File

@ -1164,9 +1164,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
unsigned size = fieldSize(t, code);
if (flags & ACC_STATIC) {
unsigned excess = (staticOffset % size) % BytesPerWord;
if (excess) {
staticOffset += BytesPerWord - excess;
while (staticOffset % size) {
++ staticOffset;
}
fieldOffset(t, field) = staticOffset;
@ -1205,9 +1204,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
for (unsigned i = 0, offset = 0; i < staticCount; ++i) {
unsigned size = fieldSize(t, RUNTIME_ARRAY_BODY(staticTypes)[i]);
unsigned excess = offset % size;
if (excess) {
offset += BytesPerWord - excess;
while (offset % size) {
++ offset;
}
unsigned value = intArrayBody(t, staticValueTable, i);
@ -2457,7 +2455,8 @@ namespace vm {
Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
Finder* appFinder, Processor* processor, Classpath* classpath,
const char** properties, unsigned propertyCount,
const char** arguments, unsigned argumentCount):
const char** arguments, unsigned argumentCount,
unsigned stackSizeInBytes):
vtable(&javaVMVTable),
system(system),
heapClient(new (heap->allocate(sizeof(HeapClient)))
@ -2480,6 +2479,7 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
liveCount(0),
daemonCount(0),
fixedFootprint(0),
stackSizeInBytes(stackSizeInBytes),
localThread(0),
stateLock(0),
heapLock(0),

View File

@ -112,9 +112,6 @@ const unsigned ThreadBackupHeapSizeInBytes = 2 * 1024;
const unsigned ThreadBackupHeapSizeInWords
= ThreadBackupHeapSizeInBytes / BytesPerWord;
const unsigned StackSizeInBytes = 128 * 1024;
const unsigned StackSizeInWords = StackSizeInBytes / BytesPerWord;
const unsigned ThreadHeapPoolSize = 64;
const unsigned FixedFootprintThresholdInBytes
@ -1281,7 +1278,7 @@ class Machine {
Machine(System* system, Heap* heap, Finder* bootFinder, Finder* appFinder,
Processor* processor, Classpath* classpath, const char** properties,
unsigned propertyCount, const char** arguments,
unsigned argumentCount);
unsigned argumentCount, unsigned stackSizeInBytes);
~Machine() {
dispose();
@ -1310,6 +1307,7 @@ class Machine {
unsigned liveCount;
unsigned daemonCount;
unsigned fixedFootprint;
unsigned stackSizeInBytes;
System::Local* localThread;
System::Monitor* stateLock;
System::Monitor* heapLock;
@ -1579,6 +1577,9 @@ class Classpath {
virtual object
makeThread(Thread* t, Thread* parent) = 0;
virtual void
clearInterrupted(Thread* t) = 0;
virtual void
runThread(Thread* t) = 0;
@ -1639,6 +1640,12 @@ objectClass(Thread*, object o)
return mask(cast<object>(o, 0));
}
inline unsigned
stackSizeInWords(Thread* t)
{
return t->m->stackSizeInBytes / BytesPerWord;
}
void
enter(Thread* t, Thread::State state);
@ -3211,6 +3218,7 @@ wait(Thread* t, object o, int64_t milliseconds)
if (interrupted) {
if (t->m->alive or (t->flags & Thread::DaemonFlag) == 0) {
t->m->classpath->clearInterrupted(t);
throwNew(t, Machine::InterruptedExceptionType);
} else {
throw_(t, root(t, Machine::Shutdown));

View File

@ -143,6 +143,7 @@ usageAndExit(const char* name)
(stderr, "usage: %s\n"
"\t[{-cp|-classpath} <classpath>]\n"
"\t[-Xmx<maximum heap size>]\n"
"\t[-Xss<maximum stack size>]\n"
"\t[-Xbootclasspath/p:<classpath to prepend to bootstrap classpath>]\n"
"\t[-Xbootclasspath:<bootstrap classpath>]\n"
"\t[-Xbootclasspath/a:<classpath to append to bootstrap classpath>]\n"

View File

@ -0,0 +1,28 @@
#include "java_props_macosx.h"
PreferredToolkit
getPreferredToolkit()
{
return unset;
}
void
setOSNameAndVersion(java_props_t* props)
{
props->os_name = strdup("iOS");
props->os_version = strdup("Unknown");
}
void
setProxyProperties(java_props_t* props)
{
// ignore
}
char*
setupMacOSXLocale(int cat)
{
return 0;
}
char* environ[0];

View File

@ -122,8 +122,7 @@ pathOfExecutable(System* s, const char** retBuf, unsigned* size)
const bool Verbose = false;
const unsigned Waiting = 1 << 0;
const unsigned Notified = 1 << 1;
const unsigned Notified = 1 << 0;
class MySystem: public System {
public:
@ -256,7 +255,14 @@ class MySystem: public System {
}
void append(Thread* t) {
#ifndef NDEBUG
for (Thread* x = first; x; x = x->next) {
expect(s, t != x);
}
#endif
if (last) {
expect(s, t != last);
last->next = t;
last = t;
} else {
@ -271,6 +277,7 @@ class MySystem: public System {
if (current == first) {
first = t->next;
} else {
expect(s, previous != t->next);
previous->next = t->next;
}
@ -286,6 +293,12 @@ class MySystem: public System {
current = current->next;
}
}
#ifndef NDEBUG
for (Thread* x = first; x; x = x->next) {
expect(s, t != x);
}
#endif
}
virtual void wait(System::Thread* context, int64_t time) {
@ -308,13 +321,13 @@ class MySystem: public System {
{ ACQUIRE(t->mutex);
expect(s, (t->flags & Notified) == 0);
interrupted = t->r->interrupted();
if (interrupted and clearInterrupted) {
t->r->setInterrupted(false);
}
t->flags |= Waiting;
append(t);
depth = this->depth;
@ -343,14 +356,22 @@ class MySystem: public System {
}
notified = ((t->flags & Notified) != 0);
t->flags = 0;
}
pthread_mutex_lock(&mutex);
{ ACQUIRE(t->mutex);
t->flags = 0;
}
if (not notified) {
remove(t);
} else {
#ifndef NDEBUG
for (Thread* x = first; x; x = x->next) {
expect(s, t != x);
}
#endif
}
t->next = 0;
@ -380,6 +401,7 @@ class MySystem: public System {
Thread* t = first;
first = first->next;
if (t == last) {
expect(s, first == 0);
last = 0;
}

View File

@ -220,6 +220,8 @@
(type negativeArraySizeException java/lang/NegativeArraySizeException)
(type reflectiveOperationException java/lang/ReflectiveOperationException)
(type classCastException java/lang/ClassCastException)
(type classNotFoundException java/lang/ClassNotFoundException)

View File

@ -215,6 +215,12 @@ class MySystem: public System {
}
void append(Thread* t) {
#ifndef NDEBUG
for (Thread* x = first; x; x = x->next) {
expect(s, t != x);
}
#endif
if (last) {
last->next = t;
last = t;
@ -245,6 +251,12 @@ class MySystem: public System {
current = current->next;
}
}
#ifndef NDEBUG
for (Thread* x = first; x; x = x->next) {
expect(s, t != x);
}
#endif
}
virtual void wait(System::Thread* context, int64_t time) {
@ -270,6 +282,8 @@ class MySystem: public System {
{ ACQUIRE(s, t->mutex);
expect(s, (t->flags & Notified) == 0);
interrupted = t->r->interrupted();
if (interrupted and clearInterrupted) {
t->r->setInterrupted(false);
@ -306,15 +320,23 @@ class MySystem: public System {
}
notified = ((t->flags & Notified) != 0);
t->flags = 0;
}
r = WaitForSingleObject(mutex, INFINITE);
assert(s, r == WAIT_OBJECT_0);
{ ACQUIRE(s, t->mutex);
t->flags = 0;
}
if (not notified) {
remove(t);
} else {
#ifndef NDEBUG
for (Thread* x = first; x; x = x->next) {
expect(s, t != x);
}
#endif
}
t->next = 0;
@ -346,6 +368,7 @@ class MySystem: public System {
Thread* t = first;
first = first->next;
if (t == last) {
expect(s, first == 0);
last = 0;
}