Merge remote branch 'rtgithub/master' into mkgithubmaster

This commit is contained in:
Mike Keesey 2012-06-13 15:36:21 -06:00
commit 478560e269
29 changed files with 1045 additions and 347 deletions

View File

@ -76,7 +76,9 @@ Java_java_util_zip_Inflater_inflate
int r = inflate(s, Z_SYNC_FLUSH); int r = inflate(s, Z_SYNC_FLUSH);
jint resultArray[3] jint resultArray[3]
= { r, inputLength - s->avail_in, outputLength - s->avail_out }; = { r,
static_cast<jint>(inputLength - s->avail_in),
static_cast<jint>(outputLength - s->avail_out) };
free(in); free(in);
@ -147,7 +149,9 @@ Java_java_util_zip_Deflater_deflate
int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH); int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH);
jint resultArray[3] jint resultArray[3]
= { r, inputLength - s->avail_in, outputLength - s->avail_out }; = { r,
static_cast<jint>(inputLength - s->avail_in),
static_cast<jint>(outputLength - s->avail_out) };
free(in); free(in);

View File

@ -73,8 +73,6 @@ typedef unsigned __int64 uint64_t;
#endif // not _MSC_VER #endif // not _MSC_VER
namespace {
inline void inline void
throwNew(JNIEnv* e, const char* class_, const char* message, ...) throwNew(JNIEnv* e, const char* class_, const char* message, ...)
{ {
@ -149,7 +147,4 @@ class RuntimeArray {
#endif // not _MSC_VER #endif // not _MSC_VER
} // namespace
#endif//JNI_UTIL #endif//JNI_UTIL

168
makefile
View File

@ -1,7 +1,7 @@
MAKEFLAGS = -s MAKEFLAGS = -s
name = avian name = avian
version = 0.5 version = 0.6
build-arch := $(shell uname -m \ build-arch := $(shell uname -m \
| sed 's/^i.86$$/i386/' \ | sed 's/^i.86$$/i386/' \
@ -33,6 +33,9 @@ endif
ifneq ($(mode),fast) ifneq ($(mode),fast)
options := $(options)-$(mode) options := $(options)-$(mode)
endif endif
ifneq ($(lzma),)
options := $(options)-lzma
endif
ifeq ($(bootimage),true) ifeq ($(bootimage),true)
options := $(options)-bootimage options := $(options)-bootimage
endif endif
@ -68,6 +71,8 @@ ifeq ($(build-platform),cygwin)
native-path = cygpath -m native-path = cygpath -m
endif endif
windows-path = echo
path-separator = : path-separator = :
ifneq (,$(filter mingw32 cygwin,$(build-platform))) ifneq (,$(filter mingw32 cygwin,$(build-platform)))
@ -138,8 +143,13 @@ endif
input = List input = List
build-cxx = g++ ifeq ($(use-clang),true)
build-cc = gcc build-cxx = clang -std=c++11
build-cc = clang
else
build-cxx = g++
build-cc = gcc
endif
mflag = mflag =
ifneq ($(platform),darwin) ifneq ($(platform),darwin)
@ -195,7 +205,8 @@ build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject -Isrc/ \ converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject -Isrc/ \
-fno-rtti -fno-exceptions \ -fno-rtti -fno-exceptions \
-DAVIAN_TARGET_ARCH=AVIAN_ARCH_UNKNOWN \ -DAVIAN_TARGET_ARCH=AVIAN_ARCH_UNKNOWN \
-DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_UNKNOWN -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_UNKNOWN \
-Wall -Wextra -Werror -Wunused-parameter -Winit-self -Wno-non-virtual-dtor
cflags = $(build-cflags) cflags = $(build-cflags)
@ -219,6 +230,8 @@ so-suffix = .so
shared = -shared shared = -shared
no-error = -Wno-error
openjdk-extra-cflags = -fvisibility=hidden openjdk-extra-cflags = -fvisibility=hidden
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size) bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
@ -313,8 +326,12 @@ ifeq ($(platform),darwin)
endif endif
version-script-flag = version-script-flag =
lflags = $(common-lflags) -ldl -framework CoreFoundation \ lflags = $(common-lflags) -ldl -framework CoreFoundation
-Wl,-compatibility_version,1.0.0
ifeq (,$(shell ld -v 2>&1 | grep cctools))
lflags += -Wl,-compatibility_version,1.0.0
endif
ifneq ($(arch),arm) ifneq ($(arch),arm)
lflags += -framework CoreServices -framework SystemConfiguration \ lflags += -framework CoreServices -framework SystemConfiguration \
-framework Security -framework Security
@ -446,23 +463,36 @@ ifeq ($(mode),stress-major)
strip = : strip = :
endif endif
ifeq ($(mode),fast) ifeq ($(mode),fast)
optimization-cflags = -O3 -g3 -DNDEBUG ifeq ($(use-clang),true)
optimization-cflags = -O4 -g3 -DNDEBUG
else
optimization-cflags = -O3 -g3 -DNDEBUG
endif
use-lto = true use-lto = true
endif endif
ifeq ($(mode),small) ifeq ($(mode),small)
optimization-cflags = -Os -g3 -DNDEBUG ifeq ($(use-clang),true)
optimization-cflags = -Oz -g3 -DNDEBUG
else
optimization-cflags = -Os -g3 -DNDEBUG
endif
use-lto = true use-lto = true
endif endif
ifeq ($(use-lto),true) ifeq ($(use-lto),true)
# only try to use LTO when GCC 4.6.0 or greater is available ifeq ($(use-clang),true)
gcc-major := $(shell $(cc) -dumpversion | cut -f1 -d.)
gcc-minor := $(shell $(cc) -dumpversion | cut -f2 -d.)
ifeq ($(shell expr 4 \< $(gcc-major) \
\| \( 4 \<= $(gcc-major) \& 6 \<= $(gcc-minor) \)),1)
optimization-cflags += -flto optimization-cflags += -flto
no-lto = -fno-lto
lflags += $(optimization-cflags) lflags += $(optimization-cflags)
else
# only try to use LTO when GCC 4.6.0 or greater is available
gcc-major := $(shell $(cc) -dumpversion | cut -f1 -d.)
gcc-minor := $(shell $(cc) -dumpversion | cut -f2 -d.)
ifeq ($(shell expr 4 \< $(gcc-major) \
\| \( 4 \<= $(gcc-major) \& 6 \<= $(gcc-minor) \)),1)
optimization-cflags += -flto
no-lto = -fno-lto
lflags += $(optimization-cflags)
endif
endif endif
endif endif
@ -482,8 +512,10 @@ ld := $(cc)
build-ld := $(build-cc) build-ld := $(build-cc)
ifdef msvc ifdef msvc
windows-java-home := $(shell cygpath -m "$(JAVA_HOME)") no-error =
zlib := $(shell cygpath -m "$(win32)/msvc") windows-path = $(native-path)
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
zlib := $(shell $(windows-path) "$(win32)/msvc")
cxx = "$(msvc)/BIN/cl.exe" cxx = "$(msvc)/BIN/cl.exe"
cc = $(cxx) cc = $(cxx)
ld = "$(msvc)/BIN/link.exe" ld = "$(msvc)/BIN/link.exe"
@ -494,6 +526,11 @@ ifdef msvc
-Fd$(build)/$(name).pdb -I"$(zlib)/include" -I$(src) -I"$(build)" \ -Fd$(build)/$(name).pdb -I"$(zlib)/include" -I$(src) -I"$(build)" \
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \ -I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \
-DTARGET_BYTES_PER_WORD=$(pointer-size) -DTARGET_BYTES_PER_WORD=$(pointer-size)
ifneq ($(lzma),)
cflags += -I$(shell $(windows-path) "$(lzma)")
endif
shared = -dll shared = -dll
lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \ lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \
-DEFAULTLIB:zlib -MANIFEST -debug -DEFAULTLIB:zlib -MANIFEST -debug
@ -517,6 +554,7 @@ ifdef msvc
strip = : strip = :
endif endif
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x))) cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x))) asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x)))
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x))) java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
@ -580,6 +618,9 @@ ifeq ($(continuations),true)
endif endif
bootimage-generator-sources = $(src)/bootimage.cpp bootimage-generator-sources = $(src)/bootimage.cpp
ifneq ($(lzma),)
bootimage-generator-sources += $(src)/lzma-encode.cpp
endif
bootimage-generator-objects = \ bootimage-generator-objects = \
$(call cpp-objects,$(bootimage-generator-sources),$(src),$(build)) $(call cpp-objects,$(bootimage-generator-sources),$(src),$(build))
bootimage-generator = $(build)/bootimage-generator bootimage-generator = $(build)/bootimage-generator
@ -614,17 +655,62 @@ generator-sources = \
$(src)/type-generator.cpp \ $(src)/type-generator.cpp \
$(src)/$(build-system).cpp \ $(src)/$(build-system).cpp \
$(src)/finder.cpp $(src)/finder.cpp
ifneq ($(lzma),)
common-cflags += -I$(lzma) -DAVIAN_USE_LZMA -D_7ZIP_ST
vm-sources += \
$(src)/lzma-decode.cpp
generator-sources += \
$(src)/lzma-decode.cpp
lzma-decode-sources = \
$(lzma)/C/LzmaDec.c
lzma-decode-objects = \
$(call c-objects,$(lzma-decode-sources),$(lzma)/C,$(build))
lzma-encode-sources = \
$(lzma)/C/LzmaEnc.c \
$(lzma)/C/LzFind.c
lzma-encode-objects = \
$(call c-objects,$(lzma-encode-sources),$(lzma)/C,$(build))
lzma-encoder = $(build)/lzma/lzma
lzma-encoder-cflags = -D__STDC_CONSTANT_MACROS -fno-rtti -fno-exceptions \
-I$(lzma)/C
lzma-encoder-sources = \
$(src)/lzma/main.cpp
lzma-encoder-objects = \
$(call cpp-objects,$(lzma-encoder-sources),$(src),$(build))
lzma-encoder-lzma-sources = $(lzma-encode-sources) $(lzma-decode-sources)
lzma-encoder-lzma-objects = \
$(call generator-c-objects,$(lzma-encoder-lzma-sources),$(lzma)/C,$(build))
lzma-loader = $(build)/lzma/load.o
endif
generator-cpp-objects = \ generator-cpp-objects = \
$(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%-build.o,$(x))) $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%-build.o,$(x)))
generator-c-objects = \
$(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%-build.o,$(x)))
generator-objects = \ generator-objects = \
$(call generator-cpp-objects,$(generator-sources),$(src),$(build)) $(call generator-cpp-objects,$(generator-sources),$(src),$(build))
generator-lzma-objects = \
$(call generator-c-objects,$(lzma-decode-sources),$(lzma)/C,$(build))
generator = $(build)/generator generator = $(build)/generator
converter-depends = \ converter-depends = \
$(src)/binaryToObject/tools.h \ $(src)/binaryToObject/tools.h \
$(src)/binaryToObject/endianness.h $(src)/binaryToObject/endianness.h
converter-sources = \ converter-sources = \
$(src)/binaryToObject/tools.cpp \ $(src)/binaryToObject/tools.cpp \
$(src)/binaryToObject/elf.cpp \ $(src)/binaryToObject/elf.cpp \
@ -745,8 +831,9 @@ test-flags = -cp $(build)/test
test-args = $(test-flags) $(input) test-args = $(test-flags) $(input)
.PHONY: build .PHONY: build
build: $(static-library) $(executable) $(dynamic-library) \ build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \
$(executable-dynamic) $(classpath-dep) $(test-dep) $(test-extra-dep) $(lzma-encoder) $(executable-dynamic) $(classpath-dep) $(test-dep) \
$(test-extra-dep)
$(test-dep): $(classpath-dep) $(test-dep): $(classpath-dep)
@ -836,7 +923,7 @@ $(test-extra-dep): $(test-extra-sources)
define compile-object define compile-object
@echo "compiling $(@)" @echo "compiling $(@)"
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
$(cxx) $(cflags) -c $(<) $(call output,$(@)) $(cxx) $(cflags) -c $$($(windows-path) $(<)) $(call output,$(@))
endef endef
define compile-asm-object define compile-asm-object
@ -848,6 +935,11 @@ endef
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends) $(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
$(compile-object) $(compile-object)
$(build)/%.o: $(lzma)/C/%.c
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cxx) $(cflags) $(no-error) -c $$($(windows-path) $(<)) $(call output,$(@))
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S $(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S
$(compile-asm-object) $(compile-asm-object)
@ -879,6 +971,16 @@ $(converter-objects) $(converter-tool-objects): $(build)/binaryToObject/%.o: $(s
$(converter): $(converter-objects) $(converter-tool-objects) $(converter): $(converter-objects) $(converter-tool-objects)
$(build-cc) $(^) -g -o $(@) $(build-cc) $(^) -g -o $(@)
$(lzma-encoder-objects): $(build)/lzma/%.o: $(src)/lzma/%.cpp
@mkdir -p $(dir $(@))
$(build-cxx) $(lzma-encoder-cflags) -c $(<) -o $(@)
$(lzma-encoder): $(lzma-encoder-objects) $(lzma-encoder-lzma-objects)
$(build-cc) $(^) -g -o $(@)
$(lzma-loader): $(src)/lzma/load.cpp
$(compile-object)
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep) $(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
@echo "creating $(@)" @echo "creating $(@)"
(wd=$$(pwd) && \ (wd=$$(pwd) && \
@ -901,18 +1003,28 @@ $(javahome-object): $(build)/javahome.jar $(converter)
$(converter) $(<) $(@) _binary_javahome_jar_start \ $(converter) $(<) $(@) _binary_javahome_jar_start \
_binary_javahome_jar_end $(platform) $(arch) _binary_javahome_jar_end $(platform) $(arch)
$(generator-objects): $(generator-depends) define compile-generator-object
$(generator-objects): $(build)/%-build.o: $(src)/%.cpp
@echo "compiling $(@)" @echo "compiling $(@)"
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
$(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \ $(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \
-c $(<) -o $(@) -c $(<) -o $(@)
endef
$(generator-objects): $(generator-depends)
$(generator-objects): $(build)/%-build.o: $(src)/%.cpp
$(compile-generator-object)
$(build)/%-build.o: $(lzma)/C/%.c
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \
$(no-error) -c $(<) -o $(@)
$(jni-objects): $(build)/%.o: $(classpath-src)/%.cpp $(jni-objects): $(build)/%.o: $(classpath-src)/%.cpp
$(compile-object) $(compile-object)
$(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
$(javahome-object) $(boot-javahome-object) $(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
@echo "creating $(@)" @echo "creating $(@)"
rm -rf $(@) rm -rf $(@)
$(ar) cru $(@) $(^) $(ar) cru $(@) $(^)
@ -925,7 +1037,7 @@ $(bootimage-object) $(codeimage-object): $(bootimage-generator)
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \ executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \ $(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
$(javahome-object) $(boot-javahome-object) $(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
$(executable): $(executable-objects) $(executable): $(executable-objects)
@echo "linking $(@)" @echo "linking $(@)"
@ -961,7 +1073,8 @@ $(bootimage-generator): $(bootimage-generator-objects)
$(build-bootimage-generator): \ $(build-bootimage-generator): \
$(vm-objects) $(classpath-object) $(classpath-objects) \ $(vm-objects) $(classpath-object) $(classpath-objects) \
$(heapwalk-objects) $(bootimage-generator-objects) $(converter-objects) $(heapwalk-objects) $(bootimage-generator-objects) $(converter-objects) \
$(lzma-decode-objects) $(lzma-encode-objects)
@echo "linking $(@)" @echo "linking $(@)"
ifeq ($(platform),windows) ifeq ($(platform),windows)
ifdef msvc ifdef msvc
@ -979,7 +1092,8 @@ endif
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \ $(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \ $(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
$(classpath-libraries) $(javahome-object) $(boot-javahome-object) $(classpath-libraries) $(javahome-object) $(boot-javahome-object) \
$(lzma-decode-objects)
@echo "linking $(@)" @echo "linking $(@)"
ifdef msvc ifdef msvc
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \ $(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
@ -1005,7 +1119,7 @@ else
endif endif
$(strip) $(strip-all) $(@) $(strip) $(strip-all) $(@)
$(generator): $(generator-objects) $(generator): $(generator-objects) $(generator-lzma-objects)
@echo "linking $(@)" @echo "linking $(@)"
$(build-ld) $(^) $(build-lflags) -o $(@) $(build-ld) $(^) $(build-lflags) -o $(@)

View File

@ -239,8 +239,7 @@ ifeq ($(platform),windows)
-Ds6_bytes=_s6_bytes -Ds6_bytes=_s6_bytes
else else
openjdk-sources += \ openjdk-sources += \
$(openjdk-src)/solaris/native/common/jdk_util_md.c \ $(shell find $(openjdk-src)/solaris/native/common -name '*.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/canonicalize_md.c \
$(openjdk-src)/solaris/native/java/io/Console_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/FileDescriptor_md.c \
@ -305,9 +304,6 @@ else
ifeq ($(platform),linux) ifeq ($(platform),linux)
openjdk-sources += \ openjdk-sources += \
$(openjdk-src)/solaris/native/java/net/linux_close.c \ $(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-src)/solaris/native/sun/nio/ch/EPollArrayWrapper.c
openjdk-headers-classes += \ openjdk-headers-classes += \
@ -316,6 +312,8 @@ else
openjdk-cflags += \ openjdk-cflags += \
"-I$(openjdk-src)/solaris/native/common/deps/glib2" \ "-I$(openjdk-src)/solaris/native/common/deps/glib2" \
"-I$(openjdk-src)/solaris/native/common/deps/gconf2" \ "-I$(openjdk-src)/solaris/native/common/deps/gconf2" \
"-I$(openjdk-src)/solaris/native/common/deps/fontconfig2" \
"-I$(openjdk-src)/solaris/native/common/deps/gtk2" \
$(shell pkg-config --cflags glib-2.0) \ $(shell pkg-config --cflags glib-2.0) \
$(shell pkg-config --cflags gconf-2.0) $(shell pkg-config --cflags gconf-2.0)
endif endif
@ -341,12 +339,13 @@ openjdk-local-sources += \
$(src)/openjdk/my_net_util.c \ $(src)/openjdk/my_net_util.c \
$(src)/openjdk/my_management.c $(src)/openjdk/my_management.c
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%-openjdk.o,$(x))) openjdk-c-objects = \
$(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%-openjdk.o,$(x)))
openjdk-objects = \ openjdk-objects = \
$(call c-objects,$(openjdk-sources),$(openjdk-src),$(build)/openjdk) $(call openjdk-c-objects,$(openjdk-sources),$(openjdk-src),$(build)/openjdk)
openjdk-local-objects = \ openjdk-local-objects = \
$(call c-objects,$(openjdk-local-sources),$(src)/openjdk,$(build)/openjdk) $(call openjdk-c-objects,$(openjdk-local-sources),$(src)/openjdk,$(build)/openjdk)
openjdk-headers-dep = $(build)/openjdk/headers.dep openjdk-headers-dep = $(build)/openjdk/headers.dep

View File

@ -63,6 +63,7 @@ Build requirements include:
* GNU make 3.80 or later * GNU make 3.80 or later
* GCC 3.4 or later (4.5.1 or later for Windows/x86_64) * GCC 3.4 or later (4.5.1 or later for Windows/x86_64)
or LLVM Clang 3.1 or later (see use-clang option below)
* JDK 1.5 or later * JDK 1.5 or later
* MinGW 3.4 or later (only if compiling for Windows) * MinGW 3.4 or later (only if compiling for Windows)
* zlib 1.2.3 or later * zlib 1.2.3 or later
@ -78,11 +79,13 @@ certain flags described below, all of which are optional.
arch={i386,x86_64,powerpc,arm} \ arch={i386,x86_64,powerpc,arm} \
process={compile,interpret} \ process={compile,interpret} \
mode={debug,debug-fast,fast,small} \ mode={debug,debug-fast,fast,small} \
lzma=<lzma source directory> \
ios={true,false} \ ios={true,false} \
bootimage={true,false} \ bootimage={true,false} \
heapdump={true,false} \ heapdump={true,false} \
tails={true,false} \ tails={true,false} \
continuations={true,false} \ continuations={true,false} \
use-clang={true,false} \
openjdk=<openjdk installation directory> \ openjdk=<openjdk installation directory> \
openjdk-src=<openjdk source directory> openjdk-src=<openjdk source directory>
@ -102,11 +105,18 @@ certain flags described below, all of which are optional.
assertions assertions
default: fast default: fast
* lzma - if set, support use of LZMA to compress embedded JARs and
boot images. The value of this option should be a directory
containing a recent LZMA SDK (available at
http://www.7-zip.org/sdk.html). Currently, only version 9.20 of
the SDK has been tested, but other versions might work.
default: not set
* ios - if true, cross-compile for iOS on OS X. Note that * ios - if true, cross-compile for iOS on OS X. Note that
non-jailbroken iOS devices do not allow JIT compilation, so only non-jailbroken iOS devices do not allow JIT compilation, so only
process=interpret or bootimage=true builds will run on such process=interpret or bootimage=true builds will run on such
devices. See git://oss.readytalk.com/hello-ios.git for an example devices. See https://github.com/ReadyTalk/hello-ios for an
of an Xcode project for iOS which uses Avian. example of an Xcode project for iOS which uses Avian.
default: false default: false
* bootimage - if true, create a boot image containing the pre-parsed * bootimage - if true, create a boot image containing the pre-parsed
@ -134,6 +144,11 @@ certain flags described below, all of which are optional.
only valid for process=compile builds. only valid for process=compile builds.
default: false default: false
* use-clang - if true, use LLVM's clang instead of GCC to build.
Note that this does not currently affect cross compiles, only
native builds.
default: false
* openjdk - if set, use OpenJDK class library instead of the default * openjdk - if set, use OpenJDK class library instead of the default
Avian class library. See "Building with the OpenJDK Class Avian class library. See "Building with the OpenJDK Class
Library" below for details. Library" below for details.
@ -359,8 +374,20 @@ EOF
Step 3: Make an object file out of the jar. Step 3: Make an object file out of the jar.
$ ../build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar boot-jar.o \ $ ../build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar \
_binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch} boot-jar.o _binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch}
If you've built Avian using the lzma option, you may optionally
compress the jar before generating the object:
$ ../build/$(platform}-${arch}-lzma/lzma/lzma encode boot.jar boot.jar.lzma
&& ../build/${platform}-${arch}-lzma/binaryToObject/binaryToObject \
boot.jar.lzma boot-jar.o _binary_boot_jar_start _binary_boot_jar_end \
${platform} ${arch}
Note that you'll need to specify "-Xbootclasspath:[lzma:bootJar]"
instead of "-Xbootclasspath:[bootJar]" in the next step if you've used
LZMA to compress the jar.
Step 4: Write a driver which starts the VM and runs the desired main Step 4: Write a driver which starts the VM and runs the desired main
method. Note the bootJar function, which will be called by the VM to method. Note the bootJar function, which will be called by the VM to

View File

@ -131,8 +131,9 @@ unsigned getElfPlatform(PlatformInfo::Architecture arch) {
return EM_ARM; return EM_ARM;
case PlatformInfo::PowerPC: case PlatformInfo::PowerPC:
return EM_PPC; return EM_PPC;
default:
return ~0;
} }
return ~0;
} }
const char* getSectionName(unsigned accessFlags, unsigned& sectionFlags) { const char* getSectionName(unsigned accessFlags, unsigned& sectionFlags) {
@ -255,8 +256,8 @@ public:
SectionWriter(FileWriter& file): SectionWriter(FileWriter& file):
file(file), file(file),
name(""), name(""),
data(0), dataSize(0),
dataSize(0) data(0)
{ {
memset(&header, 0, sizeof(SectionHeader)); memset(&header, 0, sizeof(SectionHeader));
file.sectionCount++; file.sectionCount++;
@ -279,8 +280,8 @@ public:
file(file), file(file),
name(chname), name(chname),
data(data), dataSize(dataSize),
dataSize(dataSize) data(data)
{ {
if(strcmp(chname, ".shstrtab") == 0) { if(strcmp(chname, ".shstrtab") == 0) {
file.sectionStringTableSectionNumber = file.sectionCount; file.sectionStringTableSectionNumber = file.sectionCount;
@ -359,11 +360,11 @@ public:
file.writeHeader(out); file.writeHeader(out);
for(int i = 0; i < file.sectionCount; i++) { for(unsigned i = 0; i < file.sectionCount; i++) {
sections[i].writeHeader(out); sections[i].writeHeader(out);
} }
for(int i = 0; i < file.sectionCount; i++) { for(unsigned i = 0; i < file.sectionCount; i++) {
sections[i].writeData(out); sections[i].writeData(out);
} }

View File

@ -183,14 +183,14 @@ public:
FileHeader header = { FileHeader header = {
V4(Magic), // magic V4(Magic), // magic
V4(cpuType), static_cast<cpu_type_t>(V4(cpuType)),
V4(cpuSubType), static_cast<cpu_subtype_t>(V4(cpuSubType)),
V4(MH_OBJECT), // filetype, V4(MH_OBJECT), // filetype,
V4(2), // ncmds V4(2), // ncmds
V4(sizeof(SegmentCommand) V4(sizeof(SegmentCommand)
+ sizeof(Section) + sizeof(Section)
+ sizeof(SymtabCommand)), // sizeofcmds + sizeof(SymtabCommand)), // sizeofcmds
V4(0) // flags { V4(0) } // flags
}; };
AddrTy finalSize = pad(data.count); AddrTy finalSize = pad(data.count);
@ -206,8 +206,8 @@ public:
+ sizeof(Section) + sizeof(Section)
+ sizeof(SymtabCommand))), // fileoff + sizeof(SymtabCommand))), // fileoff
VANY(static_cast<AddrTy>(finalSize)), // filesize VANY(static_cast<AddrTy>(finalSize)), // filesize
V4(7), // maxprot static_cast<vm_prot_t>(V4(7)), // maxprot
V4(7), // initprot static_cast<vm_prot_t>(V4(7)), // initprot
V4(1), // nsects V4(1), // nsects
V4(0) // flags V4(0) // flags
}; };
@ -243,7 +243,7 @@ public:
strings.write("_", 1); strings.write("_", 1);
strings.add(sym->name); strings.add(sym->name);
NList symbol = { NList symbol = {
V4(offset), // n_un { V4(offset) }, // n_un
V1(N_SECT | N_EXT), // n_type V1(N_SECT | N_EXT), // n_type
V1(1), // n_sect V1(1), // n_sect
V2(0), // n_desc V2(0), // n_desc
@ -281,6 +281,8 @@ public:
out->writeChunk(symbolList.data, symbolList.length); out->writeChunk(symbolList.data, symbolList.length);
out->writeChunk(strings.data, strings.length); out->writeChunk(strings.data, strings.length);
return true;
} }
MachOPlatform(PlatformInfo::Architecture arch): MachOPlatform(PlatformInfo::Architecture arch):

View File

@ -33,7 +33,7 @@ void* operator new(size_t size) {
return malloc(size); return malloc(size);
} }
void operator delete(void* mem) { abort(); } void operator delete(void*) { abort(); }
namespace { namespace {

View File

@ -129,11 +129,11 @@ public:
void addSymbol(String name, unsigned addr, unsigned sectionNumber, unsigned type, unsigned storageClass) { void addSymbol(String name, unsigned addr, unsigned sectionNumber, unsigned type, unsigned storageClass) {
unsigned nameOffset = strings.add(name); unsigned nameOffset = strings.add(name);
IMAGE_SYMBOL symbol = { IMAGE_SYMBOL symbol = {
{ 0 }, // Name { { 0, 0 } }, // Name
addr, // Value addr, // Value
sectionNumber, // SectionNumber static_cast<int16_t>(sectionNumber), // SectionNumber
type, // Type static_cast<uint16_t>(type), // Type
storageClass, // StorageClass static_cast<uint8_t>(storageClass), // StorageClass
0, // NumberOfAuxSymbols 0, // NumberOfAuxSymbols
}; };
symbol.N.Name.Long = nameOffset+4; symbol.N.Name.Long = nameOffset+4;
@ -165,9 +165,9 @@ public:
size_t dataSize): size_t dataSize):
file(file), file(file),
data(data),
dataSize(dataSize), dataSize(dataSize),
finalSize(pad(dataSize)) finalSize(pad(dataSize)),
data(data)
{ {
file.sectionCount++; file.sectionCount++;
file.dataStart += sizeof(IMAGE_SECTION_HEADER); file.dataStart += sizeof(IMAGE_SECTION_HEADER);

View File

@ -5,6 +5,8 @@
FIELD(magic) FIELD(magic)
FIELD(initialized)
FIELD(heapSize) FIELD(heapSize)
FIELD(codeSize) FIELD(codeSize)

View File

@ -17,6 +17,7 @@
#include "assembler.h" #include "assembler.h"
#include "target.h" #include "target.h"
#include "binaryToObject/tools.h" #include "binaryToObject/tools.h"
#include "lzma.h"
// since we aren't linking against libstdc++, we must implement this // since we aren't linking against libstdc++, we must implement this
// ourselves: // ourselves:
@ -62,14 +63,6 @@ enum Type {
class Field { class Field {
public: public:
Field() { }
Field(Type type, unsigned buildOffset, unsigned buildSize,
unsigned targetOffset, unsigned targetSize):
type(type), buildOffset(buildOffset), buildSize(buildSize),
targetOffset(targetOffset), targetSize(targetSize)
{ }
Type type; Type type;
unsigned buildOffset; unsigned buildOffset;
unsigned buildSize; unsigned buildSize;
@ -77,6 +70,17 @@ class Field {
unsigned targetSize; unsigned targetSize;
}; };
void
init(Field* f, Type type, unsigned buildOffset, unsigned buildSize,
unsigned targetOffset, unsigned targetSize)
{
f->type = type;
f->buildOffset = buildOffset;
f->buildSize = buildSize;
f->targetOffset = targetOffset;
f->targetSize = targetSize;
}
class TypeMap { class TypeMap {
public: public:
enum Kind { enum Kind {
@ -397,9 +401,9 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
map->targetFixedOffsets()[i * BytesPerWord] map->targetFixedOffsets()[i * BytesPerWord]
= i * TargetBytesPerWord; = i * TargetBytesPerWord;
new (map->fixedFields() + i) Field init(new (map->fixedFields() + i) Field, types[i],
(types[i], i * BytesPerWord, BytesPerWord, i * BytesPerWord, BytesPerWord, i * TargetBytesPerWord,
i * TargetBytesPerWord, TargetBytesPerWord); TargetBytesPerWord);
} }
hashMapInsert hashMapInsert
@ -446,8 +450,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
++ memberIndex; ++ memberIndex;
} }
} else { } else {
new (memberFields) Field init(new (memberFields) Field, Type_object, 0, BytesPerWord, 0,
(Type_object, 0, BytesPerWord, 0, TargetBytesPerWord); TargetBytesPerWord);
memberIndex = 1; memberIndex = 1;
buildMemberOffset = BytesPerWord; buildMemberOffset = BytesPerWord;
@ -456,12 +460,11 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
Field staticFields[count + 2]; Field staticFields[count + 2];
new (staticFields) Field init(new (staticFields) Field, Type_object, 0, BytesPerWord, 0,
(Type_object, 0, BytesPerWord, 0, TargetBytesPerWord); TargetBytesPerWord);
new (staticFields + 1) Field init(new (staticFields + 1) Field, Type_intptr_t, BytesPerWord,
(Type_intptr_t, BytesPerWord, BytesPerWord, TargetBytesPerWord, BytesPerWord, TargetBytesPerWord, TargetBytesPerWord);
TargetBytesPerWord);
unsigned staticIndex = 2; unsigned staticIndex = 2;
unsigned buildStaticOffset = BytesPerWord * 2; unsigned buildStaticOffset = BytesPerWord * 2;
@ -510,9 +513,9 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
buildStaticOffset = fieldOffset(t, field); buildStaticOffset = fieldOffset(t, field);
new (staticFields + staticIndex) Field init(new (staticFields + staticIndex) Field, type,
(type, buildStaticOffset, buildSize, targetStaticOffset, buildStaticOffset, buildSize, targetStaticOffset,
targetSize); targetSize);
targetStaticOffset += targetSize; targetStaticOffset += targetSize;
@ -524,9 +527,9 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
buildMemberOffset = fieldOffset(t, field); buildMemberOffset = fieldOffset(t, field);
new (memberFields + memberIndex) Field init(new (memberFields + memberIndex) Field, type,
(type, buildMemberOffset, buildSize, targetMemberOffset, buildMemberOffset, buildSize, targetMemberOffset,
targetSize); targetSize);
targetMemberOffset += targetSize; targetMemberOffset += targetSize;
@ -693,12 +696,6 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
return constants; return constants;
} }
unsigned
objectSize(Thread* t, object o)
{
return baseSize(t, o, objectClass(t, o));
}
void void
visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants) visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants)
{ {
@ -1267,12 +1264,6 @@ updateConstants(Thread* t, object constants, HeapMap* heapTable)
} }
} }
unsigned
offset(object a, uintptr_t* b)
{
return reinterpret_cast<uintptr_t>(b) - reinterpret_cast<uintptr_t>(a);
}
BootImage::Thunk BootImage::Thunk
targetThunk(BootImage::Thunk t) targetThunk(BootImage::Thunk t)
{ {
@ -1285,7 +1276,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
BootImage* image, uint8_t* code, const char* className, BootImage* image, uint8_t* code, const char* className,
const char* methodName, const char* methodSpec, const char* methodName, const char* methodSpec,
const char* bootimageStart, const char* bootimageEnd, const char* bootimageStart, const char* bootimageEnd,
const char* codeimageStart, const char* codeimageEnd) const char* codeimageStart, const char* codeimageEnd,
bool useLZMA)
{ {
setRoot(t, Machine::OutOfMemoryError, setRoot(t, Machine::OutOfMemoryError,
make(t, type(t, Machine::OutOfMemoryErrorType))); make(t, type(t, Machine::OutOfMemoryErrorType)));
@ -1347,7 +1339,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
Field fields[count]; Field fields[count];
new (fields) Field(Type_object, 0, BytesPerWord, 0, TargetBytesPerWord); init(new (fields) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord);
unsigned buildOffset = BytesPerWord; unsigned buildOffset = BytesPerWord;
unsigned targetOffset = TargetBytesPerWord; unsigned targetOffset = TargetBytesPerWord;
@ -1424,8 +1417,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
++ targetOffset; ++ targetOffset;
} }
new (fields + j) Field init(new (fields + j) Field, type, buildOffset, buildSize,
(type, buildOffset, buildSize, targetOffset, targetSize); targetOffset, targetSize);
buildOffset += buildSize; buildOffset += buildSize;
targetOffset += targetSize; targetOffset += targetSize;
@ -1603,6 +1596,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
heapWalker->dispose(); heapWalker->dispose();
image->magic = BootImage::Magic; image->magic = BootImage::Magic;
image->initialized = 0;
fprintf(stderr, "class count %d string count %d call count %d\n" fprintf(stderr, "class count %d string count %d call count %d\n"
"heap size %d code size %d\n", "heap size %d code size %d\n",
@ -1665,7 +1659,27 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
SymbolInfo(bootimageData.length, bootimageEnd) SymbolInfo(bootimageData.length, bootimageEnd)
}; };
platform->writeObject(bootimageOutput, Slice<SymbolInfo>(bootimageSymbols, 2), Slice<const uint8_t>(bootimageData.data, bootimageData.length), Platform::Writable, TargetBytesPerWord); uint8_t* bootimage;
unsigned bootimageLength;
if (useLZMA) {
#ifdef AVIAN_USE_LZMA
bootimage = encodeLZMA(t->m->system, t->m->heap, bootimageData.data,
bootimageData.length, &bootimageLength);
fprintf(stderr, "compressed heap size %d\n", bootimageLength);
#else
abort(t);
#endif
} else {
bootimage = bootimageData.data;
bootimageLength = bootimageData.length;
}
platform->writeObject(bootimageOutput, Slice<SymbolInfo>(bootimageSymbols, 2), Slice<const uint8_t>(bootimage, bootimageLength), Platform::Writable, TargetBytesPerWord);
if (useLZMA) {
t->m->heap->free(bootimage, bootimageLength);
}
compilationHandler.symbols.add(SymbolInfo(0, codeimageStart)); compilationHandler.symbols.add(SymbolInfo(0, codeimageStart));
compilationHandler.symbols.add(SymbolInfo(image->codeSize, codeimageEnd)); compilationHandler.symbols.add(SymbolInfo(image->codeSize, codeimageEnd));
@ -1693,10 +1707,12 @@ writeBootImage(Thread* t, uintptr_t* arguments)
const char* bootimageEnd = reinterpret_cast<const char*>(arguments[8]); const char* bootimageEnd = reinterpret_cast<const char*>(arguments[8]);
const char* codeimageStart = reinterpret_cast<const char*>(arguments[9]); const char* codeimageStart = reinterpret_cast<const char*>(arguments[9]);
const char* codeimageEnd = reinterpret_cast<const char*>(arguments[10]); const char* codeimageEnd = reinterpret_cast<const char*>(arguments[10]);
bool useLZMA = arguments[11];
writeBootImage2 writeBootImage2
(t, bootimageOutput, codeOutput, image, code, className, methodName, (t, bootimageOutput, codeOutput, image, code, className, methodName,
methodSpec, bootimageStart, bootimageEnd, codeimageStart, codeimageEnd); methodSpec, bootimageStart, bootimageEnd, codeimageStart, codeimageEnd,
useLZMA);
return 1; return 1;
} }
@ -1753,12 +1769,18 @@ bool ArgParser::parse(int ac, const char** av) {
fprintf(stderr, "expected -parameter\n"); fprintf(stderr, "expected -parameter\n");
return false; return false;
} }
bool found = false;
for(Arg* arg = first; arg; arg = arg->next) { for(Arg* arg = first; arg; arg = arg->next) {
if(strcmp(arg->name, &av[i][1]) == 0) { if(strcmp(arg->name, &av[i][1]) == 0) {
state = arg; found = true;
if (arg->desc == 0) {
arg->value = "true";
} else {
state = arg;
}
} }
} }
if(!state) { if (not found) {
fprintf(stderr, "unrecognized parameter %s\n", av[i]); fprintf(stderr, "unrecognized parameter %s\n", av[i]);
return false; return false;
} }
@ -1786,8 +1808,10 @@ void ArgParser::printUsage(const char* exe) {
const char* lineEnd = arg->next ? " \\" : ""; const char* lineEnd = arg->next ? " \\" : "";
if(arg->required) { if(arg->required) {
fprintf(stderr, " -%s\t%s%s\n", arg->name, arg->desc, lineEnd); fprintf(stderr, " -%s\t%s%s\n", arg->name, arg->desc, lineEnd);
} else { } else if (arg->desc) {
fprintf(stderr, " [-%s\t%s]%s\n", arg->name, arg->desc, lineEnd); fprintf(stderr, " [-%s\t%s]%s\n", arg->name, arg->desc, lineEnd);
} else {
fprintf(stderr, " [-%s]%s\n", arg->name, lineEnd);
} }
} }
} }
@ -1810,6 +1834,8 @@ public:
char* codeimageStart; char* codeimageStart;
char* codeimageEnd; char* codeimageEnd;
bool useLZMA;
bool maybeSplit(const char* src, char*& destA, char*& destB) { bool maybeSplit(const char* src, char*& destA, char*& destB) {
if(src) { if(src) {
const char* split = strchr(src, ':'); const char* split = strchr(src, ':');
@ -1839,6 +1865,7 @@ public:
Arg entry(parser, false, "entry", "<class name>[.<method name>[<method spec>]]"); Arg entry(parser, false, "entry", "<class name>[.<method name>[<method spec>]]");
Arg bootimageSymbols(parser, false, "bootimage-symbols", "<start symbol name>:<end symbol name>"); Arg bootimageSymbols(parser, false, "bootimage-symbols", "<start symbol name>:<end symbol name>");
Arg codeimageSymbols(parser, false, "codeimage-symbols", "<start symbol name>:<end symbol name>"); Arg codeimageSymbols(parser, false, "codeimage-symbols", "<start symbol name>:<end symbol name>");
Arg useLZMA(parser, false, "use-lzma", 0);
if(!parser.parse(ac, av)) { if(!parser.parse(ac, av)) {
parser.printUsage(av[0]); parser.printUsage(av[0]);
@ -1848,6 +1875,7 @@ public:
this->classpath = classpath.value; this->classpath = classpath.value;
this->bootimage = bootimage.value; this->bootimage = bootimage.value;
this->codeimage = codeimage.value; this->codeimage = codeimage.value;
this->useLZMA = useLZMA.value != 0;
if(entry.value) { if(entry.value) {
if(const char* entryClassEnd = strchr(entry.value, '.')) { if(const char* entryClassEnd = strchr(entry.value, '.')) {
@ -1997,7 +2025,8 @@ main(int ac, const char** av)
reinterpret_cast<uintptr_t>(args.bootimageStart), reinterpret_cast<uintptr_t>(args.bootimageStart),
reinterpret_cast<uintptr_t>(args.bootimageEnd), reinterpret_cast<uintptr_t>(args.bootimageEnd),
reinterpret_cast<uintptr_t>(args.codeimageStart), reinterpret_cast<uintptr_t>(args.codeimageStart),
reinterpret_cast<uintptr_t>(args.codeimageEnd) reinterpret_cast<uintptr_t>(args.codeimageEnd),
static_cast<uintptr_t>(args.useLZMA)
}; };
run(t, writeBootImage, arguments); run(t, writeBootImage, arguments);

View File

@ -562,6 +562,14 @@ class MyClasspath : public Classpath {
expect(t, loadLibrary(t, libraryPath, "java", true, true)); expect(t, loadLibrary(t, libraryPath, "java", true, true));
#endif // not AVIAN_OPENJDK_SRC #endif // not AVIAN_OPENJDK_SRC
{ object assertionLock = resolveField
(t, type(t, Machine::ClassLoaderType), "assertionLock",
"Ljava/lang/Object;");
set(t, root(t, Machine::BootLoader), fieldOffset(t, assertionLock),
root(t, Machine::BootLoader));
}
{ object class_ = resolveClass { object class_ = resolveClass
(t, root(t, Machine::BootLoader), "java/util/Properties", true, (t, root(t, Machine::BootLoader), "java/util/Properties", true,
Machine::NoClassDefFoundErrorType); Machine::NoClassDefFoundErrorType);
@ -594,14 +602,6 @@ class MyClasspath : public Classpath {
root(t, Machine::BootLoader)); root(t, Machine::BootLoader));
} }
{ object assertionLock = resolveField
(t, type(t, Machine::ClassLoaderType), "assertionLock",
"Ljava/lang/Object;");
set(t, root(t, Machine::BootLoader), fieldOffset(t, assertionLock),
root(t, Machine::BootLoader));
}
{ object scl = resolveField { object scl = resolveField
(t, type(t, Machine::ClassLoaderType), "scl", (t, type(t, Machine::ClassLoaderType), "scl",
"Ljava/lang/ClassLoader;"); "Ljava/lang/ClassLoader;");

View File

@ -288,14 +288,6 @@ transition(MyThread* t, void* ip, void* stack, object continuation,
MyThread::doTransition(t, ip, stack, continuation, trace); MyThread::doTransition(t, ip, stack, continuation, trace);
} }
unsigned
parameterOffset(MyThread* t, object method)
{
return methodParameterFootprint(t, method)
+ t->arch->frameFooterSize()
+ t->arch->frameReturnAddressSize() - 1;
}
object object
resolveThisPointer(MyThread* t, void* stack) resolveThisPointer(MyThread* t, void* stack)
{ {
@ -9639,9 +9631,7 @@ boot(MyThread* t, BootImage* image, uint8_t* code)
// fprintf(stderr, "code from %p to %p\n", // fprintf(stderr, "code from %p to %p\n",
// code, code + image->codeSize); // code, code + image->codeSize);
static bool fixed = false; if (not image->initialized) {
if (not fixed) {
fixupHeap(t, heapMap, heapMapSizeInWords, heap); fixupHeap(t, heapMap, heapMapSizeInWords, heap);
} }
@ -9688,7 +9678,7 @@ boot(MyThread* t, BootImage* image, uint8_t* code)
findThunks(t, image, code); findThunks(t, image, code);
if (fixed) { if (image->initialized) {
resetRuntimeState resetRuntimeState
(t, classLoaderMap(t, root(t, Machine::BootLoader)), heap, (t, classLoaderMap(t, root(t, Machine::BootLoader)), heap,
image->heapSize); image->heapSize);
@ -9711,7 +9701,7 @@ boot(MyThread* t, BootImage* image, uint8_t* code)
(t, classLoaderMap(t, root(t, Machine::AppLoader)), image, code); (t, classLoaderMap(t, root(t, Machine::AppLoader)), image, code);
} }
fixed = true; image->initialized = true;
setRoot(t, Machine::BootstrapClassMap, makeHashMap(t, 0, 0)); setRoot(t, Machine::BootstrapClassMap, makeHashMap(t, 0, 0));
} }
@ -10032,7 +10022,7 @@ compileVirtualThunk(MyThread* t, unsigned index, unsigned* size)
sprintf(RUNTIME_ARRAY_BODY(virtualThunkName), "%s%d", virtualThunkBaseName, index); sprintf(RUNTIME_ARRAY_BODY(virtualThunkName), "%s%d", virtualThunkBaseName, index);
logCompile(t, start, *size, 0, virtualThunkName, 0); logCompile(t, start, *size, 0, RUNTIME_ARRAY_BODY(virtualThunkName), 0);
return reinterpret_cast<uintptr_t>(start); return reinterpret_cast<uintptr_t>(start);
} }

View File

@ -579,27 +579,6 @@ cons(Context* c, void* value, Cell* next)
return new (c->zone) Cell(next, value); return new (c->zone) Cell(next, value);
} }
Cell*
append(Context* c, Cell* first, Cell* second)
{
if (first) {
if (second) {
Cell* start = cons(c, first->value, second);
Cell* end = start;
for (Cell* cell = first->next; cell; cell = cell->next) {
Cell* n = cons(c, cell->value, second);
end->next = n;
end = n;
}
return start;
} else {
return first;
}
} else {
return second;
}
}
Cell* Cell*
reverseDestroy(Cell* cell) reverseDestroy(Cell* cell)
{ {
@ -992,6 +971,8 @@ valid(Read* r)
return r and r->valid(); return r and r->valid();
} }
#ifndef NDEBUG
bool bool
hasBuddy(Context* c, Value* a, Value* b) hasBuddy(Context* c, Value* a, Value* b)
{ {
@ -1011,6 +992,8 @@ hasBuddy(Context* c, Value* a, Value* b)
return false; return false;
} }
#endif // not NDEBUG
Read* Read*
live(Context* c UNUSED, Value* v) live(Context* c UNUSED, Value* v)
{ {
@ -1618,7 +1601,7 @@ class ConstantSite: public Site {
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
if (value->resolved()) { if (value->resolved()) {
return vm::snprintf return vm::snprintf
(buffer, bufferSize, "constant %"LLD, value->value()); (buffer, bufferSize, "constant %" LLD, value->value());
} else { } else {
return vm::snprintf(buffer, bufferSize, "constant unresolved"); return vm::snprintf(buffer, bufferSize, "constant unresolved");
} }
@ -1709,7 +1692,7 @@ class AddressSite: public Site {
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
if (address->resolved()) { if (address->resolved()) {
return vm::snprintf return vm::snprintf
(buffer, bufferSize, "address %"LLD, address->value()); (buffer, bufferSize, "address %" LLD, address->value());
} else { } else {
return vm::snprintf(buffer, bufferSize, "address unresolved"); return vm::snprintf(buffer, bufferSize, "address unresolved");
} }
@ -5302,16 +5285,17 @@ propagateJunctionSites(Context* c, Event* e)
class SiteRecord { class SiteRecord {
public: public:
SiteRecord(Site* site, Value* value):
site(site), value(value)
{ }
SiteRecord() { }
Site* site; Site* site;
Value* value; Value* value;
}; };
void
init(SiteRecord* r, Site* s, Value* v)
{
r->site = s;
r->value = v;
}
class SiteRecordList { class SiteRecordList {
public: public:
SiteRecordList(SiteRecord* records, unsigned capacity): SiteRecordList(SiteRecord* records, unsigned capacity):
@ -5329,7 +5313,7 @@ freeze(Context* c, SiteRecordList* frozen, Site* s, Value* v)
assert(c, frozen->index < frozen->capacity); assert(c, frozen->index < frozen->capacity);
s->freeze(c, v); s->freeze(c, v);
new (frozen->records + (frozen->index ++)) SiteRecord(s, v); init(new (frozen->records + (frozen->index ++)) SiteRecord, s, v);
} }
void void
@ -5866,17 +5850,6 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
c->firstBlock = firstBlock; c->firstBlock = firstBlock;
} }
unsigned
count(Stack* s)
{
unsigned c = 0;
while (s) {
++ c;
s = s->next;
}
return c;
}
void void
restore(Context* c, ForkState* state) restore(Context* c, ForkState* state)
{ {

View File

@ -12,6 +12,7 @@
#include "system.h" #include "system.h"
#include "tokenizer.h" #include "tokenizer.h"
#include "finder.h" #include "finder.h"
#include "lzma.h"
using namespace vm; using namespace vm;
@ -173,11 +174,12 @@ class DirectoryElement: public Element {
class PointerRegion: public System::Region { class PointerRegion: public System::Region {
public: public:
PointerRegion(System* s, Allocator* allocator, const uint8_t* start, PointerRegion(System* s, Allocator* allocator, const uint8_t* start,
size_t length): size_t length, bool freePointer = false):
s(s), s(s),
allocator(allocator), allocator(allocator),
start_(start), start_(start),
length_(length) length_(length),
freePointer(freePointer)
{ } { }
virtual const uint8_t* start() { virtual const uint8_t* start() {
@ -189,6 +191,9 @@ class PointerRegion: public System::Region {
} }
virtual void dispose() { virtual void dispose() {
if (freePointer) {
allocator->free(start_, length_);
}
allocator->free(this, sizeof(*this)); allocator->free(this, sizeof(*this));
} }
@ -196,6 +201,7 @@ class PointerRegion: public System::Region {
Allocator* allocator; Allocator* allocator;
const uint8_t* start_; const uint8_t* start_;
size_t length_; size_t length_;
bool freePointer;
}; };
class DataRegion: public System::Region { class DataRegion: public System::Region {
@ -556,7 +562,10 @@ class BuiltinElement: public JarElement {
virtual void init() { virtual void init() {
if (index == 0) { if (index == 0) {
if (s->success(s->load(&library, libraryName))) { if (s->success(s->load(&library, libraryName))) {
void* p = library->resolve(name); bool lzma = strncmp("lzma:", name, 5) == 0;
const char* symbolName = lzma ? name + 5 : name;
void* p = library->resolve(symbolName);
if (p) { if (p) {
uint8_t* (*function)(unsigned*); uint8_t* (*function)(unsigned*);
memcpy(&function, &p, BytesPerWord); memcpy(&function, &p, BytesPerWord);
@ -564,10 +573,29 @@ class BuiltinElement: public JarElement {
unsigned size; unsigned size;
uint8_t* data = function(&size); uint8_t* data = function(&size);
if (data) { if (data) {
bool freePointer;
if (lzma) {
#ifdef AVIAN_USE_LZMA
unsigned outSize;
data = decodeLZMA(s, allocator, data, size, &outSize);
size = outSize;
freePointer = true;
#else
abort(s);
#endif
} else {
freePointer = false;
}
region = new (allocator->allocate(sizeof(PointerRegion))) region = new (allocator->allocate(sizeof(PointerRegion)))
PointerRegion(s, allocator, data, size); PointerRegion(s, allocator, data, size, freePointer);
index = JarIndex::open(s, allocator, region); index = JarIndex::open(s, allocator, region);
} else if (DebugFind) {
fprintf(stderr, "%s in %s returned null\n", symbolName,
libraryName);
} }
} else if (DebugFind) {
fprintf(stderr, "unable to find %s in %s\n", symbolName,
libraryName);
} }
} }
} }

View File

@ -60,7 +60,6 @@ void NO_RETURN abort(Context*);
void assert(Context*, bool); void assert(Context*, bool);
#endif #endif
System* system(Context*);
void* tryAllocate(Context* c, unsigned size); void* tryAllocate(Context* c, unsigned size);
void* allocate(Context* c, unsigned size); void* allocate(Context* c, unsigned size);
void free(Context* c, const void* p, unsigned size); void free(Context* c, const void* p, unsigned size);
@ -689,12 +688,6 @@ class Context {
int64_t totalTime; int64_t totalTime;
}; };
inline System*
system(Context* c)
{
return c->system;
}
const char* const char*
segment(Context* c, void* p) segment(Context* c, void* p)
{ {

View File

@ -231,16 +231,6 @@ get(object o, unsigned offsetInWords)
(mask(cast<void*>(o, offsetInWords * BytesPerWord))); (mask(cast<void*>(o, offsetInWords * BytesPerWord)));
} }
unsigned
objectSize(Thread* t, object o)
{
unsigned n = baseSize(t, o, objectClass(t, o));
if (objectExtended(t, o)) {
++ n;
}
return n;
}
unsigned unsigned
walk(Context* c, HeapVisitor* v, object p) walk(Context* c, HeapVisitor* v, object p)
{ {

View File

@ -252,7 +252,8 @@ NewString(Thread* t, const jchar* chars, jsize size)
{ {
if (chars == 0) return 0; if (chars == 0) return 0;
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(chars), size }; uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(chars),
static_cast<uintptr_t>(size) };
return reinterpret_cast<jstring>(run(t, newString, arguments)); return reinterpret_cast<jstring>(run(t, newString, arguments));
} }
@ -311,7 +312,7 @@ DefineClass(Thread* t, const char*, jobject loader, const jbyte* buffer,
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(loader), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(loader),
reinterpret_cast<uintptr_t>(buffer), reinterpret_cast<uintptr_t>(buffer),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jclass>(run(t, defineClass, arguments)); return reinterpret_cast<jclass>(run(t, defineClass, arguments));
} }
@ -1495,7 +1496,7 @@ SetByteField(Thread* t, jobject o, jfieldID field, jbyte v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
field, field,
v }; static_cast<uintptr_t>(v) };
run(t, setByteField, arguments); run(t, setByteField, arguments);
} }
@ -1545,7 +1546,7 @@ SetShortField(Thread* t, jobject o, jfieldID field, jshort v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
field, field,
v }; static_cast<uintptr_t>(v) };
run(t, setShortField, arguments); run(t, setShortField, arguments);
} }
@ -1570,7 +1571,7 @@ SetIntField(Thread* t, jobject o, jfieldID field, jint v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(o),
field, field,
v }; static_cast<uintptr_t>(v) };
run(t, setIntField, arguments); run(t, setIntField, arguments);
} }
@ -1975,7 +1976,7 @@ SetStaticByteField(Thread* t, jobject c, jfieldID field, jbyte v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
v }; static_cast<uintptr_t>(v) };
run(t, setStaticByteField, arguments); run(t, setStaticByteField, arguments);
} }
@ -2033,7 +2034,7 @@ SetStaticShortField(Thread* t, jobject c, jfieldID field, jshort v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
v }; static_cast<uintptr_t>(v) };
run(t, setStaticShortField, arguments); run(t, setStaticShortField, arguments);
} }
@ -2062,7 +2063,7 @@ SetStaticIntField(Thread* t, jobject c, jfieldID field, jint v)
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
field, field,
v }; static_cast<uintptr_t>(v) };
run(t, setStaticIntField, arguments); run(t, setStaticIntField, arguments);
} }
@ -2261,7 +2262,7 @@ newObjectArray(Thread* t, uintptr_t* arguments)
jobjectArray JNICALL jobjectArray JNICALL
NewObjectArray(Thread* t, jsize length, jclass class_, jobject init) NewObjectArray(Thread* t, jsize length, jclass class_, jobject init)
{ {
uintptr_t arguments[] = { length, uintptr_t arguments[] = { static_cast<uintptr_t>(length),
reinterpret_cast<uintptr_t>(class_), reinterpret_cast<uintptr_t>(class_),
reinterpret_cast<uintptr_t>(init) }; reinterpret_cast<uintptr_t>(init) };
@ -2302,7 +2303,7 @@ NewBooleanArray(Thread* t, jsize length)
{ {
uintptr_t arguments[] uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeBooleanArray)), = { reinterpret_cast<uintptr_t>(voidPointer(makeBooleanArray)),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jbooleanArray>(run(t, newArray, arguments)); return reinterpret_cast<jbooleanArray>(run(t, newArray, arguments));
} }
@ -2318,7 +2319,7 @@ NewByteArray(Thread* t, jsize length)
{ {
uintptr_t arguments[] uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeByteArray0)), = { reinterpret_cast<uintptr_t>(voidPointer(makeByteArray0)),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jbyteArray>(run(t, newArray, arguments)); return reinterpret_cast<jbyteArray>(run(t, newArray, arguments));
} }
@ -2328,7 +2329,7 @@ NewCharArray(Thread* t, jsize length)
{ {
uintptr_t arguments[] uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeCharArray)), = { reinterpret_cast<uintptr_t>(voidPointer(makeCharArray)),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jcharArray>(run(t, newArray, arguments)); return reinterpret_cast<jcharArray>(run(t, newArray, arguments));
} }
@ -2338,7 +2339,7 @@ NewShortArray(Thread* t, jsize length)
{ {
uintptr_t arguments[] uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeShortArray)), = { reinterpret_cast<uintptr_t>(voidPointer(makeShortArray)),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jshortArray>(run(t, newArray, arguments)); return reinterpret_cast<jshortArray>(run(t, newArray, arguments));
} }
@ -2348,7 +2349,7 @@ NewIntArray(Thread* t, jsize length)
{ {
uintptr_t arguments[] uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeIntArray)), = { reinterpret_cast<uintptr_t>(voidPointer(makeIntArray)),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jintArray>(run(t, newArray, arguments)); return reinterpret_cast<jintArray>(run(t, newArray, arguments));
} }
@ -2358,7 +2359,7 @@ NewLongArray(Thread* t, jsize length)
{ {
uintptr_t arguments[] uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeLongArray)), = { reinterpret_cast<uintptr_t>(voidPointer(makeLongArray)),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jlongArray>(run(t, newArray, arguments)); return reinterpret_cast<jlongArray>(run(t, newArray, arguments));
} }
@ -2368,7 +2369,7 @@ NewFloatArray(Thread* t, jsize length)
{ {
uintptr_t arguments[] uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeFloatArray)), = { reinterpret_cast<uintptr_t>(voidPointer(makeFloatArray)),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jfloatArray>(run(t, newArray, arguments)); return reinterpret_cast<jfloatArray>(run(t, newArray, arguments));
} }
@ -2378,7 +2379,7 @@ NewDoubleArray(Thread* t, jsize length)
{ {
uintptr_t arguments[] uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeDoubleArray)), = { reinterpret_cast<uintptr_t>(voidPointer(makeDoubleArray)),
length }; static_cast<uintptr_t>(length) };
return reinterpret_cast<jdoubleArray>(run(t, newArray, arguments)); return reinterpret_cast<jdoubleArray>(run(t, newArray, arguments));
} }
@ -2905,7 +2906,7 @@ RegisterNatives(Thread* t, jclass c, const JNINativeMethod* methods,
{ {
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c), uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c),
reinterpret_cast<uintptr_t>(methods), reinterpret_cast<uintptr_t>(methods),
methodCount }; static_cast<uintptr_t>(methodCount) };
return run(t, registerNatives, arguments) ? 0 : -1; return run(t, registerNatives, arguments) ? 0 : -1;
} }

