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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,28 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.security;
public class AccessControlException extends SecurityException {
private final Permission permission;
public AccessControlException(String message) {
this(message, null);
}
public AccessControlException(String message, Permission permission) {
super(message);
this.permission = permission;
}
public Permission getPermission() {
return permission;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -64,13 +64,14 @@ void
dispose(Thread* t, Thread* o, bool remove)
{
if (remove) {
// debug
#ifndef NDEBUG
expect(t, find(t->m->rootThread, o));
unsigned c = count(t->m->rootThread, o);
Thread* threads[c];
Thread** threads = static_cast<Thread**>
(allocate(t->m->system, c * sizeof(Thread*)));
fill(t->m->rootThread, o, threads);
// end debug
#endif
if (o->parent) {
Thread* previous = 0;
@ -110,13 +111,13 @@ dispose(Thread* t, Thread* o, bool remove)
abort(t);
}
// debug
#ifndef NDEBUG
expect(t, not find(t->m->rootThread, o));
for (unsigned i = 0; i < c; ++i) {
expect(t, find(t->m->rootThread, threads[i]));
}
// end debug
#endif
}
o->dispose();
@ -211,6 +212,23 @@ killZombies(Thread* t, Thread* o)
}
}
object
makeJavaThread(Thread* t, Thread* parent)
{
object group;
if (parent) {
group = threadGroup(t, parent->javaThread);
} else {
group = makeThreadGroup(t, 0, 0);
}
const unsigned NewState = 0;
const unsigned NormalPriority = 5;
return makeThread
(t, 0, 0, 0, NewState, NormalPriority, 0, 0, 0, t->m->loader, 0, 0, group);
}
unsigned
footprint(Thread* t)
{
@ -547,20 +565,14 @@ postCollect(Thread* t)
void
finalizeObject(Thread* t, object o)
{
if (t->state == Thread::ExitState) {
// don't waste time running Java finalizers if we're exiting the
// VM
return;
}
for (object c = objectClass(t, o); c; c = classSuper(t, c)) {
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
object m = arrayBody(t, classMethodTable(t, c), i);
if (strcmp(reinterpret_cast<const int8_t*>("finalize"),
&byteArrayBody(t, methodName(t, m), 0)) == 0
and strcmp(reinterpret_cast<const int8_t*>("()V"),
&byteArrayBody(t, methodSpec(t, m), 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("finalize"),
&byteArrayBody(t, methodName(t, m), 0)) == 0
and vm::strcmp(reinterpret_cast<const int8_t*>("()V"),
&byteArrayBody(t, methodSpec(t, m), 0)) == 0)
{
t->m->processor->invoke(t, m, o);
t->exception = 0;
@ -577,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);
@ -1020,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();
@ -1037,8 +1049,8 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("ConstantValue"),
&byteArrayBody(t, name, 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("ConstantValue"),
&byteArrayBody(t, name, 0)) == 0)
{
value = s.read2();
} else {
@ -1069,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;
@ -1098,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;
@ -1106,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);
@ -1139,7 +1151,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
}
}
if (staticTypes[i] == ObjectField) {
if (RUNTIME_ARRAY_BODY(staticTypes)[i] == ObjectField) {
singletonMarkObject(t, staticTable, offset / BytesPerWord);
}
@ -1227,8 +1239,8 @@ parseCode(Thread* t, Stream& s, object pool)
object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("LineNumberTable"),
&byteArrayBody(t, name, 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("LineNumberTable"),
&byteArrayBody(t, name, 0)) == 0)
{
unsigned lntLength = s.read2();
object lnt = makeLineNumberTable(t, lntLength);
@ -1373,8 +1385,8 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
object name = singletonObject(t, pool, s.read2() - 1);
unsigned length = s.read4();
if (strcmp(reinterpret_cast<const int8_t*>("Code"),
&byteArrayBody(t, name, 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("Code"),
&byteArrayBody(t, name, 0)) == 0)
{
code = parseCode(t, s, pool);
} else {
@ -1423,10 +1435,10 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
}
if (UNLIKELY((classFlags(t, class_) & ACC_INTERFACE) == 0
and strcmp
and vm::strcmp
(reinterpret_cast<const int8_t*>("finalize"),
&byteArrayBody(t, methodName(t, method), 0)) == 0
and strcmp
and vm::strcmp
(reinterpret_cast<const int8_t*>("()V"),
&byteArrayBody(t, methodSpec(t, method), 0)) == 0
and (not emptyMethod(t, method))))
@ -1436,13 +1448,14 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
} else {
methodOffset(t, method) = i;
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
{
methodVmFlags(t, method) |= ClassInitFlag;
classVmFlags(t, class_) |= NeedInitFlag;
} else if (strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
} else if (vm::strcmp
(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0)) == 0)
{
methodVmFlags(t, method) |= ConstructorFlag;
}
@ -2016,6 +2029,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
processor(processor),
rootThread(0),
exclusive(0),
finalizeThread(0),
jniReferences(0),
properties(properties),
propertyCount(propertyCount),
@ -2044,6 +2058,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder,
weakReferences(0),
tenuredWeakReferences(0),
shutdownHooks(0),
objectsToFinalize(0),
unsafe(false),
triedBuiltinOnLoad(false),
heapPoolIndex(0)
@ -2172,23 +2187,11 @@ Thread::init()
parent->child = this;
}
if (javaThread) {
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
} else {
object group;
if (parent) {
group = threadGroup(this, parent->javaThread);
} else {
group = makeThreadGroup(this, 0, 0);
}
const unsigned NewState = 0;
const unsigned NormalPriority = 5;
this->javaThread = makeThread
(this, reinterpret_cast<int64_t>(this), 0, 0, NewState, NormalPriority,
0, 0, 0, m->loader, 0, 0, group);
if (javaThread == 0) {
this->javaThread = makeJavaThread(this, parent);
}
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
}
void
@ -2256,6 +2259,22 @@ shutDown(Thread* t)
}
}
}
// tell finalize thread to exit and wait for it to do so
{ ACQUIRE(t, t->m->stateLock);
Thread* finalizeThread = t->m->finalizeThread;
if (finalizeThread) {
t->m->finalizeThread = 0;
t->m->stateLock->notifyAll(t->systemThread);
while (finalizeThread->state != Thread::ZombieState
and finalizeThread->state != Thread::JoinedState)
{
ENTER(t, Thread::IdleState);
t->m->stateLock->wait(t->systemThread, 0);
}
}
}
}
void
@ -2519,7 +2538,7 @@ makeNewGeneral(Thread* t, object class_)
}
if (classVmFlags(t, class_) & HasFinalizerFlag) {
addFinalizer(t, instance, finalizeObject);
addFinalizer(t, instance, 0);
}
return instance;
@ -2643,8 +2662,8 @@ classInitializer(Thread* t, object class_)
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, class_)); ++i) {
object o = arrayBody(t, classMethodTable(t, class_), i);
if (strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, o), 0)) == 0)
if (vm::strcmp(reinterpret_cast<const int8_t*>("<clinit>"),
&byteArrayBody(t, methodName(t, o), 0)) == 0)
{
return o;
}
@ -2747,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:
@ -2857,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) {
@ -3224,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;
}
@ -3429,7 +3452,24 @@ collect(Thread* t, Heap::CollectionType type)
for (; f; f = finalizerNext(t, f)) {
void (*function)(Thread*, object);
memcpy(&function, &finalizerFinalize(t, f), BytesPerWord);
function(t, finalizerTarget(t, f));
if (function) {
function(t, finalizerTarget(t, f));
} else {
m->objectsToFinalize = makePair
(t, finalizerTarget(t, f), m->objectsToFinalize);
}
}
if (m->objectsToFinalize and m->finalizeThread == 0) {
m->finalizeThread = m->processor->makeThread
(m, makeJavaThread(t, m->rootThread), m->rootThread);
if (not t->m->system->success
(m->system->start(&(m->finalizeThread->runnable))))
{
m->finalizeThread->exit();
m->finalizeThread = 0;
}
}
}
@ -3449,11 +3489,12 @@ walk(Thread* t, Heap::Walker* w, object o, unsigned start)
= (arrayElementSize ?
cast<uintptr_t>(o, fixedSize - BytesPerWord) : 0);
uint32_t mask[intArrayLength(t, objectMask)];
memcpy(mask, &intArrayBody(t, objectMask, 0),
RUNTIME_ARRAY(uint32_t, mask, intArrayLength(t, objectMask));
memcpy(RUNTIME_ARRAY_BODY(mask), &intArrayBody(t, objectMask, 0),
intArrayLength(t, objectMask) * 4);
more = ::walk(t, w, mask, fixedSize, arrayElementSize, arrayLength, start);
more = ::walk(t, w, RUNTIME_ARRAY_BODY(mask), fixedSize, arrayElementSize,
arrayLength, start);
} else if (classVmFlags(t, class_) & SingletonFlag) {
unsigned length = singletonLength(t, o);
if (length) {
@ -3502,6 +3543,7 @@ visitRoots(Machine* m, Heap::Visitor* v)
v->visit(&(m->types));
v->visit(&(m->jniMethodTable));
v->visit(&(m->shutdownHooks));
v->visit(&(m->objectsToFinalize));
for (Thread* t = m->rootThread; t; t = t->peer) {
::visitRoots(t, v);
@ -3529,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");
}
@ -3575,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;
@ -3600,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;
}
@ -3624,6 +3666,36 @@ runJavaThread(Thread* t)
}
}
void
runFinalizeThread(Thread* t)
{
setDaemon(t, t->javaThread, true);
object list = 0;
PROTECT(t, list);
while (true) {
{ ACQUIRE(t, t->m->stateLock);
while (t->m->finalizeThread and t->m->objectsToFinalize == 0) {
ENTER(t, Thread::IdleState);
t->m->stateLock->wait(t->systemThread, 0);
}
if (t->m->finalizeThread == 0) {
return;
} else {
list = t->m->objectsToFinalize;
t->m->objectsToFinalize = 0;
}
}
for (; list; list = pairSecond(t, list)) {
finalizeObject(t, pairFirst(t, list));
}
}
}
void
noop()
{ }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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