Merge branch 'master' of oss.readytalk.com:/var/local/git/avian into armvfp

This commit is contained in:
JET 2012-06-04 12:39:45 -06:00
commit 714aebfec1
27 changed files with 949 additions and 327 deletions

View File

@ -76,7 +76,9 @@ Java_java_util_zip_Inflater_inflate
int r = inflate(s, Z_SYNC_FLUSH);
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);
@ -147,7 +149,9 @@ Java_java_util_zip_Deflater_deflate
int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH);
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);

View File

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

159
makefile
View File

@ -1,7 +1,7 @@
MAKEFLAGS = -s
name = avian
version = 0.5
version = 0.6
build-arch := $(shell uname -m \
| sed 's/^i.86$$/i386/' \
@ -33,6 +33,9 @@ endif
ifneq ($(mode),fast)
options := $(options)-$(mode)
endif
ifneq ($(lzma),)
options := $(options)-lzma
endif
ifeq ($(bootimage),true)
options := $(options)-bootimage
endif
@ -68,6 +71,8 @@ ifeq ($(build-platform),cygwin)
native-path = cygpath -m
endif
windows-path = echo
path-separator = :
ifneq (,$(filter mingw32 cygwin,$(build-platform)))
@ -138,8 +143,13 @@ endif
input = List
build-cxx = g++
build-cc = gcc
ifeq ($(use-clang),true)
build-cxx = clang -std=c++11
build-cc = clang
else
build-cxx = g++
build-cc = gcc
endif
mflag =
ifneq ($(platform),darwin)
@ -195,7 +205,8 @@ build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject -Isrc/ \
-fno-rtti -fno-exceptions \
-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)
@ -446,23 +457,36 @@ ifeq ($(mode),stress-major)
strip = :
endif
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
endif
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
endif
ifeq ($(use-lto),true)
# 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)
ifeq ($(use-clang),true)
optimization-cflags += -flto
no-lto = -fno-lto
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
@ -482,8 +506,9 @@ ld := $(cc)
build-ld := $(build-cc)
ifdef msvc
windows-java-home := $(shell cygpath -m "$(JAVA_HOME)")
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"
cc = $(cxx)
ld = "$(msvc)/BIN/link.exe"
@ -494,6 +519,11 @@ ifdef msvc
-Fd$(build)/$(name).pdb -I"$(zlib)/include" -I$(src) -I"$(build)" \
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \
-DTARGET_BYTES_PER_WORD=$(pointer-size)
ifneq ($(lzma),)
cflags += -I$(shell $(windows-path) "$(lzma)")
endif
shared = -dll
lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \
-DEFAULTLIB:zlib -MANIFEST -debug
@ -517,6 +547,7 @@ ifdef msvc
strip = :
endif
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(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)))
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
@ -579,7 +610,10 @@ ifeq ($(continuations),true)
asmflags += -DAVIAN_CONTINUATIONS
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 = \
$(call cpp-objects,$(bootimage-generator-sources),$(src),$(build))
bootimage-generator = $(build)/bootimage-generator
@ -614,17 +648,62 @@ generator-sources = \
$(src)/type-generator.cpp \
$(src)/$(build-system).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 = \
$(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 = \
$(call generator-cpp-objects,$(generator-sources),$(src),$(build))
generator-lzma-objects = \
$(call generator-c-objects,$(lzma-decode-sources),$(lzma)/C,$(build))
generator = $(build)/generator
converter-depends = \
$(src)/binaryToObject/tools.h \
$(src)/binaryToObject/endianness.h
converter-sources = \
$(src)/binaryToObject/tools.cpp \
$(src)/binaryToObject/elf.cpp \
@ -745,8 +824,9 @@ test-flags = -cp $(build)/test
test-args = $(test-flags) $(input)
.PHONY: build
build: $(static-library) $(executable) $(dynamic-library) \
$(executable-dynamic) $(classpath-dep) $(test-dep) $(test-extra-dep)
build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \
$(lzma-encoder) $(executable-dynamic) $(classpath-dep) $(test-dep) \
$(test-extra-dep)
$(test-dep): $(classpath-dep)
@ -836,7 +916,7 @@ $(test-extra-dep): $(test-extra-sources)
define compile-object
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cxx) $(cflags) -c $(<) $(call output,$(@))
$(cxx) $(cflags) -c $$($(windows-path) $(<)) $(call output,$(@))
endef
define compile-asm-object
@ -848,6 +928,11 @@ endef
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
$(compile-object)
$(build)/%.o: $(lzma)/C/%.c
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cxx) $(cflags) -Wno-error -c $$($(windows-path) $(<)) $(call output,$(@))
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S
$(compile-asm-object)
@ -879,6 +964,16 @@ $(converter-objects) $(converter-tool-objects): $(build)/binaryToObject/%.o: $(s
$(converter): $(converter-objects) $(converter-tool-objects)
$(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)
@echo "creating $(@)"
(wd=$$(pwd) && \
@ -901,18 +996,28 @@ $(javahome-object): $(build)/javahome.jar $(converter)
$(converter) $(<) $(@) _binary_javahome_jar_start \
_binary_javahome_jar_end $(platform) $(arch)
$(generator-objects): $(generator-depends)
$(generator-objects): $(build)/%-build.o: $(src)/%.cpp
define compile-generator-object
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \
-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) \
-Wno-error -c $(<) -o $(@)
$(jni-objects): $(build)/%.o: $(classpath-src)/%.cpp
$(compile-object)
$(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
$(javahome-object) $(boot-javahome-object)
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
@echo "creating $(@)"
rm -rf $(@)
$(ar) cru $(@) $(^)
@ -925,7 +1030,7 @@ $(bootimage-object) $(codeimage-object): $(bootimage-generator)
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
$(javahome-object) $(boot-javahome-object)
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
$(executable): $(executable-objects)
@echo "linking $(@)"
@ -961,7 +1066,8 @@ $(bootimage-generator): $(bootimage-generator-objects)
$(build-bootimage-generator): \
$(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 $(@)"
ifeq ($(platform),windows)
ifdef msvc
@ -979,7 +1085,8 @@ endif
$(dynamic-library): $(vm-objects) $(dynamic-object) $(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 $(@)"
ifdef msvc
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
@ -1005,7 +1112,7 @@ else
endif
$(strip) $(strip-all) $(@)
$(generator): $(generator-objects)
$(generator): $(generator-objects) $(generator-lzma-objects)
@echo "linking $(@)"
$(build-ld) $(^) $(build-lflags) -o $(@)

View File

@ -63,6 +63,7 @@ Build requirements include:
* GNU make 3.80 or later
* 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
* MinGW 3.4 or later (only if compiling for Windows)
* 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} \
process={compile,interpret} \
mode={debug,debug-fast,fast,small} \
lzma=<lzma source directory> \
ios={true,false} \
bootimage={true,false} \
heapdump={true,false} \
tails={true,false} \
continuations={true,false} \
use-clang={true,false} \
openjdk=<openjdk installation directory> \
openjdk-src=<openjdk source directory>
@ -102,11 +105,18 @@ certain flags described below, all of which are optional.
assertions
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
non-jailbroken iOS devices do not allow JIT compilation, so only
process=interpret or bootimage=true builds will run on such
devices. See git://oss.readytalk.com/hello-ios.git for an example
of an Xcode project for iOS which uses Avian.
devices. See https://github.com/ReadyTalk/hello-ios for an
example of an Xcode project for iOS which uses Avian.
default: false
* 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.
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
Avian class library. See "Building with the OpenJDK Class
Library" below for details.
@ -359,8 +374,20 @@ EOF
Step 3: Make an object file out of the jar.
$ ../build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar boot-jar.o \
_binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch}
$ ../build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar \
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
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;
case PlatformInfo::PowerPC:
return EM_PPC;
default:
return ~0;
}
return ~0;
}
const char* getSectionName(unsigned accessFlags, unsigned& sectionFlags) {
@ -255,8 +256,8 @@ public:
SectionWriter(FileWriter& file):
file(file),
name(""),
data(0),
dataSize(0)
dataSize(0),
data(0)
{
memset(&header, 0, sizeof(SectionHeader));
file.sectionCount++;
@ -279,8 +280,8 @@ public:
file(file),
name(chname),
data(data),
dataSize(dataSize)
dataSize(dataSize),
data(data)
{
if(strcmp(chname, ".shstrtab") == 0) {
file.sectionStringTableSectionNumber = file.sectionCount;
@ -359,11 +360,11 @@ public:
file.writeHeader(out);
for(int i = 0; i < file.sectionCount; i++) {
for(unsigned i = 0; i < file.sectionCount; i++) {
sections[i].writeHeader(out);
}
for(int i = 0; i < file.sectionCount; i++) {
for(unsigned i = 0; i < file.sectionCount; i++) {
sections[i].writeData(out);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -17,6 +17,7 @@
#include "assembler.h"
#include "target.h"
#include "binaryToObject/tools.h"
#include "lzma.h"
// since we aren't linking against libstdc++, we must implement this
// ourselves:
@ -62,14 +63,6 @@ enum Type {
class Field {
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;
unsigned buildOffset;
unsigned buildSize;
@ -77,6 +70,17 @@ class Field {
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 {
public:
enum Kind {
@ -397,9 +401,9 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
map->targetFixedOffsets()[i * BytesPerWord]
= i * TargetBytesPerWord;
new (map->fixedFields() + i) Field
(types[i], i * BytesPerWord, BytesPerWord,
i * TargetBytesPerWord, TargetBytesPerWord);
init(new (map->fixedFields() + i) Field, types[i],
i * BytesPerWord, BytesPerWord, i * TargetBytesPerWord,
TargetBytesPerWord);
}
hashMapInsert
@ -446,8 +450,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
++ memberIndex;
}
} else {
new (memberFields) Field
(Type_object, 0, BytesPerWord, 0, TargetBytesPerWord);
init(new (memberFields) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord);
memberIndex = 1;
buildMemberOffset = BytesPerWord;
@ -456,12 +460,11 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
Field staticFields[count + 2];
new (staticFields) Field
(Type_object, 0, BytesPerWord, 0, TargetBytesPerWord);
init(new (staticFields) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord);
new (staticFields + 1) Field
(Type_intptr_t, BytesPerWord, BytesPerWord, TargetBytesPerWord,
TargetBytesPerWord);
init(new (staticFields + 1) Field, Type_intptr_t, BytesPerWord,
BytesPerWord, TargetBytesPerWord, TargetBytesPerWord);
unsigned staticIndex = 2;
unsigned buildStaticOffset = BytesPerWord * 2;
@ -510,9 +513,9 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
buildStaticOffset = fieldOffset(t, field);
new (staticFields + staticIndex) Field
(type, buildStaticOffset, buildSize, targetStaticOffset,
targetSize);
init(new (staticFields + staticIndex) Field, type,
buildStaticOffset, buildSize, targetStaticOffset,
targetSize);
targetStaticOffset += targetSize;
@ -524,9 +527,9 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
buildMemberOffset = fieldOffset(t, field);
new (memberFields + memberIndex) Field
(type, buildMemberOffset, buildSize, targetMemberOffset,
targetSize);
init(new (memberFields + memberIndex) Field, type,
buildMemberOffset, buildSize, targetMemberOffset,
targetSize);
targetMemberOffset += targetSize;
@ -693,12 +696,6 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
return constants;
}
unsigned
objectSize(Thread* t, object o)
{
return baseSize(t, o, objectClass(t, o));
}
void
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
targetThunk(BootImage::Thunk t)
{
@ -1285,7 +1276,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
BootImage* image, uint8_t* code, const char* className,
const char* methodName, const char* methodSpec,
const char* bootimageStart, const char* bootimageEnd,
const char* codeimageStart, const char* codeimageEnd)
const char* codeimageStart, const char* codeimageEnd,
bool useLZMA)
{
setRoot(t, Machine::OutOfMemoryError,
make(t, type(t, Machine::OutOfMemoryErrorType)));
@ -1347,7 +1339,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
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 targetOffset = TargetBytesPerWord;
@ -1424,8 +1417,8 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
++ targetOffset;
}
new (fields + j) Field
(type, buildOffset, buildSize, targetOffset, targetSize);
init(new (fields + j) Field, type, buildOffset, buildSize,
targetOffset, targetSize);
buildOffset += buildSize;
targetOffset += targetSize;
@ -1603,6 +1596,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
heapWalker->dispose();
image->magic = BootImage::Magic;
image->initialized = 0;
fprintf(stderr, "class count %d string count %d call count %d\n"
"heap size %d code size %d\n",
@ -1665,7 +1659,27 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
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(image->codeSize, codeimageEnd));
@ -1693,10 +1707,12 @@ writeBootImage(Thread* t, uintptr_t* arguments)
const char* bootimageEnd = reinterpret_cast<const char*>(arguments[8]);
const char* codeimageStart = reinterpret_cast<const char*>(arguments[9]);
const char* codeimageEnd = reinterpret_cast<const char*>(arguments[10]);
bool useLZMA = arguments[11];
writeBootImage2
(t, bootimageOutput, codeOutput, image, code, className, methodName,
methodSpec, bootimageStart, bootimageEnd, codeimageStart, codeimageEnd);
methodSpec, bootimageStart, bootimageEnd, codeimageStart, codeimageEnd,
useLZMA);
return 1;
}
@ -1755,7 +1771,11 @@ bool ArgParser::parse(int ac, const char** av) {
}
for(Arg* arg = first; arg; arg = arg->next) {
if(strcmp(arg->name, &av[i][1]) == 0) {
state = arg;
if (arg->desc == 0) {
arg->value = "true";
} else {
state = arg;
}
}
}
if(!state) {
@ -1810,6 +1830,8 @@ public:
char* codeimageStart;
char* codeimageEnd;
bool useLZMA;
bool maybeSplit(const char* src, char*& destA, char*& destB) {
if(src) {
const char* split = strchr(src, ':');
@ -1839,6 +1861,7 @@ public:
Arg entry(parser, false, "entry", "<class name>[.<method name>[<method spec>]]");
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 useLZMA(parser, false, "use-lzma", 0);
if(!parser.parse(ac, av)) {
parser.printUsage(av[0]);
@ -1848,6 +1871,7 @@ public:
this->classpath = classpath.value;
this->bootimage = bootimage.value;
this->codeimage = codeimage.value;
this->useLZMA = useLZMA.value != 0;
if(entry.value) {
if(const char* entryClassEnd = strchr(entry.value, '.')) {
@ -1997,7 +2021,8 @@ main(int ac, const char** av)
reinterpret_cast<uintptr_t>(args.bootimageStart),
reinterpret_cast<uintptr_t>(args.bootimageEnd),
reinterpret_cast<uintptr_t>(args.codeimageStart),
reinterpret_cast<uintptr_t>(args.codeimageEnd)
reinterpret_cast<uintptr_t>(args.codeimageEnd),
reinterpret_cast<uintptr_t>(args.useLZMA)
};
run(t, writeBootImage, arguments);

View File

@ -288,14 +288,6 @@ transition(MyThread* t, void* ip, void* stack, object continuation,
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
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",
// code, code + image->codeSize);
static bool fixed = false;
if (not fixed) {
if (not image->initialized) {
fixupHeap(t, heapMap, heapMapSizeInWords, heap);
}
@ -9688,7 +9678,7 @@ boot(MyThread* t, BootImage* image, uint8_t* code)
findThunks(t, image, code);
if (fixed) {
if (image->initialized) {
resetRuntimeState
(t, classLoaderMap(t, root(t, Machine::BootLoader)), heap,
image->heapSize);
@ -9711,7 +9701,7 @@ boot(MyThread* t, BootImage* image, uint8_t* code)
(t, classLoaderMap(t, root(t, Machine::AppLoader)), image, code);
}
fixed = true;
image->initialized = true;
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);
logCompile(t, start, *size, 0, virtualThunkName, 0);
logCompile(t, start, *size, 0, RUNTIME_ARRAY_BODY(virtualThunkName), 0);
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);
}
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*
reverseDestroy(Cell* cell)
{
@ -992,6 +971,8 @@ valid(Read* r)
return r and r->valid();
}
#ifndef NDEBUG
bool
hasBuddy(Context* c, Value* a, Value* b)
{
@ -1011,6 +992,8 @@ hasBuddy(Context* c, Value* a, Value* b)
return false;
}
#endif // not NDEBUG
Read*
live(Context* c UNUSED, Value* v)
{
@ -1618,7 +1601,7 @@ class ConstantSite: public Site {
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
if (value->resolved()) {
return vm::snprintf
(buffer, bufferSize, "constant %"LLD, value->value());
(buffer, bufferSize, "constant %" LLD, value->value());
} else {
return vm::snprintf(buffer, bufferSize, "constant unresolved");
}
@ -1709,7 +1692,7 @@ class AddressSite: public Site {
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
if (address->resolved()) {
return vm::snprintf
(buffer, bufferSize, "address %"LLD, address->value());
(buffer, bufferSize, "address %" LLD, address->value());
} else {
return vm::snprintf(buffer, bufferSize, "address unresolved");
}
@ -5302,16 +5285,17 @@ propagateJunctionSites(Context* c, Event* e)
class SiteRecord {
public:
SiteRecord(Site* site, Value* value):
site(site), value(value)
{ }
SiteRecord() { }
Site* site;
Value* value;
};
void
init(SiteRecord* r, Site* s, Value* v)
{
r->site = s;
r->value = v;
}
class SiteRecordList {
public:
SiteRecordList(SiteRecord* records, unsigned capacity):
@ -5329,7 +5313,7 @@ freeze(Context* c, SiteRecordList* frozen, Site* s, Value* v)
assert(c, frozen->index < frozen->capacity);
s->freeze(c, v);
new (frozen->records + (frozen->index ++)) SiteRecord(s, v);
init(new (frozen->records + (frozen->index ++)) SiteRecord, s, v);
}
void
@ -5866,17 +5850,6 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
c->firstBlock = firstBlock;
}
unsigned
count(Stack* s)
{
unsigned c = 0;
while (s) {
++ c;
s = s->next;
}
return c;
}
void
restore(Context* c, ForkState* state)
{

View File

@ -12,6 +12,7 @@
#include "system.h"
#include "tokenizer.h"
#include "finder.h"
#include "lzma.h"
using namespace vm;
@ -173,11 +174,12 @@ class DirectoryElement: public Element {
class PointerRegion: public System::Region {
public:
PointerRegion(System* s, Allocator* allocator, const uint8_t* start,
size_t length):
size_t length, bool freePointer = false):
s(s),
allocator(allocator),
start_(start),
length_(length)
length_(length),
freePointer(freePointer)
{ }
virtual const uint8_t* start() {
@ -189,6 +191,9 @@ class PointerRegion: public System::Region {
}
virtual void dispose() {
if (freePointer) {
allocator->free(start_, length_);
}
allocator->free(this, sizeof(*this));
}
@ -196,6 +201,7 @@ class PointerRegion: public System::Region {
Allocator* allocator;
const uint8_t* start_;
size_t length_;
bool freePointer;
};
class DataRegion: public System::Region {
@ -556,7 +562,10 @@ class BuiltinElement: public JarElement {
virtual void init() {
if (index == 0) {
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) {
uint8_t* (*function)(unsigned*);
memcpy(&function, &p, BytesPerWord);
@ -564,10 +573,29 @@ class BuiltinElement: public JarElement {
unsigned size;
uint8_t* data = function(&size);
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)))
PointerRegion(s, allocator, data, size);
PointerRegion(s, allocator, data, size, freePointer);
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);
#endif
System* system(Context*);
void* tryAllocate(Context* c, unsigned size);
void* allocate(Context* c, unsigned size);
void free(Context* c, const void* p, unsigned size);
@ -689,12 +688,6 @@ class Context {
int64_t totalTime;
};
inline System*
system(Context* c)
{
return c->system;
}
const char*
segment(Context* c, void* p)
{

View File

@ -231,16 +231,6 @@ get(object o, unsigned offsetInWords)
(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
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;
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));
}
@ -311,7 +312,7 @@ DefineClass(Thread* t, const char*, jobject loader, const jbyte* buffer,
{
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(loader),
reinterpret_cast<uintptr_t>(buffer),
length };
static_cast<uintptr_t>(length) };
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),
field,
v };
static_cast<uintptr_t>(v) };
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),
field,
v };
static_cast<uintptr_t>(v) };
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),
field,
v };
static_cast<uintptr_t>(v) };
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),
field,
v };
static_cast<uintptr_t>(v) };
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),
field,
v };
static_cast<uintptr_t>(v) };
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),
field,
v };
static_cast<uintptr_t>(v) };
run(t, setStaticIntField, arguments);
}
@ -2261,7 +2262,7 @@ newObjectArray(Thread* t, uintptr_t* arguments)
jobjectArray JNICALL
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>(init) };
@ -2302,7 +2303,7 @@ NewBooleanArray(Thread* t, jsize length)
{
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeBooleanArray)),
length };
static_cast<uintptr_t>(length) };
return reinterpret_cast<jbooleanArray>(run(t, newArray, arguments));
}
@ -2318,7 +2319,7 @@ NewByteArray(Thread* t, jsize length)
{
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeByteArray0)),
length };
static_cast<uintptr_t>(length) };
return reinterpret_cast<jbyteArray>(run(t, newArray, arguments));
}
@ -2328,7 +2329,7 @@ NewCharArray(Thread* t, jsize length)
{
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeCharArray)),
length };
static_cast<uintptr_t>(length) };
return reinterpret_cast<jcharArray>(run(t, newArray, arguments));
}
@ -2338,7 +2339,7 @@ NewShortArray(Thread* t, jsize length)
{
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeShortArray)),
length };
static_cast<uintptr_t>(length) };
return reinterpret_cast<jshortArray>(run(t, newArray, arguments));
}
@ -2348,7 +2349,7 @@ NewIntArray(Thread* t, jsize length)
{
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeIntArray)),
length };
static_cast<uintptr_t>(length) };
return reinterpret_cast<jintArray>(run(t, newArray, arguments));
}
@ -2358,7 +2359,7 @@ NewLongArray(Thread* t, jsize length)
{
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeLongArray)),
length };
static_cast<uintptr_t>(length) };
return reinterpret_cast<jlongArray>(run(t, newArray, arguments));
}
@ -2368,7 +2369,7 @@ NewFloatArray(Thread* t, jsize length)
{
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeFloatArray)),
length };
static_cast<uintptr_t>(length) };
return reinterpret_cast<jfloatArray>(run(t, newArray, arguments));
}
@ -2378,7 +2379,7 @@ NewDoubleArray(Thread* t, jsize length)
{
uintptr_t arguments[]
= { reinterpret_cast<uintptr_t>(voidPointer(makeDoubleArray)),
length };
static_cast<uintptr_t>(length) };
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),
reinterpret_cast<uintptr_t>(methods),
methodCount };
static_cast<uintptr_t>(methodCount) };
return run(t, registerNatives, arguments) ? 0 : -1;
}

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

