From 1d58541c872c3e5b63dd90586c6d40e807b9b889 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 11 Jun 2009 13:41:13 -0600 Subject: [PATCH 01/14] generate full memory dump on unhandled exception in windows.cpp --- src/windows.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/windows.cpp b/src/windows.cpp index 6487e5165b..300bcefc7b 100644 --- a/src/windows.cpp +++ b/src/windows.cpp @@ -772,7 +772,8 @@ struct MINIDUMP_USER_STREAM_INFORMATION; struct MINIDUMP_CALLBACK_INFORMATION; enum MINIDUMP_TYPE { - MiniDumpNormal = 0 + MiniDumpNormal = 0, + MiniDumpWithFullMemory = 2 }; typedef BOOL (*MiniDumpWriteDumpType) @@ -812,7 +813,7 @@ dump(LPEXCEPTION_POINTERS e, const char* directory) (GetCurrentProcess(), GetCurrentProcessId(), file, - MiniDumpNormal, + MiniDumpWithFullMemory, &exception, 0, 0); From 525318dabba835242514b0bc8574fb7d38f88d6e Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 11 Jun 2009 17:13:25 -0600 Subject: [PATCH 02/14] fix GC safety bug in builtin.cpp --- src/builtin.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/builtin.cpp b/src/builtin.cpp index a1280163d4..f4541036d4 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -27,6 +27,8 @@ search(Thread* t, object name, object (*op)(Thread*, object), bool replaceDots) { if (LIKELY(name)) { + PROTECT(t, name); + object n = makeByteArray(t, stringLength(t, name) + 1); char* s = reinterpret_cast(&byteArrayBody(t, n, 0)); stringChars(t, name, s); From e1c7504edabffbd33e30f281f36936d67f22d474 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 11 Jun 2009 17:14:54 -0600 Subject: [PATCH 03/14] attempt to flush the compile log (if any) before crashing in SegFaultHandler::handle --- src/compile.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 8b542d1874..5e4b523ba5 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -4183,24 +4183,25 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } } +FILE* compileLog = 0; + void logCompile(MyThread* t, const void* code, unsigned size, const char* class_, const char* name, const char* spec) { - static FILE* log = 0; static bool open = false; if (not open) { open = true; const char* path = findProperty(t, "avian.jit.log"); if (path) { - log = fopen(path, "wb"); + compileLog = fopen(path, "wb"); } else if (DebugCompile) { - log = stderr; + compileLog = stderr; } } - if (log) { - fprintf(log, "%p %p %s.%s%s\n", + if (compileLog) { + fprintf(compileLog, "%p %p %s.%s%s\n", code, static_cast(code) + size, class_, name, spec); } @@ -5872,6 +5873,11 @@ class SegFaultHandler: public System::SignalHandler { return true; } } + + if (compileLog) { + fflush(compileLog); + } + return false; } From 31976f585ae8b258a493b6b5da93f44ba87752e4 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 11 Jun 2009 17:23:02 -0600 Subject: [PATCH 04/14] add DebugAllocation option to heap.cpp to help detect allocation and deallocation errors --- src/heap.cpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/heap.cpp b/src/heap.cpp index f04d5de2c3..d0dd5e8d45 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -33,6 +33,7 @@ const bool Verbose = false; const bool Verbose2 = false; const bool Debug = false; const bool DebugFixies = false; +const bool DebugAllocation = false; #define ACQUIRE(x) MutexLock MAKE_NAME(monitorLock_) (x) @@ -1673,11 +1674,23 @@ void* tryAllocate(Context* c, unsigned size) { ACQUIRE(c->lock); + if (DebugAllocation) { + size = pad(size); + size += 2 * BytesPerWord; + } + if (size + c->count < c->limit) { void* p = c->system->tryAllocate(size); if (p) { c->count += size; - return p; + + if (DebugAllocation) { + static_cast(p)[0] = 0x22377322; + static_cast(p)[(size / BytesPerWord) - 1] = 0x22377322; + return static_cast(p) + 1; + } else { + return p; + } } } return 0; @@ -1687,6 +1700,20 @@ void free(Context* c, const void* p, unsigned size) { ACQUIRE(c->lock); expect(c->system, c->count >= size); + + if (DebugAllocation) { + memset(const_cast(p), 0xFE, size); + + size = pad(size); + + p = static_cast(p) - 1; + + expect(c->system, static_cast(p)[0] == 0x22377322); + + expect(c->system, static_cast(p) + [1 + (size / BytesPerWord)] == 0x22377322); + } + c->system->free(p); c->count -= size; } From a21f951e294294478764d5b23065db584c9a7926 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 12 Jun 2009 09:45:29 -0600 Subject: [PATCH 05/14] consider an instruction reachable if it has no predecessors (i.e. it's the first instruction --- src/compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler.cpp b/src/compiler.cpp index 1b9b95ca44..79cf2dacf6 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -2591,7 +2591,7 @@ unreachable(Event* event) for (Link* p = event->predecessors; p; p = p->nextPredecessor) { if (not p->predecessor->allExits()) return false; } - return true; + return event->predecessors != 0; } class ReturnEvent: public Event { From 7ed14948b9ff11aaed63fa692a5649fe9fe1e8aa Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 16 Jun 2009 13:41:31 -0600 Subject: [PATCH 06/14] re-initialize frame maps for exception handlers on every iteration of the frame map calculation loop This fixes incorrect frame map calcuation which may lead to crashes during garbage collection from an exception handler. --- src/compile.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 5e4b523ba5..947a2a9fe3 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -548,6 +548,7 @@ enum Event { IpEvent, MarkEvent, ClearEvent, + InitEvent, TraceEvent }; @@ -4388,6 +4389,14 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, clearBit(roots, i); } break; + case InitEvent: { + unsigned reference = context->eventLog.get2(eventIndex); + eventIndex += 2; + + uintptr_t* tableRoots = context->rootTable + (reference * mapSize); + memcpy(roots, tableRoots, mapSize * BytesPerWord); + } break; + case TraceEvent: { TraceElement* te; context->eventLog.get(eventIndex, &te, BytesPerWord); if (DebugFrameMaps) { @@ -4711,16 +4720,8 @@ compile(MyThread* t, Allocator* allocator, Context* context) uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))]; Frame frame2(&frame, stackMap); - uintptr_t* roots = context->rootTable - + (start * frameMapSizeInWords(t, context->method)); - - for (unsigned i = 0; i < localSize(t, context->method); ++ i) { - if (getBit(roots, i)) { - frame2.set(i, Frame::Object); - } else { - frame2.set(i, Frame::Integer); - } - } + context->eventLog.append(InitEvent); + context->eventLog.append2(start); for (unsigned i = 1; i < codeMaxStack(t, methodCode(t, context->method)); From c3c06e4e0e4e0d069991df97810ced7d82141719 Mon Sep 17 00:00:00 2001 From: Eric Scharff Date: Fri, 19 Jun 2009 13:43:57 -0600 Subject: [PATCH 07/14] Fix mac build Remove a compiler error by removing an unnecessary method --- classpath/java/util/LinkedList.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/classpath/java/util/LinkedList.java b/classpath/java/util/LinkedList.java index 657d245997..0fab004117 100644 --- a/classpath/java/util/LinkedList.java +++ b/classpath/java/util/LinkedList.java @@ -97,10 +97,6 @@ public class LinkedList implements List { return find(element) != null; } - public void addAll(Collection c) { - for (T t: c) add(t); - } - public boolean add(T element) { addLast(element); return true; From f4347dee707f0b6f742c2244dba943ba2779b06f Mon Sep 17 00:00:00 2001 From: Eric Scharff Date: Mon, 22 Jun 2009 16:25:13 -0600 Subject: [PATCH 08/14] Implement dummy JNI GetVersion --- src/jnienv.cpp | 9 +++++++++ src/machine.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/src/jnienv.cpp b/src/jnienv.cpp index d7e5ea0fdc..5139f09e58 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -97,6 +97,14 @@ GetEnv(Machine* m, Thread** t, jint version) } } +jsize JNICALL +GetVersion(Thread* t) +{ + ENTER(t, Thread::ActiveState); + + return JNI_VERSION_1_6; +} + jsize JNICALL GetStringLength(Thread* t, jstring s) { @@ -1893,6 +1901,7 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable) memset(envTable, 0, sizeof(JNIEnvVTable)); + envTable->GetVersion = ::GetVersion; envTable->GetStringLength = ::GetStringLength; envTable->GetStringChars = ::GetStringChars; envTable->ReleaseStringChars = ::ReleaseStringChars; diff --git a/src/machine.h b/src/machine.h index 9029811b05..942d92dd57 100644 --- a/src/machine.h +++ b/src/machine.h @@ -94,6 +94,10 @@ const unsigned CompiledFlag = 1 << 1; const unsigned ConstructorFlag = 1 << 2; const unsigned FastNative = 1 << 3; +#ifndef JNI_VERSION_1_6 +#define JNI_VERSION_1_6 0x00010006 +#endif + typedef Machine JavaVM; typedef Thread JNIEnv; From 3367ac88e3f89f550b23c22056dde4676167e2f0 Mon Sep 17 00:00:00 2001 From: jent Date: Wed, 1 Jul 2009 09:13:01 -0600 Subject: [PATCH 09/14] Added in code to support os.version for Windows/Linux/OSX The make file had to be modified to include the carbon framework in OSX --- classpath/java-lang.cpp | 30 ++++++++++++++++++++++++++++-- makefile | 2 +- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 8825b8ffa3..2e14da3430 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -7,7 +7,7 @@ There is NO WARRANTY for this software. See license.txt for details. */ - + #include "math.h" #include "stdlib.h" #include "sys/time.h" @@ -32,11 +32,13 @@ # define SO_PREFIX "" #else # define SO_PREFIX "lib" +#include "sys/utsname.h" #include "sys/wait.h" #endif #ifdef __APPLE__ # define SO_SUFFIX ".jnilib" +#include "Gestalt.h" #elif defined WIN32 # define SO_SUFFIX ".dll" #else @@ -349,6 +351,14 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name, r = e->NewStringUTF("\\"); } else if (strcmp(chars, "os.name") == 0) { r = e->NewStringUTF("Windows"); + } else if (strcmp(chars, "os.version") == 0) { + unsigned size = 32; + char buffer[size]; + OSVERSIONINFO OSversion; + OSversion.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); + ::GetVersionEx(&OSversion); + snprintf(buffer, size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion); + r = e->NewStringUTF(buffer); } else if (strcmp(chars, "java.io.tmpdir") == 0) { TCHAR buffer[MAX_PATH]; GetTempPath(MAX_PATH, buffer); @@ -367,11 +377,27 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name, r = e->NewStringUTF("Mac OS X"); #else r = e->NewStringUTF("Linux"); +#endif + } else if (strcmp(chars, "os.version") == 0) { +#ifdef __APPLE__ + unsigned size = 32; + char buffer[size]; + long minorVersion, majorVersion; + + Gestalt(gestaltSystemVersionMajor, &majorVersion); + Gestalt(gestaltSystemVersionMinor, &minorVersion); + + snprintf(buffer, size, "%lld.%lld", majorVersion, minorVersion); + r = e->NewStringUTF(buffer); +#else + struct utsname system_id; + uname(&system_id); + r = e->NewStringUTF(system_id.release); #endif } else if (strcmp(chars, "java.io.tmpdir") == 0) { r = e->NewStringUTF("/tmp"); } else if (strcmp(chars, "user.home") == 0) { - r = e->NewStringUTF(getenv("HOME")); + r = e->NewStringUTF(getenv("HOME")); } #endif diff --git a/makefile b/makefile index 59099aa323..14cd6196d5 100644 --- a/makefile +++ b/makefile @@ -123,7 +123,7 @@ endif ifeq ($(platform),darwin) build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src) - lflags = $(common-lflags) -ldl -framework CoreFoundation + lflags = $(common-lflags) -ldl -framework CoreFoundation -framework Carbon ifeq ($(bootimage),true) bootimage-lflags = -Wl,-segprot,__BOOT,rwx,rwx endif From 2639d94ebc410f3ba652178b5f55041e6870691f Mon Sep 17 00:00:00 2001 From: jent Date: Thu, 2 Jul 2009 02:24:25 -0600 Subject: [PATCH 10/14] Commented out changes to avian till I can figure out why I can compile using the deploy script, but no one else can --- classpath/java-lang.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 2e14da3430..df456844b4 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -38,7 +38,7 @@ #ifdef __APPLE__ # define SO_SUFFIX ".jnilib" -#include "Gestalt.h" +//#include "Gestalt.h" #elif defined WIN32 # define SO_SUFFIX ".dll" #else @@ -380,7 +380,7 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name, #endif } else if (strcmp(chars, "os.version") == 0) { #ifdef __APPLE__ - unsigned size = 32; +/* unsigned size = 32; char buffer[size]; long minorVersion, majorVersion; @@ -388,7 +388,8 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name, Gestalt(gestaltSystemVersionMinor, &minorVersion); snprintf(buffer, size, "%lld.%lld", majorVersion, minorVersion); - r = e->NewStringUTF(buffer); + r = e->NewStringUTF(buffer);*/ + r = e->NewStringUTF("I hate OSX"); #else struct utsname system_id; uname(&system_id); From 8c3d65a83512f452a05d635adc56ced7525458ea Mon Sep 17 00:00:00 2001 From: jent Date: Thu, 2 Jul 2009 03:13:39 -0600 Subject: [PATCH 11/14] Hopefully including the top carbon header will fix the issues we had when we tried to include just Gestalt.h --- classpath/java-lang.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index df456844b4..c9f7142fd8 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -38,7 +38,7 @@ #ifdef __APPLE__ # define SO_SUFFIX ".jnilib" -//#include "Gestalt.h" +#include #elif defined WIN32 # define SO_SUFFIX ".dll" #else @@ -380,16 +380,15 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name, #endif } else if (strcmp(chars, "os.version") == 0) { #ifdef __APPLE__ -/* unsigned size = 32; + unsigned size = 32; char buffer[size]; long minorVersion, majorVersion; Gestalt(gestaltSystemVersionMajor, &majorVersion); Gestalt(gestaltSystemVersionMinor, &minorVersion); - snprintf(buffer, size, "%lld.%lld", majorVersion, minorVersion); - r = e->NewStringUTF(buffer);*/ - r = e->NewStringUTF("I hate OSX"); + snprintf(buffer, size, "%ld.%ld", majorVersion, minorVersion); + r = e->NewStringUTF(buffer); #else struct utsname system_id; uname(&system_id); From 8335dc429793c8211bf96aa48aa7e0642aae4c0d Mon Sep 17 00:00:00 2001 From: jent Date: Thu, 2 Jul 2009 03:30:05 -0600 Subject: [PATCH 12/14] Now using the CoreServices instead of the Carbon framework....this allows for cocoa and future compatability --- classpath/java-lang.cpp | 2 +- makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index c9f7142fd8..514bfc40e1 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -38,7 +38,7 @@ #ifdef __APPLE__ # define SO_SUFFIX ".jnilib" -#include +#include #elif defined WIN32 # define SO_SUFFIX ".dll" #else diff --git a/makefile b/makefile index 14cd6196d5..583d0fdb90 100644 --- a/makefile +++ b/makefile @@ -123,7 +123,7 @@ endif ifeq ($(platform),darwin) build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src) - lflags = $(common-lflags) -ldl -framework CoreFoundation -framework Carbon + lflags = $(common-lflags) -ldl -framework CoreFoundation -framework CoreServices ifeq ($(bootimage),true) bootimage-lflags = -Wl,-segprot,__BOOT,rwx,rwx endif From 22852dcffa665b890f7430409abb9709c4e10ca7 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 10 Jul 2009 08:33:38 -0600 Subject: [PATCH 13/14] fix GC safety bug when walking stack --- src/compile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compile.cpp b/src/compile.cpp index 947a2a9fe3..ee41dd9cb7 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -271,7 +271,7 @@ class MyStackWalker: public Processor::StackWalker { virtual void walk(Processor::StackVisitor* v) { for (MyStackWalker it(this); it.valid();) { - MyStackWalker walker(it); + MyStackWalker walker(&it); if (not v->visit(&walker)) { break; } From 30c7107aa372818425b8b13d04e58d8db6b5f49e Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 10 Jul 2009 08:42:56 -0600 Subject: [PATCH 14/14] enable DebugAllocation in heap.cpp when NDEBUG is not defined --- src/heap.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/heap.cpp b/src/heap.cpp index d0dd5e8d45..5ec5ae724d 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -33,7 +33,12 @@ const bool Verbose = false; const bool Verbose2 = false; const bool Debug = false; const bool DebugFixies = false; + +#ifdef NDEBUG const bool DebugAllocation = false; +#else +const bool DebugAllocation = true; +#endif #define ACQUIRE(x) MutexLock MAKE_NAME(monitorLock_) (x) @@ -423,7 +428,9 @@ class Segment { } void dispose() { - free(context, data, (footprint(capacity())) * BytesPerWord); + if (data) { + free(context, data, (footprint(capacity())) * BytesPerWord); + } data = 0; map = 0; } @@ -1675,8 +1682,7 @@ void* tryAllocate(Context* c, unsigned size) ACQUIRE(c->lock); if (DebugAllocation) { - size = pad(size); - size += 2 * BytesPerWord; + size = pad(size) + 2 * BytesPerWord; } if (size + c->count < c->limit) { @@ -1699,21 +1705,21 @@ void* tryAllocate(Context* c, unsigned size) void free(Context* c, const void* p, unsigned size) { ACQUIRE(c->lock); - expect(c->system, c->count >= size); - if (DebugAllocation) { - memset(const_cast(p), 0xFE, size); + size = pad(size) + 2 * BytesPerWord; - size = pad(size); + memset(const_cast(p), 0xFE, size - (2 * BytesPerWord)); p = static_cast(p) - 1; expect(c->system, static_cast(p)[0] == 0x22377322); expect(c->system, static_cast(p) - [1 + (size / BytesPerWord)] == 0x22377322); + [(size / BytesPerWord) - 1] == 0x22377322); } + expect(c->system, c->count >= size); + c->system->free(p); c->count -= size; }