61
src/lzma-decode.cpp Normal file
View File

@ -0,0 +1,61 @@
/* 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. */
#include "lzma-util.h"
#include "C/LzmaDec.h"
using namespace vm;
namespace {
int32_t
read4(const uint8_t* in)
{
return (static_cast<int32_t>(in[3]) << 24)
| (static_cast<int32_t>(in[2]) << 16)
| (static_cast<int32_t>(in[1]) << 8)
| (static_cast<int32_t>(in[0]) );
}
} // namespace
namespace vm {
uint8_t*
decodeLZMA(System* s, Allocator* a, uint8_t* in, unsigned inSize,
unsigned* outSize)
{
const unsigned PropHeaderSize = 5;
const unsigned HeaderSize = 13;
int32_t outSize32 = read4(in + PropHeaderSize);
expect(s, outSize32 >= 0);
SizeT outSizeT = outSize32;
uint8_t* out = static_cast<uint8_t*>(a->allocate(outSize32));
SizeT inSizeT = inSize;
LzmaAllocator allocator(a);
ELzmaStatus status;
int result = LzmaDecode
(out, &outSizeT, in + HeaderSize, &inSizeT, in, PropHeaderSize,
LZMA_FINISH_END, &status, &(allocator.allocator));
expect(s, result == SZ_OK);
expect(s, status == LZMA_STATUS_FINISHED_WITH_MARK);
*outSize = outSize32;
return out;
}
} // namespace vm

