enable standalone OpenJDK builds

As described in readme.txt, a standalone OpenJDK build embeds all
libraries, classes, and other files needed at runtime in the resulting
binary, eliminating dependencies on external resources.
This commit is contained in:
Joel Dice 2010-11-04 11:02:09 -06:00
parent cb69ac23bd
commit cabad6926f
10 changed files with 509 additions and 92 deletions

110
makefile
View File

@ -52,22 +52,31 @@ classpath = avian
test-executable = $(executable)
boot-classpath = $(classpath-build)
java-home = /tmp
java-home = /avian-embedded
ifdef openjdk
ifdef openjdk-src
include openjdk-src.mk
options := $(options)-openjdk-src
classpath-objects = $(openjdk-objects)
classpath-cflags = -DAVIAN_OPENJDK_SRC
openjdk-jar-dep = $(build)/openjdk-jar.dep
classpath-jar-dep = $(openjdk-jar-dep)
else
options := $(options)-openjdk
test-executable = $(executable-dynamic)
library-path = LD_LIBRARY_PATH=$(build)
java-home = $(openjdk)/jre
endif
classpath = openjdk
options := $(options)-openjdk
java-home = $(openjdk)/jre
test-executable = $(executable-dynamic)
boot-classpath := $(boot-classpath):$(openjdk)/jre/lib/rt.jar
endif
ifneq ($(classpath),avian)
classpath-object-dep = $(build)/classpath-object.dep
classpath-objects = $(shell find $(build)/classpath-objects -name "*.o")
else
ifeq ($(classpath),avian)
jni-sources := $(shell find $(classpath-src) -name '*.cpp')
jni-objects = $(call cpp-objects,$(jni-sources),$(classpath-src),$(build))
classpath-objects = $(jni-objects)
endif
input = List
@ -95,6 +104,7 @@ vg = nice valgrind --num-callers=32 --db-attach=yes --freelist-vol=100000000
vg += --leak-check=full --suppressions=valgrind.supp
db = gdb --args
javac = "$(JAVA_HOME)/bin/javac"
javah = "$(JAVA_HOME)/bin/javah"
jar = "$(JAVA_HOME)/bin/jar"
strip = strip
strip-all = --strip-all
@ -108,7 +118,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
-Wno-non-virtual-dtor
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) \
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(java-home)\"
@ -222,28 +232,30 @@ ifeq ($(platform),windows)
endif
ifeq ($(mode),debug)
cflags += -O0 -g3
optimization-cflags = -O0 -g3
strip = :
endif
ifeq ($(mode),debug-fast)
cflags += -O0 -g3 -DNDEBUG
optimization-cflags = -O0 -g3 -DNDEBUG
strip = :
endif
ifeq ($(mode),stress)
cflags += -O0 -g3 -DVM_STRESS
optimization-cflags = -O0 -g3 -DVM_STRESS
strip = :
endif
ifeq ($(mode),stress-major)
cflags += -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
optimization-cflags = -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
strip = :
endif
ifeq ($(mode),fast)
cflags += -O3 -g3 -DNDEBUG
optimization-cflags = -O3 -g3 -DNDEBUG
endif
ifeq ($(mode),small)
cflags += -Os -g3 -DNDEBUG
optimization-cflags = -Os -g3 -DNDEBUG
endif
cflags += $(optimization-cflags)
ifneq ($(platform),darwin)
ifeq ($(arch),i386)
# this is necessary to support __sync_bool_compare_and_swap:
@ -467,15 +479,15 @@ $(test-extra-dep): $(classpath-dep)
.PHONY: run
run: build
LD_LIBRARY_PATH=$(build) $(test-executable) $(test-args)
$(library-path) $(test-executable) $(test-args)
.PHONY: debug
debug: build
LD_LIBRARY_PATH=$(build) gdb --args $(test-executable) $(test-args)
$(library-path) gdb --args $(test-executable) $(test-args)
.PHONY: vg
vg: build
LD_LIBRARY_PATH=$(build) $(vg) $(test-executable) $(test-args)
$(library-path) $(vg) $(test-executable) $(test-args)
.PHONY: test
test: build
@ -581,7 +593,8 @@ $(driver-dynamic-object): $(driver-source)
$(boot-object): $(boot-source)
$(compile-object)
$(build)/classpath.jar: $(classpath-dep)
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
@echo "creating $(@)"
(wd=$$(pwd) && \
cd $(classpath-build) && \
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
@ -622,11 +635,10 @@ $(generator-objects): $(build)/%-build.o: $(src)/%.cpp
$(jni-objects): $(build)/%.o: $(classpath-src)/%.cpp
$(compile-object)
$(static-library): $(classpath-object-dep)
$(static-library): $(vm-objects) $(jni-objects) $(vm-heapwalk-objects)
$(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects)
@echo "creating $(@)"
rm -rf $(@)
$(ar) cru $(@) $(^) $(call classpath-objects)
$(ar) cru $(@) $(^)
$(ranlib) $(@)
$(bootimage-bin): $(bootimage-generator)
@ -638,16 +650,10 @@ $(bootimage-object): $(bootimage-bin) $(converter)
_binary_bootimage_bin_end $(platform) $(arch) $(pointer-size) \
writable executable
$(classpath-object-dep): $(classpath-libraries)
@mkdir -p $(build)/classpath-objects
(cd $(build)/classpath-objects && \
for x in $(classpath-libraries); do ar x $${x}; done)
@touch $(@)
executable-objects = $(vm-objects) $(jni-objects) $(driver-object) \
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object)
$(executable): $(classpath-object-dep) $(executable-objects)
$(executable): $(executable-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
@ -655,14 +661,12 @@ ifdef msvc
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
else
$(dlltool) -z $(@).def $(executable-objects) $(call classpath-objects)
$(dlltool) -z $(@).def $(executable-objects)
$(dlltool) -d $(@).def -e $(@).exp
$(ld) $(@).exp $(executable-objects) $(call classpath-objects) $(lflags) \
-o $(@)
$(ld) $(@).exp $(executable-objects) $(lflags) -o $(@)
endif
else
$(ld) $(executable-objects) $(call classpath-objects) $(rdynamic) $(lflags) \
$(bootimage-lflags) -o $(@)
$(ld) $(executable-objects) $(rdynamic) $(lflags) $(bootimage-lflags) -o $(@)
endif
$(strip) $(strip-all) $(@)
@ -675,8 +679,8 @@ $(bootimage-generator):
$(bootimage-generator)
$(build-bootimage-generator): \
$(vm-objects) $(classpath-object) $(jni-objects) $(heapwalk-objects) \
$(bootimage-generator-objects)
$(vm-objects) $(classpath-object) $(classpath-objects) \
$(heapwalk-objects) $(bootimage-generator-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
@ -692,11 +696,11 @@ else
$(ld) $(^) $(rdynamic) $(lflags) -o $(@)
endif
dynamic-library-objects = $(vm-objects) $(dynamic-object) $(jni-objects) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object) \
$(classpath-libraries)
dynamic-library-objects = $(vm-objects) $(dynamic-object) \
$(classpath-objects) $(vm-heapwalk-objects) $(boot-object) \
$(vm-classpath-object) $(classpath-libraries)
$(dynamic-library): $(classpath-object-dep) $(dynamic-library-objects)
$(dynamic-library): $(dynamic-library-objects)
@echo "linking $(@)"
ifdef msvc
$(ld) $(shared) $(lflags) $(dynamic-library-objects) -out:$(@) \
@ -704,7 +708,7 @@ ifdef msvc
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
else
$(ld) $(dynamic-library-objects) -Wl,--version-script=openjdk.ld \
$(call classpath-objects) $(shared) $(lflags) $(bootimage-lflags) -o $(@)
$(shared) $(lflags) $(bootimage-lflags) -o $(@)
endif
$(strip) $(strip-all) $(@)
@ -722,3 +726,25 @@ endif
$(generator): $(generator-objects)
@echo "linking $(@)"
$(build-ld) $(^) $(build-lflags) -o $(@)
$(openjdk-objects): $(build)/openjdk/%.o: $(openjdk-src)/%.c \
$(openjdk-headers-dep)
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cc) -fPIC -fvisibility=hidden $(openjdk-cflags) $(optimization-cflags) \
-w -c $(<) $(call output,$(@))
$(openjdk-headers-dep): $(openjdk)/jre/lib/rt.jar
@echo "generating openjdk headers"
@mkdir -p $(dir $(@))
$(javah) -d $(build)/openjdk -bootclasspath $(boot-classpath) \
$(openjdk-headers-classes)
@touch $(@)
$(openjdk-jar-dep): $(openjdk)/jre/lib/rt.jar $(openjdk)/jre/lib/jsse.jar \
$(openjdk)/jre/lib/jce.jar $(openjdk)/jre/lib/resources.jar
@echo "extracting openjdk classes"
@mkdir -p $(dir $(@))
@mkdir -p $(classpath-build)
(cd $(classpath-build) && for x in $(^); do jar xf $${x}; done)
@touch $(@)