@ -0,0 +1,49 @@
/* 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 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;
memcpy(&outSize32, in + PropHeaderSize, 4);
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

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

@ -0,0 +1,191 @@
#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 {
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;
memcpy(&outSize32, SYMBOL(start) + PropHeaderSize, 4);
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;
}

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

@ -0,0 +1,182 @@
#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 {
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;
memcpy(&outSize32, data + PropHeaderSize, 4);
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 "processor.h"
#include "arch.h"
#include "lzma.h"
using namespace vm;
@ -35,14 +36,6 @@ atomicIncrement(uint32_t* p, int v)
}
#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
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
count(Thread* t, Thread* o)
{
@ -78,6 +81,8 @@ fill(Thread* t, Thread* o, Thread** array)
return array;
}
#endif // not NDEBUG
void
dispose(Thread* t, Thread* o, bool remove)
{
@ -233,8 +238,8 @@ turnOffTheLights(Thread* t)
Finder* af = m->appFinder;
c->dispose();
m->dispose();
h->disposeFixies();
m->dispose();
p->dispose();
bf->dispose();
af->dispose();
@ -2920,6 +2925,7 @@ Machine::Machine(System* system, Heap* heap, Finder* bootFinder,
shutdownLock(0),
libraries(0),
errorLog(0),
bootimage(0),
types(0),
roots(0),
finalizers(0),
@ -2975,6 +2981,10 @@ Machine::dispose()
heap->free(heapPool[i], ThreadHeapSizeInBytes);
}
if (bootimage) {
heap->free(bootimage, bootimageSize);
}
heap->free(arguments, sizeof(const char*) * argumentCount);
heap->free(properties, sizeof(const char*) * propertyCount);
@ -3030,13 +3040,28 @@ Thread::init()
uint8_t* code = 0;
const char* imageFunctionName = findProperty(m, "avian.bootimage");
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) {
BootImage* (*imageFunction)(unsigned*);
uint8_t* (*imageFunction)(unsigned*);
memcpy(&imageFunction, &imagep, BytesPerWord);
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");
if (codeFunctionName) {

View File

@ -1316,6 +1316,7 @@ class Machine {
System::Monitor* shutdownLock;
System::Library* libraries;
FILE* errorLog;
BootImage* bootimage;
object types;
object roots;
object finalizers;
@ -1332,6 +1333,7 @@ class Machine {
JNIEnvVTable jniEnvVTable;
uintptr_t* heapPool[ThreadHeapPoolSize];
unsigned heapPoolIndex;
unsigned bootimageSize;
};
void

View File

@ -340,7 +340,8 @@ class MySystem: public System {
// milliseconds) is infinity so as to avoid overflow:
if (time and time < INT64_C(31536000000000000)) {
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
(&(t->condition), &(t->mutex), &ts);
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;
}
inline bool
startsWith(const char* a, const char* b)
{
return strncmp(a, b, strlen(a)) == 0;
}
inline bool
endsWith(const char* a, const char* b)
{
@ -284,14 +278,6 @@ setCdr(Object* o, Object* v)
static_cast<Pair*>(o)->cdr = v;
}
unsigned
length(Object* o)
{
unsigned c = 0;
for (; o; o = cdr(o)) ++c;
return c;
}
class List {
public:
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*
append(const char* a, const char* b, const char* c, const char* d)
{
@ -1725,13 +1664,6 @@ writeConstructorInitializations(Output* out, Object* t)
}
}
unsigned
typeMemberCount(Object* o)
{
if (o == 0) return 0;
return length(typeMembers(o)) + typeMemberCount(typeSuper(o));
}
void
writeInitializerDeclarations(Output* out, Object* declarations)
{
@ -1888,17 +1820,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
methodCount(Object* o)
{

View File

@ -198,44 +198,12 @@ assert(ArchitectureContext* c, bool v)
}
#endif // not NDEBUG
void
expect(Context* c, bool v)
{
expect(c->s, v);
}
ResolvedPromise*
resolved(Context* c, int64_t 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 {
public:
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);
}
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
return_(Context* c)
{