71
src/lzma-encode.cpp Normal file
View File

@ -0,0 +1,71 @@
/* 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. */
#include "lzma-util.h"
#include "C/LzmaEnc.h"
using namespace vm;
namespace {
SRes
myProgress(void*, UInt64, UInt64)
{
return SZ_OK;
}
} // namespace
namespace vm {
uint8_t*
encodeLZMA(System* s, Allocator* a, uint8_t* in, unsigned inSize,
unsigned* outSize)
{
const unsigned PropHeaderSize = 5;
const unsigned HeaderSize = 13;
unsigned bufferSize = inSize * 2;
uint8_t* buffer = static_cast<uint8_t*>(a->allocate(bufferSize));
LzmaAllocator allocator(a);
CLzmaEncProps props;
LzmaEncProps_Init(&props);
props.level = 9;
props.writeEndMark = 1;
ICompressProgress progress = { myProgress };
SizeT propsSize = PropHeaderSize;
int32_t inSize32 = inSize;
memcpy(buffer + PropHeaderSize, &inSize32, 4);
SizeT outSizeT = bufferSize;
int result = LzmaEncode
(buffer + HeaderSize, &outSizeT, in, inSize, &props, buffer,
&propsSize, 1, &progress, &(allocator.allocator), &(allocator.allocator));
expect(s, result == SZ_OK);
*outSize = outSizeT + HeaderSize;
uint8_t* out = static_cast<uint8_t*>(a->allocate(*outSize));
memcpy(out, buffer, *outSize);
a->free(buffer, bufferSize);
return out;
}
} // namespace vm

