add support for building with MSVC on Windows

This commit is contained in:
Joel Dice 2009-08-26 18:26:44 -06:00
parent 4297fa04b3
commit 1a0eef7e2d
24 changed files with 1081 additions and 531 deletions

View File

@ -14,28 +14,39 @@
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <dirent.h>
#include "jni.h"
#include "jni-util.h"
#ifdef WIN32
#ifdef PLATFORM_WINDOWS
# include <windows.h>
# include <io.h>
# include <direct.h>
# include <share.h>
# define OPEN _open
# define CLOSE _close
# define READ _read
# define WRITE _write
# define STAT _stat
# define STRUCT_STAT struct _stat
# define MKDIR(path, mode) _mkdir(path)
# define CREAT _creat
# define UNLINK _unlink
# 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 "sys/mman.h"
@ -49,12 +60,32 @@
# define CREAT creat
# define UNLINK unlink
# define OPEN_MASK 0
#endif
#endif // not PLATFORM_WINDOWS
inline void* operator new(size_t, void* p) throw() { return p; }
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
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);
if (fd == -1) {
if (errno == ENOENT) {
throwNew(e, "java/io/FileNotFoundException", strerror(errno));
throwNewErrno(e, "java/io/FileNotFoundException");
} else {
throwNew(e, "java/io/IOException", strerror(errno));
throwNewErrno(e, "java/io/IOException");
}
}
return fd;
@ -81,7 +112,7 @@ doClose(JNIEnv* e, jint fd)
{
int r = CLOSE(fd);
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) {
return -1;
} else {
throwNew(e, "java/io/IOException", strerror(errno));
throwNewErrno(e, "java/io/IOException");
return 0;
}
}
@ -104,11 +135,11 @@ doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length)
{
int r = WRITE(fd, data, length);
if (r != length) {
throwNew(e, "java/io/IOException", strerror(errno));
throwNewErrno(e, "java/io/IOException");
}
}
#ifdef WIN32
#ifdef PLATFORM_WINDOWS
class Mapping {
public:
@ -170,7 +201,37 @@ unmap(JNIEnv*, Mapping* 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 {
public:
@ -203,7 +264,7 @@ map(JNIEnv* e, const char* path)
close(fd);
}
if (result == 0 and not e->ExceptionOccurred()) {
throwNew(e, "java/io/IOException", strerror(errno));
throwNewErrno(e, "java/io/IOException");
}
return result;
}
@ -215,7 +276,7 @@ unmap(JNIEnv*, Mapping* mapping)
free(mapping);
}
#endif // not WIN32
#endif // not PLATFORM_WINDOWS
} // namespace
@ -257,7 +318,7 @@ Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
if (not exists(chars)) {
int r = ::MKDIR(chars, 0700);
if (r != 0) {
throwNew(e, "java/io/IOException", strerror(errno));
throwNewErrno(e, "java/io/IOException");
}
}
e->ReleaseStringUTFChars(path, chars);
@ -272,7 +333,7 @@ Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
if (not exists(chars)) {
int fd = CREAT(chars, 0600);
if (fd == -1) {
throwNew(e, "java/io/IOException", strerror(errno));
throwNewErrno(e, "java/io/IOException");
} else {
doClose(e, fd);
}
@ -288,7 +349,7 @@ Java_java_io_File_delete(JNIEnv* e, jclass, jstring path)
if (chars) {
int r = UNLINK(chars);
if (r != 0) {
throwNew(e, "java/io/IOException", strerror(errno));
throwNewErrno(e, "java/io/IOException");
}
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
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
Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path)
{

View File

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

View File

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

View File

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

View File

@ -13,15 +13,63 @@
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#undef JNIEXPORT
#ifdef __MINGW32__
#if (defined __MINGW32__) || (defined _MSC_VER)
# define PLATFORM_WINDOWS
# define PATH_SEPARATOR ';'
# define JNIEXPORT __declspec(dllexport)
#else
# define PLATFORM_POSIX
# define PATH_SEPARATOR ':'
# define JNIEXPORT __attribute__ ((visibility("default")))
#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 {
@ -36,7 +84,11 @@ throwNew(JNIEnv* e, const char* class_, const char* message, ...)
va_list list;
va_start(list, message);
#ifdef _MSC_VER
vsnprintf_s(buffer, BufferSize - 1, _TRUNCATE, message, list);
#else
vsnprintf(buffer, BufferSize - 1, message, list);
#endif
va_end(list);
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*
allocate(JNIEnv* e, unsigned size)
{
@ -56,6 +121,32 @@ allocate(JNIEnv* e, unsigned size)
}
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

View File

@ -201,7 +201,6 @@ ifeq ($(platform),windows)
pointer-size = 8
object-format = pe-x86-64
endif
endif
ifeq ($(mode),debug)
@ -227,6 +226,46 @@ ifeq ($(mode),small)
cflags += -Os -g3 -DNDEBUG
endif
oflag = -o
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_ \
-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
oflag = -Fo
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)))
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x)))
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
@ -508,13 +547,13 @@ $(test-extra-dep): $(test-extra-sources)
define compile-object
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cxx) $(cflags) -c $(<) -o $(@)
$(cxx) $(cflags) -c $(<) $(oflag)$(@)
endef
define compile-asm-object
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cc) -I$(src) $(asmflags) -c $(<) -o $(@)
$(as) -I$(src) $(asmflags) -c $(<) -o $(@)
endef
$(vm-cpp-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
@ -536,7 +575,7 @@ $(driver-dynamic-object): $(driver-source)
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cxx) $(cflags) -DBOOT_LIBRARY=\"$(so-prefix)$(name)$(so-suffix)\" \
-c $(<) -o $(@)
-c $(<) $(oflag)$(@)
$(boot-object): $(boot-source)
$(compile-object)
@ -547,7 +586,7 @@ $(build)/classpath.jar: $(classpath-dep)
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
$(binaryToMacho): $(src)/binaryToMacho.cpp
$(cxx) $(^) -o $(@)
$(cxx) $(^) $(oflag)$(@)
$(classpath-object): $(build)/classpath.jar $(binaryToMacho)
@echo "creating $(@)"
@ -606,11 +645,15 @@ $(executable): \
$(boot-object) $(vm-classpath-object)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib
else
$(dlltool) -z $(@).def $(^) $(call gnu-objects)
$(dlltool) -d $(@).def -e $(@).exp
$(cc) $(@).exp $(^) $(call gnu-objects) $(lflags) -o $(@)
$(ld) $(@).exp $(^) $(call gnu-objects) $(lflags) -o $(@)
endif
else
$(cc) $(^) $(call gnu-objects) $(rdynamic) $(lflags) $(bootimage-lflags) \
$(ld) $(^) $(call gnu-objects) $(rdynamic) $(lflags) $(bootimage-lflags) \
-o $(@)
endif
$(strip) $(strip-all) $(@)
@ -633,11 +676,15 @@ $(build-bootimage-generator): \
$(bootimage-generator-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib
else
$(dlltool) -z $(@).def $(^)
$(dlltool) -d $(@).def -e $(@).exp
$(cc) $(@).exp $(^) $(lflags) -o $(@)
$(ld) $(@).exp $(^) $(lflags) -o $(@)
endif
else
$(cc) $(^) $(rdynamic) $(lflags) -o $(@)
$(ld) $(^) $(rdynamic) $(lflags) -o $(@)
endif
$(dynamic-library): $(gnu-object-dep)
@ -645,15 +692,25 @@ $(dynamic-library): \
$(vm-objects) $(dynamic-object) $(jni-objects) $(vm-heapwalk-objects) \
$(boot-object) $(vm-classpath-object) $(gnu-libraries)
@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 $(@)
endif
$(strip) $(strip-all) $(@)
$(executable-dynamic): $(driver-dynamic-object) $(dynamic-library)
@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) $(@)
$(generator): $(generator-objects)
@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,
uintptr_t returnLow, uintptr_t returnHigh);
#if (defined __i386__) || (defined __x86_64__)
#if (defined ARCH_x86_32) || (defined ARCH_x86_64)
# include "x86.h"
#elif defined __POWERPC__
#elif defined ARCH_powerpc
# include "powerpc.h"
#elif defined __arm__
#elif defined ARCH_arm
# include "arm.h"
#else
# error unsupported architecture

