Method.invoke must throw an IllegalArgumentException if it receives
the wrong number or types of arguments, and since this isn't done by
the OpenJDK class library, we must do it in the VM.
This library is placed in the xawt subdirectory of jre/lib/$arch on
POSIX systems, so it isn't found automatically when third-party
libraries which depend on it are loaded. The simplest way to ensure
that it's found seems to be to just load it when the VM starts up.
The original stub implementation just echoed back its argument, but
that confused URLClassLoader when dealing with sealed JARs --
returning a non-null value for a non-system class from
JVM_GetSystemPackage made URLClassloader think it had already loaded a
class from a package which was supposed to be sealed, resulting in
SecurityExceptions which ultimately triggered NoClassDefFoundErrors.
The solution is to only return non-null values for actual system
classes.
We weren't wrapping exceptions thrown by invoked methods in
InvocationTargetExceptions in JVM_InvokeMethod or
JVM_NewInstanceFromConstructor. Also, JVM_GetCallerClass is supposed
to ignore Method.invoke frames when walking the stack.
The existing code did not handle static field lookups for
synchronization on 32-bit systems, which is necessary because such
systems generally don't support atomic operations on 64-bit values.
set java.vm.version based on makefile version=
in order to display relevant OpenJDK -version information.
Signed-off-by: Matthias Klose <doko@ubuntu.com>
Signed-off-by: Xerxes Rånby <xerxes@zafena.se>
Some apps refuse to run if Runtime.maxMemory returns a value that's
"too small", so our stub implementation returning zero was not
sufficient. Now we return the actual heap size limit in bytes.
sun.misc.Launcher has its own idea about what the application
classloader should be, but we need to override it with the system
classloader created by the VM. This is achieved by running
Launcher.getLauncher (which has the side effect of setting
Thread.contextClassLoader) and then overriding it.
Our implementation uses Object.wait(long) to implement Thread.sleep,
which had the side effect of interpreting zero as infinity. However,
for Thread.sleep, zero just means zero. I assume that doesn't mean
"don't sleep at all", though, or else the app wouldn't have called
Thread.sleep in the first place, so this patch sleeps for one
millisecond when zero is passed -- just enough to yield the processor
for a bit. Thread.yield might be a better choice in this case, but I
assume the app would have called that directly if that's what it
wanted.
OpenJDK 7 has refactored this code relative to OpenJDK 6, and now
FontManager is an interface, with SunFontManager providing a (partial)
implementation.
On the ARM platform, Avian compiled to use OpenJDK gets this error on
startup:
java/lang/UnsatisfiedLinkError: no zip in java.library.path
at java/lang/ClassLoader.loadLibrary (line 1860)
at java/lang/Runtime.loadLibrary0 (line 845)
at java/lang/System.loadLibrary (line 1084)
at java/lang/System.initializeSystemClass (line 1145)
Using strace shows why:
[pid 22431]
stat64("/usr/lib/jvm/java-7-openjdk-armhf/jre/lib/i386/libzip.so",
0xbee377e0) = -1 ENOENT (No such file or directory)
The attached patch uses "arm" instead of "i386" in that path. This fixes the
problem.
sun.misc.Unsafe now has two native getByte methods: one which takes a
long and another which takes an Object and a long. Thus, we need to
decorate each version with its parameter signature so we don't
accidentally call the wrong one at runtime.
As of the latest code from the jdk7u-dev Mercurial repository,
java.lang.String no longer has offset or length fields. Instead, the
content fits exactly into the backing char array, so offset is
implicitly zero and length is the length of the array. The VM
previously relied on those fields being present, whereas this commit
handles the case where they are not.
In addition, I've made some changes to openjdk-src.mk to ensure that
we can build against both a stock OpenJDK 7 and an IcedTea-patched
version.
The JRE lib dir for OpenJDK 7 on OS X seems to be just "lib", not
e.g. "lib/amd64" by default, so we use that now. Also, the default
library compatibility version for libjvm.dylib is 0.0.0, but OpenJDK
wants 1.0.0, so we set it explicitly.
The bug here is that when a thread exits and becomes a "zombie", the
OS resources associated with it are not necessarily released until we
actually join and dispose of that thread. Since that only happens
during garbage collection, and collection normally only happens in
response to heap memory pressure, there's no guarantee that we'll GC
frequently enough to clean up zombies promptly and avoid running out
of resources.
The solution is to force a GC whenever we start a new thread and there
are at least N zombies waiting to be disposed, where N=16 for now.
We never define atomicCompareAndSwap64 for ARM or PowerPC, and
apparently only very recent ARM chips support it, so we must fall back
to synchronization-based emulation.
There were a couple of problems with the Avian_sun_misc_Unsafe_park
implementation in classpath-openjdk.cpp. First, the wait time should
be interpreted as milliseconds if absolute, but as nanoseconds
otherwise, whereas we were treating it as milliseconds in both cases.
Second, there was no mechanism to exit the while loop after the
specified time; the only way we could exit was via an unpark or
interrupt.