53
src/lzma-util.h Normal file
View File

@ -0,0 +1,53 @@
/* 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. */
#ifndef LZMA_UTIL_H
#define LZMA_UTIL_H
#include "lzma.h"
#include "C/Types.h"
#include "system.h"
#include "allocator.h"
namespace vm {
const unsigned Padding = 16;
class LzmaAllocator {
public:
LzmaAllocator(Allocator* a): a(a) {
allocator.Alloc = allocate;
allocator.Free = free;
}
ISzAlloc allocator;
Allocator* a;
static void* allocate(void* allocator, size_t size) {
uint8_t* p = static_cast<uint8_t*>
(static_cast<LzmaAllocator*>(allocator)->a->allocate(size + Padding));
int32_t size32 = size;
memcpy(p, &size32, 4);
return p + Padding;
}
static void free(void* allocator, void* address) {
if (address) {
void* p = static_cast<uint8_t*>(address) - Padding;
int32_t size32;
memcpy(&size32, p, 4);
static_cast<LzmaAllocator*>(allocator)->a->free(p, size32 + Padding);
}
}
};
} // namespace vm
#endif // LZMA_UTIL_H

29
src/lzma.h Normal file
View File

@ -0,0 +1,29 @@
/* 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. */
#ifndef LZMA_H
#define LZMA_H
#include "system.h"
#include "allocator.h"
namespace vm {
uint8_t*
decodeLZMA(System* s, Allocator* a, uint8_t* in, unsigned inSize,
unsigned* outSize);
uint8_t*
encodeLZMA(System* s, Allocator* a, uint8_t* in, unsigned inSize,
unsigned* outSize);
} // namespace vm
#endif // LZMA_H

