diff --git a/makefile b/makefile index 2912cfde5b..dd110464d1 100755 --- a/makefile +++ b/makefile @@ -18,9 +18,11 @@ build-platform := \ | sed 's/^cygwin.*$$/cygwin/') arch = $(build-arch) +target-arch = $(arch) bootimage-platform = \ $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform))) platform = $(bootimage-platform) +target-platform = $(platform) mode = fast process = compile @@ -190,8 +192,10 @@ endif build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \ "-I$(JAVA_HOME)/include/linux" -I$(src) -pthread -converter-cflags = -D__STDC_CONSTANT_MACROS -Isrc/binaryToObject \ - -fno-rtti -fno-exceptions +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 cflags = $(build-cflags) @@ -231,6 +235,7 @@ endif ifeq ($(arch),i386) pointer-size = 4 endif + ifeq ($(arch),powerpc) asm = powerpc pointer-size = 4 @@ -249,9 +254,11 @@ ifeq ($(arch),powerpc) endif endif endif + ifeq ($(arch),arm) asm = arm pointer-size = 4 + ifeq ($(build-platform),darwin) ios = true else @@ -281,10 +288,6 @@ ifeq ($(ios),true) cflags += -DAVIAN_IOS endif -ifeq ($(platform),linux) - bootimage-cflags += -DTARGET_PLATFORM_LINUX -endif - ifeq ($(build-platform),darwin) build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src) cflags += -I/System/Library/Frameworks/JavaVM.framework/Headers/ @@ -292,8 +295,6 @@ ifeq ($(build-platform),darwin) endif ifeq ($(platform),darwin) - bootimage-cflags += -DTARGET_PLATFORM_DARWIN - ifeq (${OSX_SDK_SYSROOT},) OSX_SDK_SYSROOT = 10.4u endif @@ -371,8 +372,6 @@ ifeq ($(platform),darwin) endif ifeq ($(platform),windows) - bootimage-cflags += -DTARGET_PLATFORM_WINDOWS - inc = "$(win32)/include" lib = "$(win32)/lib" @@ -385,7 +384,7 @@ ifeq ($(platform),windows) exe-suffix = .exe lflags = -L$(lib) $(common-lflags) -lws2_32 -liphlpapi -mwindows -mconsole - cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500 -DTARGET_PLATFORM_WINDOWS + cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500 ifeq (,$(filter mingw32 cygwin,$(build-platform))) openjdk-extra-cflags += -I$(src)/openjdk/caseSensitive @@ -494,7 +493,7 @@ ifdef msvc -DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \ -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) -DTARGET_PLATFORM_WINDOWS + -DTARGET_BYTES_PER_WORD=$(pointer-size) shared = -dll lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \ -DEFAULTLIB:zlib -MANIFEST -debug @@ -585,10 +584,7 @@ bootimage-generator-objects = \ $(call cpp-objects,$(bootimage-generator-sources),$(src),$(build)) bootimage-generator = $(build)/bootimage-generator -bootimage-bin = $(build)/bootimage.bin bootimage-object = $(build)/bootimage-bin.o - -codeimage-bin = $(build)/codeimage.bin codeimage-object = $(build)/codeimage-bin.o ifeq ($(bootimage),true) @@ -630,13 +626,16 @@ converter-depends = \ converter-sources = \ - $(src)/binaryToObject/main.cpp \ $(src)/binaryToObject/tools.cpp \ $(src)/binaryToObject/elf.cpp \ $(src)/binaryToObject/mach-o.cpp \ $(src)/binaryToObject/pe.cpp +converter-tool-sources = \ + $(src)/binaryToObject/main.cpp + converter-objects = $(call cpp-objects,$(converter-sources),$(src),$(build)) +converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build)) converter = $(build)/binaryToObject/binaryToObject static-library = $(build)/lib$(name).a @@ -707,6 +706,34 @@ ifeq ($(tails),true) extra.Tails endif +ifeq ($(target-arch),i386) + cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_X86 +endif + +ifeq ($(target-arch),x86_64) + cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_X86_64 +endif + +ifeq ($(target-arch),powerpc) + cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_POWERPC +endif + +ifeq ($(target-arch),arm) + cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_ARM +endif + +ifeq ($(target-platform),linux) + cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_LINUX +endif + +ifeq ($(target-platform),windows) + cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_WINDOWS +endif + +ifeq ($(target-platform),darwin) + cflags += -DAVIAN_TARGET_PLATFORM=AVIAN_PLATFORM_DARWIN +endif + class-name = $(patsubst $(1)/%.class,%,$(2)) class-names = $(foreach x,$(2),$(call class-name,$(1),$(x))) @@ -842,11 +869,11 @@ $(boot-object): $(boot-source) $(boot-javahome-object): $(src)/boot-javahome.cpp $(compile-object) -$(converter-objects): $(build)/binaryToObject/%.o: $(src)/binaryToObject/%.cpp $(converter-depends) +$(converter-objects) $(converter-tool-objects): $(build)/binaryToObject/%.o: $(src)/binaryToObject/%.cpp $(converter-depends) @mkdir -p $(dir $(@)) $(build-cxx) $(converter-cflags) -c $(<) -o $(@) -$(converter): $(converter-objects) +$(converter): $(converter-objects) $(converter-tool-objects) $(build-cc) $(^) -g -o $(@) $(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep) @@ -888,20 +915,8 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \ $(ar) cru $(@) $(^) $(ranlib) $(@) -$(bootimage-bin): $(bootimage-generator) - $(<) $(classpath-build) $(@) $(codeimage-bin) - -$(bootimage-object): $(bootimage-bin) $(converter) - @echo "creating $(@)" - $(converter) $(<) $(@) _binary_bootimage_bin_start \ - _binary_bootimage_bin_end $(platform) $(arch) $(pointer-size) \ - writable - -$(codeimage-object): $(bootimage-bin) $(converter) - @echo "creating $(@)" - $(converter) $(codeimage-bin) $(@) _binary_codeimage_bin_start \ - _binary_codeimage_bin_end $(platform) $(arch) $(pointer-size) \ - executable +$(bootimage-object) $(codeimage-object): $(bootimage-generator) + $(<) $(classpath-build) $(bootimage-object) $(codeimage-object) executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \ $(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \ @@ -924,10 +939,13 @@ else endif $(strip) $(strip-all) $(@) -$(bootimage-generator): +$(bootimage-generator): $(bootimage-generator-objects) + echo arch=$(arch) platform=$(platform) $(MAKE) mode=$(mode) \ arch=$(build-arch) \ + target-arch=$(arch) \ platform=$(bootimage-platform) \ + target-platform=$(platform) \ openjdk=$(openjdk) \ openjdk-src=$(openjdk-src) \ bootimage-generator= \ @@ -938,7 +956,7 @@ $(bootimage-generator): $(build-bootimage-generator): \ $(vm-objects) $(classpath-object) $(classpath-objects) \ - $(heapwalk-objects) $(bootimage-generator-objects) + $(heapwalk-objects) $(bootimage-generator-objects) $(converter-objects) @echo "linking $(@)" ifeq ($(platform),windows) ifdef msvc diff --git a/readme.txt b/readme.txt index 9b0c1d28e1..d0299875c3 100644 --- a/readme.txt +++ b/readme.txt @@ -568,19 +568,7 @@ Step 6: Build the boot and code images. $ ../build/linux-i386-bootimage/bootimage-generator stage2 \ bootimage.bin codeimage.bin -Step 7: Make an object file out of the boot and code images. - - $ ../build/linux-i386-bootimage/binaryToObject \ - bootimage.bin bootimage-bin.o \ - _binary_bootimage_bin_start _binary_bootimage_bin_end \ - linux i386 8 writable - - $ ../build/linux-i386-bootimage/binaryToObject \ - codeimage.bin codeimage-bin.o \ - _binary_codeimage_bin_start _binary_codeimage_bin_end \ - linux i386 8 executable - -Step 8: Write a driver which starts the VM and runs the desired main +Step 7: Write a driver which starts the VM and runs the desired main method. Note the bootimageBin function, which will be called by the VM to get a handle to the embedded boot image. We tell the VM about this function via the "avian.bootimage" property. diff --git a/src/binaryToObject/main.cpp b/src/binaryToObject/main.cpp index e9bc749abc..b7a35b90f4 100644 --- a/src/binaryToObject/main.cpp +++ b/src/binaryToObject/main.cpp @@ -18,9 +18,9 @@ #include #else #include +#include #endif #include -#include #include "tools.h" @@ -45,18 +45,17 @@ writeObject(uint8_t* data, size_t size, OutputStream* out, const char* startName const char* architecture, unsigned alignment, bool writable, bool executable) { - Platform* platform = Platform::getPlatform(PlatformInfo(os, architecture)); + Platform* platform = Platform::getPlatform(PlatformInfo(PlatformInfo::osFromString(os), PlatformInfo::archFromString(architecture))); if(!platform) { fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture); return false; } - SymbolInfo symbols[2]; - symbols[0].name = startName; - symbols[0].addr = 0; - symbols[1].name = endName; - symbols[1].addr = size; + SymbolInfo symbols[] = { + SymbolInfo(0, startName), + SymbolInfo(size, endName) + }; unsigned accessFlags = (writable ? Platform::Writable : 0) | (executable ? Platform::Executable : 0); diff --git a/src/binaryToObject/pe.cpp b/src/binaryToObject/pe.cpp index aab60feb90..ddad7b3bb6 100644 --- a/src/binaryToObject/pe.cpp +++ b/src/binaryToObject/pe.cpp @@ -121,9 +121,7 @@ public: void writeHeader(OutputStream* out) { header.NumberOfSections = sectionCount; header.PointerToSymbolTable = dataStart + dataOffset; - printf("symbol table start: 0x%x\n", header.PointerToSymbolTable); dataOffset = pad(dataOffset + symbolCount * sizeof(IMAGE_SYMBOL)); - printf("string table start: 0x%x\n", dataStart + dataOffset); header.NumberOfSymbols = symbolCount; out->writeChunk(&header, sizeof(IMAGE_FILE_HEADER)); } @@ -188,7 +186,6 @@ public: void writeHeader(OutputStream* out) { header.PointerToRawData = dataOffset + file.dataStart; - printf("section %s: data at 0x%x, ending at 0x%x\n", header.Name, header.PointerToRawData, header.PointerToRawData + header.SizeOfRawData); out->writeChunk(&header, sizeof(IMAGE_SECTION_HEADER)); } diff --git a/src/binaryToObject/tools.h b/src/binaryToObject/tools.h index bc3d1f4f19..999d010535 100644 --- a/src/binaryToObject/tools.h +++ b/src/binaryToObject/tools.h @@ -11,6 +11,9 @@ #ifndef AVIAN_TOOLS_H_ #define AVIAN_TOOLS_H_ +#include +#include "environment.h" + namespace avian { namespace tools { @@ -41,6 +44,10 @@ public: size_t length; String(const char* text); + + inline String(const char* text, size_t length): + text(text), + length(length) {} }; class SymbolInfo { @@ -84,6 +91,10 @@ public: items(items), count(count) {} + inline Slice(const Slice& copy): + items(copy.items), + count(copy.count) {} + inline T* begin() { return items; } @@ -93,14 +104,46 @@ public: } }; +template +class DynamicArray : public Slice { +public: + size_t capacity; + + DynamicArray(): + Slice((T*)malloc(10 * sizeof(T)), 0), + capacity(10) {} + ~DynamicArray() { + free(Slice::items); + } + + void ensure(size_t more) { + if(Slice::count + more > capacity) { + capacity = capacity * 2 + more; + Slice::items = (T*)realloc(Slice::items, capacity * sizeof(T)); + } +} + + void add(const T& item) { + ensure(1); + Slice::items[Slice::count++] = item; + } +}; + class PlatformInfo { public: enum OperatingSystem { - Linux, Windows, Darwin, UnknownOS + Linux = AVIAN_PLATFORM_LINUX, + Windows = AVIAN_PLATFORM_WINDOWS, + Darwin = AVIAN_PLATFORM_DARWIN, + UnknownOS = AVIAN_PLATFORM_UNKNOWN }; enum Architecture { - x86, x86_64, PowerPC, Arm, UnknownArch + x86 = AVIAN_ARCH_X86, + x86_64 = AVIAN_ARCH_X86_64, + PowerPC = AVIAN_ARCH_POWERPC, + Arm = AVIAN_ARCH_ARM, + UnknownArch = AVIAN_ARCH_UNKNOWN }; const OperatingSystem os; @@ -113,10 +156,6 @@ public: os(os), arch(arch) {} - inline PlatformInfo(const char* os, const char* arch): - os(osFromString(os)), - arch(archFromString(arch)) {} - inline bool operator == (const PlatformInfo& other) { return os == other.os && arch == other.arch; } diff --git a/src/bootimage.cpp b/src/bootimage.cpp index 3447dff69a..b4060ed9e7 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -16,12 +16,14 @@ #include "stream.h" #include "assembler.h" #include "target.h" +#include "binaryToObject/tools.h" // since we aren't linking against libstdc++, we must implement this // ourselves: extern "C" void __cxa_pure_virtual(void) { abort(); } using namespace vm; +using namespace avian::tools; namespace { @@ -1283,7 +1285,7 @@ targetThunk(BootImage::Thunk t) } void -writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput, +writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutput, BootImage* image, uint8_t* code, const char* className, const char* methodName, const char* methodSpec) { @@ -1292,6 +1294,31 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput, Zone zone(t->m->system, t->m->heap, 64 * 1024); + class MyCompilationHandler : public Processor::CompilationHandler { + public: + virtual void compiled(const void* code, unsigned size UNUSED, unsigned frameSize UNUSED, const char* class_, const char* name, const char* spec) { + size_t classLen = strlen(class_); + size_t nameLen = strlen(name); + size_t specLen = strlen(spec); + + char* completeName = (char*)malloc(classLen + nameLen + specLen + 2); + sprintf(completeName, "%s.%s%s", class_, name, spec); + uint64_t offset = reinterpret_cast(code) - codeOffset; + symbols.add(SymbolInfo(offset, completeName)); + // printf("%ld %ld %s.%s%s\n", offset, offset + size, class_, name, spec); + } + + virtual void dispose() {} + + DynamicArray symbols; + uint64_t codeOffset; + + MyCompilationHandler(uint64_t codeOffset): + codeOffset(codeOffset) {} + } compilationHandler(reinterpret_cast(code)); + + t->m->processor->addCompilationHandler(&compilationHandler); + object classPoolMap; object typeMaps; object constants; @@ -1578,6 +1605,8 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput, image->bootClassCount, image->stringCount, image->callCount, image->heapSize, image->codeSize); + Buffer bootimageData; + if (true) { { BootImage targetImage; @@ -1594,19 +1623,15 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput, #include "bootimage-fields.cpp" #undef THUNK_FIELD - fwrite(&targetImage, sizeof(BootImage), 1, bootimageOutput); + bootimageData.write(&targetImage, sizeof(BootImage)); } - fwrite(bootClassTable, image->bootClassCount * sizeof(unsigned), 1, - bootimageOutput); - fwrite(appClassTable, image->appClassCount * sizeof(unsigned), 1, - bootimageOutput); - fwrite(stringTable, image->stringCount * sizeof(unsigned), 1, - bootimageOutput); - fwrite(callTable, image->callCount * sizeof(unsigned) * 2, 1, - bootimageOutput); + bootimageData.write(bootClassTable, image->bootClassCount * sizeof(unsigned)); + bootimageData.write(appClassTable, image->appClassCount * sizeof(unsigned)); + bootimageData.write(stringTable, image->stringCount * sizeof(unsigned)); + bootimageData.write(callTable, image->callCount * sizeof(unsigned) * 2); - unsigned offset = sizeof(BootImage) + unsigned offset = sizeof(BootImage) + (image->bootClassCount * sizeof(unsigned)) + (image->appClassCount * sizeof(unsigned)) + (image->stringCount * sizeof(unsigned)) @@ -1614,24 +1639,46 @@ writeBootImage2(Thread* t, FILE* bootimageOutput, FILE* codeOutput, while (offset % TargetBytesPerWord) { uint8_t c = 0; - fwrite(&c, 1, 1, bootimageOutput); + bootimageData.write(&c, 1); ++ offset; } - fwrite(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord), 1, - bootimageOutput); + bootimageData.write(heapMap, pad(heapMapSize(image->heapSize), TargetBytesPerWord)); - fwrite(heap, pad(image->heapSize, TargetBytesPerWord), 1, bootimageOutput); + bootimageData.write(heap, pad(image->heapSize, TargetBytesPerWord)); - fwrite(code, pad(image->codeSize, TargetBytesPerWord), 1, codeOutput); + // fwrite(code, pad(image->codeSize, TargetBytesPerWord), 1, codeOutput); + + Platform* platform = Platform::getPlatform(PlatformInfo((PlatformInfo::OperatingSystem)AVIAN_TARGET_PLATFORM, (PlatformInfo::Architecture)AVIAN_TARGET_ARCH)); + + // if(!platform) { + // fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture); + // return false; + // } + + SymbolInfo bootimageSymbols[] = { + SymbolInfo(0, "_binary_bootimage_bin_start"), + SymbolInfo(bootimageData.length, "_binary_bootimage_bin_end") + }; + + platform->writeObject(bootimageOutput, Slice(bootimageSymbols, 2), Slice(bootimageData.data, bootimageData.length), Platform::Writable, TargetBytesPerWord); + + compilationHandler.symbols.add(SymbolInfo(0, strdup("_binary_codeimage_bin_start"))); + compilationHandler.symbols.add(SymbolInfo(image->codeSize, strdup("_binary_codeimage_bin_end"))); + + platform->writeObject(codeOutput, Slice(compilationHandler.symbols), Slice(code, image->codeSize), Platform::Executable, TargetBytesPerWord); + + for(SymbolInfo* sym = compilationHandler.symbols.begin(); sym != compilationHandler.symbols.end(); sym++) { + free(const_cast((const void*)sym->name.text)); + } } } uint64_t writeBootImage(Thread* t, uintptr_t* arguments) { - FILE* bootimageOutput = reinterpret_cast(arguments[0]); - FILE* codeOutput = reinterpret_cast(arguments[1]); + OutputStream* bootimageOutput = reinterpret_cast(arguments[0]); + OutputStream* codeOutput = reinterpret_cast(arguments[1]); BootImage* image = reinterpret_cast(arguments[2]); uint8_t* code = reinterpret_cast(arguments[3]); const char* className = reinterpret_cast(arguments[4]); @@ -1684,20 +1731,20 @@ main(int ac, const char** av) enter(t, Thread::ActiveState); enter(t, Thread::IdleState); - FILE* bootimageOutput = vm::fopen(av[2], "wb"); - if (bootimageOutput == 0) { + FileOutputStream bootimageOutput(av[2]); + if (!bootimageOutput.isValid()) { fprintf(stderr, "unable to open %s\n", av[2]); return -1; } - FILE* codeOutput = vm::fopen(av[3], "wb"); - if (codeOutput == 0) { + FileOutputStream codeOutput(av[3]); + if (!codeOutput.isValid()) { fprintf(stderr, "unable to open %s\n", av[3]); return -1; } - uintptr_t arguments[] = { reinterpret_cast(bootimageOutput), - reinterpret_cast(codeOutput), + uintptr_t arguments[] = { reinterpret_cast(&bootimageOutput), + reinterpret_cast(&codeOutput), reinterpret_cast(&image), reinterpret_cast(code), reinterpret_cast(ac > 4 ? av[4] : 0), @@ -1706,9 +1753,6 @@ main(int ac, const char** av) run(t, writeBootImage, arguments); - fclose(codeOutput); - fclose(bootimageOutput); - if (t->exception) { printTrace(t, t->exception); return -1; diff --git a/src/builtin.cpp b/src/builtin.cpp index 6988dcf8eb..e5cd6bfe07 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -332,7 +332,8 @@ extern "C" JNIEXPORT int64_t JNICALL Avian_sun_misc_Unsafe_allocateMemory (Thread* t, object, uintptr_t* arguments) { - void* p = malloc(arguments[1]); + int64_t size; memcpy(&size, arguments + 1, 8); + void* p = malloc(size); if (p) { return reinterpret_cast(p); } else { @@ -344,9 +345,9 @@ extern "C" JNIEXPORT void JNICALL Avian_sun_misc_Unsafe_freeMemory (Thread*, object, uintptr_t* arguments) { - void* p = reinterpret_cast(arguments[1]); + int64_t p; memcpy(&p, arguments + 1, 8); if (p) { - free(p); + free(reinterpret_cast(p)); } } diff --git a/src/compile.cpp b/src/compile.cpp index 6b1a63f414..0f7f73cbcf 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -6149,25 +6149,7 @@ FILE* compileLog = 0; void logCompile(MyThread* t, const void* code, unsigned size, const char* class_, - const char* name, const char* spec) -{ - static bool open = false; - if (not open) { - open = true; - const char* path = findProperty(t, "avian.jit.log"); - if (path) { - compileLog = vm::fopen(path, "wb"); - } else if (DebugCompile) { - compileLog = stderr; - } - } - - if (compileLog) { - fprintf(compileLog, "%p %p %s.%s%s\n", - code, static_cast(code) + size, - class_, name, spec); - } -} + const char* name, const char* spec); int resolveIpForwards(Context* context, int start, int end) @@ -8454,6 +8436,24 @@ processor(MyThread* t); void compileThunks(MyThread* t, FixedAllocator* allocator); +class CompilationHandlerList { +public: + CompilationHandlerList(CompilationHandlerList* next, Processor::CompilationHandler* handler): + next(next), + handler(handler) {} + + void dispose(Allocator* allocator) { + if(this) { + next->dispose(allocator); + handler->dispose(); + allocator->free(this, sizeof(*this)); + } + } + + CompilationHandlerList* next; + Processor::CompilationHandler* handler; +}; + class MyProcessor: public Processor { public: class Thunk { @@ -8497,7 +8497,8 @@ class MyProcessor: public Processor { FixedSizeOfArithmeticException), codeAllocator(s, 0, 0), callTableSize(0), - useNativeFeatures(useNativeFeatures) + useNativeFeatures(useNativeFeatures), + compilationHandlers(0) { thunkTable[compileMethodIndex] = voidPointer(local::compileMethod); thunkTable[compileVirtualMethodIndex] = voidPointer(compileVirtualMethod); @@ -8803,6 +8804,7 @@ class MyProcessor: public Processor { t->arch->release(); t->m->heap->free(t, sizeof(*t)); + } virtual void dispose() { @@ -8810,6 +8812,8 @@ class MyProcessor: public Processor { s->freeExecutable(codeAllocator.base, codeAllocator.capacity); } + compilationHandlers->dispose(allocator); + s->handleSegFault(0); allocator->free(this, sizeof(*this)); @@ -8906,6 +8910,10 @@ class MyProcessor: public Processor { codeAllocator.capacity = capacity; } + virtual void addCompilationHandler(CompilationHandler* handler) { + compilationHandlers = new(allocator->allocate(sizeof(CompilationHandlerList))) CompilationHandlerList(compilationHandlers, handler); + } + virtual void compileMethod(Thread* vmt, Zone* zone, object* constants, object* calls, DelayedPromise** addresses, object method, OffsetResolver* resolver) @@ -9061,8 +9069,36 @@ class MyProcessor: public Processor { unsigned callTableSize; bool useNativeFeatures; void* thunkTable[dummyIndex + 1]; + CompilationHandlerList* compilationHandlers; }; +void +logCompile(MyThread* t, const void* code, unsigned size, const char* class_, + const char* name, const char* spec) +{ + static bool open = false; + if (not open) { + open = true; + const char* path = findProperty(t, "avian.jit.log"); + if (path) { + compileLog = vm::fopen(path, "wb"); + } else if (DebugCompile) { + compileLog = stderr; + } + } + + if (compileLog) { + fprintf(compileLog, "%p %p %s.%s%s\n", + code, static_cast(code) + size, + class_, name, spec); + } + + MyProcessor* p = static_cast(t->m->processor); + for(CompilationHandlerList* h = p->compilationHandlers; h; h = h->next) { + h->handler->compiled(code, 0, 0, class_, name, spec); + } +} + void* compileMethod2(MyThread* t, void* ip) { diff --git a/src/environment.h b/src/environment.h new file mode 100644 index 0000000000..53a309057e --- /dev/null +++ b/src/environment.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2008-2011, 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 AVIAN_ENVIRONMENT_H +#define AVIAN_ENVIRONMENT_H + +#ifndef AVIAN_TARGET_PLATFORM +#error build system should have defined AVIAN_TARGET_PLATFORM +#endif + +#ifndef AVIAN_TARGET_ARCH +#error build system should have defined AVIAN_TARGET_ARCH +#endif + +#define AVIAN_PLATFORM_UNKNOWN 0 +#define AVIAN_PLATFORM_LINUX 1 +#define AVIAN_PLATFORM_WINDOWS 2 +#define AVIAN_PLATFORM_DARWIN 3 + +#define AVIAN_ARCH_UNKNOWN 0 +#define AVIAN_ARCH_X86 (1 << 8) +#define AVIAN_ARCH_X86_64 (2 << 8) +#define AVIAN_ARCH_ARM (3 << 8) +#define AVIAN_ARCH_POWERPC (4 << 8) + +#endif \ No newline at end of file diff --git a/src/interpret.cpp b/src/interpret.cpp index 57b2e9836b..439f4ca069 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -3067,6 +3067,10 @@ class MyProcessor: public Processor { abort(s); } + virtual void addCompilationHandler(CompilationHandler* handler) { + abort(s); + } + virtual void compileMethod(vm::Thread*, Zone*, object*, object*, DelayedPromise**, object, OffsetResolver*) { diff --git a/src/processor.h b/src/processor.h index 71defc268e..3794570b14 100644 --- a/src/processor.h +++ b/src/processor.h @@ -41,6 +41,13 @@ class Processor { virtual unsigned count() = 0; }; + class CompilationHandler { + public: + virtual void compiled(const void* code, unsigned size, unsigned frameSize, const char* class_, const char* name, const char* spec) = 0; + + virtual void dispose() = 0; + }; + virtual Thread* makeThread(Machine* m, object javaThread, Thread* parent) = 0; @@ -120,6 +127,9 @@ class Processor { virtual void initialize(BootImage* image, uint8_t* code, unsigned capacity) = 0; + virtual void + addCompilationHandler(CompilationHandler* handler) = 0; + virtual void compileMethod(Thread* t, Zone* zone, object* constants, object* calls, DelayedPromise** addresses, object method, diff --git a/src/x86.cpp b/src/x86.cpp index bd6c418417..89d6f5df25 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -8,6 +8,7 @@ There is NO WARRANTY for this software. See license.txt for details. */ +#include "environment.h" #include "assembler.h" #include "target.h" #include "vector.h" @@ -2816,7 +2817,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual unsigned frameFootprint(unsigned footprint) { -#ifdef TARGET_PLATFORM_WINDOWS +#if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS return max(footprint, StackAlignmentInWords); #else return max(footprint > argumentRegisterCount() ? @@ -2838,7 +2839,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual unsigned argumentRegisterCount() { -#ifdef TARGET_PLATFORM_WINDOWS +#if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS if (TargetBytesPerWord == 8) return 4; else #else if (TargetBytesPerWord == 8) return 6; else @@ -2849,7 +2850,7 @@ class MyArchitecture: public Assembler::Architecture { virtual int argumentRegister(unsigned index) { assert(&c, TargetBytesPerWord == 8); switch (index) { -#ifdef TARGET_PLATFORM_WINDOWS +#if AVIAN_TARGET_PLATFORM == AVIAN_PLATFORM_WINDOWS case 0: return rcx; case 1: