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

This commit is contained in:
jet 2009-08-27 15:32:11 -06:00
commit ae377e8fc6
26 changed files with 1249 additions and 575 deletions

View File

@ -14,28 +14,39 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <dirent.h>
#include "jni.h" #include "jni.h"
#include "jni-util.h" #include "jni-util.h"
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
# include <windows.h> # include <windows.h>
# include <io.h> # include <io.h>
# include <direct.h> # include <direct.h>
# include <share.h>
# define OPEN _open
# define CLOSE _close # define CLOSE _close
# define READ _read # define READ _read
# define WRITE _write # define WRITE _write
# define STAT _stat # define STAT _stat
# define STRUCT_STAT struct _stat # define STRUCT_STAT struct _stat
# define MKDIR(path, mode) _mkdir(path) # define MKDIR(path, mode) _mkdir(path)
# define CREAT _creat
# define UNLINK _unlink # define UNLINK _unlink
# define OPEN_MASK O_BINARY # define OPEN_MASK O_BINARY
#else
# ifdef _MSC_VER
# define S_ISREG(x) ((x) | _S_IFREG)
# define S_ISDIR(x) ((x) | _S_IFDIR)
# define S_IRUSR _S_IREAD
# define S_IWUSR _S_IWRITE
# else
# define OPEN _open
# define CREAT _creat
# endif
#else // not PLATFORM_WINDOWS
# include <dirent.h>
# include <unistd.h> # include <unistd.h>
# include "sys/mman.h" # include "sys/mman.h"
@ -49,12 +60,32 @@
# define CREAT creat # define CREAT creat
# define UNLINK unlink # define UNLINK unlink
# define OPEN_MASK 0 # define OPEN_MASK 0
#endif
#endif // not PLATFORM_WINDOWS
inline void* operator new(size_t, void* p) throw() { return p; } inline void* operator new(size_t, void* p) throw() { return p; }
namespace { namespace {
#ifdef _MSC_VER
inline int
OPEN(const char* path, int mask, int mode)
{
int fd;
if (_sopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) {
return fd;
} else {
return -1;
}
}
inline int
CREAT(const char* path, int mode)
{
return OPEN(path, _O_CREAT, mode);
}
#endif
inline bool inline bool
exists(const char* path) exists(const char* path)
{ {
@ -68,9 +99,9 @@ doOpen(JNIEnv* e, const char* path, int mask)
int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR); int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR);
if (fd == -1) { if (fd == -1) {
if (errno == ENOENT) { if (errno == ENOENT) {
throwNew(e, "java/io/FileNotFoundException", strerror(errno)); throwNewErrno(e, "java/io/FileNotFoundException");
} else { } else {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} }
} }
return fd; return fd;
@ -81,7 +112,7 @@ doClose(JNIEnv* e, jint fd)
{ {
int r = CLOSE(fd); int r = CLOSE(fd);
if (r == -1) { if (r == -1) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} }
} }
@ -94,7 +125,7 @@ doRead(JNIEnv* e, jint fd, jbyte* data, jint length)
} else if (r == 0) { } else if (r == 0) {
return -1; return -1;
} else { } else {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
return 0; return 0;
} }
} }
@ -104,11 +135,11 @@ doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length)
{ {
int r = WRITE(fd, data, length); int r = WRITE(fd, data, length);
if (r != length) { if (r != length) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} }
} }
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
class Mapping { class Mapping {
public: public:
@ -170,7 +201,37 @@ unmap(JNIEnv*, Mapping* mapping)
free(mapping); free(mapping);
} }
#else // not WIN32 class Directory {
public:
Directory(): handle(0), findNext(false) { }
virtual const char* next() {
if (handle and handle != INVALID_HANDLE_VALUE) {
if (findNext) {
if (FindNextFile(handle, &data)) {
return data.cFileName;
}
} else {
findNext = true;
return data.cFileName;
}
}
return 0;
}
virtual void dispose() {
if (handle and handle != INVALID_HANDLE_VALUE) {
FindClose(handle);
}
free(this);
}
HANDLE handle;
WIN32_FIND_DATA data;
bool findNext;
};
#else // not PLATFORM_WINDOWS
class Mapping { class Mapping {
public: public:
@ -203,7 +264,7 @@ map(JNIEnv* e, const char* path)
close(fd); close(fd);
} }
if (result == 0 and not e->ExceptionOccurred()) { if (result == 0 and not e->ExceptionOccurred()) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} }
return result; return result;
} }
@ -215,7 +276,7 @@ unmap(JNIEnv*, Mapping* mapping)
free(mapping); free(mapping);
} }
#endif // not WIN32 #endif // not PLATFORM_WINDOWS
} // namespace } // namespace
@ -257,7 +318,7 @@ Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
if (not exists(chars)) { if (not exists(chars)) {
int r = ::MKDIR(chars, 0700); int r = ::MKDIR(chars, 0700);
if (r != 0) { if (r != 0) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} }
} }
e->ReleaseStringUTFChars(path, chars); e->ReleaseStringUTFChars(path, chars);
@ -272,7 +333,7 @@ Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
if (not exists(chars)) { if (not exists(chars)) {
int fd = CREAT(chars, 0600); int fd = CREAT(chars, 0600);
if (fd == -1) { if (fd == -1) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} else { } else {
doClose(e, fd); doClose(e, fd);
} }
@ -288,7 +349,7 @@ Java_java_io_File_delete(JNIEnv* e, jclass, jstring path)
if (chars) { if (chars) {
int r = UNLINK(chars); int r = UNLINK(chars);
if (r != 0) { if (r != 0) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} }
e->ReleaseStringUTFChars(path, chars); e->ReleaseStringUTFChars(path, chars);
} }
@ -337,6 +398,48 @@ Java_java_io_File_exists(JNIEnv* e, jclass, jstring path)
} }
} }
#ifdef PLATFORM_WINDOWS
extern "C" JNIEXPORT jlong JNICALL
Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
{
const char* chars = e->GetStringUTFChars(path, 0);
if (chars) {
Directory* d = new (malloc(sizeof(Directory))) Directory;
d->handle = FindFirstFile(chars, &(d->data));
if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose();
d = 0;
}
e->ReleaseStringUTFChars(path, chars);
return reinterpret_cast<jlong>(d);
} else {
return 0;
}
}
extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
{
Directory* d = reinterpret_cast<Directory*>(handle);
const char* s = d->next();
if (s) {
return e->NewStringUTF(s);
} else {
return 0;
}
}
extern "C" JNIEXPORT void JNICALL
Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle)
{
reinterpret_cast<Directory*>(handle)->dispose();
}
#else // not PLATFORM_WINDOWS
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path) Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
{ {
@ -373,6 +476,8 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle)
} }
} }
#endif // not PLATFORM_WINDOWS
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path) Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path)
{ {

View File

@ -10,44 +10,56 @@
#include "math.h" #include "math.h"
#include "stdlib.h" #include "stdlib.h"
#include "sys/time.h"
#include "time.h" #include "time.h"
#include "time.h" #include "time.h"
#include "string.h" #include "string.h"
#include "stdio.h" #include "stdio.h"
#include "stdint.h"
#include "jni.h" #include "jni.h"
#include "jni-util.h" #include "jni-util.h"
#include "errno.h" #include "errno.h"
#include "fcntl.h" #include "fcntl.h"
#include "unistd.h"
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
# include "windows.h" # include "windows.h"
# include "winbase.h" # include "winbase.h"
# include "io.h" # include "io.h"
# include "tchar.h" # include "tchar.h"
# include "float.h"
# include "sys/types.h" # include "sys/types.h"
# include "sys/timeb.h" # include "sys/timeb.h"
# define SO_PREFIX "" # define SO_PREFIX ""
#else
# define SO_PREFIX "lib"
#include <sys/sysctl.h>
#include "sys/utsname.h"
#include "sys/wait.h"
#endif
#ifdef __APPLE__
# define SO_SUFFIX ".jnilib"
#include <CoreServices/CoreServices.h>
#elif defined WIN32
# define SO_SUFFIX ".dll" # define SO_SUFFIX ".dll"
#else
# define SO_SUFFIX ".so" # ifdef _MSC_VER
#endif # define snprintf sprintf_s
# define isnan _isnan
# define isfinite _finite
# define strtof strtod
# define FTIME _ftime_s
# else
# define FTIME _ftime
# endif
#else // not PLATFORM_WINDOWS
# define SO_PREFIX "lib"
# ifdef __APPLE__
# define SO_SUFFIX ".jnilib"
# include <CoreServices/CoreServices.h>
# else
# define SO_SUFFIX ".so"
# endif
# include "unistd.h"
# include "sys/time.h"
# include "sys/sysctl.h"
# include "sys/utsname.h"
# include "sys/wait.h"
#endif // not PLATFORM_WINDOWS
namespace { namespace {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
char* getErrorStr(DWORD err){ char* getErrorStr(DWORD err){
// The poor man's error string, just print the error code // The poor man's error string, just print the error code
char * errStr = (char*) malloc(9 * sizeof(char)); char * errStr = (char*) malloc(9 * sizeof(char));
@ -84,7 +96,7 @@ namespace {
{ {
int fd = _open_osfhandle(reinterpret_cast<intptr_t>(h), 0); int fd = _open_osfhandle(reinterpret_cast<intptr_t>(h), 0);
if (fd == -1) { if (fd == -1) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} }
return fd; return fd;
} }
@ -92,7 +104,7 @@ namespace {
void makePipe(JNIEnv* e, int p[2]) void makePipe(JNIEnv* e, int p[2])
{ {
if(pipe(p) != 0) { if(pipe(p) != 0) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
} }
} }
@ -120,7 +132,7 @@ namespace {
#endif #endif
} }
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_exec(JNIEnv* e, jclass, Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
jobjectArray command, jlongArray process) jobjectArray command, jlongArray process)
@ -132,13 +144,17 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
size += e->GetStringUTFLength(element) + 1; size += e->GetStringUTFLength(element) + 1;
} }
char line[size]; RUNTIME_ARRAY(char, line, size);
char* linep = line; char* linep = RUNTIME_ARRAY_BODY(line);
for (int i = 0; i < e->GetArrayLength(command); ++i) { for (int i = 0; i < e->GetArrayLength(command); ++i) {
if (i) *(linep++) = _T(' '); if (i) *(linep++) = _T(' ');
jstring element = (jstring) e->GetObjectArrayElement(command, i); jstring element = (jstring) e->GetObjectArrayElement(command, i);
const char* s = e->GetStringUTFChars(element, 0); const char* s = e->GetStringUTFChars(element, 0);
#ifdef _MSC_VER
_tcscpy_s(linep, size - (linep - RUNTIME_ARRAY_BODY(line)), s);
#else
_tcscpy(linep, s); _tcscpy(linep, s);
#endif
e->ReleaseStringUTFChars(element, s); e->ReleaseStringUTFChars(element, s);
linep += e->GetStringUTFLength(element); linep += e->GetStringUTFLength(element);
} }
@ -175,7 +191,7 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
si.hStdInput = out[0]; si.hStdInput = out[0];
si.hStdError = err[1]; si.hStdError = err[1];
BOOL success = CreateProcess(0, (LPSTR) line, 0, 0, 1, BOOL success = CreateProcess(0, (LPSTR) RUNTIME_ARRAY_BODY(line), 0, 0, 1,
CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
0, 0, &si, &pi); 0, 0, &si, &pi);
@ -247,14 +263,14 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
makePipe(e, msg); makePipe(e, msg);
if(e->ExceptionOccurred()) return; if(e->ExceptionOccurred()) return;
if(fcntl(msg[1], F_SETFD, FD_CLOEXEC) != 0) { if(fcntl(msg[1], F_SETFD, FD_CLOEXEC) != 0) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
return; return;
} }
pid_t pid = fork(); pid_t pid = fork();
switch(pid){ switch(pid){
case -1: // error case -1: // error
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
return; return;
case 0: { // child case 0: { // child
// Setup stdin, stdout and stderr // Setup stdin, stdout and stderr
@ -286,10 +302,10 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
char c; char c;
int r = read(msg[0], &c, 1); int r = read(msg[0], &c, 1);
if(r == -1) { if(r == -1) {
throwNew(e, "java/io/IOException", strerror(errno)); throwNewErrno(e, "java/io/IOException");
return; return;
} else if(r) { } else if(r) {
throwNew(e, "java/io/IOException", strerror(c)); throwNewErrno(e, "java/io/IOException");
return; return;
} }
} break; } break;
@ -309,9 +325,9 @@ Java_java_lang_Runtime_exitValue(JNIEnv* e, jclass, jlong pid)
int status; int status;
pid_t returned = waitpid(pid, &status, WNOHANG); pid_t returned = waitpid(pid, &status, WNOHANG);
if(returned == 0){ if(returned == 0){
throwNew(e, "java/lang/IllegalThreadStateException", strerror(errno)); throwNewErrno(e, "java/lang/IllegalThreadStateException");
} else if(returned == -1){ } else if(returned == -1){
throwNew(e, "java/lang/Exception", strerror(errno)); throwNewErrno(e, "java/lang/Exception");
} }
return WEXITSTATUS(status); return WEXITSTATUS(status);
@ -345,7 +361,7 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
jstring r = 0; jstring r = 0;
const char* chars = e->GetStringUTFChars(name, 0); const char* chars = e->GetStringUTFChars(name, 0);
if (chars) { if (chars) {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
if (strcmp(chars, "line.separator") == 0) { if (strcmp(chars, "line.separator") == 0) {
r = e->NewStringUTF("\r\n"); r = e->NewStringUTF("\r\n");
} else if (strcmp(chars, "file.separator") == 0) { } else if (strcmp(chars, "file.separator") == 0) {
@ -354,49 +370,38 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
r = e->NewStringUTF("Windows"); r = e->NewStringUTF("Windows");
} else if (strcmp(chars, "os.version") == 0) { } else if (strcmp(chars, "os.version") == 0) {
unsigned size = 32; unsigned size = 32;
char buffer[size]; RUNTIME_ARRAY(char, buffer, size);
OSVERSIONINFO OSversion; OSVERSIONINFO OSversion;
OSversion.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); OSversion.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
::GetVersionEx(&OSversion); ::GetVersionEx(&OSversion);
snprintf(buffer, size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion); snprintf(RUNTIME_ARRAY_BODY(buffer), size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion);
r = e->NewStringUTF(buffer); r = e->NewStringUTF(RUNTIME_ARRAY_BODY(buffer));
} else if (strcmp(chars, "os.arch") == 0) { } else if (strcmp(chars, "os.arch") == 0) {
#ifdef __i386__ #ifdef ARCH_x86_32
r = e->NewStringUTF("x86"); r = e->NewStringUTF("x86");
#else #elif defined ARCH_x86_64
#ifdef __x86_64__ r = e->NewStringUTF("x86_64");
r = e->NewStringUTF("x86_64"); #elif defined ARCH_powerpc
#else r = e->NewStringUTF("ppc");
#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__) #elif defined ARCH_arm
r = e->NewStringUTF("ppc"); r = e->NewStringUTF("arm");
#else #endif
#ifdef __ia64__
r = e->NewStringUTF("ia64");
#else
#ifdef __arm__
r = e->NewStringUTF("arm");
#else
#ifdef __alpha__
r = e->NewStringUTF("alpha");
#else
#ifdef __sparc64__
r = e->NewStringUTF("sparc64");
#else
r = e->NewStringUTF("unknown");
#endif
#endif
#endif
#endif
#endif
#endif
#endif
} else if (strcmp(chars, "java.io.tmpdir") == 0) { } else if (strcmp(chars, "java.io.tmpdir") == 0) {
TCHAR buffer[MAX_PATH]; TCHAR buffer[MAX_PATH];
GetTempPath(MAX_PATH, buffer); GetTempPath(MAX_PATH, buffer);
r = e->NewStringUTF(buffer); r = e->NewStringUTF(buffer);
} else if (strcmp(chars, "user.home") == 0) { } else if (strcmp(chars, "user.home") == 0) {
# ifdef _MSC_VER
WCHAR buffer[MAX_PATH];
if (_wgetenv_s(0, buffer, MAX_PATH, L"USERPROFILE") == 0) {
r = e->NewString(reinterpret_cast<jchar*>(buffer), lstrlenW(buffer));
} else {
r = 0;
}
# else
LPWSTR home = _wgetenv(L"USERPROFILE"); LPWSTR home = _wgetenv(L"USERPROFILE");
r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home)); r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
# endif
} }
#else #else
if (strcmp(chars, "line.separator") == 0) { if (strcmp(chars, "line.separator") == 0) {
@ -426,35 +431,15 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
r = e->NewStringUTF(system_id.release); r = e->NewStringUTF(system_id.release);
#endif #endif
} else if (strcmp(chars, "os.arch") == 0) { } else if (strcmp(chars, "os.arch") == 0) {
#ifdef __i386__ #ifdef ARCH_x86_32
r = e->NewStringUTF("x86"); r = e->NewStringUTF("x86");
#else #elif defined ARCH_x86_64
#ifdef __x86_64__ r = e->NewStringUTF("x86_64");
r = e->NewStringUTF("x86_64"); #elif defined ARCH_powerpc
#else r = e->NewStringUTF("ppc");
#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__) #elif defined ARCH_arm
r = e->NewStringUTF("ppc"); r = e->NewStringUTF("arm");
#else #endif
#ifdef __ia64__
r = e->NewStringUTF("ia64");
#else
#ifdef __arm__
r = e->NewStringUTF("arm");
#else
#ifdef __alpha__
r = e->NewStringUTF("alpha");
#else
#ifdef __sparc64__
r = e->NewStringUTF("sparc64");
#else
r = e->NewStringUTF("unknown");
#endif
#endif
#endif
#endif
#endif
#endif
#endif
} else if (strcmp(chars, "java.io.tmpdir") == 0) { } else if (strcmp(chars, "java.io.tmpdir") == 0) {
r = e->NewStringUTF("/tmp"); r = e->NewStringUTF("/tmp");
} else if (strcmp(chars, "user.home") == 0) { } else if (strcmp(chars, "user.home") == 0) {
@ -476,9 +461,9 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass) Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
{ {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
_timeb tb; _timeb tb;
_ftime(&tb); FTIME(&tb);
return (static_cast<jlong>(tb.time) * 1000) + static_cast<jlong>(tb.millitm); return (static_cast<jlong>(tb.time) * 1000) + static_cast<jlong>(tb.millitm);
#else #else
timeval tv = { 0, 0 }; timeval tv = { 0, 0 };
@ -496,9 +481,10 @@ Java_java_lang_System_doMapLibraryName(JNIEnv* e, jclass, jstring name)
if (chars) { if (chars) {
unsigned nameLength = strlen(chars); unsigned nameLength = strlen(chars);
unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX); unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX);
char buffer[size]; RUNTIME_ARRAY(char, buffer, size);
snprintf(buffer, size, SO_PREFIX "%s" SO_SUFFIX, chars); snprintf
r = e->NewStringUTF(buffer); (RUNTIME_ARRAY_BODY(buffer), size, SO_PREFIX "%s" SO_SUFFIX, chars);
r = e->NewStringUTF(RUNTIME_ARRAY_BODY(buffer));
e->ReleaseStringUTFChars(name, chars); e->ReleaseStringUTFChars(name, chars);
} }

View File

@ -12,16 +12,20 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include "jni.h" #include "jni.h"
#include "jni-util.h" #include "jni-util.h"
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
# include <winsock2.h> # include <winsock2.h>
# include <errno.h> # include <errno.h>
# ifdef _MSC_VER
# define snprintf sprintf_s
# else
# include <unistd.h>
# endif
#else #else
# include <unistd.h>
# include <fcntl.h> # include <fcntl.h>
# include <errno.h> # include <errno.h>
# include <netdb.h> # include <netdb.h>
@ -34,7 +38,7 @@
#define java_nio_channels_SelectionKey_OP_WRITE 4L #define java_nio_channels_SelectionKey_OP_WRITE 4L
#define java_nio_channels_SelectionKey_OP_ACCEPT 16L #define java_nio_channels_SelectionKey_OP_ACCEPT 16L
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
typedef int socklen_t; typedef int socklen_t;
#endif #endif
@ -51,16 +55,31 @@ charsToArray(JNIEnv* e, const char* s)
return a; return a;
} }
#ifdef _MSC_VER
inline void
close(int socket)
{
closesocket(socket);
}
#endif
inline jbyteArray inline jbyteArray
errorString(JNIEnv* e, int n) errorString(JNIEnv* e, int n)
{ {
#ifdef _MSC_VER
const unsigned size = 128;
char buffer[size];
strerror_s(buffer, size, n);
return charsToArray(e, buffer);
#else
return charsToArray(e, strerror(n)); return charsToArray(e, strerror(n));
#endif
} }
inline jbyteArray inline jbyteArray
errorString(JNIEnv* e) errorString(JNIEnv* e)
{ {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
const unsigned size = 64; const unsigned size = 64;
char buffer[size]; char buffer[size];
snprintf(buffer, size, "wsa code: %d", WSAGetLastError()); snprintf(buffer, size, "wsa code: %d", WSAGetLastError());
@ -118,7 +137,7 @@ init(JNIEnv* e, sockaddr_in* address, jstring hostString, jint port)
hostent* host = gethostbyname(chars); hostent* host = gethostbyname(chars);
e->ReleaseStringUTFChars(hostString, chars); e->ReleaseStringUTFChars(hostString, chars);
if (host == 0) { if (host == 0) {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
throwIOException(e); throwIOException(e);
#else #else
throwIOException(e, hstrerror(h_errno)); throwIOException(e, hstrerror(h_errno));
@ -135,7 +154,7 @@ init(JNIEnv* e, sockaddr_in* address, jstring hostString, jint port)
inline bool inline bool
einProgress() einProgress()
{ {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
return WSAGetLastError() == WSAEINPROGRESS return WSAGetLastError() == WSAEINPROGRESS
or WSAGetLastError() == WSAEWOULDBLOCK; or WSAGetLastError() == WSAEWOULDBLOCK;
#else #else
@ -146,7 +165,7 @@ einProgress()
inline bool inline bool
eagain() eagain()
{ {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
return WSAGetLastError() == WSAEINPROGRESS return WSAGetLastError() == WSAEINPROGRESS
or WSAGetLastError() == WSAEWOULDBLOCK; or WSAGetLastError() == WSAEWOULDBLOCK;
#else #else
@ -157,7 +176,7 @@ eagain()
bool bool
setBlocking(JNIEnv* e, int d, bool blocking) setBlocking(JNIEnv* e, int d, bool blocking)
{ {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
u_long a = (blocking ? 0 : 1); u_long a = (blocking ? 0 : 1);
int r = ioctlsocket(d, FIONBIO, &a); int r = ioctlsocket(d, FIONBIO, &a);
if (r != 0) { if (r != 0) {
@ -244,7 +263,7 @@ doAccept(JNIEnv* e, int s)
int int
doRead(int fd, void* buffer, size_t count) doRead(int fd, void* buffer, size_t count)
{ {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
return recv(fd, static_cast<char*>(buffer), count, 0); return recv(fd, static_cast<char*>(buffer), count, 0);
#else #else
return read(fd, buffer, count); return read(fd, buffer, count);
@ -254,7 +273,7 @@ doRead(int fd, void* buffer, size_t count)
int int
doWrite(int fd, const void* buffer, size_t count) doWrite(int fd, const void* buffer, size_t count)
{ {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
return send(fd, static_cast<const char*>(buffer), count, 0); return send(fd, static_cast<const char*>(buffer), count, 0);
#else #else
return write(fd, buffer, count); return write(fd, buffer, count);
@ -264,7 +283,7 @@ doWrite(int fd, const void* buffer, size_t count)
int int
makeSocket(JNIEnv* e) makeSocket(JNIEnv* e)
{ {
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
static bool wsaInitialized = false; static bool wsaInitialized = false;
if (not wsaInitialized) { if (not wsaInitialized) {
WSADATA data; WSADATA data;
@ -427,7 +446,7 @@ namespace {
class Pipe { class Pipe {
public: public:
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
// The Windows socket API only accepts socket file descriptors, not // The Windows socket API only accepts socket file descriptors, not
// pipe descriptors or others. Thus, to implement // pipe descriptors or others. Thus, to implement
// Selector.wakeup(), we make a socket connection via the loopback // Selector.wakeup(), we make a socket connection via the loopback
@ -625,7 +644,7 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
if (max < socket) max = socket; if (max < socket) max = socket;
} }
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
if (s->control.listener() >= 0) { if (s->control.listener() >= 0) {
int socket = s->control.listener(); int socket = s->control.listener();
FD_SET(static_cast<unsigned>(socket), &(s->read)); FD_SET(static_cast<unsigned>(socket), &(s->read));
@ -660,7 +679,7 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
} }
} }
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
if (FD_ISSET(s->control.writer(), &(s->write)) or if (FD_ISSET(s->control.writer(), &(s->write)) or
FD_ISSET(s->control.writer(), &(s->except))) FD_ISSET(s->control.writer(), &(s->except)))
{ {

View File

@ -30,17 +30,24 @@ removeNewline(char* s)
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jstring JNICALL
Java_java_util_Date_toString(JNIEnv* e, jclass c UNUSED, jlong when) Java_java_util_Date_toString(JNIEnv* e, jclass c UNUSED, jlong when)
{ {
const unsigned BufferSize UNUSED = 27;
time_t time = when / 1000; time_t time = when / 1000;
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
e->MonitorEnter(c); e->MonitorEnter(c);
char* s = ctime(&time); # ifdef _MSC_VER
removeNewline(s); char buffer[BufferSize];
jstring r = e->NewStringUTF(s); ctime_s(buffer, BufferSize, &time);
removeNewline(buffer);
# else
char* buffer = ctime(&time);
# endif
jstring r = e->NewStringUTF(buffer);
e->MonitorExit(c); e->MonitorExit(c);
return r; return r;
#else #else
char buffer[27]; char buffer[BufferSize];
ctime_r(&time, buffer); ctime_r(&time, buffer);
removeNewline(buffer); removeNewline(buffer);
return e->NewStringUTF(buffer); return e->NewStringUTF(buffer);

View File

@ -0,0 +1,28 @@
/* Copyright (c) 2009, 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. */
package java.security;
public class AccessControlException extends SecurityException {
private final Permission permission;
public AccessControlException(String message) {
this(message, null);
}
public AccessControlException(String message, Permission permission) {
super(message);
this.permission = permission;
}
public Permission getPermission() {
return permission;
}
}

View File

@ -13,15 +13,63 @@
#include "stdio.h" #include "stdio.h"
#include "stdlib.h" #include "stdlib.h"
#include "string.h"
#undef JNIEXPORT #undef JNIEXPORT
#ifdef __MINGW32__ #if (defined __MINGW32__) || (defined _MSC_VER)
# define PLATFORM_WINDOWS
# define PATH_SEPARATOR ';'
# define JNIEXPORT __declspec(dllexport) # define JNIEXPORT __declspec(dllexport)
#else #else
# define PLATFORM_POSIX
# define PATH_SEPARATOR ':'
# define JNIEXPORT __attribute__ ((visibility("default"))) # define JNIEXPORT __attribute__ ((visibility("default")))
#endif #endif
#define UNUSED __attribute__((unused)) #ifdef _MSC_VER
# define UNUSED
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
# define INT32_MAX 2147483647
# define not !
# define or ||
# define and &&
# define xor ^
# ifdef _M_IX86
# define ARCH_x86_32
# elif defined _M_X64
# define ARCH_x86_64
# endif
#else // not _MSC_VER
# define UNUSED __attribute__((unused))
# include "stdint.h"
# include "errno.h"
# ifdef __i386__
# define ARCH_x86_32
# elif defined __x86_64__
# define ARCH_x86_64
# elif defined __POWERPC__
# define ARCH_powerpc
# elif defined __arm__
# define ARCH_arm
# endif
#endif // not _MSC_VER
namespace { namespace {
@ -36,7 +84,11 @@ throwNew(JNIEnv* e, const char* class_, const char* message, ...)
va_list list; va_list list;
va_start(list, message); va_start(list, message);
#ifdef _MSC_VER
vsnprintf_s(buffer, BufferSize - 1, _TRUNCATE, message, list);
#else
vsnprintf(buffer, BufferSize - 1, message, list); vsnprintf(buffer, BufferSize - 1, message, list);
#endif
va_end(list); va_end(list);
e->ThrowNew(c, buffer); e->ThrowNew(c, buffer);
@ -47,6 +99,19 @@ throwNew(JNIEnv* e, const char* class_, const char* message, ...)
} }
} }
inline void
throwNewErrno(JNIEnv* e, const char* class_)
{
#ifdef _MSC_VER
const unsigned size = 128;
char buffer[size];
strerror_s(buffer, size, errno);
throwNew(e, class_, buffer);
#else
throwNew(e, class_, strerror(errno));
#endif
}
inline void* inline void*
allocate(JNIEnv* e, unsigned size) allocate(JNIEnv* e, unsigned size)
{ {
@ -56,6 +121,32 @@ allocate(JNIEnv* e, unsigned size)
} }
return p; return p;
} }
#ifdef _MSC_VER
template <class T>
class RuntimeArray {
public:
RuntimeArray(unsigned size):
body(static_cast<T*>(malloc(size * sizeof(T))))
{ }
~RuntimeArray() {
free(body);
}
T* body;
};
# define RUNTIME_ARRAY(type, name, size) RuntimeArray<type> name(size);
# define RUNTIME_ARRAY_BODY(name) name.body
#else // not _MSC_VER
# define RUNTIME_ARRAY(type, name, size) type name[size];
# define RUNTIME_ARRAY_BODY(name) name
#endif // not _MSC_VER
} // namespace } // namespace

View File

@ -88,7 +88,7 @@ vg += --leak-check=full --suppressions=valgrind.supp
db = gdb --args db = gdb --args
javac = "$(JAVA_HOME)/bin/javac" javac = "$(JAVA_HOME)/bin/javac"
jar = "$(JAVA_HOME)/bin/jar" jar = "$(JAVA_HOME)/bin/jar"
strip = : strip = strip
strip-all = --strip-all strip-all = --strip-all
rdynamic = -rdynamic rdynamic = -rdynamic
@ -210,26 +210,29 @@ ifeq ($(platform),windows)
ar = x86_64-pc-mingw32-ar ar = x86_64-pc-mingw32-ar
ranlib = x86_64-pc-mingw32-ranlib ranlib = x86_64-pc-mingw32-ranlib
objcopy = x86_64-pc-mingw32-objcopy objcopy = x86_64-pc-mingw32-objcopy
strip = : strip = x86_64-pc-mingw32-strip
inc = "$(root)/win64/include" inc = "$(root)/win64/include"
lib = "$(root)/win64/lib" lib = "$(root)/win64/lib"
pointer-size = 8 pointer-size = 8
object-format = pe-x86-64 object-format = pe-x86-64
endif endif
endif endif
ifeq ($(mode),debug) ifeq ($(mode),debug)
cflags += -O0 -g3 cflags += -O0 -g3
strip = :
endif endif
ifeq ($(mode),debug-fast) ifeq ($(mode),debug-fast)
cflags += -O0 -g3 -DNDEBUG cflags += -O0 -g3 -DNDEBUG
strip = :
endif endif
ifeq ($(mode),stress) ifeq ($(mode),stress)
cflags += -O0 -g3 -DVM_STRESS cflags += -O0 -g3 -DVM_STRESS
strip = :
endif endif
ifeq ($(mode),stress-major) ifeq ($(mode),stress-major)
cflags += -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR cflags += -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
strip = :
endif endif
ifeq ($(mode),fast) ifeq ($(mode),fast)
cflags += -O3 -g3 -DNDEBUG cflags += -O3 -g3 -DNDEBUG
@ -238,6 +241,46 @@ ifeq ($(mode),small)
cflags += -Os -g3 -DNDEBUG cflags += -Os -g3 -DNDEBUG
endif endif
output = -o $(1)
as := $(cc)
ld := $(cc)
build-ld := $(build-cc)
ifdef msvc
windows-java-home = $(shell cygpath -m "$(JAVA_HOME)")
zlib = $(shell cygpath -m "$(root)/win32/msvc")
cxx = "$(msvc)/BIN/cl.exe"
cc = $(cxx)
ld = "$(msvc)/BIN/link.exe"
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
-Fd$(native-build)/$(name).pdb -I"$(zlib)/include" -I$(src) \
-I"$(native-build)" -I"$(windows-java-home)/include" \
-I"$(windows-java-home)/include/win32"
shared = -dll
lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \
-DEFAULTLIB:zlib
output = -Fo$(1)
ifeq ($(mode),debug)
cflags += -Od -Zi
lflags += -debug
endif
ifeq ($(mode),debug-fast)
cflags += -Od -Zi -DNDEBUG
lflags += -debug
endif
ifeq ($(mode),fast)
cflags += -Ob2it -GL -Zi -DNDEBUG
lflags += -LTCG
endif
ifeq ($(mode),small)
cflags += -O1s -Zi -GL -DNDEBUG
lflags += -LTCG
endif
strip = :
endif
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x))) cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x))) asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x)))
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x))) java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
@ -519,13 +562,13 @@ $(test-extra-dep): $(test-extra-sources)
define compile-object define compile-object
@echo "compiling $(@)" @echo "compiling $(@)"
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
$(cxx) $(cflags) -c $(<) -o $(@) $(cxx) $(cflags) -c $(<) $(call output,$(@))
endef endef
define compile-asm-object define compile-asm-object
@echo "compiling $(@)" @echo "compiling $(@)"
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
$(cc) -I$(src) $(asmflags) -c $(<) -o $(@) $(as) -I$(src) $(asmflags) -c $(<) -o $(@)
endef endef
$(vm-cpp-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends) $(vm-cpp-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
@ -547,7 +590,7 @@ $(driver-dynamic-object): $(driver-source)
@echo "compiling $(@)" @echo "compiling $(@)"
@mkdir -p $(dir $(@)) @mkdir -p $(dir $(@))
$(cxx) $(cflags) -DBOOT_LIBRARY=\"$(so-prefix)$(name)$(so-suffix)\" \ $(cxx) $(cflags) -DBOOT_LIBRARY=\"$(so-prefix)$(name)$(so-suffix)\" \
-c $(<) -o $(@) -c $(<) $(call output,$(@))
$(boot-object): $(boot-source) $(boot-object): $(boot-source)
$(compile-object) $(compile-object)
@ -558,7 +601,7 @@ $(build)/classpath.jar: $(classpath-dep)
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .) $(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
$(binaryToMacho): $(src)/binaryToMacho.cpp $(binaryToMacho): $(src)/binaryToMacho.cpp
$(cxx) $(^) -o $(@) $(cxx) $(^) $(call output,$(@))
$(classpath-object): $(build)/classpath.jar $(binaryToMacho) $(classpath-object): $(build)/classpath.jar $(binaryToMacho)
@echo "creating $(@)" @echo "creating $(@)"
@ -617,11 +660,15 @@ $(executable): \
$(boot-object) $(vm-classpath-object) $(boot-object) $(vm-classpath-object)
@echo "linking $(@)" @echo "linking $(@)"
ifeq ($(platform),windows) ifeq ($(platform),windows)
ifdef msvc
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib
else
$(dlltool) -z $(@).def $(^) $(call gnu-objects) $(dlltool) -z $(@).def $(^) $(call gnu-objects)
$(dlltool) -d $(@).def -e $(@).exp $(dlltool) -d $(@).def -e $(@).exp
$(cc) $(@).exp $(^) $(call gnu-objects) $(lflags) -o $(@) $(ld) $(@).exp $(^) $(call gnu-objects) $(lflags) -o $(@)
endif
else else
$(cc) $(^) $(call gnu-objects) $(rdynamic) $(lflags) $(bootimage-lflags) \ $(ld) $(^) $(call gnu-objects) $(rdynamic) $(lflags) $(bootimage-lflags) \
-o $(@) -o $(@)
endif endif
$(strip) $(strip-all) $(@) $(strip) $(strip-all) $(@)
@ -644,11 +691,15 @@ $(build-bootimage-generator): \
$(bootimage-generator-objects) $(bootimage-generator-objects)
@echo "linking $(@)" @echo "linking $(@)"
ifeq ($(platform),windows) ifeq ($(platform),windows)
ifdef msvc
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib
else
$(dlltool) -z $(@).def $(^) $(dlltool) -z $(@).def $(^)
$(dlltool) -d $(@).def -e $(@).exp $(dlltool) -d $(@).def -e $(@).exp
$(cc) $(@).exp $(^) $(lflags) -o $(@) $(ld) $(@).exp $(^) $(lflags) -o $(@)
endif
else else
$(cc) $(^) $(rdynamic) $(lflags) -o $(@) $(ld) $(^) $(rdynamic) $(lflags) -o $(@)
endif endif
$(dynamic-library): $(gnu-object-dep) $(dynamic-library): $(gnu-object-dep)
@ -656,15 +707,25 @@ $(dynamic-library): \
$(vm-objects) $(dynamic-object) $(jni-objects) $(vm-heapwalk-objects) \ $(vm-objects) $(dynamic-object) $(jni-objects) $(vm-heapwalk-objects) \
$(boot-object) $(vm-classpath-object) $(gnu-libraries) $(boot-object) $(vm-classpath-object) $(gnu-libraries)
@echo "linking $(@)" @echo "linking $(@)"
$(cc) $(^) $(call gnu-objects) $(shared) $(lflags) $(bootimage-lflags) \ ifdef msvc
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(native-build)/$(name).lib
else
$(ld) $(^) $(call gnu-objects) $(shared) $(lflags) $(bootimage-lflags) \
-o $(@) -o $(@)
endif
$(strip) $(strip-all) $(@) $(strip) $(strip-all) $(@)
$(executable-dynamic): $(driver-dynamic-object) $(dynamic-library) $(executable-dynamic): $(driver-dynamic-object) $(dynamic-library)
@echo "linking $(@)" @echo "linking $(@)"
$(cc) $(^) $(lflags) -o $(@) ifdef msvc
$(ld) $(lflags) -LIBPATH:$(native-build) -DEFAULTLIB:$(name) \
-PDB:$(@).pdb -IMPLIB:$(@).lib $(<) -out:$(@)
else
$(ld) $(^) $(lflags) -o $(@)
endif
$(strip) $(strip-all) $(@) $(strip) $(strip-all) $(@)
$(generator): $(generator-objects) $(generator): $(generator-objects)
@echo "linking $(@)" @echo "linking $(@)"
$(build-cc) $(^) $(build-lflags) -o $(@) $(build-ld) $(^) $(build-lflags) -o $(@)

View File

@ -17,11 +17,11 @@ extern "C" void NO_RETURN
vmJump(void* address, void* base, void* stack, void* thread, vmJump(void* address, void* base, void* stack, void* thread,
uintptr_t returnLow, uintptr_t returnHigh); uintptr_t returnLow, uintptr_t returnHigh);
#if (defined __i386__) || (defined __x86_64__) #if (defined ARCH_x86_32) || (defined ARCH_x86_64)
# include "x86.h" # include "x86.h"
#elif defined __POWERPC__ #elif defined ARCH_powerpc
# include "powerpc.h" # include "powerpc.h"
#elif defined __arm__ #elif defined ARCH_arm
# include "arm.h" # include "arm.h"
#else #else
# error unsupported architecture # error unsupported architecture

View File

@ -8,16 +8,25 @@
There is NO WARRANTY for this software. See license.txt for There is NO WARRANTY for this software. See license.txt for
details. */ details. */
#include "stdint.h"
#include "stdlib.h" #include "stdlib.h"
#ifdef _MSC_VER
typedef unsigned char uint8_t;
#else // not _MSC_VER
# include "stdint.h"
// since we aren't linking against libstdc++, we must implement this // since we aren't linking against libstdc++, we must implement this
// ourselves: // ourselves:
extern "C" void __cxa_pure_virtual(void) { abort(); } extern "C" void __cxa_pure_virtual(void) { abort(); }
#endif // not _MSC_VER
#ifdef BOOT_IMAGE #ifdef BOOT_IMAGE
#ifdef __MINGW32__ #if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport) # define EXPORT __declspec(dllexport)
# define SYMBOL(x) binary_bootimage_bin_##x # define SYMBOL(x) binary_bootimage_bin_##x
#else #else
@ -43,7 +52,7 @@ extern "C" {
#ifdef BOOT_CLASSPATH #ifdef BOOT_CLASSPATH
#ifdef __MINGW32__ #if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport) # define EXPORT __declspec(dllexport)
# define SYMBOL(x) binary_classpath_jar_##x # define SYMBOL(x) binary_classpath_jar_##x
#else #else

View File

@ -234,9 +234,9 @@ Avian_avian_SystemClassLoader_resourceExists
object name = reinterpret_cast<object>(arguments[1]); object name = reinterpret_cast<object>(arguments[1]);
if (LIKELY(name)) { if (LIKELY(name)) {
char n[stringLength(t, name) + 1]; RUNTIME_ARRAY(char, n, stringLength(t, name) + 1);
stringChars(t, name, n); stringChars(t, name, RUNTIME_ARRAY_BODY(n));
return t->m->finder->exists(n); return t->m->finder->exists(RUNTIME_ARRAY_BODY(n));
} else { } else {
t->exception = makeNullPointerException(t); t->exception = makeNullPointerException(t);
return 0; return 0;
@ -547,18 +547,18 @@ Avian_java_lang_System_getVMProperty
PROTECT(t, found); PROTECT(t, found);
unsigned length = stringLength(t, name); unsigned length = stringLength(t, name);
char n[length + 1]; RUNTIME_ARRAY(char, n, length + 1);
stringChars(t, name, n); stringChars(t, name, RUNTIME_ARRAY_BODY(n));
int64_t r = 0; int64_t r = 0;
if (strcmp(n, "java.lang.classpath") == 0) { if (::strcmp(RUNTIME_ARRAY_BODY(n), "java.lang.classpath") == 0) {
r = reinterpret_cast<int64_t>(makeString(t, "%s", t->m->finder->path())); r = reinterpret_cast<int64_t>(makeString(t, "%s", t->m->finder->path()));
} else if (strcmp(n, "avian.version") == 0) { } else if (::strcmp(RUNTIME_ARRAY_BODY(n), "avian.version") == 0) {
r = reinterpret_cast<int64_t>(makeString(t, AVIAN_VERSION)); r = reinterpret_cast<int64_t>(makeString(t, AVIAN_VERSION));
} else if (strcmp(n, "file.encoding") == 0) { } else if (::strcmp(RUNTIME_ARRAY_BODY(n), "file.encoding") == 0) {
r = reinterpret_cast<int64_t>(makeString(t, "ASCII")); r = reinterpret_cast<int64_t>(makeString(t, "ASCII"));
} else { } else {
const char* v = findProperty(t, n); const char* v = findProperty(t, RUNTIME_ARRAY_BODY(n));
if (v) { if (v) {
r = reinterpret_cast<int64_t>(makeString(t, v)); r = reinterpret_cast<int64_t>(makeString(t, v));
} }
@ -643,8 +643,8 @@ Avian_java_lang_Runtime_load
bool mapName = arguments[1]; bool mapName = arguments[1];
unsigned length = stringLength(t, name); unsigned length = stringLength(t, name);
char n[length + 1]; RUNTIME_ARRAY(char, n, length + 1);
stringChars(t, name, n); stringChars(t, name, RUNTIME_ARRAY_BODY(n));
ACQUIRE(t, t->m->classLock); ACQUIRE(t, t->m->classLock);
@ -652,7 +652,7 @@ Avian_java_lang_Runtime_load
if (mapName and builtins) { if (mapName and builtins) {
const char* s = builtins; const char* s = builtins;
while (*s) { while (*s) {
if (strncmp(s, n, length) == 0 if (::strncmp(s, RUNTIME_ARRAY_BODY(n), length) == 0
and (s[length] == ',' or s[length] == 0)) and (s[length] == ',' or s[length] == 0))
{ {
// library is built in to this executable // library is built in to this executable
@ -671,7 +671,7 @@ Avian_java_lang_Runtime_load
System::Library* last = t->m->libraries; System::Library* last = t->m->libraries;
for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) { for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) {
if (lib->name() if (lib->name()
and strcmp(lib->name(), n) == 0 and ::strcmp(lib->name(), RUNTIME_ARRAY_BODY(n)) == 0
and lib->mapName() == mapName) and lib->mapName() == mapName)
{ {
// already loaded // already loaded
@ -681,11 +681,14 @@ Avian_java_lang_Runtime_load
} }
System::Library* lib; System::Library* lib;
if (LIKELY(t->m->system->success(t->m->system->load(&lib, n, mapName)))) { if (LIKELY(t->m->system->success
(t->m->system->load(&lib, RUNTIME_ARRAY_BODY(n), mapName))))
{
last->setNext(lib); last->setNext(lib);
runOnLoadIfFound(t, lib); runOnLoadIfFound(t, lib);
} else { } else {
object message = makeString(t, "library not found: %s", n); object message = makeString
(t, "library not found: %s", RUNTIME_ARRAY_BODY(n));
t->exception = makeUnsatisfiedLinkError(t, message); t->exception = makeUnsatisfiedLinkError(t, message);
} }
} }
@ -777,8 +780,8 @@ Avian_java_lang_Throwable_trace
if (isAssignableFrom if (isAssignableFrom
(t, arrayBody(t, t->m->types, Machine::ThrowableType), (t, arrayBody(t, t->m->types, Machine::ThrowableType),
methodClass(t, method)) methodClass(t, method))
and strcmp(reinterpret_cast<const int8_t*>("<init>"), and vm::strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0)) &byteArrayBody(t, methodName(t, method), 0))
== 0) == 0)
{ {
return true; return true;
@ -909,18 +912,7 @@ Avian_java_lang_Thread_setDaemon
object thread = reinterpret_cast<object>(arguments[0]); object thread = reinterpret_cast<object>(arguments[0]);
bool daemon = arguments[1] != 0; bool daemon = arguments[1] != 0;
ACQUIRE_RAW(t, t->m->stateLock); setDaemon(t, thread, daemon);
threadDaemon(t, thread) = daemon;
if (daemon) {
++ t->m->daemonCount;
} else {
expect(t, t->m->daemonCount);
-- t->m->daemonCount;
}
t->m->stateLock->notifyAll(t->systemThread);
} }
extern "C" JNIEXPORT int64_t JNICALL extern "C" JNIEXPORT int64_t JNICALL
@ -930,10 +922,10 @@ Avian_avian_resource_Handler_00024ResourceInputStream_getContentLength
object path = reinterpret_cast<object>(*arguments); object path = reinterpret_cast<object>(*arguments);
if (LIKELY(path)) { if (LIKELY(path)) {
char p[stringLength(t, path) + 1]; RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
stringChars(t, path, p); stringChars(t, path, RUNTIME_ARRAY_BODY(p));
System::Region* r = t->m->finder->find(p); System::Region* r = t->m->finder->find(RUNTIME_ARRAY_BODY(p));
if (r) { if (r) {
jint rSize = r->length(); jint rSize = r->length();
r->dispose(); r->dispose();
@ -950,10 +942,11 @@ Avian_avian_resource_Handler_00024ResourceInputStream_open
object path = reinterpret_cast<object>(*arguments); object path = reinterpret_cast<object>(*arguments);
if (LIKELY(path)) { if (LIKELY(path)) {
char p[stringLength(t, path) + 1]; RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
stringChars(t, path, p); stringChars(t, path, RUNTIME_ARRAY_BODY(p));
return reinterpret_cast<int64_t>(t->m->finder->find(p)); return reinterpret_cast<int64_t>
(t->m->finder->find(RUNTIME_ARRAY_BODY(p)));
} else { } else {
t->exception = makeNullPointerException(t); t->exception = makeNullPointerException(t);
return 0; return 0;

View File

@ -11,7 +11,6 @@
#ifndef COMMON_H #ifndef COMMON_H
#define COMMON_H #define COMMON_H
#include "stdint.h"
#include "stdlib.h" #include "stdlib.h"
#include "stdarg.h" #include "stdarg.h"
#include "stddef.h" #include "stddef.h"
@ -20,8 +19,77 @@
#include "types.h" #include "types.h"
#include "math.h" #include "math.h"
#ifdef _MSC_VER
// don't complain about using 'this' in member initializers:
# pragma warning(disable:4355)
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
# define not !
# define or ||
# define and &&
# define xor ^
# define LIKELY(v) v
# define UNLIKELY(v) v
# define UNUSED
# define NO_RETURN __declspec(noreturn)
# define PLATFORM_WINDOWS
# ifdef _M_IX86
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
# define ARCH_x86_32
# elif defined _M_X64
typedef int64_t intptr_t;
typedef uint64_t uintptr_t;
# define ARCH_x86_64
# else
# error "unsupported architecture"
# endif
#else // not _MSC_VER
# include "stdint.h"
# define LIKELY(v) __builtin_expect((v) != 0, true)
# define UNLIKELY(v) __builtin_expect((v) != 0, false)
# define UNUSED __attribute__((unused))
# define NO_RETURN __attribute__((noreturn))
# ifdef __MINGW32__
# define PLATFORM_WINDOWS
# endif
# ifdef __i386__
# define ARCH_x86_32
# elif defined __x86_64__
# define ARCH_x86_64
# elif defined __POWERPC__
# define ARCH_powerpc
# elif defined __arm__
# define ARCH_arm
# else
# error "unsupported architecture"
# endif
#endif // not _MSC_VER
#undef JNIEXPORT #undef JNIEXPORT
#ifdef __MINGW32__ #ifdef PLATFORM_WINDOWS
# define JNIEXPORT __declspec(dllexport) # define JNIEXPORT __declspec(dllexport)
# define PATH_SEPARATOR ';' # define PATH_SEPARATOR ';'
#else #else
@ -29,9 +97,9 @@
# define PATH_SEPARATOR ':' # define PATH_SEPARATOR ':'
#endif #endif
#if (defined __i386__) || (defined __POWERPC__) || (defined __arm__) #if (defined ARCH_x86_32) || (defined ARCH_powerpc) || (defined ARCH_arm)
# define LD "ld" # define LD "ld"
# if (defined __MINGW32__) && __GNUC__ == 4 # if (defined _MSC_VER) || ((defined __MINGW32__) && __GNUC__ >= 4)
# define LLD "I64d" # define LLD "I64d"
# else # else
# define LLD "lld" # define LLD "lld"
@ -43,10 +111,10 @@
# define LX "x" # define LX "x"
# define ULD "u" # define ULD "u"
# endif # endif
#elif defined __x86_64__ #elif defined ARCH_x86_64
# define LD "ld" # define LD "ld"
# define LX "lx" # define LX "lx"
# ifdef __MINGW32__ # if (defined _MSC_VER) || (defined __MINGW32__)
# define LLD "I64d" # define LLD "I64d"
# define ULD "I64x" # define ULD "I64x"
# else # else
@ -57,7 +125,7 @@
# error "Unsupported architecture" # error "Unsupported architecture"
#endif #endif
#ifdef __MINGW32__ #ifdef PLATFORM_WINDOWS
# define SO_PREFIX "" # define SO_PREFIX ""
#else #else
# define SO_PREFIX "lib" # define SO_PREFIX "lib"
@ -65,27 +133,95 @@
#ifdef __APPLE__ #ifdef __APPLE__
# define SO_SUFFIX ".jnilib" # define SO_SUFFIX ".jnilib"
#elif defined __MINGW32__ #elif defined PLATFORM_WINDOWS
# define SO_SUFFIX ".dll" # define SO_SUFFIX ".dll"
#else #else
# define SO_SUFFIX ".so" # define SO_SUFFIX ".so"
#endif #endif
#define NO_RETURN __attribute__((noreturn))
#define LIKELY(v) __builtin_expect((v) != 0, true)
#define UNLIKELY(v) __builtin_expect((v) != 0, false)
#define MACRO_XY(X, Y) X##Y #define MACRO_XY(X, Y) X##Y
#define MACRO_MakeNameXY(FX, LINE) MACRO_XY(FX, LINE) #define MACRO_MakeNameXY(FX, LINE) MACRO_XY(FX, LINE)
#define MAKE_NAME(FX) MACRO_MakeNameXY(FX, __LINE__) #define MAKE_NAME(FX) MACRO_MakeNameXY(FX, __LINE__)
#define UNUSED __attribute__((unused))
inline void* operator new(size_t, void* p) throw() { return p; } inline void* operator new(size_t, void* p) throw() { return p; }
namespace vm { namespace vm {
#ifdef _MSC_VER
template <class T>
class RuntimeArray {
public:
RuntimeArray(unsigned size):
body(static_cast<T*>(malloc(size * sizeof(T))))
{ }
~RuntimeArray() {
free(body);
}
T* body;
};
# define RUNTIME_ARRAY(type, name, size) RuntimeArray<type> name(size);
# define RUNTIME_ARRAY_BODY(name) name.body
inline int
vsnprintf(char* dst, size_t size, const char* format, va_list a)
{
return vsnprintf_s(dst, size, _TRUNCATE, format, a);
}
inline int
snprintf(char* dst, size_t size, const char* format, ...)
{
va_list a;
va_start(a, format);
int r = vsnprintf(dst, size, format, a);
va_end(a);
return r;
}
inline FILE*
fopen(const char* name, const char* mode)
{
FILE* file;
if (fopen_s(&file, name, mode) == 0) {
return file;
} else {
return 0;
}
}
#else // not _MSC_VER
# define RUNTIME_ARRAY(type, name, size) type name[size];
# define RUNTIME_ARRAY_BODY(name) name
inline int
vsnprintf(char* dst, size_t size, const char* format, va_list a)
{
return ::vsnprintf(dst, size, format, a);
}
inline int
snprintf(char* dst, size_t size, const char* format, ...)
{
va_list a;
va_start(a, format);
int r = vsnprintf(dst, size, format, a);
va_end(a);
return r;
}
inline FILE*
fopen(const char* name, const char* mode)
{
return ::fopen(name, mode);
}
#endif // not _MSC_VER
const unsigned BytesPerWord = sizeof(uintptr_t); const unsigned BytesPerWord = sizeof(uintptr_t);
const unsigned BitsPerWord = BytesPerWord * 8; const unsigned BitsPerWord = BytesPerWord * 8;

View File

@ -32,6 +32,8 @@ vmCall();
namespace { namespace {
namespace local {
const bool DebugCompile = false; const bool DebugCompile = false;
const bool DebugNatives = false; const bool DebugNatives = false;
const bool DebugCallTable = false; const bool DebugCallTable = false;
@ -777,13 +779,13 @@ class Context {
switch (op) { switch (op) {
case Divide: case Divide:
if (size == 8) { if (size == 8) {
return ::getThunk(t, divideLongThunk); return local::getThunk(t, divideLongThunk);
} }
break; break;
case Remainder: case Remainder:
if (size == 8) { if (size == 8) {
return ::getThunk(t, moduloLongThunk); return local::getThunk(t, moduloLongThunk);
} }
break; break;
@ -962,7 +964,7 @@ class Frame {
} }
unsigned localSize() { unsigned localSize() {
return ::localSize(t, context->method); return local::localSize(t, context->method);
} }
unsigned stackSize() { unsigned stackSize() {
@ -2166,21 +2168,21 @@ makeMultidimensionalArray2(MyThread* t, object class_, uintptr_t* countStack,
{ {
PROTECT(t, class_); PROTECT(t, class_);
int32_t counts[dimensions]; RUNTIME_ARRAY(int32_t, counts, dimensions);
for (int i = dimensions - 1; i >= 0; --i) { for (int i = dimensions - 1; i >= 0; --i) {
counts[i] = countStack[dimensions - i - 1]; RUNTIME_ARRAY_BODY(counts)[i] = countStack[dimensions - i - 1];
if (UNLIKELY(counts[i] < 0)) { if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) {
object message = makeString(t, "%d", counts[i]); object message = makeString(t, "%d", RUNTIME_ARRAY_BODY(counts)[i]);
t->exception = makeNegativeArraySizeException(t, message); t->exception = makeNegativeArraySizeException(t, message);
return 0; return 0;
} }
} }
object array = makeArray(t, counts[0]); object array = makeArray(t, RUNTIME_ARRAY_BODY(counts)[0]);
setObjectClass(t, array, class_); setObjectClass(t, array, class_);
PROTECT(t, array); PROTECT(t, array);
populateMultiArray(t, array, counts, 0, dimensions); populateMultiArray(t, array, RUNTIME_ARRAY_BODY(counts), 0, dimensions);
return array; return array;
} }
@ -2575,9 +2577,9 @@ void
compile(MyThread* t, Frame* initialFrame, unsigned ip, compile(MyThread* t, Frame* initialFrame, unsigned ip,
int exceptionHandlerStart) int exceptionHandlerStart)
{ {
uint8_t stackMap RUNTIME_ARRAY(uint8_t, stackMap,
[codeMaxStack(t, methodCode(t, initialFrame->context->method))]; codeMaxStack(t, methodCode(t, initialFrame->context->method)));
Frame myFrame(initialFrame, stackMap); Frame myFrame(initialFrame, RUNTIME_ARRAY_BODY(stackMap));
Frame* frame = &myFrame; Frame* frame = &myFrame;
Compiler* c = frame->c; Compiler* c = frame->c;
Context* context = frame->context; Context* context = frame->context;
@ -3828,14 +3830,14 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
if (pairCount) { if (pairCount) {
Compiler::Operand* start = 0; Compiler::Operand* start = 0;
uint32_t ipTable[pairCount]; RUNTIME_ARRAY(uint32_t, ipTable, pairCount);
for (int32_t i = 0; i < pairCount; ++i) { for (int32_t i = 0; i < pairCount; ++i) {
unsigned index = ip + (i * 8); unsigned index = ip + (i * 8);
int32_t key = codeReadInt32(t, code, index); int32_t key = codeReadInt32(t, code, index);
uint32_t newIp = base + codeReadInt32(t, code, index); uint32_t newIp = base + codeReadInt32(t, code, index);
assert(t, newIp < codeLength(t, code)); assert(t, newIp < codeLength(t, code));
ipTable[i] = newIp; RUNTIME_ARRAY_BODY(ipTable)[i] = newIp;
Promise* p = c->poolAppend(key); Promise* p = c->poolAppend(key);
if (i == 0) { if (i == 0) {
@ -3854,7 +3856,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
Compiler::State* state = c->saveState(); Compiler::State* state = c->saveState();
for (int32_t i = 0; i < pairCount; ++i) { for (int32_t i = 0; i < pairCount; ++i) {
compile(t, frame, ipTable[i]); compile(t, frame, RUNTIME_ARRAY_BODY(ipTable)[i]);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state); c->restoreState(state);
@ -4207,13 +4209,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
int32_t top = codeReadInt32(t, code, ip); int32_t top = codeReadInt32(t, code, ip);
Compiler::Operand* start = 0; Compiler::Operand* start = 0;
uint32_t ipTable[top - bottom + 1]; RUNTIME_ARRAY(uint32_t, ipTable, top - bottom + 1);
for (int32_t i = 0; i < top - bottom + 1; ++i) { for (int32_t i = 0; i < top - bottom + 1; ++i) {
unsigned index = ip + (i * 4); unsigned index = ip + (i * 4);
uint32_t newIp = base + codeReadInt32(t, code, index); uint32_t newIp = base + codeReadInt32(t, code, index);
assert(t, newIp < codeLength(t, code)); assert(t, newIp < codeLength(t, code));
ipTable[i] = newIp; RUNTIME_ARRAY_BODY(ipTable)[i] = newIp;
Promise* p = c->poolAppendPromise Promise* p = c->poolAppendPromise
(frame->addressPromise(c->machineIp(newIp))); (frame->addressPromise(c->machineIp(newIp)));
@ -4249,7 +4251,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
Compiler::State* state = c->saveState(); Compiler::State* state = c->saveState();
for (int32_t i = 0; i < top - bottom + 1; ++i) { for (int32_t i = 0; i < top - bottom + 1; ++i) {
compile(t, frame, ipTable[i]); compile(t, frame, RUNTIME_ARRAY_BODY(ipTable)[i]);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state); c->restoreState(state);
@ -4320,7 +4322,7 @@ logCompile(MyThread* t, const void* code, unsigned size, const char* class_,
open = true; open = true;
const char* path = findProperty(t, "avian.jit.log"); const char* path = findProperty(t, "avian.jit.log");
if (path) { if (path) {
compileLog = fopen(path, "wb"); compileLog = vm::fopen(path, "wb");
} else if (DebugCompile) { } else if (DebugCompile) {
compileLog = stderr; compileLog = stderr;
} }
@ -4432,11 +4434,11 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
unsigned mapSize = frameMapSizeInWords(t, context->method); unsigned mapSize = frameMapSizeInWords(t, context->method);
uintptr_t roots[mapSize]; RUNTIME_ARRAY(uintptr_t, roots, mapSize);
if (originalRoots) { if (originalRoots) {
memcpy(roots, originalRoots, mapSize * BytesPerWord); memcpy(RUNTIME_ARRAY_BODY(roots), originalRoots, mapSize * BytesPerWord);
} else { } else {
memset(roots, 0, mapSize * BytesPerWord); memset(RUNTIME_ARRAY_BODY(roots), 0, mapSize * BytesPerWord);
} }
int32_t ip = -1; int32_t ip = -1;
@ -4455,7 +4457,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
switch (e) { switch (e) {
case PushContextEvent: { case PushContextEvent: {
eventIndex = calculateFrameMaps eventIndex = calculateFrameMaps
(t, context, roots, eventIndex, subroutinePath); (t, context, RUNTIME_ARRAY_BODY(roots), eventIndex, subroutinePath);
} break; } break;
case PopContextEvent: case PopContextEvent:
@ -4467,7 +4469,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
if (DebugFrameMaps) { if (DebugFrameMaps) {
fprintf(stderr, " roots at ip %3d: ", ip); fprintf(stderr, " roots at ip %3d: ", ip);
printSet(*roots, mapSize); printSet(*RUNTIME_ARRAY_BODY(roots), mapSize);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@ -4477,7 +4479,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
if (context->visitTable[ip] > 1) { if (context->visitTable[ip] > 1) {
for (unsigned wi = 0; wi < mapSize; ++wi) { for (unsigned wi = 0; wi < mapSize; ++wi) {
uintptr_t newRoots = tableRoots[wi] & roots[wi]; uintptr_t newRoots = tableRoots[wi] & RUNTIME_ARRAY_BODY(roots)[wi];
if ((eventIndex == length if ((eventIndex == length
or context->eventLog.get(eventIndex) == PopContextEvent) or context->eventLog.get(eventIndex) == PopContextEvent)
@ -4491,7 +4493,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
} }
tableRoots[wi] = newRoots; tableRoots[wi] = newRoots;
roots[wi] &= tableRoots[wi]; RUNTIME_ARRAY_BODY(roots)[wi] &= tableRoots[wi];
} }
if (DebugFrameMaps) { if (DebugFrameMaps) {
@ -4500,7 +4502,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
} else { } else {
memcpy(tableRoots, roots, mapSize * BytesPerWord); memcpy(tableRoots, RUNTIME_ARRAY_BODY(roots), mapSize * BytesPerWord);
} }
} break; } break;
@ -4508,14 +4510,14 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
unsigned i = context->eventLog.get2(eventIndex); unsigned i = context->eventLog.get2(eventIndex);
eventIndex += 2; eventIndex += 2;
markBit(roots, i); markBit(RUNTIME_ARRAY_BODY(roots), i);
} break; } break;
case ClearEvent: { case ClearEvent: {
unsigned i = context->eventLog.get2(eventIndex); unsigned i = context->eventLog.get2(eventIndex);
eventIndex += 2; eventIndex += 2;
clearBit(roots, i); clearBit(RUNTIME_ARRAY_BODY(roots), i);
} break; } break;
case PushExceptionHandlerEvent: { case PushExceptionHandlerEvent: {
@ -4528,18 +4530,21 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
for (SubroutineCall* c = s->calls; c; c = c->next) { for (SubroutineCall* c = s->calls; c; c = c->next) {
for (SubroutinePath* p = c->paths; p; p = p->listNext) { for (SubroutinePath* p = c->paths; p; p = p->listNext) {
memcpy(roots, p->rootTable + (reference * mapSize), memcpy(RUNTIME_ARRAY_BODY(roots),
p->rootTable + (reference * mapSize),
mapSize * BytesPerWord); mapSize * BytesPerWord);
eventIndex = calculateFrameMaps eventIndex = calculateFrameMaps
(t, context, roots, originalEventIndex, p); (t, context, RUNTIME_ARRAY_BODY(roots), originalEventIndex, p);
} }
} }
} else { } else {
memcpy(roots, context->rootTable + (reference * mapSize), memcpy(RUNTIME_ARRAY_BODY(roots),
context->rootTable + (reference * mapSize),
mapSize * BytesPerWord); mapSize * BytesPerWord);
eventIndex = calculateFrameMaps(t, context, roots, eventIndex, 0); eventIndex = calculateFrameMaps
(t, context, RUNTIME_ARRAY_BODY(roots), eventIndex, 0);
} }
} break; } break;
@ -4547,7 +4552,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
TraceElement* te; context->eventLog.get(eventIndex, &te, BytesPerWord); TraceElement* te; context->eventLog.get(eventIndex, &te, BytesPerWord);
if (DebugFrameMaps) { if (DebugFrameMaps) {
fprintf(stderr, "trace roots at ip %3d: ", ip); fprintf(stderr, "trace roots at ip %3d: ", ip);
printSet(*roots, mapSize); printSet(*RUNTIME_ARRAY_BODY(roots), mapSize);
if (subroutinePath) { if (subroutinePath) {
fprintf(stderr, " "); fprintf(stderr, " ");
print(subroutinePath); print(subroutinePath);
@ -4556,7 +4561,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
} }
if (subroutinePath == 0) { if (subroutinePath == 0) {
memcpy(te->map, roots, mapSize * BytesPerWord); memcpy(te->map, RUNTIME_ARRAY_BODY(roots), mapSize * BytesPerWord);
} else { } else {
SubroutineTrace* trace = 0; SubroutineTrace* trace = 0;
for (SubroutineTrace* t = te->subroutineTrace; t; t = t->next) { for (SubroutineTrace* t = te->subroutineTrace; t; t = t->next) {
@ -4574,7 +4579,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
++ te->subroutineTraceCount; ++ te->subroutineTraceCount;
} }
memcpy(trace->map, roots, mapSize * BytesPerWord); memcpy(trace->map, RUNTIME_ARRAY_BODY(roots), mapSize * BytesPerWord);
} }
eventIndex += BytesPerWord; eventIndex += BytesPerWord;
@ -4603,7 +4608,9 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
makeRootTable(t, &(context->zone), context->method)); makeRootTable(t, &(context->zone), context->method));
} }
calculateFrameMaps(t, context, roots, call->subroutine->logIndex, path); calculateFrameMaps
(t, context, RUNTIME_ARRAY_BODY(roots), call->subroutine->logIndex,
path);
} break; } break;
case PopSubroutineEvent: case PopSubroutineEvent:
@ -4841,26 +4848,26 @@ makeGeneralFrameMapTable(MyThread* t, Context* context, uint8_t* start,
pathIndex = subroutine->tableIndex; pathIndex = subroutine->tableIndex;
SubroutineTrace* traces[p->subroutineTraceCount]; RUNTIME_ARRAY(SubroutineTrace*, traces, p->subroutineTraceCount);
unsigned i = 0; unsigned i = 0;
for (SubroutineTrace* trace = p->subroutineTrace; for (SubroutineTrace* trace = p->subroutineTrace;
trace; trace = trace->next) trace; trace = trace->next)
{ {
assert(t, i < p->subroutineTraceCount); assert(t, i < p->subroutineTraceCount);
traces[i++] = trace; RUNTIME_ARRAY_BODY(traces)[i++] = trace;
} }
assert(t, i == p->subroutineTraceCount); assert(t, i == p->subroutineTraceCount);
qsort(traces, p->subroutineTraceCount, sizeof(SubroutineTrace*), qsort(RUNTIME_ARRAY_BODY(traces), p->subroutineTraceCount,
compareSubroutineTracePointers); sizeof(SubroutineTrace*), compareSubroutineTracePointers);
for (unsigned i = 0; i < p->subroutineTraceCount; ++i) { for (unsigned i = 0; i < p->subroutineTraceCount; ++i) {
assert(t, mapsOffset + ceiling(nextMapIndex + mapSize, 32) * 4 assert(t, mapsOffset + ceiling(nextMapIndex + mapSize, 32) * 4
<= pathsOffset); <= pathsOffset);
copyFrameMap(reinterpret_cast<int32_t*>(body + mapsOffset), copyFrameMap(reinterpret_cast<int32_t*>(body + mapsOffset),
traces[i]->map, mapSize, nextMapIndex, p, RUNTIME_ARRAY_BODY(traces)[i]->map, mapSize,
traces[i]->path); nextMapIndex, p, RUNTIME_ARRAY_BODY(traces)[i]->path);
nextMapIndex += mapSize; nextMapIndex += mapSize;
} }
@ -4987,7 +4994,7 @@ finish(MyThread* t, Allocator* allocator, Context* context)
} }
if (context->traceLogCount) { if (context->traceLogCount) {
TraceElement* elements[context->traceLogCount]; RUNTIME_ARRAY(TraceElement*, elements, context->traceLogCount);
unsigned index = 0; unsigned index = 0;
unsigned pathFootprint = 0; unsigned pathFootprint = 0;
unsigned mapCount = 0; unsigned mapCount = 0;
@ -5012,7 +5019,7 @@ finish(MyThread* t, Allocator* allocator, Context* context)
mapCount += myMapCount; mapCount += myMapCount;
elements[index++] = p; RUNTIME_ARRAY_BODY(elements)[index++] = p;
if (p->target) { if (p->target) {
insertCallNode insertCallNode
@ -5021,15 +5028,17 @@ finish(MyThread* t, Allocator* allocator, Context* context)
} }
} }
qsort(elements, context->traceLogCount, sizeof(TraceElement*), qsort(RUNTIME_ARRAY_BODY(elements), context->traceLogCount,
compareTraceElementPointers); sizeof(TraceElement*), compareTraceElementPointers);
object map; object map;
if (pathFootprint) { if (pathFootprint) {
map = makeGeneralFrameMapTable map = makeGeneralFrameMapTable
(t, context, start, elements, pathFootprint, mapCount); (t, context, start, RUNTIME_ARRAY_BODY(elements), pathFootprint,
mapCount);
} else { } else {
map = makeSimpleFrameMapTable(t, context, start, elements); map = makeSimpleFrameMapTable
(t, context, start, RUNTIME_ARRAY_BODY(elements));
} }
set(t, methodCode(t, context->method), CodePool, map); set(t, methodCode(t, context->method), CodePool, map);
@ -5046,11 +5055,11 @@ finish(MyThread* t, Allocator* allocator, Context* context)
// for debugging: // for debugging:
if (false and if (false and
strcmp ::strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
"java/lang/Throwable") == 0 and "java/lang/Throwable") == 0 and
strcmp ::strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, context->method), 0)), (&byteArrayBody(t, methodName(t, context->method), 0)),
"printStackTrace") == 0) "printStackTrace") == 0)
@ -5078,8 +5087,9 @@ compile(MyThread* t, Allocator* allocator, Context* context)
c->init(codeLength(t, methodCode(t, context->method)), footprint, locals, c->init(codeLength(t, methodCode(t, context->method)), footprint, locals,
alignedFrameSize(t, context->method)); alignedFrameSize(t, context->method));
uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))]; RUNTIME_ARRAY(uint8_t, stackMap,
Frame frame(context, stackMap); codeMaxStack(t, methodCode(t, context->method)));
Frame frame(context, RUNTIME_ARRAY_BODY(stackMap));
unsigned index = methodParameterFootprint(t, context->method); unsigned index = methodParameterFootprint(t, context->method);
if ((methodFlags(t, context->method) & ACC_STATIC) == 0) { if ((methodFlags(t, context->method) & ACC_STATIC) == 0) {
@ -5129,8 +5139,8 @@ compile(MyThread* t, Allocator* allocator, Context* context)
unsigned visitCount = exceptionHandlerTableLength(t, eht); unsigned visitCount = exceptionHandlerTableLength(t, eht);
bool visited[visitCount]; RUNTIME_ARRAY(bool, visited, visitCount);
memset(visited, 0, visitCount * sizeof(bool)); memset(RUNTIME_ARRAY_BODY(visited), 0, visitCount * sizeof(bool));
while (visitCount) { while (visitCount) {
bool progress = false; bool progress = false;
@ -5141,13 +5151,16 @@ compile(MyThread* t, Allocator* allocator, Context* context)
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
unsigned start = exceptionHandlerStart(eh); unsigned start = exceptionHandlerStart(eh);
if ((not visited[i]) and context->visitTable[start]) { if ((not RUNTIME_ARRAY_BODY(visited)[i])
and context->visitTable[start])
{
-- visitCount; -- visitCount;
visited[i] = true; RUNTIME_ARRAY_BODY(visited)[i] = true;
progress = true; progress = true;
uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))]; RUNTIME_ARRAY(uint8_t, stackMap,
Frame frame2(&frame, stackMap); codeMaxStack(t, methodCode(t, context->method)));
Frame frame2(&frame, RUNTIME_ARRAY_BODY(stackMap));
context->eventLog.append(PushExceptionHandlerEvent); context->eventLog.append(PushExceptionHandlerEvent);
context->eventLog.append2(start); context->eventLog.append2(start);
@ -5351,31 +5364,33 @@ invokeNativeSlow(MyThread* t, object method)
} }
unsigned count = methodParameterCount(t, method) + 2; unsigned count = methodParameterCount(t, method) + 2;
uintptr_t args[footprint]; RUNTIME_ARRAY(uintptr_t, args, footprint);
unsigned argOffset = 0; unsigned argOffset = 0;
uint8_t types[count]; RUNTIME_ARRAY(uint8_t, types, count);
unsigned typeOffset = 0; unsigned typeOffset = 0;
args[argOffset++] = reinterpret_cast<uintptr_t>(t); RUNTIME_ARRAY_BODY(args)[argOffset++] = reinterpret_cast<uintptr_t>(t);
types[typeOffset++] = POINTER_TYPE; RUNTIME_ARRAY_BODY(types)[typeOffset++] = POINTER_TYPE;
uintptr_t* sp = static_cast<uintptr_t*>(t->stack) uintptr_t* sp = static_cast<uintptr_t*>(t->stack)
+ t->arch->frameFooterSize() + t->arch->frameFooterSize()
+ t->arch->frameReturnAddressSize(); + t->arch->frameReturnAddressSize();
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
args[argOffset++] = reinterpret_cast<uintptr_t>(&class_); RUNTIME_ARRAY_BODY(args)[argOffset++]
= reinterpret_cast<uintptr_t>(&class_);
} else { } else {
args[argOffset++] = reinterpret_cast<uintptr_t>(sp++); RUNTIME_ARRAY_BODY(args)[argOffset++]
= reinterpret_cast<uintptr_t>(sp++);
} }
types[typeOffset++] = POINTER_TYPE; RUNTIME_ARRAY_BODY(types)[typeOffset++] = POINTER_TYPE;
MethodSpecIterator it MethodSpecIterator it
(t, reinterpret_cast<const char*> (t, reinterpret_cast<const char*>
(&byteArrayBody(t, methodSpec(t, method), 0))); (&byteArrayBody(t, methodSpec(t, method), 0)));
while (it.hasNext()) { while (it.hasNext()) {
unsigned type = types[typeOffset++] unsigned type = RUNTIME_ARRAY_BODY(types)[typeOffset++]
= fieldType(t, fieldCode(t, *it.next())); = fieldType(t, fieldCode(t, *it.next()));
switch (type) { switch (type) {
@ -5383,21 +5398,22 @@ invokeNativeSlow(MyThread* t, object method)
case INT16_TYPE: case INT16_TYPE:
case INT32_TYPE: case INT32_TYPE:
case FLOAT_TYPE: case FLOAT_TYPE:
args[argOffset++] = *(sp++); RUNTIME_ARRAY_BODY(args)[argOffset++] = *(sp++);
break; break;
case INT64_TYPE: case INT64_TYPE:
case DOUBLE_TYPE: { case DOUBLE_TYPE: {
memcpy(args + argOffset, sp, 8); memcpy(RUNTIME_ARRAY_BODY(args) + argOffset, sp, 8);
argOffset += (8 / BytesPerWord); argOffset += (8 / BytesPerWord);
sp += 2; sp += 2;
} break; } break;
case POINTER_TYPE: { case POINTER_TYPE: {
if (*sp) { if (*sp) {
args[argOffset++] = reinterpret_cast<uintptr_t>(sp); RUNTIME_ARRAY_BODY(args)[argOffset++]
= reinterpret_cast<uintptr_t>(sp);
} else { } else {
args[argOffset++] = 0; RUNTIME_ARRAY_BODY(args)[argOffset++] = 0;
} }
++ sp; ++ sp;
} break; } break;
@ -5421,7 +5437,7 @@ invokeNativeSlow(MyThread* t, object method)
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
acquire(t, methodClass(t, method)); acquire(t, methodClass(t, method));
} else { } else {
acquire(t, *reinterpret_cast<object*>(args[0])); acquire(t, *reinterpret_cast<object*>(RUNTIME_ARRAY_BODY(args)[0]));
} }
} }
@ -5431,8 +5447,8 @@ invokeNativeSlow(MyThread* t, object method)
result = t->m->system->call result = t->m->system->call
(function, (function,
args, RUNTIME_ARRAY_BODY(args),
types, RUNTIME_ARRAY_BODY(types),
count, count,
footprint * BytesPerWord, footprint * BytesPerWord,
returnType); returnType);
@ -5442,7 +5458,7 @@ invokeNativeSlow(MyThread* t, object method)
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
release(t, methodClass(t, method)); release(t, methodClass(t, method));
} else { } else {
release(t, *reinterpret_cast<object*>(args[0])); release(t, *reinterpret_cast<object*>(RUNTIME_ARRAY_BODY(args)[0]));
} }
} }
@ -5904,10 +5920,10 @@ jumpAndInvoke(MyThread* t, object method, void* base, void* stack, ...)
} }
unsigned argumentCount = methodParameterFootprint(t, method); unsigned argumentCount = methodParameterFootprint(t, method);
uintptr_t arguments[argumentCount]; RUNTIME_ARRAY(uintptr_t, arguments, argumentCount);
va_list a; va_start(a, stack); va_list a; va_start(a, stack);
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
arguments[i] = va_arg(a, uintptr_t); RUNTIME_ARRAY_BODY(arguments)[i] = va_arg(a, uintptr_t);
} }
va_end(a); va_end(a);
@ -5916,7 +5932,7 @@ jumpAndInvoke(MyThread* t, object method, void* base, void* stack, ...)
base, base,
stack, stack,
argumentCount * BytesPerWord, argumentCount * BytesPerWord,
arguments, RUNTIME_ARRAY_BODY(arguments),
(t->arch->alignFrameSize(t->arch->argumentFootprint(argumentCount)) (t->arch->alignFrameSize(t->arch->argumentFootprint(argumentCount))
+ t->arch->frameReturnAddressSize()) + t->arch->frameReturnAddressSize())
* BytesPerWord); * BytesPerWord);
@ -5994,7 +6010,7 @@ callContinuation(MyThread* t, object continuation, object result,
if (method) { if (method) {
rewindMethod(t) = method; rewindMethod(t) = method;
compile(t, ::codeAllocator(t), 0, method); compile(t, local::codeAllocator(t), 0, method);
if (UNLIKELY(t->exception)) { if (UNLIKELY(t->exception)) {
action = Throw; action = Throw;
@ -6078,7 +6094,7 @@ callWithCurrentContinuation(MyThread* t, object receiver)
(t, receiveMethod(t), objectClass(t, receiver)); (t, receiveMethod(t), objectClass(t, receiver));
PROTECT(t, method); PROTECT(t, method);
compile(t, ::codeAllocator(t), 0, method); compile(t, local::codeAllocator(t), 0, method);
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
t->continuation = makeCurrentContinuation(t, &ip, &base, &stack); t->continuation = makeCurrentContinuation(t, &ip, &base, &stack);
@ -6112,7 +6128,7 @@ dynamicWind(MyThread* t, object before, object thunk, object after)
if (method) { if (method) {
windMethod(t) = method; windMethod(t) = method;
compile(t, ::codeAllocator(t), 0, method); compile(t, local::codeAllocator(t), 0, method);
} }
} }
@ -6438,7 +6454,7 @@ class MyProcessor: public Processor {
return vm::makeMethod return vm::makeMethod
(t, vmFlags, returnCode, parameterCount, parameterFootprint, flags, (t, vmFlags, returnCode, parameterCount, parameterFootprint, flags,
offset, 0, name, spec, class_, code, offset, 0, name, spec, class_, code,
::defaultThunk(static_cast<MyThread*>(t))); local::defaultThunk(static_cast<MyThread*>(t)));
} }
virtual object virtual object
@ -6564,17 +6580,19 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0)); (&byteArrayBody(t, methodSpec(t, method), 0));
unsigned size = methodParameterFootprint(t, method); unsigned size = methodParameterFootprint(t, method);
uintptr_t array[size]; RUNTIME_ARRAY(uintptr_t, array, size);
bool objectMask[size]; RUNTIME_ARRAY(bool, objectMask, size);
ArgumentList list(t, array, size, objectMask, this_, spec, arguments); ArgumentList list
(t, RUNTIME_ARRAY_BODY(array), size, RUNTIME_ARRAY_BODY(objectMask),
this_, spec, arguments);
PROTECT(t, method); PROTECT(t, method);
compile(static_cast<MyThread*>(t), compile(static_cast<MyThread*>(t),
::codeAllocator(static_cast<MyThread*>(t)), 0, method); local::codeAllocator(static_cast<MyThread*>(t)), 0, method);
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
return ::invoke(t, method, &list); return local::invoke(t, method, &list);
} }
return 0; return 0;
@ -6597,16 +6615,17 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0)); (&byteArrayBody(t, methodSpec(t, method), 0));
unsigned size = methodParameterFootprint(t, method); unsigned size = methodParameterFootprint(t, method);
uintptr_t array[size]; RUNTIME_ARRAY(uintptr_t, array, size);
bool objectMask[size]; RUNTIME_ARRAY(bool, objectMask, size);
ArgumentList list ArgumentList list
(t, array, size, objectMask, this_, spec, indirectObjects, arguments); (t, RUNTIME_ARRAY_BODY(array), size, RUNTIME_ARRAY_BODY(objectMask),
this_, spec, indirectObjects, arguments);
PROTECT(t, method); PROTECT(t, method);
if (false) { if (false) {
compile(static_cast<MyThread*>(t), compile(static_cast<MyThread*>(t),
::codeAllocator(static_cast<MyThread*>(t)), 0, local::codeAllocator(static_cast<MyThread*>(t)), 0,
resolveMethod(t, t->m->loader, resolveMethod(t, t->m->loader,
"java/beans/PropertyChangeSupport", "java/beans/PropertyChangeSupport",
"firePropertyChange", "firePropertyChange",
@ -6615,10 +6634,10 @@ class MyProcessor: public Processor {
} }
compile(static_cast<MyThread*>(t), compile(static_cast<MyThread*>(t),
::codeAllocator(static_cast<MyThread*>(t)), 0, method); local::codeAllocator(static_cast<MyThread*>(t)), 0, method);
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
return ::invoke(t, method, &list); return local::invoke(t, method, &list);
} }
return 0; return 0;
@ -6635,10 +6654,11 @@ class MyProcessor: public Processor {
or t->state == Thread::ExclusiveState); or t->state == Thread::ExclusiveState);
unsigned size = parameterFootprint(t, methodSpec, false); unsigned size = parameterFootprint(t, methodSpec, false);
uintptr_t array[size]; RUNTIME_ARRAY(uintptr_t, array, size);
bool objectMask[size]; RUNTIME_ARRAY(bool, objectMask, size);
ArgumentList list ArgumentList list
(t, array, size, objectMask, this_, methodSpec, false, arguments); (t, RUNTIME_ARRAY_BODY(array), size, RUNTIME_ARRAY_BODY(objectMask),
this_, methodSpec, false, arguments);
object method = resolveMethod object method = resolveMethod
(t, loader, className, methodName, methodSpec); (t, loader, className, methodName, methodSpec);
@ -6648,10 +6668,10 @@ class MyProcessor: public Processor {
PROTECT(t, method); PROTECT(t, method);
compile(static_cast<MyThread*>(t), compile(static_cast<MyThread*>(t),
::codeAllocator(static_cast<MyThread*>(t)), 0, method); local::codeAllocator(static_cast<MyThread*>(t)), 0, method);
if (LIKELY(t->exception == 0)) { if (LIKELY(t->exception == 0)) {
return ::invoke(t, method, &list); return local::invoke(t, method, &list);
} }
} }
@ -6795,7 +6815,7 @@ class MyProcessor: public Processor {
} }
if (image) { if (image) {
::boot(static_cast<MyThread*>(t), image); local::boot(static_cast<MyThread*>(t), image);
} else { } else {
callTable = makeArray(t, 128); callTable = makeArray(t, 128);
@ -6803,7 +6823,7 @@ class MyProcessor: public Processor {
set(t, methodTree, TreeNodeLeft, methodTreeSentinal); set(t, methodTree, TreeNodeLeft, methodTreeSentinal);
set(t, methodTree, TreeNodeRight, methodTreeSentinal); set(t, methodTree, TreeNodeRight, methodTreeSentinal);
::compileThunks(static_cast<MyThread*>(t), &codeAllocator, this); local::compileThunks(static_cast<MyThread*>(t), &codeAllocator, this);
} }
segFaultHandler.m = t->m; segFaultHandler.m = t->m;
@ -6813,7 +6833,7 @@ class MyProcessor: public Processor {
virtual void callWithCurrentContinuation(Thread* t, object receiver) { virtual void callWithCurrentContinuation(Thread* t, object receiver) {
if (Continuations) { if (Continuations) {
::callWithCurrentContinuation(static_cast<MyThread*>(t), receiver); local::callWithCurrentContinuation(static_cast<MyThread*>(t), receiver);
} else { } else {
abort(t); abort(t);
} }
@ -6823,7 +6843,7 @@ class MyProcessor: public Processor {
object after) object after)
{ {
if (Continuations) { if (Continuations) {
::dynamicWind(static_cast<MyThread*>(t), before, thunk, after); local::dynamicWind(static_cast<MyThread*>(t), before, thunk, after);
} else { } else {
abort(t); abort(t);
} }
@ -6853,7 +6873,7 @@ class MyProcessor: public Processor {
unsigned start) unsigned start)
{ {
if (Continuations) { if (Continuations) {
::walkContinuationBody(static_cast<MyThread*>(t), w, o, start); local::walkContinuationBody(static_cast<MyThread*>(t), w, o, start);
} else { } else {
abort(t); abort(t);
} }
@ -7153,12 +7173,12 @@ fixupThunks(MyThread* t, BootImage* image, uint8_t* code)
p->defaultThunk = code + image->defaultThunk; p->defaultThunk = code + image->defaultThunk;
updateCall(t, LongCall, false, code + image->compileMethodCall, updateCall(t, LongCall, false, code + image->compileMethodCall,
voidPointer(::compileMethod)); voidPointer(local::compileMethod));
p->defaultVirtualThunk = code + image->defaultVirtualThunk; p->defaultVirtualThunk = code + image->defaultVirtualThunk;
updateCall(t, LongCall, false, code + image->compileVirtualMethodCall, updateCall(t, LongCall, false, code + image->compileVirtualMethodCall,
voidPointer(::compileVirtualMethod)); voidPointer(local::compileVirtualMethod));
p->nativeThunk = code + image->nativeThunk; p->nativeThunk = code + image->nativeThunk;
@ -7676,6 +7696,8 @@ codeAllocator(MyThread* t)
return &(processor(t)->codeAllocator); return &(processor(t)->codeAllocator);
} }
} // namespace local
} // namespace } // namespace
namespace vm { namespace vm {
@ -7683,8 +7705,8 @@ namespace vm {
Processor* Processor*
makeProcessor(System* system, Allocator* allocator) makeProcessor(System* system, Allocator* allocator)
{ {
return new (allocator->allocate(sizeof(MyProcessor))) return new (allocator->allocate(sizeof(local::MyProcessor)))
MyProcessor(system, allocator); local::MyProcessor(system, allocator);
} }
} // namespace vm } // namespace vm

View File

@ -15,6 +15,8 @@ using namespace vm;
namespace { namespace {
namespace local {
const bool DebugAppend = false; const bool DebugAppend = false;
const bool DebugCompile = false; const bool DebugCompile = false;
const bool DebugResources = false; const bool DebugResources = false;
@ -294,8 +296,6 @@ class Value: public Compiler::Operand {
reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this), reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this),
high(0), home(NoFrameIndex) high(0), home(NoFrameIndex)
{ } { }
virtual void addPredecessor(Context*, Event*) { }
Read* reads; Read* reads;
Read* lastRead; Read* lastRead;
@ -383,7 +383,7 @@ class Context {
unsigned unsigned
RegisterResource::toString(Context* c, char* buffer, unsigned bufferSize) RegisterResource::toString(Context* c, char* buffer, unsigned bufferSize)
{ {
return snprintf return vm::snprintf
(buffer, bufferSize, "register %d", static_cast<int> (buffer, bufferSize, "register %d", static_cast<int>
(this - c->registerResources)); (this - c->registerResources));
} }
@ -391,8 +391,8 @@ RegisterResource::toString(Context* c, char* buffer, unsigned bufferSize)
unsigned unsigned
FrameResource::toString(Context* c, char* buffer, unsigned bufferSize) FrameResource::toString(Context* c, char* buffer, unsigned bufferSize)
{ {
return snprintf(buffer, bufferSize, "frame %d", static_cast<int> return vm::snprintf(buffer, bufferSize, "frame %d", static_cast<int>
(this - c->frameResources)); (this - c->frameResources));
} }
class PoolPromise: public Promise { class PoolPromise: public Promise {
@ -924,12 +924,16 @@ deadBuddy(Context* c, Value* v, Read* r UNUSED)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
assert(c, v->buddy);
Value* next = v->buddy; Value* next = v->buddy;
v->buddy = v; v->buddy = v;
Value* p = next; Value* p = next;
while (p->buddy != v) p = p->buddy; while (p->buddy != v) p = p->buddy;
p->buddy = next; p->buddy = next;
assert(c, p->buddy);
for (SiteIterator it(v); it.hasMore();) { for (SiteIterator it(v); it.hasMore();) {
Site* s = it.next(); Site* s = it.next();
it.remove(c); it.remove(c);
@ -1335,10 +1339,10 @@ class ConstantSite: public Site {
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
if (value->resolved()) { if (value->resolved()) {
return snprintf return vm::snprintf
(buffer, bufferSize, "constant %"LLD, value->value()); (buffer, bufferSize, "constant %"LLD, value->value());
} else { } else {
return snprintf(buffer, bufferSize, "constant unresolved"); return vm::snprintf(buffer, bufferSize, "constant unresolved");
} }
} }
@ -1407,10 +1411,10 @@ class AddressSite: public Site {
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
if (address->resolved()) { if (address->resolved()) {
return snprintf return vm::snprintf
(buffer, bufferSize, "address %"LLD, address->value()); (buffer, bufferSize, "address %"LLD, address->value());
} else { } else {
return snprintf(buffer, bufferSize, "address unresolved"); return vm::snprintf(buffer, bufferSize, "address unresolved");
} }
} }
@ -1466,9 +1470,9 @@ class RegisterSite: public Site {
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
if (number != NoRegister) { if (number != NoRegister) {
return snprintf(buffer, bufferSize, "%p register %d", this, number); return vm::snprintf(buffer, bufferSize, "%p register %d", this, number);
} else { } else {
return snprintf(buffer, bufferSize, "%p register unacquired", this); return vm::snprintf(buffer, bufferSize, "%p register unacquired", this);
} }
} }
@ -1506,7 +1510,7 @@ class RegisterSite: public Site {
} }
RegisterResource* resource = c->registerResources + target.index; RegisterResource* resource = c->registerResources + target.index;
::acquire(c, resource, v, this); local::acquire(c, resource, v, this);
number = target.index; number = target.index;
} }
@ -1514,7 +1518,7 @@ class RegisterSite: public Site {
virtual void release(Context* c, Value* v) { virtual void release(Context* c, Value* v) {
assert(c, number != NoRegister); assert(c, number != NoRegister);
::release(c, c->registerResources + number, v, this); local::release(c, c->registerResources + number, v, this);
} }
virtual void freeze(Context* c, Value* v) { virtual void freeze(Context* c, Value* v) {
@ -1608,10 +1612,10 @@ class MemorySite: public Site {
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
if (acquired) { if (acquired) {
return snprintf(buffer, bufferSize, "memory %d 0x%x %d %d", return vm::snprintf(buffer, bufferSize, "memory %d 0x%x %d %d",
base, offset, index, scale); base, offset, index, scale);
} else { } else {
return snprintf(buffer, bufferSize, "memory unacquired"); return vm::snprintf(buffer, bufferSize, "memory unacquired");
} }
} }
@ -1659,7 +1663,8 @@ class MemorySite: public Site {
if (base == c->arch->stack()) { if (base == c->arch->stack()) {
assert(c, index == NoRegister); assert(c, index == NoRegister);
::acquire(c, c->frameResources + offsetToFrameIndex(c, offset), v, this); local::acquire
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
} }
acquired = true; acquired = true;
@ -1669,7 +1674,8 @@ class MemorySite: public Site {
if (base == c->arch->stack()) { if (base == c->arch->stack()) {
assert(c, index == NoRegister); assert(c, index == NoRegister);
::release(c, c->frameResources + offsetToFrameIndex(c, offset), v, this); local::release
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
} }
decrement(c, c->registerResources + base); decrement(c, c->registerResources + base);
@ -1842,10 +1848,10 @@ sitesToString(Context* c, Value* v, char* buffer, unsigned size)
} }
if (p->sites) { if (p->sites) {
total += snprintf(buffer + total, size - total, "%p has ", p); total += vm::snprintf(buffer + total, size - total, "%p has ", p);
total += sitesToString(c, p->sites, buffer + total, size - total); total += sitesToString(c, p->sites, buffer + total, size - total);
} else { } else {
total += snprintf(buffer + total, size - total, "%p has nothing", p); total += vm::snprintf(buffer + total, size - total, "%p has nothing", p);
} }
p = p->buddy; p = p->buddy;
@ -1940,7 +1946,7 @@ class SingleRead: public Read {
{ } { }
virtual bool intersect(SiteMask* mask, unsigned) { virtual bool intersect(SiteMask* mask, unsigned) {
*mask = ::intersect(*mask, this->mask); *mask = local::intersect(*mask, this->mask);
return true; return true;
} }
@ -2222,7 +2228,8 @@ void
addRead(Context* c, Event* e, Value* v, Read* r) addRead(Context* c, Event* e, Value* v, Read* r)
{ {
if (DebugReads) { if (DebugReads) {
fprintf(stderr, "add read %p to %p last %p event %p (%s)\n", r, v, v->lastRead, e, (e ? e->name() : 0)); fprintf(stderr, "add read %p to %p last %p event %p (%s)\n",
r, v, v->lastRead, e, (e ? e->name() : 0));
} }
r->value = v; r->value = v;
@ -2307,11 +2314,11 @@ saveLocals(Context* c, Event* e)
if (local->value) { if (local->value) {
if (DebugReads) { if (DebugReads) {
fprintf(stderr, "local save read %p at %d of %d\n", fprintf(stderr, "local save read %p at %d of %d\n",
local->value, ::frameIndex(c, li), totalFrameSize(c)); local->value, local::frameIndex(c, li), totalFrameSize(c));
} }
addRead(c, e, local->value, read addRead(c, e, local->value, read
(c, SiteMask(1 << MemoryOperand, 0, ::frameIndex(c, li)))); (c, SiteMask(1 << MemoryOperand, 0, local::frameIndex(c, li))));
} }
} }
} }
@ -2457,7 +2464,7 @@ class CallEvent: public Event {
while (stack) { while (stack) {
if (stack->value) { if (stack->value) {
unsigned logicalIndex = ::frameIndex unsigned logicalIndex = local::frameIndex
(c, stack->index + c->localFootprint); (c, stack->index + c->localFootprint);
if (DebugReads) { if (DebugReads) {
@ -2783,6 +2790,9 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize,
} else { } else {
target = src->source; target = src->source;
assert(c, src);
assert(c, dst);
addBuddy(src, dst); addBuddy(src, dst);
if (DebugMoves) { if (DebugMoves) {
@ -3207,12 +3217,16 @@ removeBuddy(Context* c, Value* v)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
assert(c, v->buddy);
Value* next = v->buddy; Value* next = v->buddy;
v->buddy = v; v->buddy = v;
Value* p = next; Value* p = next;
while (p->buddy != v) p = p->buddy; while (p->buddy != v) p = p->buddy;
p->buddy = next; p->buddy = next;
assert(c, p->buddy);
if (not live(next)) { if (not live(next)) {
clearSites(c, next); clearSites(c, next);
} }
@ -3499,8 +3513,8 @@ appendCombine(Context* c, TernaryOperation type,
if (thunk) { if (thunk) {
Stack* oldStack = c->stack; Stack* oldStack = c->stack;
::push(c, ceiling(secondSize, BytesPerWord), second, false); local::push(c, ceiling(secondSize, BytesPerWord), second, false);
::push(c, ceiling(firstSize, BytesPerWord), first, false); local::push(c, ceiling(firstSize, BytesPerWord), first, false);
Stack* argumentStack = c->stack; Stack* argumentStack = c->stack;
c->stack = oldStack; c->stack = oldStack;
@ -3722,8 +3736,6 @@ class BranchEvent: public Event {
BranchEvent(Context* c, UnaryOperation type, Value* address, bool exit): BranchEvent(Context* c, UnaryOperation type, Value* address, bool exit):
Event(c), type(type), address(address), exit(exit) Event(c), type(type), address(address), exit(exit)
{ {
address->addPredecessor(c, this);
bool thunk; bool thunk;
uint8_t typeMask; uint8_t typeMask;
uint64_t registerMask; uint64_t registerMask;
@ -3980,6 +3992,9 @@ class BuddyEvent: public Event {
// fprintf(stderr, "original %p buddy %p\n", original, buddy); // fprintf(stderr, "original %p buddy %p\n", original, buddy);
assert(c, hasSite(original)); assert(c, hasSite(original));
assert(c, original);
assert(c, buddy);
addBuddy(original, buddy); addBuddy(original, buddy);
popRead(c, this, original); popRead(c, this, original);
@ -4104,7 +4119,8 @@ append(Context* c, Event* e)
e->logicalInstruction->index); e->logicalInstruction->index);
} }
Link* link = ::link(c, p, e->predecessors, e, p->successors, c->forkState); Link* link = local::link
(c, p, e->predecessors, e, p->successors, c->forkState);
e->predecessors = link; e->predecessors = link;
p->successors = link; p->successors = link;
} }
@ -4457,11 +4473,12 @@ resolveBranchSites(Context* c, Event* e, SiteRecordList* frozen)
{ {
if (e->successors->nextSuccessor and e->junctionSites == 0) { if (e->successors->nextSuccessor and e->junctionSites == 0) {
unsigned footprint = frameFootprint(c, e->stackAfter); unsigned footprint = frameFootprint(c, e->stackAfter);
Site* branchSites[footprint]; RUNTIME_ARRAY(Site*, branchSites, footprint);
memset(branchSites, 0, sizeof(Site*) * footprint); memset(RUNTIME_ARRAY_BODY(branchSites), 0, sizeof(Site*) * footprint);
if (not resolveSourceSites(c, e, frozen, branchSites)) { if (not resolveSourceSites(c, e, frozen, RUNTIME_ARRAY_BODY(branchSites)))
resolveTargetSites(c, e, frozen, branchSites); {
resolveTargetSites(c, e, frozen, RUNTIME_ARRAY_BODY(branchSites));
} }
} }
} }
@ -4560,6 +4577,8 @@ restore(Context* c, Event* e, Snapshot* snapshots)
// fprintf(stderr, "restore %p buddy %p sites %s live %p\n", // fprintf(stderr, "restore %p buddy %p sites %s live %p\n",
// s->value, s->value->buddy, buffer, live(s->value)); // s->value, s->value->buddy, buffer, live(s->value));
assert(c, s->buddy);
s->value->buddy = s->buddy; s->value->buddy = s->buddy;
} }
@ -4577,8 +4596,8 @@ restore(Context* c, Event* e, Snapshot* snapshots)
void void
populateSources(Context* c, Event* e) populateSources(Context* c, Event* e)
{ {
SiteRecord frozenRecords[e->readCount]; RUNTIME_ARRAY(SiteRecord, frozenRecords, e->readCount);
SiteRecordList frozen(frozenRecords, e->readCount); SiteRecordList frozen(RUNTIME_ARRAY_BODY(frozenRecords), e->readCount);
for (Read* r = e->reads; r; r = r->eventNext) { for (Read* r = e->reads; r; r = r->eventNext) {
r->value->source = readSource(c, r); r->value->source = readSource(c, r);
@ -4752,8 +4771,8 @@ compile(Context* c)
} }
unsigned footprint = frameFootprint(c, e->stackAfter); unsigned footprint = frameFootprint(c, e->stackAfter);
SiteRecord frozenRecords[footprint]; RUNTIME_ARRAY(SiteRecord, frozenRecords, footprint);
SiteRecordList frozen(frozenRecords, footprint); SiteRecordList frozen(RUNTIME_ARRAY_BODY(frozenRecords), footprint);
bool branch = e->isBranch(); bool branch = e->isBranch();
if (branch and e->successors) { if (branch and e->successors) {
@ -4803,7 +4822,7 @@ compile(Context* c)
block->assemblerBlock = a->endBlock(e->next != 0); block->assemblerBlock = a->endBlock(e->next != 0);
if (e->next) { if (e->next) {
block = ::block(c, e->next); block = local::block(c, e->next);
} }
} }
} }
@ -4962,13 +4981,13 @@ class MyCompiler: public Compiler {
} }
virtual State* saveState() { virtual State* saveState() {
State* s = ::saveState(&c); State* s = local::saveState(&c);
restoreState(s); restoreState(s);
return s; return s;
} }
virtual void restoreState(State* state) { virtual void restoreState(State* state) {
::restoreState(&c, static_cast<ForkState*>(state)); local::restoreState(&c, static_cast<ForkState*>(state));
} }
virtual Subroutine* startSubroutine() { virtual Subroutine* startSubroutine() {
@ -4978,7 +4997,7 @@ class MyCompiler: public Compiler {
virtual void endSubroutine(Subroutine* subroutine) { virtual void endSubroutine(Subroutine* subroutine) {
appendCleanLocals(&c); appendCleanLocals(&c);
static_cast<MySubroutine*>(subroutine)->forkState = ::saveState(&c); static_cast<MySubroutine*>(subroutine)->forkState = local::saveState(&c);
} }
virtual void linkSubroutine(Subroutine* subroutine) { virtual void linkSubroutine(Subroutine* subroutine) {
@ -5042,7 +5061,7 @@ class MyCompiler: public Compiler {
p->stackAfter = c.stack; p->stackAfter = c.stack;
p->localsAfter = c.locals; p->localsAfter = c.locals;
Link* link = ::link Link* link = local::link
(&c, p, e->predecessors, e, p->successors, c.forkState); (&c, p, e->predecessors, e, p->successors, c.forkState);
e->predecessors = link; e->predecessors = link;
p->successors = link; p->successors = link;
@ -5141,11 +5160,11 @@ class MyCompiler: public Compiler {
} }
virtual Operand* promiseConstant(Promise* value) { virtual Operand* promiseConstant(Promise* value) {
return ::value(&c, ::constantSite(&c, value)); return local::value(&c, local::constantSite(&c, value));
} }
virtual Operand* address(Promise* address) { virtual Operand* address(Promise* address) {
return value(&c, ::addressSite(&c, address)); return value(&c, local::addressSite(&c, address));
} }
virtual Operand* memory(Operand* base, virtual Operand* memory(Operand* base,
@ -5174,13 +5193,13 @@ class MyCompiler: public Compiler {
assert(&c, footprint == 1); assert(&c, footprint == 1);
Value* v = value(&c); Value* v = value(&c);
Stack* s = ::stack(&c, v, c.stack); Stack* s = local::stack(&c, v, c.stack);
v->home = frameIndex(&c, s->index + c.localFootprint); v->home = frameIndex(&c, s->index + c.localFootprint);
c.stack = s; c.stack = s;
} }
virtual void push(unsigned footprint, Operand* value) { virtual void push(unsigned footprint, Operand* value) {
::push(&c, footprint, static_cast<Value*>(value), true); local::push(&c, footprint, static_cast<Value*>(value), true);
} }
virtual void save(unsigned footprint, Operand* value) { virtual void save(unsigned footprint, Operand* value) {
@ -5194,7 +5213,7 @@ class MyCompiler: public Compiler {
} }
virtual Operand* pop(unsigned footprint) { virtual Operand* pop(unsigned footprint) {
return ::pop(&c, footprint); return local::pop(&c, footprint);
} }
virtual void pushed() { virtual void pushed() {
@ -5203,7 +5222,7 @@ class MyCompiler: public Compiler {
(&c, v, frameIndex (&c, v, frameIndex
(&c, (c.stack ? c.stack->index : 0) + c.localFootprint)); (&c, (c.stack ? c.stack->index : 0) + c.localFootprint));
Stack* s = ::stack(&c, v, c.stack); Stack* s = local::stack(&c, v, c.stack);
v->home = frameIndex(&c, s->index + c.localFootprint); v->home = frameIndex(&c, s->index + c.localFootprint);
c.stack = s; c.stack = s;
} }
@ -5271,17 +5290,17 @@ class MyCompiler: public Compiler {
unsigned footprint = 0; unsigned footprint = 0;
unsigned size = BytesPerWord; unsigned size = BytesPerWord;
Value* arguments[argumentCount]; RUNTIME_ARRAY(Value*, arguments, argumentCount);
int index = 0; int index = 0;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
Value* o = va_arg(a, Value*); Value* o = va_arg(a, Value*);
if (o) { if (o) {
if (bigEndian and size > BytesPerWord) { if (bigEndian and size > BytesPerWord) {
arguments[index++] = o->high; RUNTIME_ARRAY_BODY(arguments)[index++] = o->high;
} }
arguments[index] = o; RUNTIME_ARRAY_BODY(arguments)[index] = o;
if ((not bigEndian) and size > BytesPerWord) { if ((not bigEndian) and size > BytesPerWord) {
arguments[++index] = o->high; RUNTIME_ARRAY_BODY(arguments)[++index] = o->high;
} }
size = BytesPerWord; size = BytesPerWord;
++ index; ++ index;
@ -5295,7 +5314,8 @@ class MyCompiler: public Compiler {
Stack* argumentStack = c.stack; Stack* argumentStack = c.stack;
for (int i = index - 1; i >= 0; --i) { for (int i = index - 1; i >= 0; --i) {
argumentStack = ::stack(&c, arguments[i], argumentStack); argumentStack = local::stack
(&c, RUNTIME_ARRAY_BODY(arguments)[i], argumentStack);
} }
Value* result = value(&c); Value* result = value(&c);
@ -5391,11 +5411,11 @@ class MyCompiler: public Compiler {
} }
virtual void storeLocal(unsigned footprint, Operand* src, unsigned index) { virtual void storeLocal(unsigned footprint, Operand* src, unsigned index) {
::storeLocal(&c, footprint, static_cast<Value*>(src), index, true); local::storeLocal(&c, footprint, static_cast<Value*>(src), index, true);
} }
virtual Operand* loadLocal(unsigned footprint, unsigned index) { virtual Operand* loadLocal(unsigned footprint, unsigned index) {
return ::loadLocal(&c, footprint, index); return local::loadLocal(&c, footprint, index);
} }
virtual void saveLocals() { virtual void saveLocals() {
@ -5578,7 +5598,7 @@ class MyCompiler: public Compiler {
} }
virtual unsigned compile() { virtual unsigned compile() {
return c.machineCodeSize = ::compile(&c); return c.machineCodeSize = local::compile(&c);
} }
virtual unsigned poolSize() { virtual unsigned poolSize() {
@ -5621,9 +5641,11 @@ class MyCompiler: public Compiler {
} }
Context c; Context c;
::Client client; local::Client client;
}; };
} // namespace local
} // namespace } // namespace
namespace vm { namespace vm {
@ -5632,8 +5654,8 @@ Compiler*
makeCompiler(System* system, Assembler* assembler, Zone* zone, makeCompiler(System* system, Assembler* assembler, Zone* zone,
Compiler::Client* client) Compiler::Client* client)
{ {
return new (zone->allocate(sizeof(MyCompiler))) return new (zone->allocate(sizeof(local::MyCompiler)))
MyCompiler(system, assembler, zone, client); local::MyCompiler(system, assembler, zone, client);
} }
} // namespace vm } // namespace vm

View File

@ -149,7 +149,7 @@ Avian_gnu_classpath_VMSystemProperties_preInit
setProperty(t, method, properties, "java.library.path", setProperty(t, method, properties, "java.library.path",
LIBRARY_PATH_SENTINAL); LIBRARY_PATH_SENTINAL);
#ifdef WIN32 #ifdef PLATFORM_WINDOWS
# define FILE_SEPARATOR "\\" # define FILE_SEPARATOR "\\"
setProperty(t, method, properties, "line.separator", "\r\n"); setProperty(t, method, properties, "line.separator", "\r\n");
@ -182,17 +182,16 @@ Avian_gnu_classpath_VMSystemProperties_preInit
setProperty(t, method, properties, "user.dir", getenv("PWD")); setProperty(t, method, properties, "user.dir", getenv("PWD"));
#endif #endif
#ifdef __i386__ #ifdef ARCH_x86_32
setProperty(t, method, properties, "gnu.cpu.endian", "little"); setProperty(t, method, properties, "gnu.cpu.endian", "little");
setProperty(t, method, properties, "os.arch", "x86"); setProperty(t, method, properties, "os.arch", "x86");
#elif defined __x86_64__ #elif defined ARCH_x86_64
setProperty(t, method, properties, "gnu.cpu.endian", "little"); setProperty(t, method, properties, "gnu.cpu.endian", "little");
setProperty(t, method, properties, "os.arch", "x86_64"); setProperty(t, method, properties, "os.arch", "x86_64");
#elif defined(__ppc__) || defined(__powerpc__) \ #elif defined ARCH_powerpc
|| defined(__ppc64__) || defined(__powerpc64__)
setProperty(t, method, properties, "gnu.cpu.endian", "big"); setProperty(t, method, properties, "gnu.cpu.endian", "big");
setProperty(t, method, properties, "os.arch", "ppc"); setProperty(t, method, properties, "os.arch", "ppc");
#elif defined __arm__ #elif defined ARCH_arm
setProperty(t, method, properties, "os.arch", "arm"); setProperty(t, method, properties, "os.arch", "arm");
#else #else
setProperty(t, method, properties, "os.arch", "unknown"); setProperty(t, method, properties, "os.arch", "unknown");

View File

@ -16,6 +16,8 @@ using namespace vm;
namespace { namespace {
namespace local {
// an object must survive TenureThreshold + 2 garbage collections // an object must survive TenureThreshold + 2 garbage collections
// before being copied to gen2 (must be at least 1): // before being copied to gen2 (must be at least 1):
const unsigned TenureThreshold = 3; const unsigned TenureThreshold = 3;
@ -1194,7 +1196,7 @@ void
collect(Context* c, void** p, void* target, unsigned offset) collect(Context* c, void** p, void* target, unsigned offset)
{ {
void* original = mask(*p); void* original = mask(*p);
void* parent = 0; void* parent_ = 0;
if (Debug) { if (Debug) {
fprintf(stderr, "update %p (%s) at %p (%s)\n", fprintf(stderr, "update %p (%s) at %p (%s)\n",
@ -1202,7 +1204,7 @@ collect(Context* c, void** p, void* target, unsigned offset)
} }
bool needsVisit; bool needsVisit;
set(p, update(c, mask(p), target, offset, &needsVisit)); local::set(p, update(c, mask(p), target, offset, &needsVisit));
if (Debug) { if (Debug) {
fprintf(stderr, " result: %p (%s) (visit? %d)\n", fprintf(stderr, " result: %p (%s) (visit? %d)\n",
@ -1262,7 +1264,7 @@ collect(Context* c, void** p, void* target, unsigned offset)
second = offset; second = offset;
} }
} else { } else {
set(copy, offset, childCopy); local::set(copy, offset, childCopy);
} }
if (visits > 1 and total > 2 and (second or needsVisit)) { if (visits > 1 and total > 2 and (second or needsVisit)) {
@ -1301,16 +1303,16 @@ collect(Context* c, void** p, void* target, unsigned offset)
if (walker.visits) { if (walker.visits) {
// descend // descend
if (walker.visits > 1) { if (walker.visits > 1) {
::parent(c, original) = parent; parent(c, original) = parent_;
parent = original; parent_ = original;
} }
original = get(copy, walker.first); original = get(copy, walker.first);
set(copy, walker.first, follow(c, original)); local::set(copy, walker.first, follow(c, original));
goto visit; goto visit;
} else { } else {
// ascend // ascend
original = parent; original = parent_;
} }
} }
@ -1359,9 +1361,9 @@ collect(Context* c, void** p, void* target, unsigned offset)
assert(c, walker.total > 1); assert(c, walker.total > 1);
if (walker.total == 3 and bitsetHasMore(bitset(c, original))) { if (walker.total == 3 and bitsetHasMore(bitset(c, original))) {
parent = original; parent_ = original;
} else { } else {
parent = ::parent(c, original); parent_ = parent(c, original);
} }
if (Debug) { if (Debug) {
@ -1375,7 +1377,7 @@ collect(Context* c, void** p, void* target, unsigned offset)
} }
original = get(copy, walker.next); original = get(copy, walker.next);
set(copy, walker.next, follow(c, original)); local::set(copy, walker.next, follow(c, original));
goto visit; goto visit;
} else { } else {
return; return;
@ -1475,7 +1477,7 @@ visitMarkedFixies(Context* c)
{ } { }
virtual bool visit(unsigned offset) { virtual bool visit(unsigned offset) {
collect(c, p, offset); local::collect(c, p, offset);
return true; return true;
} }
@ -1559,7 +1561,7 @@ collect2(Context* c)
Visitor(Context* c): c(c) { } Visitor(Context* c): c(c) { }
virtual void visit(void* p) { virtual void visit(void* p) {
collect(c, static_cast<void**>(p)); local::collect(c, static_cast<void**>(p));
visitMarkedFixies(c); visitMarkedFixies(c);
} }
@ -1745,11 +1747,11 @@ class MyHeap: public Heap {
} }
virtual void* tryAllocate(unsigned size) { virtual void* tryAllocate(unsigned size) {
return ::tryAllocate(&c, size); return local::tryAllocate(&c, size);
} }
virtual void* allocate(unsigned size) { virtual void* allocate(unsigned size) {
void* p = ::tryAllocate(&c, size); void* p = local::tryAllocate(&c, size);
expect(c.system, p); expect(c.system, p);
return p; return p;
} }
@ -1762,7 +1764,7 @@ class MyHeap: public Heap {
c.mode = type; c.mode = type;
c.incomingFootprint = incomingFootprint; c.incomingFootprint = incomingFootprint;
::collect(&c); local::collect(&c);
} }
virtual void* allocateFixed(Allocator* allocator, unsigned sizeInWords, virtual void* allocateFixed(Allocator* allocator, unsigned sizeInWords,
@ -1856,10 +1858,10 @@ class MyHeap: public Heap {
if (Debug) { if (Debug) {
fprintf(stderr, "follow %p (%s) to %p (%s)\n", fprintf(stderr, "follow %p (%s) to %p (%s)\n",
p, segment(&c, p), p, segment(&c, p),
::follow(&c, p), segment(&c, ::follow(&c, p))); local::follow(&c, p), segment(&c, local::follow(&c, p)));
} }
return ::follow(&c, p); return local::follow(&c, p);
} else { } else {
return p; return p;
} }
@ -1903,6 +1905,8 @@ class MyHeap: public Heap {
Context c; Context c;
}; };
} // namespace local
} // namespace } // namespace
namespace vm { namespace vm {
@ -1910,7 +1914,8 @@ namespace vm {
Heap* Heap*
makeHeap(System* system, unsigned limit) makeHeap(System* system, unsigned limit)
{ {
return new (system->tryAllocate(sizeof(MyHeap))) MyHeap(system, limit); return new (system->tryAllocate(sizeof(local::MyHeap)))
local::MyHeap(system, limit);
} }
} // namespace vm } // namespace vm

View File

@ -1854,17 +1854,17 @@ int
parseSize(const char* s) parseSize(const char* s)
{ {
unsigned length = strlen(s); unsigned length = strlen(s);
char buffer[length + 1]; RUNTIME_ARRAY(char, buffer, length + 1);
if (length == 0) { if (length == 0) {
return 0; return 0;
} else if (s[length - 1] == 'k') { } else if (s[length - 1] == 'k') {
memcpy(buffer, s, length - 1); memcpy(RUNTIME_ARRAY_BODY(buffer), s, length - 1);
buffer[length] = 0; RUNTIME_ARRAY_BODY(buffer)[length] = 0;
return atoi(buffer) * 1024; return atoi(RUNTIME_ARRAY_BODY(buffer)) * 1024;
} else if (s[length - 1] == 'm') { } else if (s[length - 1] == 'm') {
memcpy(buffer, s, length - 1); memcpy(RUNTIME_ARRAY_BODY(buffer), s, length - 1);
buffer[length] = 0; RUNTIME_ARRAY_BODY(buffer)[length] = 0;
return atoi(buffer) * 1024 * 1024; return atoi(RUNTIME_ARRAY_BODY(buffer)) * 1024 * 1024;
} else { } else {
return atoi(s); return atoi(s);
} }
@ -2144,8 +2144,8 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
unsigned cpl = strlen(classpath); unsigned cpl = strlen(classpath);
unsigned classpathBufferSize = bcppl + bcpl + bcpal + cpl + 4; unsigned classpathBufferSize = bcppl + bcpl + bcpal + cpl + 4;
char classpathBuffer[classpathBufferSize]; RUNTIME_ARRAY(char, classpathBuffer, classpathBufferSize);
char* classpathPointer = classpathBuffer; char* classpathPointer = RUNTIME_ARRAY_BODY(classpathBuffer);
append(&classpathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR); append(&classpathPointer, bootClasspathPrepend, bcppl, PATH_SEPARATOR);
append(&classpathPointer, bootClasspath, bcpl, PATH_SEPARATOR); append(&classpathPointer, bootClasspath, bcpl, PATH_SEPARATOR);
@ -2154,7 +2154,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
System* s = makeSystem(crashDumpDirectory); System* s = makeSystem(crashDumpDirectory);
Heap* h = makeHeap(s, heapLimit); Heap* h = makeHeap(s, heapLimit);
Finder* f = makeFinder(s, classpathBuffer, bootLibrary); Finder* f = makeFinder(s, RUNTIME_ARRAY_BODY(classpathBuffer), bootLibrary);
Processor* p = makeProcessor(s, h); Processor* p = makeProcessor(s, h);
const char** properties = static_cast<const char**> const char** properties = static_cast<const char**>

View File

@ -64,13 +64,14 @@ void
dispose(Thread* t, Thread* o, bool remove) dispose(Thread* t, Thread* o, bool remove)
{ {
if (remove) { if (remove) {
// debug #ifndef NDEBUG
expect(t, find(t->m->rootThread, o)); expect(t, find(t->m->rootThread, o));
unsigned c = count(t->m->rootThread, o); unsigned c = count(t->m->rootThread, o);
Thread* threads[c]; Thread** threads = static_cast<Thread**>
(allocate(t->m->system, c * sizeof(Thread*)));
fill(t->m->rootThread, o, threads); fill(t->m->rootThread, o, threads);
// end debug #endif
if (o->parent) { if (o->parent) {
Thread* previous = 0; Thread* previous = 0;
@ -110,13 +111,13 @@ dispose(Thread* t, Thread* o, bool remove)
abort(t); abort(t);
} }
// debug #ifndef NDEBUG
expect(t, not find(t->m->rootThread, o)); expect(t, not find(t->m->rootThread, o));
for (unsigned i = 0; i < c; ++i) { for (unsigned i = 0; i < c; ++i) {
expect(t, find(t->m->rootThread, threads[i])); expect(t, find(t->m->rootThread, threads[i]));
} }
// end debug #endif
} }
o->dispose(); o->dispose();
@ -211,6 +212,23 @@ killZombies(Thread* t, Thread* o)
} }
} }
object
makeJavaThread(Thread* t, Thread* parent)
{
object group;
if (parent) {
group = threadGroup(t, parent->javaThread);
} else {
group = makeThreadGroup(t, 0, 0);
}
const unsigned NewState = 0;
const unsigned NormalPriority = 5;
return makeThread
(t, 0, 0, 0, NewState, NormalPriority, 0, 0, 0, t->m->loader, 0, 0, group);
}
unsigned unsigned
footprint(Thread* t) footprint(Thread* t)
{ {
@ -547,20 +565,14 @@ postCollect(Thread* t)
void void
finalizeObject(Thread* t, object o) finalizeObject(Thread* t, object o)
{ {
if (t->state == Thread::ExitState) {
// don't waste time running Java finalizers if we're exiting the
// VM
return;
}
for (object c = objectClass(t, o); c; c = classSuper(t, c)) { for (object c = objectClass(t, o); c; c = classSuper(t, c)) {
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
object m = arrayBody(t, classMethodTable(t, c), i); object m = arrayBody(t, classMethodTable(t, c), i);
if (strcmp(reinterpret_cast<const int8_t*>("finalize"), if (vm::strcmp(reinterpret_cast<const int8_t*>("finalize"),
&byteArrayBody(t, methodName(t, m), 0)) == 0 &byteArrayBody(t, methodName(t, m), 0)) == 0
and strcmp(reinterpret_cast<const int8_t*>("()V"), and vm::strcmp(reinterpret_cast<const int8_t*>("()V"),
&byteArrayBody(t, methodSpec(t, m), 0)) == 0) &byteArrayBody(t, methodSpec(t, m), 0)) == 0)
{ {
t->m->processor->invoke(t, m, o); t->m->processor->invoke(t, m, o);
t->exception = 0; t->exception = 0;
@ -577,7 +589,7 @@ makeByteArray(Thread* t, const char* format, va_list a)
const int Size = 256; const int Size = 256;
char buffer[Size]; char buffer[Size];
int r = vsnprintf(buffer, Size - 1, format, a); int r = vm::vsnprintf(buffer, Size - 1, format, a);
expect(t, r >= 0 and r < Size - 1); expect(t, r >= 0 and r < Size - 1);
object s = makeByteArray(t, strlen(buffer) + 1); object s = makeByteArray(t, strlen(buffer) + 1);
@ -1020,7 +1032,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
object staticValueTable = makeIntArray(t, count); object staticValueTable = makeIntArray(t, count);
PROTECT(t, staticValueTable); PROTECT(t, staticValueTable);
uint8_t staticTypes[count]; RUNTIME_ARRAY(uint8_t, staticTypes, count);
for (unsigned i = 0; i < count; ++i) { for (unsigned i = 0; i < count; ++i) {
unsigned flags = s.read2(); unsigned flags = s.read2();
@ -1037,8 +1049,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
object name = singletonObject(t, pool, s.read2() - 1); object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4(); unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("ConstantValue"), if (vm::strcmp(reinterpret_cast<const int8_t*>("ConstantValue"),
&byteArrayBody(t, name, 0)) == 0) &byteArrayBody(t, name, 0)) == 0)
{ {
value = s.read2(); value = s.read2();
} else { } else {
@ -1069,7 +1081,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
intArrayBody(t, staticValueTable, staticCount) = value; intArrayBody(t, staticValueTable, staticCount) = value;
staticTypes[staticCount++] = code; RUNTIME_ARRAY_BODY(staticTypes)[staticCount++] = code;
} else { } else {
if (flags & ACC_FINAL) { if (flags & ACC_FINAL) {
classVmFlags(t, class_) |= HasFinalMemberFlag; classVmFlags(t, class_) |= HasFinalMemberFlag;
@ -1098,7 +1110,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
(&singletonBody(t, staticTable, 0)); (&singletonBody(t, staticTable, 0));
for (unsigned i = 0, offset = 0; i < staticCount; ++i) { for (unsigned i = 0, offset = 0; i < staticCount; ++i) {
unsigned size = fieldSize(t, staticTypes[i]); unsigned size = fieldSize(t, RUNTIME_ARRAY_BODY(staticTypes)[i]);
unsigned excess = offset % size; unsigned excess = offset % size;
if (excess) { if (excess) {
offset += BytesPerWord - excess; offset += BytesPerWord - excess;
@ -1106,7 +1118,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
unsigned value = intArrayBody(t, staticValueTable, i); unsigned value = intArrayBody(t, staticValueTable, i);
if (value) { if (value) {
switch (staticTypes[i]) { switch (RUNTIME_ARRAY_BODY(staticTypes)[i]) {
case ByteField: case ByteField:
case BooleanField: case BooleanField:
body[offset] = singletonValue(t, pool, value - 1); body[offset] = singletonValue(t, pool, value - 1);
@ -1139,7 +1151,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
} }
} }
if (staticTypes[i] == ObjectField) { if (RUNTIME_ARRAY_BODY(staticTypes)[i] == ObjectField) {
singletonMarkObject(t, staticTable, offset / BytesPerWord); singletonMarkObject(t, staticTable, offset / BytesPerWord);
} }
@ -1227,8 +1239,8 @@ parseCode(Thread* t, Stream& s, object pool)
object name = singletonObject(t, pool, s.read2() - 1); object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4(); unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("LineNumberTable"), if (vm::strcmp(reinterpret_cast<const int8_t*>("LineNumberTable"),
&byteArrayBody(t, name, 0)) == 0) &byteArrayBody(t, name, 0)) == 0)
{ {
unsigned lntLength = s.read2(); unsigned lntLength = s.read2();
object lnt = makeLineNumberTable(t, lntLength); object lnt = makeLineNumberTable(t, lntLength);
@ -1373,8 +1385,8 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
object name = singletonObject(t, pool, s.read2() - 1); object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4(); unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("Code"), if (vm::strcmp(reinterpret_cast<const int8_t*>("Code"),
&byteArrayBody(t, name, 0)) == 0) &byteArrayBody(t, name, 0)) == 0)
{ {
code = parseCode(t, s, pool); code = parseCode(t, s, pool);
} else { } else {
@ -1423,10 +1435,10 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
} }
if (UNLIKELY((classFlags(t, class_) & ACC_INTERFACE) == 0 if (UNLIKELY((classFlags(t, class_) & ACC_INTERFACE) == 0
and strcmp and vm::strcmp
(reinterpret_cast<const int8_t*>("finalize"), (reinterpret_cast<const int8_t*>("finalize"),
&byteArrayBody(t, methodName(t, method), 0)) == 0 &byteArrayBody(t, methodName(t, method), 0)) == 0
and strcmp and vm::strcmp
(reinterpret_cast<const int8_t*>("()V"), (reinterpret_cast<const int8_t*>("()V"),
&byteArrayBody(t, methodSpec(t, method), 0)) == 0 &byteArrayBody(t, methodSpec(t, method), 0)) == 0
and (not emptyMethod(t, method)))) and (not emptyMethod(t, method))))
@ -1436,13 +1448,14 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
} else { } else {
methodOffset(t, method) = i; methodOffset(t, method) = i;
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"), if (vm::strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0) &byteArrayBody(t, methodName(t, method), 0)) == 0)
{ {
methodVmFlags(t, method) |= ClassInitFlag; methodVmFlags(t, method) |= ClassInitFlag;
classVmFlags(t, class_) |= NeedInitFlag; classVmFlags(t, class_) |= NeedInitFlag;
} else if (strcmp(reinterpret_cast<const int8_t*>("<init>"), } else if (vm::strcmp
&byteArrayBody(t, methodName(t, method), 0)) == 0) (reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
{ {
methodVmFlags(t, method) |= ConstructorFlag; methodVmFlags(t, method) |= ConstructorFlag;
} }
@ -2016,6 +2029,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
processor(processor), processor(processor),
rootThread(0), rootThread(0),
exclusive(0), exclusive(0),
finalizeThread(0),
jniReferences(0), jniReferences(0),
properties(properties), properties(properties),
propertyCount(propertyCount), propertyCount(propertyCount),
@ -2044,6 +2058,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
weakReferences(0), weakReferences(0),
tenuredWeakReferences(0), tenuredWeakReferences(0),
shutdownHooks(0), shutdownHooks(0),
objectsToFinalize(0),
unsafe(false), unsafe(false),
triedBuiltinOnLoad(false), triedBuiltinOnLoad(false),
heapPoolIndex(0) heapPoolIndex(0)
@ -2172,23 +2187,11 @@ Thread::init()
parent->child = this; parent->child = this;
} }
if (javaThread) { if (javaThread == 0) {
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this); this->javaThread = makeJavaThread(this, parent);
} else {
object group;
if (parent) {
group = threadGroup(this, parent->javaThread);
} else {
group = makeThreadGroup(this, 0, 0);
}
const unsigned NewState = 0;
const unsigned NormalPriority = 5;
this->javaThread = makeThread
(this, reinterpret_cast<int64_t>(this), 0, 0, NewState, NormalPriority,
0, 0, 0, m->loader, 0, 0, group);
} }
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
} }
void void
@ -2256,6 +2259,22 @@ shutDown(Thread* t)
} }
} }
} }
// tell finalize thread to exit and wait for it to do so
{ ACQUIRE(t, t->m->stateLock);
Thread* finalizeThread = t->m->finalizeThread;
if (finalizeThread) {
t->m->finalizeThread = 0;
t->m->stateLock->notifyAll(t->systemThread);
while (finalizeThread->state != Thread::ZombieState
and finalizeThread->state != Thread::JoinedState)
{
ENTER(t, Thread::IdleState);
t->m->stateLock->wait(t->systemThread, 0);
}
}
}
} }
void void
@ -2519,7 +2538,7 @@ makeNewGeneral(Thread* t, object class_)
} }
if (classVmFlags(t, class_) & HasFinalizerFlag) { if (classVmFlags(t, class_) & HasFinalizerFlag) {
addFinalizer(t, instance, finalizeObject); addFinalizer(t, instance, 0);
} }
return instance; return instance;
@ -2643,8 +2662,8 @@ classInitializer(Thread* t, object class_)
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, class_)); ++i) { for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, class_)); ++i) {
object o = arrayBody(t, classMethodTable(t, class_), i); object o = arrayBody(t, classMethodTable(t, class_), i);
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"), if (vm::strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, o), 0)) == 0) &byteArrayBody(t, methodName(t, o), 0)) == 0)
{ {
return o; return o;
} }
@ -2747,12 +2766,12 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
{ {
PROTECT(t, loader); PROTECT(t, loader);
class Client : public Stream::Client { class Client: public Stream::Client {
public: public:
Client(Thread* t): t(t) { } Client(Thread* t): t(t) { }
virtual void NO_RETURN handleError() { virtual void NO_RETURN handleError() {
abort(t); vm::abort(t);
} }
private: private:
@ -2857,11 +2876,15 @@ resolveSystemClass(Thread* t, object spec)
if (byteArrayBody(t, spec, 0) == '[') { if (byteArrayBody(t, spec, 0) == '[') {
class_ = resolveArrayClass(t, t->m->loader, spec); class_ = resolveArrayClass(t, t->m->loader, spec);
} else { } else {
char file[byteArrayLength(t, spec) + 6]; RUNTIME_ARRAY(char, file, byteArrayLength(t, spec) + 6);
memcpy(file, &byteArrayBody(t, spec, 0), byteArrayLength(t, spec) - 1); memcpy(RUNTIME_ARRAY_BODY(file),
memcpy(file + byteArrayLength(t, spec) - 1, ".class", 7); &byteArrayBody(t, spec, 0),
byteArrayLength(t, spec) - 1);
memcpy(RUNTIME_ARRAY_BODY(file) + byteArrayLength(t, spec) - 1,
".class",
7);
System::Region* region = t->m->finder->find(file); System::Region* region = t->m->finder->find(RUNTIME_ARRAY_BODY(file));
if (region) { if (region) {
if (Verbose) { if (Verbose) {
@ -3224,10 +3247,10 @@ findInTable(Thread* t, object table, object name, object spec,
if (table) { if (table) {
for (unsigned i = 0; i < arrayLength(t, table); ++i) { for (unsigned i = 0; i < arrayLength(t, table); ++i) {
object o = arrayBody(t, table, i); object o = arrayBody(t, table, i);
if (strcmp(&byteArrayBody(t, getName(t, o), 0), if (vm::strcmp(&byteArrayBody(t, getName(t, o), 0),
&byteArrayBody(t, name, 0)) == 0 and &byteArrayBody(t, name, 0)) == 0 and
strcmp(&byteArrayBody(t, getSpec(t, o), 0), vm::strcmp(&byteArrayBody(t, getSpec(t, o), 0),
&byteArrayBody(t, spec, 0)) == 0) &byteArrayBody(t, spec, 0)) == 0)
{ {
return o; return o;
} }
@ -3429,7 +3452,24 @@ collect(Thread* t, Heap::CollectionType type)
for (; f; f = finalizerNext(t, f)) { for (; f; f = finalizerNext(t, f)) {
void (*function)(Thread*, object); void (*function)(Thread*, object);
memcpy(&function, &finalizerFinalize(t, f), BytesPerWord); memcpy(&function, &finalizerFinalize(t, f), BytesPerWord);
function(t, finalizerTarget(t, f)); if (function) {
function(t, finalizerTarget(t, f));
} else {
m->objectsToFinalize = makePair
(t, finalizerTarget(t, f), m->objectsToFinalize);
}
}
if (m->objectsToFinalize and m->finalizeThread == 0) {
m->finalizeThread = m->processor->makeThread
(m, makeJavaThread(t, m->rootThread), m->rootThread);
if (not t->m->system->success
(m->system->start(&(m->finalizeThread->runnable))))
{
m->finalizeThread->exit();
m->finalizeThread = 0;
}
} }
} }
@ -3449,11 +3489,12 @@ walk(Thread* t, Heap::Walker* w, object o, unsigned start)
= (arrayElementSize ? = (arrayElementSize ?
cast<uintptr_t>(o, fixedSize - BytesPerWord) : 0); cast<uintptr_t>(o, fixedSize - BytesPerWord) : 0);
uint32_t mask[intArrayLength(t, objectMask)]; RUNTIME_ARRAY(uint32_t, mask, intArrayLength(t, objectMask));
memcpy(mask, &intArrayBody(t, objectMask, 0), memcpy(RUNTIME_ARRAY_BODY(mask), &intArrayBody(t, objectMask, 0),
intArrayLength(t, objectMask) * 4); intArrayLength(t, objectMask) * 4);
more = ::walk(t, w, mask, fixedSize, arrayElementSize, arrayLength, start); more = ::walk(t, w, RUNTIME_ARRAY_BODY(mask), fixedSize, arrayElementSize,
arrayLength, start);
} else if (classVmFlags(t, class_) & SingletonFlag) { } else if (classVmFlags(t, class_) & SingletonFlag) {
unsigned length = singletonLength(t, o); unsigned length = singletonLength(t, o);
if (length) { if (length) {
@ -3502,6 +3543,7 @@ visitRoots(Machine* m, Heap::Visitor* v)
v->visit(&(m->types)); v->visit(&(m->types));
v->visit(&(m->jniMethodTable)); v->visit(&(m->jniMethodTable));
v->visit(&(m->shutdownHooks)); v->visit(&(m->shutdownHooks));
v->visit(&(m->objectsToFinalize));
for (Thread* t = m->rootThread; t; t = t->peer) { for (Thread* t = m->rootThread; t; t = t->peer) {
::visitRoots(t, v); ::visitRoots(t, v);
@ -3529,9 +3571,9 @@ printTrace(Thread* t, object exception)
if (throwableMessage(t, e)) { if (throwableMessage(t, e)) {
object m = throwableMessage(t, e); object m = throwableMessage(t, e);
char message[stringLength(t, m) + 1]; RUNTIME_ARRAY(char, message, stringLength(t, m) + 1);
stringChars(t, m, message); stringChars(t, m, RUNTIME_ARRAY_BODY(message));
fprintf(stderr, ": %s\n", message); fprintf(stderr, ": %s\n", RUNTIME_ARRAY_BODY(message));
} else { } else {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@ -3575,7 +3617,7 @@ makeTrace(Thread* t, Processor::StackWalker* walker)
} }
object e = makeTraceElement(t, walker->method(), walker->ip()); object e = makeTraceElement(t, walker->method(), walker->ip());
assert(t, index < arrayLength(t, trace)); vm_assert(t, index < arrayLength(t, trace));
set(t, trace, ArrayBody + (index * BytesPerWord), e); set(t, trace, ArrayBody + (index * BytesPerWord), e);
++ index; ++ index;
return true; return true;
@ -3600,7 +3642,7 @@ makeTrace(Thread* t, Thread* target)
Visitor(Thread* t): t(t), trace(0) { } Visitor(Thread* t): t(t), trace(0) { }
virtual bool visit(Processor::StackWalker* walker) { virtual bool visit(Processor::StackWalker* walker) {
trace = makeTrace(t, walker); trace = vm::makeTrace(t, walker);
return false; return false;
} }
@ -3624,6 +3666,36 @@ runJavaThread(Thread* t)
} }
} }
void
runFinalizeThread(Thread* t)
{
setDaemon(t, t->javaThread, true);
object list = 0;
PROTECT(t, list);
while (true) {
{ ACQUIRE(t, t->m->stateLock);
while (t->m->finalizeThread and t->m->objectsToFinalize == 0) {
ENTER(t, Thread::IdleState);
t->m->stateLock->wait(t->systemThread, 0);
}
if (t->m->finalizeThread == 0) {
return;
} else {
list = t->m->objectsToFinalize;
t->m->objectsToFinalize = 0;
}
}
for (; list; list = pairSecond(t, list)) {
finalizeObject(t, pairFirst(t, list));
}
}
}
void void
noop() noop()
{ } { }

View File

@ -18,7 +18,7 @@
#include "processor.h" #include "processor.h"
#include "constants.h" #include "constants.h"
#ifdef __MINGW32__ #ifdef PLATFORM_WINDOWS
# define JNICALL __stdcall # define JNICALL __stdcall
#else #else
# define JNICALL # define JNICALL
@ -1173,6 +1173,7 @@ class Machine {
Processor* processor; Processor* processor;
Thread* rootThread; Thread* rootThread;
Thread* exclusive; Thread* exclusive;
Thread* finalizeThread;
Reference* jniReferences; Reference* jniReferences;
const char** properties; const char** properties;
unsigned propertyCount; unsigned propertyCount;
@ -1201,6 +1202,7 @@ class Machine {
object weakReferences; object weakReferences;
object tenuredWeakReferences; object tenuredWeakReferences;
object shutdownHooks; object shutdownHooks;
object objectsToFinalize;
bool unsafe; bool unsafe;
bool triedBuiltinOnLoad; bool triedBuiltinOnLoad;
JavaVMVTable javaVMVTable; JavaVMVTable javaVMVTable;
@ -1231,6 +1233,9 @@ inline void stress(Thread* t);
void void
runJavaThread(Thread* t); runJavaThread(Thread* t);
void
runFinalizeThread(Thread* t);
class Thread { class Thread {
public: public:
enum State { enum State {
@ -1302,10 +1307,14 @@ class Thread {
t->m->localThread->set(t); t->m->localThread->set(t);
runJavaThread(t); if (t == t->m->finalizeThread) {
runFinalizeThread(t);
} else if (t->javaThread) {
runJavaThread(t);
if (t->exception) { if (t->exception) {
printTrace(t, t->exception); printTrace(t, t->exception);
}
} }
t->exit(); t->exit();
@ -2357,6 +2366,25 @@ interrupt(Thread*, Thread* target)
target->systemThread->interrupt(); target->systemThread->interrupt();
} }
inline void
setDaemon(Thread* t, object thread, bool daemon)
{
ACQUIRE_RAW(t, t->m->stateLock);
if ((threadDaemon(t, thread) != 0) != daemon) {
threadDaemon(t, thread) = daemon;
if (daemon) {
++ t->m->daemonCount;
} else {
expect(t, t->m->daemonCount);
-- t->m->daemonCount;
}
t->m->stateLock->notifyAll(t->systemThread);
}
}
object object
intern(Thread* t, object s); intern(Thread* t, object s);

View File

@ -11,15 +11,45 @@
#include "stdlib.h" #include "stdlib.h"
#include "stdio.h" #include "stdio.h"
#include "string.h" #include "string.h"
#include "stdint.h"
#include "jni.h" #include "jni.h"
#ifdef __MINGW32__ #if (defined __MINGW32__) || (defined _MSC_VER)
# define PATH_SEPARATOR ';' # define PATH_SEPARATOR ';'
#else #else
# define PATH_SEPARATOR ':' # define PATH_SEPARATOR ':'
#endif #endif
#ifdef _MSC_VER
# define not !
# define or ||
# define and &&
# define xor ^
template <class T>
class RuntimeArray {
public:
RuntimeArray(unsigned size):
body(static_cast<T*>(malloc(size * sizeof(T))))
{ }
~RuntimeArray() {
free(body);
}
T* body;
};
# define RUNTIME_ARRAY(type, name, size) RuntimeArray<type> name(size);
# define RUNTIME_ARRAY_BODY(name) name.body
#else // not _MSC_VER
# define RUNTIME_ARRAY(type, name, size) type name[size];
# define RUNTIME_ARRAY_BODY(name) name
#endif // not _MSC_VER
namespace { namespace {
void void
@ -87,28 +117,28 @@ main(int ac, const char** av)
++ vmArgs.nOptions; ++ vmArgs.nOptions;
#endif #endif
JavaVMOption options[vmArgs.nOptions]; RUNTIME_ARRAY(JavaVMOption, options, vmArgs.nOptions);
vmArgs.options = options; vmArgs.options = RUNTIME_ARRAY_BODY(options);
unsigned optionIndex = 0; unsigned optionIndex = 0;
#ifdef BOOT_IMAGE #ifdef BOOT_IMAGE
options[optionIndex++].optionString vmArgs.options[optionIndex++].optionString
= const_cast<char*>("-Davian.bootimage=" BOOT_IMAGE); = const_cast<char*>("-Davian.bootimage=" BOOT_IMAGE);
#endif #endif
#ifdef BOOT_CLASSPATH #ifdef BOOT_CLASSPATH
options[optionIndex++].optionString vmArgs.options[optionIndex++].optionString
= const_cast<char*>("-Xbootclasspath:" BOOT_CLASSPATH); = const_cast<char*>("-Xbootclasspath:" BOOT_CLASSPATH);
#endif #endif
#ifdef BOOT_LIBRARY #ifdef BOOT_LIBRARY
options[optionIndex++].optionString vmArgs.options[optionIndex++].optionString
= const_cast<char*>("-Davian.bootstrap=" BOOT_LIBRARY); = const_cast<char*>("-Davian.bootstrap=" BOOT_LIBRARY);
#endif #endif
#ifdef BOOT_BUILTINS #ifdef BOOT_BUILTINS
options[optionIndex++].optionString vmArgs.options[optionIndex++].optionString
= const_cast<char*>("-Davian.builtins=" BOOT_BUILTINS); = const_cast<char*>("-Davian.builtins=" BOOT_BUILTINS);
#endif #endif
@ -118,21 +148,23 @@ main(int ac, const char** av)
unsigned classpathPropertyBufferSize unsigned classpathPropertyBufferSize
= sizeof(CLASSPATH_PROPERTY) + classpathSize; = sizeof(CLASSPATH_PROPERTY) + classpathSize;
char classpathPropertyBuffer[classpathPropertyBufferSize]; RUNTIME_ARRAY(char, classpathPropertyBuffer, classpathPropertyBufferSize);
memcpy(classpathPropertyBuffer, memcpy(RUNTIME_ARRAY_BODY(classpathPropertyBuffer),
CLASSPATH_PROPERTY, CLASSPATH_PROPERTY,
sizeof(CLASSPATH_PROPERTY) - 1); sizeof(CLASSPATH_PROPERTY) - 1);
memcpy(classpathPropertyBuffer + sizeof(CLASSPATH_PROPERTY) - 1, memcpy(RUNTIME_ARRAY_BODY(classpathPropertyBuffer)
+ sizeof(CLASSPATH_PROPERTY) - 1,
classpath, classpath,
classpathSize + 1); classpathSize + 1);
options[optionIndex++].optionString = classpathPropertyBuffer; vmArgs.options[optionIndex++].optionString
= RUNTIME_ARRAY_BODY(classpathPropertyBuffer);
for (int i = 1; i < ac; ++i) { for (int i = 1; i < ac; ++i) {
if (strncmp(av[i], "-X", 2) == 0 if (strncmp(av[i], "-X", 2) == 0
or strncmp(av[i], "-D", 2) == 0) or strncmp(av[i], "-D", 2) == 0)
{ {
options[optionIndex++].optionString = const_cast<char*>(av[i]); vmArgs.options[optionIndex++].optionString = const_cast<char*>(av[i]);
} }
} }

View File

@ -704,7 +704,7 @@ class MySystem: public System {
if (mapName and name) { if (mapName and name) {
unsigned size = nameLength + 3 + sizeof(SO_SUFFIX); unsigned size = nameLength + 3 + sizeof(SO_SUFFIX);
char buffer[size]; char buffer[size];
snprintf(buffer, size, "lib%s" SO_SUFFIX, name); vm::snprintf(buffer, size, "lib%s" SO_SUFFIX, name);
p = dlopen(buffer, RTLD_LAZY | RTLD_LOCAL); p = dlopen(buffer, RTLD_LAZY | RTLD_LOCAL);
} else { } else {
if (!name) { if (!name) {

View File

@ -152,19 +152,24 @@ resolveNativeMethod(Thread* t, object method, const char* prefix,
unsigned prefixLength, int footprint UNUSED) unsigned prefixLength, int footprint UNUSED)
{ {
unsigned undecoratedSize = prefixLength + jniNameLength(t, method, false); unsigned undecoratedSize = prefixLength + jniNameLength(t, method, false);
char undecorated[undecoratedSize + 1 + 6]; // extra 6 is for code below // extra 6 is for code below:
makeJNIName(t, prefix, prefixLength, undecorated + 1, method, false); RUNTIME_ARRAY(char, undecorated, undecoratedSize + 1 + 6);
makeJNIName(t, prefix, prefixLength, RUNTIME_ARRAY_BODY(undecorated) + 1,
method, false);
unsigned decoratedSize = prefixLength + jniNameLength(t, method, true); unsigned decoratedSize = prefixLength + jniNameLength(t, method, true);
char decorated[decoratedSize + 1 + 6]; // extra 6 is for code below // extra 6 is for code below:
makeJNIName(t, prefix, prefixLength, decorated + 1, method, true); RUNTIME_ARRAY(char, decorated, decoratedSize + 1 + 6);
makeJNIName(t, prefix, prefixLength, RUNTIME_ARRAY_BODY(decorated) + 1,
method, true);
void* p = resolveNativeMethod(t, undecorated + 1, decorated + 1); void* p = resolveNativeMethod(t, RUNTIME_ARRAY_BODY(undecorated) + 1,
RUNTIME_ARRAY_BODY(decorated) + 1);
if (p) { if (p) {
return p; return p;
} }
#ifdef __MINGW32__ #ifdef PLATFORM_WINDOWS
// on windows, we also try the _%s@%d and %s@%d variants // on windows, we also try the _%s@%d and %s@%d variants
if (footprint == -1) { if (footprint == -1) {
footprint = methodParameterFootprint(t, method) + 1; footprint = methodParameterFootprint(t, method) + 1;
@ -173,21 +178,23 @@ resolveNativeMethod(Thread* t, object method, const char* prefix,
} }
} }
*undecorated = '_'; *RUNTIME_ARRAY_BODY(undecorated) = '_';
snprintf(undecorated + undecoratedSize + 1, 5, "@%d", vm::snprintf(RUNTIME_ARRAY_BODY(undecorated) + undecoratedSize + 1, 5, "@%d",
footprint * BytesPerWord); footprint * BytesPerWord);
*decorated = '_'; *RUNTIME_ARRAY_BODY(decorated) = '_';
snprintf(decorated + decoratedSize + 1, 5, "@%d", vm::snprintf(RUNTIME_ARRAY_BODY(decorated) + decoratedSize + 1, 5, "@%d",
footprint * BytesPerWord); footprint * BytesPerWord);
p = resolveNativeMethod(t, undecorated, decorated); p = resolveNativeMethod(t, RUNTIME_ARRAY_BODY(undecorated),
RUNTIME_ARRAY_BODY(decorated));
if (p) { if (p) {
return p; return p;
} }
// one more try without the leading underscore // one more try without the leading underscore
p = resolveNativeMethod(t, undecorated + 1, decorated + 1); p = resolveNativeMethod(t, RUNTIME_ARRAY_BODY(undecorated) + 1,
RUNTIME_ARRAY_BODY(decorated) + 1);
if (p) { if (p) {
return p; return p;
} }

View File

@ -176,6 +176,7 @@ expect(System* s, bool v)
#ifdef NDEBUG #ifdef NDEBUG
# define assert(a, b) # define assert(a, b)
# define vm_assert(a, b)
#else // not NDEBUG #else // not NDEBUG
@ -185,6 +186,8 @@ assert(System* s, bool v)
expect(s, v); expect(s, v);
} }
# define vm_assert(a, b) vm::assert(a, b)
#endif // not NDEBUG #endif // not NDEBUG
System* System*

View File

@ -11,7 +11,14 @@
#include "sys/stat.h" #include "sys/stat.h"
#include "windows.h" #include "windows.h"
#include "sys/timeb.h" #include "sys/timeb.h"
#include "dirent.h"
#ifdef _MSC_VER
# define S_ISREG(x) ((x) & _S_IFREG)
# define S_ISDIR(x) ((x) & _S_IFDIR)
# define FTIME _ftime_s
#else
# define FTIME _ftime
#endif
#undef max #undef max
#undef min #undef min
@ -419,27 +426,33 @@ class MySystem: public System {
class Directory: public System::Directory { class Directory: public System::Directory {
public: public:
Directory(System* s, DIR* directory): s(s), directory(directory) { } Directory(System* s): s(s), handle(0), findNext(false) { }
virtual const char* next() { virtual const char* next() {
if (directory) { if (handle and handle != INVALID_HANDLE_VALUE) {
dirent* e = readdir(directory); if (findNext) {
if (e) { if (FindNextFile(handle, &data)) {
return e->d_name; return data.cFileName;
}
} else {
findNext = true;
return data.cFileName;
} }
} }
return 0; return 0;
} }
virtual void dispose() { virtual void dispose() {
if (directory) { if (handle and handle != INVALID_HANDLE_VALUE) {
closedir(directory); FindClose(handle);
} }
s->free(this); s->free(this);
} }
System* s; System* s;
DIR* directory; HANDLE handle;
WIN32_FIND_DATA data;
bool findNext;
}; };
class Library: public System::Library { class Library: public System::Library {
@ -574,18 +587,18 @@ class MySystem: public System {
if (handler) { if (handler) {
segFaultHandler = handler; segFaultHandler = handler;
#ifdef __i386__ #ifdef ARCH_x86_32
oldSegFaultHandler = SetUnhandledExceptionFilter(handleException); oldSegFaultHandler = SetUnhandledExceptionFilter(handleException);
#elif defined __x86_64__ #elif defined ARCH_x86_64
AddVectoredExceptionHandler(1, handleException); AddVectoredExceptionHandler(1, handleException);
oldSegFaultHandler = 0; oldSegFaultHandler = 0;
#endif #endif
return 0; return 0;
} else if (segFaultHandler) { } else if (segFaultHandler) {
segFaultHandler = 0; segFaultHandler = 0;
#ifdef __i386__ #ifdef ARCH_x86_32
SetUnhandledExceptionFilter(oldSegFaultHandler); SetUnhandledExceptionFilter(oldSegFaultHandler);
#elif defined __x86_64__ #elif defined ARCH_x86_64
//do nothing, handlers are never "unregistered" anyway //do nothing, handlers are never "unregistered" anyway
#endif #endif
return 0; return 0;
@ -609,12 +622,12 @@ class MySystem: public System {
CONTEXT context; CONTEXT context;
rv = GetThreadContext(target->thread, &context); rv = GetThreadContext(target->thread, &context);
expect(this, rv); expect(this, rv);
#ifdef __i386__ #ifdef ARCH_x86_32
visitor->visit(reinterpret_cast<void*>(context.Eip), visitor->visit(reinterpret_cast<void*>(context.Eip),
reinterpret_cast<void*>(context.Ebp), reinterpret_cast<void*>(context.Ebp),
reinterpret_cast<void*>(context.Esp)); reinterpret_cast<void*>(context.Esp));
#elif defined __x86_64__ #elif defined ARCH_x86_64
visitor->visit(reinterpret_cast<void*>(context.Rip), visitor->visit(reinterpret_cast<void*>(context.Rip),
reinterpret_cast<void*>(context.Rbp), reinterpret_cast<void*>(context.Rbp),
reinterpret_cast<void*>(context.Rsp)); reinterpret_cast<void*>(context.Rsp));
#endif #endif
@ -664,10 +677,13 @@ class MySystem: public System {
virtual Status open(System::Directory** directory, const char* name) { virtual Status open(System::Directory** directory, const char* name) {
Status status = 1; Status status = 1;
DIR* d = opendir(name); Directory* d = new (allocate(this, sizeof(Directory))) Directory(this);
if (d) { d->handle = FindFirstFile(name, &(d->data));
*directory = new (allocate(this, sizeof(Directory))) Directory(this, d); if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose();
} else {
*directory = d;
status = 0; status = 0;
} }
@ -698,9 +714,10 @@ class MySystem: public System {
unsigned nameLength = (name ? strlen(name) : 0); unsigned nameLength = (name ? strlen(name) : 0);
if (mapName and name) { if (mapName and name) {
unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX); unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX);
char buffer[size]; RUNTIME_ARRAY(char, buffer, size);;
snprintf(buffer, size, SO_PREFIX "%s" SO_SUFFIX, name); vm::snprintf
handle = LoadLibrary(buffer); (RUNTIME_ARRAY_BODY(buffer), size, SO_PREFIX "%s" SO_SUFFIX, name);
handle = LoadLibrary(RUNTIME_ARRAY_BODY(buffer));
} else if (name) { } else if (name) {
handle = LoadLibrary(name); handle = LoadLibrary(name);
} else { } else {
@ -811,10 +828,10 @@ dump(LPEXCEPTION_POINTERS e, const char* directory)
if (MiniDumpWriteDump) { if (MiniDumpWriteDump) {
char name[MAX_PATH]; char name[MAX_PATH];
_timeb tb; _timeb tb;
_ftime(&tb); FTIME(&tb);
snprintf(name, MAX_PATH, "%s\\crash-%"LLD".mdmp", directory, vm::snprintf(name, MAX_PATH, "%s\\crash-%"LLD".mdmp", directory,
(static_cast<int64_t>(tb.time) * 1000) (static_cast<int64_t>(tb.time) * 1000)
+ static_cast<int64_t>(tb.millitm)); + static_cast<int64_t>(tb.millitm));
HANDLE file = CreateFile HANDLE file = CreateFile
(name, FILE_WRITE_DATA, 0, 0, CREATE_ALWAYS, 0, 0); (name, FILE_WRITE_DATA, 0, 0, CREATE_ALWAYS, 0, 0);
@ -844,12 +861,12 @@ LONG CALLBACK
handleException(LPEXCEPTION_POINTERS e) handleException(LPEXCEPTION_POINTERS e)
{ {
if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
#ifdef __i386__ #ifdef ARCH_x86_32
void* ip = reinterpret_cast<void*>(e->ContextRecord->Eip); void* ip = reinterpret_cast<void*>(e->ContextRecord->Eip);
void* base = reinterpret_cast<void*>(e->ContextRecord->Ebp); void* base = reinterpret_cast<void*>(e->ContextRecord->Ebp);
void* stack = reinterpret_cast<void*>(e->ContextRecord->Esp); void* stack = reinterpret_cast<void*>(e->ContextRecord->Esp);
void* thread = reinterpret_cast<void*>(e->ContextRecord->Ebx); void* thread = reinterpret_cast<void*>(e->ContextRecord->Ebx);
#elif defined __x86_64__ #elif defined ARCH_x86_64
void* ip = reinterpret_cast<void*>(e->ContextRecord->Rip); void* ip = reinterpret_cast<void*>(e->ContextRecord->Rip);
void* base = reinterpret_cast<void*>(e->ContextRecord->Rbp); void* base = reinterpret_cast<void*>(e->ContextRecord->Rbp);
void* stack = reinterpret_cast<void*>(e->ContextRecord->Rsp); void* stack = reinterpret_cast<void*>(e->ContextRecord->Rsp);
@ -858,12 +875,12 @@ handleException(LPEXCEPTION_POINTERS e)
bool jump = system->segFaultHandler->handleSignal bool jump = system->segFaultHandler->handleSignal
(&ip, &base, &stack, &thread); (&ip, &base, &stack, &thread);
#ifdef __i386__ #ifdef ARCH_x86_32
e->ContextRecord->Eip = reinterpret_cast<DWORD>(ip); e->ContextRecord->Eip = reinterpret_cast<DWORD>(ip);
e->ContextRecord->Ebp = reinterpret_cast<DWORD>(base); e->ContextRecord->Ebp = reinterpret_cast<DWORD>(base);
e->ContextRecord->Esp = reinterpret_cast<DWORD>(stack); e->ContextRecord->Esp = reinterpret_cast<DWORD>(stack);
e->ContextRecord->Ebx = reinterpret_cast<DWORD>(thread); e->ContextRecord->Ebx = reinterpret_cast<DWORD>(thread);
#elif defined __x86_64__ #elif defined ARCH_x86_64
e->ContextRecord->Rip = reinterpret_cast<DWORD64>(ip); e->ContextRecord->Rip = reinterpret_cast<DWORD64>(ip);
e->ContextRecord->Rbp = reinterpret_cast<DWORD64>(base); e->ContextRecord->Rbp = reinterpret_cast<DWORD64>(base);
e->ContextRecord->Rsp = reinterpret_cast<DWORD64>(stack); e->ContextRecord->Rsp = reinterpret_cast<DWORD64>(stack);

View File

@ -7,13 +7,10 @@
There is NO WARRANTY for this software. See license.txt for There is NO WARRANTY for this software. See license.txt for
details. */ details. */
#if (defined __i386__) || (defined __x86_64__)
#include "assembler.h" #include "assembler.h"
#include "vector.h" #include "vector.h"
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x) #define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x) #define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
@ -21,6 +18,8 @@ using namespace vm;
namespace { namespace {
namespace local {
enum { enum {
rax = 0, rax = 0,
rcx = 1, rcx = 1,
@ -2101,7 +2100,7 @@ class MyArchitecture: public Assembler::Architecture {
} }
virtual unsigned frameFootprint(unsigned footprint) { virtual unsigned frameFootprint(unsigned footprint) {
#ifdef __MINGW32__ #ifdef PLATFORM_WINDOWS
return max(footprint, StackAlignmentInWords); return max(footprint, StackAlignmentInWords);
#else #else
return max(footprint > argumentRegisterCount() ? return max(footprint > argumentRegisterCount() ?
@ -2115,7 +2114,7 @@ class MyArchitecture: public Assembler::Architecture {
} }
virtual unsigned argumentRegisterCount() { virtual unsigned argumentRegisterCount() {
#ifdef __MINGW32__ #ifdef PLATFORM_WINDOWS
if (BytesPerWord == 8) return 4; else if (BytesPerWord == 8) return 4; else
#else #else
if (BytesPerWord == 8) return 6; else if (BytesPerWord == 8) return 6; else
@ -2126,7 +2125,7 @@ class MyArchitecture: public Assembler::Architecture {
virtual int argumentRegister(unsigned index) { virtual int argumentRegister(unsigned index) {
assert(&c, BytesPerWord == 8); assert(&c, BytesPerWord == 8);
switch (index) { switch (index) {
#ifdef __MINGW32__ #ifdef PLATFORM_WINDOWS
case 0: case 0:
return rcx; return rcx;
case 1: case 1:
@ -2407,18 +2406,21 @@ class MyAssembler: public Assembler {
} }
virtual void pushFrame(unsigned argumentCount, ...) { virtual void pushFrame(unsigned argumentCount, ...) {
struct { struct Argument {
unsigned size; unsigned size;
OperandType type; OperandType type;
Operand* operand; Operand* operand;
} arguments[argumentCount]; };
RUNTIME_ARRAY(Argument, arguments, argumentCount);
va_list a; va_start(a, argumentCount); va_list a; va_start(a, argumentCount);
unsigned footprint = 0; unsigned footprint = 0;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
arguments[i].size = va_arg(a, unsigned); RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned);
arguments[i].type = static_cast<OperandType>(va_arg(a, int)); RUNTIME_ARRAY_BODY(arguments)[i].type
arguments[i].operand = va_arg(a, Operand*); = static_cast<OperandType>(va_arg(a, int));
footprint += ceiling(arguments[i].size, BytesPerWord); RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*);
footprint += ceiling
(RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord);
} }
va_end(a); va_end(a);
@ -2429,14 +2431,22 @@ class MyAssembler: public Assembler {
if (i < arch_->argumentRegisterCount()) { if (i < arch_->argumentRegisterCount()) {
Register dst(arch_->argumentRegister(i)); Register dst(arch_->argumentRegister(i));
apply(Move, apply(Move,
arguments[i].size, arguments[i].type, arguments[i].operand, RUNTIME_ARRAY_BODY(arguments)[i].size,
pad(arguments[i].size), RegisterOperand, &dst); RUNTIME_ARRAY_BODY(arguments)[i].type,
RUNTIME_ARRAY_BODY(arguments)[i].operand,
pad(RUNTIME_ARRAY_BODY(arguments)[i].size),
RegisterOperand,
&dst);
} else { } else {
Memory dst(rsp, offset * BytesPerWord); Memory dst(rsp, offset * BytesPerWord);
apply(Move, apply(Move,
arguments[i].size, arguments[i].type, arguments[i].operand, RUNTIME_ARRAY_BODY(arguments)[i].size,
pad(arguments[i].size), MemoryOperand, &dst); RUNTIME_ARRAY_BODY(arguments)[i].type,
offset += ceiling(arguments[i].size, BytesPerWord); RUNTIME_ARRAY_BODY(arguments)[i].operand,
pad(RUNTIME_ARRAY_BODY(arguments)[i].size),
MemoryOperand,
&dst);
offset += ceiling(RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord);
} }
} }
} }
@ -2620,7 +2630,7 @@ class MyAssembler: public Assembler {
} }
virtual Promise* offset() { virtual Promise* offset() {
return ::offset(&c); return local::offset(&c);
} }
virtual Block* endBlock(bool startNew) { virtual Block* endBlock(bool startNew) {
@ -2647,6 +2657,8 @@ class MyAssembler: public Assembler {
MyArchitecture* arch_; MyArchitecture* arch_;
}; };
} // namespace local
} // namespace } // namespace
namespace vm { namespace vm {
@ -2654,19 +2666,17 @@ namespace vm {
Assembler::Architecture* Assembler::Architecture*
makeArchitecture(System* system) makeArchitecture(System* system)
{ {
return new (allocate(system, sizeof(MyArchitecture))) MyArchitecture(system); return new (allocate(system, sizeof(local::MyArchitecture)))
local::MyArchitecture(system);
} }
Assembler* Assembler*
makeAssembler(System* system, Allocator* allocator, Zone* zone, makeAssembler(System* system, Allocator* allocator, Zone* zone,
Assembler::Architecture* architecture) Assembler::Architecture* architecture)
{ {
return new (zone->allocate(sizeof(MyAssembler))) return new (zone->allocate(sizeof(local::MyAssembler)))
MyAssembler(system, allocator, zone, local::MyAssembler(system, allocator, zone,
static_cast<MyArchitecture*>(architecture)); static_cast<local::MyArchitecture*>(architecture));
} }
} // namespace vm } // namespace vm
#endif //(defined __i386__) || (defined __x86_64__)

View File

@ -14,7 +14,11 @@
#include "types.h" #include "types.h"
#include "common.h" #include "common.h"
#ifdef __i386__ #ifdef _MSC_VER
# include "windows.h"
#endif
#ifdef ARCH_x86_32
# ifdef __APPLE__ # ifdef __APPLE__
# if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32) # if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32)
@ -50,7 +54,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t*,
} // namespace vm } // namespace vm
#elif defined __x86_64__ #elif defined ARCH_x86_64
# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP]) # define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP])
# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP]) # define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP])
@ -58,7 +62,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t*,
# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX]) # define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX])
extern "C" uint64_t extern "C" uint64_t
# ifdef __MINGW32__ # ifdef PLATFORM_WINDOWS
vmNativeCall(void* function, void* stack, unsigned stackSize, vmNativeCall(void* function, void* stack, unsigned stackSize,
unsigned returnType); unsigned returnType);
# else # else
@ -68,7 +72,7 @@ vmNativeCall(void* function, void* stack, unsigned stackSize,
namespace vm { namespace vm {
# ifdef __MINGW32__ # ifdef PLATFORM_WINDOWS
inline uint64_t inline uint64_t
dynamicCall(void* function, uint64_t* arguments, UNUSED uint8_t* argumentTypes, dynamicCall(void* function, uint64_t* arguments, UNUSED uint8_t* argumentTypes,
unsigned argumentCount, unsigned, unsigned returnType) unsigned argumentCount, unsigned, unsigned returnType)
@ -129,13 +133,21 @@ namespace vm {
inline void inline void
trap() trap()
{ {
#ifdef _MSC_VER
__asm int 3
#else
asm("int3"); asm("int3");
#endif
} }
inline void inline void
memoryBarrier() memoryBarrier()
{ {
#ifdef _MSC_VER
MemoryBarrier();
#else
__asm__ __volatile__("": : :"memory"); __asm__ __volatile__("": : :"memory");
#endif
} }
inline void inline void

View File

@ -1,4 +1,5 @@
public class Finalizers { public class Finalizers {
private static final Object lock = new Object();
private static boolean finalized = false; private static boolean finalized = false;
private static void expect(boolean v) { private static void expect(boolean v) {
@ -6,15 +7,21 @@ public class Finalizers {
} }
protected void finalize() { protected void finalize() {
finalized = true; synchronized (lock) {
finalized = true;
lock.notifyAll();
}
} }
public static void main(String[] args) { public static void main(String[] args) throws Exception {
new Finalizers(); new Finalizers();
expect(! finalized); expect(! finalized);
System.gc(); synchronized (lock) {
System.gc();
lock.wait(5000);
}
expect(finalized); expect(finalized);
@ -24,7 +31,10 @@ public class Finalizers {
expect(! finalized); expect(! finalized);
System.gc(); synchronized (lock) {
System.gc();
lock.wait(5000);
}
expect(finalized); expect(finalized);
} }