199
src/lzma/load.cpp Normal file
View File

@ -0,0 +1,199 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "C/LzmaDec.h"
#if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport)
# include <io.h>
# define open _open
# define write _write
# define close _close
# ifdef _MSC_VER
# define S_IRWXU (_S_IREAD | _S_IWRITE)
# define and &&
# endif
#else
# define EXPORT __attribute__ ((visibility("default")))
# include <dlfcn.h>
# include <unistd.h>
# include <errno.h>
# define O_BINARY 0
#endif
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_exe_##x
#else
# define SYMBOL(x) _binary_exe_##x
#endif
extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
} // extern "C"
namespace {
int32_t
read4(const uint8_t* in)
{
return (static_cast<int32_t>(in[3]) << 24)
| (static_cast<int32_t>(in[2]) << 16)
| (static_cast<int32_t>(in[1]) << 8)
| (static_cast<int32_t>(in[0]) );
}
void*
myAllocate(void*, size_t size)
{
return malloc(size);
}
void
myFree(void*, void* address)
{
free(address);
}
#if (defined __MINGW32__) || (defined _MSC_VER)
void*
openLibrary(const char* name)
{
return LoadLibrary(name);
}
void*
librarySymbol(void* library, const char* name)
{
void* address;
FARPROC p = GetProcAddress(static_cast<HMODULE>(library), name);
memcpy(&address, &p, sizeof(void*));
return address;
}
const char*
libraryError(void*)
{
return "unknown error";
}
const char*
temporaryFileName(char* buffer, unsigned size)
{
unsigned c = GetTempPathA(size, buffer);
if (c) {
if (GetTempFileNameA(buffer, "223", 0, buffer + c)) {
DeleteFileA(buffer + c);
return buffer + c;
}
}
return 0;
}
#else
void*
openLibrary(const char* name)
{
return dlopen(name, RTLD_LAZY | RTLD_LOCAL);
}
void*
librarySymbol(void* library, const char* name)
{
return dlsym(library, name);
}
const char*
libraryError(void*)
{
return dlerror();
}
const char*
temporaryFileName(char* buffer, unsigned)
{
return tmpnam(buffer);
}
#endif
} // namespace
int
main(int ac, const char** av)
{
const unsigned PropHeaderSize = 5;
const unsigned HeaderSize = 13;
SizeT inSize = SYMBOL(end) - SYMBOL(start);
int32_t outSize32 = read4(SYMBOL(start) + PropHeaderSize);
SizeT outSize = outSize32;
uint8_t* out = static_cast<uint8_t*>(malloc(outSize));
if (out) {
ISzAlloc allocator = { myAllocate, myFree };
ELzmaStatus status = LZMA_STATUS_NOT_SPECIFIED;
if (SZ_OK == LzmaDecode
(out, &outSize, SYMBOL(start) + HeaderSize, &inSize, SYMBOL(start),
PropHeaderSize, LZMA_FINISH_END, &status, &allocator))
{
const unsigned BufferSize = 1024;
char buffer[BufferSize];
const char* name = temporaryFileName(buffer, BufferSize);
if (name) {
int file = open(name, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, S_IRWXU);
if (file != -1) {
SizeT result = write(file, out, outSize);
free(out);
if (close(file) == 0 and outSize == result) {
void* library = openLibrary(name);
unlink(name);
if (library) {
void* main = librarySymbol(library, "avianMain");
if (main) {
int (*mainFunction)(const char*, int, const char**);
memcpy(&mainFunction, &main, sizeof(void*));
return mainFunction(name, ac, av);
} else {
fprintf(stderr, "unable to find main in %s", name);
}
} else {
fprintf(stderr, "unable to load %s: %s\n", name,
libraryError(library));
}
} else {
unlink(name);
fprintf(stderr, "close or write failed; tried %d, got %d; %s\n",
static_cast<int>(outSize), static_cast<int>(result),
strerror(errno));
}
} else {
fprintf(stderr, "unable to open %s\n", name);
}
} else {
fprintf(stderr, "unable to make temporary file name\n");
}
} else {
fprintf(stderr, "unable to decode LZMA data\n");
}
} else {
fprintf(stderr, "unable to allocate buffer of size %d\n",
static_cast<int>(outSize));
}
return -1;
}

