diff --git a/classpath/java-io.cpp b/classpath/java-io.cpp index 868c449062..035a6ecc1c 100644 --- a/classpath/java-io.cpp +++ b/classpath/java-io.cpp @@ -14,28 +14,39 @@ #include #include #include -#include -#include #include "jni.h" #include "jni-util.h" -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS + # include # include # include +# include -# 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 # include # 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(d); + } else { + return 0; + } +} + +extern "C" JNIEXPORT jstring JNICALL +Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle) +{ + Directory* d = reinterpret_cast(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(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) { diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 1225ca9e69..dacf5d2338 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -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 -#include "sys/utsname.h" -#include "sys/wait.h" -#endif - -#ifdef __APPLE__ -# define SO_SUFFIX ".jnilib" -#include -#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 +# 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(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(buffer), lstrlenW(buffer)); + } else { + r = 0; + } +# else LPWSTR home = _wgetenv(L"USERPROFILE"); r = e->NewString(reinterpret_cast(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(tb.time) * 1000) + static_cast(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); } diff --git a/classpath/java-nio.cpp b/classpath/java-nio.cpp index 84810c8000..8eec3cc5fc 100644 --- a/classpath/java-nio.cpp +++ b/classpath/java-nio.cpp @@ -12,16 +12,20 @@ #include #include #include -#include -#include #include "jni.h" #include "jni-util.h" -#ifdef WIN32 +#ifdef PLATFORM_WINDOWS # include # include +# ifdef _MSC_VER +# define snprintf sprintf_s +# else +# include +# endif #else +# include # include # include # include @@ -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(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(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(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))) { diff --git a/classpath/java-util.cpp b/classpath/java-util.cpp index 17dac0e960..f5b48bb158 100644 --- a/classpath/java-util.cpp +++ b/classpath/java-util.cpp @@ -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); diff --git a/classpath/jni-util.h b/classpath/jni-util.h index 9e0972225a..d144e704db 100644 --- a/classpath/jni-util.h +++ b/classpath/jni-util.h @@ -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 RuntimeArray { + public: + RuntimeArray(unsigned size): + body(static_cast(malloc(size * sizeof(T)))) + { } + + ~RuntimeArray() { + free(body); + } + + T* body; +}; + +# define RUNTIME_ARRAY(type, name, size) RuntimeArray 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 diff --git a/makefile b/makefile index 88d6b07919..43309975c0 100644 --- a/makefile +++ b/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 $(@) diff --git a/src/arch.h b/src/arch.h index a6fc2af570..49b30bda62 100644 --- a/src/arch.h +++ b/src/arch.h @@ -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 diff --git a/src/boot.cpp b/src/boot.cpp index 9fca36f7f5..e313b6c553 100644 --- a/src/boot.cpp +++ b/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 diff --git a/src/builtin.cpp b/src/builtin.cpp index 46e2850c0e..8f12b2921f 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -234,9 +234,9 @@ Avian_avian_SystemClassLoader_resourceExists object name = reinterpret_cast(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(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(makeString(t, AVIAN_VERSION)); - } else if (strcmp(n, "file.encoding") == 0) { + } else if (::strcmp(RUNTIME_ARRAY_BODY(n), "file.encoding") == 0) { r = reinterpret_cast(makeString(t, "ASCII")); } else { - const char* v = findProperty(t, n); + const char* v = findProperty(t, RUNTIME_ARRAY_BODY(n)); if (v) { r = reinterpret_cast(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(""), - &byteArrayBody(t, methodName(t, method), 0)) + and vm::strcmp(reinterpret_cast(""), + &byteArrayBody(t, methodName(t, method), 0)) == 0) { return true; @@ -919,10 +922,10 @@ Avian_avian_resource_Handler_00024ResourceInputStream_getContentLength object path = reinterpret_cast(*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(*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(t->m->finder->find(p)); + return reinterpret_cast + (t->m->finder->find(RUNTIME_ARRAY_BODY(p))); } else { t->exception = makeNullPointerException(t); return 0; diff --git a/src/common.h b/src/common.h index 21f2dce4a8..7c92f85f2c 100644 --- a/src/common.h +++ b/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 RuntimeArray { + public: + RuntimeArray(unsigned size): + body(static_cast(malloc(size * sizeof(T)))) + { } + + ~RuntimeArray() { + free(body); + } + + T* body; +}; + +# define RUNTIME_ARRAY(type, name, size) RuntimeArray 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; diff --git a/src/compile.cpp b/src/compile.cpp index e045bb04b6..0422d12e7d 100644 --- a/src/compile.cpp +++ b/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(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 (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), "java/lang/Throwable") == 0 and - strcmp + ::strcmp (reinterpret_cast (&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(t); - types[typeOffset++] = POINTER_TYPE; + RUNTIME_ARRAY_BODY(args)[argOffset++] = reinterpret_cast(t); + RUNTIME_ARRAY_BODY(types)[typeOffset++] = POINTER_TYPE; uintptr_t* sp = static_cast(t->stack) + t->arch->frameFooterSize() + t->arch->frameReturnAddressSize(); if (methodFlags(t, method) & ACC_STATIC) { - args[argOffset++] = reinterpret_cast(&class_); + RUNTIME_ARRAY_BODY(args)[argOffset++] + = reinterpret_cast(&class_); } else { - args[argOffset++] = reinterpret_cast(sp++); + RUNTIME_ARRAY_BODY(args)[argOffset++] + = reinterpret_cast(sp++); } - types[typeOffset++] = POINTER_TYPE; + RUNTIME_ARRAY_BODY(types)[typeOffset++] = POINTER_TYPE; MethodSpecIterator it (t, reinterpret_cast (&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(sp); + RUNTIME_ARRAY_BODY(args)[argOffset++] + = reinterpret_cast(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(args[0])); + acquire(t, *reinterpret_cast(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(args[0])); + release(t, *reinterpret_cast(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(t))); + local::defaultThunk(static_cast(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(t), - ::codeAllocator(static_cast(t)), 0, method); + local::codeAllocator(static_cast(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(t), - ::codeAllocator(static_cast(t)), 0, + local::codeAllocator(static_cast(t)), 0, resolveMethod(t, t->m->loader, "java/beans/PropertyChangeSupport", "firePropertyChange", @@ -6615,10 +6634,10 @@ class MyProcessor: public Processor { } compile(static_cast(t), - ::codeAllocator(static_cast(t)), 0, method); + local::codeAllocator(static_cast(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(t), - ::codeAllocator(static_cast(t)), 0, method); + local::codeAllocator(static_cast(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(t), image); + local::boot(static_cast(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(t), &codeAllocator, this); + local::compileThunks(static_cast(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(t), receiver); + local::callWithCurrentContinuation(static_cast(t), receiver); } else { abort(t); } @@ -6823,7 +6843,7 @@ class MyProcessor: public Processor { object after) { if (Continuations) { - ::dynamicWind(static_cast(t), before, thunk, after); + local::dynamicWind(static_cast(t), before, thunk, after); } else { abort(t); } @@ -6853,7 +6873,7 @@ class MyProcessor: public Processor { unsigned start) { if (Continuations) { - ::walkContinuationBody(static_cast(t), w, o, start); + local::walkContinuationBody(static_cast(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 diff --git a/src/compiler.cpp b/src/compiler.cpp index 81e84d5d80..15a82a12f8 100644 --- a/src/compiler.cpp +++ b/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 (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 - (this - c->frameResources)); + return vm::snprintf(buffer, bufferSize, "frame %d", static_cast + (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(state)); + local::restoreState(&c, static_cast(state)); } virtual Subroutine* startSubroutine() { @@ -4978,7 +4997,7 @@ class MyCompiler: public Compiler { virtual void endSubroutine(Subroutine* subroutine) { appendCleanLocals(&c); - static_cast(subroutine)->forkState = ::saveState(&c); + static_cast(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), true); + local::push(&c, footprint, static_cast(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(src), index, true); + local::storeLocal(&c, footprint, static_cast(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 diff --git a/src/gnu.cpp b/src/gnu.cpp index fa655611b2..289f159f4c 100644 --- a/src/gnu.cpp +++ b/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"); diff --git a/src/heap.cpp b/src/heap.cpp index 5ec5ae724d..dbc66ba21a 100644 --- a/src/heap.cpp +++ b/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(p)); + local::collect(c, static_cast(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 diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 11d4e42e34..beff31ec03 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -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 diff --git a/src/machine.cpp b/src/machine.cpp index 46e7bf6d9d..8819dce09e 100644 --- a/src/machine.cpp +++ b/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 + (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("finalize"), - &byteArrayBody(t, methodName(t, m), 0)) == 0 - and strcmp(reinterpret_cast("()V"), - &byteArrayBody(t, methodSpec(t, m), 0)) == 0) + if (vm::strcmp(reinterpret_cast("finalize"), + &byteArrayBody(t, methodName(t, m), 0)) == 0 + and vm::strcmp(reinterpret_cast("()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("ConstantValue"), - &byteArrayBody(t, name, 0)) == 0) + if (vm::strcmp(reinterpret_cast("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("LineNumberTable"), - &byteArrayBody(t, name, 0)) == 0) + if (vm::strcmp(reinterpret_cast("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("Code"), - &byteArrayBody(t, name, 0)) == 0) + if (vm::strcmp(reinterpret_cast("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("finalize"), &byteArrayBody(t, methodName(t, method), 0)) == 0 - and strcmp + and vm::strcmp (reinterpret_cast("()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(""), - &byteArrayBody(t, methodName(t, method), 0)) == 0) + if (vm::strcmp(reinterpret_cast(""), + &byteArrayBody(t, methodName(t, method), 0)) == 0) { methodVmFlags(t, method) |= ClassInitFlag; classVmFlags(t, class_) |= NeedInitFlag; - } else if (strcmp(reinterpret_cast(""), - &byteArrayBody(t, methodName(t, method), 0)) == 0) + } else if (vm::strcmp + (reinterpret_cast(""), + &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(""), - &byteArrayBody(t, methodName(t, o), 0)) == 0) + if (vm::strcmp(reinterpret_cast(""), + &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(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; } diff --git a/src/machine.h b/src/machine.h index 549b464025..2191dedfbe 100644 --- a/src/machine.h +++ b/src/machine.h @@ -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) { diff --git a/src/main.cpp b/src/main.cpp index 074297016d..7fc29b2ea5 100644 --- a/src/main.cpp +++ b/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 RuntimeArray { + public: + RuntimeArray(unsigned size): + body(static_cast(malloc(size * sizeof(T)))) + { } + + ~RuntimeArray() { + free(body); + } + + T* body; +}; + +# define RUNTIME_ARRAY(type, name, size) RuntimeArray 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("-Davian.bootimage=" BOOT_IMAGE); #endif #ifdef BOOT_CLASSPATH - options[optionIndex++].optionString + vmArgs.options[optionIndex++].optionString = const_cast("-Xbootclasspath:" BOOT_CLASSPATH); #endif #ifdef BOOT_LIBRARY - options[optionIndex++].optionString + vmArgs.options[optionIndex++].optionString = const_cast("-Davian.bootstrap=" BOOT_LIBRARY); #endif #ifdef BOOT_BUILTINS - options[optionIndex++].optionString + vmArgs.options[optionIndex++].optionString = const_cast("-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(av[i]); + vmArgs.options[optionIndex++].optionString = const_cast(av[i]); } } diff --git a/src/posix.cpp b/src/posix.cpp index 48096dac52..97cc3ea841 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -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) { diff --git a/src/process.cpp b/src/process.cpp index 41d4a829e5..7732dedae2 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -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; } diff --git a/src/system.h b/src/system.h index bb16c9be5d..909e91b7e6 100644 --- a/src/system.h +++ b/src/system.h @@ -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* diff --git a/src/windows.cpp b/src/windows.cpp index 8af8dafe41..74aa32b498 100644 --- a/src/windows.cpp +++ b/src/windows.cpp @@ -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(context.Eip), reinterpret_cast(context.Ebp), reinterpret_cast(context.Esp)); -#elif defined __x86_64__ - visitor->visit(reinterpret_cast(context.Rip), +#elif defined ARCH_x86_64 + visitor->visit(reinterpret_cast(context.Rip), reinterpret_cast(context.Rbp), reinterpret_cast(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(tb.time) * 1000) - + static_cast(tb.millitm)); + FTIME(&tb); + vm::snprintf(name, MAX_PATH, "%s\\crash-%"LLD".mdmp", directory, + (static_cast(tb.time) * 1000) + + static_cast(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(e->ContextRecord->Eip); void* base = reinterpret_cast(e->ContextRecord->Ebp); void* stack = reinterpret_cast(e->ContextRecord->Esp); void* thread = reinterpret_cast(e->ContextRecord->Ebx); -#elif defined __x86_64__ +#elif defined ARCH_x86_64 void* ip = reinterpret_cast(e->ContextRecord->Rip); void* base = reinterpret_cast(e->ContextRecord->Rbp); void* stack = reinterpret_cast(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(ip); e->ContextRecord->Ebp = reinterpret_cast(base); e->ContextRecord->Esp = reinterpret_cast(stack); e->ContextRecord->Ebx = reinterpret_cast(thread); -#elif defined __x86_64__ +#elif defined ARCH_x86_64 e->ContextRecord->Rip = reinterpret_cast(ip); e->ContextRecord->Rbp = reinterpret_cast(base); e->ContextRecord->Rsp = reinterpret_cast(stack); diff --git a/src/x86.cpp b/src/x86.cpp index 1854a01427..9bb5f9172d 100644 --- a/src/x86.cpp +++ b/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(x) #define CAST2(x) reinterpret_cast(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(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(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(architecture)); + return new (zone->allocate(sizeof(local::MyAssembler))) + local::MyAssembler(system, allocator, zone, + static_cast(architecture)); } - } // namespace vm - -#endif //(defined __i386__) || (defined __x86_64__) diff --git a/src/x86.h b/src/x86.h index a7f8e4dd8f..9a132deb05 100644 --- a/src/x86.h +++ b/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