166
openjdk-src.mk Normal file
View File

@ -0,0 +1,166 @@
openjdk-sources = \
$(openjdk-src)/share/native/common/check_code.c \
$(openjdk-src)/share/native/common/check_format.c \
$(openjdk-src)/share/native/common/check_version.c \
$(openjdk-src)/share/native/common/jdk_util.c \
$(openjdk-src)/share/native/common/jio.c \
$(openjdk-src)/share/native/common/jni_util.c \
$(openjdk-src)/share/native/common/verify_stub.c \
$(openjdk-src)/share/native/java/io/FileInputStream.c \
$(openjdk-src)/share/native/java/io/io_util.c \
$(openjdk-src)/share/native/java/io/ObjectInputStream.c \
$(openjdk-src)/share/native/java/io/ObjectOutputStream.c \
$(openjdk-src)/share/native/java/io/ObjectStreamClass.c \
$(openjdk-src)/share/native/java/io/RandomAccessFile.c \
$(openjdk-src)/share/native/java/lang/Class.c \
$(openjdk-src)/share/native/java/lang/ClassLoader.c \
$(openjdk-src)/share/native/java/lang/Compiler.c \
$(openjdk-src)/share/native/java/lang/Double.c \
$(openjdk-src)/share/native/java/lang/Float.c \
$(openjdk-src)/share/native/java/lang/Object.c \
$(openjdk-src)/share/native/java/lang/Package.c \
$(openjdk-src)/share/native/java/lang/ref/Finalizer.c \
$(openjdk-src)/share/native/java/lang/reflect/Array.c \
$(openjdk-src)/share/native/java/lang/reflect/Proxy.c \
$(openjdk-src)/share/native/java/lang/ResourceBundle.c \
$(openjdk-src)/share/native/java/lang/Runtime.c \
$(openjdk-src)/share/native/java/lang/SecurityManager.c \
$(openjdk-src)/share/native/java/lang/Shutdown.c \
$(openjdk-src)/share/native/java/lang/StrictMath.c \
$(openjdk-src)/share/native/java/lang/String.c \
$(openjdk-src)/share/native/java/lang/System.c \
$(openjdk-src)/share/native/java/lang/Thread.c \
$(openjdk-src)/share/native/java/lang/Throwable.c \
$(wildcard $(openjdk-src)/share/native/java/lang/fdlibm/src/*.c) \
$(openjdk-src)/share/native/java/nio/Bits.c \
$(openjdk-src)/share/native/java/security/AccessController.c \
$(openjdk-src)/share/native/java/sql/DriverManager.c \
$(openjdk-src)/share/native/java/util/concurrent/atomic/AtomicLong.c \
$(openjdk-src)/share/native/java/util/TimeZone.c \
$(openjdk-src)/share/native/java/util/zip/Adler32.c \
$(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/misc/GC.c \
$(openjdk-src)/share/native/sun/misc/MessageUtils.c \
$(openjdk-src)/share/native/sun/misc/NativeSignalHandler.c \
$(openjdk-src)/share/native/sun/misc/Signal.c \
$(openjdk-src)/share/native/sun/misc/Version.c \
$(openjdk-src)/share/native/sun/misc/VM.c \
$(openjdk-src)/share/native/sun/misc/VMSupport.c \
$(openjdk-src)/share/native/sun/reflect/ConstantPool.c \
$(openjdk-src)/share/native/sun/reflect/NativeAccessors.c \
$(openjdk-src)/share/native/sun/reflect/Reflection.c
openjdk-headers-classes = \
java.io.Console \
java.io.FileDescriptor \
java.io.FileInputStream \
java.io.FileOutputStream \
java.io.FileSystem \
java.io.ObjectInputStream \
java.io.ObjectOutputStream \
java.io.ObjectStreamClass \
java.io.RandomAccessFile \
java.lang.Class \
java.lang.ClassLoader \
java.lang.Compiler \
java.lang.Double \
java.lang.Float \
java.lang.Object \
java.lang.Package \
java.lang.Runtime \
java.lang.SecurityManager \
java.lang.Shutdown \
java.lang.StrictMath \
java.lang.String \
java.lang.System \
java.lang.Thread \
java.lang.Throwable \
java.lang.ref.Finalizer \
java.lang.reflect.Array \
java.lang.reflect.Proxy \
java.security.AccessController \
java.util.ResourceBundle \
java.util.TimeZone \
java.util.concurrent.atomic.AtomicLong \
java.util.jar.JarFile \
java.util.zip.Adler32 \
java.util.zip.CRC32 \
java.util.zip.Deflater \
java.util.zip.Inflater \
java.util.zip.ZipEntry \
java.util.zip.ZipFile \
sun.misc.GC \
sun.misc.MessageUtils \
sun.misc.NativeSignalHandler \
sun.misc.Signal \
sun.misc.VM \
sun.misc.VMSupport \
sun.misc.Version \
sun.reflect.ConstantPool \
sun.reflect.NativeConstructorAccessorImpl \
sun.reflect.NativeMethodAccessorImpl \
sun.reflect.Reflection \
# todo: set properties according to architecture targeted and OpenJDK
# version used:
openjdk-cflags = \
"-I$(src)/openjdk" \
"-I$(build)/openjdk" \
"-I$(openjdk-src)/share/javavm/export" \
"-I$(openjdk-src)/share/native/common" \
"-I$(openjdk-src)/share/native/java/io" \
"-I$(openjdk-src)/share/native/java/lang" \
"-I$(openjdk-src)/share/native/java/lang/fdlibm/include" \
"-I$(openjdk-src)/share/native/java/util/zip" \
"-I$(openjdk-src)/share/javavm/include" \
-D_LITTLE_ENDIAN \
-DARCHPROPNAME=\"x86\" \
-DRELEASE=\"1.6.0\" \
-DJDK_MAJOR_VERSION=\"1\" \
-DJDK_MINOR_VERSION=\"6\" \
-DJDK_MICRO_VERSION=\"0\" \
-DJDK_BUILD_NUMBER=\"0\" \
-D_GNU_SOURCE
ifeq ($(platform),windows)
# todo
else
openjdk-sources += \
$(openjdk-src)/solaris/native/common/jdk_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 \
$(openjdk-src)/solaris/native/java/io/FileInputStream_md.c \
$(openjdk-src)/solaris/native/java/io/FileOutputStream_md.c \
$(openjdk-src)/solaris/native/java/io/FileSystem_md.c \
$(openjdk-src)/solaris/native/java/io/io_util_md.c \
$(openjdk-src)/solaris/native/java/io/RandomAccessFile_md.c \
$(openjdk-src)/solaris/native/java/io/UnixFileSystem_md.c \
$(openjdk-src)/solaris/native/java/lang/java_props_md.c \
$(openjdk-src)/solaris/native/java/lang/ProcessEnvironment_md.c \
$(openjdk-src)/solaris/native/java/lang/UNIXProcess_md.c \
$(openjdk-src)/solaris/native/java/util/FileSystemPreferences.c \
$(openjdk-src)/solaris/native/java/util/logging.c \
$(openjdk-src)/solaris/native/java/util/TimeZone_md.c
openjdk-headers-classes += \
java.io.UnixFileSystem
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/util" \
"-I$(openjdk-src)/solaris/javavm/include"
endif
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
openjdk-objects = \
$(call c-objects,$(openjdk-sources),$(openjdk-src),$(build)/openjdk)
openjdk-headers-dep = $(build)/openjdk/headers.dep

View File

@ -191,6 +191,54 @@ Finally, build with the msvc flag set to the MSVC tool directory:
$ make msvc="/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC"
Building with the OpenJDK Class Library
---------------------------------------
By default, Avian uses its own lightweight class library. However,
that library only contains a relatively small subset of the classes
and methods included in the JRE. If your application requires
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
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
application in this configuration, you'll need to make sure the VM is
in your library search path. For example:
$ LD_LIBRARY_PATH=build/linux-x86_64-openjdk \
build/linux-x86_64-openjdk/avian-dynamic -cp /path/to/my/application \
com.example.MyApplication
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
The result of such a build is a self-contained binary which does not
depend on external libraries, jars, or other files. In this case, the
specified paths are used only at build time; anything needed at
runtime is embedded in the binary. Thus, the process of running an
application is simplified:
$ build/linux-x86_64-openjdk-src/avian -cp /path/to/my/application \
com.example.MyApplication
Note that the resulting binary will be very large due to the size of
OpenJDK's class library. This can be mitigated using UPX, preferably
an LZMA-enabled version:
$ upx --lzma --best build/linux-x86_64-openjdk-src/avian
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).
Installing
----------

View File

@ -35,6 +35,9 @@
# define CREAT _wcreat
# endif
# define LIBRARY_PREFIX ""
# define LIBRARY_SUFFIX ".dll"
#else // not PLATFORM_WINDOWS
# include <unistd.h>
@ -53,6 +56,9 @@
# define FSTAT fstat
# define LSEEK lseek
# define LIBRARY_PREFIX "lib"
# define LIBRARY_SUFFIX ".so"
#endif // not PLATFORM_WINDOWS
using namespace vm;
@ -139,6 +145,72 @@ makeClassNameString(Thread* t, object name)
return makeString(t, "%s", s);
}
#ifdef AVIAN_OPENJDK_SRC
// only safe to call during bootstrap when there's only one thread
// running:
void
intercept(Thread* t, object c, const char* name, const char* spec,
void* function)
{
object m = findMethodOrNull(t, c, name, spec);
if (m) {
PROTECT(t, m);
object clone = methodClone(t, m);
// make clone private to prevent vtable updates at compilation
// time. Otherwise, our interception might be bypassed by calls
// through the vtable.
methodFlags(t, clone) |= ACC_PRIVATE;
methodFlags(t, m) |= ACC_NATIVE;
object native = makeNativeIntercept(t, function, true, clone);
set(t, m, MethodCode, native);
}
}
const char*
zipLibrary(Thread*);
int64_t JNICALL
getFileAttributes
(Thread* t, object method, uintptr_t* arguments)
{
const unsigned Exists = 1;
const unsigned Regular = 2;
object file = reinterpret_cast<object>(arguments[1]);
object pathField = findFieldInClass2
(t, objectClass(t, file), "path", "Ljava/lang/String;");
if (pathField) {
object path = cast<object>(file, fieldOffset(t, pathField));
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
if (strcmp(zipLibrary(t), p) == 0) {
return Exists | Regular;
} else {
object r = t->m->processor->invoke
(t, nativeInterceptOriginal(t, methodCode(t, method)),
reinterpret_cast<object>(arguments[0]), file);
return (r ? intValue(t, r) : 0);
}
} else {
object message = makeString
(t, "path Ljava/lang/String; not found in %s",
&byteArrayBody(t, className(t, objectClass(t, file)), 0));
t->exception = t->m->classpath->makeThrowable
(t, Machine::RuntimeExceptionType, message);
return 0;
}
}
#endif // AVIAN_OPENJDK_SRC
class MyClasspath : public Classpath {
public:
static const unsigned BufferSize = 1024;
@ -205,6 +277,14 @@ class MyClasspath : public Classpath {
// todo: handle other architectures
sb.append("/lib/i386");
#endif
sb.append('\0');
this->zipLibrary = sb.pointer;
sb.append(this->libraryPath);
sb.append("/");
sb.append(LIBRARY_PREFIX);
sb.append("zip");
sb.append(LIBRARY_SUFFIX);
}
virtual object
@ -296,9 +376,20 @@ class MyClasspath : public Classpath {
{
globalMachine = t->m;
#ifdef AVIAN_OPENJDK_SRC
{ object c = resolveClass
(t, root(t, Machine::BootLoader), "java/io/UnixFileSystem");
if (c) {
intercept(t, c, "getBooleanAttributes0", "(Ljava/io/File;)I",
voidPointer(getFileAttributes));
}
}
#else // not AVIAN_OPENJDK_SRC
if (loadLibrary(t, libraryPath, "java", true, true) == 0) {
abort(t);
}
#endif // not AVIAN_OPENJDK_SRC
t->m->processor->invoke
(t, root(t, Machine::BootLoader), "java/lang/System",
@ -351,6 +442,7 @@ class MyClasspath : public Classpath {
const char* javaHome;
const char* classpath;
const char* libraryPath;
const char* zipLibrary;
char buffer[BufferSize];
};
@ -374,6 +466,12 @@ struct jvm_version_info {
unsigned int: 32;
};
const char*
zipLibrary(Thread* t)
{
return static_cast<MyClasspath*>(t->m->classpath)->zipLibrary;
}
unsigned
countMethods(Thread* t, object c, bool publicOnly)
{
@ -1205,7 +1303,13 @@ extern "C" JNIEXPORT void* JNICALL
JVM_LoadLibrary(const char* name)
{
Thread* t = static_cast<Thread*>(local::globalMachine->localThread->get());
#ifdef AVIAN_OPENJDK_SRC
if (strcmp(local::zipLibrary(t), name) == 0) {
return t->m->libraries;
}
#endif // AVIAN_OPENJDK_SRC
ENTER(t, Thread::ActiveState);
return loadLibrary
@ -2597,18 +2701,18 @@ jio_vsnprintf(char* dst, size_t size, const char* format, va_list a)
return vm::vsnprintf(dst, size, format, a);
}
extern "C" JNIEXPORT int
jio_snprintf(char* dst, size_t size, const char* format, ...)
{
va_list a;
va_start(a, format);
// extern "C" JNIEXPORT int
// jio_snprintf(char* dst, size_t size, const char* format, ...)
// {
// va_list a;
// va_start(a, format);
int r = jio_vsnprintf(dst, size, format, a);
// int r = jio_vsnprintf(dst, size, format, a);
va_end(a);
// va_end(a);
return r;
}
// return r;
// }
extern "C" JNIEXPORT int
jio_vfprintf(FILE* stream, const char* format, va_list a)
@ -2616,15 +2720,15 @@ jio_vfprintf(FILE* stream, const char* format, va_list a)
return vfprintf(stream, format, a);
}
extern "C" JNIEXPORT int
jio_fprintf(FILE* stream, const char* format, ...)
{
va_list a;
va_start(a, format);
// extern "C" JNIEXPORT int
// jio_fprintf(FILE* stream, const char* format, ...)
// {
// va_list a;
// va_start(a, format);
int r = jio_vfprintf(stream, format, a);
// int r = jio_vfprintf(stream, format, a);
va_end(a);
// va_end(a);
return r;
}
// return r;
// }

View File

@ -8601,19 +8601,7 @@ compile(MyThread* t, Allocator* allocator, BootContext* bootContext,
// method so that we won't be confused if another thread updates the
// original while we're working.
object clone = makeMethod
(t, methodVmFlags(t, method),
methodReturnCode(t, method),
methodParameterCount(t, method),
methodParameterFootprint(t, method),
methodFlags(t, method),
methodOffset(t, method),
methodNativeID(t, method),
methodName(t, method),
methodSpec(t, method),
methodAddendum(t, method),
methodClass(t, method),
methodCode(t, method));
object clone = methodClone(t, method);
loadMemoryBarrier();

View File

@ -1928,10 +1928,16 @@ RegisterNatives(Thread* t, jclass c, const JNINativeMethod* methods,
for (int i = 0; i < methodCount; ++i) {
if (methods[i].function) {
object method = findMethod(t, c, methods[i].name, methods[i].signature);
if (UNLIKELY(t->exception)) return -1;
object method = findMethodOrNull
(t, jclassVmClass(t, *c), methods[i].name, methods[i].signature);
registerNative(t, method, methods[i].function);
if (method == 0 or (methodFlags(t, method) & ACC_NATIVE) == 0) {
// The JNI spec says we must throw a NoSuchMethodError in this
// case, but that would prevent using a code shrinker like
// ProGuard effectively. Instead, we just ignore it.
} else {
registerNative(t, method, methods[i].function);
}
}
}

View File

@ -3546,9 +3546,8 @@ findInTable(Thread* t, object table, object name, object spec,
}
object
findInHierarchy(Thread* t, object class_, object name, object spec,
object (*find)(Thread*, object, object, object),
Machine::Type errorType)
findInHierarchyOrNull(Thread* t, object class_, object name, object spec,
object (*find)(Thread*, object, object, object))
{
object originalClass = class_;
@ -3570,15 +3569,6 @@ findInHierarchy(Thread* t, object class_, object name, object spec,
}
}
if (o == 0) {
object message = makeString
(t, "%s %s not found in %s",
&byteArrayBody(t, name, 0),
&byteArrayBody(t, spec, 0),
&byteArrayBody(t, className(t, originalClass), 0));
t->exception = t->m->classpath->makeThrowable(t, errorType, message);
}
return o;
}

View File

@ -2127,11 +2127,11 @@ object
resolveClass(Thread* t, object loader, object name, bool throw_ = true);
inline object
resolveClass(Thread* t, object loader, const char* name)
resolveClass(Thread* t, object loader, const char* name, bool throw_ = true)
{
PROTECT(t, loader);
object n = makeByteArray(t, "%s", name);
return resolveClass(t, loader, n);
return resolveClass(t, loader, n, throw_);
}
object
@ -2211,6 +2211,16 @@ findFieldInClass(Thread* t, object class_, object name, object spec)
(t, classFieldTable(t, class_), name, spec, fieldName, fieldSpec);
}
inline object
findFieldInClass2(Thread* t, object class_, const char* name, const char* spec)
{
PROTECT(t, class_);
object n = makeByteArray(t, "%s", name);
PROTECT(t, n);
object s = makeByteArray(t, "%s", spec);
return findFieldInClass(t, class_, n, s);
}
inline object
findMethodInClass(Thread* t, object class_, object name, object spec)
{
@ -2219,9 +2229,27 @@ findMethodInClass(Thread* t, object class_, object name, object spec)
}
object
findInHierarchyOrNull(Thread* t, object class_, object name, object spec,
object (*find)(Thread*, object, object, object));
inline object
findInHierarchy(Thread* t, object class_, object name, object spec,
object (*find)(Thread*, object, object, object),
Machine::Type errorType);
Machine::Type errorType)
{
object o = findInHierarchyOrNull(t, class_, name, spec, find);
if (o == 0) {
object message = makeString
(t, "%s %s not found in %s",
&byteArrayBody(t, name, 0),
&byteArrayBody(t, spec, 0),
&byteArrayBody(t, className(t, class_), 0));
t->exception = t->m->classpath->makeThrowable(t, errorType, message);
}
return o;
}
inline object
findMethod(Thread* t, object class_, object name, object spec)
@ -2230,6 +2258,16 @@ findMethod(Thread* t, object class_, object name, object spec)
(t, class_, name, spec, findMethodInClass, Machine::NoSuchMethodErrorType);
}
inline object
findMethodOrNull(Thread* t, object class_, const char* name, const char* spec)
{
PROTECT(t, class_);
object n = makeByteArray(t, "%s", name);
PROTECT(t, n);
object s = makeByteArray(t, "%s", spec);
return findInHierarchyOrNull(t, class_, n, s, findMethodInClass);
}
inline object
findVirtualMethod(Thread* t, object method, object class_)
{
@ -3066,6 +3104,24 @@ defineClass(Thread* t, object loader, const uint8_t* buffer, unsigned length);
void
dumpHeap(Thread* t, FILE* out);
inline object
methodClone(Thread* t, object method)
{
return makeMethod
(t, methodVmFlags(t, method),
methodReturnCode(t, method),
methodParameterCount(t, method),
methodParameterFootprint(t, method),
methodFlags(t, method),
methodOffset(t, method),
methodNativeID(t, method),
methodName(t, method),
methodSpec(t, method),
methodAddendum(t, method),
methodClass(t, method),
methodCode(t, method));
}
} // namespace vm
void

29
src/openjdk/jni_md.h Normal file
View File

@ -0,0 +1,29 @@
/* Copyright (c) 2010, 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. */
#ifndef JNI_MD_H
#define JNI_MD_H
#include "stdint.h"
#if (defined __MINGW32__) || (defined _MSC_VER)
# define JNIEXPORT __declspec(dllexport)
#else // not (defined __MINGW32__) || (defined _MSC_VER)
# define JNIEXPORT __attribute__ ((visibility("default")))
#endif // not (defined __MINGW32__) || (defined _MSC_VER)
#define JNIIMPORT
#define JNICALL
typedef int32_t jint;
typedef int64_t jlong;
typedef int8_t jbyte;
#endif//JNI_MD_H

View File

@ -44,6 +44,10 @@
(void* function)
(uint8_t fast))
(type nativeIntercept
(extends native)
(object original))
(pod exceptionHandler
(uint16_t start)
(uint16_t end)