mirror of
https://github.com/corda/corda.git
synced 2025-01-01 02:36:44 +00:00
add support for building with MSVC on Windows
This commit is contained in:
parent
4297fa04b3
commit
1a0eef7e2d
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)))
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
81
makefile
81
makefile
@ -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 $(@)
|
||||
|
@ -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
|
||||
|
15
src/boot.cpp
15
src/boot.cpp
@ -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
|
||||
|
@ -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;
|
||||
|
166
src/common.h
166
src/common.h
@ -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;
|
||||
|
||||
|
236
src/compile.cpp
236
src/compile.cpp
@ -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
|
||||
|
140
src/compiler.cpp
140
src/compiler.cpp
@ -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
|
||||
|
11
src/gnu.cpp
11
src/gnu.cpp
@ -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");
|
||||
|
41
src/heap.cpp
41
src/heap.cpp
@ -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
|
||||
|
@ -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**>
|
||||
|
101
src/machine.cpp
101
src/machine.cpp
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
58
src/main.cpp
58
src/main.cpp
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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*
|
||||
|
@ -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);
|
||||
|
62
src/x86.cpp
62
src/x86.cpp
@ -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__)
|
||||
|
20
src/x86.h
20
src/x86.h
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user