OpenJDK's compile.c and Avian's compile.cpp were both being compiled
to compile.o, which led to a conflict when building libavian.a. We
now append "-openjdk" to the object file name for OpenJDK code to
avoid such conflicts.
If we fail to resolve a given class (e.g. due to ProGuard obfuscating
or eliminating it), just move on to the next one rather than return
immediately. Otherwise, we may miss intercepting methods of classes
we can resolve.
sun.font.FontManager.initIDs is a native method defined in
libfontmanager.so, yet there seems to be no mechanism in OpenJDK's
class library to actually load that library, so we lazily load it
before trying to resolve the method.
Internally, the VM augments the method tables for abstract classes
with any inherited abstract methods to make code simpler elsewhere,
but that means we can't use that table to construct the result of
Class.getDeclaredMethods since it would include methods not actually
declared in the class. This commit ensures that we preserve and use
the original, un-augmented table for that purpose.
Under certain circumstances, the implementations of these functions
may throw errors, so we need to wrap them using vm::run so we don't
try to unwind past the JNI boundary.
As described in commit 36aa0d6, apps such as jython which generate
bytecode dynamically can produce patterns of bytecode for which the
VM's compiler could not handle properly. However, that commit
introduced a regression and had to be partially reverted.
It turns out the real problem was the call to Compiler::restoreState
which we made before checking whether we were actually ready to
compile the exception handler (we delay compiling an exception handler
until and unless the try/catch block it serves has been compiled so we
can calculate the stack maps properly). That confused the compiler in
rare cases, so we now only call restoreState once we're actually ready
to compile the handler.
My last commit introduced a regression in JIT compilation of
subroutines. This reverts the specific change which caused the
regression. Further work will be needed to address the case which
that change was intended to fix (namely, exception handlers which
apply to multiple try/catch blocks).
Bytecode generated by compilers other than javac or ecj (such as
jython's dynamically generated classes) can contain unreachable code
and exception handlers which apply to more than one try/catch scope.
Previously, the VM's JIT compiler did not handle either of these cases
well, hence this commit.
Previously, we would abort the process if we encountered a truncated
multibyte character in parseUtf8NonAscii (called by the JNI method
NewStringUTF). Now we simply terminate the string at that point.
Also, assume any class which has an ancestor class which has a static
initializer needs initialization even if it doesn't have one itself,
per the Java Language Spec.
The result of Class.getInterfaces should not include interfaces
declared to be implemented/extended by superclasses/superinterfaces,
only those declared by the class itself. This is important because it
influences how java.io.ObjectStreamClass calculates serial version
IDs.
Some broken code implicitly relies on System.identityHashCode always
returning a non-negative number (e.g. old versions of
com/sun/xml/bind/v2/util/CollisionCheckStack.hash).
Code including subroutines and conditionals can result in frame and
register resources being held by values which aren't in scope when
resetFrame is called, so we need to clean them up after cleaning the
in-scope values.
OpenJDK's sun.reflect.MethodAccessorGenerator can generate
invokevirtual calls to private methods (which we normally consider
non-virtual); we must compile them as non-virtual calls since they
aren't in the vtable.
It turns out commit 31eb047 was too aggressive and led to incorrect
calculation of line numbers for machine addresses, as well as
potentially incorrect exception handler scope calculation. This fixes
the regression.
OpenJDK's java.lang.ClassLoader.getResource makes use of
sun.misc.Launcher to load bootstrap resources, which is not
appropriate for the Avian build, so we override it to ensure we get
the behavior we want.