View File

@ -8,16 +8,25 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "stdint.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
// ourselves:
extern "C" void __cxa_pure_virtual(void) { abort(); }
#endif // not _MSC_VER
#ifdef BOOT_IMAGE
#ifdef __MINGW32__
#if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport)
# define SYMBOL(x) binary_bootimage_bin_##x
#else
@ -43,7 +52,7 @@ extern "C" {
#ifdef BOOT_CLASSPATH
#ifdef __MINGW32__
#if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport)
# define SYMBOL(x) binary_classpath_jar_##x
#else

View File

@ -234,9 +234,9 @@ Avian_avian_SystemClassLoader_resourceExists
object name = reinterpret_cast<object>(arguments[1]);
if (LIKELY(name)) {
char n[stringLength(t, name) + 1];
stringChars(t, name, n);
return t->m->finder->exists(n);
RUNTIME_ARRAY(char, n, stringLength(t, name) + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
return t->m->finder->exists(RUNTIME_ARRAY_BODY(n));
} else {
t->exception = makeNullPointerException(t);
return 0;
@ -547,18 +547,18 @@ Avian_java_lang_System_getVMProperty
PROTECT(t, found);
unsigned length = stringLength(t, name);
char n[length + 1];
stringChars(t, name, n);
RUNTIME_ARRAY(char, n, length + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
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()));
} 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));
} 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"));
} else {
const char* v = findProperty(t, n);
const char* v = findProperty(t, RUNTIME_ARRAY_BODY(n));
if (v) {
r = reinterpret_cast<int64_t>(makeString(t, v));
}
@ -643,8 +643,8 @@ Avian_java_lang_Runtime_load
bool mapName = arguments[1];
unsigned length = stringLength(t, name);
char n[length + 1];
stringChars(t, name, n);
RUNTIME_ARRAY(char, n, length + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
ACQUIRE(t, t->m->classLock);
@ -652,7 +652,7 @@ Avian_java_lang_Runtime_load
if (mapName and builtins) {
const char* s = builtins;
while (*s) {
if (strncmp(s, n, length) == 0
if (::strncmp(s, RUNTIME_ARRAY_BODY(n), length) == 0
and (s[length] == ',' or s[length] == 0))
{
// library is built in to this executable
@ -671,7 +671,7 @@ Avian_java_lang_Runtime_load
System::Library* last = t->m->libraries;
for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) {
if (lib->name()
and strcmp(lib->name(), n) == 0
and ::strcmp(lib->name(), RUNTIME_ARRAY_BODY(n)) == 0
and lib->mapName() == mapName)
{
// already loaded
@ -681,11 +681,14 @@ Avian_java_lang_Runtime_load
}
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);
runOnLoadIfFound(t, lib);
} 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);
}
}
@ -777,8 +780,8 @@ Avian_java_lang_Throwable_trace
if (isAssignableFrom
(t, arrayBody(t, t->m->types, Machine::ThrowableType),
methodClass(t, method))
and strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0))
and vm::strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0))
== 0)
{
return true;
@ -919,10 +922,10 @@ Avian_avian_resource_Handler_00024ResourceInputStream_getContentLength
object path = reinterpret_cast<object>(*arguments);
if (LIKELY(path)) {
char p[stringLength(t, path) + 1];
stringChars(t, path, p);
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
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) {
jint rSize = r->length();
r->dispose();
@ -939,10 +942,11 @@ Avian_avian_resource_Handler_00024ResourceInputStream_open
object path = reinterpret_cast<object>(*arguments);
if (LIKELY(path)) {
char p[stringLength(t, path) + 1];
stringChars(t, path, p);
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
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 {
t->exception = makeNullPointerException(t);
return 0;

View File

@ -11,7 +11,6 @@
#ifndef COMMON_H
#define COMMON_H
#include "stdint.h"
#include "stdlib.h"
#include "stdarg.h"
#include "stddef.h"
@ -20,8 +19,77 @@
#include "types.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
#ifdef __MINGW32__
#ifdef PLATFORM_WINDOWS
# define JNIEXPORT __declspec(dllexport)
# define PATH_SEPARATOR ';'
#else
@ -29,9 +97,9 @@
# define PATH_SEPARATOR ':'
#endif
#if (defined __i386__) || (defined __POWERPC__) || (defined __arm__)
#if (defined ARCH_x86_32) || (defined ARCH_powerpc) || (defined ARCH_arm)
# define LD "ld"
# if (defined __MINGW32__) && __GNUC__ == 4
# if (defined _MSC_VER) || ((defined __MINGW32__) && __GNUC__ >= 4)
# define LLD "I64d"
# else
# define LLD "lld"
@ -43,10 +111,10 @@
# define LX "x"
# define ULD "u"
# endif
#elif defined __x86_64__
#elif defined ARCH_x86_64
# define LD "ld"
# define LX "lx"
# ifdef __MINGW32__
# if (defined _MSC_VER) || (defined __MINGW32__)
# define LLD "I64d"
# define ULD "I64x"
# else
@ -57,7 +125,7 @@
# error "Unsupported architecture"
#endif
#ifdef __MINGW32__
#ifdef PLATFORM_WINDOWS
# define SO_PREFIX ""
#else
# define SO_PREFIX "lib"
@ -65,27 +133,95 @@
#ifdef __APPLE__
# define SO_SUFFIX ".jnilib"
#elif defined __MINGW32__
#elif defined PLATFORM_WINDOWS
# define SO_SUFFIX ".dll"
#else
# define SO_SUFFIX ".so"
#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_MakeNameXY(FX, LINE) MACRO_XY(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; }
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 BitsPerWord = BytesPerWord * 8;

View File

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

View File

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

View File

@ -149,7 +149,7 @@ Avian_gnu_classpath_VMSystemProperties_preInit
setProperty(t, method, properties, "java.library.path",
LIBRARY_PATH_SENTINAL);
#ifdef WIN32
#ifdef PLATFORM_WINDOWS
# define FILE_SEPARATOR "\\"
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"));
#endif
#ifdef __i386__
#ifdef ARCH_x86_32
setProperty(t, method, properties, "gnu.cpu.endian", "little");
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, "os.arch", "x86_64");
#elif defined(__ppc__) || defined(__powerpc__) \
|| defined(__ppc64__) || defined(__powerpc64__)
#elif defined ARCH_powerpc
setProperty(t, method, properties, "gnu.cpu.endian", "big");
setProperty(t, method, properties, "os.arch", "ppc");
#elif defined __arm__
#elif defined ARCH_arm
setProperty(t, method, properties, "os.arch", "arm");
#else
setProperty(t, method, properties, "os.arch", "unknown");

View File

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

View File

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

View File

@ -64,13 +64,14 @@ void
dispose(Thread* t, Thread* o, bool remove)
{
if (remove) {
// debug
#ifndef NDEBUG
expect(t, find(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);
// end debug
#endif
if (o->parent) {
Thread* previous = 0;
@ -110,13 +111,13 @@ dispose(Thread* t, Thread* o, bool remove)
abort(t);
}
// debug
#ifndef NDEBUG
expect(t, not find(t->m->rootThread, o));
for (unsigned i = 0; i < c; ++i) {
expect(t, find(t->m->rootThread, threads[i]));
}
// end debug
#endif
}
o->dispose();
@ -568,10 +569,10 @@ finalizeObject(Thread* t, object o)
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
object m = arrayBody(t, classMethodTable(t, c), i);
if (strcmp(reinterpret_cast<const int8_t*>("finalize"),
&byteArrayBody(t, methodName(t, m), 0)) == 0
and strcmp(reinterpret_cast<const int8_t*>("()V"),
&byteArrayBody(t, methodSpec(t, m), 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("finalize"),
&byteArrayBody(t, methodName(t, m), 0)) == 0
and vm::strcmp(reinterpret_cast<const int8_t*>("()V"),
&byteArrayBody(t, methodSpec(t, m), 0)) == 0)
{
t->m->processor->invoke(t, m, o);
t->exception = 0;
@ -588,7 +589,7 @@ makeByteArray(Thread* t, const char* format, va_list a)
const int Size = 256;
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);
object s = makeByteArray(t, strlen(buffer) + 1);
@ -1031,7 +1032,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
object staticValueTable = makeIntArray(t, count);
PROTECT(t, staticValueTable);
uint8_t staticTypes[count];
RUNTIME_ARRAY(uint8_t, staticTypes, count);
for (unsigned i = 0; i < count; ++i) {
unsigned flags = s.read2();
@ -1048,8 +1049,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("ConstantValue"),
&byteArrayBody(t, name, 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("ConstantValue"),
&byteArrayBody(t, name, 0)) == 0)
{
value = s.read2();
} else {
@ -1080,7 +1081,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
intArrayBody(t, staticValueTable, staticCount) = value;
staticTypes[staticCount++] = code;
RUNTIME_ARRAY_BODY(staticTypes)[staticCount++] = code;
} else {
if (flags & ACC_FINAL) {
classVmFlags(t, class_) |= HasFinalMemberFlag;
@ -1109,7 +1110,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
(&singletonBody(t, staticTable, 0));
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;
if (excess) {
offset += BytesPerWord - excess;
@ -1117,7 +1118,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
unsigned value = intArrayBody(t, staticValueTable, i);
if (value) {
switch (staticTypes[i]) {
switch (RUNTIME_ARRAY_BODY(staticTypes)[i]) {
case ByteField:
case BooleanField:
body[offset] = singletonValue(t, pool, value - 1);
@ -1150,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);
}
@ -1238,8 +1239,8 @@ parseCode(Thread* t, Stream& s, object pool)
object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("LineNumberTable"),
&byteArrayBody(t, name, 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("LineNumberTable"),
&byteArrayBody(t, name, 0)) == 0)
{
unsigned lntLength = s.read2();
object lnt = makeLineNumberTable(t, lntLength);
@ -1384,8 +1385,8 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("Code"),
&byteArrayBody(t, name, 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("Code"),
&byteArrayBody(t, name, 0)) == 0)
{
code = parseCode(t, s, pool);
} else {
@ -1434,10 +1435,10 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
}
if (UNLIKELY((classFlags(t, class_) & ACC_INTERFACE) == 0
and strcmp
and vm::strcmp
(reinterpret_cast<const int8_t*>("finalize"),
&byteArrayBody(t, methodName(t, method), 0)) == 0
and strcmp
and vm::strcmp
(reinterpret_cast<const int8_t*>("()V"),
&byteArrayBody(t, methodSpec(t, method), 0)) == 0
and (not emptyMethod(t, method))))
@ -1447,13 +1448,14 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
} else {
methodOffset(t, method) = i;
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
{
methodVmFlags(t, method) |= ClassInitFlag;
classVmFlags(t, class_) |= NeedInitFlag;
} else if (strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
} else if (vm::strcmp
(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
{
methodVmFlags(t, method) |= ConstructorFlag;
}
@ -2660,8 +2662,8 @@ classInitializer(Thread* t, object class_)
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, class_)); ++i) {
object o = arrayBody(t, classMethodTable(t, class_), i);
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, o), 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, o), 0)) == 0)
{
return o;
}
@ -2764,12 +2766,12 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
{
PROTECT(t, loader);
class Client : public Stream::Client {
class Client: public Stream::Client {
public:
Client(Thread* t): t(t) { }
virtual void NO_RETURN handleError() {
abort(t);
vm::abort(t);
}
private:
@ -2874,11 +2876,15 @@ resolveSystemClass(Thread* t, object spec)
if (byteArrayBody(t, spec, 0) == '[') {
class_ = resolveArrayClass(t, t->m->loader, spec);
} else {
char file[byteArrayLength(t, spec) + 6];
memcpy(file, &byteArrayBody(t, spec, 0), byteArrayLength(t, spec) - 1);
memcpy(file + byteArrayLength(t, spec) - 1, ".class", 7);
RUNTIME_ARRAY(char, file, byteArrayLength(t, spec) + 6);
memcpy(RUNTIME_ARRAY_BODY(file),
&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 (Verbose) {
@ -3241,10 +3247,10 @@ findInTable(Thread* t, object table, object name, object spec,
if (table) {
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
object o = arrayBody(t, table, i);
if (strcmp(&byteArrayBody(t, getName(t, o), 0),
&byteArrayBody(t, name, 0)) == 0 and
strcmp(&byteArrayBody(t, getSpec(t, o), 0),
&byteArrayBody(t, spec, 0)) == 0)
if (vm::strcmp(&byteArrayBody(t, getName(t, o), 0),
&byteArrayBody(t, name, 0)) == 0 and
vm::strcmp(&byteArrayBody(t, getSpec(t, o), 0),
&byteArrayBody(t, spec, 0)) == 0)
{
return o;
}
@ -3483,11 +3489,12 @@ walk(Thread* t, Heap::Walker* w, object o, unsigned start)
= (arrayElementSize ?
cast<uintptr_t>(o, fixedSize - BytesPerWord) : 0);
uint32_t mask[intArrayLength(t, objectMask)];
memcpy(mask, &intArrayBody(t, objectMask, 0),
RUNTIME_ARRAY(uint32_t, mask, intArrayLength(t, objectMask));
memcpy(RUNTIME_ARRAY_BODY(mask), &intArrayBody(t, objectMask, 0),
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) {
unsigned length = singletonLength(t, o);
if (length) {
@ -3564,9 +3571,9 @@ printTrace(Thread* t, object exception)
if (throwableMessage(t, e)) {
object m = throwableMessage(t, e);
char message[stringLength(t, m) + 1];
stringChars(t, m, message);
fprintf(stderr, ": %s\n", message);
RUNTIME_ARRAY(char, message, stringLength(t, m) + 1);
stringChars(t, m, RUNTIME_ARRAY_BODY(message));
fprintf(stderr, ": %s\n", RUNTIME_ARRAY_BODY(message));
} else {
fprintf(stderr, "\n");
}
@ -3610,7 +3617,7 @@ makeTrace(Thread* t, Processor::StackWalker* walker)
}
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);
++ index;
return true;
@ -3635,7 +3642,7 @@ makeTrace(Thread* t, Thread* target)
Visitor(Thread* t): t(t), trace(0) { }
virtual bool visit(Processor::StackWalker* walker) {
trace = makeTrace(t, walker);
trace = vm::makeTrace(t, walker);
return false;
}

View File

@ -18,7 +18,7 @@
#include "processor.h"
#include "constants.h"
#ifdef __MINGW32__
#ifdef PLATFORM_WINDOWS
# define JNICALL __stdcall
#else
# define JNICALL
@ -2371,7 +2371,7 @@ setDaemon(Thread* t, object thread, bool daemon)
{
ACQUIRE_RAW(t, t->m->stateLock);
if (threadDaemon(t, thread) != daemon) {
if ((threadDaemon(t, thread) != 0) != daemon) {
threadDaemon(t, thread) = daemon;
if (daemon) {

View File

@ -11,15 +11,45 @@
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "stdint.h"
#include "jni.h"
#ifdef __MINGW32__
#if (defined __MINGW32__) || (defined _MSC_VER)
# define PATH_SEPARATOR ';'
#else
# define PATH_SEPARATOR ':'
#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 {
void
@ -87,28 +117,28 @@ main(int ac, const char** av)
++ vmArgs.nOptions;
#endif
JavaVMOption options[vmArgs.nOptions];
vmArgs.options = options;
RUNTIME_ARRAY(JavaVMOption, options, vmArgs.nOptions);
vmArgs.options = RUNTIME_ARRAY_BODY(options);
unsigned optionIndex = 0;
#ifdef BOOT_IMAGE
options[optionIndex++].optionString
vmArgs.options[optionIndex++].optionString
= const_cast<char*>("-Davian.bootimage=" BOOT_IMAGE);
#endif
#ifdef BOOT_CLASSPATH
options[optionIndex++].optionString
vmArgs.options[optionIndex++].optionString
= const_cast<char*>("-Xbootclasspath:" BOOT_CLASSPATH);
#endif
#ifdef BOOT_LIBRARY
options[optionIndex++].optionString
vmArgs.options[optionIndex++].optionString
= const_cast<char*>("-Davian.bootstrap=" BOOT_LIBRARY);
#endif
#ifdef BOOT_BUILTINS
options[optionIndex++].optionString
vmArgs.options[optionIndex++].optionString
= const_cast<char*>("-Davian.builtins=" BOOT_BUILTINS);
#endif
@ -118,21 +148,23 @@ main(int ac, const char** av)
unsigned classpathPropertyBufferSize
= sizeof(CLASSPATH_PROPERTY) + classpathSize;
char classpathPropertyBuffer[classpathPropertyBufferSize];
memcpy(classpathPropertyBuffer,
RUNTIME_ARRAY(char, classpathPropertyBuffer, classpathPropertyBufferSize);
memcpy(RUNTIME_ARRAY_BODY(classpathPropertyBuffer),
CLASSPATH_PROPERTY,
sizeof(CLASSPATH_PROPERTY) - 1);
memcpy(classpathPropertyBuffer + sizeof(CLASSPATH_PROPERTY) - 1,
memcpy(RUNTIME_ARRAY_BODY(classpathPropertyBuffer)
+ sizeof(CLASSPATH_PROPERTY) - 1,
classpath,
classpathSize + 1);
options[optionIndex++].optionString = classpathPropertyBuffer;
vmArgs.options[optionIndex++].optionString
= RUNTIME_ARRAY_BODY(classpathPropertyBuffer);
for (int i = 1; i < ac; ++i) {
if (strncmp(av[i], "-X", 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) {
unsigned size = nameLength + 3 + sizeof(SO_SUFFIX);
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);
} else {
if (!name) {

View File

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

View File

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

View File

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

View File

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

View File

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