190
src/lzma/main.cpp Normal file
View File

@ -0,0 +1,190 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#include <unistd.h>
#endif
#include <fcntl.h>
#include "LzmaEnc.h"
#include "LzmaDec.h"
namespace {
int32_t
read4(const uint8_t* in)
{
return (static_cast<int32_t>(in[3]) << 24)
| (static_cast<int32_t>(in[2]) << 16)
| (static_cast<int32_t>(in[1]) << 8)
| (static_cast<int32_t>(in[0]) );
}
void*
myAllocate(void*, size_t size)
{
return malloc(size);
}
void
myFree(void*, void* address)
{
free(address);
}
SRes
myProgress(void*, UInt64, UInt64)
{
return SZ_OK;
}
void
usageAndExit(const char* program)
{
fprintf(stderr,
"usage: %s {encode|decode} <input file> <output file> "
"[<uncompressed size>]", program);
exit(-1);
}
} // namespace
int
main(int argc, const char** argv)
{
if (argc < 4 or argc > 5) {
usageAndExit(argv[0]);
}
bool encode = strcmp(argv[1], "encode") == 0;
uint8_t* data = 0;
unsigned size;
int fd = open(argv[2], O_RDONLY);
if (fd != -1) {
struct stat s;
int r = fstat(fd, &s);
if (r != -1) {
#ifdef WIN32
HANDLE fm;
HANDLE h = (HANDLE) _get_osfhandle (fd);
fm = CreateFileMapping(
h,
NULL,
PAGE_READONLY,
0,
0,
NULL);
data = static_cast<uint8_t*>(MapViewOfFile(
fm,
FILE_MAP_READ,
0,
0,
s.st_size));
CloseHandle(fm);
#else
data = static_cast<uint8_t*>
(mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
#endif
size = s.st_size;
}
close(fd);
}
bool success = false;
if (data) {
const unsigned PropHeaderSize = 5;
const unsigned HeaderSize = 13;
SizeT outSize;
if (encode) {
outSize = size * 2;
} else {
int32_t outSize32 = read4(data + PropHeaderSize);
if (outSize32 >= 0) {
outSize = outSize32;
} else if (argc == 5) {
outSize = atoi(argv[4]);
} else {
outSize = -1;
}
}
if (outSize >= 0) {
uint8_t* out = static_cast<uint8_t*>(malloc(outSize));
if (out) {
SizeT inSize = size;
ISzAlloc allocator = { myAllocate, myFree };
ELzmaStatus status = LZMA_STATUS_NOT_SPECIFIED;
int result;
if (encode) {
CLzmaEncProps props;
LzmaEncProps_Init(&props);
props.level = 9;
props.writeEndMark = 1;
ICompressProgress progress = { myProgress };
SizeT propsSize = PropHeaderSize;
int32_t inSize32 = inSize;
memcpy(out + PropHeaderSize, &inSize32, 4);
result = LzmaEncode
(out + HeaderSize, &outSize, data, inSize, &props, out,
&propsSize, 1, &progress, &allocator, &allocator);
outSize += HeaderSize;
} else {
result = LzmaDecode
(out, &outSize, data + HeaderSize, &inSize, data, PropHeaderSize,
LZMA_FINISH_END, &status, &allocator);
}
if (result == SZ_OK) {
FILE* outFile = fopen(argv[3], "wb");
if (outFile) {
if (fwrite(out, outSize, 1, outFile) == 1) {
success = true;
} else {
fprintf(stderr, "unable to write to %s\n", argv[3]);
}
fclose(outFile);
} else {
fprintf(stderr, "unable to open %s\n", argv[3]);
}
} else {
fprintf(stderr, "unable to %s data: result %d status %d\n",
encode ? "encode" : "decode", result, status);
}
free(out);
} else {
fprintf(stderr, "unable to allocate output buffer\n");
}
} else {
fprintf(stderr, "unable to determine uncompressed size\n");
}
#ifdef WIN32
UnmapViewOfFile(data);
#else
munmap(data, size);
#endif
} else {
perror(argv[0]);
}
return (success ? 0 : -1);
}

View File

@ -15,6 +15,7 @@
#include "constants.h" #include "constants.h"
#include "processor.h" #include "processor.h"
#include "arch.h" #include "arch.h"
#include "lzma.h"
using namespace vm; using namespace vm;
@ -35,14 +36,6 @@ atomicIncrement(uint32_t* p, int v)
} }
#endif #endif
bool
find(Thread* t, Thread* o)
{
return (t == o)
or (t->peer and find(t->peer, o))
or (t->child and find(t->child, o));
}
void void
join(Thread* t, Thread* o) join(Thread* t, Thread* o)
{ {
@ -56,6 +49,16 @@ join(Thread* t, Thread* o)
} }
} }
#ifndef NDEBUG
bool
find(Thread* t, Thread* o)
{
return (t == o)
or (t->peer and find(t->peer, o))
or (t->child and find(t->child, o));
}
unsigned unsigned
count(Thread* t, Thread* o) count(Thread* t, Thread* o)
{ {
@ -78,6 +81,8 @@ fill(Thread* t, Thread* o, Thread** array)
return array; return array;
} }
#endif // not NDEBUG
void void
dispose(Thread* t, Thread* o, bool remove) dispose(Thread* t, Thread* o, bool remove)
{ {
@ -233,8 +238,8 @@ turnOffTheLights(Thread* t)
Finder* af = m->appFinder; Finder* af = m->appFinder;
c->dispose(); c->dispose();
m->dispose();
h->disposeFixies(); h->disposeFixies();
m->dispose();
p->dispose(); p->dispose();
bf->dispose(); bf->dispose();
af->dispose(); af->dispose();
@ -2920,6 +2925,7 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
shutdownLock(0), shutdownLock(0),
libraries(0), libraries(0),
errorLog(0), errorLog(0),
bootimage(0),
types(0), types(0),
roots(0), roots(0),
finalizers(0), finalizers(0),
@ -2975,6 +2981,10 @@ Machine::dispose()
heap->free(heapPool[i], ThreadHeapSizeInBytes); heap->free(heapPool[i], ThreadHeapSizeInBytes);
} }
if (bootimage) {
heap->free(bootimage, bootimageSize);
}
heap->free(arguments, sizeof(const char*) * argumentCount); heap->free(arguments, sizeof(const char*) * argumentCount);
heap->free(properties, sizeof(const char*) * propertyCount); heap->free(properties, sizeof(const char*) * propertyCount);
@ -3030,13 +3040,28 @@ Thread::init()
uint8_t* code = 0; uint8_t* code = 0;
const char* imageFunctionName = findProperty(m, "avian.bootimage"); const char* imageFunctionName = findProperty(m, "avian.bootimage");
if (imageFunctionName) { if (imageFunctionName) {
void* imagep = m->libraries->resolve(imageFunctionName); bool lzma = strncmp("lzma:", imageFunctionName, 5) == 0;
const char* symbolName
= lzma ? imageFunctionName + 5 : imageFunctionName;
void* imagep = m->libraries->resolve(symbolName);
if (imagep) { if (imagep) {
BootImage* (*imageFunction)(unsigned*); uint8_t* (*imageFunction)(unsigned*);
memcpy(&imageFunction, &imagep, BytesPerWord); memcpy(&imageFunction, &imagep, BytesPerWord);
unsigned size; unsigned size;
image = imageFunction(&size); uint8_t* imageBytes = imageFunction(&size);
if (lzma) {
#ifdef AVIAN_USE_LZMA
m->bootimage = image = reinterpret_cast<BootImage*>
(decodeLZMA
(m->system, m->heap, imageBytes, size, &(m->bootimageSize)));
#else
abort(this);
#endif
} else {
image = reinterpret_cast<BootImage*>(imageBytes);
}
const char* codeFunctionName = findProperty(m, "avian.codeimage"); const char* codeFunctionName = findProperty(m, "avian.codeimage");
if (codeFunctionName) { if (codeFunctionName) {

View File

@ -1316,6 +1316,7 @@ class Machine {
System::Monitor* shutdownLock; System::Monitor* shutdownLock;
System::Library* libraries; System::Library* libraries;
FILE* errorLog; FILE* errorLog;
BootImage* bootimage;
object types; object types;
object roots; object roots;
object finalizers; object finalizers;
@ -1332,6 +1333,7 @@ class Machine {
JNIEnvVTable jniEnvVTable; JNIEnvVTable jniEnvVTable;
uintptr_t* heapPool[ThreadHeapPoolSize]; uintptr_t* heapPool[ThreadHeapPoolSize];
unsigned heapPoolIndex; unsigned heapPoolIndex;
unsigned bootimageSize;
}; };
void void
@ -2231,6 +2233,39 @@ makeByteArray(Thread* t, const char* format, ...);
object object
makeString(Thread* t, const char* format, ...); makeString(Thread* t, const char* format, ...);
#ifndef HAVE_StringOffset
inline unsigned
stringLength(Thread* t, object string)
{
return arrayLength(t, stringData(t, string));
}
inline unsigned
stringOffset(Thread*, object)
{
return 0;
}
inline object
makeString(Thread* t, object data, unsigned offset, unsigned length, unsigned)
{
if (offset == 0 and length == arrayLength(t, data)) {
return makeString(t, data, 0, 0);
} else {
PROTECT(t, data);
object array = makeCharArray(t, length);
memcpy(&charArrayBody(t, array, 0), &charArrayBody(t, data, offset),
length * 2);
return makeString(t, array, 0, 0);
}
}
#endif // not HAVE_StringOffset
int int
stringUTFLength(Thread* t, object string, unsigned start, unsigned length); stringUTFLength(Thread* t, object string, unsigned start, unsigned length);

View File

@ -340,7 +340,8 @@ class MySystem: public System {
// milliseconds) is infinity so as to avoid overflow: // milliseconds) is infinity so as to avoid overflow:
if (time and time < INT64_C(31536000000000000)) { if (time and time < INT64_C(31536000000000000)) {
int64_t then = s->now() + time; int64_t then = s->now() + time;
timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 }; timespec ts = { static_cast<long>(then / 1000),
static_cast<long>((then % 1000) * 1000 * 1000) };
int rv UNUSED = pthread_cond_timedwait int rv UNUSED = pthread_cond_timedwait
(&(t->condition), &(t->mutex), &ts); (&(t->condition), &(t->mutex), &ts);
expect(s, rv == 0 or rv == ETIMEDOUT or rv == EINTR); expect(s, rv == 0 or rv == ETIMEDOUT or rv == EINTR);

View File

@ -70,12 +70,6 @@ equal(const char* a, const char* b)
return strcmp(a, b) == 0; return strcmp(a, b) == 0;
} }
inline bool
startsWith(const char* a, const char* b)
{
return strncmp(a, b, strlen(a)) == 0;
}
inline bool inline bool
endsWith(const char* a, const char* b) endsWith(const char* a, const char* b)
{ {
@ -284,14 +278,6 @@ setCdr(Object* o, Object* v)
static_cast<Pair*>(o)->cdr = v; static_cast<Pair*>(o)->cdr = v;
} }
unsigned
length(Object* o)
{
unsigned c = 0;
for (; o; o = cdr(o)) ++c;
return c;
}
class List { class List {
public: public:
Object* first; Object* first;
@ -1078,53 +1064,6 @@ parseSubdeclaration(Object* t, Object* p, Object* declarations)
} }
} }
bool
memberEqual(Object* a, Object* b)
{
if (a->type == b->type) {
switch (a->type) {
case Object::Scalar:
return equal(memberTypeName(a), memberTypeName(b))
and memberNoAssert(a) == memberNoAssert(b)
and memberNoGC(a) == memberNoGC(b);
// todo: compare array fields
default: return false;
}
} else {
return false;
}
}
bool
specEqual(Object* a, Object* b)
{
if (a->type == Object::Type and
b->type == Object::Type)
{
MemberIterator ai(a);
MemberIterator bi(b);
while (ai.hasMore()) {
if (not bi.hasMore()) {
return false;
}
if (not memberEqual(ai.next(), bi.next())) {
return false;
}
}
if (bi.hasMore()) {
return false;
} else {
return true;
}
} else {
return false;
}
}
const char* const char*
append(const char* a, const char* b, const char* c, const char* d) append(const char* a, const char* b, const char* c, const char* d)
{ {
@ -1445,6 +1384,11 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
out->write(" = "); out->write(" = ");
writeOffset(out, offset); writeOffset(out, offset);
out->write(";\n\n"); out->write(";\n\n");
out->write("#define HAVE_");
out->write(capitalize(local::typeName(memberOwner(member))));
out->write(capitalize(memberName(member)));
out->write(" 1\n\n");
} }
out->write("inline "); out->write("inline ");
@ -1725,13 +1669,6 @@ writeConstructorInitializations(Output* out, Object* t)
} }
} }
unsigned
typeMemberCount(Object* o)
{
if (o == 0) return 0;
return length(typeMembers(o)) + typeMemberCount(typeSuper(o));
}
void void
writeInitializerDeclarations(Output* out, Object* declarations) writeInitializerDeclarations(Output* out, Object* declarations)
{ {
@ -1888,17 +1825,6 @@ writeEnums(Output* out, Object* declarations)
} }
} }
unsigned
memberCount(Object* o)
{
unsigned c = 0;
for (MemberIterator it(o); it.hasMore();) {
it.next();
++c;
}
return c;
}
unsigned unsigned
methodCount(Object* o) methodCount(Object* o)
{ {

View File

@ -198,44 +198,12 @@ assert(ArchitectureContext* c, bool v)
} }
#endif // not NDEBUG #endif // not NDEBUG
void
expect(Context* c, bool v)
{
expect(c->s, v);
}
ResolvedPromise* ResolvedPromise*
resolved(Context* c, int64_t value) resolved(Context* c, int64_t value)
{ {
return new(c->zone) ResolvedPromise(value); return new(c->zone) ResolvedPromise(value);
} }
class CodePromise: public Promise {
public:
CodePromise(Context* c, unsigned offset): c(c), offset(offset) { }
virtual int64_t value() {
if (resolved()) {
return reinterpret_cast<intptr_t>(c->result + offset);
}
abort(c);
}
virtual bool resolved() {
return c->result != 0;
}
Context* c;
unsigned offset;
};
CodePromise*
codePromise(Context* c, unsigned offset)
{
return new (c->zone) CodePromise(c, offset);
}
class Offset: public Promise { class Offset: public Promise {
public: public:
Offset(Context* c, MyBlock* block, unsigned offset, AlignmentPadding* limit): Offset(Context* c, MyBlock* block, unsigned offset, AlignmentPadding* limit):
@ -629,14 +597,6 @@ opcode(Context* c, uint8_t op1, uint8_t op2)
c->code.append(op2); c->code.append(op2);
} }
void
opcode(Context* c, uint8_t op1, uint8_t op2, uint8_t op3)
{
c->code.append(op1);
c->code.append(op2);
c->code.append(op3);
}
void void
return_(Context* c) return_(Context* c)
{ {