bulk, global reformat

This commit is contained in:
Joshua Warner
2014-07-11 09:50:18 -06:00
parent 7642b94308
commit 836cc41320
157 changed files with 18636 additions and 14484 deletions

View File

@ -20,40 +20,41 @@
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# define UNICODE #define UNICODE
# include <windows.h> #include <windows.h>
# include <io.h> #include <io.h>
# include <direct.h> #include <direct.h>
# include <share.h> #include <share.h>
# define ACCESS _waccess #define ACCESS _waccess
# define CLOSE _close #define CLOSE _close
# define READ _read #define READ _read
# define WRITE _write #define WRITE _write
# define STAT _wstat #define STAT _wstat
# define STRUCT_STAT struct _stat #define STRUCT_STAT struct _stat
# define MKDIR(path, mode) _wmkdir(path) #define MKDIR(path, mode) _wmkdir(path)
# define CHMOD(path, mode) _wchmod(path, mode) #define CHMOD(path, mode) _wchmod(path, mode)
# define REMOVE _wremove #define REMOVE _wremove
# define RENAME _wrename #define RENAME _wrename
# define OPEN_MASK O_BINARY #define OPEN_MASK O_BINARY
# define CHECK_X_OK R_OK #define CHECK_X_OK R_OK
# ifdef _MSC_VER #ifdef _MSC_VER
# define S_ISREG(x) ((x) & _S_IFREG) #define S_ISREG(x) ((x)&_S_IFREG)
# define S_ISDIR(x) ((x) & _S_IFDIR) #define S_ISDIR(x) ((x)&_S_IFDIR)
# define S_IRUSR _S_IREAD #define S_IRUSR _S_IREAD
# define S_IWUSR _S_IWRITE #define S_IWUSR _S_IWRITE
# define W_OK 2 #define W_OK 2
# define R_OK 4 #define R_OK 4
# else #else
# define OPEN _wopen #define OPEN _wopen
# endif #endif
# define GET_CHARS GetStringChars #define GET_CHARS GetStringChars
# define RELEASE_CHARS(path, chars) ReleaseStringChars(path, reinterpret_cast<const jchar*>(chars)) #define RELEASE_CHARS(path, chars) \
ReleaseStringChars(path, reinterpret_cast<const jchar*>(chars))
typedef wchar_t char_t; typedef wchar_t char_t;
@ -68,44 +69,47 @@ typedef wchar_t char_t;
#else // not PLATFORM_WINDOWS #else // not PLATFORM_WINDOWS
# include <dirent.h> #include <dirent.h>
# include <unistd.h> #include <unistd.h>
# include "sys/mman.h" #include "sys/mman.h"
# define ACCESS access #define ACCESS access
# define OPEN open #define OPEN open
# define CLOSE close #define CLOSE close
# define READ read #define READ read
# define WRITE write #define WRITE write
# define STAT stat #define STAT stat
# define STRUCT_STAT struct stat #define STRUCT_STAT struct stat
# define MKDIR mkdir #define MKDIR mkdir
# define CHMOD chmod #define CHMOD chmod
# define REMOVE remove #define REMOVE remove
# define RENAME rename #define RENAME rename
# define OPEN_MASK 0 #define OPEN_MASK 0
# define CHECK_X_OK X_OK #define CHECK_X_OK X_OK
# define GET_CHARS GetStringUTFChars #define GET_CHARS GetStringUTFChars
# define RELEASE_CHARS ReleaseStringUTFChars #define RELEASE_CHARS ReleaseStringUTFChars
typedef char char_t; typedef char char_t;
#endif // not PLATFORM_WINDOWS #endif // not PLATFORM_WINDOWS
#ifndef WINAPI_FAMILY #ifndef WINAPI_FAMILY
# ifndef WINAPI_PARTITION_DESKTOP #ifndef WINAPI_PARTITION_DESKTOP
# define WINAPI_PARTITION_DESKTOP 1 #define WINAPI_PARTITION_DESKTOP 1
# endif #endif
# ifndef WINAPI_FAMILY_PARTITION #ifndef WINAPI_FAMILY_PARTITION
# define WINAPI_FAMILY_PARTITION(x) (x) #define WINAPI_FAMILY_PARTITION(x) (x)
# endif #endif
#endif // WINAPI_FAMILY #endif // WINAPI_FAMILY
#if !defined(SKIP_OPERATOR_NEW) #if !defined(SKIP_OPERATOR_NEW)
inline void* operator new(size_t, void* p) throw() { return p; } inline void* operator new(size_t, void* p) throw()
{
return p;
}
#endif #endif
typedef const char_t* string_t; typedef const char_t* string_t;
@ -113,8 +117,7 @@ typedef const char_t* string_t;
namespace { namespace {
#ifdef _MSC_VER #ifdef _MSC_VER
inline int inline int OPEN(string_t path, int mask, int mode)
OPEN(string_t path, int mask, int mode)
{ {
int fd; int fd;
if (_wsopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) { if (_wsopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) {
@ -125,8 +128,7 @@ OPEN(string_t path, int mask, int mode)
} }
#endif #endif
inline bool inline bool exists(string_t path)
exists(string_t path)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
return GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES; return GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES;
@ -136,8 +138,7 @@ exists(string_t path)
#endif #endif
} }
inline int inline int doOpen(JNIEnv* e, string_t path, int mask)
doOpen(JNIEnv* e, string_t path, int mask)
{ {
int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR); int fd = OPEN(path, mask | OPEN_MASK, S_IRUSR | S_IWUSR);
if (fd == -1) { if (fd == -1) {
@ -150,8 +151,7 @@ doOpen(JNIEnv* e, string_t path, int mask)
return fd; return fd;
} }
inline void inline void doClose(JNIEnv* e, jint fd)
doClose(JNIEnv* e, jint fd)
{ {
int r = CLOSE(fd); int r = CLOSE(fd);
if (r == -1) { if (r == -1) {
@ -159,8 +159,7 @@ doClose(JNIEnv* e, jint fd)
} }
} }
inline int inline int doRead(JNIEnv* e, jint fd, jbyte* data, jint length)
doRead(JNIEnv* e, jint fd, jbyte* data, jint length)
{ {
int r = READ(fd, data, length); int r = READ(fd, data, length);
if (r > 0) { if (r > 0) {
@ -173,8 +172,7 @@ doRead(JNIEnv* e, jint fd, jbyte* data, jint length)
} }
} }
inline void inline void doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length)
doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length)
{ {
int r = WRITE(fd, data, length); int r = WRITE(fd, data, length);
if (r != length) { if (r != length) {
@ -182,14 +180,16 @@ doWrite(JNIEnv* e, jint fd, const jbyte* data, jint length)
} }
} }
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
class Directory { class Directory {
public: public:
Directory(): handle(0), findNext(false) { } Directory() : handle(0), findNext(false)
{
}
virtual string_t next() { virtual string_t next()
{
if (handle and handle != INVALID_HANDLE_VALUE) { if (handle and handle != INVALID_HANDLE_VALUE) {
if (findNext) { if (findNext) {
if (FindNextFileW(handle, &data)) { if (FindNextFileW(handle, &data)) {
@ -203,7 +203,8 @@ class Directory {
return 0; return 0;
} }
virtual void dispose() { virtual void dispose()
{
if (handle and handle != INVALID_HANDLE_VALUE) { if (handle and handle != INVALID_HANDLE_VALUE) {
FindClose(handle); FindClose(handle);
} }
@ -219,29 +220,30 @@ class Directory {
#endif // not PLATFORM_WINDOWS #endif // not PLATFORM_WINDOWS
} // namespace } // namespace
static inline string_t getChars(JNIEnv* e, jstring path) { static inline string_t getChars(JNIEnv* e, jstring path)
{
return reinterpret_cast<string_t>(e->GET_CHARS(path, 0)); return reinterpret_cast<string_t>(e->GET_CHARS(path, 0));
} }
static inline void releaseChars(JNIEnv* e, jstring path, string_t chars) { static inline void releaseChars(JNIEnv* e, jstring path, string_t chars)
{
e->RELEASE_CHARS(path, chars); e->RELEASE_CHARS(path, chars);
} }
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_toCanonicalPath(JNIEnv* /*e*/, jclass, jstring path) Java_java_io_File_toCanonicalPath(JNIEnv* /*e*/, jclass, jstring path)
{ {
// todo // todo
return path; return path;
} }
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path) Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
const unsigned BufferSize = MAX_PATH; const unsigned BufferSize = MAX_PATH;
@ -250,25 +252,25 @@ Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
releaseChars(e, path, chars); releaseChars(e, path, chars);
if (success) { if (success) {
return e->NewString return e->NewString(reinterpret_cast<const jchar*>(buffer),
(reinterpret_cast<const jchar*>(buffer), wcslen(buffer)); wcslen(buffer));
} }
} }
return path; return path;
# else #else
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if(chars) { if (chars) {
std::wstring partialPath = chars; std::wstring partialPath = chars;
releaseChars(e, path, chars); releaseChars(e, path, chars);
std::wstring fullPath = AvianInterop::GetFullPath(partialPath); std::wstring fullPath = AvianInterop::GetFullPath(partialPath);
return e->NewString return e->NewString(reinterpret_cast<const jchar*>(fullPath.c_str()),
(reinterpret_cast<const jchar*>(fullPath.c_str()), fullPath.length()); fullPath.length());
} }
return path; return path;
# endif #endif
#else #else
jstring result = path; jstring result = path;
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
@ -290,44 +292,43 @@ Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
} }
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_io_File_length(JNIEnv* e, jclass, jstring path) Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
// Option: without opening file // Option: without opening file
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946(v=vs.85).aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946(v=vs.85).aspx
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if(chars) { if (chars) {
LARGE_INTEGER fileSize; LARGE_INTEGER fileSize;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE file = CreateFileW HANDLE file = CreateFileW(
(chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
#else #else
HANDLE file = CreateFile2 HANDLE file = CreateFile2(
(chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr); chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
#endif #endif
releaseChars(e, path, chars); releaseChars(e, path, chars);
if (file == INVALID_HANDLE_VALUE) if (file == INVALID_HANDLE_VALUE)
return 0; return 0;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
if(!GetFileSizeEx(file, &fileSize)) if (!GetFileSizeEx(file, &fileSize)) {
{
CloseHandle(file); CloseHandle(file);
return 0; return 0;
} }
#else #else
FILE_STANDARD_INFO info; FILE_STANDARD_INFO info;
if(!GetFileInformationByHandleEx(file, FileStandardInfo, &info, sizeof(info))) if (!GetFileInformationByHandleEx(
{ file, FileStandardInfo, &info, sizeof(info))) {
CloseHandle(file); CloseHandle(file);
return 0; return 0;
} }
fileSize = info.EndOfFile; fileSize = info.EndOfFile;
#endif #endif
CloseHandle(file); CloseHandle(file);
return static_cast<jlong>(fileSize.QuadPart); return static_cast<jlong>(fileSize.QuadPart);
} }
#else #else
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -339,13 +340,13 @@ Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
} }
} }
#endif #endif
return 0; return 0;
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path) Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -360,7 +361,7 @@ Java_java_io_File_mkdir(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path) Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
{ {
bool result = false; bool result = false;
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
@ -382,7 +383,7 @@ Java_java_io_File_createNewFile(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_File_delete(JNIEnv* e, jclass, jstring path) Java_java_io_File_delete(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -395,7 +396,7 @@ Java_java_io_File_delete(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_canRead(JNIEnv* e, jclass, jstring path) Java_java_io_File_canRead(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -407,7 +408,7 @@ Java_java_io_File_canRead(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_canWrite(JNIEnv* e, jclass, jstring path) Java_java_io_File_canWrite(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -419,7 +420,7 @@ Java_java_io_File_canWrite(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_canExecute(JNIEnv* e, jclass, jstring path) Java_java_io_File_canExecute(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -432,13 +433,17 @@ Java_java_io_File_canExecute(JNIEnv* e, jclass, jstring path)
#ifndef PLATFORM_WINDOWS #ifndef PLATFORM_WINDOWS
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_setExecutable(JNIEnv* e, jclass, jstring path, jboolean executable, jboolean ownerOnly) Java_java_io_File_setExecutable(JNIEnv* e,
jclass,
jstring path,
jboolean executable,
jboolean ownerOnly)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if(chars) { if (chars) {
jboolean v; jboolean v;
int mask; int mask;
if(ownerOnly) { if (ownerOnly) {
mask = S_IXUSR; mask = S_IXUSR;
} else { } else {
mask = S_IXUSR | S_IXGRP | S_IXOTH; mask = S_IXUSR | S_IXGRP | S_IXOTH;
@ -446,14 +451,14 @@ Java_java_io_File_setExecutable(JNIEnv* e, jclass, jstring path, jboolean execut
STRUCT_STAT s; STRUCT_STAT s;
int r = STAT(chars, &s); int r = STAT(chars, &s);
if(r == 0) { if (r == 0) {
int mode = s.st_mode; int mode = s.st_mode;
if(executable) { if (executable) {
mode |= mask; mode |= mask;
} else { } else {
mode &= ~mask; mode &= ~mask;
} }
if(CHMOD(chars, mode) != 0) { if (CHMOD(chars, mode) != 0) {
v = false; v = false;
} else { } else {
v = true; v = true;
@ -470,7 +475,11 @@ Java_java_io_File_setExecutable(JNIEnv* e, jclass, jstring path, jboolean execut
#else // ifndef PLATFORM_WINDOWS #else // ifndef PLATFORM_WINDOWS
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_setExecutable(JNIEnv*, jclass, jstring, jboolean executable, jboolean) Java_java_io_File_setExecutable(JNIEnv*,
jclass,
jstring,
jboolean executable,
jboolean)
{ {
return executable; return executable;
} }
@ -478,7 +487,7 @@ Java_java_io_File_setExecutable(JNIEnv*, jclass, jstring, jboolean executable, j
#endif #endif
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_) Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
{ {
string_t oldChars = getChars(e, old); string_t oldChars = getChars(e, old);
string_t newChars = getChars(e, new_); string_t newChars = getChars(e, new_);
@ -499,7 +508,7 @@ Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path) Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -514,7 +523,7 @@ Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path) Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -529,7 +538,7 @@ Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_exists(JNIEnv* e, jclass, jstring path) Java_java_io_File_exists(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -542,43 +551,42 @@ Java_java_io_File_exists(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_io_File_lastModified(JNIEnv* e, jclass, jstring path) Java_java_io_File_lastModified(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
// Option: without opening file // Option: without opening file
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946(v=vs.85).aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946(v=vs.85).aspx
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE hFile = CreateFileW HANDLE hFile = CreateFileW(
(chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
# else #else
HANDLE hFile = CreateFile2 HANDLE hFile = CreateFile2(
(chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr); chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
# endif #endif
releaseChars(e, path, chars); releaseChars(e, path, chars);
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
return 0; return 0;
LARGE_INTEGER fileDate, filetimeToUnixEpochAdjustment; LARGE_INTEGER fileDate, filetimeToUnixEpochAdjustment;
filetimeToUnixEpochAdjustment.QuadPart = 11644473600000L * 10000L; filetimeToUnixEpochAdjustment.QuadPart = 11644473600000L * 10000L;
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
FILETIME fileLastWriteTime; FILETIME fileLastWriteTime;
if (!GetFileTime(hFile, 0, 0, &fileLastWriteTime)) if (!GetFileTime(hFile, 0, 0, &fileLastWriteTime)) {
{
CloseHandle(hFile); CloseHandle(hFile);
return 0; return 0;
} }
fileDate.HighPart = fileLastWriteTime.dwHighDateTime; fileDate.HighPart = fileLastWriteTime.dwHighDateTime;
fileDate.LowPart = fileLastWriteTime.dwLowDateTime; fileDate.LowPart = fileLastWriteTime.dwLowDateTime;
# else #else
FILE_BASIC_INFO fileInfo; FILE_BASIC_INFO fileInfo;
if (!GetFileInformationByHandleEx(hFile, FileBasicInfo, &fileInfo, sizeof(fileInfo))) if (!GetFileInformationByHandleEx(
{ hFile, FileBasicInfo, &fileInfo, sizeof(fileInfo))) {
CloseHandle(hFile); CloseHandle(hFile);
return 0; return 0;
} }
fileDate = fileInfo.ChangeTime; fileDate = fileInfo.ChangeTime;
# endif #endif
CloseHandle(hFile); CloseHandle(hFile);
fileDate.QuadPart -= filetimeToUnixEpochAdjustment.QuadPart; fileDate.QuadPart -= filetimeToUnixEpochAdjustment.QuadPart;
return fileDate.QuadPart / 10000000L; return fileDate.QuadPart / 10000000L;
@ -590,13 +598,13 @@ Java_java_io_File_lastModified(JNIEnv* e, jclass, jstring path)
if (res == -1) { if (res == -1) {
return 0; return 0;
} }
# ifdef __APPLE__ #ifdef __APPLE__
#define MTIME st_mtimespec #define MTIME st_mtimespec
# else #else
#define MTIME st_mtim #define MTIME st_mtim
# endif #endif
return (static_cast<jlong>(fileStat.MTIME.tv_sec) * 1000) + return (static_cast<jlong>(fileStat.MTIME.tv_sec) * 1000)
(static_cast<jlong>(fileStat.MTIME.tv_nsec) / (1000*1000)); + (static_cast<jlong>(fileStat.MTIME.tv_nsec) / (1000 * 1000));
#endif #endif
} }
@ -606,7 +614,7 @@ Java_java_io_File_lastModified(JNIEnv* e, jclass, jstring path)
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path) Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -620,11 +628,16 @@ Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
releaseChars(e, path, chars); releaseChars(e, path, chars);
Directory* d = new (malloc(sizeof(Directory))) Directory; Directory* d = new (malloc(sizeof(Directory))) Directory;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data)); d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data));
#else #else
d->handle = FindFirstFileExW(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, NULL, 0); d->handle = FindFirstFileExW(RUNTIME_ARRAY_BODY(buffer),
#endif FindExInfoStandard,
&(d->data),
FindExSearchNameMatch,
NULL,
0);
#endif
if (d->handle == INVALID_HANDLE_VALUE) { if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose(); d->dispose();
d = 0; d = 0;
@ -637,7 +650,7 @@ Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle) Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
{ {
Directory* d = reinterpret_cast<Directory*>(handle); Directory* d = reinterpret_cast<Directory*>(handle);
@ -656,7 +669,7 @@ Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle) Java_java_io_File_closeDir(JNIEnv*, jclass, jlong handle)
{ {
reinterpret_cast<Directory*>(handle)->dispose(); reinterpret_cast<Directory*>(handle)->dispose();
} }
@ -664,7 +677,7 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle)
#else // not PLATFORM_WINDOWS #else // not PLATFORM_WINDOWS
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path) Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -677,18 +690,17 @@ Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle) Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
{ {
struct dirent * directoryEntry; struct dirent* directoryEntry;
if (handle!=0) { if (handle != 0) {
while (true) { while (true) {
directoryEntry = readdir(reinterpret_cast<DIR*>(handle)); directoryEntry = readdir(reinterpret_cast<DIR*>(handle));
if (directoryEntry == NULL) { if (directoryEntry == NULL) {
return NULL; return NULL;
} else if (strcmp(directoryEntry->d_name, ".") == 0 } else if (strcmp(directoryEntry->d_name, ".") == 0
|| strcmp(directoryEntry->d_name, "..") == 0) || strcmp(directoryEntry->d_name, "..") == 0) {
{
// skip . or .. and try again // skip . or .. and try again
} else { } else {
return e->NewStringUTF(directoryEntry->d_name); return e->NewStringUTF(directoryEntry->d_name);
@ -699,9 +711,9 @@ Java_java_io_File_readDir(JNIEnv* e, jclass, jlong handle)
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle) Java_java_io_File_closeDir(JNIEnv*, jclass, jlong handle)
{ {
if (handle!=0) { if (handle != 0) {
closedir(reinterpret_cast<DIR*>(handle)); closedir(reinterpret_cast<DIR*>(handle));
} }
} }
@ -709,7 +721,7 @@ Java_java_io_File_closeDir(JNIEnv* , jclass, jlong handle)
#endif // not PLATFORM_WINDOWS #endif // not PLATFORM_WINDOWS
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path) Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
@ -722,7 +734,7 @@ Java_java_io_FileInputStream_open(JNIEnv* e, jclass, jstring path)
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_io_FileInputStream_read__I(JNIEnv* e, jclass, jint fd) Java_java_io_FileInputStream_read__I(JNIEnv* e, jclass, jint fd)
{ {
jbyte data; jbyte data;
int r = doRead(e, fd, &data, 1); int r = doRead(e, fd, &data, 1);
@ -734,8 +746,12 @@ Java_java_io_FileInputStream_read__I(JNIEnv* e, jclass, jint fd)
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_io_FileInputStream_read__I_3BII Java_java_io_FileInputStream_read__I_3BII(JNIEnv* e,
(JNIEnv* e, jclass, jint fd, jbyteArray b, jint offset, jint length) jclass,
jint fd,
jbyteArray b,
jint offset,
jint length)
{ {
jbyte* data = static_cast<jbyte*>(malloc(length)); jbyte* data = static_cast<jbyte*>(malloc(length));
if (data == 0) { if (data == 0) {
@ -753,18 +769,22 @@ Java_java_io_FileInputStream_read__I_3BII
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_FileInputStream_close(JNIEnv* e, jclass, jint fd) Java_java_io_FileInputStream_close(JNIEnv* e, jclass, jint fd)
{ {
doClose(e, fd); doClose(e, fd);
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path, jboolean append) Java_java_io_FileOutputStream_open(JNIEnv* e,
jclass,
jstring path,
jboolean append)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
int fd = doOpen(e, chars, append int fd = doOpen(e,
? (O_WRONLY | O_CREAT | O_APPEND) chars,
append ? (O_WRONLY | O_CREAT | O_APPEND)
: (O_WRONLY | O_CREAT | O_TRUNC)); : (O_WRONLY | O_CREAT | O_TRUNC));
releaseChars(e, path, chars); releaseChars(e, path, chars);
return fd; return fd;
@ -774,15 +794,19 @@ Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path, jboolean app
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_FileOutputStream_write__II(JNIEnv* e, jclass, jint fd, jint c) Java_java_io_FileOutputStream_write__II(JNIEnv* e, jclass, jint fd, jint c)
{ {
jbyte data = c; jbyte data = c;
doWrite(e, fd, &data, 1); doWrite(e, fd, &data, 1);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_FileOutputStream_write__I_3BII Java_java_io_FileOutputStream_write__I_3BII(JNIEnv* e,
(JNIEnv* e, jclass, jint fd, jbyteArray b, jint offset, jint length) jclass,
jint fd,
jbyteArray b,
jint offset,
jint length)
{ {
jbyte* data = static_cast<jbyte*>(malloc(length)); jbyte* data = static_cast<jbyte*>(malloc(length));
@ -800,49 +824,53 @@ Java_java_io_FileOutputStream_write__I_3BII
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_FileOutputStream_close(JNIEnv* e, jclass, jint fd) Java_java_io_FileOutputStream_close(JNIEnv* e, jclass, jint fd)
{ {
doClose(e, fd); doClose(e, fd);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path, Java_java_io_RandomAccessFile_open(JNIEnv* e,
jboolean allowWrite, jlongArray result) jclass,
jstring path,
jboolean allowWrite,
jlongArray result)
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
jlong peer = 0; jlong peer = 0;
jlong length = 0; jlong length = 0;
int flags = (allowWrite ? O_RDWR | O_CREAT : O_RDONLY) | OPEN_MASK; int flags = (allowWrite ? O_RDWR | O_CREAT : O_RDONLY) | OPEN_MASK;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if defined(PLATFORM_WINDOWS) #if defined(PLATFORM_WINDOWS)
int fd = ::_wopen(chars, flags); int fd = ::_wopen(chars, flags);
#else #else
int fd = ::open((const char*)chars, flags, 0666); int fd = ::open((const char*)chars, flags, 0666);
#endif #endif
releaseChars(e, path, chars); releaseChars(e, path, chars);
if (fd == -1) { if (fd == -1) {
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return; return;
} }
struct ::stat fileStats; struct ::stat fileStats;
if(::fstat(fd, &fileStats) == -1) { if (::fstat(fd, &fileStats) == -1) {
::close(fd); ::close(fd);
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return; return;
} }
peer = fd; peer = fd;
length = fileStats.st_size; length = fileStats.st_size;
#else #else
HANDLE hFile = CreateFile2 HANDLE hFile = CreateFile2(
(chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr); chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
if (hFile == INVALID_HANDLE_VALUE) { if (hFile == INVALID_HANDLE_VALUE) {
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return; return;
} }
FILE_STANDARD_INFO info; FILE_STANDARD_INFO info;
if(!GetFileInformationByHandleEx(hFile, FileStandardInfo, &info, sizeof(info))) { if (!GetFileInformationByHandleEx(
hFile, FileStandardInfo, &info, sizeof(info))) {
CloseHandle(hFile); CloseHandle(hFile);
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return; return;
@ -850,7 +878,7 @@ Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path,
peer = (jlong)hFile; peer = (jlong)hFile;
length = info.EndOfFile.QuadPart; length = info.EndOfFile.QuadPart;
#endif #endif
e->SetLongArrayRegion(result, 0, 1, &peer); e->SetLongArrayRegion(result, 0, 1, &peer);
e->SetLongArrayRegion(result, 1, 1, &length); e->SetLongArrayRegion(result, 1, 1, &length);
@ -858,24 +886,28 @@ Java_java_io_RandomAccessFile_open(JNIEnv* e, jclass, jstring path,
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer, Java_java_io_RandomAccessFile_readBytes(JNIEnv* e,
jlong position, jbyteArray buffer, jclass,
int offset, int length) jlong peer,
jlong position,
jbyteArray buffer,
int offset,
int length)
{ {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int fd = (int)peer; int fd = (int)peer;
if(::lseek(fd, position, SEEK_SET) == -1) { if (::lseek(fd, position, SEEK_SET) == -1) {
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return -1; return -1;
} }
uint8_t* dst = reinterpret_cast<uint8_t*> uint8_t* dst
(e->GetPrimitiveArrayCritical(buffer, 0)); = reinterpret_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, 0));
int64_t bytesRead = ::read(fd, dst + offset, length); int64_t bytesRead = ::read(fd, dst + offset, length);
e->ReleasePrimitiveArrayCritical(buffer, dst, 0); e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
if(bytesRead == -1) { if (bytesRead == -1) {
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return -1; return -1;
} }
@ -883,16 +915,16 @@ Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer,
HANDLE hFile = (HANDLE)peer; HANDLE hFile = (HANDLE)peer;
LARGE_INTEGER lPos; LARGE_INTEGER lPos;
lPos.QuadPart = position; lPos.QuadPart = position;
if(!SetFilePointerEx(hFile, lPos, nullptr, FILE_BEGIN)) { if (!SetFilePointerEx(hFile, lPos, nullptr, FILE_BEGIN)) {
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return -1; return -1;
} }
uint8_t* dst = reinterpret_cast<uint8_t*> uint8_t* dst
(e->GetPrimitiveArrayCritical(buffer, 0)); = reinterpret_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, 0));
DWORD bytesRead = 0; DWORD bytesRead = 0;
if(!ReadFile(hFile, dst + offset, length, &bytesRead, nullptr)) { if (!ReadFile(hFile, dst + offset, length, &bytesRead, nullptr)) {
e->ReleasePrimitiveArrayCritical(buffer, dst, 0); e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return -1; return -1;
@ -904,24 +936,28 @@ Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer,
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_io_RandomAccessFile_writeBytes(JNIEnv* e, jclass, jlong peer, Java_java_io_RandomAccessFile_writeBytes(JNIEnv* e,
jlong position, jbyteArray buffer, jclass,
int offset, int length) jlong peer,
jlong position,
jbyteArray buffer,
int offset,
int length)
{ {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int fd = (int)peer; int fd = (int)peer;
if(::lseek(fd, position, SEEK_SET) == -1) { if (::lseek(fd, position, SEEK_SET) == -1) {
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return -1; return -1;
} }
uint8_t* dst = reinterpret_cast<uint8_t*> uint8_t* dst
(e->GetPrimitiveArrayCritical(buffer, 0)); = reinterpret_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, 0));
int64_t bytesWritten = ::write(fd, dst + offset, length); int64_t bytesWritten = ::write(fd, dst + offset, length);
e->ReleasePrimitiveArrayCritical(buffer, dst, 0); e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
if(bytesWritten == -1) { if (bytesWritten == -1) {
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return -1; return -1;
} }
@ -929,16 +965,16 @@ Java_java_io_RandomAccessFile_writeBytes(JNIEnv* e, jclass, jlong peer,
HANDLE hFile = (HANDLE)peer; HANDLE hFile = (HANDLE)peer;
LARGE_INTEGER lPos; LARGE_INTEGER lPos;
lPos.QuadPart = position; lPos.QuadPart = position;
if(!SetFilePointerEx(hFile, lPos, nullptr, FILE_BEGIN)) { if (!SetFilePointerEx(hFile, lPos, nullptr, FILE_BEGIN)) {
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return -1; return -1;
} }
uint8_t* dst = reinterpret_cast<uint8_t*> uint8_t* dst
(e->GetPrimitiveArrayCritical(buffer, 0)); = reinterpret_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, 0));
DWORD bytesWritten = 0; DWORD bytesWritten = 0;
if(!WriteFile(hFile, dst + offset, length, &bytesWritten, nullptr)) { if (!WriteFile(hFile, dst + offset, length, &bytesWritten, nullptr)) {
e->ReleasePrimitiveArrayCritical(buffer, dst, 0); e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
throwNewErrno(e, "java/io/IOException"); throwNewErrno(e, "java/io/IOException");
return -1; return -1;
@ -950,7 +986,7 @@ Java_java_io_RandomAccessFile_writeBytes(JNIEnv* e, jclass, jlong peer,
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_close(JNIEnv* /* e*/, jclass, jlong peer) Java_java_io_RandomAccessFile_close(JNIEnv* /* e*/, jclass, jlong peer)
{ {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int fd = (int)peer; int fd = (int)peer;

File diff suppressed because it is too large Load Diff

View File

@ -15,48 +15,62 @@
using namespace avian::classpath::sockets; using namespace avian::classpath::sockets;
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_init(JNIEnv* e, jclass)
Java_java_net_Socket_init(JNIEnv* e, jclass) { {
init(e); init(e);
} }
extern "C" JNIEXPORT SOCKET JNICALL extern "C" JNIEXPORT SOCKET JNICALL
Java_java_net_Socket_create(JNIEnv* e, jclass) { Java_java_net_Socket_create(JNIEnv* e, jclass)
{
return create(e); return create(e);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_connect(JNIEnv* e,
Java_java_net_Socket_connect(JNIEnv* e, jclass, SOCKET sock, long addr, short port) { jclass,
SOCKET sock,
long addr,
short port)
{
connect(e, sock, addr, port); connect(e, sock, addr, port);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL Java_java_net_Socket_bind(JNIEnv* e,
Java_java_net_Socket_bind(JNIEnv* e, jclass, SOCKET sock, long addr, short port) { jclass,
SOCKET sock,
long addr,
short port)
{
bind(e, sock, addr, port); bind(e, sock, addr, port);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_net_Socket_abort(JNIEnv* e, jclass, SOCKET sock) { Java_java_net_Socket_abort(JNIEnv* e, jclass, SOCKET sock)
{
abort(e, sock); abort(e, sock);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_net_Socket_close(JNIEnv* e, jclass, SOCKET sock) { Java_java_net_Socket_close(JNIEnv* e, jclass, SOCKET sock)
{
close(e, sock); close(e, sock);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_net_Socket_closeOutput(JNIEnv* e, jclass, SOCKET sock) { Java_java_net_Socket_closeOutput(JNIEnv* e, jclass, SOCKET sock)
{
close_output(e, sock); close_output(e, sock);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_net_Socket_closeInput(JNIEnv* e, jclass, SOCKET sock) { Java_java_net_Socket_closeInput(JNIEnv* e, jclass, SOCKET sock)
{
close_input(e, sock); close_input(e, sock);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Avian_java_net_Socket_send(vm::Thread* t, vm::object, uintptr_t* arguments) { /* SOCKET s, object buffer_obj, int start_pos, int count */ Avian_java_net_Socket_send(vm::Thread* t, vm::object, uintptr_t* arguments)
{ /* SOCKET s, object buffer_obj, int start_pos, int count */
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0])); SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>( vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
t, reinterpret_cast<vm::object>(arguments[2])); t, reinterpret_cast<vm::object>(arguments[2]));
@ -67,7 +81,8 @@ Avian_java_net_Socket_send(vm::Thread* t, vm::object, uintptr_t* arguments) { /
} }
extern "C" JNIEXPORT int64_t JNICALL extern "C" JNIEXPORT int64_t JNICALL
Avian_java_net_Socket_recv(vm::Thread* t, vm::object, uintptr_t* arguments) { /* SOCKET s, object buffer_obj, int start_pos, int count */ Avian_java_net_Socket_recv(vm::Thread* t, vm::object, uintptr_t* arguments)
{ /* SOCKET s, object buffer_obj, int start_pos, int count */
SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0])); SOCKET& s = *(reinterpret_cast<SOCKET*>(&arguments[0]));
vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>( vm::GcByteArray* buffer_obj = vm::cast<vm::GcByteArray>(
t, reinterpret_cast<vm::object>(arguments[2])); t, reinterpret_cast<vm::object>(arguments[2]));
@ -78,7 +93,7 @@ Avian_java_net_Socket_recv(vm::Thread* t, vm::object, uintptr_t* arguments) { /
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_net_InetAddress_ipv4AddressForName(JNIEnv* e, Java_java_net_InetAddress_ipv4AddressForName(JNIEnv* e,
jclass, jclass,
jstring name) jstring name)
{ {
@ -107,8 +122,8 @@ Java_java_net_InetAddress_ipv4AddressForName(JNIEnv* e,
throwNew(e, "java/net/UnknownHostException", 0); throwNew(e, "java/net/UnknownHostException", 0);
return 0; return 0;
} else { } else {
int address = ntohl int address = ntohl(
(reinterpret_cast<sockaddr_in*>(result->ai_addr)->sin_addr.s_addr); reinterpret_cast<sockaddr_in*>(result->ai_addr)->sin_addr.s_addr);
freeaddrinfo(result); freeaddrinfo(result);
return address; return address;
@ -119,4 +134,3 @@ Java_java_net_InetAddress_ipv4AddressForName(JNIEnv* e,
return 0; return 0;
} }
} }

View File

@ -17,25 +17,25 @@
#include "jni-util.h" #include "jni-util.h"
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# include <winsock2.h> #include <winsock2.h>
# include <ws2tcpip.h> #include <ws2tcpip.h>
# include <errno.h> #include <errno.h>
# ifdef _MSC_VER #ifdef _MSC_VER
# define snprintf sprintf_s #define snprintf sprintf_s
# else
# include <unistd.h>
# endif
#else #else
# include <unistd.h> #include <unistd.h>
# include <fcntl.h> #endif
# include <errno.h> #else
# include <netdb.h> #include <unistd.h>
# include <sys/select.h> #include <fcntl.h>
# include <arpa/inet.h> #include <errno.h>
# include <netinet/in.h> #include <netdb.h>
# include <netinet/ip.h> #include <sys/select.h>
# include <netinet/tcp.h> #include <arpa/inet.h>
# include <sys/socket.h> #include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#endif #endif
#define java_nio_channels_SelectionKey_OP_READ 1L #define java_nio_channels_SelectionKey_OP_READ 1L
@ -47,12 +47,14 @@
typedef int socklen_t; typedef int socklen_t;
#endif #endif
inline void* operator new(size_t, void* p) throw() { return p; } inline void* operator new(size_t, void* p) throw()
{
return p;
}
namespace { namespace {
inline jbyteArray inline jbyteArray charsToArray(JNIEnv* e, const char* s)
charsToArray(JNIEnv* e, const char* s)
{ {
unsigned length = strlen(s); unsigned length = strlen(s);
jbyteArray a = e->NewByteArray(length + 1); jbyteArray a = e->NewByteArray(length + 1);
@ -60,8 +62,7 @@ charsToArray(JNIEnv* e, const char* s)
return a; return a;
} }
inline void inline void doClose(int socket)
doClose(int socket)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
closesocket(socket); closesocket(socket);
@ -70,8 +71,7 @@ doClose(int socket)
#endif #endif
} }
inline jbyteArray inline jbyteArray errorString(JNIEnv* e, int n)
errorString(JNIEnv* e, int n)
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
const unsigned size = 128; const unsigned size = 128;
@ -83,8 +83,7 @@ errorString(JNIEnv* e, int n)
#endif #endif
} }
inline jbyteArray inline jbyteArray socketErrorString(JNIEnv* e, int n)
socketErrorString(JNIEnv* e, int n)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
const unsigned size = 64; const unsigned size = 64;
@ -96,8 +95,7 @@ socketErrorString(JNIEnv* e, int n)
#endif #endif
} }
inline jbyteArray inline jbyteArray errorString(JNIEnv* e)
errorString(JNIEnv* e)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
const unsigned size = 64; const unsigned size = 64;
@ -109,8 +107,7 @@ errorString(JNIEnv* e)
#endif #endif
} }
void void throwIOException(JNIEnv* e, const char* s)
throwIOException(JNIEnv* e, const char* s)
{ {
throwNew(e, "java/io/IOException", s); throwNew(e, "java/io/IOException", s);
} }
@ -128,20 +125,17 @@ void throwIOException(JNIEnv* e, jbyteArray a)
} }
} }
void void throwIOException(JNIEnv* e)
throwIOException(JNIEnv* e)
{ {
throwIOException(e, errorString(e)); throwIOException(e, errorString(e));
} }
void void throwSocketException(JNIEnv* e, const char* s)
throwSocketException(JNIEnv* e, const char* s)
{ {
throwNew(e, "java/net/SocketException", s); throwNew(e, "java/net/SocketException", s);
} }
void void throwSocketException(JNIEnv* e, jbyteArray a)
throwSocketException(JNIEnv* e, jbyteArray a)
{ {
size_t length = e->GetArrayLength(a); size_t length = e->GetArrayLength(a);
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length)); uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
@ -154,8 +148,7 @@ throwSocketException(JNIEnv* e, jbyteArray a)
} }
} }
void void throwSocketException(JNIEnv* e)
throwSocketException(JNIEnv* e)
{ {
throwSocketException(e, errorString(e)); throwSocketException(e, errorString(e));
} }
@ -168,19 +161,16 @@ void init(sockaddr_in* address, jint host, jint port)
address->sin_addr.s_addr = htonl(host); address->sin_addr.s_addr = htonl(host);
} }
inline bool inline bool einProgress(int error)
einProgress(int error)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
return error == WSAEINPROGRESS return error == WSAEINPROGRESS or error == WSAEWOULDBLOCK;
or error == WSAEWOULDBLOCK;
#else #else
return error == EINPROGRESS; return error == EINPROGRESS;
#endif #endif
} }
inline bool inline bool einProgress()
einProgress()
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
return WSAGetLastError() == WSAEINPROGRESS return WSAGetLastError() == WSAEINPROGRESS
@ -190,8 +180,7 @@ einProgress()
#endif #endif
} }
inline bool inline bool eagain()
eagain()
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
return WSAGetLastError() == WSAEINPROGRESS return WSAGetLastError() == WSAEINPROGRESS
@ -201,8 +190,7 @@ eagain()
#endif #endif
} }
bool bool setBlocking(JNIEnv* e, int d, bool blocking)
setBlocking(JNIEnv* e, int d, bool blocking)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
u_long a = (blocking ? 0 : 1); u_long a = (blocking ? 0 : 1);
@ -212,8 +200,9 @@ setBlocking(JNIEnv* e, int d, bool blocking)
return false; return false;
} }
#else #else
int r = fcntl(d, F_SETFL, (blocking int r = fcntl(d,
? (fcntl(d, F_GETFL) & (~O_NONBLOCK)) F_SETFL,
(blocking ? (fcntl(d, F_GETFL) & (~O_NONBLOCK))
: (fcntl(d, F_GETFL) | O_NONBLOCK))); : (fcntl(d, F_GETFL) | O_NONBLOCK)));
if (r < 0) { if (r < 0) {
throwIOException(e); throwIOException(e);
@ -223,12 +212,11 @@ setBlocking(JNIEnv* e, int d, bool blocking)
return true; return true;
} }
bool bool setTcpNoDelay(JNIEnv* e, int d, bool on)
setTcpNoDelay(JNIEnv* e, int d, bool on)
{ {
int flag = on; int flag = on;
int r = setsockopt int r = setsockopt(
(d, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&flag), sizeof(int)); d, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&flag), sizeof(int));
if (r < 0) { if (r < 0) {
throwSocketException(e); throwSocketException(e);
return false; return false;
@ -236,12 +224,15 @@ setTcpNoDelay(JNIEnv* e, int d, bool on)
return true; return true;
} }
void void doBind(JNIEnv* e, int s, sockaddr_in* address)
doBind(JNIEnv* e, int s, sockaddr_in* address)
{ {
{ int opt = 1; {
int r = ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, int opt = 1;
reinterpret_cast<char*>(&opt), sizeof(int)); int r = ::setsockopt(s,
SOL_SOCKET,
SO_REUSEADDR,
reinterpret_cast<char*>(&opt),
sizeof(int));
if (r != 0) { if (r != 0) {
throwIOException(e); throwIOException(e);
return; return;
@ -249,9 +240,13 @@ doBind(JNIEnv* e, int s, sockaddr_in* address)
} }
#ifdef SO_NOSIGPIPE #ifdef SO_NOSIGPIPE
{ int opt = 1; {
int r = ::setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, int opt = 1;
reinterpret_cast<char*>(&opt), sizeof(int)); int r = ::setsockopt(s,
SOL_SOCKET,
SO_NOSIGPIPE,
reinterpret_cast<char*>(&opt),
sizeof(int));
if (r != 0) { if (r != 0) {
throwIOException(e); throwIOException(e);
return; return;
@ -259,8 +254,9 @@ doBind(JNIEnv* e, int s, sockaddr_in* address)
} }
#endif #endif
{ int r = ::bind {
(s, reinterpret_cast<sockaddr*>(address), sizeof(sockaddr_in)); int r
= ::bind(s, reinterpret_cast<sockaddr*>(address), sizeof(sockaddr_in));
if (r != 0) { if (r != 0) {
throwIOException(e); throwIOException(e);
return; return;
@ -268,8 +264,7 @@ doBind(JNIEnv* e, int s, sockaddr_in* address)
} }
} }
void void doListen(JNIEnv* e, int s)
doListen(JNIEnv* e, int s)
{ {
int r = ::listen(s, 100); int r = ::listen(s, 100);
if (r != 0) { if (r != 0) {
@ -277,13 +272,12 @@ doListen(JNIEnv* e, int s)
} }
} }
void void doFinishConnect(JNIEnv* e, int socket)
doFinishConnect(JNIEnv* e, int socket)
{ {
int error; int error;
socklen_t size = sizeof(int); socklen_t size = sizeof(int);
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR, int r = getsockopt(
reinterpret_cast<char*>(&error), &size); socket, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&error), &size);
if (r != 0 or size != sizeof(int)) { if (r != 0 or size != sizeof(int)) {
throwIOException(e); throwIOException(e);
@ -292,11 +286,10 @@ doFinishConnect(JNIEnv* e, int socket)
} }
} }
bool bool doConnect(JNIEnv* e, int s, sockaddr_in* address)
doConnect(JNIEnv* e, int s, sockaddr_in* address)
{ {
int r = ::connect(s, reinterpret_cast<sockaddr*>(address), int r
sizeof(sockaddr_in)); = ::connect(s, reinterpret_cast<sockaddr*>(address), sizeof(sockaddr_in));
if (r == 0) { if (r == 0) {
return true; return true;
} else if (not einProgress()) { } else if (not einProgress()) {
@ -307,8 +300,7 @@ doConnect(JNIEnv* e, int s, sockaddr_in* address)
} }
} }
int int doAccept(JNIEnv* e, int s)
doAccept(JNIEnv* e, int s)
{ {
sockaddr address; sockaddr address;
socklen_t length = sizeof(address); socklen_t length = sizeof(address);
@ -321,8 +313,7 @@ doAccept(JNIEnv* e, int s)
return -1; return -1;
} }
int int doRead(int fd, void* buffer, size_t count)
doRead(int fd, void* buffer, size_t count)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
return recv(fd, static_cast<char*>(buffer), count, 0); return recv(fd, static_cast<char*>(buffer), count, 0);
@ -331,16 +322,15 @@ doRead(int fd, void* buffer, size_t count)
#endif #endif
} }
int int doRecv(int fd, void* buffer, size_t count, int32_t* host, int32_t* port)
doRecv(int fd, void* buffer, size_t count, int32_t* host, int32_t* port)
{ {
sockaddr address; sockaddr address;
socklen_t length = sizeof(address); socklen_t length = sizeof(address);
int r = recvfrom int r = recvfrom(fd, static_cast<char*>(buffer), count, 0, &address, &length);
(fd, static_cast<char*>(buffer), count, 0, &address, &length);
if (r > 0) { if (r > 0) {
sockaddr_in a; memcpy(&a, &address, length); sockaddr_in a;
memcpy(&a, &address, length);
*host = ntohl(a.sin_addr.s_addr); *host = ntohl(a.sin_addr.s_addr);
*port = ntohs(a.sin_port); *port = ntohs(a.sin_port);
} else { } else {
@ -351,8 +341,7 @@ doRecv(int fd, void* buffer, size_t count, int32_t* host, int32_t* port)
return r; return r;
} }
int int doWrite(int fd, const void* buffer, size_t count)
doWrite(int fd, const void* buffer, size_t count)
{ {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
return send(fd, static_cast<const char*>(buffer), count, 0); return send(fd, static_cast<const char*>(buffer), count, 0);
@ -384,9 +373,10 @@ int makeSocket(JNIEnv* e, int type = SOCK_STREAM, int protocol = IPPROTO_TCP)
} // namespace <anonymous> } // namespace <anonymous>
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_ServerSocketChannel_natDoAccept(JNIEnv *e, jclass, jint socket) Java_java_nio_channels_ServerSocketChannel_natDoAccept(JNIEnv* e,
jclass,
jint socket)
{ {
return ::doAccept(e, socket); return ::doAccept(e, socket);
} }
@ -432,7 +422,7 @@ extern "C" JNIEXPORT void JNICALL
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_configureBlocking(JNIEnv *e, Java_java_nio_channels_SocketChannel_configureBlocking(JNIEnv* e,
jclass, jclass,
jint socket, jint socket,
jboolean blocking) jboolean blocking)
@ -441,17 +431,17 @@ Java_java_nio_channels_SocketChannel_configureBlocking(JNIEnv *e,
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_DatagramChannel_configureBlocking(JNIEnv* e, Java_java_nio_channels_DatagramChannel_configureBlocking(JNIEnv* e,
jclass c, jclass c,
jint socket, jint socket,
jboolean blocking) jboolean blocking)
{ {
return Java_java_nio_channels_SocketChannel_configureBlocking return Java_java_nio_channels_SocketChannel_configureBlocking(
(e, c, socket, blocking); e, c, socket, blocking);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natSetTcpNoDelay(JNIEnv *e, Java_java_nio_channels_SocketChannel_natSetTcpNoDelay(JNIEnv* e,
jclass, jclass,
jint socket, jint socket,
jboolean on) jboolean on)
@ -498,7 +488,7 @@ extern "C" JNIEXPORT jboolean JNICALL
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e, Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv* e,
jclass, jclass,
jint socket) jint socket)
{ {
@ -506,7 +496,7 @@ Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e,
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e, Java_java_nio_channels_SocketChannel_natRead(JNIEnv* e,
jclass, jclass,
jint socket, jint socket,
jbyteArray buffer, jbyteArray buffer,
@ -520,8 +510,7 @@ Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e,
if (buf) { if (buf) {
r = ::doRead(socket, buf, length); r = ::doRead(socket, buf, length);
if (r > 0) { if (r > 0) {
e->SetByteArrayRegion e->SetByteArrayRegion(buffer, offset, r, reinterpret_cast<jbyte*>(buf));
(buffer, offset, r, reinterpret_cast<jbyte*>(buf));
} }
free(buf); free(buf);
} else { } else {
@ -529,8 +518,8 @@ Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e,
} }
} else { } else {
jboolean isCopy; jboolean isCopy;
uint8_t* buf = static_cast<uint8_t*> uint8_t* buf
(e->GetPrimitiveArrayCritical(buffer, &isCopy)); = static_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
r = ::doRead(socket, buf + offset, length); r = ::doRead(socket, buf + offset, length);
@ -550,7 +539,7 @@ Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e,
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_DatagramChannel_receive(JNIEnv* e, Java_java_nio_channels_DatagramChannel_receive(JNIEnv* e,
jclass, jclass,
jint socket, jint socket,
jbyteArray buffer, jbyteArray buffer,
@ -567,8 +556,7 @@ Java_java_nio_channels_DatagramChannel_receive(JNIEnv* e,
if (buf) { if (buf) {
r = ::doRecv(socket, buf, length, &host, &port); r = ::doRecv(socket, buf, length, &host, &port);
if (r > 0) { if (r > 0) {
e->SetByteArrayRegion e->SetByteArrayRegion(buffer, offset, r, reinterpret_cast<jbyte*>(buf));
(buffer, offset, r, reinterpret_cast<jbyte*>(buf));
} }
free(buf); free(buf);
} else { } else {
@ -576,8 +564,8 @@ Java_java_nio_channels_DatagramChannel_receive(JNIEnv* e,
} }
} else { } else {
jboolean isCopy; jboolean isCopy;
uint8_t* buf = static_cast<uint8_t*> uint8_t* buf
(e->GetPrimitiveArrayCritical(buffer, &isCopy)); = static_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
r = ::doRecv(socket, buf + offset, length, &host, &port); r = ::doRecv(socket, buf + offset, length, &host, &port);
@ -593,15 +581,17 @@ Java_java_nio_channels_DatagramChannel_receive(JNIEnv* e,
} else if (r == 0) { } else if (r == 0) {
return -1; return -1;
} else { } else {
jint jhost = host; e->SetIntArrayRegion(address, 0, 1, &jhost); jint jhost = host;
jint jport = port; e->SetIntArrayRegion(address, 1, 1, &jport); e->SetIntArrayRegion(address, 0, 1, &jhost);
jint jport = port;
e->SetIntArrayRegion(address, 1, 1, &jport);
} }
return r; return r;
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketChannel_natWrite(JNIEnv *e, Java_java_nio_channels_SocketChannel_natWrite(JNIEnv* e,
jclass, jclass,
jint socket, jint socket,
jbyteArray buffer, jbyteArray buffer,
@ -613,8 +603,8 @@ Java_java_nio_channels_SocketChannel_natWrite(JNIEnv *e,
if (blocking) { if (blocking) {
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length)); uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
if (buf) { if (buf) {
e->GetByteArrayRegion e->GetByteArrayRegion(
(buffer, offset, length, reinterpret_cast<jbyte*>(buf)); buffer, offset, length, reinterpret_cast<jbyte*>(buf));
r = ::doWrite(socket, buf, length); r = ::doWrite(socket, buf, length);
free(buf); free(buf);
} else { } else {
@ -622,8 +612,8 @@ Java_java_nio_channels_SocketChannel_natWrite(JNIEnv *e,
} }
} else { } else {
jboolean isCopy; jboolean isCopy;
uint8_t* buf = static_cast<uint8_t*> uint8_t* buf
(e->GetPrimitiveArrayCritical(buffer, &isCopy)); = static_cast<uint8_t*>(e->GetPrimitiveArrayCritical(buffer, &isCopy));
r = ::doWrite(socket, buf + offset, length); r = ::doWrite(socket, buf + offset, length);
@ -641,7 +631,7 @@ Java_java_nio_channels_SocketChannel_natWrite(JNIEnv *e,
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_DatagramChannel_write(JNIEnv* e, Java_java_nio_channels_DatagramChannel_write(JNIEnv* e,
jclass c, jclass c,
jint socket, jint socket,
jbyteArray buffer, jbyteArray buffer,
@ -649,8 +639,8 @@ Java_java_nio_channels_DatagramChannel_write(JNIEnv* e,
jint length, jint length,
jboolean blocking) jboolean blocking)
{ {
return Java_java_nio_channels_SocketChannel_natWrite return Java_java_nio_channels_SocketChannel_natWrite(
(e, c, socket, buffer, offset, length, blocking); e, c, socket, buffer, offset, length, blocking);
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
@ -699,14 +689,14 @@ extern "C" JNIEXPORT jint JNICALL
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natThrowWriteError(JNIEnv *e, Java_java_nio_channels_SocketChannel_natThrowWriteError(JNIEnv* e,
jclass, jclass,
jint socket) jint socket)
{ {
int error; int error;
socklen_t size = sizeof(int); socklen_t size = sizeof(int);
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR, int r = getsockopt(
reinterpret_cast<char*>(&error), &size); socket, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&error), &size);
if (r != 0 or size != sizeof(int)) { if (r != 0 or size != sizeof(int)) {
throwIOException(e); throwIOException(e);
} else if (error != 0) { } else if (error != 0) {
@ -715,7 +705,7 @@ Java_java_nio_channels_SocketChannel_natThrowWriteError(JNIEnv *e,
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natCloseSocket(JNIEnv *, Java_java_nio_channels_SocketChannel_natCloseSocket(JNIEnv*,
jclass, jclass,
jint socket) jint socket)
{ {
@ -723,9 +713,7 @@ Java_java_nio_channels_SocketChannel_natCloseSocket(JNIEnv *,
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_DatagramChannel_close(JNIEnv *, Java_java_nio_channels_DatagramChannel_close(JNIEnv*, jclass, jint socket)
jclass,
jint socket)
{ {
doClose(socket); doClose(socket);
} }
@ -739,69 +727,85 @@ class Pipe {
// pipe descriptors or others. Thus, to implement // pipe descriptors or others. Thus, to implement
// Selector.wakeup(), we make a socket connection via the loopback // Selector.wakeup(), we make a socket connection via the loopback
// interface and use it as a pipe. // interface and use it as a pipe.
Pipe(JNIEnv* e): connected_(false), listener_(-1), reader_(-1), writer_(-1) { Pipe(JNIEnv* e) : connected_(false), listener_(-1), reader_(-1), writer_(-1)
{
sockaddr_in address; sockaddr_in address;
address.sin_family = AF_INET; address.sin_family = AF_INET;
address.sin_port = 0; address.sin_port = 0;
address.sin_addr.s_addr = inet_addr("127.0.0.1"); //INADDR_LOOPBACK; address.sin_addr.s_addr = inet_addr("127.0.0.1"); // INADDR_LOOPBACK;
listener_ = makeSocket(e); listener_ = makeSocket(e);
if (e->ExceptionCheck()) return; if (e->ExceptionCheck())
return;
setBlocking(e, listener_, false); setBlocking(e, listener_, false);
::doBind(e, listener_, &address); ::doBind(e, listener_, &address);
if (e->ExceptionCheck()) return; if (e->ExceptionCheck())
return;
::doListen(e, listener_); ::doListen(e, listener_);
if (e->ExceptionCheck()) return; if (e->ExceptionCheck())
return;
socklen_t length = sizeof(sockaddr_in); socklen_t length = sizeof(sockaddr_in);
int r = getsockname(listener_, reinterpret_cast<sockaddr*>(&address), int r = getsockname(
&length); listener_, reinterpret_cast<sockaddr*>(&address), &length);
if (r) { if (r) {
throwIOException(e); throwIOException(e);
return; return;
} }
writer_ = makeSocket(e); writer_ = makeSocket(e);
if (e->ExceptionCheck()) return; if (e->ExceptionCheck())
return;
setBlocking(e, writer_, true); setBlocking(e, writer_, true);
connected_ = ::doConnect(e, writer_, &address); connected_ = ::doConnect(e, writer_, &address);
} }
void dispose() { void dispose()
if (listener_ >= 0) ::doClose(listener_); {
if (reader_ >= 0) ::doClose(reader_); if (listener_ >= 0)
if (writer_ >= 0) ::doClose(writer_); ::doClose(listener_);
if (reader_ >= 0)
::doClose(reader_);
if (writer_ >= 0)
::doClose(writer_);
} }
bool connected() { bool connected()
{
return connected_; return connected_;
} }
void setConnected(bool v) { void setConnected(bool v)
{
connected_ = v; connected_ = v;
} }
int listener() { int listener()
{
return listener_; return listener_;
} }
void setListener(int v) { void setListener(int v)
{
listener_ = v; listener_ = v;
} }
int reader() { int reader()
{
return reader_; return reader_;
} }
void setReader(int v) { void setReader(int v)
{
reader_ = v; reader_ = v;
} }
int writer() { int writer()
{
return writer_; return writer_;
} }
@ -811,7 +815,8 @@ class Pipe {
int reader_; int reader_;
int writer_; int writer_;
#else #else
Pipe(JNIEnv* e) { Pipe(JNIEnv* e)
{
if (::pipe(pipe) != 0) { if (::pipe(pipe) != 0) {
throwIOException(e); throwIOException(e);
return; return;
@ -824,21 +829,25 @@ class Pipe {
open_ = true; open_ = true;
} }
void dispose() { void dispose()
{
::doClose(pipe[0]); ::doClose(pipe[0]);
::doClose(pipe[1]); ::doClose(pipe[1]);
open_ = false; open_ = false;
} }
bool connected() { bool connected()
{
return open_; return open_;
} }
int reader() { int reader()
{
return pipe[0]; return pipe[0];
} }
int writer() { int writer()
{
return pipe[1]; return pipe[1];
} }
@ -853,18 +862,21 @@ struct SelectorState {
fd_set write; fd_set write;
fd_set except; fd_set except;
Pipe control; Pipe control;
SelectorState(JNIEnv* e) : control(e) { } SelectorState(JNIEnv* e) : control(e)
{
}
}; };
} // namespace } // namespace
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_nio_channels_SocketSelector_natInit(JNIEnv* e, jclass) Java_java_nio_channels_SocketSelector_natInit(JNIEnv* e, jclass)
{ {
void *mem = malloc(sizeof(SelectorState)); void* mem = malloc(sizeof(SelectorState));
if (mem) { if (mem) {
SelectorState *s = new (mem) SelectorState(e); SelectorState* s = new (mem) SelectorState(e);
if (e->ExceptionCheck()) return 0; if (e->ExceptionCheck())
return 0;
if (s) { if (s) {
FD_ZERO(&(s->read)); FD_ZERO(&(s->read));
@ -878,7 +890,9 @@ Java_java_nio_channels_SocketSelector_natInit(JNIEnv* e, jclass)
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketSelector_natWakeup(JNIEnv *e, jclass, jlong state) Java_java_nio_channels_SocketSelector_natWakeup(JNIEnv* e,
jclass,
jlong state)
{ {
SelectorState* s = reinterpret_cast<SelectorState*>(state); SelectorState* s = reinterpret_cast<SelectorState*>(state);
if (s->control.connected()) { if (s->control.connected()) {
@ -891,7 +905,7 @@ Java_java_nio_channels_SocketSelector_natWakeup(JNIEnv *e, jclass, jlong state)
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketSelector_natClose(JNIEnv *, jclass, jlong state) Java_java_nio_channels_SocketSelector_natClose(JNIEnv*, jclass, jlong state)
{ {
SelectorState* s = reinterpret_cast<SelectorState*>(state); SelectorState* s = reinterpret_cast<SelectorState*>(state);
s->control.dispose(); s->control.dispose();
@ -899,7 +913,8 @@ Java_java_nio_channels_SocketSelector_natClose(JNIEnv *, jclass, jlong state)
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketSelector_natSelectClearAll(JNIEnv *, jclass, Java_java_nio_channels_SocketSelector_natSelectClearAll(JNIEnv*,
jclass,
jint socket, jint socket,
jlong state) jlong state)
{ {
@ -910,7 +925,8 @@ Java_java_nio_channels_SocketSelector_natSelectClearAll(JNIEnv *, jclass,
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketSelector_natSelectUpdateInterestSet(JNIEnv *, Java_java_nio_channels_SocketSelector_natSelectUpdateInterestSet(
JNIEnv*,
jclass, jclass,
jint socket, jint socket,
jint interest, jint interest,
@ -918,19 +934,21 @@ Java_java_nio_channels_SocketSelector_natSelectUpdateInterestSet(JNIEnv *,
jint max) jint max)
{ {
SelectorState* s = reinterpret_cast<SelectorState*>(state); SelectorState* s = reinterpret_cast<SelectorState*>(state);
if (interest & (java_nio_channels_SelectionKey_OP_READ | if (interest & (java_nio_channels_SelectionKey_OP_READ
java_nio_channels_SelectionKey_OP_ACCEPT)) { | java_nio_channels_SelectionKey_OP_ACCEPT)) {
FD_SET(static_cast<unsigned>(socket), &(s->read)); FD_SET(static_cast<unsigned>(socket), &(s->read));
if (max < socket) max = socket; if (max < socket)
max = socket;
} else { } else {
FD_CLR(static_cast<unsigned>(socket), &(s->read)); FD_CLR(static_cast<unsigned>(socket), &(s->read));
} }
if (interest & (java_nio_channels_SelectionKey_OP_WRITE | if (interest & (java_nio_channels_SelectionKey_OP_WRITE
java_nio_channels_SelectionKey_OP_CONNECT)) { | java_nio_channels_SelectionKey_OP_CONNECT)) {
FD_SET(static_cast<unsigned>(socket), &(s->write)); FD_SET(static_cast<unsigned>(socket), &(s->write));
FD_SET(static_cast<unsigned>(socket), &(s->except)); FD_SET(static_cast<unsigned>(socket), &(s->except));
if (max < socket) max = socket; if (max < socket)
max = socket;
} else { } else {
FD_CLR(static_cast<unsigned>(socket), &(s->write)); FD_CLR(static_cast<unsigned>(socket), &(s->write));
} }
@ -938,7 +956,8 @@ Java_java_nio_channels_SocketSelector_natSelectUpdateInterestSet(JNIEnv *,
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass, Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv* e,
jclass,
jlong state, jlong state,
jint max, jint max,
jlong interval) jlong interval)
@ -947,21 +966,24 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
if (s->control.reader() >= 0) { if (s->control.reader() >= 0) {
int socket = s->control.reader(); int socket = s->control.reader();
FD_SET(static_cast<unsigned>(socket), &(s->read)); FD_SET(static_cast<unsigned>(socket), &(s->read));
if (max < socket) max = socket; if (max < socket)
max = socket;
} }
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
if (s->control.listener() >= 0) { if (s->control.listener() >= 0) {
int socket = s->control.listener(); int socket = s->control.listener();
FD_SET(static_cast<unsigned>(socket), &(s->read)); FD_SET(static_cast<unsigned>(socket), &(s->read));
if (max < socket) max = socket; if (max < socket)
max = socket;
} }
if (not s->control.connected()) { if (not s->control.connected()) {
int socket = s->control.writer(); int socket = s->control.writer();
FD_SET(static_cast<unsigned>(socket), &(s->write)); FD_SET(static_cast<unsigned>(socket), &(s->write));
FD_SET(static_cast<unsigned>(socket), &(s->except)); FD_SET(static_cast<unsigned>(socket), &(s->except));
if (max < socket) max = socket; if (max < socket)
max = socket;
} }
#endif #endif
@ -986,17 +1008,16 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
} }
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
if (FD_ISSET(s->control.writer(), &(s->write)) or if (FD_ISSET(s->control.writer(), &(s->write))
FD_ISSET(s->control.writer(), &(s->except))) or FD_ISSET(s->control.writer(), &(s->except))) {
{
int socket = s->control.writer(); int socket = s->control.writer();
FD_CLR(static_cast<unsigned>(socket), &(s->write)); FD_CLR(static_cast<unsigned>(socket), &(s->write));
FD_CLR(static_cast<unsigned>(socket), &(s->except)); FD_CLR(static_cast<unsigned>(socket), &(s->except));
int error; int error;
socklen_t size = sizeof(int); socklen_t size = sizeof(int);
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR, int r = getsockopt(
reinterpret_cast<char*>(&error), &size); socket, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&error), &size);
if (r != 0 or size != sizeof(int)) { if (r != 0 or size != sizeof(int)) {
throwIOException(e); throwIOException(e);
} else if (error != 0) { } else if (error != 0) {
@ -1005,9 +1026,8 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
s->control.setConnected(true); s->control.setConnected(true);
} }
if (s->control.listener() >= 0 and if (s->control.listener() >= 0
FD_ISSET(s->control.listener(), &(s->read))) and FD_ISSET(s->control.listener(), &(s->read))) {
{
FD_CLR(static_cast<unsigned>(s->control.listener()), &(s->read)); FD_CLR(static_cast<unsigned>(s->control.listener()), &(s->read));
s->control.setReader(::doAccept(e, s->control.listener())); s->control.setReader(::doAccept(e, s->control.listener()));
@ -1015,9 +1035,7 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
} }
#endif #endif
if (s->control.reader() >= 0 and if (s->control.reader() >= 0 and FD_ISSET(s->control.reader(), &(s->read))) {
FD_ISSET(s->control.reader(), &(s->read)))
{
FD_CLR(static_cast<unsigned>(s->control.reader()), &(s->read)); FD_CLR(static_cast<unsigned>(s->control.reader()), &(s->read));
char c; char c;
@ -1034,7 +1052,8 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketSelector_natUpdateReadySet(JNIEnv *, jclass, Java_java_nio_channels_SocketSelector_natUpdateReadySet(JNIEnv*,
jclass,
jint socket, jint socket,
jint interest, jint interest,
jlong state) jlong state)
@ -1065,9 +1084,8 @@ Java_java_nio_channels_SocketSelector_natUpdateReadySet(JNIEnv *, jclass,
return ready; return ready;
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_java_nio_ByteOrder_isNativeBigEndian(JNIEnv *, jclass) Java_java_nio_ByteOrder_isNativeBigEndian(JNIEnv*, jclass)
{ {
union { union {
uint32_t i; uint32_t i;

View File

@ -16,8 +16,7 @@
#include "jni-util.h" #include "jni-util.h"
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_util_zip_Inflater_make Java_java_util_zip_Inflater_make(JNIEnv* e, jclass, jboolean nowrap)
(JNIEnv* e, jclass, jboolean nowrap)
{ {
z_stream* s = static_cast<z_stream*>(malloc(sizeof(z_stream))); z_stream* s = static_cast<z_stream*>(malloc(sizeof(z_stream)));
if (s == 0) { if (s == 0) {
@ -38,7 +37,7 @@ Java_java_util_zip_Inflater_make
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_util_zip_Inflater_dispose(JNIEnv*, jclass, jlong peer) Java_java_util_zip_Inflater_dispose(JNIEnv*, jclass, jlong peer)
{ {
z_stream* s = reinterpret_cast<z_stream*>(peer); z_stream* s = reinterpret_cast<z_stream*>(peer);
inflateEnd(s); inflateEnd(s);
@ -46,10 +45,15 @@ Java_java_util_zip_Inflater_dispose(JNIEnv*, jclass, jlong peer)
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_util_zip_Inflater_inflate Java_java_util_zip_Inflater_inflate(JNIEnv* e,
(JNIEnv* e, jclass, jlong peer, jclass,
jbyteArray input, jint inputOffset, jint inputLength, jlong peer,
jbyteArray output, jint outputOffset, jint outputLength, jbyteArray input,
jint inputOffset,
jint inputLength,
jbyteArray output,
jint outputOffset,
jint outputLength,
jintArray results) jintArray results)
{ {
z_stream* s = reinterpret_cast<z_stream*>(peer); z_stream* s = reinterpret_cast<z_stream*>(peer);
@ -75,10 +79,9 @@ Java_java_util_zip_Inflater_inflate
s->avail_out = outputLength; s->avail_out = outputLength;
int r = inflate(s, Z_SYNC_FLUSH); int r = inflate(s, Z_SYNC_FLUSH);
jint resultArray[3] jint resultArray[3] = {r,
= { r,
static_cast<jint>(inputLength - s->avail_in), static_cast<jint>(inputLength - s->avail_in),
static_cast<jint>(outputLength - s->avail_out) }; static_cast<jint>(outputLength - s->avail_out)};
free(in); free(in);
@ -89,8 +92,10 @@ Java_java_util_zip_Inflater_inflate
} }
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL
Java_java_util_zip_Deflater_make Java_java_util_zip_Deflater_make(JNIEnv* e,
(JNIEnv* e, jclass, jboolean nowrap, jint level) jclass,
jboolean nowrap,
jint level)
{ {
z_stream* s = static_cast<z_stream*>(malloc(sizeof(z_stream))); z_stream* s = static_cast<z_stream*>(malloc(sizeof(z_stream)));
if (s == 0) { if (s == 0) {
@ -111,7 +116,7 @@ Java_java_util_zip_Deflater_make
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_util_zip_Deflater_dispose(JNIEnv*, jclass, jlong peer) Java_java_util_zip_Deflater_dispose(JNIEnv*, jclass, jlong peer)
{ {
z_stream* s = reinterpret_cast<z_stream*>(peer); z_stream* s = reinterpret_cast<z_stream*>(peer);
deflateEnd(s); deflateEnd(s);
@ -119,11 +124,17 @@ Java_java_util_zip_Deflater_dispose(JNIEnv*, jclass, jlong peer)
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_util_zip_Deflater_deflate Java_java_util_zip_Deflater_deflate(JNIEnv* e,
(JNIEnv* e, jclass, jlong peer, jclass,
jbyteArray input, jint inputOffset, jint inputLength, jlong peer,
jbyteArray output, jint outputOffset, jint outputLength, jbyteArray input,
jboolean finish, jintArray results) jint inputOffset,
jint inputLength,
jbyteArray output,
jint outputOffset,
jint outputLength,
jboolean finish,
jintArray results)
{ {
z_stream* s = reinterpret_cast<z_stream*>(peer); z_stream* s = reinterpret_cast<z_stream*>(peer);
@ -148,10 +159,9 @@ Java_java_util_zip_Deflater_deflate
s->avail_out = outputLength; s->avail_out = outputLength;
int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH); int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH);
jint resultArray[3] jint resultArray[3] = {r,
= { r,
static_cast<jint>(inputLength - s->avail_in), static_cast<jint>(inputLength - s->avail_in),
static_cast<jint>(outputLength - s->avail_out) }; static_cast<jint>(outputLength - s->avail_out)};
free(in); free(in);

View File

@ -16,8 +16,7 @@ namespace {
#if (!defined PLATFORM_WINDOWS) || (defined _MSC_VER) #if (!defined PLATFORM_WINDOWS) || (defined _MSC_VER)
void void removeNewline(char* s)
removeNewline(char* s)
{ {
for (; s; ++s) { for (; s; ++s) {
if (*s == '\n') { if (*s == '\n') {
@ -32,7 +31,7 @@ removeNewline(char* s)
} // namespace } // namespace
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jstring JNICALL
Java_java_util_Date_toString(JNIEnv* e, jclass c UNUSED, jlong when) Java_java_util_Date_toString(JNIEnv* e, jclass c UNUSED, jlong when)
{ {
const unsigned BufferSize UNUSED = 27; const unsigned BufferSize UNUSED = 27;
@ -40,13 +39,13 @@ Java_java_util_Date_toString(JNIEnv* e, jclass c UNUSED, jlong when)
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
e->MonitorEnter(c); e->MonitorEnter(c);
# ifdef _MSC_VER #ifdef _MSC_VER
char buffer[BufferSize]; char buffer[BufferSize];
ctime_s(buffer, BufferSize, &time); ctime_s(buffer, BufferSize, &time);
removeNewline(buffer); removeNewline(buffer);
# else #else
char* buffer = ctime(&time); char* buffer = ctime(&time);
# endif #endif
jstring r = e->NewStringUTF(buffer); jstring r = e->NewStringUTF(buffer);
e->MonitorExit(c); e->MonitorExit(c);
return r; return r;

View File

@ -20,19 +20,18 @@
#undef JNIEXPORT #undef JNIEXPORT
#if (defined __MINGW32__) || (defined _MSC_VER) #if (defined __MINGW32__) || (defined _MSC_VER)
# define PLATFORM_WINDOWS #define PLATFORM_WINDOWS
# define PATH_SEPARATOR ';' #define PATH_SEPARATOR ';'
# define JNIEXPORT __declspec(dllexport) #define JNIEXPORT __declspec(dllexport)
#else // not (defined __MINGW32__) || (defined _MSC_VER) #else // not (defined __MINGW32__) || (defined _MSC_VER)
# define PLATFORM_POSIX #define PLATFORM_POSIX
# define PATH_SEPARATOR ':' #define PATH_SEPARATOR ':'
# define JNIEXPORT __attribute__ ((visibility("default"))) \ #define JNIEXPORT __attribute__((visibility("default"))) __attribute__((used))
__attribute__ ((used))
#endif // not (defined __MINGW32__) || (defined _MSC_VER) #endif // not (defined __MINGW32__) || (defined _MSC_VER)
#ifdef _MSC_VER #ifdef _MSC_VER
# define UNUSED #define UNUSED
typedef char int8_t; typedef char int8_t;
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
@ -43,38 +42,37 @@ typedef unsigned int uint32_t;
typedef __int64 int64_t; typedef __int64 int64_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
# define INT32_MAX 2147483647 #define INT32_MAX 2147483647
# define not ! #define not!
# define or || #define or ||
# define and && #define and &&
# define xor ^ #define xor ^
# ifdef _M_IX86 #ifdef _M_IX86
# define ARCH_x86_32 #define ARCH_x86_32
# elif defined _M_X64 #elif defined _M_X64
# define ARCH_x86_64 #define ARCH_x86_64
# endif #endif
#else // not _MSC_VER #else // not _MSC_VER
# define UNUSED __attribute__((unused)) #define UNUSED __attribute__((unused))
# include "stdint.h" #include "stdint.h"
# include "errno.h" #include "errno.h"
# ifdef __i386__ #ifdef __i386__
# define ARCH_x86_32 #define ARCH_x86_32
# elif defined __x86_64__ #elif defined __x86_64__
# define ARCH_x86_64 #define ARCH_x86_64
# elif defined __arm__ #elif defined __arm__
# define ARCH_arm #define ARCH_arm
# endif #endif
#endif // not _MSC_VER #endif // not _MSC_VER
inline void inline void throwNew(JNIEnv* e, const char* class_, const char* message, ...)
throwNew(JNIEnv* e, const char* class_, const char* message, ...)
{ {
jclass c = e->FindClass(class_); jclass c = e->FindClass(class_);
if (c) { if (c) {
@ -99,8 +97,7 @@ throwNew(JNIEnv* e, const char* class_, const char* message, ...)
} }
} }
inline void inline void throwNewErrno(JNIEnv* e, const char* class_)
throwNewErrno(JNIEnv* e, const char* class_)
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
const unsigned size = 128; const unsigned size = 128;
@ -112,8 +109,7 @@ throwNewErrno(JNIEnv* e, const char* class_)
#endif #endif
} }
inline void* inline void* allocate(JNIEnv* e, unsigned size)
allocate(JNIEnv* e, unsigned size)
{ {
void* p = malloc(size); void* p = malloc(size);
if (p == 0) { if (p == 0) {
@ -122,4 +118,4 @@ allocate(JNIEnv* e, unsigned size)
return p; return p;
} }
#endif//JNI_UTIL #endif // JNI_UTIL

View File

@ -19,7 +19,8 @@ namespace avian {
namespace classpath { namespace classpath {
namespace sockets { namespace sockets {
int last_socket_error() { int last_socket_error()
{
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
int error = WSAGetLastError(); int error = WSAGetLastError();
#else #else
@ -28,8 +29,8 @@ int last_socket_error() {
return error; return error;
} }
void init(JNIEnv* ONLY_ON_WINDOWS(e))
void init(JNIEnv* ONLY_ON_WINDOWS(e)) { {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
static bool wsaInitialized = false; static bool wsaInitialized = false;
if (not wsaInitialized) { if (not wsaInitialized) {
@ -44,18 +45,21 @@ void init(JNIEnv* ONLY_ON_WINDOWS(e)) {
#endif #endif
} }
SOCKET create(JNIEnv* e) { SOCKET create(JNIEnv* e)
{
SOCKET sock; SOCKET sock;
if (INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) { if (INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
char buf[255]; char buf[255];
sprintf(buf, "Can't create a socket. System error: %d", last_socket_error()); sprintf(
buf, "Can't create a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf); throwNew(e, "java/io/IOException", buf);
return 0; // This doesn't matter cause we have risen an exception return 0; // This doesn't matter cause we have risen an exception
} }
return sock; return sock;
} }
void connect(JNIEnv* e, SOCKET sock, long addr, short port) { void connect(JNIEnv* e, SOCKET sock, long addr, short port)
{
sockaddr_in adr; sockaddr_in adr;
adr.sin_family = AF_INET; adr.sin_family = AF_INET;
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
@ -63,18 +67,19 @@ void connect(JNIEnv* e, SOCKET sock, long addr, short port) {
#else #else
adr.sin_addr.s_addr = htonl(addr); adr.sin_addr.s_addr = htonl(addr);
#endif #endif
adr.sin_port = htons (port); adr.sin_port = htons(port);
if (SOCKET_ERROR == ::connect(sock, (sockaddr* )&adr, sizeof(adr))) if (SOCKET_ERROR == ::connect(sock, (sockaddr*)&adr, sizeof(adr))) {
{
char buf[255]; char buf[255];
sprintf(buf, "Can't connect a socket. System error: %d", last_socket_error()); sprintf(
buf, "Can't connect a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf); throwNew(e, "java/io/IOException", buf);
return; return;
} }
} }
void bind(JNIEnv* e, SOCKET sock, long addr, short port) { void bind(JNIEnv* e, SOCKET sock, long addr, short port)
{
sockaddr_in adr; sockaddr_in adr;
adr.sin_family = AF_INET; adr.sin_family = AF_INET;
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
@ -82,10 +87,9 @@ void bind(JNIEnv* e, SOCKET sock, long addr, short port) {
#else #else
adr.sin_addr.s_addr = htonl(addr); adr.sin_addr.s_addr = htonl(addr);
#endif #endif
adr.sin_port = htons (port); adr.sin_port = htons(port);
if (SOCKET_ERROR == ::bind(sock, (sockaddr* )&adr, sizeof(adr))) if (SOCKET_ERROR == ::bind(sock, (sockaddr*)&adr, sizeof(adr))) {
{
char buf[255]; char buf[255];
sprintf(buf, "Can't bind a socket. System error: %d", last_socket_error()); sprintf(buf, "Can't bind a socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf); throwNew(e, "java/io/IOException", buf);
@ -93,60 +97,72 @@ void bind(JNIEnv* e, SOCKET sock, long addr, short port) {
} }
} }
SOCKET accept(JNIEnv* e, SOCKET sock, long* client_addr, short* client_port) { SOCKET accept(JNIEnv* e, SOCKET sock, long* client_addr, short* client_port)
{
sockaddr_in adr; sockaddr_in adr;
SOCKET client_socket = ::accept(sock, (sockaddr* )&adr, NULL); SOCKET client_socket = ::accept(sock, (sockaddr*)&adr, NULL);
if (INVALID_SOCKET == client_socket) { if (INVALID_SOCKET == client_socket) {
char buf[255]; char buf[255];
sprintf(buf, "Can't accept the incoming connection. System error: %d", last_socket_error()); sprintf(buf,
"Can't accept the incoming connection. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf); throwNew(e, "java/io/IOException", buf);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
if (client_addr != NULL) { if (client_addr != NULL) {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
*client_addr = ntohl(adr.sin_addr.S_un.S_addr); *client_addr = ntohl(adr.sin_addr.S_un.S_addr);
#else #else
*client_addr = ntohl(adr.sin_addr.s_addr); *client_addr = ntohl(adr.sin_addr.s_addr);
#endif #endif
} }
if (client_port != NULL) { if (client_port != NULL) {
*client_port = ntohs (adr.sin_port); *client_port = ntohs(adr.sin_port);
} }
return client_socket; return client_socket;
} }
void send(JNIEnv* e, SOCKET sock, const char* buff_ptr, int buff_size) { void send(JNIEnv* e, SOCKET sock, const char* buff_ptr, int buff_size)
{
if (SOCKET_ERROR == ::send(sock, buff_ptr, buff_size, 0)) { if (SOCKET_ERROR == ::send(sock, buff_ptr, buff_size, 0)) {
char buf[255]; char buf[255];
sprintf(buf, "Can't send data through the socket. System error: %d", last_socket_error()); sprintf(buf,
"Can't send data through the socket. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf); throwNew(e, "java/io/IOException", buf);
return; return;
} }
} }
int recv(JNIEnv* e, SOCKET sock, char* buff_ptr, int buff_size) { int recv(JNIEnv* e, SOCKET sock, char* buff_ptr, int buff_size)
{
int length = ::recv(sock, buff_ptr, buff_size, 0); int length = ::recv(sock, buff_ptr, buff_size, 0);
if (SOCKET_ERROR == length) { if (SOCKET_ERROR == length) {
char buf[255]; char buf[255];
sprintf(buf, "Can't receive data through the socket. System error: %d", last_socket_error()); sprintf(buf,
"Can't receive data through the socket. System error: %d",
last_socket_error());
throwNew(e, "java/io/IOException", buf); throwNew(e, "java/io/IOException", buf);
return 0; // This doesn't matter cause we have risen an exception return 0; // This doesn't matter cause we have risen an exception
} }
return length; return length;
} }
void abort(JNIEnv* e, SOCKET sock) { void abort(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::closesocket(sock)) { if (SOCKET_ERROR == ::closesocket(sock)) {
char buf[255]; char buf[255];
sprintf(buf, "Can't close the socket. System error: %d", last_socket_error()); sprintf(
buf, "Can't close the socket. System error: %d", last_socket_error());
throwNew(e, "java/io/IOException", buf); throwNew(e, "java/io/IOException", buf);
} }
} }
void close(JNIEnv* e, SOCKET sock) { void close(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_BOTH)) { if (SOCKET_ERROR == ::shutdown(sock, SD_BOTH)) {
int errcode = last_socket_error(); int errcode = last_socket_error();
if (errcode != ENOTCONN) { if (errcode != ENOTCONN) {
@ -157,7 +173,8 @@ void close(JNIEnv* e, SOCKET sock) {
} }
} }
void close_input(JNIEnv* e, SOCKET sock) { void close_input(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_RECEIVE)) { if (SOCKET_ERROR == ::shutdown(sock, SD_RECEIVE)) {
int errcode = last_socket_error(); int errcode = last_socket_error();
if (errcode != ENOTCONN) { if (errcode != ENOTCONN) {
@ -168,7 +185,8 @@ void close_input(JNIEnv* e, SOCKET sock) {
} }
} }
void close_output(JNIEnv* e, SOCKET sock) { void close_output(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_SEND)) { if (SOCKET_ERROR == ::shutdown(sock, SD_SEND)) {
int errcode = last_socket_error(); int errcode = last_socket_error();
if (errcode != ENOTCONN) { if (errcode != ENOTCONN) {
@ -178,7 +196,6 @@ void close_output(JNIEnv* e, SOCKET sock) {
} }
} }
} }
} }
} }
} }

View File

@ -8,7 +8,6 @@
There is NO WARRANTY for this software. See license.txt for There is NO WARRANTY for this software. See license.txt for
details. */ details. */
/* /*
* This file represents a simple cross-platform JNI sockets API * This file represents a simple cross-platform JNI sockets API
* It is used from different classes of the default Avian classpath * It is used from different classes of the default Avian classpath
@ -22,28 +21,28 @@
#include "jni-util.h" #include "jni-util.h"
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# include <winsock2.h> #include <winsock2.h>
# define ONLY_ON_WINDOWS(x) x #define ONLY_ON_WINDOWS(x) x
# ifndef ENOTCONN #ifndef ENOTCONN
# define ENOTCONN WSAENOTCONN #define ENOTCONN WSAENOTCONN
# endif #endif
#else #else
# include <netdb.h> #include <netdb.h>
# include <sys/socket.h> #include <sys/socket.h>
# include <netinet/in.h> #include <netinet/in.h>
# include <unistd.h> #include <unistd.h>
# define ONLY_ON_WINDOWS(x) #define ONLY_ON_WINDOWS(x)
# define SOCKET int #define SOCKET int
# define INVALID_SOCKET -1 #define INVALID_SOCKET -1
# define SOCKET_ERROR -1 #define SOCKET_ERROR -1
# define closesocket(x) close(x) #define closesocket(x) close(x)
# define SD_RECEIVE SHUT_RD #define SD_RECEIVE SHUT_RD
# define SD_SEND SHUT_WR #define SD_SEND SHUT_WR
# define SD_BOTH SHUT_RDWR #define SD_BOTH SHUT_RDWR
#endif #endif
@ -69,7 +68,6 @@ void abort(JNIEnv* e, SOCKET sock);
void close(JNIEnv* e, SOCKET sock); void close(JNIEnv* e, SOCKET sock);
void close_input(JNIEnv* e, SOCKET sock); void close_input(JNIEnv* e, SOCKET sock);
void close_output(JNIEnv* e, SOCKET sock); void close_output(JNIEnv* e, SOCKET sock);
} }
} }
} }

View File

@ -30,113 +30,123 @@ class Assembler;
class RegisterFile; class RegisterFile;
class OperandMask { class OperandMask {
public: public:
uint8_t typeMask; uint8_t typeMask;
uint64_t registerMask; uint64_t registerMask;
OperandMask(uint8_t typeMask, uint64_t registerMask): OperandMask(uint8_t typeMask, uint64_t registerMask)
typeMask(typeMask), : typeMask(typeMask), registerMask(registerMask)
registerMask(registerMask) {
{ } }
OperandMask(): OperandMask() : typeMask(~0), registerMask(~static_cast<uint64_t>(0))
typeMask(~0), {
registerMask(~static_cast<uint64_t>(0)) }
{ }
}; };
class Architecture { class Architecture {
public: public:
virtual unsigned floatRegisterSize() = 0; virtual unsigned floatRegisterSize() = 0;
virtual const RegisterFile* registerFile() = 0; virtual const RegisterFile* registerFile() = 0;
virtual int scratch() = 0; virtual int scratch() = 0;
virtual int stack() = 0; virtual int stack() = 0;
virtual int thread() = 0; virtual int thread() = 0;
virtual int returnLow() = 0; virtual int returnLow() = 0;
virtual int returnHigh() = 0; virtual int returnHigh() = 0;
virtual int virtualCallTarget() = 0; virtual int virtualCallTarget() = 0;
virtual int virtualCallIndex() = 0; virtual int virtualCallIndex() = 0;
virtual ir::TargetInfo targetInfo() = 0; virtual ir::TargetInfo targetInfo() = 0;
virtual bool bigEndian() = 0; virtual bool bigEndian() = 0;
virtual uintptr_t maximumImmediateJump() = 0; virtual uintptr_t maximumImmediateJump() = 0;
virtual bool alwaysCondensed(lir::BinaryOperation op) = 0; virtual bool alwaysCondensed(lir::BinaryOperation op) = 0;
virtual bool alwaysCondensed(lir::TernaryOperation op) = 0; virtual bool alwaysCondensed(lir::TernaryOperation op) = 0;
virtual bool reserved(int register_) = 0; virtual bool reserved(int register_) = 0;
virtual unsigned frameFootprint(unsigned footprint) = 0; virtual unsigned frameFootprint(unsigned footprint) = 0;
virtual unsigned argumentFootprint(unsigned footprint) = 0; virtual unsigned argumentFootprint(unsigned footprint) = 0;
virtual bool argumentAlignment() = 0; virtual bool argumentAlignment() = 0;
virtual bool argumentRegisterAlignment() = 0; virtual bool argumentRegisterAlignment() = 0;
virtual unsigned argumentRegisterCount() = 0; virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0; virtual int argumentRegister(unsigned index) = 0;
virtual bool hasLinkRegister() = 0; virtual bool hasLinkRegister() = 0;
virtual unsigned stackAlignmentInWords() = 0; virtual unsigned stackAlignmentInWords() = 0;
virtual bool matchCall(void* returnAddress, void* target) = 0; virtual bool matchCall(void* returnAddress, void* target) = 0;
virtual void updateCall(lir::UnaryOperation op, void* returnAddress, virtual void updateCall(lir::UnaryOperation op,
void* returnAddress,
void* newTarget) = 0; void* newTarget) = 0;
virtual void setConstant(void* dst, uint64_t constant) = 0; virtual void setConstant(void* dst, uint64_t constant) = 0;
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0; virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
virtual void nextFrame(void* start, unsigned size, unsigned footprint, virtual void nextFrame(void* start,
void* link, bool mostRecent, unsigned size,
int targetParameterFootprint, void** ip, unsigned footprint,
void* link,
bool mostRecent,
int targetParameterFootprint,
void** ip,
void** stack) = 0; void** stack) = 0;
virtual void* frameIp(void* stack) = 0; virtual void* frameIp(void* stack) = 0;
virtual unsigned frameHeaderSize() = 0; virtual unsigned frameHeaderSize() = 0;
virtual unsigned frameReturnAddressSize() = 0; virtual unsigned frameReturnAddressSize() = 0;
virtual unsigned frameFooterSize() = 0; virtual unsigned frameFooterSize() = 0;
virtual int returnAddressOffset() = 0; virtual int returnAddressOffset() = 0;
virtual int framePointerOffset() = 0; virtual int framePointerOffset() = 0;
virtual void plan virtual void plan(lir::UnaryOperation op,
(lir::UnaryOperation op, unsigned aSize,
unsigned aSize, OperandMask& aMask, OperandMask& aMask,
bool* thunk) = 0; bool* thunk) = 0;
virtual void planSource virtual void planSource(lir::BinaryOperation op,
(lir::BinaryOperation op, unsigned aSize,
unsigned aSize, OperandMask& aMask, OperandMask& aMask,
unsigned bSize, bool* thunk) = 0; unsigned bSize,
bool* thunk) = 0;
virtual void planDestination virtual void planDestination(lir::BinaryOperation op,
(lir::BinaryOperation op, unsigned aSize,
unsigned aSize, const OperandMask& aMask, const OperandMask& aMask,
unsigned bSize, OperandMask& bMask) = 0; unsigned bSize,
OperandMask& bMask) = 0;
virtual void planMove virtual void planMove(unsigned size,
(unsigned size, OperandMask& src, OperandMask& src,
OperandMask& tmp, OperandMask& tmp,
const OperandMask& dst) = 0; const OperandMask& dst) = 0;
virtual void planSource virtual void planSource(lir::TernaryOperation op,
(lir::TernaryOperation op, unsigned aSize,
unsigned aSize, OperandMask& aMask, OperandMask& aMask,
unsigned bSize, OperandMask& bMask, unsigned bSize,
unsigned cSize, bool* thunk) = 0; OperandMask& bMask,
unsigned cSize,
bool* thunk) = 0;
virtual void planDestination virtual void planDestination(lir::TernaryOperation op,
(lir::TernaryOperation op, unsigned aSize,
unsigned aSize, const OperandMask& aMask, const OperandMask& aMask,
unsigned bSize, const OperandMask& bMask, unsigned bSize,
unsigned cSize, OperandMask& cMask) = 0; const OperandMask& bMask,
unsigned cSize,
OperandMask& cMask) = 0;
virtual Assembler* makeAssembler(util::Allocator*, vm::Zone*) = 0; virtual Assembler* makeAssembler(util::Allocator*, vm::Zone*) = 0;
virtual void acquire() = 0; virtual void acquire() = 0;
virtual void release() = 0; virtual void release() = 0;
}; };
} // namespace codegen } // namespace codegen

View File

@ -23,16 +23,17 @@ namespace codegen {
class Architecture; class Architecture;
class OperandInfo { class OperandInfo {
public: public:
const unsigned size; const unsigned size;
const lir::OperandType type; const lir::OperandType type;
lir::Operand* const operand; lir::Operand* const operand;
inline OperandInfo(unsigned size, lir::OperandType type, lir::Operand* operand): inline OperandInfo(unsigned size,
size(size), lir::OperandType type,
type(type), lir::Operand* operand)
operand(operand) : size(size), type(type), operand(operand)
{ } {
}
}; };
#ifdef AVIAN_TAILS #ifdef AVIAN_TAILS
@ -49,11 +50,9 @@ const bool UseFramePointer = false;
class Assembler { class Assembler {
public: public:
class Client { class Client {
public: public:
virtual int acquireTemporary virtual int acquireTemporary(uint32_t mask = ~static_cast<uint32_t>(0)) = 0;
(uint32_t mask = ~static_cast<uint32_t>(0)) = 0;
virtual void releaseTemporary(int r) = 0; virtual void releaseTemporary(int r) = 0;
virtual void save(int r) = 0; virtual void save(int r) = 0;
@ -75,12 +74,12 @@ class Assembler {
virtual void allocateFrame(unsigned footprint) = 0; virtual void allocateFrame(unsigned footprint) = 0;
virtual void adjustFrame(unsigned difference) = 0; virtual void adjustFrame(unsigned difference) = 0;
virtual void popFrame(unsigned footprint) = 0; virtual void popFrame(unsigned footprint) = 0;
virtual void popFrameForTailCall(unsigned footprint, int offset, virtual void popFrameForTailCall(unsigned footprint,
int offset,
int returnAddressSurrogate, int returnAddressSurrogate,
int framePointerSurrogate) = 0; int framePointerSurrogate) = 0;
virtual void popFrameAndPopArgumentsAndReturn(unsigned frameFootprint, virtual void popFrameAndPopArgumentsAndReturn(unsigned frameFootprint,
unsigned argumentFootprint) unsigned argumentFootprint) = 0;
= 0;
virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint, virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint,
unsigned stackOffsetFromThread) unsigned stackOffsetFromThread)
= 0; = 0;
@ -88,7 +87,10 @@ class Assembler {
virtual void apply(lir::Operation op) = 0; virtual void apply(lir::Operation op) = 0;
virtual void apply(lir::UnaryOperation op, OperandInfo a) = 0; virtual void apply(lir::UnaryOperation op, OperandInfo a) = 0;
virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) = 0; virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) = 0;
virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) = 0; virtual void apply(lir::TernaryOperation op,
OperandInfo a,
OperandInfo b,
OperandInfo c) = 0;
virtual void setDestination(uint8_t* dst) = 0; virtual void setDestination(uint8_t* dst) = 0;

View File

@ -30,10 +30,13 @@ class Compiler {
class Client { class Client {
public: public:
virtual intptr_t getThunk(lir::UnaryOperation op, unsigned size) = 0; virtual intptr_t getThunk(lir::UnaryOperation op, unsigned size) = 0;
virtual intptr_t getThunk(lir::BinaryOperation op, unsigned size, virtual intptr_t getThunk(lir::BinaryOperation op,
unsigned size,
unsigned resultSize) = 0; unsigned resultSize) = 0;
virtual intptr_t getThunk(lir::TernaryOperation op, unsigned size, virtual intptr_t getThunk(lir::TernaryOperation op,
unsigned resultSize, bool* threadParameter) = 0; unsigned size,
unsigned resultSize,
bool* threadParameter) = 0;
}; };
static const unsigned Aligned = 1 << 0; static const unsigned Aligned = 1 << 0;
@ -41,13 +44,16 @@ class Compiler {
static const unsigned TailJump = 1 << 2; static const unsigned TailJump = 1 << 2;
static const unsigned LongJumpOrCall = 1 << 3; static const unsigned LongJumpOrCall = 1 << 3;
class State { }; class State {
};
virtual State* saveState() = 0; virtual State* saveState() = 0;
virtual void restoreState(State* state) = 0; virtual void restoreState(State* state) = 0;
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint, virtual void init(unsigned logicalCodeSize,
unsigned localFootprint, unsigned alignedFrameSize) = 0; unsigned parameterFootprint,
unsigned localFootprint,
unsigned alignedFrameSize) = 0;
virtual void extendLogicalCode(unsigned more) = 0; virtual void extendLogicalCode(unsigned more) = 0;
@ -128,8 +134,7 @@ class Compiler {
ir::Type type, ir::Type type,
ir::Value* a, ir::Value* a,
ir::Value* b) = 0; ir::Value* b) = 0;
virtual ir::Value* unaryOp(lir::BinaryOperation op, virtual ir::Value* unaryOp(lir::BinaryOperation op, ir::Value* a) = 0;
ir::Value* a) = 0;
virtual void nullaryOp(lir::Operation op) = 0; virtual void nullaryOp(lir::Operation op) = 0;
virtual ir::Value* f2f(ir::Type resType, ir::Value* a) = 0; virtual ir::Value* f2f(ir::Type resType, ir::Value* a) = 0;
@ -145,8 +150,9 @@ class Compiler {
virtual void dispose() = 0; virtual void dispose() = 0;
}; };
Compiler* Compiler* makeCompiler(vm::System* system,
makeCompiler(vm::System* system, Assembler* assembler, vm::Zone* zone, Assembler* assembler,
vm::Zone* zone,
Compiler::Client* client); Compiler::Client* client);
} // namespace codegen } // namespace codegen

View File

@ -17,71 +17,67 @@ class Promise;
namespace lir { namespace lir {
enum Operation { enum Operation {
#define LIR_OP_0(x) x, #define LIR_OP_0(x) x,
#define LIR_OP_1(x) #define LIR_OP_1(x)
#define LIR_OP_2(x) #define LIR_OP_2(x)
#define LIR_OP_3(x) #define LIR_OP_3(x)
#include "lir-ops.inc.cpp" #include "lir-ops.inc.cpp"
#undef LIR_OP_0 #undef LIR_OP_0
#undef LIR_OP_1 #undef LIR_OP_1
#undef LIR_OP_2 #undef LIR_OP_2
#undef LIR_OP_3 #undef LIR_OP_3
}; };
const unsigned OperationCount = Trap + 1; const unsigned OperationCount = Trap + 1;
enum UnaryOperation { enum UnaryOperation {
#define LIR_OP_0(x) #define LIR_OP_0(x)
#define LIR_OP_1(x) x, #define LIR_OP_1(x) x,
#define LIR_OP_2(x) #define LIR_OP_2(x)
#define LIR_OP_3(x) #define LIR_OP_3(x)
#include "lir-ops.inc.cpp" #include "lir-ops.inc.cpp"
#undef LIR_OP_0 #undef LIR_OP_0
#undef LIR_OP_1 #undef LIR_OP_1
#undef LIR_OP_2 #undef LIR_OP_2
#undef LIR_OP_3 #undef LIR_OP_3
NoUnaryOperation = -1 NoUnaryOperation = -1
}; };
const unsigned UnaryOperationCount = AlignedJump + 1; const unsigned UnaryOperationCount = AlignedJump + 1;
enum BinaryOperation { enum BinaryOperation {
#define LIR_OP_0(x) #define LIR_OP_0(x)
#define LIR_OP_1(x) #define LIR_OP_1(x)
#define LIR_OP_2(x) x, #define LIR_OP_2(x) x,
#define LIR_OP_3(x) #define LIR_OP_3(x)
#include "lir-ops.inc.cpp" #include "lir-ops.inc.cpp"
#undef LIR_OP_0 #undef LIR_OP_0
#undef LIR_OP_1 #undef LIR_OP_1
#undef LIR_OP_2 #undef LIR_OP_2
#undef LIR_OP_3 #undef LIR_OP_3
NoBinaryOperation = -1 NoBinaryOperation = -1
}; };
const unsigned BinaryOperationCount = Absolute + 1; const unsigned BinaryOperationCount = Absolute + 1;
enum TernaryOperation { enum TernaryOperation {
#define LIR_OP_0(x) #define LIR_OP_0(x)
#define LIR_OP_1(x) #define LIR_OP_1(x)
#define LIR_OP_2(x) #define LIR_OP_2(x)
#define LIR_OP_3(x) x, #define LIR_OP_3(x) x,
#include "lir-ops.inc.cpp" #include "lir-ops.inc.cpp"
#undef LIR_OP_0 #undef LIR_OP_0
#undef LIR_OP_1 #undef LIR_OP_1
#undef LIR_OP_2 #undef LIR_OP_2
#undef LIR_OP_3 #undef LIR_OP_3
NoTernaryOperation = -1 NoTernaryOperation = -1
}; };
const unsigned TernaryOperationCount const unsigned TernaryOperationCount = JumpIfFloatGreaterOrEqualOrUnordered + 1;
= JumpIfFloatGreaterOrEqualOrUnordered + 1;
const unsigned NonBranchTernaryOperationCount = FloatMin + 1; const unsigned NonBranchTernaryOperationCount = FloatMin + 1;
const unsigned BranchOperationCount const unsigned BranchOperationCount = JumpIfFloatGreaterOrEqualOrUnordered
= JumpIfFloatGreaterOrEqualOrUnordered - FloatMin; - FloatMin;
enum OperandType { enum OperandType {
ConstantOperand, ConstantOperand,
@ -90,72 +86,84 @@ enum OperandType {
MemoryOperand MemoryOperand
}; };
enum ValueType { enum ValueType { ValueGeneral, ValueFloat };
ValueGeneral,
ValueFloat
};
const unsigned OperandTypeCount = MemoryOperand + 1; const unsigned OperandTypeCount = MemoryOperand + 1;
const int NoRegister = -1; const int NoRegister = -1;
inline bool isBranch(lir::TernaryOperation op) { inline bool isBranch(lir::TernaryOperation op)
{
return op > FloatMin; return op > FloatMin;
} }
inline bool isFloatBranch(lir::TernaryOperation op) { inline bool isFloatBranch(lir::TernaryOperation op)
{
return op > JumpIfNotEqual; return op > JumpIfNotEqual;
} }
inline bool isGeneralBranch(lir::TernaryOperation op) { inline bool isGeneralBranch(lir::TernaryOperation op)
{
return isBranch(op) && !isFloatBranch(op); return isBranch(op) && !isFloatBranch(op);
} }
inline bool isGeneralBinaryOp(lir::TernaryOperation op) { inline bool isGeneralBinaryOp(lir::TernaryOperation op)
{
return op < FloatAdd; return op < FloatAdd;
} }
inline bool isFloatBinaryOp(lir::TernaryOperation op) { inline bool isFloatBinaryOp(lir::TernaryOperation op)
{
return op >= FloatAdd && op <= FloatMin; return op >= FloatAdd && op <= FloatMin;
} }
inline bool isGeneralUnaryOp(lir::BinaryOperation op) { inline bool isGeneralUnaryOp(lir::BinaryOperation op)
{
return op == Negate || op == Absolute; return op == Negate || op == Absolute;
} }
inline bool isFloatUnaryOp(lir::BinaryOperation op) { inline bool isFloatUnaryOp(lir::BinaryOperation op)
{
return op == FloatNegate || op == FloatSquareRoot || op == FloatAbsolute; return op == FloatNegate || op == FloatSquareRoot || op == FloatAbsolute;
} }
class Operand { }; class Operand {
};
class Constant: public Operand { class Constant : public Operand {
public: public:
Constant(Promise* value): value(value) { } Constant(Promise* value) : value(value)
{
}
Promise* value; Promise* value;
}; };
class Address: public Operand { class Address : public Operand {
public: public:
Address(Promise* address): address(address) { } Address(Promise* address) : address(address)
{
}
Promise* address; Promise* address;
}; };
class Register: public Operand { class Register : public Operand {
public: public:
Register(int low, int high = NoRegister): low(low), high(high) { } Register(int low, int high = NoRegister) : low(low), high(high)
{
}
int low; int low;
int high; int high;
}; };
class Memory: public Operand { class Memory : public Operand {
public: public:
Memory(int base, int offset, int index = NoRegister, unsigned scale = 1): Memory(int base, int offset, int index = NoRegister, unsigned scale = 1)
base(base), offset(offset), index(index), scale(scale) : base(base), offset(offset), index(index), scale(scale)
{ } {
}
int base; int base;
int offset; int offset;

View File

@ -29,35 +29,45 @@ class Promise {
virtual int64_t value() = 0; virtual int64_t value() = 0;
virtual bool resolved() = 0; virtual bool resolved() = 0;
virtual Listener* listen(unsigned) { return 0; } virtual Listener* listen(unsigned)
{
return 0;
}
}; };
class ResolvedPromise: public Promise { class ResolvedPromise : public Promise {
public: public:
ResolvedPromise(int64_t value): value_(value) { } ResolvedPromise(int64_t value) : value_(value)
{
}
virtual int64_t value() { virtual int64_t value()
{
return value_; return value_;
} }
virtual bool resolved() { virtual bool resolved()
{
return true; return true;
} }
int64_t value_; int64_t value_;
}; };
class ShiftMaskPromise: public Promise { class ShiftMaskPromise : public Promise {
public: public:
ShiftMaskPromise(Promise* base, unsigned shift, int64_t mask): ShiftMaskPromise(Promise* base, unsigned shift, int64_t mask)
base(base), shift(shift), mask(mask) : base(base), shift(shift), mask(mask)
{ } {
}
virtual int64_t value() { virtual int64_t value()
{
return (base->value() >> shift) & mask; return (base->value() >> shift) & mask;
} }
virtual bool resolved() { virtual bool resolved()
{
return base->resolved(); return base->resolved();
} }
@ -66,17 +76,19 @@ class ShiftMaskPromise: public Promise {
int64_t mask; int64_t mask;
}; };
class CombinedPromise: public Promise { class CombinedPromise : public Promise {
public: public:
CombinedPromise(Promise* low, Promise* high): CombinedPromise(Promise* low, Promise* high) : low(low), high(high)
low(low), high(high) {
{ } }
virtual int64_t value() { virtual int64_t value()
{
return low->value() | (high->value() << 32); return low->value() | (high->value() << 32);
} }
virtual bool resolved() { virtual bool resolved()
{
return low->resolved() and high->resolved(); return low->resolved() and high->resolved();
} }
@ -84,17 +96,19 @@ class CombinedPromise: public Promise {
Promise* high; Promise* high;
}; };
class OffsetPromise: public Promise { class OffsetPromise : public Promise {
public: public:
OffsetPromise(Promise* base, int64_t offset): OffsetPromise(Promise* base, int64_t offset) : base(base), offset(offset)
base(base), offset(offset) {
{ } }
virtual int64_t value() { virtual int64_t value()
{
return base->value() + offset; return base->value() + offset;
} }
virtual bool resolved() { virtual bool resolved()
{
return base->resolved(); return base->resolved();
} }
@ -102,21 +116,25 @@ class OffsetPromise: public Promise {
int64_t offset; int64_t offset;
}; };
class ListenPromise: public Promise { class ListenPromise : public Promise {
public: public:
ListenPromise(vm::System* s, util::Allocator* allocator) ListenPromise(vm::System* s, util::Allocator* allocator)
: s(s), allocator(allocator), listener(0) : s(s), allocator(allocator), listener(0)
{ } {
}
virtual int64_t value() { virtual int64_t value()
{
abort(s); abort(s);
} }
virtual bool resolved() { virtual bool resolved()
{
return false; return false;
} }
virtual Listener* listen(unsigned sizeInBytes) { virtual Listener* listen(unsigned sizeInBytes)
{
Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes)); Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes));
l->next = listener; l->next = listener;
listener = l; listener = l;
@ -129,24 +147,28 @@ class ListenPromise: public Promise {
Promise* promise; Promise* promise;
}; };
class DelayedPromise: public ListenPromise { class DelayedPromise : public ListenPromise {
public: public:
DelayedPromise(vm::System* s, DelayedPromise(vm::System* s,
util::Allocator* allocator, util::Allocator* allocator,
Promise* basis, Promise* basis,
DelayedPromise* next) DelayedPromise* next)
: ListenPromise(s, allocator), basis(basis), next(next) : ListenPromise(s, allocator), basis(basis), next(next)
{ } {
}
virtual int64_t value() { virtual int64_t value()
{
abort(s); abort(s);
} }
virtual bool resolved() { virtual bool resolved()
{
return false; return false;
} }
virtual Listener* listen(unsigned sizeInBytes) { virtual Listener* listen(unsigned sizeInBytes)
{
Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes)); Listener* l = static_cast<Listener*>(allocator->allocate(sizeInBytes));
l->next = listener; l->next = listener;
listener = l; listener = l;

View File

@ -17,7 +17,7 @@ namespace avian {
namespace codegen { namespace codegen {
class RegisterMask { class RegisterMask {
public: public:
uint32_t mask; uint32_t mask;
uint8_t start; uint8_t start;
uint8_t limit; uint8_t limit;
@ -25,44 +25,47 @@ public:
static unsigned maskStart(uint32_t mask); static unsigned maskStart(uint32_t mask);
static unsigned maskLimit(uint32_t mask); static unsigned maskLimit(uint32_t mask);
inline RegisterMask(uint32_t mask): inline RegisterMask(uint32_t mask)
mask(mask), : mask(mask), start(maskStart(mask)), limit(maskLimit(mask))
start(maskStart(mask)), {
limit(maskLimit(mask)) }
{ }
}; };
class RegisterFile { class RegisterFile {
public: public:
RegisterMask allRegisters; RegisterMask allRegisters;
RegisterMask generalRegisters; RegisterMask generalRegisters;
RegisterMask floatRegisters; RegisterMask floatRegisters;
inline RegisterFile(uint32_t generalRegisterMask, uint32_t floatRegisterMask): inline RegisterFile(uint32_t generalRegisterMask, uint32_t floatRegisterMask)
allRegisters(generalRegisterMask | floatRegisterMask), : allRegisters(generalRegisterMask | floatRegisterMask),
generalRegisters(generalRegisterMask), generalRegisters(generalRegisterMask),
floatRegisters(floatRegisterMask) floatRegisters(floatRegisterMask)
{ } {
}
}; };
class RegisterIterator { class RegisterIterator {
public: public:
int index; int index;
const RegisterMask& mask; const RegisterMask& mask;
inline RegisterIterator(const RegisterMask& mask): inline RegisterIterator(const RegisterMask& mask)
index(mask.start), : index(mask.start), mask(mask)
mask(mask) {} {
}
inline bool hasNext() { inline bool hasNext()
{
return index < mask.limit; return index < mask.limit;
} }
inline int next() { inline int next()
{
int r = index; int r = index;
do { do {
index++; index++;
} while(index < mask.limit && !(mask.mask & (1 << index))); } while (index < mask.limit && !(mask.mask & (1 << index)));
return r; return r;
} }
}; };

View File

@ -20,7 +20,8 @@ namespace codegen {
class Architecture; class Architecture;
Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures); Architecture* makeArchitectureNative(vm::System* system,
bool useNativeFeatures);
Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures); Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures);
Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures); Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures);

View File

@ -24,17 +24,9 @@ const unsigned FixieTenureThreshold = TenureThreshold + 2;
class Heap : public avian::util::Allocator { class Heap : public avian::util::Allocator {
public: public:
enum CollectionType { enum CollectionType { MinorCollection, MajorCollection };
MinorCollection,
MajorCollection
};
enum Status { enum Status { Null, Reachable, Unreachable, Tenured };
Null,
Reachable,
Unreachable,
Tenured
};
class Visitor { class Visitor {
public: public:
@ -62,7 +54,8 @@ class Heap : public avian::util::Allocator {
virtual unsigned remaining() = 0; virtual unsigned remaining() = 0;
virtual unsigned limit() = 0; virtual unsigned limit() = 0;
virtual bool limitExceeded(int pendingAllocation = 0) = 0; virtual bool limitExceeded(int pendingAllocation = 0) = 0;
virtual void collect(CollectionType type, unsigned footprint, virtual void collect(CollectionType type,
unsigned footprint,
int pendingAllocation) = 0; int pendingAllocation) = 0;
virtual unsigned fixedFootprint(unsigned sizeInWords, bool objectMask) = 0; virtual unsigned fixedFootprint(unsigned sizeInWords, bool objectMask) = 0;
virtual void* allocateFixed(avian::util::Allocator* allocator, virtual void* allocateFixed(avian::util::Allocator* allocator,
@ -92,4 +85,4 @@ Heap* makeHeap(System* system, unsigned limit);
} // namespace vm } // namespace vm
#endif//HEAP_H #endif // HEAP_H

View File

@ -21,7 +21,8 @@ namespace system {
// order to trigger the crash dump logic. // order to trigger the crash dump logic.
NO_RETURN void crash(); NO_RETURN void crash();
// Registrar for unix-like "signals" (implemented with structured exceptions on windows). // Registrar for unix-like "signals" (implemented with structured exceptions on
// windows).
// TODO: remove dependence on generated code having a well-known "thread" // TODO: remove dependence on generated code having a well-known "thread"
// register. Use a thread-local variable instead. // register. Use a thread-local variable instead.
class SignalRegistrar { class SignalRegistrar {
@ -40,7 +41,6 @@ class SignalRegistrar {
// "Segmentation fault" exceptions (mostly null pointer dereference, but // "Segmentation fault" exceptions (mostly null pointer dereference, but
// generally access to any non-mapped memory) // generally access to any non-mapped memory)
SegFault, SegFault,
DivideByZero, DivideByZero,
}; };
@ -72,7 +72,6 @@ class SignalRegistrar {
struct Data; struct Data;
private: private:
Data* data; Data* data;
}; };

View File

@ -21,12 +21,7 @@ class System : public avian::util::Aborter {
public: public:
typedef intptr_t Status; typedef intptr_t Status;
enum FileType { enum FileType { TypeUnknown, TypeDoesNotExist, TypeFile, TypeDirectory };
TypeUnknown,
TypeDoesNotExist,
TypeFile,
TypeDirectory
};
class Thread { class Thread {
public: public:
@ -100,11 +95,13 @@ class System : public avian::util::Aborter {
class MonitorResource { class MonitorResource {
public: public:
MonitorResource(System::Thread* t, System::Monitor* m): t(t), m(m) { MonitorResource(System::Thread* t, System::Monitor* m) : t(t), m(m)
{
m->acquire(t); m->acquire(t);
} }
~MonitorResource() { ~MonitorResource()
{
m->release(t); m->release(t);
} }
@ -126,8 +123,8 @@ class System : public avian::util::Aborter {
virtual Status make(Monitor**) = 0; virtual Status make(Monitor**) = 0;
virtual Status make(Local**) = 0; virtual Status make(Local**) = 0;
virtual Status visit(Thread* thread, Thread* target, virtual Status visit(Thread* thread, Thread* target, ThreadVisitor* visitor)
ThreadVisitor* visitor) = 0; = 0;
virtual Status map(Region**, const char* name) = 0; virtual Status map(Region**, const char* name) = 0;
virtual FileType stat(const char* name, unsigned* length) = 0; virtual FileType stat(const char* name, unsigned* length) = 0;
@ -145,23 +142,23 @@ class System : public avian::util::Aborter {
virtual void dispose() = 0; virtual void dispose() = 0;
}; };
inline void* inline void* allocate(System* s, unsigned size)
allocate(System* s, unsigned size)
{ {
void* p = s->tryAllocate(size); void* p = s->tryAllocate(size);
if (p == 0) s->abort(); if (p == 0)
s->abort();
return p; return p;
} }
#define ACQUIRE_MONITOR(t, m) \ #define ACQUIRE_MONITOR(t, m) \
System::MonitorResource MAKE_NAME(monitorResource_) (t, m) System::MonitorResource MAKE_NAME(monitorResource_)(t, m)
inline avian::util::Aborter* getAborter(System* s) { inline avian::util::Aborter* getAborter(System* s)
{
return s; return s;
} }
inline void NO_RETURN inline void NO_RETURN sysAbort(System* s)
sysAbort(System* s)
{ {
abort(s); abort(s);
} }
@ -183,9 +180,8 @@ sysAbort(System* s)
// #endif // not NDEBUG // #endif // not NDEBUG
AVIAN_EXPORT System* AVIAN_EXPORT System* makeSystem();
makeSystem();
} // namespace vm } // namespace vm
#endif//SYSTEM_H #endif // SYSTEM_H

View File

@ -23,16 +23,17 @@ namespace avian {
namespace tools { namespace tools {
class OutputStream { class OutputStream {
public: public:
virtual void writeChunk(const void* data, size_t size) = 0; virtual void writeChunk(const void* data, size_t size) = 0;
virtual void write(uint8_t byte); virtual void write(uint8_t byte);
virtual void writeRepeat(uint8_t byte, size_t size); virtual void writeRepeat(uint8_t byte, size_t size);
}; };
class FileOutputStream : public OutputStream { class FileOutputStream : public OutputStream {
private: private:
FILE* file; FILE* file;
public:
public:
FileOutputStream(const char* name); FileOutputStream(const char* name);
~FileOutputStream(); ~FileOutputStream();
@ -43,20 +44,22 @@ public:
}; };
class SymbolInfo { class SymbolInfo {
public: public:
unsigned addr; unsigned addr;
util::String name; util::String name;
inline SymbolInfo(uint64_t addr, const util::String& name): inline SymbolInfo(uint64_t addr, const util::String& name)
addr(addr), : addr(addr), name(name)
name(name) {} {
}
inline SymbolInfo(): inline SymbolInfo() : name("")
name("") {} {
}
}; };
class Buffer { class Buffer {
public: public:
size_t capacity; size_t capacity;
size_t length; size_t length;
uint8_t* data; uint8_t* data;
@ -69,7 +72,7 @@ public:
}; };
class StringTable : public Buffer { class StringTable : public Buffer {
public: public:
unsigned add(util::String str); unsigned add(util::String str);
}; };
@ -103,7 +106,7 @@ class DynamicArray : public util::Slice<T> {
}; };
class PlatformInfo { class PlatformInfo {
public: public:
enum Format { enum Format {
Elf = AVIAN_FORMAT_ELF, Elf = AVIAN_FORMAT_ELF,
Pe = AVIAN_FORMAT_PE, Pe = AVIAN_FORMAT_PE,
@ -124,33 +127,31 @@ public:
static Format formatFromString(const char* format); static Format formatFromString(const char* format);
static Architecture archFromString(const char* arch); static Architecture archFromString(const char* arch);
inline PlatformInfo(Format format, Architecture arch): inline PlatformInfo(Format format, Architecture arch)
format(format), : format(format), arch(arch)
arch(arch) {} {
}
inline bool operator == (const PlatformInfo& other) { inline bool operator==(const PlatformInfo& other)
{
return format == other.format && arch == other.arch; return format == other.format && arch == other.arch;
} }
}; };
class Platform { class Platform {
private: private:
Platform* next; Platform* next;
static Platform* first; static Platform* first;
public:
public:
PlatformInfo info; PlatformInfo info;
inline Platform(PlatformInfo info): inline Platform(PlatformInfo info) : next(first), info(info)
next(first),
info(info)
{ {
first = this; first = this;
} }
enum AccessFlags { enum AccessFlags { Writable = 1 << 0, Executable = 1 << 1 };
Writable = 1 << 0,
Executable = 1 << 1
};
virtual bool writeObject(OutputStream* out, virtual bool writeObject(OutputStream* out,
util::Slice<SymbolInfo> symbols, util::Slice<SymbolInfo> symbols,
@ -166,4 +167,3 @@ public:
} // namespace avian } // namespace avian
#endif #endif

View File

@ -19,7 +19,7 @@ namespace avian {
namespace util { namespace util {
class Aborter { class Aborter {
public: public:
virtual void NO_RETURN abort() = 0; virtual void NO_RETURN abort() = 0;
}; };
@ -28,15 +28,17 @@ inline Aborter* getAborter(Aborter* a)
return a; return a;
} }
template<class T> template <class T>
inline void NO_RETURN abort(T t) { inline void NO_RETURN abort(T t)
{
getAborter(t)->abort(); getAborter(t)->abort();
::abort(); ::abort();
} }
template<class T> template <class T>
inline void expect(T t, bool v) { inline void expect(T t, bool v)
if(UNLIKELY(!v)) { {
if (UNLIKELY(!v)) {
abort(t); abort(t);
} }
} }

View File

@ -31,7 +31,7 @@ class ArgParser {
}; };
class Arg { class Arg {
public: public:
Arg* next; Arg* next;
bool required; bool required;
const char* name; const char* name;
@ -42,7 +42,6 @@ public:
Arg(ArgParser& parser, bool required, const char* name, const char* desc); Arg(ArgParser& parser, bool required, const char* name, const char* desc);
}; };
} // namespace avian } // namespace avian
} // namespace util } // namespace util

View File

@ -18,16 +18,17 @@ namespace util {
template <class T> template <class T>
class List { class List {
public: public:
List(const T& item, List<T>* next): List(const T& item, List<T>* next) : item(item), next(next)
item(item), {
next(next) {} }
unsigned count() { unsigned count()
{
unsigned count = 0; unsigned count = 0;
List<T>* c = this; List<T>* c = this;
while (c) { while (c) {
++ count; ++count;
c = c->next; c = c->next;
} }
return count; return count;

View File

@ -17,36 +17,47 @@
namespace avian { namespace avian {
namespace util { namespace util {
inline unsigned max(unsigned a, unsigned b) { inline unsigned max(unsigned a, unsigned b)
{
return (a > b ? a : b); return (a > b ? a : b);
} }
inline unsigned min(unsigned a, unsigned b) { inline unsigned min(unsigned a, unsigned b)
{
return (a < b ? a : b); return (a < b ? a : b);
} }
inline unsigned avg(unsigned a, unsigned b) { inline unsigned avg(unsigned a, unsigned b)
{
return (a + b) / 2; return (a + b) / 2;
} }
inline unsigned ceilingDivide(unsigned n, unsigned d) { inline unsigned ceilingDivide(unsigned n, unsigned d)
{
return (n + d - 1) / d; return (n + d - 1) / d;
} }
inline bool powerOfTwo(unsigned n) { inline bool powerOfTwo(unsigned n)
for (; n > 2; n >>= 1) if (n & 1) return false; {
for (; n > 2; n >>= 1)
if (n & 1)
return false;
return true; return true;
} }
inline unsigned nextPowerOfTwo(unsigned n) { inline unsigned nextPowerOfTwo(unsigned n)
{
unsigned r = 1; unsigned r = 1;
while (r < n) r <<= 1; while (r < n)
r <<= 1;
return r; return r;
} }
inline unsigned log(unsigned n) { inline unsigned log(unsigned n)
{
unsigned r = 0; unsigned r = 0;
for (unsigned i = 1; i < n; ++r) i <<= 1; for (unsigned i = 1; i < n; ++r)
i <<= 1;
return r; return r;
} }

View File

@ -16,24 +16,25 @@
template <class T> template <class T>
class RuntimeArray { class RuntimeArray {
public: public:
RuntimeArray(unsigned size): RuntimeArray(unsigned size) : body(static_cast<T*>(malloc(size * sizeof(T))))
body(static_cast<T*>(malloc(size * sizeof(T)))) {
{ } }
~RuntimeArray() { ~RuntimeArray()
{
free(body); free(body);
} }
T* body; T* body;
}; };
# define RUNTIME_ARRAY(type, name, size) RuntimeArray<type> name(size); #define RUNTIME_ARRAY(type, name, size) RuntimeArray<type> name(size);
# define RUNTIME_ARRAY_BODY(name) name.body #define RUNTIME_ARRAY_BODY(name) name.body
#else // not _MSC_VER #else // not _MSC_VER
# define RUNTIME_ARRAY(type, name, size) type name##_body[size]; #define RUNTIME_ARRAY(type, name, size) type name##_body[size];
# define RUNTIME_ARRAY_BODY(name) name##_body #define RUNTIME_ARRAY_BODY(name) name##_body
#endif #endif

View File

@ -22,19 +22,23 @@ class AbstractStream {
virtual void handleError() = 0; virtual void handleError() = 0;
}; };
AbstractStream(Client* client, unsigned size): AbstractStream(Client* client, unsigned size)
client(client), size(size), position_(0) : client(client), size(size), position_(0)
{ } {
}
unsigned position() { unsigned position()
{
return position_; return position_;
} }
void setPosition(unsigned p) { void setPosition(unsigned p)
{
position_ = p; position_ = p;
} }
void skip(unsigned size) { void skip(unsigned size)
{
if (size > this->size - position_) { if (size > this->size - position_) {
client->handleError(); client->handleError();
} else { } else {
@ -42,7 +46,8 @@ class AbstractStream {
} }
} }
void read(uint8_t* dst, unsigned size) { void read(uint8_t* dst, unsigned size)
{
if (size > this->size - position_) { if (size > this->size - position_) {
memset(dst, 0, size); memset(dst, 0, size);
@ -53,35 +58,41 @@ class AbstractStream {
} }
} }
uint8_t read1() { uint8_t read1()
{
uint8_t v; uint8_t v;
read(&v, 1); read(&v, 1);
return v; return v;
} }
uint16_t read2() { uint16_t read2()
{
uint16_t a = read1(); uint16_t a = read1();
uint16_t b = read1(); uint16_t b = read1();
return (a << 8) | b; return (a << 8) | b;
} }
uint32_t read4() { uint32_t read4()
{
uint32_t a = read2(); uint32_t a = read2();
uint32_t b = read2(); uint32_t b = read2();
return (a << 16) | b; return (a << 16) | b;
} }
uint64_t read8() { uint64_t read8()
{
uint64_t a = read4(); uint64_t a = read4();
uint64_t b = read4(); uint64_t b = read4();
return (a << 32) | b; return (a << 32) | b;
} }
uint32_t readFloat() { uint32_t readFloat()
{
return read4(); return read4();
} }
uint64_t readDouble() { uint64_t readDouble()
{
return read8(); return read8();
} }
@ -94,14 +105,16 @@ class AbstractStream {
unsigned position_; unsigned position_;
}; };
class Stream: public AbstractStream { class Stream : public AbstractStream {
public: public:
Stream(Client* client, const uint8_t* data, unsigned size): Stream(Client* client, const uint8_t* data, unsigned size)
AbstractStream(client, size), data(data) : AbstractStream(client, size), data(data)
{ } {
}
private: private:
virtual void copy(uint8_t* dst, unsigned offset, unsigned size) { virtual void copy(uint8_t* dst, unsigned offset, unsigned size)
{
memcpy(dst, data + offset, size); memcpy(dst, data + offset, size);
} }
@ -110,4 +123,4 @@ class Stream: public AbstractStream {
} // namespace vm } // namespace vm
#endif//STREAM_H #endif // STREAM_H

View File

@ -17,38 +17,43 @@ namespace avian {
namespace util { namespace util {
class String { class String {
public: public:
const char* text; const char* text;
size_t length; size_t length;
String(const char* text): String(const char* text) : text(text), length(strlen(text))
text(text), {
length(strlen(text)) {} }
inline String(const char* text, size_t length): inline String(const char* text, size_t length) : text(text), length(length)
text(text), {
length(length) {} }
}; };
class Tokenizer { class Tokenizer {
public: public:
Tokenizer(const char* s, char delimiter)
: s(s), limit(0), delimiter(delimiter)
{
}
Tokenizer(const char* s, char delimiter): Tokenizer(String str, char delimiter)
s(s), limit(0), delimiter(delimiter) : s(str.text), limit(str.text + str.length), delimiter(delimiter)
{ } {
}
Tokenizer(String str, char delimiter): bool hasMore()
s(str.text), limit(str.text + str.length), delimiter(delimiter) {
{ } while (s != limit and *s == delimiter)
++s;
bool hasMore() {
while (s != limit and *s == delimiter) ++s;
return s != limit and *s != 0; return s != limit and *s != 0;
} }
String next() { String next()
{
const char* p = s; const char* p = s;
while (s != limit and *s and *s != delimiter) ++s; while (s != limit and *s and *s != delimiter)
++s;
return String(p, s - p); return String(p, s - p);
} }
@ -60,4 +65,4 @@ class Tokenizer {
} // namespace util } // namespace util
} // namespace avain } // namespace avain
#endif//AVIAN_UTIL_STRING_H #endif // AVIAN_UTIL_STRING_H

View File

@ -11,8 +11,7 @@ struct JniConstants {
static void init(_JNIEnv* env); static void init(_JNIEnv* env);
}; };
void void JniConstants::init(_JNIEnv*)
JniConstants::init(_JNIEnv*)
{ {
// ignore // ignore
} }

View File

@ -33,13 +33,16 @@ class Vector {
data(0, 0), data(0, 0),
position(0), position(0),
minimumCapacity(minimumCapacity) minimumCapacity(minimumCapacity)
{ } {
}
~Vector() { ~Vector()
{
dispose(); dispose();
} }
void dispose() { void dispose()
{
if (data.items and minimumCapacity > 0) { if (data.items and minimumCapacity > 0) {
allocator->free(data.items, data.count); allocator->free(data.items, data.count);
data.items = 0; data.items = 0;
@ -95,27 +98,33 @@ class Vector {
return r; return r;
} }
void append(uint8_t v) { void append(uint8_t v)
{
append(&v, 1); append(&v, 1);
} }
void append2(uint16_t v) { void append2(uint16_t v)
{
append(&v, 2); append(&v, 2);
} }
void append4(uint32_t v) { void append4(uint32_t v)
{
append(&v, 4); append(&v, 4);
} }
void appendTargetAddress(target_uintptr_t v) { void appendTargetAddress(target_uintptr_t v)
{
append(&v, TargetBytesPerWord); append(&v, TargetBytesPerWord);
} }
void appendAddress(uintptr_t v) { void appendAddress(uintptr_t v)
{
append(&v, BytesPerWord); append(&v, BytesPerWord);
} }
void appendAddress(void* v) { void appendAddress(void* v)
{
append(&v, BytesPerWord); append(&v, BytesPerWord);
} }
@ -127,25 +136,29 @@ class Vector {
size_t get(size_t offset) size_t get(size_t offset)
{ {
uint8_t v; get(offset, &v, 1); uint8_t v;
get(offset, &v, 1);
return v; return v;
} }
size_t get2(size_t offset) size_t get2(size_t offset)
{ {
uint16_t v; get(offset, &v, 2); uint16_t v;
get(offset, &v, 2);
return v; return v;
} }
size_t get4(size_t offset) size_t get4(size_t offset)
{ {
uint32_t v; get(offset, &v, 4); uint32_t v;
get(offset, &v, 4);
return v; return v;
} }
uintptr_t getAddress(size_t offset) uintptr_t getAddress(size_t offset)
{ {
uintptr_t v; get(offset, &v, BytesPerWord); uintptr_t v;
get(offset, &v, BytesPerWord);
return v; return v;
} }
@ -170,4 +183,4 @@ class Vector {
} // namespace vm } // namespace vm
#endif//VECTOR_H #endif // VECTOR_H

View File

@ -12,39 +12,41 @@
#define ARCH_H #define ARCH_H
#ifdef _MSC_VER #ifdef _MSC_VER
# include "windows.h" #include "windows.h"
# pragma push_macro("assert") #pragma push_macro("assert")
# include "intrin.h" #include "intrin.h"
# pragma pop_macro("assert") #pragma pop_macro("assert")
# undef interface #undef interface
#endif #endif
#include "avian/common.h" #include "avian/common.h"
extern "C" void NO_RETURN extern "C" void NO_RETURN vmJump(void* address,
vmJump(void* address, void* frame, void* stack, void* thread, void* frame,
uintptr_t returnLow, uintptr_t returnHigh); void* stack,
void* thread,
uintptr_t returnLow,
uintptr_t returnHigh);
namespace vm { namespace vm {
inline void inline void compileTimeMemoryBarrier()
compileTimeMemoryBarrier()
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
_ReadWriteBarrier(); _ReadWriteBarrier();
#else #else
__asm__ __volatile__("": : :"memory"); __asm__ __volatile__("" : : : "memory");
#endif #endif
} }
} // namespace vm } // namespace vm
#if (defined ARCH_x86_32) || (defined ARCH_x86_64) #if (defined ARCH_x86_32) || (defined ARCH_x86_64)
# include "x86.h" #include "x86.h"
#elif defined ARCH_arm #elif defined ARCH_arm
# include "arm.h" #include "arm.h"
#else #else
# error unsupported architecture #error unsupported architecture
#endif #endif
#endif//ARCH_H #endif // ARCH_H

View File

@ -16,61 +16,62 @@
#include <avian/util/runtime-array.h> #include <avian/util/runtime-array.h>
#ifdef __APPLE__ #ifdef __APPLE__
# include "libkern/OSAtomic.h" #include "libkern/OSAtomic.h"
# include "libkern/OSCacheControl.h" #include "libkern/OSCacheControl.h"
# include "mach/mach_types.h" #include "mach/mach_types.h"
# include "mach/thread_act.h" #include "mach/thread_act.h"
# include "mach/thread_status.h" #include "mach/thread_status.h"
# define THREAD_STATE ARM_THREAD_STATE #define THREAD_STATE ARM_THREAD_STATE
# define THREAD_STATE_TYPE arm_thread_state_t #define THREAD_STATE_TYPE arm_thread_state_t
# define THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT #define THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT
# if __DARWIN_UNIX03 && defined(_STRUCT_ARM_EXCEPTION_STATE) #if __DARWIN_UNIX03 && defined(_STRUCT_ARM_EXCEPTION_STATE)
# define FIELD(x) __##x #define FIELD(x) __##x
# else
# define FIELD(x) x
# endif
# define THREAD_STATE_IP(state) ((state).FIELD(pc))
# define THREAD_STATE_STACK(state) ((state).FIELD(sp))
# define THREAD_STATE_THREAD(state) ((state).FIELD(r[8]))
# define THREAD_STATE_LINK(state) ((state).FIELD(lr))
# define IP_REGISTER(context) \
THREAD_STATE_IP(context->uc_mcontext->FIELD(ss))
# define STACK_REGISTER(context) \
THREAD_STATE_STACK(context->uc_mcontext->FIELD(ss))
# define THREAD_REGISTER(context) \
THREAD_STATE_THREAD(context->uc_mcontext->FIELD(ss))
# define LINK_REGISTER(context) \
THREAD_STATE_LINK(context->uc_mcontext->FIELD(ss))
#elif (defined __QNX__)
# include "arm/smpxchg.h"
# include "sys/mman.h"
# define IP_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_PC])
# define STACK_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_SP])
# define THREAD_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_IP])
# define LINK_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_LR])
#else #else
# define IP_REGISTER(context) (context->uc_mcontext.arm_pc) #define FIELD(x) x
# define STACK_REGISTER(context) (context->uc_mcontext.arm_sp) #endif
# define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip)
# define LINK_REGISTER(context) (context->uc_mcontext.arm_lr) #define THREAD_STATE_IP(state) ((state).FIELD(pc))
#define THREAD_STATE_STACK(state) ((state).FIELD(sp))
#define THREAD_STATE_THREAD(state) ((state).FIELD(r[8]))
#define THREAD_STATE_LINK(state) ((state).FIELD(lr))
#define IP_REGISTER(context) THREAD_STATE_IP(context->uc_mcontext->FIELD(ss))
#define STACK_REGISTER(context) \
THREAD_STATE_STACK(context->uc_mcontext->FIELD(ss))
#define THREAD_REGISTER(context) \
THREAD_STATE_THREAD(context->uc_mcontext->FIELD(ss))
#define LINK_REGISTER(context) \
THREAD_STATE_LINK(context->uc_mcontext->FIELD(ss))
#elif(defined __QNX__)
#include "arm/smpxchg.h"
#include "sys/mman.h"
#define IP_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_PC])
#define STACK_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_SP])
#define THREAD_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_IP])
#define LINK_REGISTER(context) (context->uc_mcontext.cpu.gpr[ARM_REG_LR])
#else
#define IP_REGISTER(context) (context->uc_mcontext.arm_pc)
#define STACK_REGISTER(context) (context->uc_mcontext.arm_sp)
#define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip)
#define LINK_REGISTER(context) (context->uc_mcontext.arm_lr)
#endif #endif
#define VA_LIST(x) (&(x)) #define VA_LIST(x) (&(x))
extern "C" uint64_t extern "C" uint64_t vmNativeCall(void* function,
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable, unsigned stackTotal,
unsigned memoryCount, void* gprTable, void* vfpTable, void* memoryTable,
unsigned memoryCount,
void* gprTable,
void* vfpTable,
unsigned returnType); unsigned returnType);
namespace vm { namespace vm {
inline void inline void trap()
trap()
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
__debugbreak(); __debugbreak();
@ -86,23 +87,21 @@ trap()
// performant choice. // performant choice.
#ifndef _MSC_VER #ifndef _MSC_VER
inline void inline void memoryBarrier()
memoryBarrier()
{ {
#ifdef __APPLE__ #ifdef __APPLE__
OSMemoryBarrier(); OSMemoryBarrier();
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1) #elif(__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
return __sync_synchronize(); return __sync_synchronize();
#elif (! defined AVIAN_ASSUME_ARMV6) #elif(!defined AVIAN_ASSUME_ARMV6)
__asm__ __volatile__ ("dmb" : : : "memory"); __asm__ __volatile__("dmb" : : : "memory");
#else #else
__asm__ __volatile__ ("" : : : "memory"); __asm__ __volatile__("" : : : "memory");
#endif #endif
} }
#endif #endif
inline void inline void storeStoreMemoryBarrier()
storeStoreMemoryBarrier()
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
_ReadWriteBarrier(); _ReadWriteBarrier();
@ -111,8 +110,7 @@ storeStoreMemoryBarrier()
#endif #endif
} }
inline void inline void storeLoadMemoryBarrier()
storeLoadMemoryBarrier()
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
MemoryBarrier(); MemoryBarrier();
@ -121,8 +119,7 @@ storeLoadMemoryBarrier()
#endif #endif
} }
inline void inline void loadMemoryBarrier()
loadMemoryBarrier()
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
_ReadWriteBarrier(); _ReadWriteBarrier();
@ -135,18 +132,18 @@ loadMemoryBarrier()
#if defined(__ANDROID__) #if defined(__ANDROID__)
// http://code.google.com/p/android/issues/detail?id=1803 // http://code.google.com/p/android/issues/detail?id=1803
extern "C" void __clear_cache (void *beg __attribute__((__unused__)), void *end __attribute__((__unused__))); extern "C" void __clear_cache(void* beg __attribute__((__unused__)),
void* end __attribute__((__unused__)));
#endif #endif
inline void inline void syncInstructionCache(const void* start, unsigned size)
syncInstructionCache(const void* start, unsigned size)
{ {
#ifdef __APPLE__ #ifdef __APPLE__
sys_icache_invalidate(const_cast<void*>(start), size); sys_icache_invalidate(const_cast<void*>(start), size);
#elif (defined __QNX__) #elif(defined __QNX__)
msync(const_cast<void*>(start), size, MS_INVALIDATE_ICACHE); msync(const_cast<void*>(start), size, MS_INVALIDATE_ICACHE);
#else #else
__clear_cache __clear_cache(
(const_cast<void*>(start), const_cast<void*>(start),
const_cast<uint8_t*>(static_cast<const uint8_t*>(start) + size)); const_cast<uint8_t*>(static_cast<const uint8_t*>(start) + size));
#endif #endif
} }
@ -154,32 +151,34 @@ syncInstructionCache(const void* start, unsigned size)
#endif // AVIAN_AOT_ONLY #endif // AVIAN_AOT_ONLY
#ifndef __APPLE__ #ifndef __APPLE__
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr); typedef int(__kernel_cmpxchg_t)(int oldval, int newval, int* ptr);
# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) #define __kernel_cmpxchg (*(__kernel_cmpxchg_t*)0xffff0fc0)
#endif #endif
inline bool inline bool atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
{ {
#ifdef __APPLE__ #ifdef __APPLE__
return OSAtomicCompareAndSwap32Barrier(old, new_, reinterpret_cast<int32_t*>(p)); return OSAtomicCompareAndSwap32Barrier(
#elif (defined __QNX__) old, new_, reinterpret_cast<int32_t*>(p));
#elif(defined __QNX__)
return old == _smp_cmpxchg(p, old, new_); return old == _smp_cmpxchg(p, old, new_);
#else #else
int r = __kernel_cmpxchg(static_cast<int>(old), static_cast<int>(new_), reinterpret_cast<int*>(p)); int r = __kernel_cmpxchg(
static_cast<int>(old), static_cast<int>(new_), reinterpret_cast<int*>(p));
return (!r ? true : false); return (!r ? true : false);
#endif #endif
} }
inline bool inline bool atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
{ {
return atomicCompareAndSwap32(reinterpret_cast<uint32_t*>(p), old, new_); return atomicCompareAndSwap32(reinterpret_cast<uint32_t*>(p), old, new_);
} }
inline uint64_t inline uint64_t dynamicCall(void* function,
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes, uintptr_t* arguments,
unsigned argumentCount, unsigned argumentsSize UNUSED, uint8_t* argumentTypes,
unsigned argumentCount,
unsigned argumentsSize UNUSED,
unsigned returnType) unsigned returnType)
{ {
#ifdef __APPLE__ #ifdef __APPLE__
@ -197,11 +196,14 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned vfpIndex = 0; unsigned vfpIndex = 0;
unsigned vfpBackfillIndex UNUSED = 0; unsigned vfpBackfillIndex UNUSED = 0;
RUNTIME_ARRAY(uintptr_t, stack, (argumentCount * 8) / BytesPerWord); // is > argumentSize to account for padding RUNTIME_ARRAY(uintptr_t,
stack,
(argumentCount * 8)
/ BytesPerWord); // is > argumentSize to account for padding
unsigned stackIndex = 0; unsigned stackIndex = 0;
unsigned ai = 0; unsigned ai = 0;
for (unsigned ati = 0; ati < argumentCount; ++ ati) { for (unsigned ati = 0; ati < argumentCount; ++ati) {
switch (argumentTypes[ati]) { switch (argumentTypes[ati]) {
case DOUBLE_TYPE: case DOUBLE_TYPE:
#if defined(__ARM_PCS_VFP) #if defined(__ARM_PCS_VFP)
@ -209,7 +211,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
if (vfpIndex + Alignment <= VfpCount) { if (vfpIndex + Alignment <= VfpCount) {
if (vfpIndex % Alignment) { if (vfpIndex % Alignment) {
vfpBackfillIndex = vfpIndex; vfpBackfillIndex = vfpIndex;
++ vfpIndex; ++vfpIndex;
} }
memcpy(vfpTable + vfpIndex, arguments + ai, 8); memcpy(vfpTable + vfpIndex, arguments + ai, 8);
@ -217,7 +219,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
} else { } else {
vfpIndex = VfpCount; vfpIndex = VfpCount;
if (stackIndex % Alignment) { if (stackIndex % Alignment) {
++ stackIndex; ++stackIndex;
} }
memcpy(RUNTIME_ARRAY_BODY(stack) + stackIndex, arguments + ai, 8); memcpy(RUNTIME_ARRAY_BODY(stack) + stackIndex, arguments + ai, 8);
@ -235,15 +237,13 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
} else { } else {
RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai]; RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai];
} }
++ ai; ++ai;
break; break;
#endif #endif
case INT64_TYPE: { case INT64_TYPE: {
if (gprIndex + Alignment <= GprCount) { // pass argument in register(s) if (gprIndex + Alignment <= GprCount) { // pass argument in register(s)
if (Alignment == 1 if (Alignment == 1 and BytesPerWord < 8
and BytesPerWord < 8 and gprIndex + Alignment == GprCount) {
and gprIndex + Alignment == GprCount)
{
gprTable[gprIndex++] = arguments[ai]; gprTable[gprIndex++] = arguments[ai];
RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai + 1]; RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai + 1];
} else { } else {
@ -272,25 +272,28 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
} else { } else {
RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai]; RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai];
} }
++ ai; ++ai;
} break; } break;
} }
} }
if (gprIndex < GprCount) { // pad since assembly loads all GPRs if (gprIndex < GprCount) { // pad since assembly loads all GPRs
memset(gprTable + gprIndex, 0, (GprCount-gprIndex)*4); memset(gprTable + gprIndex, 0, (GprCount - gprIndex) * 4);
gprIndex = GprCount; gprIndex = GprCount;
} }
if (vfpIndex < VfpCount) { if (vfpIndex < VfpCount) {
memset(vfpTable + vfpIndex, 0, (VfpCount-vfpIndex)*4); memset(vfpTable + vfpIndex, 0, (VfpCount - vfpIndex) * 4);
vfpIndex = VfpCount; vfpIndex = VfpCount;
} }
unsigned stackSize = stackIndex*BytesPerWord + ((stackIndex & 1) << 2); unsigned stackSize = stackIndex * BytesPerWord + ((stackIndex & 1) << 2);
return vmNativeCall return vmNativeCall(function,
(function, stackSize, RUNTIME_ARRAY_BODY(stack), stackIndex * BytesPerWord, stackSize,
RUNTIME_ARRAY_BODY(stack),
stackIndex * BytesPerWord,
(gprIndex ? gprTable : 0), (gprIndex ? gprTable : 0),
(vfpIndex ? vfpTable : 0), returnType); (vfpIndex ? vfpTable : 0),
returnType);
} }
} // namespace vm } // namespace vm

View File

@ -24,13 +24,14 @@ class BootImage {
public: public:
class Thunk { class Thunk {
public: public:
Thunk(): Thunk() : start(0), frameSavedOffset(0), length(0)
start(0), frameSavedOffset(0), length(0) {
{ } }
Thunk(uint32_t start, uint32_t frameSavedOffset, uint32_t length): Thunk(uint32_t start, uint32_t frameSavedOffset, uint32_t length)
start(start), frameSavedOffset(frameSavedOffset), length(length) : start(start), frameSavedOffset(frameSavedOffset), length(length)
{ } {
}
uint32_t start; uint32_t start;
uint32_t frameSavedOffset; uint32_t frameSavedOffset;
@ -74,4 +75,4 @@ class OffsetResolver {
} // namespace vm } // namespace vm
#endif//BOOTIMAGE_H #endif // BOOTIMAGE_H

View File

@ -18,16 +18,16 @@ using namespace avian::util;
namespace vm { namespace vm {
object object getTrace(Thread* t, unsigned skipCount)
getTrace(Thread* t, unsigned skipCount)
{ {
class Visitor: public Processor::StackVisitor { class Visitor : public Processor::StackVisitor {
public: public:
Visitor(Thread* t, int skipCount): Visitor(Thread* t, int skipCount) : t(t), trace(0), skipCount(skipCount)
t(t), trace(0), skipCount(skipCount) {
{ } }
virtual bool visit(Processor::StackWalker* walker) { virtual bool visit(Processor::StackWalker* walker)
{
if (skipCount == 0) { if (skipCount == 0) {
GcMethod* method = walker->method(); GcMethod* method = walker->method();
if (isAssignableFrom(t, type(t, GcThrowable::Type), method->class_()) if (isAssignableFrom(t, type(t, GcThrowable::Type), method->class_())
@ -39,7 +39,7 @@ getTrace(Thread* t, unsigned skipCount)
return false; return false;
} }
} else { } else {
-- skipCount; --skipCount;
return true; return true;
} }
} }
@ -51,7 +51,8 @@ getTrace(Thread* t, unsigned skipCount)
t->m->processor->walkStack(t, &v); t->m->processor->walkStack(t, &v);
if (v.trace == 0) v.trace = makeObjectArray(t, 0); if (v.trace == 0)
v.trace = makeObjectArray(t, 0);
return v.trace; return v.trace;
} }
@ -63,23 +64,24 @@ bool compatibleArrayTypes(Thread* t UNUSED, GcClass* a, GcClass* b)
or (b->vmFlags() & PrimitiveFlag)))); or (b->vmFlags() & PrimitiveFlag))));
} }
void void arrayCopy(Thread* t,
arrayCopy(Thread* t, object src, int32_t srcOffset, object dst, object src,
int32_t dstOffset, int32_t length) int32_t srcOffset,
object dst,
int32_t dstOffset,
int32_t length)
{ {
if (LIKELY(src and dst)) { if (LIKELY(src and dst)) {
if (LIKELY(compatibleArrayTypes if (LIKELY(compatibleArrayTypes(
(t, objectClass(t, src), objectClass(t, dst)))) t, objectClass(t, src), objectClass(t, dst)))) {
{
unsigned elementSize = objectClass(t, src)->arrayElementSize(); unsigned elementSize = objectClass(t, src)->arrayElementSize();
if (LIKELY(elementSize)) { if (LIKELY(elementSize)) {
intptr_t sl = fieldAtOffset<uintptr_t>(src, BytesPerWord); intptr_t sl = fieldAtOffset<uintptr_t>(src, BytesPerWord);
intptr_t dl = fieldAtOffset<uintptr_t>(dst, BytesPerWord); intptr_t dl = fieldAtOffset<uintptr_t>(dst, BytesPerWord);
if (LIKELY(length > 0)) { if (LIKELY(length > 0)) {
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl
dstOffset >= 0 and dstOffset + length <= dl)) and dstOffset >= 0 and dstOffset + length <= dl)) {
{
uint8_t* sbody = &fieldAtOffset<uint8_t>(src, ArrayBody); uint8_t* sbody = &fieldAtOffset<uint8_t>(src, ArrayBody);
uint8_t* dbody = &fieldAtOffset<uint8_t>(dst, ArrayBody); uint8_t* dbody = &fieldAtOffset<uint8_t>(dst, ArrayBody);
if (src == dst) { if (src == dst) {
@ -113,8 +115,7 @@ arrayCopy(Thread* t, object src, int32_t srcOffset, object dst,
throwNew(t, GcArrayStoreException::Type); throwNew(t, GcArrayStoreException::Type);
} }
void void runOnLoadIfFound(Thread* t, System::Library* library)
runOnLoadIfFound(Thread* t, System::Library* library)
{ {
void* p = library->resolve("JNI_OnLoad"); void* p = library->resolve("JNI_OnLoad");
@ -128,14 +129,13 @@ runOnLoadIfFound(Thread* t, System::Library* library)
#endif #endif
if (p) { if (p) {
jint (JNICALL * JNI_OnLoad)(Machine*, void*); jint(JNICALL * JNI_OnLoad)(Machine*, void*);
memcpy(&JNI_OnLoad, &p, sizeof(void*)); memcpy(&JNI_OnLoad, &p, sizeof(void*));
JNI_OnLoad(t->m, 0); JNI_OnLoad(t->m, 0);
} }
} }
System::Library* System::Library* loadLibrary(Thread* t, const char* name)
loadLibrary(Thread* t, const char* name)
{ {
ACQUIRE(t, t->m->classLock); ACQUIRE(t, t->m->classLock);
@ -157,9 +157,12 @@ loadLibrary(Thread* t, const char* name)
} }
} }
System::Library* System::Library* loadLibrary(Thread* t,
loadLibrary(Thread* t, const char* path, const char* name, bool mapName, const char* path,
bool runOnLoad, bool throw_ = true) const char* name,
bool mapName,
bool runOnLoad,
bool throw_ = true)
{ {
ACQUIRE(t, t->m->classLock); ACQUIRE(t, t->m->classLock);
@ -171,8 +174,7 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
const char* s = builtins; const char* s = builtins;
while (*s) { while (*s) {
if (::strncmp(s, name, nameLength) == 0 if (::strncmp(s, name, nameLength) == 0
and (s[nameLength] == ',' or s[nameLength] == 0)) and (s[nameLength] == ',' or s[nameLength] == 0)) {
{
// library is built in to this executable // library is built in to this executable
if (runOnLoad and not t->m->triedBuiltinOnLoad) { if (runOnLoad and not t->m->triedBuiltinOnLoad) {
t->m->triedBuiltinOnLoad = true; t->m->triedBuiltinOnLoad = true;
@ -182,8 +184,10 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
} }
return t->m->libraries; return t->m->libraries;
} else { } else {
while (*s and *s != ',') ++ s; while (*s and *s != ',')
if (*s) ++ s; ++s;
if (*s)
++s;
} }
} }
} }
@ -192,8 +196,7 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
const char* suffix = t->m->system->librarySuffix(); const char* suffix = t->m->system->librarySuffix();
unsigned mappedNameLength = nameLength + strlen(prefix) + strlen(suffix); unsigned mappedNameLength = nameLength + strlen(prefix) + strlen(suffix);
mappedName = static_cast<char*> mappedName = static_cast<char*>(t->m->heap->allocate(mappedNameLength + 1));
(t->m->heap->allocate(mappedNameLength + 1));
snprintf(mappedName, mappedNameLength + 1, "%s%s%s", prefix, name, suffix); snprintf(mappedName, mappedNameLength + 1, "%s%s%s", prefix, name, suffix);
@ -203,25 +206,28 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
mappedName = 0; mappedName = 0;
} }
THREAD_RESOURCE2 THREAD_RESOURCE2(t, char*, mappedName, unsigned, nameLength, if (mappedName) {
(t, char*, mappedName, unsigned, nameLength, if (mappedName) {
t->m->heap->free(mappedName, nameLength + 1); t->m->heap->free(mappedName, nameLength + 1);
}); });
System::Library* lib = 0; System::Library* lib = 0;
for (Tokenizer tokenizer(path, t->m->system->pathSeparator()); for (Tokenizer tokenizer(path, t->m->system->pathSeparator());
tokenizer.hasMore();) tokenizer.hasMore();) {
{
String token(tokenizer.next()); String token(tokenizer.next());
unsigned fullNameLength = token.length + 1 + nameLength; unsigned fullNameLength = token.length + 1 + nameLength;
THREAD_RUNTIME_ARRAY(t, char, fullName, fullNameLength + 1); THREAD_RUNTIME_ARRAY(t, char, fullName, fullNameLength + 1);
snprintf(RUNTIME_ARRAY_BODY(fullName), fullNameLength + 1, snprintf(RUNTIME_ARRAY_BODY(fullName),
"%.*s/%s", token.length, token.text, name); fullNameLength + 1,
"%.*s/%s",
token.length,
token.text,
name);
lib = loadLibrary(t, RUNTIME_ARRAY_BODY(fullName)); lib = loadLibrary(t, RUNTIME_ARRAY_BODY(fullName));
if (lib) break; if (lib)
break;
} }
if (lib == 0) { if (lib == 0) {
@ -243,8 +249,7 @@ loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
return lib; return lib;
} }
object object clone(Thread* t, object o)
clone(Thread* t, object o)
{ {
PROTECT(t, o); PROTECT(t, o);
@ -396,10 +401,10 @@ GcPair* resolveParameterTypes(Thread* t,
switch (spec->body()[offset]) { switch (spec->body()[offset]) {
case 'L': { case 'L': {
unsigned start = offset; unsigned start = offset;
++ offset; ++offset;
while (spec->body()[offset] != ';') while (spec->body()[offset] != ';')
++offset; ++offset;
++ offset; ++offset;
GcClass* type GcClass* type
= resolveClassBySpec(t, = resolveClassBySpec(t,
@ -409,7 +414,7 @@ GcPair* resolveParameterTypes(Thread* t,
list = makePair(t, type, list); list = makePair(t, type, list);
++ count; ++count;
} break; } break;
case '[': { case '[': {
@ -418,14 +423,14 @@ GcPair* resolveParameterTypes(Thread* t,
++offset; ++offset;
switch (spec->body()[offset]) { switch (spec->body()[offset]) {
case 'L': case 'L':
++ offset; ++offset;
while (spec->body()[offset] != ';') while (spec->body()[offset] != ';')
++offset; ++offset;
++ offset; ++offset;
break; break;
default: default:
++ offset; ++offset;
break; break;
} }
@ -436,13 +441,13 @@ GcPair* resolveParameterTypes(Thread* t,
offset - start); offset - start);
list = makePair(t, type, list); list = makePair(t, type, list);
++ count; ++count;
} break; } break;
default: default:
list = makePair(t, primitiveClass(t, spec->body()[offset]), list); list = makePair(t, primitiveClass(t, spec->body()[offset]), list);
++ offset; ++offset;
++ count; ++count;
break; break;
} }
} }
@ -570,7 +575,7 @@ object invoke(Thread* t, GcMethod* method, object instance, object args)
objectType = true; objectType = true;
unsigned nameLength; unsigned nameLength;
if (*p == 'L') { if (*p == 'L') {
++ p; ++p;
nameLength = it.s - p; nameLength = it.s - p;
} else { } else {
nameLength = (it.s - p) + 1; nameLength = (it.s - p) + 1;
@ -588,9 +593,10 @@ object invoke(Thread* t, GcMethod* method, object instance, object args)
object arg = objectArrayBody(t, args, i++); object arg = objectArrayBody(t, args, i++);
if ((arg == 0 and (not objectType)) if ((arg == 0 and (not objectType))
or (arg and (not instanceOf(t, type, arg)))) or (arg and (not instanceOf(t, type, arg)))) {
{ // fprintf(stderr, "%s is not a %s\n", arg ? &byteArrayBody(t,
// fprintf(stderr, "%s is not a %s\n", arg ? &byteArrayBody(t, className(t, objectClass(t, arg)), 0) : reinterpret_cast<const int8_t*>("<null>"), &byteArrayBody(t, className(t, type), 0)); // className(t, objectClass(t, arg)), 0) : reinterpret_cast<const
// int8_t*>("<null>"), &byteArrayBody(t, className(t, type), 0));
throwNew(t, GcIllegalArgumentException::Type); throwNew(t, GcIllegalArgumentException::Type);
} }
@ -664,8 +670,7 @@ void intercept(Thread* t,
} }
} }
Finder* Finder* getFinder(Thread* t, const char* name, unsigned nameLength)
getFinder(Thread* t, const char* name, unsigned nameLength)
{ {
ACQUIRE(t, t->m->referenceLock); ACQUIRE(t, t->m->referenceLock);
@ -718,7 +723,7 @@ object getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
GcByteArray* outer = reference->outer(); GcByteArray* outer = reference->outer();
if (outer and byteArrayEqual(t, outer, c->name()) if (outer and byteArrayEqual(t, outer, c->name())
and ((not publicOnly) or (reference->flags() & ACC_PUBLIC))) { and ((not publicOnly) or (reference->flags() & ACC_PUBLIC))) {
++ count; ++count;
} }
} }
@ -734,7 +739,7 @@ object getDeclaredClasses(Thread* t, GcClass* c, bool publicOnly)
object inner object inner
= getJClass(t, resolveClass(t, c->loader(), reference->inner())); = getJClass(t, resolveClass(t, c->loader(), reference->inner()));
-- count; --count;
reinterpret_cast<GcArray*>(result)->setBodyElement(t, count, inner); reinterpret_cast<GcArray*>(result)->setBodyElement(t, count, inner);
} }
} }
@ -789,4 +794,4 @@ unsigned classModifiers(Thread* t, GcClass* c)
} // namespace vm } // namespace vm
#endif//CLASSPATH_COMMON_H #endif // CLASSPATH_COMMON_H

View File

@ -12,7 +12,7 @@
#define AVIAN_COMMON_H #define AVIAN_COMMON_H
#ifndef __STDC_CONSTANT_MACROS #ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS #define __STDC_CONSTANT_MACROS
#endif #endif
#include <new> #include <new>
@ -31,11 +31,11 @@
#include <stdint.h> #include <stdint.h>
#ifdef linux #ifdef linux
# undef linux #undef linux
#endif #endif
// don't complain about using 'this' in member initializers: // don't complain about using 'this' in member initializers:
# pragma warning(disable:4355) #pragma warning(disable : 4355)
#define strncasecmp _strnicmp #define strncasecmp _strnicmp
@ -43,9 +43,9 @@
#define FP_INFINITE 1 #define FP_INFINITE 1
#define FP_UNDEF 2 #define FP_UNDEF 2
inline int fpclassify(double d) { inline int fpclassify(double d)
{
switch(_fpclass(d)) { switch (_fpclass(d)) {
case _FPCLASS_SNAN: case _FPCLASS_SNAN:
case _FPCLASS_QNAN: case _FPCLASS_QNAN:
return FP_NAN; return FP_NAN;
@ -56,44 +56,45 @@ inline int fpclassify(double d) {
return FP_UNDEF; return FP_UNDEF;
} }
inline int signbit(double d) { inline int signbit(double d)
{
return _copysign(1.0, d) < 0; return _copysign(1.0, d) < 0;
} }
# define not ! #define not!
# define or || #define or ||
# define and && #define and &&
# define xor ^ #define xor ^
# define LIKELY(v) v #define LIKELY(v) v
# define UNLIKELY(v) v #define UNLIKELY(v) v
# define UNUSED #define UNUSED
# define NO_RETURN __declspec(noreturn) #define NO_RETURN __declspec(noreturn)
# define PACKED #define PACKED
# define PLATFORM_WINDOWS #define PLATFORM_WINDOWS
# ifdef _M_IX86 #ifdef _M_IX86
typedef int32_t intptr_t; typedef int32_t intptr_t;
typedef uint32_t uintptr_t; typedef uint32_t uintptr_t;
# define ARCH_x86_32 #define ARCH_x86_32
# define BYTES_PER_WORD 4 #define BYTES_PER_WORD 4
# elif defined _M_X64 #elif defined _M_X64
typedef int64_t intptr_t; typedef int64_t intptr_t;
typedef uint64_t uintptr_t; typedef uint64_t uintptr_t;
# define ARCH_x86_64 #define ARCH_x86_64
# define BYTES_PER_WORD 8 #define BYTES_PER_WORD 8
# elif defined _M_ARM_FP #elif defined _M_ARM_FP
typedef int32_t intptr_t; typedef int32_t intptr_t;
typedef uint32_t uintptr_t; typedef uint32_t uintptr_t;
# define ARCH_arm #define ARCH_arm
# define BYTES_PER_WORD 4 #define BYTES_PER_WORD 4
# else #else
# error "unsupported architecture" #error "unsupported architecture"
# endif #endif
namespace vm { namespace vm {
@ -103,32 +104,32 @@ typedef intptr_t intptr_alias_t;
#else // not _MSC_VER #else // not _MSC_VER
# include <stdint.h> #include <stdint.h>
# define BYTES_PER_WORD __SIZEOF_POINTER__ #define BYTES_PER_WORD __SIZEOF_POINTER__
# define LIKELY(v) __builtin_expect((v) != 0, true) #define LIKELY(v) __builtin_expect((v) != 0, true)
# define UNLIKELY(v) __builtin_expect((v) != 0, false) #define UNLIKELY(v) __builtin_expect((v) != 0, false)
# define UNUSED __attribute__((unused)) #define UNUSED __attribute__((unused))
# define NO_RETURN __attribute__((noreturn)) #define NO_RETURN __attribute__((noreturn))
# define PACKED __attribute__((packed)) #define PACKED __attribute__((packed))
# ifdef __MINGW32__ #ifdef __MINGW32__
# define PLATFORM_WINDOWS #define PLATFORM_WINDOWS
# endif #endif
# ifdef __i386__ #ifdef __i386__
# define ARCH_x86_32 #define ARCH_x86_32
# elif defined __x86_64__ #elif defined __x86_64__
# define ARCH_x86_64 #define ARCH_x86_64
# elif defined __arm__ #elif defined __arm__
# define ARCH_arm #define ARCH_arm
# else #else
# error "unsupported architecture" #error "unsupported architecture"
# endif #endif
namespace vm { namespace vm {
@ -139,58 +140,58 @@ typedef intptr_t __attribute__((__may_alias__)) intptr_alias_t;
#endif // not _MSC_VER #endif // not _MSC_VER
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# define AVIAN_EXPORT __declspec(dllexport) #define AVIAN_EXPORT __declspec(dllexport)
# define PATH_SEPARATOR ';' #define PATH_SEPARATOR ';'
#else // not PLATFORM_WINDOWS #else // not PLATFORM_WINDOWS
# define AVIAN_EXPORT __attribute__ ((visibility("default"))) \ #define AVIAN_EXPORT \
__attribute__ ((used)) __attribute__((visibility("default"))) __attribute__((used))
# define PATH_SEPARATOR ':' #define PATH_SEPARATOR ':'
#endif // not PLATFORM_WINDOWS #endif // not PLATFORM_WINDOWS
#if (defined ARCH_x86_32) || (defined ARCH_arm) #if (defined ARCH_x86_32) || (defined ARCH_arm)
# define LD "ld" #define LD "ld"
# if (defined _MSC_VER) || ((defined __MINGW32__) && __GNUC__ >= 4) #if (defined _MSC_VER) || ((defined __MINGW32__) && __GNUC__ >= 4)
# define LLD "I64d" #define LLD "I64d"
# else
# define LLD "lld"
# endif
# ifdef __APPLE__
# define ULD "lu"
# define LX "lx"
# else
# define LX "x"
# define ULD "u"
# endif
#elif defined ARCH_x86_64
# define LD "ld"
# define LX "lx"
# if (defined _MSC_VER) || (defined __MINGW32__)
# define LLD "I64d"
# define ULD "I64x"
# else
# ifdef __APPLE__
# define LLD "lld"
# else
# define LLD "ld"
# endif
# define ULD "lu"
# endif
#else #else
# error "Unsupported architecture" #define LLD "lld"
#endif
#ifdef __APPLE__
#define ULD "lu"
#define LX "lx"
#else
#define LX "x"
#define ULD "u"
#endif
#elif defined ARCH_x86_64
#define LD "ld"
#define LX "lx"
#if (defined _MSC_VER) || (defined __MINGW32__)
#define LLD "I64d"
#define ULD "I64x"
#else
#ifdef __APPLE__
#define LLD "lld"
#else
#define LLD "ld"
#endif
#define ULD "lu"
#endif
#else
#error "Unsupported architecture"
#endif #endif
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
# define SO_PREFIX "" #define SO_PREFIX ""
#else #else
# define SO_PREFIX "lib" #define SO_PREFIX "lib"
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
# define SO_SUFFIX ".dylib" #define SO_SUFFIX ".dylib"
#elif defined PLATFORM_WINDOWS #elif defined PLATFORM_WINDOWS
# define SO_SUFFIX ".dll" #define SO_SUFFIX ".dll"
#else #else
# define SO_SUFFIX ".so" #define SO_SUFFIX ".so"
#endif #endif
#define MACRO_XY(X, Y) X##Y #define MACRO_XY(X, Y) X##Y
@ -200,35 +201,37 @@ typedef intptr_t __attribute__((__may_alias__)) intptr_alias_t;
#define RESOURCE(type, name, release) \ #define RESOURCE(type, name, release) \
class MAKE_NAME(Resource_) { \ class MAKE_NAME(Resource_) { \
public: \ public: \
MAKE_NAME(Resource_)(type name): name(name) { } \ MAKE_NAME(Resource_)(type name) : name(name) \
~MAKE_NAME(Resource_)() { release; } \ { \
} \
~MAKE_NAME(Resource_)() \
{ \
release; \
} \
\ \
private: \ private: \
type name; \ type name; \
} MAKE_NAME(resource_)(name); } MAKE_NAME(resource_)(name);
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning( disable : 4291 ) #pragma warning(disable : 4291)
#endif #endif
namespace vm { namespace vm {
inline intptr_alias_t& inline intptr_alias_t& alias(void* p, unsigned offset)
alias(void* p, unsigned offset)
{ {
return *reinterpret_cast<intptr_alias_t*>(static_cast<uint8_t*>(p) + offset); return *reinterpret_cast<intptr_alias_t*>(static_cast<uint8_t*>(p) + offset);
} }
#ifdef _MSC_VER #ifdef _MSC_VER
inline int inline int vsnprintf(char* dst, size_t size, const char* format, va_list a)
vsnprintf(char* dst, size_t size, const char* format, va_list a)
{ {
return vsnprintf_s(dst, size, _TRUNCATE, format, a); return vsnprintf_s(dst, size, _TRUNCATE, format, a);
} }
inline int inline int snprintf(char* dst, size_t size, const char* format, ...)
snprintf(char* dst, size_t size, const char* format, ...)
{ {
va_list a; va_list a;
va_start(a, format); va_start(a, format);
@ -237,8 +240,7 @@ snprintf(char* dst, size_t size, const char* format, ...)
return r; return r;
} }
inline FILE* inline FILE* fopen(const char* name, const char* mode)
fopen(const char* name, const char* mode)
{ {
FILE* file; FILE* file;
if (fopen_s(&file, name, mode) == 0) { if (fopen_s(&file, name, mode) == 0) {
@ -250,14 +252,12 @@ fopen(const char* name, const char* mode)
#else // not _MSC_VER #else // not _MSC_VER
inline int inline int vsnprintf(char* dst, size_t size, const char* format, va_list a)
vsnprintf(char* dst, size_t size, const char* format, va_list a)
{ {
return ::vsnprintf(dst, size, format, a); return ::vsnprintf(dst, size, format, a);
} }
inline int inline int snprintf(char* dst, size_t size, const char* format, ...)
snprintf(char* dst, size_t size, const char* format, ...)
{ {
va_list a; va_list a;
va_start(a, format); va_start(a, format);
@ -266,8 +266,7 @@ snprintf(char* dst, size_t size, const char* format, ...)
return r; return r;
} }
inline FILE* inline FILE* fopen(const char* name, const char* mode)
fopen(const char* name, const char* mode)
{ {
return ::fopen(name, mode); return ::fopen(name, mode);
} }
@ -277,102 +276,92 @@ fopen(const char* name, const char* mode)
const unsigned BytesPerWord = sizeof(uintptr_t); const unsigned BytesPerWord = sizeof(uintptr_t);
const unsigned BitsPerWord = BytesPerWord * 8; const unsigned BitsPerWord = BytesPerWord * 8;
const uintptr_t PointerMask const uintptr_t PointerMask = ((~static_cast<uintptr_t>(0)) / BytesPerWord)
= ((~static_cast<uintptr_t>(0)) / BytesPerWord) * BytesPerWord; * BytesPerWord;
const unsigned LikelyPageSizeInBytes = 4 * 1024; const unsigned LikelyPageSizeInBytes = 4 * 1024;
inline unsigned inline unsigned pad(unsigned n, unsigned alignment)
pad(unsigned n, unsigned alignment)
{ {
return (n + (alignment - 1)) & ~(alignment - 1); return (n + (alignment - 1)) & ~(alignment - 1);
} }
inline unsigned inline unsigned pad(unsigned n)
pad(unsigned n)
{ {
return pad(n, BytesPerWord); return pad(n, BytesPerWord);
} }
inline uintptr_t inline uintptr_t padWord(uintptr_t n, uintptr_t alignment)
padWord(uintptr_t n, uintptr_t alignment)
{ {
return (n + (alignment - 1)) & ~(alignment - 1); return (n + (alignment - 1)) & ~(alignment - 1);
} }
inline uintptr_t inline uintptr_t padWord(uintptr_t n)
padWord(uintptr_t n)
{ {
return padWord(n, BytesPerWord); return padWord(n, BytesPerWord);
} }
inline bool fitsInInt8(int64_t v) { inline bool fitsInInt8(int64_t v)
{
return v == static_cast<int8_t>(v); return v == static_cast<int8_t>(v);
} }
inline bool fitsInInt16(int64_t v) { inline bool fitsInInt16(int64_t v)
{
return v == static_cast<int16_t>(v); return v == static_cast<int16_t>(v);
} }
inline bool fitsInInt32(int64_t v) { inline bool fitsInInt32(int64_t v)
{
return v == static_cast<int32_t>(v); return v == static_cast<int32_t>(v);
} }
template <class T> template <class T>
inline unsigned inline unsigned wordOf(unsigned i)
wordOf(unsigned i)
{ {
return i / (sizeof(T) * 8); return i / (sizeof(T) * 8);
} }
inline unsigned inline unsigned wordOf(unsigned i)
wordOf(unsigned i)
{ {
return wordOf<uintptr_t>(i); return wordOf<uintptr_t>(i);
} }
template <class T> template <class T>
inline unsigned inline unsigned bitOf(unsigned i)
bitOf(unsigned i)
{ {
return i % (sizeof(T) * 8); return i % (sizeof(T) * 8);
} }
inline unsigned inline unsigned bitOf(unsigned i)
bitOf(unsigned i)
{ {
return bitOf<uintptr_t>(i); return bitOf<uintptr_t>(i);
} }
template <class T> template <class T>
inline unsigned inline unsigned indexOf(unsigned word, unsigned bit)
indexOf(unsigned word, unsigned bit)
{ {
return (word * (sizeof(T) * 8)) + bit; return (word * (sizeof(T) * 8)) + bit;
} }
inline unsigned inline unsigned indexOf(unsigned word, unsigned bit)
indexOf(unsigned word, unsigned bit)
{ {
return indexOf<uintptr_t>(word, bit); return indexOf<uintptr_t>(word, bit);
} }
template <class T> template <class T>
inline void inline void markBit(T* map, unsigned i)
markBit(T* map, unsigned i)
{ {
map[wordOf<T>(i)] |= static_cast<T>(1) << bitOf<T>(i); map[wordOf<T>(i)] |= static_cast<T>(1) << bitOf<T>(i);
} }
template <class T> template <class T>
inline void inline void clearBit(T* map, unsigned i)
clearBit(T* map, unsigned i)
{ {
map[wordOf<T>(i)] &= ~(static_cast<T>(1) << bitOf<T>(i)); map[wordOf<T>(i)] &= ~(static_cast<T>(1) << bitOf<T>(i));
} }
template <class T> template <class T>
inline unsigned inline unsigned getBit(T* map, unsigned i)
getBit(T* map, unsigned i)
{ {
return (map[wordOf<T>(i)] & (static_cast<T>(1) << bitOf<T>(i))) return (map[wordOf<T>(i)] & (static_cast<T>(1) << bitOf<T>(i)))
>> bitOf<T>(i); >> bitOf<T>(i);
@ -383,8 +372,7 @@ getBit(T* map, unsigned i)
// a time: // a time:
template <class T> template <class T>
inline void inline void clearBits(T* map, unsigned bitsPerRecord, unsigned index)
clearBits(T* map, unsigned bitsPerRecord, unsigned index)
{ {
for (unsigned i = index, limit = index + bitsPerRecord; i < limit; ++i) { for (unsigned i = index, limit = index + bitsPerRecord; i < limit; ++i) {
clearBit<T>(map, i); clearBit<T>(map, i);
@ -392,18 +380,19 @@ clearBits(T* map, unsigned bitsPerRecord, unsigned index)
} }
template <class T> template <class T>
inline void inline void setBits(T* map, unsigned bitsPerRecord, int index, unsigned v)
setBits(T* map, unsigned bitsPerRecord, int index, unsigned v)
{ {
for (int i = index + bitsPerRecord - 1; i >= index; --i) { for (int i = index + bitsPerRecord - 1; i >= index; --i) {
if (v & 1) markBit<T>(map, i); else clearBit<T>(map, i); if (v & 1)
markBit<T>(map, i);
else
clearBit<T>(map, i);
v >>= 1; v >>= 1;
} }
} }
template <class T> template <class T>
inline unsigned inline unsigned getBits(T* map, unsigned bitsPerRecord, unsigned index)
getBits(T* map, unsigned bitsPerRecord, unsigned index)
{ {
unsigned v = 0; unsigned v = 0;
for (unsigned i = index, limit = index + bitsPerRecord; i < limit; ++i) { for (unsigned i = index, limit = index + bitsPerRecord; i < limit; ++i) {
@ -414,86 +403,80 @@ getBits(T* map, unsigned bitsPerRecord, unsigned index)
} }
template <class T> template <class T>
inline T& inline T& fieldAtOffset(void* p, unsigned offset)
fieldAtOffset(void* p, unsigned offset)
{ {
return *reinterpret_cast<T*>(static_cast<uint8_t*>(p) + offset); return *reinterpret_cast<T*>(static_cast<uint8_t*>(p) + offset);
} }
template <class T> template <class T>
inline T* inline T* maskAlignedPointer(T* p)
maskAlignedPointer(T* p)
{ {
return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(p) & PointerMask); return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(p) & PointerMask);
} }
inline void inline void write4(uint8_t* dst, uint32_t v)
write4(uint8_t* dst, uint32_t v)
{ {
memcpy(dst, &v, 4); memcpy(dst, &v, 4);
} }
inline uint32_t inline uint32_t floatToBits(float f)
floatToBits(float f)
{ {
uint32_t bits; memcpy(&bits, &f, 4); uint32_t bits;
memcpy(&bits, &f, 4);
return bits; return bits;
} }
inline uint64_t inline uint64_t doubleToBits(double d)
doubleToBits(double d)
{ {
uint64_t bits; memcpy(&bits, &d, 8); uint64_t bits;
memcpy(&bits, &d, 8);
return bits; return bits;
} }
inline double inline double bitsToDouble(uint64_t bits)
bitsToDouble(uint64_t bits)
{ {
double d; memcpy(&d, &bits, 8); double d;
memcpy(&d, &bits, 8);
return d; return d;
} }
inline float inline float bitsToFloat(uint32_t bits)
bitsToFloat(uint32_t bits)
{ {
float f; memcpy(&f, &bits, 4); float f;
memcpy(&f, &bits, 4);
return f; return f;
} }
inline int inline int difference(void* a, void* b)
difference(void* a, void* b)
{ {
return reinterpret_cast<intptr_t>(a) - reinterpret_cast<intptr_t>(b); return reinterpret_cast<intptr_t>(a) - reinterpret_cast<intptr_t>(b);
} }
template <class T> template <class T>
inline void* inline void* voidPointer(T function)
voidPointer(T function)
{ {
void* p; void* p;
memcpy(&p, &function, sizeof(void*)); memcpy(&p, &function, sizeof(void*));
return p; return p;
} }
inline void inline void replace(char a, char b, char* c)
replace(char a, char b, char* c)
{ {
for (; *c; ++c) if (*c == a) *c = b; for (; *c; ++c)
if (*c == a)
*c = b;
} }
inline void inline void replace(char a, char b, char* dst, const char* src)
replace(char a, char b, char* dst, const char* src)
{ {
unsigned i = 0; unsigned i = 0;
for (; src[i]; ++ i) { for (; src[i]; ++i) {
dst[i] = src[i] == a ? b : src[i]; dst[i] = src[i] == a ? b : src[i];
} }
dst[i] = 0; dst[i] = 0;
} }
inline bool inline bool equal(const void* a, unsigned al, const void* b, unsigned bl)
equal(const void* a, unsigned al, const void* b, unsigned bl)
{ {
if (al == bl) { if (al == bl) {
return memcmp(a, b, al) == 0; return memcmp(a, b, al) == 0;

View File

@ -279,4 +279,4 @@ const int AVIAN_JNI_VERSION_1_4 = 0x00010004;
} // namespace vm } // namespace vm
#endif//CONSTANTS_H #endif // CONSTANTS_H

View File

@ -30,4 +30,3 @@
#define AVIAN_ARCH_ARM (3 << 8) #define AVIAN_ARCH_ARM (3 << 8)
#endif #endif

View File

@ -30,96 +30,113 @@ const unsigned EntrySignature = 0x02014b50;
const unsigned CentralDirectorySearchStart = 22; const unsigned CentralDirectorySearchStart = 22;
inline uint16_t get2(const uint8_t* p) { inline uint16_t get2(const uint8_t* p)
return {
(static_cast<uint16_t>(p[1]) << 8) | return (static_cast<uint16_t>(p[1]) << 8) | (static_cast<uint16_t>(p[0]));
(static_cast<uint16_t>(p[0]) );
} }
inline uint32_t get4(const uint8_t* p) { inline uint32_t get4(const uint8_t* p)
return {
(static_cast<uint32_t>(p[3]) << 24) | return (static_cast<uint32_t>(p[3]) << 24)
(static_cast<uint32_t>(p[2]) << 16) | | (static_cast<uint32_t>(p[2]) << 16)
(static_cast<uint32_t>(p[1]) << 8) | | (static_cast<uint32_t>(p[1]) << 8) | (static_cast<uint32_t>(p[0]));
(static_cast<uint32_t>(p[0]) );
} }
inline uint32_t signature(const uint8_t* p) { inline uint32_t signature(const uint8_t* p)
{
return get4(p); return get4(p);
} }
inline uint16_t compressionMethod(const uint8_t* centralHeader) { inline uint16_t compressionMethod(const uint8_t* centralHeader)
{
return get2(centralHeader + 10); return get2(centralHeader + 10);
} }
inline uint32_t fileTime(const uint8_t* centralHeader) { inline uint32_t fileTime(const uint8_t* centralHeader)
{
return get4(centralHeader + 12); return get4(centralHeader + 12);
} }
inline uint32_t fileCRC(const uint8_t* centralHeader) { inline uint32_t fileCRC(const uint8_t* centralHeader)
{
return get4(centralHeader + 16); return get4(centralHeader + 16);
} }
inline uint32_t compressedSize(const uint8_t* centralHeader) { inline uint32_t compressedSize(const uint8_t* centralHeader)
{
return get4(centralHeader + 20); return get4(centralHeader + 20);
} }
inline uint32_t uncompressedSize(const uint8_t* centralHeader) { inline uint32_t uncompressedSize(const uint8_t* centralHeader)
{
return get4(centralHeader + 24); return get4(centralHeader + 24);
} }
inline uint16_t fileNameLength(const uint8_t* centralHeader) { inline uint16_t fileNameLength(const uint8_t* centralHeader)
{
return get2(centralHeader + 28); return get2(centralHeader + 28);
} }
inline uint16_t extraFieldLength(const uint8_t* centralHeader) { inline uint16_t extraFieldLength(const uint8_t* centralHeader)
{
return get2(centralHeader + 30); return get2(centralHeader + 30);
} }
inline uint16_t commentFieldLength(const uint8_t* centralHeader) { inline uint16_t commentFieldLength(const uint8_t* centralHeader)
{
return get2(centralHeader + 32); return get2(centralHeader + 32);
} }
inline uint32_t localHeaderOffset(const uint8_t* centralHeader) { inline uint32_t localHeaderOffset(const uint8_t* centralHeader)
{
return get4(centralHeader + 42); return get4(centralHeader + 42);
} }
inline uint16_t localFileNameLength(const uint8_t* localHeader) { inline uint16_t localFileNameLength(const uint8_t* localHeader)
{
return get2(localHeader + 26); return get2(localHeader + 26);
} }
inline uint16_t localExtraFieldLength(const uint8_t* localHeader) { inline uint16_t localExtraFieldLength(const uint8_t* localHeader)
{
return get2(localHeader + 28); return get2(localHeader + 28);
} }
inline uint32_t centralDirectoryOffset(const uint8_t* centralHeader) { inline uint32_t centralDirectoryOffset(const uint8_t* centralHeader)
{
return get4(centralHeader + 16); return get4(centralHeader + 16);
} }
inline const uint8_t* fileName(const uint8_t* centralHeader) { inline const uint8_t* fileName(const uint8_t* centralHeader)
{
return centralHeader + 46; return centralHeader + 46;
} }
inline const uint8_t* fileData(const uint8_t* localHeader) { inline const uint8_t* fileData(const uint8_t* localHeader)
return localHeader + LocalHeaderSize + localFileNameLength(localHeader) + {
localExtraFieldLength(localHeader); return localHeader + LocalHeaderSize + localFileNameLength(localHeader)
+ localExtraFieldLength(localHeader);
} }
inline const uint8_t* endOfEntry(const uint8_t* p) { inline const uint8_t* endOfEntry(const uint8_t* p)
return p + HeaderSize + fileNameLength(p) + extraFieldLength(p) + {
commentFieldLength(p); return p + HeaderSize + fileNameLength(p) + extraFieldLength(p)
+ commentFieldLength(p);
} }
inline bool inline bool readLine(const uint8_t* base,
readLine(const uint8_t* base, unsigned total, unsigned* start, unsigned total,
unsigned* start,
unsigned* length) unsigned* length)
{ {
const uint8_t* p = base + *start; const uint8_t* p = base + *start;
const uint8_t* end = base + total; const uint8_t* end = base + total;
while (p != end and (*p == '\n' or *p == '\r')) ++ p; while (p != end and (*p == '\n' or *p == '\r'))
++p;
*start = p - base; *start = p - base;
while (p != end and not (*p == '\n' or *p == '\r')) ++ p; while (p != end and not(*p == '\n' or *p == '\r'))
++p;
*length = (p - base) - *start; *length = (p - base) - *start;
@ -136,22 +153,26 @@ class Finder {
class Iterator { class Iterator {
public: public:
Iterator(Finder* finder): Iterator(Finder* finder)
it(finder->iterator()), : it(finder->iterator()), current(it->next(&currentSize))
current(it->next(&currentSize)) {
{ } }
~Iterator() { ~Iterator()
{
it->dispose(); it->dispose();
} }
bool hasMore() { bool hasMore()
if (current) return true; {
if (current)
return true;
current = it->next(&currentSize); current = it->next(&currentSize);
return current != 0; return current != 0;
} }
const char* next(unsigned* size) { const char* next(unsigned* size)
{
if (hasMore()) { if (hasMore()) {
*size = currentSize; *size = currentSize;
const char* v = current; const char* v = current;
@ -173,7 +194,8 @@ class Finder {
unsigned* length, unsigned* length,
bool tryDirectory = false) = 0; bool tryDirectory = false) = 0;
virtual const char* urlPrefix(const char* name) = 0; virtual const char* urlPrefix(const char* name) = 0;
virtual const char* nextUrlPrefix(const char* name, void *&finderElementPtr) = 0; virtual const char* nextUrlPrefix(const char* name, void*& finderElementPtr)
= 0;
virtual const char* sourceUrl(const char* name) = 0; virtual const char* sourceUrl(const char* name) = 0;
virtual const char* path() = 0; virtual const char* path() = 0;
virtual void dispose() = 0; virtual void dispose() = 0;
@ -191,4 +213,4 @@ Finder* makeFinder(System* s,
} // namespace vm } // namespace vm
#endif//FINDER_H #endif // FINDER_H

View File

@ -29,8 +29,8 @@ class HeapVisitor {
virtual void root() = 0; virtual void root() = 0;
virtual unsigned visitNew(object value) = 0; virtual unsigned visitNew(object value) = 0;
virtual void visitOld(object value, unsigned number) = 0; virtual void visitOld(object value, unsigned number) = 0;
virtual void push(object parent, unsigned parentNumber, virtual void push(object parent, unsigned parentNumber, unsigned childOffset)
unsigned childOffset) = 0; = 0;
virtual void pop() = 0; virtual void pop() = 0;
}; };
@ -42,9 +42,8 @@ class HeapWalker {
virtual void dispose() = 0; virtual void dispose() = 0;
}; };
HeapWalker* HeapWalker* makeHeapWalker(Thread* t, HeapVisitor* v);
makeHeapWalker(Thread* t, HeapVisitor* v);
} // namespace vm } // namespace vm
#endif//HEAPWALK_H #endif // HEAPWALK_H

View File

@ -27,9 +27,8 @@
namespace vm { namespace vm {
void void populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable);
populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable);
} // namespace vm } // namespace vm
#endif//JNIENV_H #endif // JNIENV_H

View File

@ -22,7 +22,8 @@ const unsigned Padding = 16;
class LzmaAllocator { class LzmaAllocator {
public: public:
LzmaAllocator(avian::util::Allocator* a): a(a) { LzmaAllocator(avian::util::Allocator* a) : a(a)
{
allocator.Alloc = allocate; allocator.Alloc = allocate;
allocator.Free = free; allocator.Free = free;
} }
@ -30,15 +31,17 @@ class LzmaAllocator {
ISzAlloc allocator; ISzAlloc allocator;
avian::util::Allocator* a; avian::util::Allocator* a;
static void* allocate(void* allocator, size_t size) { static void* allocate(void* allocator, size_t size)
uint8_t* p = static_cast<uint8_t*> {
(static_cast<LzmaAllocator*>(allocator)->a->allocate(size + Padding)); uint8_t* p = static_cast<uint8_t*>(
static_cast<LzmaAllocator*>(allocator)->a->allocate(size + Padding));
int32_t size32 = size; int32_t size32 = size;
memcpy(p, &size32, 4); memcpy(p, &size32, 4);
return p + Padding; return p + Padding;
} }
static void free(void* allocator, void* address) { static void free(void* allocator, void* address)
{
if (address) { if (address) {
void* p = static_cast<uint8_t*>(address) - Padding; void* p = static_cast<uint8_t*>(address) - Padding;
int32_t size32; int32_t size32;

File diff suppressed because it is too large Load Diff

View File

@ -58,4 +58,4 @@ int findLineNumber(Thread* t, GcMethod* method, unsigned ip);
} // namespace vm } // namespace vm
#endif//PROCESS_H #endif // PROCESS_H

View File

@ -69,7 +69,10 @@ class Processor {
class CompilationHandler { class CompilationHandler {
public: public:
virtual void compiled(const void* code, unsigned size, unsigned frameSize, const char* name) = 0; virtual void compiled(const void* code,
unsigned size,
unsigned frameSize,
const char* name) = 0;
virtual void dispose() = 0; virtual void dispose() = 0;
}; };
@ -112,25 +115,19 @@ class Processor {
virtual void initVtable(Thread* t, GcClass* c) = 0; virtual void initVtable(Thread* t, GcClass* c) = 0;
virtual void virtual void visitObjects(Thread* t, Heap::Visitor* v) = 0;
visitObjects(Thread* t, Heap::Visitor* v) = 0;
virtual void virtual void walkStack(Thread* t, StackVisitor* v) = 0;
walkStack(Thread* t, StackVisitor* v) = 0;
virtual int lineNumber(Thread* t, GcMethod* method, int ip) = 0; virtual int lineNumber(Thread* t, GcMethod* method, int ip) = 0;
virtual object* virtual object* makeLocalReference(Thread* t, object o) = 0;
makeLocalReference(Thread* t, object o) = 0;
virtual void virtual void disposeLocalReference(Thread* t, object* r) = 0;
disposeLocalReference(Thread* t, object* r) = 0;
virtual bool virtual bool pushLocalFrame(Thread* t, unsigned capacity) = 0;
pushLocalFrame(Thread* t, unsigned capacity) = 0;
virtual void virtual void popLocalFrame(Thread* t) = 0;
popLocalFrame(Thread* t) = 0;
virtual object invokeArray(Thread* t, virtual object invokeArray(Thread* t,
GcMethod* method, GcMethod* method,
@ -156,20 +153,16 @@ class Processor {
object this_, object this_,
va_list arguments) = 0; va_list arguments) = 0;
virtual void virtual void dispose(Thread* t) = 0;
dispose(Thread* t) = 0;
virtual void virtual void dispose() = 0;
dispose() = 0;
virtual object virtual object getStackTrace(Thread* t, Thread* target) = 0;
getStackTrace(Thread* t, Thread* target) = 0;
virtual void initialize(BootImage* image, avian::util::Slice<uint8_t> code) virtual void initialize(BootImage* image, avian::util::Slice<uint8_t> code)
= 0; = 0;
virtual void virtual void addCompilationHandler(CompilationHandler* handler) = 0;
addCompilationHandler(CompilationHandler* handler) = 0;
virtual void compileMethod(Thread* t, virtual void compileMethod(Thread* t,
Zone* zone, Zone* zone,
@ -179,23 +172,18 @@ class Processor {
GcMethod* method, GcMethod* method,
OffsetResolver* resolver) = 0; OffsetResolver* resolver) = 0;
virtual void virtual void visitRoots(Thread* t, HeapWalker* w) = 0;
visitRoots(Thread* t, HeapWalker* w) = 0;
virtual void virtual void normalizeVirtualThunks(Thread* t) = 0;
normalizeVirtualThunks(Thread* t) = 0;
virtual unsigned* virtual unsigned* makeCallTable(Thread* t, HeapWalker* w) = 0;
makeCallTable(Thread* t, HeapWalker* w) = 0;
virtual void virtual void boot(Thread* t, BootImage* image, uint8_t* code) = 0;
boot(Thread* t, BootImage* image, uint8_t* code) = 0;
virtual void virtual void callWithCurrentContinuation(Thread* t, object receiver) = 0;
callWithCurrentContinuation(Thread* t, object receiver) = 0;
virtual void virtual void dynamicWind(Thread* t, object before, object thunk, object after)
dynamicWind(Thread* t, object before, object thunk, object after) = 0; = 0;
virtual void feedResultToContinuation(Thread* t, virtual void feedResultToContinuation(Thread* t,
GcContinuation* continuation, GcContinuation* continuation,
@ -205,9 +193,10 @@ class Processor {
GcContinuation* continuation, GcContinuation* continuation,
GcThrowable* exception) = 0; GcThrowable* exception) = 0;
virtual void virtual void walkContinuationBody(Thread* t,
walkContinuationBody(Thread* t, Heap::Walker* w, object o, unsigned start) Heap::Walker* w,
= 0; object o,
unsigned start) = 0;
object invoke(Thread* t, GcMethod* method, object this_, ...) object invoke(Thread* t, GcMethod* method, object this_, ...)
{ {
@ -232,8 +221,8 @@ class Processor {
va_list a; va_list a;
va_start(a, this_); va_start(a, this_);
object r = invokeList object r
(t, loader, className, methodName, methodSpec, this_, a); = invokeList(t, loader, className, methodName, methodSpec, this_, a);
va_end(a); va_end(a);
@ -248,4 +237,4 @@ Processor* makeProcessor(System* system,
} // namespace vm } // namespace vm
#endif//PROCESSOR_H #endif // PROCESSOR_H

View File

@ -11,9 +11,8 @@
#ifndef AVIAN_TARGET_FIELDS_H #ifndef AVIAN_TARGET_FIELDS_H
#define AVIAN_TARGET_FIELDS_H #define AVIAN_TARGET_FIELDS_H
#ifdef TARGET_BYTES_PER_WORD #ifdef TARGET_BYTES_PER_WORD
# if (TARGET_BYTES_PER_WORD == 8) #if (TARGET_BYTES_PER_WORD == 8)
#define TARGET_THREAD_EXCEPTION 80 #define TARGET_THREAD_EXCEPTION 80
#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2264 #define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2264
@ -33,7 +32,7 @@
#define TARGET_THREAD_THUNKTABLE 2328 #define TARGET_THREAD_THUNKTABLE 2328
#define TARGET_THREAD_STACKLIMIT 2376 #define TARGET_THREAD_STACKLIMIT 2376
# elif (TARGET_BYTES_PER_WORD == 4) #elif(TARGET_BYTES_PER_WORD == 4)
#define TARGET_THREAD_EXCEPTION 44 #define TARGET_THREAD_EXCEPTION 44
#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2168 #define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2168
@ -53,12 +52,11 @@
#define TARGET_THREAD_THUNKTABLE 2200 #define TARGET_THREAD_THUNKTABLE 2200
#define TARGET_THREAD_STACKLIMIT 2224 #define TARGET_THREAD_STACKLIMIT 2224
# else
# error
# endif
#else #else
# error #error
#endif
#else
#error
#endif #endif
#endif #endif

View File

@ -17,96 +17,82 @@
namespace vm { namespace vm {
template <class T> template <class T>
inline T inline T targetV1(T v)
targetV1(T v)
{ {
return v; return v;
} }
template <class T> template <class T>
inline T inline T swapV2(T v)
swapV2(T v)
{ {
return (((v >> 8) & 0xFF) | return (((v >> 8) & 0xFF) | ((v << 8)));
((v << 8)));
} }
template <class T> template <class T>
inline T inline T swapV4(T v)
swapV4(T v)
{ {
return (((v >> 24) & 0x000000FF) | return (((v >> 24) & 0x000000FF) | ((v >> 8) & 0x0000FF00)
((v >> 8) & 0x0000FF00) | | ((v << 8) & 0x00FF0000) | ((v << 24)));
((v << 8) & 0x00FF0000) |
((v << 24)));
} }
template <class T> template <class T>
inline T inline T swapV8(T v)
swapV8(T v)
{ {
return (((static_cast<uint64_t>(v) >> 56) & UINT64_C(0x00000000000000FF)) | return (((static_cast<uint64_t>(v) >> 56) & UINT64_C(0x00000000000000FF))
((static_cast<uint64_t>(v) >> 40) & UINT64_C(0x000000000000FF00)) | | ((static_cast<uint64_t>(v) >> 40) & UINT64_C(0x000000000000FF00))
((static_cast<uint64_t>(v) >> 24) & UINT64_C(0x0000000000FF0000)) | | ((static_cast<uint64_t>(v) >> 24) & UINT64_C(0x0000000000FF0000))
((static_cast<uint64_t>(v) >> 8) & UINT64_C(0x00000000FF000000)) | | ((static_cast<uint64_t>(v) >> 8) & UINT64_C(0x00000000FF000000))
((static_cast<uint64_t>(v) << 8) & UINT64_C(0x000000FF00000000)) | | ((static_cast<uint64_t>(v) << 8) & UINT64_C(0x000000FF00000000))
((static_cast<uint64_t>(v) << 24) & UINT64_C(0x0000FF0000000000)) | | ((static_cast<uint64_t>(v) << 24) & UINT64_C(0x0000FF0000000000))
((static_cast<uint64_t>(v) << 40) & UINT64_C(0x00FF000000000000)) | | ((static_cast<uint64_t>(v) << 40) & UINT64_C(0x00FF000000000000))
((static_cast<uint64_t>(v) << 56))); | ((static_cast<uint64_t>(v) << 56)));
} }
#ifdef TARGET_OPPOSITE_ENDIAN #ifdef TARGET_OPPOSITE_ENDIAN
template <class T> template <class T>
inline T inline T targetV2(T v)
targetV2(T v)
{ {
return swapV2(v); return swapV2(v);
} }
template <class T> template <class T>
inline T inline T targetV4(T v)
targetV4(T v)
{ {
return swapV4(v); return swapV4(v);
} }
template <class T> template <class T>
inline T inline T targetV8(T v)
targetV8(T v)
{ {
return swapV8(v); return swapV8(v);
} }
#else #else
template <class T> template <class T>
inline T inline T targetV2(T v)
targetV2(T v)
{ {
return v; return v;
} }
template <class T> template <class T>
inline T inline T targetV4(T v)
targetV4(T v)
{ {
return v; return v;
} }
template <class T> template <class T>
inline T inline T targetV8(T v)
targetV8(T v)
{ {
return v; return v;
} }
#endif #endif
#ifdef TARGET_BYTES_PER_WORD #ifdef TARGET_BYTES_PER_WORD
# if (TARGET_BYTES_PER_WORD == 8) #if (TARGET_BYTES_PER_WORD == 8)
template <class T> template <class T>
inline T inline T targetVW(T v)
targetVW(T v)
{ {
return targetV8(v); return targetV8(v);
} }
@ -120,11 +106,10 @@ const unsigned TargetClassVtable = 136;
const unsigned TargetFieldOffset = 12; const unsigned TargetFieldOffset = 12;
# elif (TARGET_BYTES_PER_WORD == 4) #elif(TARGET_BYTES_PER_WORD == 4)
template <class T> template <class T>
inline T inline T targetVW(T v)
targetVW(T v)
{ {
return targetV4(v); return targetV4(v);
} }
@ -138,11 +123,11 @@ const unsigned TargetClassVtable = 72;
const unsigned TargetFieldOffset = 8; const unsigned TargetFieldOffset = 8;
# else
# error
# endif
#else #else
# error #error
#endif
#else
#error
#endif #endif
const unsigned TargetBytesPerWord = TARGET_BYTES_PER_WORD; const unsigned TargetBytesPerWord = TARGET_BYTES_PER_WORD;
@ -150,19 +135,18 @@ const unsigned TargetBytesPerWord = TARGET_BYTES_PER_WORD;
const unsigned TargetBitsPerWord = TargetBytesPerWord * 8; const unsigned TargetBitsPerWord = TargetBytesPerWord * 8;
const target_uintptr_t TargetPointerMask const target_uintptr_t TargetPointerMask
= ((~static_cast<target_uintptr_t>(0)) / TargetBytesPerWord) = ((~static_cast<target_uintptr_t>(0)) / TargetBytesPerWord)
* TargetBytesPerWord; * TargetBytesPerWord;
const unsigned TargetArrayLength = TargetBytesPerWord; const unsigned TargetArrayLength = TargetBytesPerWord;
const unsigned TargetArrayBody = TargetBytesPerWord * 2; const unsigned TargetArrayBody = TargetBytesPerWord * 2;
inline void inline void targetMarkBit(target_uintptr_t* map, unsigned i)
targetMarkBit(target_uintptr_t* map, unsigned i)
{ {
map[wordOf<target_uintptr_t>(i)] |= map[wordOf<target_uintptr_t>(i)] |= targetVW(static_cast<target_uintptr_t>(1)
targetVW(static_cast<target_uintptr_t>(1) << bitOf<target_uintptr_t>(i)); << bitOf<target_uintptr_t>(i));
} }
} // namespace vm } // namespace vm
#endif//TARGET_H #endif // TARGET_H

View File

@ -20,4 +20,4 @@
#define DOUBLE_TYPE 6 #define DOUBLE_TYPE 6
#define POINTER_TYPE 7 #define POINTER_TYPE 7
#endif//TYPES_H #endif // TYPES_H

View File

@ -84,15 +84,13 @@ object hashMapRemove(Thread* t,
object hashMapIterator(Thread* t, GcHashMap* map); object hashMapIterator(Thread* t, GcHashMap* map);
object object hashMapIteratorNext(Thread* t, object it);
hashMapIteratorNext(Thread* t, object it);
void listAppend(Thread* t, GcList* list, object value); void listAppend(Thread* t, GcList* list, object value);
GcVector* vectorAppend(Thread* t, GcVector* vector, object value); GcVector* vectorAppend(Thread* t, GcVector* vector, object value);
object object growArray(Thread* t, object array);
growArray(Thread* t, object array);
object treeQuery(Thread* t, object treeQuery(Thread* t,
GcTreeNode* tree, GcTreeNode* tree,
@ -115,7 +113,7 @@ void treeUpdate(Thread* t,
GcTreeNode* sentinal, GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b)); intptr_t (*compare)(Thread* t, intptr_t key, object b));
class HashMapIterator: public Thread::Protector { class HashMapIterator : public Thread::Protector {
public: public:
HashMapIterator(Thread* t, GcHashMap* map) HashMapIterator(Thread* t, GcHashMap* map)
: Protector(t), map(map), node(0), index(0) : Protector(t), map(map), node(0), index(0)
@ -123,7 +121,8 @@ class HashMapIterator: public Thread::Protector {
find(); find();
} }
void find() { void find()
{
GcArray* array = map->array(); GcArray* array = map->array();
if (array) { if (array) {
for (unsigned i = index; i < array->length(); ++i) { for (unsigned i = index; i < array->length(); ++i) {
@ -137,7 +136,8 @@ class HashMapIterator: public Thread::Protector {
node = 0; node = 0;
} }
bool hasMore() { bool hasMore()
{
return node != 0; return node != 0;
} }
@ -156,7 +156,8 @@ class HashMapIterator: public Thread::Protector {
} }
} }
virtual void visit(Heap::Visitor* v) { virtual void visit(Heap::Visitor* v)
{
v->visit(&map); v->visit(&map);
v->visit(&node); v->visit(&node);
} }
@ -168,4 +169,4 @@ class HashMapIterator: public Thread::Protector {
} // vm } // vm
#endif//UTIL_H #endif // UTIL_H

View File

@ -15,84 +15,87 @@
#include "avian/common.h" #include "avian/common.h"
#ifdef _MSC_VER #ifdef _MSC_VER
# include "windows.h" #include "windows.h"
# pragma push_macro("assert") #pragma push_macro("assert")
# include "intrin.h" #include "intrin.h"
# pragma pop_macro("assert") #pragma pop_macro("assert")
# undef interface #undef interface
#endif #endif
#if (defined ARCH_x86_32) || (defined PLATFORM_WINDOWS) #if (defined ARCH_x86_32) || (defined PLATFORM_WINDOWS)
# define VA_LIST(x) (&(x)) #define VA_LIST(x) (&(x))
#else #else
# define VA_LIST(x) (x) #define VA_LIST(x) (x)
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
# include "mach/mach_types.h" #include "mach/mach_types.h"
# include "mach/thread_act.h" #include "mach/thread_act.h"
# include "mach/thread_status.h" #include "mach/thread_status.h"
# if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32) #if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32)
# define FIELD(x) __##x #define FIELD(x) __##x
# else #else
# define FIELD(x) x #define FIELD(x) x
# endif #endif
#endif #endif
#ifdef ARCH_x86_32 #ifdef ARCH_x86_32
# ifdef __APPLE__ #ifdef __APPLE__
# define THREAD_STATE x86_THREAD_STATE32 #define THREAD_STATE x86_THREAD_STATE32
# define THREAD_STATE_TYPE x86_thread_state32_t #define THREAD_STATE_TYPE x86_thread_state32_t
# define THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT #define THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT
# define THREAD_STATE_IP(state) ((state).FIELD(eip)) #define THREAD_STATE_IP(state) ((state).FIELD(eip))
# define THREAD_STATE_STACK(state) ((state).FIELD(esp)) #define THREAD_STATE_STACK(state) ((state).FIELD(esp))
# define THREAD_STATE_THREAD(state) ((state).FIELD(ebx)) #define THREAD_STATE_THREAD(state) ((state).FIELD(ebx))
# define THREAD_STATE_LINK(state) ((state).FIELD(ecx)) #define THREAD_STATE_LINK(state) ((state).FIELD(ecx))
# define THREAD_STATE_FRAME(state) ((state).FIELD(ebp)) #define THREAD_STATE_FRAME(state) ((state).FIELD(ebp))
# define IP_REGISTER(context) \ #define IP_REGISTER(context) THREAD_STATE_IP(context->uc_mcontext->FIELD(ss))
THREAD_STATE_IP(context->uc_mcontext->FIELD(ss)) #define STACK_REGISTER(context) \
# define STACK_REGISTER(context) \
THREAD_STATE_STACK(context->uc_mcontext->FIELD(ss)) THREAD_STATE_STACK(context->uc_mcontext->FIELD(ss))
# define THREAD_REGISTER(context) \ #define THREAD_REGISTER(context) \
THREAD_STATE_THREAD(context->uc_mcontext->FIELD(ss)) THREAD_STATE_THREAD(context->uc_mcontext->FIELD(ss))
# define LINK_REGISTER(context) \ #define LINK_REGISTER(context) \
THREAD_STATE_LINK(context->uc_mcontext->FIELD(ss)) THREAD_STATE_LINK(context->uc_mcontext->FIELD(ss))
# define FRAME_REGISTER(context) \ #define FRAME_REGISTER(context) \
THREAD_STATE_FRAME(context->uc_mcontext->FIELD(ss)) THREAD_STATE_FRAME(context->uc_mcontext->FIELD(ss))
# elif (defined __QNX__) #elif(defined __QNX__)
# define IP_REGISTER(context) (context->uc_mcontext.cpu.eip) #define IP_REGISTER(context) (context->uc_mcontext.cpu.eip)
# define STACK_REGISTER(context) (context->uc_mcontext.cpu.esp) #define STACK_REGISTER(context) (context->uc_mcontext.cpu.esp)
# define THREAD_REGISTER(context) (context->uc_mcontext.cpu.ebx) #define THREAD_REGISTER(context) (context->uc_mcontext.cpu.ebx)
# define LINK_REGISTER(context) (context->uc_mcontext.cpu.ecx) #define LINK_REGISTER(context) (context->uc_mcontext.cpu.ecx)
# define FRAME_REGISTER(context) (context->uc_mcontext.cpu.ebp) #define FRAME_REGISTER(context) (context->uc_mcontext.cpu.ebp)
# elif (defined __FreeBSD__) #elif(defined __FreeBSD__)
# define IP_REGISTER(context) (context->uc_mcontext.mc_eip) #define IP_REGISTER(context) (context->uc_mcontext.mc_eip)
# define STACK_REGISTER(context) (context->uc_mcontext.mc_esp) #define STACK_REGISTER(context) (context->uc_mcontext.mc_esp)
# define THREAD_REGISTER(context) (context->uc_mcontext.mc_ebx) #define THREAD_REGISTER(context) (context->uc_mcontext.mc_ebx)
# define LINK_REGISTER(context) (context->uc_mcontext.mc_ecx) #define LINK_REGISTER(context) (context->uc_mcontext.mc_ecx)
# define FRAME_REGISTER(context) (context->uc_mcontext.mc_ebp) #define FRAME_REGISTER(context) (context->uc_mcontext.mc_ebp)
# else #else
# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_EIP]) #define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_EIP])
# define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_ESP]) #define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_ESP])
# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_EBX]) #define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_EBX])
# define LINK_REGISTER(context) (context->uc_mcontext.gregs[REG_ECX]) #define LINK_REGISTER(context) (context->uc_mcontext.gregs[REG_ECX])
# define FRAME_REGISTER(context) (context->uc_mcontext.gregs[REG_EBP]) #define FRAME_REGISTER(context) (context->uc_mcontext.gregs[REG_EBP])
# endif #endif
extern "C" uint64_t extern "C" uint64_t vmNativeCall(void* function,
vmNativeCall(void* function, void* stack, unsigned stackSize, void* stack,
unsigned stackSize,
unsigned returnType); unsigned returnType);
namespace vm { namespace vm {
inline uint64_t inline uint64_t dynamicCall(void* function,
dynamicCall(void* function, uintptr_t* arguments, uint8_t*, uintptr_t* arguments,
unsigned, unsigned argumentsSize, unsigned returnType) uint8_t*,
unsigned,
unsigned argumentsSize,
unsigned returnType)
{ {
return vmNativeCall(function, arguments, argumentsSize, returnType); return vmNativeCall(function, arguments, argumentsSize, returnType);
} }
@ -101,64 +104,75 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t*,
#elif defined ARCH_x86_64 #elif defined ARCH_x86_64
# ifdef __APPLE__ #ifdef __APPLE__
# define THREAD_STATE x86_THREAD_STATE64 #define THREAD_STATE x86_THREAD_STATE64
# define THREAD_STATE_TYPE x86_thread_state64_t #define THREAD_STATE_TYPE x86_thread_state64_t
# define THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT #define THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT
# define THREAD_STATE_IP(state) ((state).FIELD(rip)) #define THREAD_STATE_IP(state) ((state).FIELD(rip))
# define THREAD_STATE_STACK(state) ((state).FIELD(rsp)) #define THREAD_STATE_STACK(state) ((state).FIELD(rsp))
# define THREAD_STATE_THREAD(state) ((state).FIELD(rbx)) #define THREAD_STATE_THREAD(state) ((state).FIELD(rbx))
# define THREAD_STATE_LINK(state) ((state).FIELD(rcx)) #define THREAD_STATE_LINK(state) ((state).FIELD(rcx))
# define THREAD_STATE_FRAME(state) ((state).FIELD(rbp)) #define THREAD_STATE_FRAME(state) ((state).FIELD(rbp))
# define IP_REGISTER(context) \ #define IP_REGISTER(context) THREAD_STATE_IP(context->uc_mcontext->FIELD(ss))
THREAD_STATE_IP(context->uc_mcontext->FIELD(ss)) #define STACK_REGISTER(context) \
# define STACK_REGISTER(context) \
THREAD_STATE_STACK(context->uc_mcontext->FIELD(ss)) THREAD_STATE_STACK(context->uc_mcontext->FIELD(ss))
# define THREAD_REGISTER(context) \ #define THREAD_REGISTER(context) \
THREAD_STATE_THREAD(context->uc_mcontext->FIELD(ss)) THREAD_STATE_THREAD(context->uc_mcontext->FIELD(ss))
# define LINK_REGISTER(context) \ #define LINK_REGISTER(context) \
THREAD_STATE_LINK(context->uc_mcontext->FIELD(ss)) THREAD_STATE_LINK(context->uc_mcontext->FIELD(ss))
# define FRAME_REGISTER(context) \ #define FRAME_REGISTER(context) \
THREAD_STATE_FRAME(context->uc_mcontext->FIELD(ss)) THREAD_STATE_FRAME(context->uc_mcontext->FIELD(ss))
# elif (defined __FreeBSD__) #elif(defined __FreeBSD__)
# define IP_REGISTER(context) (context->uc_mcontext.mc_rip) #define IP_REGISTER(context) (context->uc_mcontext.mc_rip)
# define STACK_REGISTER(context) (context->uc_mcontext.mc_rsp) #define STACK_REGISTER(context) (context->uc_mcontext.mc_rsp)
# define THREAD_REGISTER(context) (context->uc_mcontext.mc_rbx) #define THREAD_REGISTER(context) (context->uc_mcontext.mc_rbx)
# define LINK_REGISTER(context) (context->uc_mcontext.mc_rcx) #define LINK_REGISTER(context) (context->uc_mcontext.mc_rcx)
# define FRAME_REGISTER(context) (context->uc_mcontext.mc_rbp) #define FRAME_REGISTER(context) (context->uc_mcontext.mc_rbp)
# else #else
# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP]) #define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP])
# define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_RSP]) #define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_RSP])
# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX]) #define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX])
# define LINK_REGISTER(context) (context->uc_mcontext.gregs[REG_RCX]) #define LINK_REGISTER(context) (context->uc_mcontext.gregs[REG_RCX])
# define FRAME_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP]) #define FRAME_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP])
# endif #endif
extern "C" uint64_t extern "C" uint64_t
# ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
vmNativeCall(void* function, void* stack, unsigned stackSize, vmNativeCall(void* function,
void* stack,
unsigned stackSize,
unsigned returnType); unsigned returnType);
# else #else
vmNativeCall(void* function, void* stack, unsigned stackSize, vmNativeCall(void* function,
void* gprTable, void* sseTable, unsigned returnType); void* stack,
# endif unsigned stackSize,
void* gprTable,
void* sseTable,
unsigned returnType);
#endif
namespace vm { namespace vm {
# ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
inline uint64_t inline uint64_t dynamicCall(void* function,
dynamicCall(void* function, uint64_t* arguments, UNUSED uint8_t* argumentTypes, uint64_t* arguments,
unsigned argumentCount, unsigned, unsigned returnType) UNUSED uint8_t* argumentTypes,
unsigned argumentCount,
unsigned,
unsigned returnType)
{ {
return vmNativeCall(function, arguments, argumentCount, returnType); return vmNativeCall(function, arguments, argumentCount, returnType);
} }
# else #else
inline uint64_t inline uint64_t dynamicCall(void* function,
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes, uintptr_t* arguments,
unsigned argumentCount, unsigned, unsigned returnType) uint8_t* argumentTypes,
unsigned argumentCount,
unsigned,
unsigned returnType)
{ {
const unsigned GprCount = 6; const unsigned GprCount = 6;
uint64_t gprTable[GprCount]; uint64_t gprTable[GprCount];
@ -192,22 +206,24 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
} }
} }
return vmNativeCall(function, stack, stackIndex * BytesPerWord, return vmNativeCall(function,
stack,
stackIndex * BytesPerWord,
(gprIndex ? gprTable : 0), (gprIndex ? gprTable : 0),
(sseIndex ? sseTable : 0), returnType); (sseIndex ? sseTable : 0),
returnType);
} }
#endif #endif
} // namespace vm } // namespace vm
#else #else
# error unsupported architecture #error unsupported architecture
#endif #endif
namespace vm { namespace vm {
inline void inline void trap()
trap()
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
__asm int 3 __asm int 3
@ -216,50 +232,44 @@ trap()
#endif #endif
} }
inline void inline void programOrderMemoryBarrier()
programOrderMemoryBarrier()
{ {
compileTimeMemoryBarrier(); compileTimeMemoryBarrier();
} }
inline void inline void storeStoreMemoryBarrier()
storeStoreMemoryBarrier()
{ {
programOrderMemoryBarrier(); programOrderMemoryBarrier();
} }
inline void inline void storeLoadMemoryBarrier()
storeLoadMemoryBarrier()
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
MemoryBarrier(); MemoryBarrier();
#elif defined ARCH_x86_32 #elif defined ARCH_x86_32
__asm__ __volatile__("lock; addl $0,0(%%esp)": : :"memory"); __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory");
#elif defined ARCH_x86_64 #elif defined ARCH_x86_64
__asm__ __volatile__("mfence": : :"memory"); __asm__ __volatile__("mfence" : : : "memory");
#endif // ARCH_x86_64 #endif // ARCH_x86_64
} }
inline void inline void loadMemoryBarrier()
loadMemoryBarrier()
{ {
programOrderMemoryBarrier(); programOrderMemoryBarrier();
} }
inline void inline void syncInstructionCache(const void*, unsigned)
syncInstructionCache(const void*, unsigned)
{ {
programOrderMemoryBarrier(); programOrderMemoryBarrier();
} }
#ifdef USE_ATOMIC_OPERATIONS #ifdef USE_ATOMIC_OPERATIONS
inline bool inline bool atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
return old == InterlockedCompareExchange return old
(reinterpret_cast<LONG*>(p), new_, old); == InterlockedCompareExchange(reinterpret_cast<LONG*>(p), new_, old);
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1) #elif(__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
return __sync_bool_compare_and_swap(p, old, new_); return __sync_bool_compare_and_swap(p, old, new_);
#else #else
uint8_t result; uint8_t result;
@ -275,13 +285,12 @@ atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
#define AVIAN_HAS_CAS64 #define AVIAN_HAS_CAS64
inline bool inline bool atomicCompareAndSwap64(uint64_t* p, uint64_t old, uint64_t new_)
atomicCompareAndSwap64(uint64_t* p, uint64_t old, uint64_t new_)
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
return old == InterlockedCompareExchange64 return old == InterlockedCompareExchange64(
(reinterpret_cast<LONGLONG*>(p), new_, old); reinterpret_cast<LONGLONG*>(p), new_, old);
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1) #elif(__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
return __sync_bool_compare_and_swap(p, old, new_); return __sync_bool_compare_and_swap(p, old, new_);
#elif defined ARCH_x86_32 #elif defined ARCH_x86_32
uint8_t result; uint8_t result;
@ -308,8 +317,7 @@ atomicCompareAndSwap64(uint64_t* p, uint64_t old, uint64_t new_)
#endif #endif
} }
inline bool inline bool atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
{ {
#ifdef ARCH_x86_32 #ifdef ARCH_x86_32
return atomicCompareAndSwap32(reinterpret_cast<uint32_t*>(p), old, new_); return atomicCompareAndSwap32(reinterpret_cast<uint32_t*>(p), old, new_);
@ -321,4 +329,4 @@ atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
} // namespace vm } // namespace vm
#endif//X86_H #endif // X86_H

View File

@ -13,11 +13,19 @@
#ifdef inflateInit2 #ifdef inflateInit2
#undef inflateInit2 #undef inflateInit2
#define inflateInit2(strm, windowBits) \ #define inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, static_cast<int>(sizeof(z_stream))) inflateInit2_( \
(strm), (windowBits), ZLIB_VERSION, static_cast<int>(sizeof(z_stream)))
#endif #endif
#ifdef deflateInit2 #ifdef deflateInit2
#undef deflateInit2 #undef deflateInit2
#define deflateInit2(strm, level, windowBits) \ #define deflateInit2(strm, level, windowBits) \
deflateInit2_((strm), (level), Z_DEFLATED, (windowBits), 8, Z_DEFAULT_STRATEGY, ZLIB_VERSION, static_cast<int>(sizeof(z_stream))) deflateInit2_((strm), \
(level), \
Z_DEFLATED, \
(windowBits), \
8, \
Z_DEFAULT_STRATEGY, \
ZLIB_VERSION, \
static_cast<int>(sizeof(z_stream)))
#endif #endif

View File

@ -21,9 +21,9 @@ class Zone : public avian::util::Allocator {
public: public:
class Segment { class Segment {
public: public:
Segment(Segment* next, unsigned size): Segment(Segment* next, unsigned size) : next(next), size(size), position(0)
next(next), size(size), position(0) {
{ } }
Segment* next; Segment* next;
uintptr_t size; uintptr_t size;
@ -31,19 +31,23 @@ class Zone : public avian::util::Allocator {
uint8_t data[0]; uint8_t data[0];
}; };
Zone(System* s, Allocator* allocator, unsigned minimumFootprint): Zone(System* s, Allocator* allocator, unsigned minimumFootprint)
s(s), : s(s),
allocator(allocator), allocator(allocator),
segment(0), segment(0),
minimumFootprint(minimumFootprint < sizeof(Segment) ? 0 : minimumFootprint(minimumFootprint < sizeof(Segment)
minimumFootprint - sizeof(Segment)) ? 0
{ } : minimumFootprint - sizeof(Segment))
{
}
~Zone() { ~Zone()
{
dispose(); dispose();
} }
void dispose() { void dispose()
{
for (Segment* seg = segment, *next; seg; seg = next) { for (Segment* seg = segment, *next; seg; seg = next) {
next = seg->next; next = seg->next;
allocator->free(seg, sizeof(Segment) + seg->size); allocator->free(seg, sizeof(Segment) + seg->size);
@ -52,17 +56,19 @@ class Zone : public avian::util::Allocator {
segment = 0; segment = 0;
} }
static unsigned padToPage(unsigned size) { static unsigned padToPage(unsigned size)
return (size + (LikelyPageSizeInBytes - 1)) {
& ~(LikelyPageSizeInBytes - 1); return (size + (LikelyPageSizeInBytes - 1)) & ~(LikelyPageSizeInBytes - 1);
} }
bool tryEnsure(unsigned space) { bool tryEnsure(unsigned space)
{
if (segment == 0 or segment->position + space > segment->size) { if (segment == 0 or segment->position + space > segment->size) {
unsigned size = padToPage unsigned size = padToPage(
(avian::util::max avian::util::max(
(space, avian::util::max space,
(minimumFootprint, segment == 0 ? 0 : segment->size * 2)) avian::util::max(minimumFootprint,
segment == 0 ? 0 : segment->size * 2))
+ sizeof(Segment)); + sizeof(Segment));
void* p = allocator->tryAllocate(size); void* p = allocator->tryAllocate(size);
@ -79,7 +85,8 @@ class Zone : public avian::util::Allocator {
return true; return true;
} }
void ensure(unsigned space) { void ensure(unsigned space)
{
if (segment == 0 or segment->position + space > segment->size) { if (segment == 0 or segment->position + space > segment->size) {
unsigned size = padToPage(space + sizeof(Segment)); unsigned size = padToPage(space + sizeof(Segment));
@ -88,7 +95,8 @@ class Zone : public avian::util::Allocator {
} }
} }
virtual void* tryAllocate(unsigned size) { virtual void* tryAllocate(unsigned size)
{
size = pad(size); size = pad(size);
if (tryEnsure(size)) { if (tryEnsure(size)) {
void* r = segment->data + segment->position; void* r = segment->data + segment->position;
@ -99,7 +107,8 @@ class Zone : public avian::util::Allocator {
} }
} }
virtual void* allocate(unsigned size) { virtual void* allocate(unsigned size)
{
size = pad(size); size = pad(size);
void* p = tryAllocate(size); void* p = tryAllocate(size);
if (p) { if (p) {
@ -112,7 +121,8 @@ class Zone : public avian::util::Allocator {
} }
} }
void* peek(unsigned size) { void* peek(unsigned size)
{
size = pad(size); size = pad(size);
Segment* s = segment; Segment* s = segment;
while (s->position < size) { while (s->position < size) {
@ -122,7 +132,8 @@ class Zone : public avian::util::Allocator {
return s->data + (s->position - size); return s->data + (s->position - size);
} }
void pop(unsigned size) { void pop(unsigned size)
{
size = pad(size); size = pad(size);
Segment* s = segment; Segment* s = segment;
while (s->position < size) { while (s->position < size) {
@ -135,7 +146,8 @@ class Zone : public avian::util::Allocator {
segment = s; segment = s;
} }
virtual void free(const void*, unsigned) { virtual void free(const void*, unsigned)
{
// not supported // not supported
abort(s); abort(s);
} }
@ -149,4 +161,4 @@ class Zone : public avian::util::Allocator {
} // namespace vm } // namespace vm
#endif//ZONE_H #endif // ZONE_H

View File

@ -12,26 +12,23 @@
#ifdef BOOT_JAVAHOME #ifdef BOOT_JAVAHOME
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER)) #if (!defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_javahome_jar_##x #define SYMBOL(x) binary_javahome_jar_##x
#else #else
# define SYMBOL(x) _binary_javahome_jar_##x #define SYMBOL(x) _binary_javahome_jar_##x
#endif #endif
extern "C" { extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
extern const uint8_t SYMBOL(start)[]; AVIAN_EXPORT const uint8_t* javahomeJar(unsigned* size)
extern const uint8_t SYMBOL(end)[]; {
AVIAN_EXPORT const uint8_t*
javahomeJar(unsigned* size)
{
*size = SYMBOL(end) - SYMBOL(start); *size = SYMBOL(end) - SYMBOL(start);
return SYMBOL(start); return SYMBOL(start);
} }
} }
#undef SYMBOL #undef SYMBOL
#endif//BOOT_JAVAHOME #endif // BOOT_JAVAHOME

View File

@ -14,68 +14,64 @@
// since we aren't linking against libstdc++, we must implement this // since we aren't linking against libstdc++, we must implement this
// ourselves: // ourselves:
extern "C" void __cxa_pure_virtual(void) { abort(); } extern "C" void __cxa_pure_virtual(void)
{
abort();
}
#ifdef BOOT_IMAGE #ifdef BOOT_IMAGE
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER)) #if (!defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define BOOTIMAGE_SYMBOL(x) binary_bootimage_bin_##x #define BOOTIMAGE_SYMBOL(x) binary_bootimage_bin_##x
# define CODEIMAGE_SYMBOL(x) binary_codeimage_bin_##x #define CODEIMAGE_SYMBOL(x) binary_codeimage_bin_##x
#else #else
# define BOOTIMAGE_SYMBOL(x) _binary_bootimage_bin_##x #define BOOTIMAGE_SYMBOL(x) _binary_bootimage_bin_##x
# define CODEIMAGE_SYMBOL(x) _binary_codeimage_bin_##x #define CODEIMAGE_SYMBOL(x) _binary_codeimage_bin_##x
#endif #endif
extern "C" { extern "C" {
extern const uint8_t BOOTIMAGE_SYMBOL(start)[];
extern const uint8_t BOOTIMAGE_SYMBOL(end)[];
extern const uint8_t BOOTIMAGE_SYMBOL(start)[]; AVIAN_EXPORT const uint8_t* bootimageBin(unsigned* size)
extern const uint8_t BOOTIMAGE_SYMBOL(end)[]; {
AVIAN_EXPORT const uint8_t*
bootimageBin(unsigned* size)
{
*size = BOOTIMAGE_SYMBOL(end) - BOOTIMAGE_SYMBOL(start); *size = BOOTIMAGE_SYMBOL(end) - BOOTIMAGE_SYMBOL(start);
return BOOTIMAGE_SYMBOL(start); return BOOTIMAGE_SYMBOL(start);
} }
extern const uint8_t CODEIMAGE_SYMBOL(start)[]; extern const uint8_t CODEIMAGE_SYMBOL(start)[];
extern const uint8_t CODEIMAGE_SYMBOL(end)[]; extern const uint8_t CODEIMAGE_SYMBOL(end)[];
AVIAN_EXPORT const uint8_t* AVIAN_EXPORT const uint8_t* codeimageBin(unsigned* size)
codeimageBin(unsigned* size) {
{
*size = CODEIMAGE_SYMBOL(end) - CODEIMAGE_SYMBOL(start); *size = CODEIMAGE_SYMBOL(end) - CODEIMAGE_SYMBOL(start);
return CODEIMAGE_SYMBOL(start); return CODEIMAGE_SYMBOL(start);
} }
} }
#undef SYMBOL #undef SYMBOL
#endif//BOOT_IMAGE #endif // BOOT_IMAGE
#ifdef BOOT_CLASSPATH #ifdef BOOT_CLASSPATH
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER)) #if (!defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_classpath_jar_##x #define SYMBOL(x) binary_classpath_jar_##x
#else #else
# define SYMBOL(x) _binary_classpath_jar_##x #define SYMBOL(x) _binary_classpath_jar_##x
#endif #endif
extern "C" { extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
extern const uint8_t SYMBOL(start)[]; AVIAN_EXPORT const uint8_t* classpathJar(unsigned* size)
extern const uint8_t SYMBOL(end)[]; {
AVIAN_EXPORT const uint8_t*
classpathJar(unsigned* size)
{
*size = SYMBOL(end) - SYMBOL(start); *size = SYMBOL(end) - SYMBOL(start);
return SYMBOL(start); return SYMBOL(start);
} }
} }
#undef SYMBOL #undef SYMBOL
#endif//BOOT_CLASSPATH #endif // BOOT_CLASSPATH

View File

@ -1,6 +1,6 @@
#ifndef FIELD #ifndef FIELD
# define FIELD(name) #define FIELD(name)
# define FIELD_DEFINED #define FIELD_DEFINED
#endif #endif
FIELD(magic) FIELD(magic)
@ -23,13 +23,13 @@ FIELD(methodTreeSentinal)
FIELD(virtualThunks) FIELD(virtualThunks)
#ifdef FIELD_DEFINED #ifdef FIELD_DEFINED
# undef FIELD #undef FIELD
# undef FIELD_DEFINED #undef FIELD_DEFINED
#endif #endif
#ifndef THUNK_FIELD #ifndef THUNK_FIELD
# define THUNK_FIELD(name) #define THUNK_FIELD(name)
# define THUNK_FIELD_DEFINED #define THUNK_FIELD_DEFINED
#endif #endif
THUNK_FIELD(default_); THUNK_FIELD(default_);
@ -40,6 +40,6 @@ THUNK_FIELD(stackOverflow);
THUNK_FIELD(table); THUNK_FIELD(table);
#ifdef THUNK_FIELD_DEFINED #ifdef THUNK_FIELD_DEFINED
# undef THUNK_FIELD #undef THUNK_FIELD
# undef THUNK_FIELD_DEFINED #undef THUNK_FIELD_DEFINED
#endif #endif

View File

@ -6,21 +6,20 @@ const unsigned NAME(BootShift) = 32 - avian::util::log(NAME(BytesPerWord));
const unsigned NAME(BootFlatConstant) = 1 << NAME(BootShift); const unsigned NAME(BootFlatConstant) = 1 << NAME(BootShift);
const unsigned NAME(BootHeapOffset) = 1 << (NAME(BootShift) + 1); const unsigned NAME(BootHeapOffset) = 1 << (NAME(BootShift) + 1);
inline unsigned inline unsigned LABEL(codeMapSize)(unsigned codeSize)
LABEL(codeMapSize)(unsigned codeSize)
{ {
return avian::util::ceilingDivide(codeSize, TargetBitsPerWord) * TargetBytesPerWord; return avian::util::ceilingDivide(codeSize, TargetBitsPerWord)
}
inline unsigned
LABEL(heapMapSize)(unsigned heapSize)
{
return avian::util::ceilingDivide(heapSize, TargetBitsPerWord * TargetBytesPerWord)
* TargetBytesPerWord; * TargetBytesPerWord;
} }
inline object inline unsigned LABEL(heapMapSize)(unsigned heapSize)
LABEL(bootObject)(LABEL(uintptr_t)* heap, unsigned offset) {
return avian::util::ceilingDivide(heapSize,
TargetBitsPerWord * TargetBytesPerWord)
* TargetBytesPerWord;
}
inline object LABEL(bootObject)(LABEL(uintptr_t) * heap, unsigned offset)
{ {
if (offset) { if (offset) {
return reinterpret_cast<object>(heap + offset - 1); return reinterpret_cast<object>(heap + offset - 1);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -22,9 +22,9 @@ namespace local {
class MyClasspath : public Classpath { class MyClasspath : public Classpath {
public: public:
MyClasspath(Allocator* allocator): MyClasspath(Allocator* allocator) : allocator(allocator)
allocator(allocator) {
{ } }
virtual GcJclass* makeJclass(Thread* t, GcClass* class_) virtual GcJclass* makeJclass(Thread* t, GcClass* class_)
{ {
@ -97,14 +97,12 @@ class MyClasspath : public Classpath {
return jfield->vmField(); return jfield->vmField();
} }
virtual void virtual void clearInterrupted(Thread*)
clearInterrupted(Thread*)
{ {
// ignore // ignore
} }
virtual void virtual void runThread(Thread* t)
runThread(Thread* t)
{ {
GcMethod* method = resolveMethod(t, GcMethod* method = resolveMethod(t,
roots(t)->bootLoader(), roots(t)->bootLoader(),
@ -120,14 +118,12 @@ class MyClasspath : public Classpath {
vm::resolveNative(t, method); vm::resolveNative(t, method);
} }
virtual void virtual void interceptMethods(Thread*)
interceptMethods(Thread*)
{ {
// ignore // ignore
} }
virtual void virtual void preBoot(Thread*)
preBoot(Thread*)
{ {
// ignore // ignore
} }
@ -137,20 +133,17 @@ class MyClasspath : public Classpath {
return true; return true;
} }
virtual void virtual void boot(Thread*)
boot(Thread*)
{ {
// ignore // ignore
} }
virtual const char* virtual const char* bootClasspath()
bootClasspath()
{ {
return AVIAN_CLASSPATH; return AVIAN_CLASSPATH;
} }
virtual object virtual object makeDirectByteBuffer(Thread* t, void* p, jlong capacity)
makeDirectByteBuffer(Thread* t, void* p, jlong capacity)
{ {
GcClass* c GcClass* c
= resolveClass(t, roots(t)->bootLoader(), "java/nio/DirectByteBuffer"); = resolveClass(t, roots(t)->bootLoader(), "java/nio/DirectByteBuffer");
@ -161,15 +154,16 @@ class MyClasspath : public Classpath {
GcMethod* constructor = resolveMethod(t, c, "<init>", "(JI)V"); GcMethod* constructor = resolveMethod(t, c, "<init>", "(JI)V");
t->m->processor->invoke t->m->processor->invoke(t,
(t, constructor, instance, reinterpret_cast<int64_t>(p), constructor,
instance,
reinterpret_cast<int64_t>(p),
static_cast<int32_t>(capacity)); static_cast<int32_t>(capacity));
return instance; return instance;
} }
virtual void* virtual void* getDirectBufferAddress(Thread* t, object b)
getDirectBufferAddress(Thread* t, object b)
{ {
PROTECT(t, b); PROTECT(t, b);
@ -178,8 +172,7 @@ class MyClasspath : public Classpath {
return reinterpret_cast<void*>(fieldAtOffset<int64_t>(b, field->offset())); return reinterpret_cast<void*>(fieldAtOffset<int64_t>(b, field->offset()));
} }
virtual int64_t virtual int64_t getDirectBufferCapacity(Thread* t, object b)
getDirectBufferCapacity(Thread* t, object b)
{ {
PROTECT(t, b); PROTECT(t, b);
@ -219,14 +212,12 @@ class MyClasspath : public Classpath {
: caller->class_()->loader(); : caller->class_()->loader();
} }
virtual void virtual void shutDown(Thread*)
shutDown(Thread*)
{ {
// ignore // ignore
} }
virtual void virtual void dispose()
dispose()
{ {
allocator->free(this, sizeof(*this)); allocator->free(this, sizeof(*this));
} }
@ -242,11 +233,13 @@ void enumerateThreads(Thread* t,
{ {
if (*index < limit) { if (*index < limit) {
array->setBodyElement(t, *index, x->javaThread); array->setBodyElement(t, *index, x->javaThread);
++ (*index); ++(*index);
if (x->peer) enumerateThreads(t, x->peer, array, index, limit); if (x->peer)
enumerateThreads(t, x->peer, array, index, limit);
if (x->child) enumerateThreads(t, x->child, array, index, limit); if (x->child)
enumerateThreads(t, x->child, array, index, limit);
} }
} }
@ -256,8 +249,10 @@ void enumerateThreads(Thread* t,
namespace vm { namespace vm {
Classpath* Classpath* makeClasspath(System*,
makeClasspath(System*, Allocator* allocator, const char*, const char*) Allocator* allocator,
const char*,
const char*)
{ {
return new (allocator->allocate(sizeof(local::MyClasspath))) return new (allocator->allocate(sizeof(local::MyClasspath)))
local::MyClasspath(allocator); local::MyClasspath(allocator);
@ -266,8 +261,7 @@ makeClasspath(System*, Allocator* allocator, const char*, const char*)
} // namespace vm } // namespace vm
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Object_toString Avian_java_lang_Object_toString(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
object this_ = reinterpret_cast<object>(arguments[0]); object this_ = reinterpret_cast<object>(arguments[0]);
@ -279,26 +273,24 @@ Avian_java_lang_Object_toString
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Object_getVMClass Avian_java_lang_Object_getVMClass(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(objectClass(t, reinterpret_cast<object>(arguments[0]))); objectClass(t, reinterpret_cast<object>(arguments[0])));
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Object_wait Avian_java_lang_Object_wait(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
object this_ = reinterpret_cast<object>(arguments[0]); object this_ = reinterpret_cast<object>(arguments[0]);
int64_t milliseconds; memcpy(&milliseconds, arguments + 1, 8); int64_t milliseconds;
memcpy(&milliseconds, arguments + 1, 8);
vm::wait(t, this_, milliseconds); vm::wait(t, this_, milliseconds);
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Object_notify Avian_java_lang_Object_notify(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
object this_ = reinterpret_cast<object>(arguments[0]); object this_ = reinterpret_cast<object>(arguments[0]);
@ -306,8 +298,7 @@ Avian_java_lang_Object_notify
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Object_notifyAll Avian_java_lang_Object_notifyAll(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
object this_ = reinterpret_cast<object>(arguments[0]); object this_ = reinterpret_cast<object>(arguments[0]);
@ -315,8 +306,7 @@ Avian_java_lang_Object_notifyAll
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Object_hashCode Avian_java_lang_Object_hashCode(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
object this_ = reinterpret_cast<object>(arguments[0]); object this_ = reinterpret_cast<object>(arguments[0]);
@ -324,16 +314,16 @@ Avian_java_lang_Object_hashCode
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Object_clone Avian_java_lang_Object_clone(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(clone(t, reinterpret_cast<object>(arguments[0]))); clone(t, reinterpret_cast<object>(arguments[0])));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_io_ObjectInputStream_makeInstance Avian_java_io_ObjectInputStream_makeInstance(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
GcClass* c = cast<GcClass>(t, reinterpret_cast<object>(arguments[0])); GcClass* c = cast<GcClass>(t, reinterpret_cast<object>(arguments[0]));
@ -341,15 +331,17 @@ Avian_java_io_ObjectInputStream_makeInstance
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_LegacyObjectInputStream_makeInstance Avian_avian_LegacyObjectInputStream_makeInstance(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
return Avian_java_io_ObjectInputStream_makeInstance(t, NULL, arguments); return Avian_java_io_ObjectInputStream_makeInstance(t, NULL, arguments);
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_reflect_Field_getPrimitive Avian_java_lang_reflect_Field_getPrimitive(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object instance = reinterpret_cast<object>(arguments[0]); object instance = reinterpret_cast<object>(arguments[0]);
int code = arguments[1]; int code = arguments[1];
@ -378,8 +370,9 @@ Avian_java_lang_reflect_Field_getPrimitive
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_reflect_Field_getObject Avian_java_lang_reflect_Field_getObject(Thread*,
(Thread*, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object instance = reinterpret_cast<object>(arguments[0]); object instance = reinterpret_cast<object>(arguments[0]);
int offset = arguments[1]; int offset = arguments[1];
@ -388,13 +381,15 @@ Avian_java_lang_reflect_Field_getObject
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_reflect_Field_setPrimitive Avian_java_lang_reflect_Field_setPrimitive(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object instance = reinterpret_cast<object>(arguments[0]); object instance = reinterpret_cast<object>(arguments[0]);
int code = arguments[1]; int code = arguments[1];
int offset = arguments[2]; int offset = arguments[2];
int64_t value; memcpy(&value, arguments + 3, 8); int64_t value;
memcpy(&value, arguments + 3, 8);
switch (code) { switch (code) {
case ByteField: case ByteField:
@ -427,8 +422,9 @@ Avian_java_lang_reflect_Field_setPrimitive
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_reflect_Field_setObject Avian_java_lang_reflect_Field_setObject(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object instance = reinterpret_cast<object>(arguments[0]); object instance = reinterpret_cast<object>(arguments[0]);
int offset = arguments[1]; int offset = arguments[1];
@ -438,8 +434,9 @@ Avian_java_lang_reflect_Field_setObject
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_reflect_Constructor_make Avian_java_lang_reflect_Constructor_make(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
GcClass* c = cast<GcClass>(t, reinterpret_cast<object>(arguments[0])); GcClass* c = cast<GcClass>(t, reinterpret_cast<object>(arguments[0]));
@ -447,15 +444,15 @@ Avian_java_lang_reflect_Constructor_make
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_getCaller Avian_java_lang_reflect_Method_getCaller(Thread* t, object, uintptr_t*)
(Thread* t, object, uintptr_t*)
{ {
return reinterpret_cast<int64_t>(getCaller(t, 2)); return reinterpret_cast<int64_t>(getCaller(t, 2));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_invoke Avian_java_lang_reflect_Method_invoke(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
GcMethod* method = cast<GcMethod>(t, reinterpret_cast<object>(arguments[0])); GcMethod* method = cast<GcMethod>(t, reinterpret_cast<object>(arguments[0]));
object instance = reinterpret_cast<object>(arguments[1]); object instance = reinterpret_cast<object>(arguments[1]);
@ -471,14 +468,14 @@ Avian_java_lang_reflect_Method_invoke
unsigned returnCode = method->returnCode(); unsigned returnCode = method->returnCode();
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(translateInvokeResult(
(translateInvokeResult t, returnCode, t->m->processor->invokeArray(t, method, instance, args)));
(t, returnCode, t->m->processor->invokeArray(t, method, instance, args)));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_reflect_Array_getLength Avian_java_lang_reflect_Array_getLength(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object array = reinterpret_cast<object>(arguments[0]); object array = reinterpret_cast<object>(arguments[0]);
@ -496,8 +493,9 @@ Avian_java_lang_reflect_Array_getLength
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_reflect_Array_makeObjectArray Avian_java_lang_reflect_Array_makeObjectArray(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
GcJclass* elementType GcJclass* elementType
= cast<GcJclass>(t, reinterpret_cast<object>(arguments[0])); = cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]));
@ -508,38 +506,41 @@ Avian_java_lang_reflect_Array_makeObjectArray
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Float_floatToRawIntBits Avian_java_lang_Float_floatToRawIntBits(Thread*,
(Thread*, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
return static_cast<int32_t>(*arguments); return static_cast<int32_t>(*arguments);
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Float_intBitsToFloat Avian_java_lang_Float_intBitsToFloat(Thread*, object, uintptr_t* arguments)
(Thread*, object, uintptr_t* arguments)
{ {
return static_cast<int32_t>(*arguments); return static_cast<int32_t>(*arguments);
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Double_doubleToRawLongBits Avian_java_lang_Double_doubleToRawLongBits(Thread*,
(Thread*, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
int64_t v; memcpy(&v, arguments, 8); int64_t v;
memcpy(&v, arguments, 8);
return v; return v;
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Double_longBitsToDouble Avian_java_lang_Double_longBitsToDouble(Thread*,
(Thread*, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
int64_t v; memcpy(&v, arguments, 8); int64_t v;
memcpy(&v, arguments, 8);
return v; return v;
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_String_intern Avian_java_lang_String_intern(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
object this_ = reinterpret_cast<object>(arguments[0]); object this_ = reinterpret_cast<object>(arguments[0]);
@ -562,10 +563,10 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_System_arraycopy Avian_java_lang_System_arraycopy(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
arrayCopy(t, reinterpret_cast<object>(arguments[0]), arrayCopy(t,
reinterpret_cast<object>(arguments[0]),
arguments[1], arguments[1],
reinterpret_cast<object>(arguments[2]), reinterpret_cast<object>(arguments[2]),
arguments[3], arguments[3],
@ -573,8 +574,9 @@ Avian_java_lang_System_arraycopy
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_System_identityHashCode Avian_java_lang_System_identityHashCode(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object o = reinterpret_cast<object>(arguments[0]); object o = reinterpret_cast<object>(arguments[0]);
@ -612,15 +614,15 @@ extern "C" AVIAN_EXPORT void JNICALL
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Runtime_gc Avian_java_lang_Runtime_gc(Thread* t, object, uintptr_t*)
(Thread* t, object, uintptr_t*)
{ {
collect(t, Heap::MajorCollection); collect(t, Heap::MajorCollection);
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Runtime_addShutdownHook Avian_java_lang_Runtime_addShutdownHook(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object hook = reinterpret_cast<object>(arguments[1]); object hook = reinterpret_cast<object>(arguments[1]);
PROTECT(t, hook); PROTECT(t, hook);
@ -633,15 +635,15 @@ Avian_java_lang_Runtime_addShutdownHook
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Throwable_trace Avian_java_lang_Throwable_trace(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t>(getTrace(t, arguments[0])); return reinterpret_cast<int64_t>(getTrace(t, arguments[0]));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Throwable_resolveTrace Avian_java_lang_Throwable_resolveTrace(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object trace = reinterpret_cast<object>(*arguments); object trace = reinterpret_cast<object>(*arguments);
PROTECT(t, trace); PROTECT(t, trace);
@ -661,63 +663,61 @@ Avian_java_lang_Throwable_resolveTrace
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Thread_currentThread Avian_java_lang_Thread_currentThread(Thread* t, object, uintptr_t*)
(Thread* t, object, uintptr_t*)
{ {
return reinterpret_cast<int64_t>(t->javaThread); return reinterpret_cast<int64_t>(t->javaThread);
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Thread_doStart Avian_java_lang_Thread_doStart(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t>( return reinterpret_cast<int64_t>(
startThread(t, cast<GcThread>(t, reinterpret_cast<object>(*arguments)))); startThread(t, cast<GcThread>(t, reinterpret_cast<object>(*arguments))));
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Thread_interrupt Avian_java_lang_Thread_interrupt(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
int64_t peer; memcpy(&peer, arguments, 8); int64_t peer;
memcpy(&peer, arguments, 8);
threadInterrupt(t, reinterpret_cast<Thread*>(peer)->javaThread); threadInterrupt(t, reinterpret_cast<Thread*>(peer)->javaThread);
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Thread_interrupted Avian_java_lang_Thread_interrupted(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
int64_t peer; memcpy(&peer, arguments, 8); int64_t peer;
memcpy(&peer, arguments, 8);
return threadIsInterrupted return threadIsInterrupted(
(t, reinterpret_cast<Thread*>(peer)->javaThread, true); t, reinterpret_cast<Thread*>(peer)->javaThread, true);
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Thread_getStackTrace Avian_java_lang_Thread_getStackTrace(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
int64_t peer; memcpy(&peer, arguments, 8); int64_t peer;
memcpy(&peer, arguments, 8);
if (reinterpret_cast<Thread*>(peer) == t) { if (reinterpret_cast<Thread*>(peer) == t) {
return reinterpret_cast<int64_t>(makeTrace(t)); return reinterpret_cast<int64_t>(makeTrace(t));
} else { } else {
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(t->m->processor->getStackTrace(t, reinterpret_cast<Thread*>(peer))); t->m->processor->getStackTrace(t, reinterpret_cast<Thread*>(peer)));
} }
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Thread_activeCount Avian_java_lang_Thread_activeCount(Thread* t, object, uintptr_t*)
(Thread* t, object, uintptr_t*)
{ {
return t->m->liveCount; return t->m->liveCount;
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Thread_enumerate Avian_java_lang_Thread_enumerate(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
GcArray* array = cast<GcArray>(t, reinterpret_cast<object>(*arguments)); GcArray* array = cast<GcArray>(t, reinterpret_cast<object>(*arguments));
@ -731,15 +731,13 @@ Avian_java_lang_Thread_enumerate
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
Avian_java_lang_Thread_yield Avian_java_lang_Thread_yield(Thread* t, object, uintptr_t*)
(Thread* t, object, uintptr_t*)
{ {
t->m->system->yield(); t->m->system->yield();
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Atomic_getOffset Avian_avian_Atomic_getOffset(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
return cast<GcJfield>(t, reinterpret_cast<object>(arguments[0])) return cast<GcJfield>(t, reinterpret_cast<object>(arguments[0]))
->vmField() ->vmField()
@ -747,8 +745,9 @@ Avian_avian_Atomic_getOffset
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_objectFieldOffset Avian_sun_misc_Unsafe_objectFieldOffset(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
return cast<GcJfield>(t, reinterpret_cast<object>(arguments[1])) return cast<GcJfield>(t, reinterpret_cast<object>(arguments[1]))
->vmField() ->vmField()
@ -756,16 +755,18 @@ Avian_sun_misc_Unsafe_objectFieldOffset
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Atomic_compareAndSwapObject Avian_avian_Atomic_compareAndSwapObject(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
object target = reinterpret_cast<object>(arguments[0]); object target = reinterpret_cast<object>(arguments[0]);
int64_t offset; memcpy(&offset, arguments + 1, 8); int64_t offset;
memcpy(&offset, arguments + 1, 8);
uintptr_t expect = arguments[3]; uintptr_t expect = arguments[3];
uintptr_t update = arguments[4]; uintptr_t update = arguments[4];
bool success = atomicCompareAndSwap bool success = atomicCompareAndSwap(
(&fieldAtOffset<uintptr_t>(target, offset), expect, update); &fieldAtOffset<uintptr_t>(target, offset), expect, update);
if (success) { if (success) {
mark(t, target, offset); mark(t, target, offset);
@ -775,8 +776,9 @@ Avian_avian_Atomic_compareAndSwapObject
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_isAssignableFrom Avian_avian_Classes_isAssignableFrom(Thread* t,
(Thread* t, object, uintptr_t* arguments) object,
uintptr_t* arguments)
{ {
GcClass* this_ = cast<GcClass>(t, reinterpret_cast<object>(arguments[0])); GcClass* this_ = cast<GcClass>(t, reinterpret_cast<object>(arguments[0]));
GcClass* that = cast<GcClass>(t, reinterpret_cast<object>(arguments[1])); GcClass* that = cast<GcClass>(t, reinterpret_cast<object>(arguments[1]));
@ -789,16 +791,14 @@ Avian_avian_Classes_isAssignableFrom
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_getVMClass Avian_avian_Classes_getVMClass(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
return reinterpret_cast<int64_t> return reinterpret_cast<int64_t>(
(objectClass(t, reinterpret_cast<object>(arguments[0]))); objectClass(t, reinterpret_cast<object>(arguments[0])));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_makeMethod Avian_avian_Classes_makeMethod(Thread* t, object, uintptr_t* arguments)
(Thread* t, object, uintptr_t* arguments)
{ {
GcMethod* method = cast<GcMethod>( GcMethod* method = cast<GcMethod>(
t, t,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -53,14 +53,18 @@ Context::Context(vm::System* system,
- regFile->generalRegisters.start), - regFile->generalRegisters.start),
targetInfo(arch->targetInfo()) targetInfo(arch->targetInfo())
{ {
for (unsigned i = regFile->generalRegisters.start; i < regFile->generalRegisters.limit; ++i) { for (unsigned i = regFile->generalRegisters.start;
i < regFile->generalRegisters.limit;
++i) {
new (registerResources + i) RegisterResource(arch->reserved(i)); new (registerResources + i) RegisterResource(arch->reserved(i));
if (registerResources[i].reserved) { if (registerResources[i].reserved) {
-- availableGeneralRegisterCount; --availableGeneralRegisterCount;
} }
} }
for (unsigned i = regFile->floatRegisters.start; i < regFile->floatRegisters.limit; ++i) { for (unsigned i = regFile->floatRegisters.start;
i < regFile->floatRegisters.limit;
++i) {
new (registerResources + i) RegisterResource(arch->reserved(i)); new (registerResources + i) RegisterResource(arch->reserved(i));
} }
} }

View File

@ -37,8 +37,9 @@ class ConstantPoolNode;
class ForkState; class ForkState;
class Block; class Block;
template<class T> template <class T>
List<T>* reverseDestroy(List<T>* cell) { List<T>* reverseDestroy(List<T>* cell)
{
List<T>* previous = 0; List<T>* previous = 0;
while (cell) { while (cell) {
List<T>* next = cell->next; List<T>* next = cell->next;
@ -93,7 +94,9 @@ class LogicalCode {
class Context { class Context {
public: public:
Context(vm::System* system, Assembler* assembler, vm::Zone* zone, Context(vm::System* system,
Assembler* assembler,
vm::Zone* zone,
Compiler::Client* client); Compiler::Client* client);
vm::System* system; vm::System* system;
@ -128,12 +131,14 @@ class Context {
ir::TargetInfo targetInfo; ir::TargetInfo targetInfo;
}; };
inline Aborter* getAborter(Context* c) { inline Aborter* getAborter(Context* c)
{
return c->system; return c->system;
} }
template<class T> template <class T>
List<T>* cons(Context* c, const T& value, List<T>* next) { List<T>* cons(Context* c, const T& value, List<T>* next)
{
return new (c->zone) List<T>(value, next); return new (c->zone) List<T>(value, next);
} }

File diff suppressed because it is too large Load Diff

View File

@ -33,25 +33,41 @@ class Event {
virtual void compile(Context* c) = 0; virtual void compile(Context* c) = 0;
virtual bool isBranch() { return false; } virtual bool isBranch()
{
virtual bool allExits() { return false; } return false;
}
virtual Local* locals() { return localsBefore; }
virtual bool allExits()
{
return false;
}
virtual Local* locals()
{
return localsBefore;
}
void addRead(Context* c, Value* v, Read* r); void addRead(Context* c, Value* v, Read* r);
void addRead(Context* c, Value* v, const SiteMask& mask, void addRead(Context* c,
Value* v,
const SiteMask& mask,
Value* successor = 0); Value* successor = 0);
void addReads(Context* c, Value* v, unsigned size, void addReads(Context* c,
const SiteMask& lowMask, Value* lowSuccessor, Value* v,
const SiteMask& highMask, Value* highSuccessor); unsigned size,
const SiteMask& lowMask,
Value* lowSuccessor,
const SiteMask& highMask,
Value* highSuccessor);
void addReads(Context* c, Value* v, unsigned size, void addReads(Context* c,
const SiteMask& lowMask, const SiteMask& highMask); Value* v,
unsigned size,
const SiteMask& lowMask,
const SiteMask& highMask);
CodePromise* makeCodePromise(Context* c); CodePromise* makeCodePromise(Context* c);
@ -82,7 +98,9 @@ class StubReadPair {
class JunctionState { class JunctionState {
public: public:
JunctionState(unsigned frameFootprint): frameFootprint(frameFootprint) { } JunctionState(unsigned frameFootprint) : frameFootprint(frameFootprint)
{
}
unsigned frameFootprint; unsigned frameFootprint;
StubReadPair reads[0]; StubReadPair reads[0];
@ -90,12 +108,19 @@ class JunctionState {
class Link { class Link {
public: public:
Link(Event* predecessor, Link* nextPredecessor, Event* successor, Link(Event* predecessor,
Link* nextSuccessor, ForkState* forkState): Link* nextPredecessor,
predecessor(predecessor), nextPredecessor(nextPredecessor), Event* successor,
successor(successor), nextSuccessor(nextSuccessor), forkState(forkState), Link* nextSuccessor,
ForkState* forkState)
: predecessor(predecessor),
nextPredecessor(nextPredecessor),
successor(successor),
nextSuccessor(nextSuccessor),
forkState(forkState),
junctionState(0) junctionState(0)
{ } {
}
unsigned countPredecessors(); unsigned countPredecessors();
Link* lastPredecessor(); Link* lastPredecessor();
@ -109,9 +134,12 @@ class Link {
JunctionState* junctionState; JunctionState* junctionState;
}; };
Link* Link* link(Context* c,
link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor, Event* predecessor,
Link* nextSuccessor, ForkState* forkState); Link* nextPredecessor,
Event* successor,
Link* nextSuccessor,
ForkState* forkState);
void appendCall(Context* c, void appendCall(Context* c,
Value* address, Value* address,
@ -142,12 +170,14 @@ void appendTranslate(Context* c,
Value* first, Value* first,
Value* result); Value* result);
void void appendOperation(Context* c, lir::Operation op);
appendOperation(Context* c, lir::Operation op);
void void appendMemory(Context* c,
appendMemory(Context* c, Value* base, int displacement, Value* index, Value* base,
unsigned scale, Value* result); int displacement,
Value* index,
unsigned scale,
Value* result);
void appendBranch(Context* c, void appendBranch(Context* c,
lir::TernaryOperation op, lir::TernaryOperation op,
@ -161,18 +191,17 @@ void appendJump(Context* c,
bool exit = false, bool exit = false,
bool cleanLocals = false); bool cleanLocals = false);
void void appendBoundsCheck(Context* c,
appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, Value* object,
Value* index, intptr_t handler); unsigned lengthOffset,
Value* index,
intptr_t handler);
void void appendFrameSite(Context* c, Value* value, int index);
appendFrameSite(Context* c, Value* value, int index);
void void appendSaveLocals(Context* c);
appendSaveLocals(Context* c);
void void appendDummy(Context* c);
appendDummy(Context* c);
void appendBuddy(Context* c, Value* original, Value* buddy); void appendBuddy(Context* c, Value* original, Value* buddy);

View File

@ -19,13 +19,14 @@ namespace avian {
namespace codegen { namespace codegen {
namespace compiler { namespace compiler {
unsigned totalFrameSize(Context* c) { unsigned totalFrameSize(Context* c)
return c->alignedFrameSize {
+ c->arch->frameHeaderSize() return c->alignedFrameSize + c->arch->frameHeaderSize()
+ c->arch->argumentFootprint(c->parameterFootprint); + c->arch->argumentFootprint(c->parameterFootprint);
} }
int frameIndex(Context* c, int localIndex) { int frameIndex(Context* c, int localIndex)
{
assertT(c, localIndex >= 0); assertT(c, localIndex >= 0);
int index = c->alignedFrameSize + c->parameterFootprint - localIndex - 1; int index = c->alignedFrameSize + c->parameterFootprint - localIndex - 1;
@ -42,13 +43,15 @@ int frameIndex(Context* c, int localIndex) {
return index; return index;
} }
unsigned frameIndexToOffset(Context* c, unsigned frameIndex) { unsigned frameIndexToOffset(Context* c, unsigned frameIndex)
{
assertT(c, frameIndex < totalFrameSize(c)); assertT(c, frameIndex < totalFrameSize(c));
return (frameIndex + c->arch->frameFooterSize()) * c->targetInfo.pointerSize; return (frameIndex + c->arch->frameFooterSize()) * c->targetInfo.pointerSize;
} }
unsigned offsetToFrameIndex(Context* c, unsigned offset) { unsigned offsetToFrameIndex(Context* c, unsigned offset)
{
assertT(c, assertT(c,
static_cast<int>((offset / c->targetInfo.pointerSize) static_cast<int>((offset / c->targetInfo.pointerSize)
- c->arch->frameFooterSize()) >= 0); - c->arch->frameFooterSize()) >= 0);
@ -59,43 +62,50 @@ unsigned offsetToFrameIndex(Context* c, unsigned offset) {
return (offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize(); return (offset / c->targetInfo.pointerSize) - c->arch->frameFooterSize();
} }
unsigned frameBase(Context* c) { unsigned frameBase(Context* c)
return c->alignedFrameSize {
- c->arch->frameReturnAddressSize() return c->alignedFrameSize - c->arch->frameReturnAddressSize()
- c->arch->frameFooterSize() - c->arch->frameFooterSize() + c->arch->frameHeaderSize();
+ c->arch->frameHeaderSize();
} }
FrameIterator::Element::Element(Value* value, unsigned localIndex): FrameIterator::Element::Element(Value* value, unsigned localIndex)
value(value), localIndex(localIndex) : value(value), localIndex(localIndex)
{ } {
}
int FrameIterator::Element::frameIndex(Context* c)
int FrameIterator::Element::frameIndex(Context* c) { {
return compiler::frameIndex(c, this->localIndex); return compiler::frameIndex(c, this->localIndex);
} }
FrameIterator::FrameIterator(Context* c, Stack* stack, Local* locals, FrameIterator::FrameIterator(Context* c,
bool includeEmpty): Stack* stack,
stack(stack), locals(locals), localIndex(c->localFootprint - 1), Local* locals,
bool includeEmpty)
: stack(stack),
locals(locals),
localIndex(c->localFootprint - 1),
includeEmpty(includeEmpty) includeEmpty(includeEmpty)
{ } {
}
bool FrameIterator::hasMore() { bool FrameIterator::hasMore()
{
if (not includeEmpty) { if (not includeEmpty) {
while (stack and stack->value == 0) { while (stack and stack->value == 0) {
stack = stack->next; stack = stack->next;
} }
while (localIndex >= 0 and locals[localIndex].value == 0) { while (localIndex >= 0 and locals[localIndex].value == 0) {
-- localIndex; --localIndex;
} }
} }
return stack != 0 or localIndex >= 0; return stack != 0 or localIndex >= 0;
} }
FrameIterator::Element FrameIterator::next(Context* c) { FrameIterator::Element FrameIterator::next(Context* c)
{
Value* v; Value* v;
unsigned li; unsigned li;
if (stack) { if (stack) {
@ -107,17 +117,16 @@ FrameIterator::Element FrameIterator::next(Context* c) {
Local* l = locals + localIndex; Local* l = locals + localIndex;
v = l->value; v = l->value;
li = localIndex; li = localIndex;
-- localIndex; --localIndex;
} }
return Element(v, li); return Element(v, li);
} }
Stack* stack(Context* c, Value* value, Stack* next) { Stack* stack(Context* c, Value* value, Stack* next)
return new(c->zone) Stack(next ? next->index + 1 : 0, value, next); {
return new (c->zone) Stack(next ? next->index + 1 : 0, value, next);
} }
} // namespace compiler } // namespace compiler
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian

View File

@ -37,7 +37,9 @@ class FrameIterator {
const unsigned localIndex; const unsigned localIndex;
}; };
FrameIterator(Context* c, Stack* stack, Local* locals, FrameIterator(Context* c,
Stack* stack,
Local* locals,
bool includeEmpty = false); bool includeEmpty = false);
bool hasMore(); bool hasMore();
@ -57,9 +59,10 @@ class Local {
class Stack { class Stack {
public: public:
Stack(unsigned index, Value* value, Stack* next): Stack(unsigned index, Value* value, Stack* next)
index(index), value(value), next(next) : index(index), value(value), next(next)
{ } {
}
unsigned index; unsigned index;
Value* value; Value* value;

View File

@ -23,29 +23,33 @@ LogicalInstruction::LogicalInstruction(int index, Stack* stack, Local* locals)
locals(locals), locals(locals),
machineOffset(0), machineOffset(0),
/*subroutine(0), */ index(index) /*subroutine(0), */ index(index)
{ } {
}
LogicalInstruction* LogicalInstruction::next(Context* c) { LogicalInstruction* LogicalInstruction::next(Context* c)
{
LogicalInstruction* i = this; LogicalInstruction* i = this;
for (size_t n = i->index + 1; n < c->logicalCode.count(); ++n) { for (size_t n = i->index + 1; n < c->logicalCode.count(); ++n) {
i = c->logicalCode[n]; i = c->logicalCode[n];
if (i) return i; if (i)
return i;
} }
return 0; return 0;
} }
unsigned unsigned machineOffset(Context* c, int logicalIp)
machineOffset(Context* c, int logicalIp)
{ {
return c->logicalCode[logicalIp]->machineOffset->value(); return c->logicalCode[logicalIp]->machineOffset->value();
} }
Block::Block(Event* head): Block::Block(Event* head)
head(head), nextBlock(0), nextInstruction(0), assemblerBlock(0), start(0) : head(head), nextBlock(0), nextInstruction(0), assemblerBlock(0), start(0)
{ } {
}
Block* block(Context* c, Event* head) { Block* block(Context* c, Event* head)
return new(c->zone) Block(head); {
return new (c->zone) Block(head);
} }
} // namespace compiler } // namespace compiler

View File

@ -24,17 +24,21 @@ class ForkElement {
bool local; bool local;
}; };
class ForkState: public Compiler::State { class ForkState : public Compiler::State {
public: public:
ForkState(Stack* stack, Local* locals, List<Value*>* saved, Event* predecessor, ForkState(Stack* stack,
unsigned logicalIp): Local* locals,
stack(stack), List<Value*>* saved,
Event* predecessor,
unsigned logicalIp)
: stack(stack),
locals(locals), locals(locals),
saved(saved), saved(saved),
predecessor(predecessor), predecessor(predecessor),
logicalIp(logicalIp), logicalIp(logicalIp),
readCount(0) readCount(0)
{ } {
}
Stack* stack; Stack* stack;
Local* locals; Local* locals;

View File

@ -18,15 +18,18 @@ namespace avian {
namespace codegen { namespace codegen {
namespace compiler { namespace compiler {
CodePromise::CodePromise(Context* c, CodePromise* next): CodePromise::CodePromise(Context* c, CodePromise* next)
c(c), offset(0), next(next) : c(c), offset(0), next(next)
{ } {
}
CodePromise::CodePromise(Context* c, Promise* offset): CodePromise::CodePromise(Context* c, Promise* offset)
c(c), offset(offset), next(0) : c(c), offset(offset), next(0)
{ } {
}
int64_t CodePromise::value() { int64_t CodePromise::value()
{
if (resolved()) { if (resolved()) {
return reinterpret_cast<intptr_t>(c->machineCode + offset->value()); return reinterpret_cast<intptr_t>(c->machineCode + offset->value());
} }
@ -34,43 +37,52 @@ int64_t CodePromise::value() {
abort(c); abort(c);
} }
bool CodePromise::resolved() { bool CodePromise::resolved()
{
return c->machineCode != 0 and offset and offset->resolved(); return c->machineCode != 0 and offset and offset->resolved();
} }
CodePromise* codePromise(Context* c, Promise* offset) { CodePromise* codePromise(Context* c, Promise* offset)
{
return new (c->zone) CodePromise(c, offset); return new (c->zone) CodePromise(c, offset);
} }
Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) { Promise* shiftMaskPromise(Context* c,
Promise* base,
unsigned shift,
int64_t mask)
{
return new (c->zone) ShiftMaskPromise(base, shift, mask); return new (c->zone) ShiftMaskPromise(base, shift, mask);
} }
Promise* combinedPromise(Context* c, Promise* low, Promise* high) { Promise* combinedPromise(Context* c, Promise* low, Promise* high)
{
return new (c->zone) CombinedPromise(low, high); return new (c->zone) CombinedPromise(low, high);
} }
Promise* resolvedPromise(Context* c, int64_t value) { Promise* resolvedPromise(Context* c, int64_t value)
{
return new (c->zone) ResolvedPromise(value); return new (c->zone) ResolvedPromise(value);
} }
class IpPromise: public Promise { class IpPromise : public Promise {
public: public:
IpPromise(Context* c, int logicalIp): IpPromise(Context* c, int logicalIp) : c(c), logicalIp(logicalIp)
c(c), {
logicalIp(logicalIp) }
{ }
virtual int64_t value() { virtual int64_t value()
{
if (resolved()) { if (resolved()) {
return reinterpret_cast<intptr_t> return reinterpret_cast<intptr_t>(c->machineCode
(c->machineCode + machineOffset(c, logicalIp)); + machineOffset(c, logicalIp));
} }
abort(c); abort(c);
} }
virtual bool resolved() { virtual bool resolved()
{
return c->machineCode != 0 return c->machineCode != 0
and c->logicalCode[logicalIp]->machineOffset->resolved(); and c->logicalCode[logicalIp]->machineOffset->resolved();
} }
@ -79,16 +91,19 @@ class IpPromise: public Promise {
int logicalIp; int logicalIp;
}; };
Promise* ipPromise(Context* c, int logicalIp) { Promise* ipPromise(Context* c, int logicalIp)
{
return new (c->zone) IpPromise(c, logicalIp); return new (c->zone) IpPromise(c, logicalIp);
} }
class PoolPromise : public Promise {
class PoolPromise: public Promise {
public: public:
PoolPromise(Context* c, int key): c(c), key(key) { } PoolPromise(Context* c, int key) : c(c), key(key)
{
}
virtual int64_t value() { virtual int64_t value()
{
if (resolved()) { if (resolved()) {
return reinterpret_cast<int64_t>( return reinterpret_cast<int64_t>(
c->machineCode c->machineCode
@ -99,7 +114,8 @@ class PoolPromise: public Promise {
abort(c); abort(c);
} }
virtual bool resolved() { virtual bool resolved()
{
return c->machineCode != 0; return c->machineCode != 0;
} }
@ -107,11 +123,11 @@ class PoolPromise: public Promise {
int key; int key;
}; };
Promise* poolPromise(Context* c, int key) { Promise* poolPromise(Context* c, int key)
return new(c->zone) PoolPromise(c, key); {
return new (c->zone) PoolPromise(c, key);
} }
} // namespace compiler } // namespace compiler
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian

View File

@ -15,8 +15,7 @@ namespace avian {
namespace codegen { namespace codegen {
namespace compiler { namespace compiler {
class CodePromise : public Promise {
class CodePromise: public Promise {
public: public:
CodePromise(Context* c, CodePromise* next); CodePromise(Context* c, CodePromise* next);
@ -33,7 +32,10 @@ class CodePromise: public Promise {
CodePromise* codePromise(Context* c, Promise* offset); CodePromise* codePromise(Context* c, Promise* offset);
Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask); Promise* shiftMaskPromise(Context* c,
Promise* base,
unsigned shift,
int64_t mask);
Promise* combinedPromise(Context* c, Promise* low, Promise* high); Promise* combinedPromise(Context* c, Promise* low, Promise* high);

View File

@ -20,43 +20,51 @@ namespace avian {
namespace codegen { namespace codegen {
namespace compiler { namespace compiler {
SingleRead::SingleRead(const SiteMask& mask, Value* successor)
: next_(0), mask(mask), high_(0), successor_(successor)
{
}
SingleRead::SingleRead(const SiteMask& mask, Value* successor): bool SingleRead::intersect(SiteMask* mask, unsigned)
next_(0), mask(mask), high_(0), successor_(successor) {
{ }
bool SingleRead::intersect(SiteMask* mask, unsigned) {
*mask = mask->intersectionWith(this->mask); *mask = mask->intersectionWith(this->mask);
return true; return true;
} }
Value* SingleRead::high(Context*) { Value* SingleRead::high(Context*)
{
return high_; return high_;
} }
Value* SingleRead::successor() { Value* SingleRead::successor()
{
return successor_; return successor_;
} }
bool SingleRead::valid() { bool SingleRead::valid()
{
return true; return true;
} }
void SingleRead::append(Context* c UNUSED, Read* r) { void SingleRead::append(Context* c UNUSED, Read* r)
{
assertT(c, next_ == 0); assertT(c, next_ == 0);
next_ = r; next_ = r;
} }
Read* SingleRead::next(Context*) { Read* SingleRead::next(Context*)
{
return next_; return next_;
} }
MultiRead::MultiRead(): MultiRead::MultiRead()
reads(0), lastRead(0), firstTarget(0), lastTarget(0), visited(false) : reads(0), lastRead(0), firstTarget(0), lastTarget(0), visited(false)
{ } {
}
bool MultiRead::intersect(SiteMask* mask, unsigned depth) { bool MultiRead::intersect(SiteMask* mask, unsigned depth)
{
if (depth > 0) { if (depth > 0) {
// short-circuit recursion to avoid poor performance in // short-circuit recursion to avoid poor performance in
// deeply-nested branches // deeply-nested branches
@ -81,11 +89,13 @@ bool MultiRead::intersect(SiteMask* mask, unsigned depth) {
return result; return result;
} }
Value* MultiRead::successor() { Value* MultiRead::successor()
{
return 0; return 0;
} }
bool MultiRead::valid() { bool MultiRead::valid()
{
bool result = false; bool result = false;
if (not visited) { if (not visited) {
visited = true; visited = true;
@ -103,7 +113,8 @@ bool MultiRead::valid() {
return result; return result;
} }
void MultiRead::append(Context* c, Read* r) { void MultiRead::append(Context* c, Read* r)
{
List<Read*>* cell = cons<Read*>(c, r, 0); List<Read*>* cell = cons<Read*>(c, r, 0);
if (lastRead == 0) { if (lastRead == 0) {
reads = cell; reads = cell;
@ -112,19 +123,21 @@ void MultiRead::append(Context* c, Read* r) {
} }
lastRead = cell; lastRead = cell;
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this); // fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
lastTarget->item = r; lastTarget->item = r;
} }
Read* MultiRead::next(Context* c) { Read* MultiRead::next(Context* c)
{
abort(c); abort(c);
} }
void MultiRead::allocateTarget(Context* c) { void MultiRead::allocateTarget(Context* c)
{
List<Read*>* cell = cons<Read*>(c, 0, 0); List<Read*>* cell = cons<Read*>(c, 0, 0);
// fprintf(stderr, "allocate target for %p: %p\n", this, cell); // fprintf(stderr, "allocate target for %p: %p\n", this, cell);
if (lastTarget) { if (lastTarget) {
lastTarget->next = cell; lastTarget->next = cell;
@ -134,7 +147,8 @@ void MultiRead::allocateTarget(Context* c) {
lastTarget = cell; lastTarget = cell;
} }
Read* MultiRead::nextTarget() { Read* MultiRead::nextTarget()
{
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget); // fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
Read* r = firstTarget->item; Read* r = firstTarget->item;
@ -142,12 +156,12 @@ Read* MultiRead::nextTarget() {
return r; return r;
} }
StubRead::StubRead() : next_(0), read(0), visited(false), valid_(true)
{
}
StubRead::StubRead(): bool StubRead::intersect(SiteMask* mask, unsigned depth)
next_(0), read(0), visited(false), valid_(true) {
{ }
bool StubRead::intersect(SiteMask* mask, unsigned depth) {
if (not visited) { if (not visited) {
visited = true; visited = true;
if (read) { if (read) {
@ -161,30 +175,33 @@ bool StubRead::intersect(SiteMask* mask, unsigned depth) {
return valid_; return valid_;
} }
Value* StubRead::successor() { Value* StubRead::successor()
{
return 0; return 0;
} }
bool StubRead::valid() { bool StubRead::valid()
{
return valid_; return valid_;
} }
void StubRead::append(Context* c UNUSED, Read* r) { void StubRead::append(Context* c UNUSED, Read* r)
{
assertT(c, next_ == 0); assertT(c, next_ == 0);
next_ = r; next_ = r;
} }
Read* StubRead::next(Context*) { Read* StubRead::next(Context*)
{
return next_; return next_;
} }
SingleRead* read(Context* c, const SiteMask& mask, Value* successor)
{
SingleRead* read(Context* c, const SiteMask& mask, Value* successor) {
assertT(c, assertT(c,
(mask.typeMask != 1 << lir::MemoryOperand) or mask.frameIndex >= 0); (mask.typeMask != 1 << lir::MemoryOperand) or mask.frameIndex >= 0);
return new(c->zone) SingleRead(mask, successor); return new (c->zone) SingleRead(mask, successor);
} }
} // namespace compiler } // namespace compiler

View File

@ -22,13 +22,16 @@ class Event;
class Read { class Read {
public: public:
Read(): Read() : value(0), event(0), eventNext(0)
value(0), event(0), eventNext(0) {
{ } }
virtual bool intersect(SiteMask* mask, unsigned depth = 0) = 0; virtual bool intersect(SiteMask* mask, unsigned depth = 0) = 0;
virtual Value* high(Context* c) { abort(c); } virtual Value* high(Context* c)
{
abort(c);
}
virtual Value* successor() = 0; virtual Value* successor() = 0;
@ -43,11 +46,12 @@ class Read {
Read* eventNext; Read* eventNext;
}; };
inline bool valid(Read* r) { inline bool valid(Read* r)
{
return r and r->valid(); return r and r->valid();
} }
class SingleRead: public Read { class SingleRead : public Read {
public: public:
SingleRead(const SiteMask& mask, Value* successor); SingleRead(const SiteMask& mask, Value* successor);
@ -69,8 +73,7 @@ class SingleRead: public Read {
Value* successor_; Value* successor_;
}; };
class MultiRead : public Read {
class MultiRead: public Read {
public: public:
MultiRead(); MultiRead();
@ -95,7 +98,7 @@ class MultiRead: public Read {
bool visited; bool visited;
}; };
class StubRead: public Read { class StubRead : public Read {
public: public:
StubRead(); StubRead();
@ -117,7 +120,6 @@ class StubRead: public Read {
SingleRead* read(Context* c, const SiteMask& mask, Value* successor = 0); SingleRead* read(Context* c, const SiteMask& mask, Value* successor = 0);
} // namespace compiler } // namespace compiler
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian

View File

@ -20,24 +20,25 @@ namespace avian {
namespace codegen { namespace codegen {
namespace compiler { namespace compiler {
RegisterAllocator::RegisterAllocator(Aborter* a, const RegisterFile* registerFile): RegisterAllocator::RegisterAllocator(Aborter* a,
a(a), const RegisterFile* registerFile)
registerFile(registerFile) : a(a), registerFile(registerFile)
{ } {
}
unsigned totalFrameSize(Context* c); unsigned totalFrameSize(Context* c);
Read* live(Context* c UNUSED, Value* v); Read* live(Context* c UNUSED, Value* v);
unsigned unsigned resourceCost(Context* c,
resourceCost(Context* c, Value* v, Resource* r, SiteMask mask, Value* v,
Resource* r,
SiteMask mask,
CostCalculator* costCalculator) CostCalculator* costCalculator)
{ {
if (r->reserved or r->freezeCount or r->referenceCount) { if (r->reserved or r->freezeCount or r->referenceCount) {
return Target::Impossible; return Target::Impossible;
} else { } else {
unsigned baseCost = unsigned baseCost = costCalculator ? costCalculator->cost(c, mask) : 0;
costCalculator ? costCalculator->cost(c, mask) : 0;
if (r->value) { if (r->value) {
assertT(c, r->value->findSite(r->site)); assertT(c, r->value->findSite(r->site));
@ -55,15 +56,23 @@ resourceCost(Context* c, Value* v, Resource* r, SiteMask mask,
} }
} }
bool bool pickRegisterTarget(Context* c,
pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target, int i,
unsigned* cost, CostCalculator* costCalculator) Value* v,
uint32_t mask,
int* target,
unsigned* cost,
CostCalculator* costCalculator)
{ {
if ((1 << i) & mask) { if ((1 << i) & mask) {
RegisterResource* r = c->registerResources + i; RegisterResource* r = c->registerResources + i;
unsigned myCost = resourceCost unsigned myCost
(c, v, r, SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex), costCalculator) = resourceCost(
+ Target::MinimumRegisterCost; c,
v,
r,
SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex),
costCalculator) + Target::MinimumRegisterCost;
if ((static_cast<uint32_t>(1) << i) == mask) { if ((static_cast<uint32_t>(1) << i) == mask) {
*cost = myCost; *cost = myCost;
@ -76,8 +85,10 @@ pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target,
return false; return false;
} }
int int pickRegisterTarget(Context* c,
pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost, Value* v,
uint32_t mask,
unsigned* cost,
CostCalculator* costCalculator) CostCalculator* costCalculator)
{ {
int target = lir::NoRegister; int target = lir::NoRegister;
@ -85,8 +96,8 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost,
if (mask & c->regFile->generalRegisters.mask) { if (mask & c->regFile->generalRegisters.mask) {
for (int i = c->regFile->generalRegisters.limit - 1; for (int i = c->regFile->generalRegisters.limit - 1;
i >= c->regFile->generalRegisters.start; --i) i >= c->regFile->generalRegisters.start;
{ --i) {
if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) {
return i; return i;
} }
@ -95,8 +106,8 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost,
if (mask & c->regFile->floatRegisters.mask) { if (mask & c->regFile->floatRegisters.mask) {
for (int i = c->regFile->floatRegisters.start; for (int i = c->regFile->floatRegisters.start;
i < static_cast<int>(c->regFile->floatRegisters.limit); ++i) i < static_cast<int>(c->regFile->floatRegisters.limit);
{ ++i) {
if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) {
return i; return i;
} }
@ -106,8 +117,9 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost,
return target; return target;
} }
Target Target pickRegisterTarget(Context* c,
pickRegisterTarget(Context* c, Value* v, uint32_t mask, Value* v,
uint32_t mask,
CostCalculator* costCalculator) CostCalculator* costCalculator)
{ {
unsigned cost; unsigned cost;
@ -115,25 +127,28 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask,
return Target(number, lir::RegisterOperand, cost); return Target(number, lir::RegisterOperand, cost);
} }
unsigned unsigned frameCost(Context* c,
frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator) Value* v,
int frameIndex,
CostCalculator* costCalculator)
{ {
return resourceCost return resourceCost(c,
(c, v, c->frameResources + frameIndex, SiteMask(1 << lir::MemoryOperand, 0, frameIndex), v,
costCalculator) c->frameResources + frameIndex,
+ Target::MinimumFrameCost; SiteMask(1 << lir::MemoryOperand, 0, frameIndex),
costCalculator) + Target::MinimumFrameCost;
} }
Target Target pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator)
pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator)
{ {
Target best; Target best;
Value* p = v; Value* p = v;
do { do {
if (p->home >= 0) { if (p->home >= 0) {
Target mine Target mine(p->home,
(p->home, lir::MemoryOperand, frameCost(c, v, p->home, costCalculator)); lir::MemoryOperand,
frameCost(c, v, p->home, costCalculator));
if (mine.cost == Target::MinimumFrameCost) { if (mine.cost == Target::MinimumFrameCost) {
return mine; return mine;
@ -147,8 +162,7 @@ pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator)
return best; return best;
} }
Target Target pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator)
pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator)
{ {
Target best; Target best;
@ -165,14 +179,16 @@ pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator)
return best; return best;
} }
Target Target pickTarget(Context* c,
pickTarget(Context* c, Value* value, const SiteMask& mask, Value* value,
unsigned registerPenalty, Target best, const SiteMask& mask,
unsigned registerPenalty,
Target best,
CostCalculator* costCalculator) CostCalculator* costCalculator)
{ {
if (mask.typeMask & (1 << lir::RegisterOperand)) { if (mask.typeMask & (1 << lir::RegisterOperand)) {
Target mine = pickRegisterTarget Target mine
(c, value, mask.registerMask, costCalculator); = pickRegisterTarget(c, value, mask.registerMask, costCalculator);
mine.cost += registerPenalty; mine.cost += registerPenalty;
if (mine.cost == Target::MinimumRegisterCost) { if (mine.cost == Target::MinimumRegisterCost) {
@ -184,7 +200,8 @@ pickTarget(Context* c, Value* value, const SiteMask& mask,
if (mask.typeMask & (1 << lir::MemoryOperand)) { if (mask.typeMask & (1 << lir::MemoryOperand)) {
if (mask.frameIndex >= 0) { if (mask.frameIndex >= 0) {
Target mine(mask.frameIndex, lir::MemoryOperand, Target mine(mask.frameIndex,
lir::MemoryOperand,
frameCost(c, value, mask.frameIndex, costCalculator)); frameCost(c, value, mask.frameIndex, costCalculator));
if (mine.cost == Target::MinimumFrameCost) { if (mine.cost == Target::MinimumFrameCost) {
return mine; return mine;
@ -204,13 +221,16 @@ pickTarget(Context* c, Value* value, const SiteMask& mask,
return best; return best;
} }
Target Target pickTarget(Context* c,
pickTarget(Context* c, Read* read, bool intersectRead, Read* read,
unsigned registerReserveCount, CostCalculator* costCalculator) bool intersectRead,
unsigned registerReserveCount,
CostCalculator* costCalculator)
{ {
unsigned registerPenalty unsigned registerPenalty
= (c->availableGeneralRegisterCount > registerReserveCount = (c->availableGeneralRegisterCount > registerReserveCount
? 0 : Target::LowRegisterPenalty); ? 0
: Target::LowRegisterPenalty);
Value* value = read->value; Value* value = read->value;
@ -235,8 +255,8 @@ pickTarget(Context* c, Read* read, bool intersectRead,
if (r) { if (r) {
SiteMask intersection = mask; SiteMask intersection = mask;
if (r->intersect(&intersection)) { if (r->intersect(&intersection)) {
best = pickTarget best = pickTarget(
(c, value, intersection, registerPenalty, best, costCalculator); c, value, intersection, registerPenalty, best, costCalculator);
if (best.cost <= Target::MinimumFrameCost) { if (best.cost <= Target::MinimumFrameCost) {
return best; return best;
@ -252,14 +272,18 @@ pickTarget(Context* c, Read* read, bool intersectRead,
if (intersectRead) { if (intersectRead) {
if (best.cost == Target::Impossible) { if (best.cost == Target::Impossible) {
fprintf(stderr, "mask type %d reg %d frame %d\n", fprintf(stderr,
mask.typeMask, mask.registerMask, mask.frameIndex); "mask type %d reg %d frame %d\n",
mask.typeMask,
mask.registerMask,
mask.frameIndex);
abort(c); abort(c);
} }
return best; return best;
} }
{ Target mine = pickRegisterTarget(c, value, registerMask, costCalculator); {
Target mine = pickRegisterTarget(c, value, registerMask, costCalculator);
mine.cost += registerPenalty; mine.cost += registerPenalty;
@ -270,7 +294,8 @@ pickTarget(Context* c, Read* read, bool intersectRead,
} }
} }
{ Target mine = pickFrameTarget(c, value, costCalculator); {
Target mine = pickFrameTarget(c, value, costCalculator);
if (mine.cost == Target::MinimumFrameCost) { if (mine.cost == Target::MinimumFrameCost) {
return mine; return mine;
} else if (mine.cost < best.cost) { } else if (mine.cost < best.cost) {
@ -279,8 +304,7 @@ pickTarget(Context* c, Read* read, bool intersectRead,
} }
if (best.cost >= Target::StealUniquePenalty if (best.cost >= Target::StealUniquePenalty
and c->availableGeneralRegisterCount == 0) and c->availableGeneralRegisterCount == 0) {
{
// there are no free registers left, so moving from memory to // there are no free registers left, so moving from memory to
// memory isn't an option - try harder to find an available frame // memory isn't an option - try harder to find an available frame
// site: // site:

View File

@ -33,14 +33,12 @@ class SiteMask;
class Resource; class Resource;
class Read; class Read;
class RegisterAllocator { class RegisterAllocator {
public: public:
Aborter* a; Aborter* a;
const RegisterFile* registerFile; const RegisterFile* registerFile;
RegisterAllocator(Aborter* a, const RegisterFile* registerFile); RegisterAllocator(Aborter* a, const RegisterFile* registerFile);
}; };
class Target { class Target {
@ -53,11 +51,14 @@ class Target {
static const unsigned LowRegisterPenalty = 10; static const unsigned LowRegisterPenalty = 10;
static const unsigned Impossible = 20; static const unsigned Impossible = 20;
Target(): cost(Impossible) { } Target() : cost(Impossible)
{
}
Target(int index, lir::OperandType type, unsigned cost): Target(int index, lir::OperandType type, unsigned cost)
index(index), type(type), cost(cost) : index(index), type(type), cost(cost)
{ } {
}
int16_t index; int16_t index;
lir::OperandType type; lir::OperandType type;
@ -69,40 +70,52 @@ class CostCalculator {
virtual unsigned cost(Context* c, SiteMask mask) = 0; virtual unsigned cost(Context* c, SiteMask mask) = 0;
}; };
unsigned unsigned resourceCost(Context* c,
resourceCost(Context* c, Value* v, Resource* r, SiteMask mask, Value* v,
Resource* r,
SiteMask mask,
CostCalculator* costCalculator); CostCalculator* costCalculator);
bool pickRegisterTarget(Context* c,
bool int i,
pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target, Value* v,
unsigned* cost, CostCalculator* costCalculator = 0); uint32_t mask,
int* target,
int unsigned* cost,
pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost,
CostCalculator* costCalculator = 0); CostCalculator* costCalculator = 0);
Target int pickRegisterTarget(Context* c,
pickRegisterTarget(Context* c, Value* v, uint32_t mask, Value* v,
uint32_t mask,
unsigned* cost,
CostCalculator* costCalculator = 0); CostCalculator* costCalculator = 0);
unsigned Target pickRegisterTarget(Context* c,
frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator); Value* v,
uint32_t mask,
CostCalculator* costCalculator = 0);
Target unsigned frameCost(Context* c,
pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator); Value* v,
int frameIndex,
Target
pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator);
Target
pickTarget(Context* c, Value* value, const SiteMask& mask,
unsigned registerPenalty, Target best,
CostCalculator* costCalculator); CostCalculator* costCalculator);
Target Target pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator);
pickTarget(Context* c, Read* read, bool intersectRead,
unsigned registerReserveCount, CostCalculator* costCalculator); Target pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator);
Target pickTarget(Context* c,
Value* value,
const SiteMask& mask,
unsigned registerPenalty,
Target best,
CostCalculator* costCalculator);
Target pickTarget(Context* c,
Read* read,
bool intersectRead,
unsigned registerReserveCount,
CostCalculator* costCalculator);
} // namespace regalloc } // namespace regalloc
} // namespace codegen } // namespace codegen

View File

@ -18,154 +18,173 @@ namespace compiler {
const bool DebugResources = false; const bool DebugResources = false;
void steal(Context* c, Resource* r, Value* thief); void steal(Context* c, Resource* r, Value* thief);
void decrementAvailableGeneralRegisterCount(Context* c) { void decrementAvailableGeneralRegisterCount(Context* c)
{
assertT(c, c->availableGeneralRegisterCount); assertT(c, c->availableGeneralRegisterCount);
-- c->availableGeneralRegisterCount; --c->availableGeneralRegisterCount;
if (DebugResources) { if (DebugResources) {
fprintf(stderr, "%d registers available\n", fprintf(
c->availableGeneralRegisterCount); stderr, "%d registers available\n", c->availableGeneralRegisterCount);
} }
} }
void incrementAvailableGeneralRegisterCount(Context* c) { void incrementAvailableGeneralRegisterCount(Context* c)
++ c->availableGeneralRegisterCount; {
++c->availableGeneralRegisterCount;
if (DebugResources) { if (DebugResources) {
fprintf(stderr, "%d registers available\n", fprintf(
c->availableGeneralRegisterCount); stderr, "%d registers available\n", c->availableGeneralRegisterCount);
} }
} }
void freezeResource(Context* c, Resource* r, Value* v) { void freezeResource(Context* c, Resource* r, Value* v)
{
if (DebugResources) { if (DebugResources) {
char buffer[256]; r->toString(c, buffer, 256); char buffer[256];
r->toString(c, buffer, 256);
fprintf(stderr, "%p freeze %s to %d\n", v, buffer, r->freezeCount + 1); fprintf(stderr, "%p freeze %s to %d\n", v, buffer, r->freezeCount + 1);
} }
++ r->freezeCount; ++r->freezeCount;
} }
void thawResource(Context* c, Resource* r, Value* v) { void thawResource(Context* c, Resource* r, Value* v)
{
if (not r->reserved) { if (not r->reserved) {
if (DebugResources) { if (DebugResources) {
char buffer[256]; r->toString(c, buffer, 256); char buffer[256];
r->toString(c, buffer, 256);
fprintf(stderr, "%p thaw %s to %d\n", v, buffer, r->freezeCount - 1); fprintf(stderr, "%p thaw %s to %d\n", v, buffer, r->freezeCount - 1);
} }
assertT(c, r->freezeCount); assertT(c, r->freezeCount);
-- r->freezeCount; --r->freezeCount;
} }
} }
Resource::Resource(bool reserved)
: value(0),
site(0),
previousAcquired(0),
nextAcquired(0),
freezeCount(0),
referenceCount(0),
reserved(reserved)
{
}
Resource::Resource(bool reserved): RegisterResource::RegisterResource(bool reserved) : Resource(reserved)
value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0), {
referenceCount(0), reserved(reserved) }
{ }
RegisterResource::RegisterResource(bool reserved): void RegisterResource::freeze(Context* c, Value* v)
Resource(reserved) {
{ }
void RegisterResource::freeze(Context* c, Value* v) {
if (not reserved) { if (not reserved) {
freezeResource(c, this, v); freezeResource(c, this, v);
if (freezeCount == 1 if (freezeCount == 1
and ((1 << index(c)) & c->regFile->generalRegisters.mask)) and ((1 << index(c)) & c->regFile->generalRegisters.mask)) {
{
decrementAvailableGeneralRegisterCount(c); decrementAvailableGeneralRegisterCount(c);
} }
} }
} }
void RegisterResource::thaw(Context* c, Value* v) { void RegisterResource::thaw(Context* c, Value* v)
{
if (not reserved) { if (not reserved) {
thawResource(c, this, v); thawResource(c, this, v);
if (freezeCount == 0 if (freezeCount == 0
and ((1 << index(c)) & c->regFile->generalRegisters.mask)) and ((1 << index(c)) & c->regFile->generalRegisters.mask)) {
{
incrementAvailableGeneralRegisterCount(c); incrementAvailableGeneralRegisterCount(c);
} }
} }
} }
unsigned RegisterResource::toString(Context* c, char* buffer, unsigned bufferSize) { unsigned RegisterResource::toString(Context* c,
char* buffer,
unsigned bufferSize)
{
return vm::snprintf(buffer, bufferSize, "register %d", index(c)); return vm::snprintf(buffer, bufferSize, "register %d", index(c));
} }
unsigned RegisterResource::index(Context* c) { unsigned RegisterResource::index(Context* c)
{
return this - c->registerResources; return this - c->registerResources;
} }
void RegisterResource::increment(Context* c) { void RegisterResource::increment(Context* c)
{
if (not this->reserved) { if (not this->reserved) {
if (DebugResources) { if (DebugResources) {
char buffer[256]; this->toString(c, buffer, 256); char buffer[256];
this->toString(c, buffer, 256);
fprintf(stderr, "increment %s to %d\n", buffer, this->referenceCount + 1); fprintf(stderr, "increment %s to %d\n", buffer, this->referenceCount + 1);
} }
++ this->referenceCount; ++this->referenceCount;
if (this->referenceCount == 1 if (this->referenceCount == 1
and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) {
{
decrementAvailableGeneralRegisterCount(c); decrementAvailableGeneralRegisterCount(c);
} }
} }
} }
void RegisterResource::decrement(Context* c) { void RegisterResource::decrement(Context* c)
{
if (not this->reserved) { if (not this->reserved) {
if (DebugResources) { if (DebugResources) {
char buffer[256]; this->toString(c, buffer, 256); char buffer[256];
this->toString(c, buffer, 256);
fprintf(stderr, "decrement %s to %d\n", buffer, this->referenceCount - 1); fprintf(stderr, "decrement %s to %d\n", buffer, this->referenceCount - 1);
} }
assertT(c, this->referenceCount > 0); assertT(c, this->referenceCount > 0);
-- this->referenceCount; --this->referenceCount;
if (this->referenceCount == 0 if (this->referenceCount == 0
and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) {
{
incrementAvailableGeneralRegisterCount(c); incrementAvailableGeneralRegisterCount(c);
} }
} }
} }
void FrameResource::freeze(Context* c, Value* v)
{
void FrameResource::freeze(Context* c, Value* v) {
freezeResource(c, this, v); freezeResource(c, this, v);
} }
void FrameResource::thaw(Context* c, Value* v) { void FrameResource::thaw(Context* c, Value* v)
{
thawResource(c, this, v); thawResource(c, this, v);
} }
unsigned FrameResource::toString(Context* c, char* buffer, unsigned bufferSize) { unsigned FrameResource::toString(Context* c, char* buffer, unsigned bufferSize)
{
return vm::snprintf(buffer, bufferSize, "frame %d", index(c)); return vm::snprintf(buffer, bufferSize, "frame %d", index(c));
} }
unsigned FrameResource::index(Context* c) { unsigned FrameResource::index(Context* c)
{
return this - c->frameResources; return this - c->frameResources;
} }
void acquire(Context* c, Resource* resource, Value* value, Site* site)
void acquire(Context* c, Resource* resource, Value* value, Site* site) { {
assertT(c, value); assertT(c, value);
assertT(c, site); assertT(c, site);
if (not resource->reserved) { if (not resource->reserved) {
if (DebugResources) { if (DebugResources) {
char buffer[256]; resource->toString(c, buffer, 256); char buffer[256];
resource->toString(c, buffer, 256);
fprintf(stderr, "%p acquire %s\n", value, buffer); fprintf(stderr, "%p acquire %s\n", value, buffer);
} }
@ -187,10 +206,15 @@ void acquire(Context* c, Resource* resource, Value* value, Site* site) {
} }
} }
void release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED) { void release(Context* c,
Resource* resource,
Value* value UNUSED,
Site* site UNUSED)
{
if (not resource->reserved) { if (not resource->reserved) {
if (DebugResources) { if (DebugResources) {
char buffer[256]; resource->toString(c, buffer, 256); char buffer[256];
resource->toString(c, buffer, 256);
fprintf(stderr, "%p release %s\n", resource->value, buffer); fprintf(stderr, "%p release %s\n", resource->value, buffer);
} }
@ -220,7 +244,6 @@ void release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNU
} }
} }
} // namespace compiler } // namespace compiler
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian

View File

@ -38,7 +38,7 @@ class Resource {
bool reserved; bool reserved;
}; };
class RegisterResource: public Resource { class RegisterResource : public Resource {
public: public:
RegisterResource(bool reserved); RegisterResource(bool reserved);
@ -55,7 +55,7 @@ class RegisterResource: public Resource {
void decrement(Context*); void decrement(Context*);
}; };
class FrameResource: public Resource { class FrameResource : public Resource {
public: public:
virtual void freeze(Context*, Value*); virtual void freeze(Context*, Value*);

View File

@ -21,25 +21,31 @@ namespace avian {
namespace codegen { namespace codegen {
namespace compiler { namespace compiler {
int intersectFrameIndexes(int a, int b)
{
int intersectFrameIndexes(int a, int b) { if (a == NoFrameIndex or b == NoFrameIndex)
if (a == NoFrameIndex or b == NoFrameIndex) return NoFrameIndex; return NoFrameIndex;
if (a == AnyFrameIndex) return b; if (a == AnyFrameIndex)
if (b == AnyFrameIndex) return a; return b;
if (a == b) return a; if (b == AnyFrameIndex)
return a;
if (a == b)
return a;
return NoFrameIndex; return NoFrameIndex;
} }
SiteMask SiteMask::intersectionWith(const SiteMask& b)
SiteMask SiteMask::intersectionWith(const SiteMask& b) { {
return SiteMask(typeMask & b.typeMask, registerMask & b.registerMask, return SiteMask(typeMask & b.typeMask,
registerMask & b.registerMask,
intersectFrameIndexes(frameIndex, b.frameIndex)); intersectFrameIndexes(frameIndex, b.frameIndex));
} }
SiteIterator::SiteIterator(Context* c, Value* v, bool includeBuddies, SiteIterator::SiteIterator(Context* c,
bool includeNextWord): Value* v,
c(c), bool includeBuddies,
bool includeNextWord)
: c(c),
originalValue(v), originalValue(v),
currentValue(v), currentValue(v),
includeBuddies(includeBuddies), includeBuddies(includeBuddies),
@ -47,9 +53,11 @@ SiteIterator::SiteIterator(Context* c, Value* v, bool includeBuddies,
pass(0), pass(0),
next_(findNext(&(v->sites))), next_(findNext(&(v->sites))),
previous(0) previous(0)
{ } {
}
Site** SiteIterator::findNext(Site** p) { Site** SiteIterator::findNext(Site** p)
{
while (true) { while (true) {
if (*p) { if (*p) {
if (pass == 0 or (*p)->registerSize(c) > c->targetInfo.pointerSize) { if (pass == 0 or (*p)->registerSize(c) > c->targetInfo.pointerSize) {
@ -83,7 +91,8 @@ Site** SiteIterator::findNext(Site** p) {
} }
} }
bool SiteIterator::hasMore() { bool SiteIterator::hasMore()
{
if (previous) { if (previous) {
next_ = findNext(&((*previous)->next)); next_ = findNext(&((*previous)->next));
previous = 0; previous = 0;
@ -91,12 +100,14 @@ bool SiteIterator::hasMore() {
return next_ != 0; return next_ != 0;
} }
Site* SiteIterator::next() { Site* SiteIterator::next()
{
previous = next_; previous = next_;
return *previous; return *previous;
} }
void SiteIterator::remove(Context* c) { void SiteIterator::remove(Context* c)
{
(*previous)->release(c, originalValue); (*previous)->release(c, originalValue);
*previous = (*previous)->next; *previous = (*previous)->next;
next_ = findNext(previous); next_ = findNext(previous);
@ -108,50 +119,59 @@ unsigned Site::registerSize(Context* c)
return c->targetInfo.pointerSize; return c->targetInfo.pointerSize;
} }
Site* constantSite(Context* c, Promise* value) { Site* constantSite(Context* c, Promise* value)
return new(c->zone) ConstantSite(value); {
return new (c->zone) ConstantSite(value);
} }
Site* constantSite(Context* c, int64_t value) { Site* constantSite(Context* c, int64_t value)
{
return constantSite(c, resolvedPromise(c, value)); return constantSite(c, resolvedPromise(c, value));
} }
class AddressSite : public Site {
class AddressSite: public Site {
public: public:
AddressSite(Promise* address): address(address) { } AddressSite(Promise* address) : address(address)
{
}
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { virtual unsigned toString(Context*, char* buffer, unsigned bufferSize)
{
if (address->resolved()) { if (address->resolved()) {
return vm::snprintf return vm::snprintf(
(buffer, bufferSize, "address %" LLD, address->value()); buffer, bufferSize, "address %" LLD, address->value());
} else { } else {
return vm::snprintf(buffer, bufferSize, "address unresolved"); return vm::snprintf(buffer, bufferSize, "address unresolved");
} }
} }
virtual unsigned copyCost(Context*, Site* s) { virtual unsigned copyCost(Context*, Site* s)
{
return (s == this ? 0 : AddressCopyCost); return (s == this ? 0 : AddressCopyCost);
} }
virtual bool match(Context*, const SiteMask& mask) { virtual bool match(Context*, const SiteMask& mask)
{
return mask.typeMask & (1 << lir::AddressOperand); return mask.typeMask & (1 << lir::AddressOperand);
} }
virtual bool loneMatch(Context*, const SiteMask&) { virtual bool loneMatch(Context*, const SiteMask&)
{
return false; return false;
} }
virtual bool matchNextWord(Context* c, Site*, unsigned) { virtual bool matchNextWord(Context* c, Site*, unsigned)
{
abort(c); abort(c);
} }
virtual lir::OperandType type(Context*) { virtual lir::OperandType type(Context*)
{
return lir::AddressOperand; return lir::AddressOperand;
} }
virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, virtual void asAssemblerOperand(Context* c UNUSED,
Site* high UNUSED,
lir::Operand* result) lir::Operand* result)
{ {
assertT(c, high == this); assertT(c, high == this);
@ -159,66 +179,74 @@ class AddressSite: public Site {
new (result) lir::Address(address); new (result) lir::Address(address);
} }
virtual Site* copy(Context* c) { virtual Site* copy(Context* c)
{
return addressSite(c, address); return addressSite(c, address);
} }
virtual Site* copyLow(Context* c) { virtual Site* copyLow(Context* c)
{
abort(c); abort(c);
} }
virtual Site* copyHigh(Context* c) { virtual Site* copyHigh(Context* c)
{
abort(c); abort(c);
} }
virtual Site* makeNextWord(Context* c, unsigned) { virtual Site* makeNextWord(Context* c, unsigned)
{
abort(c); abort(c);
} }
virtual SiteMask mask(Context*) { virtual SiteMask mask(Context*)
{
return SiteMask(1 << lir::AddressOperand, 0, NoFrameIndex); return SiteMask(1 << lir::AddressOperand, 0, NoFrameIndex);
} }
virtual SiteMask nextWordMask(Context* c, unsigned) { virtual SiteMask nextWordMask(Context* c, unsigned)
{
abort(c); abort(c);
} }
Promise* address; Promise* address;
}; };
Site* addressSite(Context* c, Promise* address) { Site* addressSite(Context* c, Promise* address)
return new(c->zone) AddressSite(address); {
return new (c->zone) AddressSite(address);
} }
RegisterSite::RegisterSite(uint32_t mask, int number)
: mask_(mask), number(number)
{
}
RegisterSite::RegisterSite(uint32_t mask, int number): unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize)
mask_(mask), number(number) {
{ }
unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize) {
if (number != lir::NoRegister) { if (number != lir::NoRegister) {
return vm::snprintf(buffer, bufferSize, "%p register %d", this, number); return vm::snprintf(buffer, bufferSize, "%p register %d", this, number);
} else { } else {
return vm::snprintf(buffer, bufferSize, return vm::snprintf(
"%p register unacquired (mask %d)", this, mask_); buffer, bufferSize, "%p register unacquired (mask %d)", this, mask_);
} }
} }
unsigned RegisterSite::copyCost(Context* c, Site* s) { unsigned RegisterSite::copyCost(Context* c, Site* s)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
if (s and if (s and (this == s
(this == s or or (s->type(c) == lir::RegisterOperand
(s->type(c) == lir::RegisterOperand and (static_cast<RegisterSite*>(s)->mask_ & (1 << number))))) {
and (static_cast<RegisterSite*>(s)->mask_ & (1 << number)))))
{
return 0; return 0;
} else { } else {
return RegisterCopyCost; return RegisterCopyCost;
} }
} }
bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) { bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
if ((mask.typeMask & (1 << lir::RegisterOperand))) { if ((mask.typeMask & (1 << lir::RegisterOperand))) {
@ -228,7 +256,8 @@ bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) {
} }
} }
bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) { bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
if ((mask.typeMask & (1 << lir::RegisterOperand))) { if ((mask.typeMask & (1 << lir::RegisterOperand))) {
@ -238,7 +267,8 @@ bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) {
} }
} }
bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) { bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
if (s->type(c) != lir::RegisterOperand) { if (s->type(c) != lir::RegisterOperand) {
@ -256,7 +286,8 @@ bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) {
} }
} }
void RegisterSite::acquire(Context* c, Value* v) { void RegisterSite::acquire(Context* c, Value* v)
{
Target target; Target target;
if (number != lir::NoRegister) { if (number != lir::NoRegister) {
target = Target(number, lir::RegisterOperand, 0); target = Target(number, lir::RegisterOperand, 0);
@ -271,35 +302,41 @@ void RegisterSite::acquire(Context* c, Value* v) {
number = target.index; number = target.index;
} }
void RegisterSite::release(Context* c, Value* v) { void RegisterSite::release(Context* c, Value* v)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
compiler::release(c, c->registerResources + number, v, this); compiler::release(c, c->registerResources + number, v, this);
} }
void RegisterSite::freeze(Context* c, Value* v) { void RegisterSite::freeze(Context* c, Value* v)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
c->registerResources[number].freeze(c, v); c->registerResources[number].freeze(c, v);
} }
void RegisterSite::thaw(Context* c, Value* v) { void RegisterSite::thaw(Context* c, Value* v)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
c->registerResources[number].thaw(c, v); c->registerResources[number].thaw(c, v);
} }
bool RegisterSite::frozen(Context* c UNUSED) { bool RegisterSite::frozen(Context* c UNUSED)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
return c->registerResources[number].freezeCount != 0; return c->registerResources[number].freezeCount != 0;
} }
lir::OperandType RegisterSite::type(Context*) { lir::OperandType RegisterSite::type(Context*)
{
return lir::RegisterOperand; return lir::RegisterOperand;
} }
void RegisterSite::asAssemblerOperand(Context* c UNUSED, Site* high, void RegisterSite::asAssemblerOperand(Context* c UNUSED,
Site* high,
lir::Operand* result) lir::Operand* result)
{ {
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
@ -315,7 +352,8 @@ void RegisterSite::asAssemblerOperand(Context* c UNUSED, Site* high,
new (result) lir::Register(number, highNumber); new (result) lir::Register(number, highNumber);
} }
Site* RegisterSite::copy(Context* c) { Site* RegisterSite::copy(Context* c)
{
uint32_t mask; uint32_t mask;
if (number != lir::NoRegister) { if (number != lir::NoRegister) {
@ -327,38 +365,44 @@ Site* RegisterSite::copy(Context* c) {
return freeRegisterSite(c, mask); return freeRegisterSite(c, mask);
} }
Site* RegisterSite::copyLow(Context* c) { Site* RegisterSite::copyLow(Context* c)
{
abort(c); abort(c);
} }
Site* RegisterSite::copyHigh(Context* c) { Site* RegisterSite::copyHigh(Context* c)
{
abort(c); abort(c);
} }
Site* RegisterSite::makeNextWord(Context* c, unsigned) { Site* RegisterSite::makeNextWord(Context* c, unsigned)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
assertT(c, ((1 << number) & c->regFile->generalRegisters.mask)); assertT(c, ((1 << number) & c->regFile->generalRegisters.mask));
return freeRegisterSite(c, c->regFile->generalRegisters.mask); return freeRegisterSite(c, c->regFile->generalRegisters.mask);
} }
SiteMask RegisterSite::mask(Context* c UNUSED) { SiteMask RegisterSite::mask(Context* c UNUSED)
{
return SiteMask(1 << lir::RegisterOperand, mask_, NoFrameIndex); return SiteMask(1 << lir::RegisterOperand, mask_, NoFrameIndex);
} }
SiteMask RegisterSite::nextWordMask(Context* c, unsigned) { SiteMask RegisterSite::nextWordMask(Context* c, unsigned)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
if (registerSize(c) > c->targetInfo.pointerSize) { if (registerSize(c) > c->targetInfo.pointerSize) {
return SiteMask return SiteMask(1 << lir::RegisterOperand, number, NoFrameIndex);
(1 << lir::RegisterOperand, number, NoFrameIndex);
} else { } else {
return SiteMask return SiteMask(1 << lir::RegisterOperand,
(1 << lir::RegisterOperand, c->regFile->generalRegisters.mask, NoFrameIndex); c->regFile->generalRegisters.mask,
NoFrameIndex);
} }
} }
unsigned RegisterSite::registerSize(Context* c) { unsigned RegisterSite::registerSize(Context* c)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
if ((1 << number) & c->regFile->floatRegisters.mask) { if ((1 << number) & c->regFile->floatRegisters.mask) {
@ -368,65 +412,68 @@ unsigned RegisterSite::registerSize(Context* c) {
} }
} }
unsigned RegisterSite::registerMask(Context* c UNUSED) { unsigned RegisterSite::registerMask(Context* c UNUSED)
{
assertT(c, number != lir::NoRegister); assertT(c, number != lir::NoRegister);
return 1 << number; return 1 << number;
} }
Site* registerSite(Context* c, int number)
{
Site* registerSite(Context* c, int number) {
assertT(c, number >= 0); assertT(c, number >= 0);
assertT(c, assertT(c,
(1 << number) & (c->regFile->generalRegisters.mask (1 << number) & (c->regFile->generalRegisters.mask
| c->regFile->floatRegisters.mask)); | c->regFile->floatRegisters.mask));
return new(c->zone) RegisterSite(1 << number, number); return new (c->zone) RegisterSite(1 << number, number);
} }
Site* freeRegisterSite(Context* c, uint32_t mask) { Site* freeRegisterSite(Context* c, uint32_t mask)
return new(c->zone) RegisterSite(mask, lir::NoRegister); {
return new (c->zone) RegisterSite(mask, lir::NoRegister);
} }
MemorySite::MemorySite(int base, int offset, int index, unsigned scale): MemorySite::MemorySite(int base, int offset, int index, unsigned scale)
acquired(false), base(base), offset(offset), index(index), scale(scale) : acquired(false), base(base), offset(offset), index(index), scale(scale)
{ } {
}
unsigned MemorySite::toString(Context*, char* buffer, unsigned bufferSize) { unsigned MemorySite::toString(Context*, char* buffer, unsigned bufferSize)
{
if (acquired) { if (acquired) {
return vm::snprintf(buffer, bufferSize, "memory %d 0x%x %d %d", return vm::snprintf(
base, offset, index, scale); buffer, bufferSize, "memory %d 0x%x %d %d", base, offset, index, scale);
} else { } else {
return vm::snprintf(buffer, bufferSize, "memory unacquired"); return vm::snprintf(buffer, bufferSize, "memory unacquired");
} }
} }
unsigned MemorySite::copyCost(Context* c, Site* s) { unsigned MemorySite::copyCost(Context* c, Site* s)
{
assertT(c, acquired); assertT(c, acquired);
if (s and if (s and (this == s or (s->type(c) == lir::MemoryOperand
(this == s or
(s->type(c) == lir::MemoryOperand
and static_cast<MemorySite*>(s)->base == base and static_cast<MemorySite*>(s)->base == base
and static_cast<MemorySite*>(s)->offset == offset and static_cast<MemorySite*>(s)->offset == offset
and static_cast<MemorySite*>(s)->index == index and static_cast<MemorySite*>(s)->index == index
and static_cast<MemorySite*>(s)->scale == scale))) and static_cast<MemorySite*>(s)->scale == scale))) {
{
return 0; return 0;
} else { } else {
return MemoryCopyCost; return MemoryCopyCost;
} }
} }
bool MemorySite::conflicts(const SiteMask& mask) { bool MemorySite::conflicts(const SiteMask& mask)
{
return (mask.typeMask & (1 << lir::RegisterOperand)) != 0 return (mask.typeMask & (1 << lir::RegisterOperand)) != 0
and (((1 << base) & mask.registerMask) == 0 and (((1 << base) & mask.registerMask) == 0
or (index != lir::NoRegister or (index != lir::NoRegister
and ((1 << index) & mask.registerMask) == 0)); and ((1 << index) & mask.registerMask) == 0));
} }
bool MemorySite::match(Context* c, const SiteMask& mask) { bool MemorySite::match(Context* c, const SiteMask& mask)
{
assertT(c, acquired); assertT(c, acquired);
if (mask.typeMask & (1 << lir::MemoryOperand)) { if (mask.typeMask & (1 << lir::MemoryOperand)) {
@ -446,7 +493,8 @@ bool MemorySite::match(Context* c, const SiteMask& mask) {
} }
} }
bool MemorySite::loneMatch(Context* c, const SiteMask& mask) { bool MemorySite::loneMatch(Context* c, const SiteMask& mask)
{
assertT(c, acquired); assertT(c, acquired);
if (mask.typeMask & (1 << lir::MemoryOperand)) { if (mask.typeMask & (1 << lir::MemoryOperand)) {
@ -463,7 +511,8 @@ bool MemorySite::loneMatch(Context* c, const SiteMask& mask) {
return false; return false;
} }
bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index) { bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index)
{
if (s->type(c) == lir::MemoryOperand) { if (s->type(c) == lir::MemoryOperand) {
MemorySite* ms = static_cast<MemorySite*>(s); MemorySite* ms = static_cast<MemorySite*>(s);
return ms->base == this->base return ms->base == this->base
@ -481,7 +530,8 @@ bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index) {
} }
} }
void MemorySite::acquire(Context* c, Value* v) { void MemorySite::acquire(Context* c, Value* v)
{
c->registerResources[base].increment(c); c->registerResources[base].increment(c);
if (index != lir::NoRegister) { if (index != lir::NoRegister) {
c->registerResources[index].increment(c); c->registerResources[index].increment(c);
@ -491,20 +541,21 @@ void MemorySite::acquire(Context* c, Value* v) {
assertT(c, index == lir::NoRegister); assertT(c, index == lir::NoRegister);
assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
compiler::acquire compiler::acquire(
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this); c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
} }
acquired = true; acquired = true;
} }
void MemorySite::release(Context* c, Value* v) { void MemorySite::release(Context* c, Value* v)
{
if (base == c->arch->stack()) { if (base == c->arch->stack()) {
assertT(c, index == lir::NoRegister); assertT(c, index == lir::NoRegister);
assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); assertT(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
compiler::release compiler::release(
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this); c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
} }
c->registerResources[base].decrement(c); c->registerResources[base].decrement(c);
@ -515,7 +566,8 @@ void MemorySite::release(Context* c, Value* v) {
acquired = false; acquired = false;
} }
void MemorySite::freeze(Context* c, Value* v) { void MemorySite::freeze(Context* c, Value* v)
{
if (base == c->arch->stack()) { if (base == c->arch->stack()) {
c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v);
} else { } else {
@ -526,7 +578,8 @@ void MemorySite::freeze(Context* c, Value* v) {
} }
} }
void MemorySite::thaw(Context* c, Value* v) { void MemorySite::thaw(Context* c, Value* v)
{
if (base == c->arch->stack()) { if (base == c->arch->stack()) {
c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v);
} else { } else {
@ -537,16 +590,19 @@ void MemorySite::thaw(Context* c, Value* v) {
} }
} }
bool MemorySite::frozen(Context* c) { bool MemorySite::frozen(Context* c)
{
return base == c->arch->stack() return base == c->arch->stack()
and c->frameResources[offsetToFrameIndex(c, offset)].freezeCount != 0; and c->frameResources[offsetToFrameIndex(c, offset)].freezeCount != 0;
} }
lir::OperandType MemorySite::type(Context*) { lir::OperandType MemorySite::type(Context*)
{
return lir::MemoryOperand; return lir::MemoryOperand;
} }
void MemorySite::asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, void MemorySite::asAssemblerOperand(Context* c UNUSED,
Site* high UNUSED,
lir::Operand* result) lir::Operand* result)
{ {
// todo: endianness? // todo: endianness?
@ -563,11 +619,13 @@ void MemorySite::asAssemblerOperand(Context* c UNUSED, Site* high UNUSED,
new (result) lir::Memory(base, offset, index, scale); new (result) lir::Memory(base, offset, index, scale);
} }
Site* MemorySite::copy(Context* c) { Site* MemorySite::copy(Context* c)
{
return memorySite(c, base, offset, index, scale); return memorySite(c, base, offset, index, scale);
} }
Site* MemorySite::copyHalf(Context* c, bool add) { Site* MemorySite::copyHalf(Context* c, bool add)
{
if (add) { if (add) {
return memorySite( return memorySite(
c, base, offset + c->targetInfo.pointerSize, index, scale); c, base, offset + c->targetInfo.pointerSize, index, scale);
@ -576,15 +634,18 @@ Site* MemorySite::copyHalf(Context* c, bool add) {
} }
} }
Site* MemorySite::copyLow(Context* c) { Site* MemorySite::copyLow(Context* c)
{
return copyHalf(c, c->arch->bigEndian()); return copyHalf(c, c->arch->bigEndian());
} }
Site* MemorySite::copyHigh(Context* c) { Site* MemorySite::copyHigh(Context* c)
{
return copyHalf(c, not c->arch->bigEndian()); return copyHalf(c, not c->arch->bigEndian());
} }
Site* MemorySite::makeNextWord(Context* c, unsigned index) { Site* MemorySite::makeNextWord(Context* c, unsigned index)
{
return memorySite(c, return memorySite(c,
base, base,
offset + ((index == 1) xor c->arch->bigEndian() offset + ((index == 1) xor c->arch->bigEndian()
@ -594,13 +655,17 @@ Site* MemorySite::makeNextWord(Context* c, unsigned index) {
scale); scale);
} }
SiteMask MemorySite::mask(Context* c) { SiteMask MemorySite::mask(Context* c)
return SiteMask(1 << lir::MemoryOperand, 0, (base == c->arch->stack()) {
return SiteMask(1 << lir::MemoryOperand,
0,
(base == c->arch->stack())
? static_cast<int>(offsetToFrameIndex(c, offset)) ? static_cast<int>(offsetToFrameIndex(c, offset))
: NoFrameIndex); : NoFrameIndex);
} }
SiteMask MemorySite::nextWordMask(Context* c, unsigned index) { SiteMask MemorySite::nextWordMask(Context* c, unsigned index)
{
int frameIndex; int frameIndex;
if (base == c->arch->stack()) { if (base == c->arch->stack()) {
assertT(c, this->index == lir::NoRegister); assertT(c, this->index == lir::NoRegister);
@ -612,19 +677,28 @@ SiteMask MemorySite::nextWordMask(Context* c, unsigned index) {
return SiteMask(1 << lir::MemoryOperand, 0, frameIndex); return SiteMask(1 << lir::MemoryOperand, 0, frameIndex);
} }
bool MemorySite::isVolatile(Context* c) { bool MemorySite::isVolatile(Context* c)
{
return base != c->arch->stack(); return base != c->arch->stack();
} }
MemorySite* memorySite(Context* c,
MemorySite* memorySite(Context* c, int base, int offset, int index, unsigned scale) { int base,
return new(c->zone) MemorySite(base, offset, index, scale); int offset,
int index,
unsigned scale)
{
return new (c->zone) MemorySite(base, offset, index, scale);
} }
MemorySite* frameSite(Context* c, int frameIndex) { MemorySite* frameSite(Context* c, int frameIndex)
{
assertT(c, frameIndex >= 0); assertT(c, frameIndex >= 0);
return memorySite return memorySite(c,
(c, c->arch->stack(), frameIndexToOffset(c, frameIndex), lir::NoRegister, 0); c->arch->stack(),
frameIndexToOffset(c, frameIndex),
lir::NoRegister,
0);
} }
} // namespace compiler } // namespace compiler

View File

@ -30,23 +30,29 @@ const unsigned CopyPenalty = 10;
class SiteMask { class SiteMask {
public: public:
SiteMask(): typeMask(~0), registerMask(~0), frameIndex(AnyFrameIndex) { } SiteMask() : typeMask(~0), registerMask(~0), frameIndex(AnyFrameIndex)
{
}
SiteMask(uint8_t typeMask, uint32_t registerMask, int frameIndex): SiteMask(uint8_t typeMask, uint32_t registerMask, int frameIndex)
typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex) : typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex)
{ } {
}
SiteMask intersectionWith(const SiteMask& b); SiteMask intersectionWith(const SiteMask& b);
static SiteMask fixedRegisterMask(int number) { static SiteMask fixedRegisterMask(int number)
{
return SiteMask(1 << lir::RegisterOperand, 1 << number, NoFrameIndex); return SiteMask(1 << lir::RegisterOperand, 1 << number, NoFrameIndex);
} }
static SiteMask lowPart(const OperandMask& mask) { static SiteMask lowPart(const OperandMask& mask)
{
return SiteMask(mask.typeMask, mask.registerMask, AnyFrameIndex); return SiteMask(mask.typeMask, mask.registerMask, AnyFrameIndex);
} }
static SiteMask highPart(const OperandMask& mask) { static SiteMask highPart(const OperandMask& mask)
{
return SiteMask(mask.typeMask, mask.registerMask >> 32, AnyFrameIndex); return SiteMask(mask.typeMask, mask.registerMask >> 32, AnyFrameIndex);
} }
@ -57,9 +63,14 @@ class SiteMask {
class Site { class Site {
public: public:
Site(): next(0) { } Site() : next(0)
{
}
virtual Site* readTarget(Context*, Read*) { return this; } virtual Site* readTarget(Context*, Read*)
{
return this;
}
virtual unsigned toString(Context*, char*, unsigned) = 0; virtual unsigned toString(Context*, char*, unsigned) = 0;
@ -71,15 +82,26 @@ class Site {
virtual bool matchNextWord(Context*, Site*, unsigned) = 0; virtual bool matchNextWord(Context*, Site*, unsigned) = 0;
virtual void acquire(Context*, Value*) { } virtual void acquire(Context*, Value*)
{
}
virtual void release(Context*, Value*) { } virtual void release(Context*, Value*)
{
}
virtual void freeze(Context*, Value*) { } virtual void freeze(Context*, Value*)
{
}
virtual void thaw(Context*, Value*) { } virtual void thaw(Context*, Value*)
{
}
virtual bool frozen(Context*) { return false; } virtual bool frozen(Context*)
{
return false;
}
virtual lir::OperandType type(Context*) = 0; virtual lir::OperandType type(Context*) = 0;
@ -99,16 +121,24 @@ class Site {
virtual unsigned registerSize(Context*); virtual unsigned registerSize(Context*);
virtual unsigned registerMask(Context*) { return 0; } virtual unsigned registerMask(Context*)
{
return 0;
}
virtual bool isVolatile(Context*) { return false; } virtual bool isVolatile(Context*)
{
return false;
}
Site* next; Site* next;
}; };
class SiteIterator { class SiteIterator {
public: public:
SiteIterator(Context* c, Value* v, bool includeBuddies = true, SiteIterator(Context* c,
Value* v,
bool includeBuddies = true,
bool includeNextWord = true); bool includeNextWord = true);
Site** findNext(Site** p); Site** findNext(Site** p);
@ -130,43 +160,52 @@ Site* constantSite(Context* c, Promise* value);
Site* constantSite(Context* c, int64_t value); Site* constantSite(Context* c, int64_t value);
Promise* combinedPromise(Context* c, Promise* low, Promise* high); Promise* combinedPromise(Context* c, Promise* low, Promise* high);
Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask); Promise* shiftMaskPromise(Context* c,
Promise* base,
unsigned shift,
int64_t mask);
class ConstantSite: public Site { class ConstantSite : public Site {
public: public:
ConstantSite(Promise* value): value(value) { } ConstantSite(Promise* value) : value(value)
{
}
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { virtual unsigned toString(Context*, char* buffer, unsigned bufferSize)
{
if (value->resolved()) { if (value->resolved()) {
return vm::snprintf return vm::snprintf(buffer, bufferSize, "constant %" LLD, value->value());
(buffer, bufferSize, "constant %" LLD, value->value());
} else { } else {
return vm::snprintf(buffer, bufferSize, "constant unresolved"); return vm::snprintf(buffer, bufferSize, "constant unresolved");
} }
} }
virtual unsigned copyCost(Context*, Site* s) { virtual unsigned copyCost(Context*, Site* s)
{
return (s == this ? 0 : ConstantCopyCost); return (s == this ? 0 : ConstantCopyCost);
} }
virtual bool match(Context*, const SiteMask& mask) { virtual bool match(Context*, const SiteMask& mask)
{
return mask.typeMask & (1 << lir::ConstantOperand); return mask.typeMask & (1 << lir::ConstantOperand);
} }
virtual bool loneMatch(Context*, const SiteMask&) { virtual bool loneMatch(Context*, const SiteMask&)
{
return true; return true;
} }
virtual bool matchNextWord(Context* c, Site* s, unsigned) { virtual bool matchNextWord(Context* c, Site* s, unsigned)
{
return s->type(c) == lir::ConstantOperand; return s->type(c) == lir::ConstantOperand;
} }
virtual lir::OperandType type(Context*) { virtual lir::OperandType type(Context*)
{
return lir::ConstantOperand; return lir::ConstantOperand;
} }
virtual void asAssemblerOperand(Context* c, Site* high, virtual void asAssemblerOperand(Context* c, Site* high, lir::Operand* result)
lir::Operand* result)
{ {
Promise* v = value; Promise* v = value;
if (high != this) { if (high != this) {
@ -175,27 +214,33 @@ class ConstantSite: public Site {
new (result) lir::Constant(v); new (result) lir::Constant(v);
} }
virtual Site* copy(Context* c) { virtual Site* copy(Context* c)
{
return constantSite(c, value); return constantSite(c, value);
} }
virtual Site* copyLow(Context* c) { virtual Site* copyLow(Context* c)
{
return constantSite(c, shiftMaskPromise(c, value, 0, 0xFFFFFFFF)); return constantSite(c, shiftMaskPromise(c, value, 0, 0xFFFFFFFF));
} }
virtual Site* copyHigh(Context* c) { virtual Site* copyHigh(Context* c)
{
return constantSite(c, shiftMaskPromise(c, value, 32, 0xFFFFFFFF)); return constantSite(c, shiftMaskPromise(c, value, 32, 0xFFFFFFFF));
} }
virtual Site* makeNextWord(Context* c, unsigned) { virtual Site* makeNextWord(Context* c, unsigned)
{
abort(c); abort(c);
} }
virtual SiteMask mask(Context*) { virtual SiteMask mask(Context*)
{
return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex);
} }
virtual SiteMask nextWordMask(Context*, unsigned) { virtual SiteMask nextWordMask(Context*, unsigned)
{
return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex);
} }
@ -204,7 +249,7 @@ class ConstantSite: public Site {
Site* addressSite(Context* c, Promise* address); Site* addressSite(Context* c, Promise* address);
class RegisterSite: public Site { class RegisterSite : public Site {
public: public:
RegisterSite(uint32_t mask, int number); RegisterSite(uint32_t mask, int number);
@ -230,7 +275,8 @@ class RegisterSite: public Site {
virtual lir::OperandType type(Context*); virtual lir::OperandType type(Context*);
virtual void asAssemblerOperand(Context* c UNUSED, Site* high, virtual void asAssemblerOperand(Context* c UNUSED,
Site* high,
lir::Operand* result); lir::Operand* result);
virtual Site* copy(Context* c); virtual Site* copy(Context* c);
@ -256,8 +302,7 @@ class RegisterSite: public Site {
Site* registerSite(Context* c, int number); Site* registerSite(Context* c, int number);
Site* freeRegisterSite(Context* c, uint32_t mask); Site* freeRegisterSite(Context* c, uint32_t mask);
class MemorySite : public Site {
class MemorySite: public Site {
public: public:
MemorySite(int base, int offset, int index, unsigned scale); MemorySite(int base, int offset, int index, unsigned scale);
@ -285,7 +330,8 @@ class MemorySite: public Site {
virtual lir::OperandType type(Context*); virtual lir::OperandType type(Context*);
virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, virtual void asAssemblerOperand(Context* c UNUSED,
Site* high UNUSED,
lir::Operand* result); lir::Operand* result);
virtual Site* copy(Context* c); virtual Site* copy(Context* c);
@ -311,7 +357,11 @@ class MemorySite: public Site {
unsigned scale; unsigned scale;
}; };
MemorySite* memorySite(Context* c, int base, int offset = 0, int index = lir::NoRegister, unsigned scale = 1); MemorySite* memorySite(Context* c,
int base,
int offset = 0,
int index = lir::NoRegister,
unsigned scale = 1);
MemorySite* frameSite(Context* c, int frameIndex); MemorySite* frameSite(Context* c, int frameIndex);
} // namespace compiler } // namespace compiler

View File

@ -31,26 +31,33 @@ Value::Value(Site* site, Site* target, ir::Type type)
{ {
} }
bool Value::findSite(Site* site) { bool Value::findSite(Site* site)
{
for (Site* s = this->sites; s; s = s->next) { for (Site* s = this->sites; s; s = s->next) {
if (s == site) return true; if (s == site)
return true;
} }
return false; return false;
} }
bool Value::isBuddyOf(Value* b) { bool Value::isBuddyOf(Value* b)
{
Value* a = this; Value* a = this;
if (a == b) return true; if (a == b)
return true;
for (Value* p = a->buddy; p != a; p = p->buddy) { for (Value* p = a->buddy; p != a; p = p->buddy) {
if (p == b) return true; if (p == b)
return true;
} }
return false; return false;
} }
void Value::addSite(Context* c, Site* s) { void Value::addSite(Context* c, Site* s)
{
if (not this->findSite(s)) { if (not this->findSite(s)) {
if (DebugSites) { if (DebugSites) {
char buffer[256]; s->toString(c, buffer, 256); char buffer[256];
s->toString(c, buffer, 256);
fprintf(stderr, "add site %s to %p\n", buffer, this); fprintf(stderr, "add site %s to %p\n", buffer, this);
} }
s->acquire(c, this); s->acquire(c, this);
@ -59,8 +66,8 @@ void Value::addSite(Context* c, Site* s) {
} }
} }
void Value::grow(Context* c)
void Value::grow(Context* c) { {
assertT(c, this->nextWord == this); assertT(c, this->nextWord == this);
Value* next = value(c, this->type); Value* next = value(c, this->type);
@ -69,14 +76,15 @@ void Value::grow(Context* c) {
next->wordIndex = 1; next->wordIndex = 1;
} }
void Value::maybeSplit(Context* c)
void Value::maybeSplit(Context* c) { {
if (this->nextWord == this) { if (this->nextWord == this) {
this->split(c); this->split(c);
} }
} }
void Value::split(Context* c) { void Value::split(Context* c)
{
this->grow(c); this->grow(c);
for (SiteIterator it(c, this); it.hasMore();) { for (SiteIterator it(c, this); it.hasMore();) {
Site* s = it.next(); Site* s = it.next();
@ -87,11 +95,13 @@ void Value::split(Context* c) {
} }
} }
void Value::removeSite(Context* c, Site* s) { void Value::removeSite(Context* c, Site* s)
{
for (SiteIterator it(c, this); it.hasMore();) { for (SiteIterator it(c, this); it.hasMore();) {
if (s == it.next()) { if (s == it.next()) {
if (DebugSites) { if (DebugSites) {
char buffer[256]; s->toString(c, buffer, 256); char buffer[256];
s->toString(c, buffer, 256);
fprintf(stderr, "remove site %s from %p\n", buffer, this); fprintf(stderr, "remove site %s from %p\n", buffer, this);
} }
it.remove(c); it.remove(c);
@ -104,12 +114,14 @@ void Value::removeSite(Context* c, Site* s) {
assertT(c, not this->findSite(s)); assertT(c, not this->findSite(s));
} }
bool Value::hasSite(Context* c) { bool Value::hasSite(Context* c)
{
SiteIterator it(c, this); SiteIterator it(c, this);
return it.hasMore(); return it.hasMore();
} }
bool Value::uniqueSite(Context* c, Site* s) { bool Value::uniqueSite(Context* c, Site* s)
{
SiteIterator it(c, this); SiteIterator it(c, this);
Site* p UNUSED = it.next(); Site* p UNUSED = it.next();
if (it.hasMore()) { if (it.hasMore()) {
@ -133,7 +145,8 @@ bool Value::uniqueSite(Context* c, Site* s) {
} }
} }
void Value::clearSites(Context* c) { void Value::clearSites(Context* c)
{
if (DebugSites) { if (DebugSites) {
fprintf(stderr, "clear sites for %p\n", this); fprintf(stderr, "clear sites for %p\n", this);
} }
@ -143,9 +156,9 @@ void Value::clearSites(Context* c) {
} }
} }
#ifndef NDEBUG #ifndef NDEBUG
bool Value::hasBuddy(Context* c, Value* b) { bool Value::hasBuddy(Context* c, Value* b)
{
Value* a = this; Value* a = this;
if (a == b) { if (a == b) {
return true; return true;
@ -166,7 +179,7 @@ bool Value::hasBuddy(Context* c, Value* b) {
Value* value(Context* c, ir::Type type, Site* site, Site* target) Value* value(Context* c, ir::Type type, Site* site, Site* target)
{ {
return new(c->zone) Value(site, target, type); return new (c->zone) Value(site, target, type);
} }
} // namespace regalloc } // namespace regalloc

View File

@ -63,7 +63,6 @@ class Value : public ir::Value {
#ifndef NDEBUG #ifndef NDEBUG
bool hasBuddy(Context* c, Value* b); bool hasBuddy(Context* c, Value* b);
#endif // not NDEBUG #endif // not NDEBUG
}; };
inline bool isFloatValue(ir::Value* a) inline bool isFloatValue(ir::Value* a)

View File

@ -13,20 +13,20 @@
namespace avian { namespace avian {
namespace codegen { namespace codegen {
unsigned unsigned RegisterMask::maskStart(uint32_t mask)
RegisterMask::maskStart(uint32_t mask)
{ {
for (int i = 0; i <= 31; ++i) { for (int i = 0; i <= 31; ++i) {
if (mask & (1 << i)) return i; if (mask & (1 << i))
return i;
} }
return 32; return 32;
} }
unsigned unsigned RegisterMask::maskLimit(uint32_t mask)
RegisterMask::maskLimit(uint32_t mask)
{ {
for (int i = 31; i >= 0; --i) { for (int i = 31; i >= 0; --i) {
if (mask & (1 << i)) return i + 1; if (mask & (1 << i))
return i + 1;
} }
return 0; return 0;
} }

View File

@ -36,8 +36,9 @@ namespace arm {
namespace isa { namespace isa {
// HARDWARE FLAGS // HARDWARE FLAGS
bool vfpSupported() { bool vfpSupported()
// TODO: Use at runtime detection {
// TODO: Use at runtime detection
#if defined(__ARM_PCS_VFP) #if defined(__ARM_PCS_VFP)
// armhf // armhf
return true; return true;
@ -51,7 +52,10 @@ bool vfpSupported() {
} }
} // namespace isa } // namespace isa
inline unsigned lo8(int64_t i) { return (unsigned)(i&MASK_LO8); } inline unsigned lo8(int64_t i)
{
return (unsigned)(i & MASK_LO8);
}
const RegisterFile MyRegisterFileWithoutFloats(GPR_MASK, 0); const RegisterFile MyRegisterFileWithoutFloats(GPR_MASK, 0);
const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK); const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK);
@ -59,8 +63,8 @@ const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK);
const unsigned FrameHeaderSize = 1; const unsigned FrameHeaderSize = 1;
const unsigned StackAlignmentInBytes = 8; const unsigned StackAlignmentInBytes = 8;
const unsigned StackAlignmentInWords const unsigned StackAlignmentInWords = StackAlignmentInBytes
= StackAlignmentInBytes / TargetBytesPerWord; / TargetBytesPerWord;
void resolve(MyBlock*); void resolve(MyBlock*);
@ -74,16 +78,20 @@ using namespace isa;
// END OPERATION COMPILERS // END OPERATION COMPILERS
unsigned unsigned argumentFootprint(unsigned footprint)
argumentFootprint(unsigned footprint)
{ {
return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords); return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords);
} }
void void nextFrame(ArchitectureContext* con,
nextFrame(ArchitectureContext* con, uint32_t* start, unsigned size UNUSED, uint32_t* start,
unsigned footprint, void* link, bool, unsigned size UNUSED,
int targetParameterFootprint UNUSED, void** ip, void** stack) unsigned footprint,
void* link,
bool,
int targetParameterFootprint UNUSED,
void** ip,
void** stack)
{ {
assertT(con, *ip >= start); assertT(con, *ip >= start);
assertT(con, *ip <= start + (size / TargetBytesPerWord)); assertT(con, *ip <= start + (size / TargetBytesPerWord));
@ -125,9 +133,14 @@ nextFrame(ArchitectureContext* con, uint32_t* start, unsigned size UNUSED,
unsigned value = *instruction & 0xff; unsigned value = *instruction & 0xff;
unsigned rotation = (*instruction >> 8) & 0xf; unsigned rotation = (*instruction >> 8) & 0xf;
switch (rotation) { switch (rotation) {
case 0: offset -= value / TargetBytesPerWord; break; case 0:
case 15: offset -= value; break; offset -= value / TargetBytesPerWord;
default: abort(con); break;
case 15:
offset -= value;
break;
default:
abort(con);
} }
} }
@ -138,45 +151,56 @@ nextFrame(ArchitectureContext* con, uint32_t* start, unsigned size UNUSED,
*stack = static_cast<void**>(*stack) + offset; *stack = static_cast<void**>(*stack) + offset;
} }
class MyArchitecture: public Architecture { class MyArchitecture : public Architecture {
public: public:
MyArchitecture(System* system): con(system), referenceCount(0) { MyArchitecture(System* system) : con(system), referenceCount(0)
{
populateTables(&con); populateTables(&con);
} }
virtual unsigned floatRegisterSize() { virtual unsigned floatRegisterSize()
{
return vfpSupported() ? 8 : 0; return vfpSupported() ? 8 : 0;
} }
virtual const RegisterFile* registerFile() { virtual const RegisterFile* registerFile()
return vfpSupported() ? &MyRegisterFileWithFloats : &MyRegisterFileWithoutFloats; {
return vfpSupported() ? &MyRegisterFileWithFloats
: &MyRegisterFileWithoutFloats;
} }
virtual int scratch() { virtual int scratch()
{
return 5; return 5;
} }
virtual int stack() { virtual int stack()
{
return StackRegister; return StackRegister;
} }
virtual int thread() { virtual int thread()
{
return ThreadRegister; return ThreadRegister;
} }
virtual int returnLow() { virtual int returnLow()
{
return 0; return 0;
} }
virtual int returnHigh() { virtual int returnHigh()
{
return 1; return 1;
} }
virtual int virtualCallTarget() { virtual int virtualCallTarget()
{
return 4; return 4;
} }
virtual int virtualCallIndex() { virtual int virtualCallIndex()
{
return 3; return 3;
} }
@ -185,15 +209,18 @@ class MyArchitecture: public Architecture {
return ir::TargetInfo(TargetBytesPerWord); return ir::TargetInfo(TargetBytesPerWord);
} }
virtual bool bigEndian() { virtual bool bigEndian()
{
return false; return false;
} }
virtual uintptr_t maximumImmediateJump() { virtual uintptr_t maximumImmediateJump()
{
return 0x1FFFFFF; return 0x1FFFFFF;
} }
virtual bool reserved(int register_) { virtual bool reserved(int register_)
{
switch (register_) { switch (register_) {
case LinkRegister: case LinkRegister:
case StackRegister: case StackRegister:
@ -206,15 +233,18 @@ class MyArchitecture: public Architecture {
} }
} }
virtual unsigned frameFootprint(unsigned footprint) { virtual unsigned frameFootprint(unsigned footprint)
{
return max(footprint, StackAlignmentInWords); return max(footprint, StackAlignmentInWords);
} }
virtual unsigned argumentFootprint(unsigned footprint) { virtual unsigned argumentFootprint(unsigned footprint)
{
return arm::argumentFootprint(footprint); return arm::argumentFootprint(footprint);
} }
virtual bool argumentAlignment() { virtual bool argumentAlignment()
{
#ifdef __APPLE__ #ifdef __APPLE__
return false; return false;
#else #else
@ -222,7 +252,8 @@ class MyArchitecture: public Architecture {
#endif #endif
} }
virtual bool argumentRegisterAlignment() { virtual bool argumentRegisterAlignment()
{
#ifdef __APPLE__ #ifdef __APPLE__
return false; return false;
#else #else
@ -230,29 +261,34 @@ class MyArchitecture: public Architecture {
#endif #endif
} }
virtual unsigned argumentRegisterCount() { virtual unsigned argumentRegisterCount()
{
return 4; return 4;
} }
virtual int argumentRegister(unsigned index) { virtual int argumentRegister(unsigned index)
{
assertT(&con, index < argumentRegisterCount()); assertT(&con, index < argumentRegisterCount());
return index; return index;
} }
virtual bool hasLinkRegister() { virtual bool hasLinkRegister()
{
return true; return true;
} }
virtual unsigned stackAlignmentInWords() { virtual unsigned stackAlignmentInWords()
{
return StackAlignmentInWords; return StackAlignmentInWords;
} }
virtual bool matchCall(void* returnAddress, void* target) { virtual bool matchCall(void* returnAddress, void* target)
{
uint32_t* instruction = static_cast<uint32_t*>(returnAddress) - 1; uint32_t* instruction = static_cast<uint32_t*>(returnAddress) - 1;
return *instruction == static_cast<uint32_t> return *instruction == static_cast<uint32_t>(
(bl(static_cast<uint8_t*>(target) bl(static_cast<uint8_t*>(target)
- reinterpret_cast<uint8_t*>(instruction))); - reinterpret_cast<uint8_t*>(instruction)));
} }
@ -265,7 +301,8 @@ class MyArchitecture: public Architecture {
case lir::Jump: case lir::Jump:
case lir::AlignedCall: case lir::AlignedCall:
case lir::AlignedJump: { case lir::AlignedJump: {
updateOffset(con.s, static_cast<uint8_t*>(returnAddress) - 4, updateOffset(con.s,
static_cast<uint8_t*>(returnAddress) - 4,
reinterpret_cast<intptr_t>(newTarget)); reinterpret_cast<intptr_t>(newTarget));
} break; } break;
@ -278,67 +315,90 @@ class MyArchitecture: public Architecture {
= newTarget; = newTarget;
} break; } break;
default: abort(&con); default:
abort(&con);
} }
} }
virtual unsigned constantCallSize() { virtual unsigned constantCallSize()
{
return 4; return 4;
} }
virtual void setConstant(void* dst, uint64_t constant) { virtual void setConstant(void* dst, uint64_t constant)
{
*static_cast<target_uintptr_t*>(dst) = constant; *static_cast<target_uintptr_t*>(dst) = constant;
} }
virtual unsigned alignFrameSize(unsigned sizeInWords) { virtual unsigned alignFrameSize(unsigned sizeInWords)
{
return pad(sizeInWords + FrameHeaderSize, StackAlignmentInWords) return pad(sizeInWords + FrameHeaderSize, StackAlignmentInWords)
- FrameHeaderSize; - FrameHeaderSize;
} }
virtual void nextFrame(void* start, unsigned size, unsigned footprint, virtual void nextFrame(void* start,
void* link, bool mostRecent, unsigned size,
int targetParameterFootprint, void** ip, unsigned footprint,
void* link,
bool mostRecent,
int targetParameterFootprint,
void** ip,
void** stack) void** stack)
{ {
arm::nextFrame(&con, static_cast<uint32_t*>(start), size, footprint, link, arm::nextFrame(&con,
mostRecent, targetParameterFootprint, ip, stack); static_cast<uint32_t*>(start),
size,
footprint,
link,
mostRecent,
targetParameterFootprint,
ip,
stack);
} }
virtual void* frameIp(void* stack) { virtual void* frameIp(void* stack)
{
return stack ? static_cast<void**>(stack)[returnAddressOffset()] : 0; return stack ? static_cast<void**>(stack)[returnAddressOffset()] : 0;
} }
virtual unsigned frameHeaderSize() { virtual unsigned frameHeaderSize()
{
return FrameHeaderSize; return FrameHeaderSize;
} }
virtual unsigned frameReturnAddressSize() { virtual unsigned frameReturnAddressSize()
{
return 0; return 0;
} }
virtual unsigned frameFooterSize() { virtual unsigned frameFooterSize()
{
return 0; return 0;
} }
virtual int returnAddressOffset() { virtual int returnAddressOffset()
{
return -1; return -1;
} }
virtual int framePointerOffset() { virtual int framePointerOffset()
{
return 0; return 0;
} }
virtual bool alwaysCondensed(lir::BinaryOperation) { virtual bool alwaysCondensed(lir::BinaryOperation)
{
return false; return false;
} }
virtual bool alwaysCondensed(lir::TernaryOperation) { virtual bool alwaysCondensed(lir::TernaryOperation)
{
return false; return false;
} }
virtual void plan virtual void plan(lir::UnaryOperation,
(lir::UnaryOperation, unsigned,
unsigned, OperandMask& aMask, OperandMask& aMask,
bool* thunk) bool* thunk)
{ {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand);
@ -346,10 +406,11 @@ class MyArchitecture: public Architecture {
*thunk = false; *thunk = false;
} }
virtual void planSource virtual void planSource(lir::BinaryOperation op,
(lir::BinaryOperation op, unsigned aSize,
unsigned aSize, OperandMask& aMask, OperandMask& aMask,
unsigned bSize, bool* thunk) unsigned bSize,
bool* thunk)
{ {
*thunk = false; *thunk = false;
aMask.typeMask = ~0; aMask.typeMask = ~0;
@ -404,10 +465,11 @@ class MyArchitecture: public Architecture {
} }
} }
virtual void planDestination virtual void planDestination(lir::BinaryOperation op,
(lir::BinaryOperation op, unsigned,
unsigned, const OperandMask& aMask, const OperandMask& aMask,
unsigned, OperandMask& bMask) unsigned,
OperandMask& bMask)
{ {
bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand);
bMask.registerMask = GPR_MASK64; bMask.registerMask = GPR_MASK64;
@ -443,8 +505,8 @@ class MyArchitecture: public Architecture {
} }
} }
virtual void planMove virtual void planMove(unsigned,
(unsigned, OperandMask& srcMask, OperandMask& srcMask,
OperandMask& tmpMask, OperandMask& tmpMask,
const OperandMask& dstMask) const OperandMask& dstMask)
{ {
@ -459,20 +521,21 @@ class MyArchitecture: public Architecture {
srcMask.typeMask = 1 << lir::RegisterOperand; srcMask.typeMask = 1 << lir::RegisterOperand;
tmpMask.typeMask = 1 << lir::RegisterOperand; tmpMask.typeMask = 1 << lir::RegisterOperand;
tmpMask.registerMask = GPR_MASK64; tmpMask.registerMask = GPR_MASK64;
} else if (vfpSupported() && } else if (vfpSupported() && dstMask.typeMask & 1 << lir::RegisterOperand
dstMask.typeMask & 1 << lir::RegisterOperand && && dstMask.registerMask & FPR_MASK) {
dstMask.registerMask & FPR_MASK) { srcMask.typeMask = tmpMask.typeMask = 1 << lir::RegisterOperand
srcMask.typeMask = tmpMask.typeMask = 1 << lir::RegisterOperand | | 1 << lir::MemoryOperand;
1 << lir::MemoryOperand;
tmpMask.registerMask = ~static_cast<uint64_t>(0); tmpMask.registerMask = ~static_cast<uint64_t>(0);
} }
} }
virtual void planSource virtual void planSource(lir::TernaryOperation op,
(lir::TernaryOperation op, unsigned,
unsigned, OperandMask& aMask, OperandMask& aMask,
unsigned bSize, OperandMask& bMask, unsigned bSize,
unsigned, bool* thunk) OperandMask& bMask,
unsigned,
bool* thunk)
{ {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand);
aMask.registerMask = GPR_MASK64; aMask.registerMask = GPR_MASK64;
@ -486,7 +549,8 @@ class MyArchitecture: public Architecture {
case lir::ShiftLeft: case lir::ShiftLeft:
case lir::ShiftRight: case lir::ShiftRight:
case lir::UnsignedShiftRight: case lir::UnsignedShiftRight:
if (bSize == 8) aMask.typeMask = bMask.typeMask = (1 << lir::RegisterOperand); if (bSize == 8)
aMask.typeMask = bMask.typeMask = (1 << lir::RegisterOperand);
break; break;
case lir::Add: case lir::Add:
@ -538,11 +602,13 @@ class MyArchitecture: public Architecture {
} }
} }
virtual void planDestination virtual void planDestination(lir::TernaryOperation op,
(lir::TernaryOperation op, unsigned,
unsigned, const OperandMask& aMask UNUSED, const OperandMask& aMask UNUSED,
unsigned, const OperandMask& bMask, unsigned,
unsigned, OperandMask& cMask) const OperandMask& bMask,
unsigned,
OperandMask& cMask)
{ {
if (isBranch(op)) { if (isBranch(op)) {
cMask.typeMask = (1 << lir::ConstantOperand); cMask.typeMask = (1 << lir::ConstantOperand);
@ -555,12 +621,14 @@ class MyArchitecture: public Architecture {
virtual Assembler* makeAssembler(Allocator* allocator, Zone* zone); virtual Assembler* makeAssembler(Allocator* allocator, Zone* zone);
virtual void acquire() { virtual void acquire()
++ referenceCount; {
++referenceCount;
} }
virtual void release() { virtual void release()
if (-- referenceCount == 0) { {
if (--referenceCount == 0) {
con.s->free(this); con.s->free(this);
} }
} }
@ -569,18 +637,21 @@ class MyArchitecture: public Architecture {
unsigned referenceCount; unsigned referenceCount;
}; };
class MyAssembler: public Assembler { class MyAssembler : public Assembler {
public: public:
MyAssembler(System* s, Allocator* a, Zone* zone, MyArchitecture* arch): MyAssembler(System* s, Allocator* a, Zone* zone, MyArchitecture* arch)
con(s, a, zone), arch_(arch) : con(s, a, zone), arch_(arch)
{ } {
}
virtual void setClient(Client* client) { virtual void setClient(Client* client)
{
assertT(&con, con.client == 0); assertT(&con, con.client == 0);
con.client = client; con.client = client;
} }
virtual Architecture* arch() { virtual Architecture* arch()
{
return arch_; return arch_;
} }
@ -589,12 +660,17 @@ class MyAssembler: public Assembler {
{ {
lir::Register stack(StackRegister); lir::Register stack(StackRegister);
lir::Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread); lir::Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread);
lir::Constant handlerConstant(new(con.zone) ResolvedPromise(handler)); lir::Constant handlerConstant(new (con.zone) ResolvedPromise(handler));
branchRM(&con, lir::JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, branchRM(&con,
lir::JumpIfGreaterOrEqual,
TargetBytesPerWord,
&stack,
&stackLimit,
&handlerConstant); &handlerConstant);
} }
virtual void saveFrame(unsigned stackOffset, unsigned ipOffset) { virtual void saveFrame(unsigned stackOffset, unsigned ipOffset)
{
lir::Register link(LinkRegister); lir::Register link(LinkRegister);
lir::Memory linkDst(ThreadRegister, ipOffset); lir::Memory linkDst(ThreadRegister, ipOffset);
moveRM(&con, TargetBytesPerWord, &link, TargetBytesPerWord, &linkDst); moveRM(&con, TargetBytesPerWord, &link, TargetBytesPerWord, &linkDst);
@ -604,7 +680,8 @@ class MyAssembler: public Assembler {
moveRM(&con, TargetBytesPerWord, &stack, TargetBytesPerWord, &stackDst); moveRM(&con, TargetBytesPerWord, &stack, TargetBytesPerWord, &stackDst);
} }
virtual void pushFrame(unsigned argumentCount, ...) { virtual void pushFrame(unsigned argumentCount, ...)
{
struct Argument { struct Argument {
unsigned size; unsigned size;
lir::OperandType type; lir::OperandType type;
@ -612,13 +689,16 @@ class MyAssembler: public Assembler {
}; };
RUNTIME_ARRAY(Argument, arguments, argumentCount); RUNTIME_ARRAY(Argument, arguments, argumentCount);
va_list a; va_start(a, argumentCount); va_list a;
va_start(a, argumentCount);
unsigned footprint = 0; unsigned footprint = 0;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned); RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned);
RUNTIME_ARRAY_BODY(arguments)[i].type = static_cast<lir::OperandType>(va_arg(a, int)); RUNTIME_ARRAY_BODY(arguments)[i].type
= static_cast<lir::OperandType>(va_arg(a, int));
RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, lir::Operand*); RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, lir::Operand*);
footprint += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); footprint += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size,
TargetBytesPerWord);
} }
va_end(a); va_end(a);
@ -630,31 +710,36 @@ class MyAssembler: public Assembler {
lir::Register dst(arch_->argumentRegister(i)); lir::Register dst(arch_->argumentRegister(i));
apply(lir::Move, apply(lir::Move,
OperandInfo( OperandInfo(RUNTIME_ARRAY_BODY(arguments)[i].size,
RUNTIME_ARRAY_BODY(arguments)[i].size,
RUNTIME_ARRAY_BODY(arguments)[i].type, RUNTIME_ARRAY_BODY(arguments)[i].type,
RUNTIME_ARRAY_BODY(arguments)[i].operand), RUNTIME_ARRAY_BODY(arguments)[i].operand),
OperandInfo( OperandInfo(pad(RUNTIME_ARRAY_BODY(arguments)[i].size,
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), lir::RegisterOperand, &dst)); TargetBytesPerWord),
lir::RegisterOperand,
&dst));
offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size,
TargetBytesPerWord);
} else { } else {
lir::Memory dst(StackRegister, offset * TargetBytesPerWord); lir::Memory dst(StackRegister, offset * TargetBytesPerWord);
apply(lir::Move, apply(lir::Move,
OperandInfo( OperandInfo(RUNTIME_ARRAY_BODY(arguments)[i].size,
RUNTIME_ARRAY_BODY(arguments)[i].size,
RUNTIME_ARRAY_BODY(arguments)[i].type, RUNTIME_ARRAY_BODY(arguments)[i].type,
RUNTIME_ARRAY_BODY(arguments)[i].operand), RUNTIME_ARRAY_BODY(arguments)[i].operand),
OperandInfo( OperandInfo(pad(RUNTIME_ARRAY_BODY(arguments)[i].size,
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), lir::MemoryOperand, &dst)); TargetBytesPerWord),
lir::MemoryOperand,
&dst));
offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size,
TargetBytesPerWord);
} }
} }
} }
virtual void allocateFrame(unsigned footprint) { virtual void allocateFrame(unsigned footprint)
{
footprint += FrameHeaderSize; footprint += FrameHeaderSize;
// larger frames may require multiple subtract/add instructions // larger frames may require multiple subtract/add instructions
@ -668,26 +753,34 @@ class MyAssembler: public Assembler {
subC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); subC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack);
lir::Register returnAddress(LinkRegister); lir::Register returnAddress(LinkRegister);
lir::Memory returnAddressDst lir::Memory returnAddressDst(StackRegister,
(StackRegister, (footprint - 1) * TargetBytesPerWord); (footprint - 1) * TargetBytesPerWord);
moveRM(&con, TargetBytesPerWord, &returnAddress, TargetBytesPerWord, moveRM(&con,
TargetBytesPerWord,
&returnAddress,
TargetBytesPerWord,
&returnAddressDst); &returnAddressDst);
} }
virtual void adjustFrame(unsigned difference) { virtual void adjustFrame(unsigned difference)
{
lir::Register stack(StackRegister); lir::Register stack(StackRegister);
ResolvedPromise differencePromise(difference * TargetBytesPerWord); ResolvedPromise differencePromise(difference * TargetBytesPerWord);
lir::Constant differenceConstant(&differencePromise); lir::Constant differenceConstant(&differencePromise);
subC(&con, TargetBytesPerWord, &differenceConstant, &stack, &stack); subC(&con, TargetBytesPerWord, &differenceConstant, &stack, &stack);
} }
virtual void popFrame(unsigned footprint) { virtual void popFrame(unsigned footprint)
{
footprint += FrameHeaderSize; footprint += FrameHeaderSize;
lir::Register returnAddress(LinkRegister); lir::Register returnAddress(LinkRegister);
lir::Memory returnAddressSrc lir::Memory returnAddressSrc(StackRegister,
(StackRegister, (footprint - 1) * TargetBytesPerWord); (footprint - 1) * TargetBytesPerWord);
moveMR(&con, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, moveMR(&con,
TargetBytesPerWord,
&returnAddressSrc,
TargetBytesPerWord,
&returnAddress); &returnAddress);
lir::Register stack(StackRegister); lir::Register stack(StackRegister);
@ -708,14 +801,17 @@ class MyAssembler: public Assembler {
footprint += FrameHeaderSize; footprint += FrameHeaderSize;
lir::Register link(LinkRegister); lir::Register link(LinkRegister);
lir::Memory returnAddressSrc lir::Memory returnAddressSrc(StackRegister,
(StackRegister, (footprint - 1) * TargetBytesPerWord); (footprint - 1) * TargetBytesPerWord);
moveMR(&con, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, moveMR(&con,
TargetBytesPerWord,
&returnAddressSrc,
TargetBytesPerWord,
&link); &link);
lir::Register stack(StackRegister); lir::Register stack(StackRegister);
ResolvedPromise footprintPromise ResolvedPromise footprintPromise((footprint - offset)
((footprint - offset) * TargetBytesPerWord); * TargetBytesPerWord);
lir::Constant footprintConstant(&footprintPromise); lir::Constant footprintConstant(&footprintPromise);
addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack);
@ -769,46 +865,52 @@ class MyAssembler: public Assembler {
return_(&con); return_(&con);
} }
virtual void apply(lir::Operation op) { virtual void apply(lir::Operation op)
{
arch_->con.operations[op](&con); arch_->con.operations[op](&con);
} }
virtual void apply(lir::UnaryOperation op, OperandInfo a) virtual void apply(lir::UnaryOperation op, OperandInfo a)
{ {
arch_->con.unaryOperations[Multimethod::index(op, a.type)] arch_->con.unaryOperations[Multimethod::index(op, a.type)](
(&con, a.size, a.operand); &con, a.size, a.operand);
} }
virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b)
{ {
arch_->con.binaryOperations[index(&(arch_->con), op, a.type, b.type)] arch_->con.binaryOperations[index(&(arch_->con), op, a.type, b.type)](
(&con, a.size, a.operand, b.size, b.operand); &con, a.size, a.operand, b.size, b.operand);
} }
virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) virtual void apply(lir::TernaryOperation op,
OperandInfo a,
OperandInfo b,
OperandInfo c)
{ {
if (isBranch(op)) { if (isBranch(op)) {
assertT(&con, a.size == b.size); assertT(&con, a.size == b.size);
assertT(&con, c.size == TargetBytesPerWord); assertT(&con, c.size == TargetBytesPerWord);
assertT(&con, c.type == lir::ConstantOperand); assertT(&con, c.type == lir::ConstantOperand);
arch_->con.branchOperations[branchIndex(&(arch_->con), a.type, b.type)] arch_->con.branchOperations[branchIndex(&(arch_->con), a.type, b.type)](
(&con, op, a.size, a.operand, b.operand, c.operand); &con, op, a.size, a.operand, b.operand, c.operand);
} else { } else {
assertT(&con, b.size == c.size); assertT(&con, b.size == c.size);
assertT(&con, b.type == lir::RegisterOperand); assertT(&con, b.type == lir::RegisterOperand);
assertT(&con, c.type == lir::RegisterOperand); assertT(&con, c.type == lir::RegisterOperand);
arch_->con.ternaryOperations[index(&(arch_->con), op, a.type)] arch_->con.ternaryOperations[index(&(arch_->con), op, a.type)](
(&con, b.size, a.operand, b.operand, c.operand); &con, b.size, a.operand, b.operand, c.operand);
} }
} }
virtual void setDestination(uint8_t* dst) { virtual void setDestination(uint8_t* dst)
{
con.result = dst; con.result = dst;
} }
virtual void write() { virtual void write()
{
uint8_t* dst = con.result; uint8_t* dst = con.result;
unsigned dstOffset = 0; unsigned dstOffset = 0;
for (MyBlock* b = con.firstBlock; b; b = b->next) { for (MyBlock* b = con.firstBlock; b; b = b->next) {
@ -828,8 +930,11 @@ class MyAssembler: public Assembler {
unsigned poolSize = 0; unsigned poolSize = 0;
for (PoolOffset* o = e->poolOffsetHead; o; o = o->next) { for (PoolOffset* o = e->poolOffsetHead; o; o = o->next) {
if (DebugPool) { if (DebugPool) {
fprintf(stderr, "visit pool offset %p %d in block %p\n", fprintf(stderr,
o, o->offset, b); "visit pool offset %p %d in block %p\n",
o,
o->offset,
b);
} }
unsigned entry = dstOffset + poolSize; unsigned entry = dstOffset + poolSize;
@ -840,8 +945,8 @@ class MyAssembler: public Assembler {
o->entry->address = dst + entry; o->entry->address = dst + entry;
unsigned instruction = o->block->start unsigned instruction = o->block->start + padding(o->block, o->offset)
+ padding(o->block, o->offset) + o->offset; + o->offset;
int32_t v = (entry - 8) - instruction; int32_t v = (entry - 8) - instruction;
expect(&con, v == (v & PoolOffsetMask)); expect(&con, v == (v & PoolOffsetMask));
@ -854,8 +959,8 @@ class MyAssembler: public Assembler {
bool jump = needJump(b); bool jump = needJump(b);
if (jump) { if (jump) {
write4 write4(dst + dstOffset,
(dst + dstOffset, isa::b((poolSize + TargetBytesPerWord - 8) >> 2)); isa::b((poolSize + TargetBytesPerWord - 8) >> 2));
} }
dstOffset += poolSize + (jump ? TargetBytesPerWord : 0); dstOffset += poolSize + (jump ? TargetBytesPerWord : 0);
@ -879,20 +984,23 @@ class MyAssembler: public Assembler {
*static_cast<target_uintptr_t*>(e->address) = e->constant->value(); *static_cast<target_uintptr_t*>(e->address) = e->constant->value();
} else { } else {
new (e->constant->listen(sizeof(ConstantPoolListener))) new (e->constant->listen(sizeof(ConstantPoolListener)))
ConstantPoolListener(con.s, static_cast<target_uintptr_t*>(e->address), ConstantPoolListener(
e->callOffset con.s,
? dst + e->callOffset->value() + 8 static_cast<target_uintptr_t*>(e->address),
: 0); e->callOffset ? dst + e->callOffset->value() + 8 : 0);
} }
// fprintf(stderr, "constant %p at %p\n", reinterpret_cast<void*>(e->constant->value()), e->address); // fprintf(stderr, "constant %p at %p\n",
// reinterpret_cast<void*>(e->constant->value()), e->address);
} }
} }
virtual Promise* offset(bool forTrace) { virtual Promise* offset(bool forTrace)
{
return arm::offsetPromise(&con, forTrace); return arm::offsetPromise(&con, forTrace);
} }
virtual Block* endBlock(bool startNew) { virtual Block* endBlock(bool startNew)
{
MyBlock* b = con.lastBlock; MyBlock* b = con.lastBlock;
b->size = con.code.length() - b->offset; b->size = con.code.length() - b->offset;
if (startNew) { if (startNew) {
@ -903,7 +1011,8 @@ class MyAssembler: public Assembler {
return b; return b;
} }
virtual void endEvent() { virtual void endEvent()
{
MyBlock* b = con.lastBlock; MyBlock* b = con.lastBlock;
unsigned thisEventOffset = con.code.length() - b->offset; unsigned thisEventOffset = con.code.length() - b->offset;
if (b->poolOffsetHead) { if (b->poolOffsetHead) {
@ -911,18 +1020,24 @@ class MyAssembler: public Assembler {
- b->poolOffsetHead->offset; - b->poolOffsetHead->offset;
if (v > 0 and v != (v & PoolOffsetMask)) { if (v > 0 and v != (v & PoolOffsetMask)) {
appendPoolEvent appendPoolEvent(&con,
(&con, b, b->lastEventOffset, b->poolOffsetHead, b,
b->lastEventOffset,
b->poolOffsetHead,
b->lastPoolOffsetTail); b->lastPoolOffsetTail);
if (DebugPool) { if (DebugPool) {
for (PoolOffset* o = b->poolOffsetHead; for (PoolOffset* o = b->poolOffsetHead;
o != b->lastPoolOffsetTail->next; o = o->next) o != b->lastPoolOffsetTail->next;
{ o = o->next) {
fprintf(stderr, fprintf(stderr,
"in endEvent, include %p %d in pool event %p at offset %d " "in endEvent, include %p %d in pool event %p at offset %d "
"in block %p\n", "in block %p\n",
o, o->offset, b->poolEventTail, b->lastEventOffset, b); o,
o->offset,
b->poolEventTail,
b->lastEventOffset,
b);
} }
} }
@ -937,15 +1052,18 @@ class MyAssembler: public Assembler {
b->lastPoolOffsetTail = b->poolOffsetTail; b->lastPoolOffsetTail = b->poolOffsetTail;
} }
virtual unsigned length() { virtual unsigned length()
{
return con.code.length(); return con.code.length();
} }
virtual unsigned footerSize() { virtual unsigned footerSize()
{
return 0; return 0;
} }
virtual void dispose() { virtual void dispose()
{
con.code.dispose(); con.code.dispose();
} }
@ -953,16 +1071,17 @@ class MyAssembler: public Assembler {
MyArchitecture* arch_; MyArchitecture* arch_;
}; };
Assembler* MyArchitecture::makeAssembler(Allocator* allocator, Zone* zone) { Assembler* MyArchitecture::makeAssembler(Allocator* allocator, Zone* zone)
return new(zone) MyAssembler(this->con.s, allocator, zone, this); {
return new (zone) MyAssembler(this->con.s, allocator, zone, this);
} }
} // namespace arm } // namespace arm
Architecture* Architecture* makeArchitectureArm(System* system, bool)
makeArchitectureArm(System* system, bool)
{ {
return new (allocate(system, sizeof(arm::MyArchitecture))) arm::MyArchitecture(system); return new (allocate(system, sizeof(arm::MyArchitecture)))
arm::MyArchitecture(system);
} }
} // namespace codegen } // namespace codegen

View File

@ -19,13 +19,23 @@ void resolve(MyBlock*);
unsigned padding(MyBlock*, unsigned); unsigned padding(MyBlock*, unsigned);
MyBlock::MyBlock(Context* context, unsigned offset): MyBlock::MyBlock(Context* context, unsigned offset)
context(context), next(0), poolOffsetHead(0), poolOffsetTail(0), : context(context),
lastPoolOffsetTail(0), poolEventHead(0), poolEventTail(0), next(0),
lastEventOffset(0), offset(offset), start(~0), size(0) poolOffsetHead(0),
{ } poolOffsetTail(0),
lastPoolOffsetTail(0),
poolEventHead(0),
poolEventTail(0),
lastEventOffset(0),
offset(offset),
start(~0),
size(0)
{
}
unsigned MyBlock::resolve(unsigned start, Assembler::Block* next) { unsigned MyBlock::resolve(unsigned start, Assembler::Block* next)
{
this->start = start; this->start = start;
this->next = static_cast<MyBlock*>(next); this->next = static_cast<MyBlock*>(next);

View File

@ -20,7 +20,7 @@ namespace arm {
class PoolEvent; class PoolEvent;
class MyBlock: public Assembler::Block { class MyBlock : public Assembler::Block {
public: public:
MyBlock(Context* context, unsigned offset); MyBlock(Context* context, unsigned offset);

View File

@ -57,38 +57,52 @@ typedef void (*OperationType)(Context*);
typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*); typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*);
typedef void (*BinaryOperationType) typedef void (*BinaryOperationType)(Context*,
(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*); unsigned,
lir::Operand*,
typedef void (*TernaryOperationType) unsigned,
(Context*, unsigned, lir::Operand*, lir::Operand*,
lir::Operand*); lir::Operand*);
typedef void (*BranchOperationType) typedef void (*TernaryOperationType)(Context*,
(Context*, lir::TernaryOperation, unsigned, lir::Operand*, unsigned,
lir::Operand*, lir::Operand*); lir::Operand*,
lir::Operand*,
lir::Operand*);
typedef void (*BranchOperationType)(Context*,
lir::TernaryOperation,
unsigned,
lir::Operand*,
lir::Operand*,
lir::Operand*);
class ArchitectureContext { class ArchitectureContext {
public: public:
ArchitectureContext(vm::System* s): s(s) { } ArchitectureContext(vm::System* s) : s(s)
{
}
vm::System* s; vm::System* s;
OperationType operations[lir::OperationCount]; OperationType operations[lir::OperationCount];
UnaryOperationType unaryOperations[lir::UnaryOperationCount UnaryOperationType
unaryOperations[lir::UnaryOperationCount * lir::OperandTypeCount];
BinaryOperationType binaryOperations[lir::BinaryOperationCount
* lir::OperandTypeCount
* lir::OperandTypeCount];
TernaryOperationType ternaryOperations[lir::NonBranchTernaryOperationCount
* lir::OperandTypeCount];
BranchOperationType branchOperations[lir::BranchOperationCount
* lir::OperandTypeCount
* lir::OperandTypeCount]; * lir::OperandTypeCount];
BinaryOperationType binaryOperations
[lir::BinaryOperationCount * lir::OperandTypeCount * lir::OperandTypeCount];
TernaryOperationType ternaryOperations
[lir::NonBranchTernaryOperationCount * lir::OperandTypeCount];
BranchOperationType branchOperations
[lir::BranchOperationCount * lir::OperandTypeCount * lir::OperandTypeCount];
}; };
inline avian::util::Aborter* getAborter(Context* c) { inline avian::util::Aborter* getAborter(Context* c)
{
return c->s; return c->s;
} }
inline avian::util::Aborter* getAborter(ArchitectureContext* c) { inline avian::util::Aborter* getAborter(ArchitectureContext* c)
{
return c->s; return c->s;
} }

View File

@ -25,159 +25,665 @@ const int FPSID = 0x0;
const int FPSCR = 0x1; const int FPSCR = 0x1;
const int FPEXC = 0x8; const int FPEXC = 0x8;
// INSTRUCTION OPTIONS // INSTRUCTION OPTIONS
enum CONDITION { EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV }; enum CONDITION {
EQ,
NE,
CS,
CC,
MI,
PL,
VS,
VC,
HI,
LS,
GE,
LT,
GT,
LE,
AL,
NV
};
enum SHIFTOP { LSL, LSR, ASR, ROR }; enum SHIFTOP { LSL, LSR, ASR, ROR };
// INSTRUCTION FORMATS // INSTRUCTION FORMATS
inline int DATA(int cond, int opcode, int S, int Rn, int Rd, int shift, int Sh, int Rm) inline int
{ return cond<<28 | opcode<<21 | S<<20 | Rn<<16 | Rd<<12 | shift<<7 | Sh<<5 | Rm; } DATA(int cond, int opcode, int S, int Rn, int Rd, int shift, int Sh, int Rm)
inline int DATAS(int cond, int opcode, int S, int Rn, int Rd, int Rs, int Sh, int Rm) {
{ return cond<<28 | opcode<<21 | S<<20 | Rn<<16 | Rd<<12 | Rs<<8 | Sh<<5 | 1<<4 | Rm; } return cond << 28 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12 | shift << 7
| Sh << 5 | Rm;
}
inline int
DATAS(int cond, int opcode, int S, int Rn, int Rd, int Rs, int Sh, int Rm)
{
return cond << 28 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12 | Rs << 8
| Sh << 5 | 1 << 4 | Rm;
}
inline int DATAI(int cond, int opcode, int S, int Rn, int Rd, int rot, int imm) inline int DATAI(int cond, int opcode, int S, int Rn, int Rd, int rot, int imm)
{ return cond<<28 | 1<<25 | opcode<<21 | S<<20 | Rn<<16 | Rd<<12 | rot<<8 | (imm&0xff); } {
return cond << 28 | 1 << 25 | opcode << 21 | S << 20 | Rn << 16 | Rd << 12
| rot << 8 | (imm & 0xff);
}
inline int BRANCH(int cond, int L, int offset) inline int BRANCH(int cond, int L, int offset)
{ return cond<<28 | 5<<25 | L<<24 | (offset&0xffffff); } {
return cond << 28 | 5 << 25 | L << 24 | (offset & 0xffffff);
}
inline int BRANCHX(int cond, int L, int Rm) inline int BRANCHX(int cond, int L, int Rm)
{ return cond<<28 | 0x4bffc<<6 | L<<5 | 1<<4 | Rm; } {
return cond << 28 | 0x4bffc << 6 | L << 5 | 1 << 4 | Rm;
}
inline int MULTIPLY(int cond, int mul, int S, int Rd, int Rn, int Rs, int Rm) inline int MULTIPLY(int cond, int mul, int S, int Rd, int Rn, int Rs, int Rm)
{ return cond<<28 | mul<<21 | S<<20 | Rd<<16 | Rn<<12 | Rs<<8 | 9<<4 | Rm; } {
inline int XFER(int cond, int P, int U, int B, int W, int L, int Rn, int Rd, int shift, int Sh, int Rm) return cond << 28 | mul << 21 | S << 20 | Rd << 16 | Rn << 12 | Rs << 8
{ return cond<<28 | 3<<25 | P<<24 | U<<23 | B<<22 | W<<21 | L<<20 | Rn<<16 | Rd<<12 | shift<<7 | Sh<<5 | Rm; } | 9 << 4 | Rm;
inline int XFERI(int cond, int P, int U, int B, int W, int L, int Rn, int Rd, int offset) }
{ return cond<<28 | 2<<25 | P<<24 | U<<23 | B<<22 | W<<21 | L<<20 | Rn<<16 | Rd<<12 | (offset&0xfff); } inline int XFER(int cond,
inline int XFER2(int cond, int P, int U, int W, int L, int Rn, int Rd, int S, int H, int Rm) int P,
{ return cond<<28 | P<<24 | U<<23 | W<<21 | L<<20 | Rn<<16 | Rd<<12 | 1<<7 | S<<6 | H<<5 | 1<<4 | Rm; } int U,
inline int XFER2I(int cond, int P, int U, int W, int L, int Rn, int Rd, int offsetH, int S, int H, int offsetL) int B,
{ return cond<<28 | P<<24 | U<<23 | 1<<22 | W<<21 | L<<20 | Rn<<16 | Rd<<12 | offsetH<<8 | 1<<7 | S<<6 | H<<5 | 1<<4 | (offsetL&0xf); } int W,
inline int COOP(int cond, int opcode_1, int CRn, int CRd, int cp_num, int opcode_2, int CRm) int L,
{ return cond<<28 | 0xe<<24 | opcode_1<<20 | CRn<<16 | CRd<<12 | cp_num<<8 | opcode_2<<5 | CRm; } int Rn,
inline int COXFER(int cond, int P, int U, int N, int W, int L, int Rn, int CRd, int cp_num, int offset) // offset is in words, not bytes int Rd,
{ return cond<<28 | 0x6<<25 | P<<24 | U<<23 | N<<22 | W<<21 | L<<20 | Rn<<16 | CRd<<12 | cp_num<<8 | (offset&0xff)>>2; } int shift,
inline int COREG(int cond, int opcode_1, int L, int CRn, int Rd, int cp_num, int opcode_2, int CRm) int Sh,
{ return cond<<28 | 0xe<<24 | opcode_1<<21 | L<<20 | CRn<<16 | Rd<<12 | cp_num<<8 | opcode_2<<5 | 1<<4 | CRm; } int Rm)
inline int COREG2(int cond, int L, int Rn, int Rd, int cp_num, int opcode, int CRm) {
{ return cond<<28 | 0xc4<<20 | L<<20 | Rn<<16 | Rd<<12 | cp_num<<8 | opcode<<4 | CRm;} return cond << 28 | 3 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20
| Rn << 16 | Rd << 12 | shift << 7 | Sh << 5 | Rm;
}
inline int XFERI(int cond,
int P,
int U,
int B,
int W,
int L,
int Rn,
int Rd,
int offset)
{
return cond << 28 | 2 << 25 | P << 24 | U << 23 | B << 22 | W << 21 | L << 20
| Rn << 16 | Rd << 12 | (offset & 0xfff);
}
inline int XFER2(int cond,
int P,
int U,
int W,
int L,
int Rn,
int Rd,
int S,
int H,
int Rm)
{
return cond << 28 | P << 24 | U << 23 | W << 21 | L << 20 | Rn << 16
| Rd << 12 | 1 << 7 | S << 6 | H << 5 | 1 << 4 | Rm;
}
inline int XFER2I(int cond,
int P,
int U,
int W,
int L,
int Rn,
int Rd,
int offsetH,
int S,
int H,
int offsetL)
{
return cond << 28 | P << 24 | U << 23 | 1 << 22 | W << 21 | L << 20 | Rn << 16
| Rd << 12 | offsetH << 8 | 1 << 7 | S << 6 | H << 5 | 1 << 4
| (offsetL & 0xf);
}
inline int COOP(int cond,
int opcode_1,
int CRn,
int CRd,
int cp_num,
int opcode_2,
int CRm)
{
return cond << 28 | 0xe << 24 | opcode_1 << 20 | CRn << 16 | CRd << 12
| cp_num << 8 | opcode_2 << 5 | CRm;
}
inline int COXFER(int cond,
int P,
int U,
int N,
int W,
int L,
int Rn,
int CRd,
int cp_num,
int offset) // offset is in words, not bytes
{
return cond << 28 | 0x6 << 25 | P << 24 | U << 23 | N << 22 | W << 21
| L << 20 | Rn << 16 | CRd << 12 | cp_num << 8 | (offset & 0xff) >> 2;
}
inline int COREG(int cond,
int opcode_1,
int L,
int CRn,
int Rd,
int cp_num,
int opcode_2,
int CRm)
{
return cond << 28 | 0xe << 24 | opcode_1 << 21 | L << 20 | CRn << 16
| Rd << 12 | cp_num << 8 | opcode_2 << 5 | 1 << 4 | CRm;
}
inline int
COREG2(int cond, int L, int Rn, int Rd, int cp_num, int opcode, int CRm)
{
return cond << 28 | 0xc4 << 20 | L << 20 | Rn << 16 | Rd << 12 | cp_num << 8
| opcode << 4 | CRm;
}
// FIELD CALCULATORS // FIELD CALCULATORS
inline int calcU(int imm) { return imm >= 0 ? 1 : 0; } inline int calcU(int imm)
{
return imm >= 0 ? 1 : 0;
}
// INSTRUCTIONS // INSTRUCTIONS
// The "cond" and "S" fields are set using the SETCOND() and SETS() functions // The "cond" and "S" fields are set using the SETCOND() and SETS() functions
inline int b(int offset) { return BRANCH(AL, 0, offset); } inline int b(int offset)
inline int bl(int offset) { return BRANCH(AL, 1, offset); } {
inline int bx(int Rm) { return BRANCHX(AL, 0, Rm); } return BRANCH(AL, 0, offset);
inline int blx(int Rm) { return BRANCHX(AL, 1, Rm); } }
inline int and_(int Rd, int Rn, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0x0, 0, Rn, Rd, shift, Sh, Rm); } inline int bl(int offset)
inline int eor(int Rd, int Rn, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0x1, 0, Rn, Rd, shift, Sh, Rm); } {
inline int rsb(int Rd, int Rn, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0x3, 0, Rn, Rd, shift, Sh, Rm); } return BRANCH(AL, 1, offset);
inline int add(int Rd, int Rn, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0x4, 0, Rn, Rd, shift, Sh, Rm); } }
inline int adc(int Rd, int Rn, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0x5, 0, Rn, Rd, shift, Sh, Rm); } inline int bx(int Rm)
inline int rsc(int Rd, int Rn, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0x7, 0, Rn, Rd, shift, Sh, Rm); } {
inline int cmp(int Rn, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0xa, 1, Rn, 0, shift, Sh, Rm); } return BRANCHX(AL, 0, Rm);
inline int orr(int Rd, int Rn, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0xc, 0, Rn, Rd, shift, Sh, Rm); } }
inline int mov(int Rd, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0xd, 0, 0, Rd, shift, Sh, Rm); } inline int blx(int Rm)
inline int mvn(int Rd, int Rm, int Sh=0, int shift=0) { return DATA(AL, 0xf, 0, 0, Rd, shift, Sh, Rm); } {
inline int andi(int Rd, int Rn, int imm, int rot=0) { return DATAI(AL, 0x0, 0, Rn, Rd, rot, imm); } return BRANCHX(AL, 1, Rm);
inline int subi(int Rd, int Rn, int imm, int rot=0) { return DATAI(AL, 0x2, 0, Rn, Rd, rot, imm); } }
inline int rsbi(int Rd, int Rn, int imm, int rot=0) { return DATAI(AL, 0x3, 0, Rn, Rd, rot, imm); } inline int and_(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
inline int addi(int Rd, int Rn, int imm, int rot=0) { return DATAI(AL, 0x4, 0, Rn, Rd, rot, imm); } {
inline int adci(int Rd, int Rn, int imm, int rot=0) { return DATAI(AL, 0x5, 0, Rn, Rd, rot, imm); } return DATA(AL, 0x0, 0, Rn, Rd, shift, Sh, Rm);
inline int bici(int Rd, int Rn, int imm, int rot=0) { return DATAI(AL, 0xe, 0, Rn, Rd, rot, imm); } }
inline int cmpi(int Rn, int imm, int rot=0) { return DATAI(AL, 0xa, 1, Rn, 0, rot, imm); } inline int eor(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
inline int movi(int Rd, int imm, int rot=0) { return DATAI(AL, 0xd, 0, 0, Rd, rot, imm); } {
inline int orrsh(int Rd, int Rn, int Rm, int Rs, int Sh) { return DATAS(AL, 0xc, 0, Rn, Rd, Rs, Sh, Rm); } return DATA(AL, 0x1, 0, Rn, Rd, shift, Sh, Rm);
inline int movsh(int Rd, int Rm, int Rs, int Sh) { return DATAS(AL, 0xd, 0, 0, Rd, Rs, Sh, Rm); } }
inline int mul(int Rd, int Rm, int Rs) { return MULTIPLY(AL, 0, 0, Rd, 0, Rs, Rm); } inline int rsb(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
inline int mla(int Rd, int Rm, int Rs, int Rn) { return MULTIPLY(AL, 1, 0, Rd, Rn, Rs, Rm); } {
inline int umull(int RdLo, int RdHi, int Rm, int Rs) { return MULTIPLY(AL, 4, 0, RdHi, RdLo, Rs, Rm); } return DATA(AL, 0x3, 0, Rn, Rd, shift, Sh, Rm);
inline int ldr(int Rd, int Rn, int Rm, int W=0) { return XFER(AL, 1, 1, 0, W, 1, Rn, Rd, 0, 0, Rm); } }
inline int ldri(int Rd, int Rn, int imm, int W=0) { return XFERI(AL, 1, calcU(imm), 0, W, 1, Rn, Rd, abs(imm)); } inline int add(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
inline int ldrb(int Rd, int Rn, int Rm) { return XFER(AL, 1, 1, 1, 0, 1, Rn, Rd, 0, 0, Rm); } {
inline int ldrbi(int Rd, int Rn, int imm) { return XFERI(AL, 1, calcU(imm), 1, 0, 1, Rn, Rd, abs(imm)); } return DATA(AL, 0x4, 0, Rn, Rd, shift, Sh, Rm);
inline int str(int Rd, int Rn, int Rm, int W=0) { return XFER(AL, 1, 1, 0, W, 0, Rn, Rd, 0, 0, Rm); } }
inline int stri(int Rd, int Rn, int imm, int W=0) { return XFERI(AL, 1, calcU(imm), 0, W, 0, Rn, Rd, abs(imm)); } inline int adc(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
inline int strb(int Rd, int Rn, int Rm) { return XFER(AL, 1, 1, 1, 0, 0, Rn, Rd, 0, 0, Rm); } {
inline int strbi(int Rd, int Rn, int imm) { return XFERI(AL, 1, calcU(imm), 1, 0, 0, Rn, Rd, abs(imm)); } return DATA(AL, 0x5, 0, Rn, Rd, shift, Sh, Rm);
inline int ldrh(int Rd, int Rn, int Rm) { return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 0, 1, Rm); } }
inline int ldrhi(int Rd, int Rn, int imm) { return XFER2I(AL, 1, calcU(imm), 0, 1, Rn, Rd, abs(imm)>>4 & 0xf, 0, 1, abs(imm)&0xf); } inline int rsc(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
inline int strh(int Rd, int Rn, int Rm) { return XFER2(AL, 1, 1, 0, 0, Rn, Rd, 0, 1, Rm); } {
inline int strhi(int Rd, int Rn, int imm) { return XFER2I(AL, 1, calcU(imm), 0, 0, Rn, Rd, abs(imm)>>4 & 0xf, 0, 1, abs(imm)&0xf); } return DATA(AL, 0x7, 0, Rn, Rd, shift, Sh, Rm);
inline int ldrsh(int Rd, int Rn, int Rm) { return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 1, 1, Rm); } }
inline int ldrshi(int Rd, int Rn, int imm) { return XFER2I(AL, 1, calcU(imm), 0, 1, Rn, Rd, abs(imm)>>4 & 0xf, 1, 1, abs(imm)&0xf); } inline int cmp(int Rn, int Rm, int Sh = 0, int shift = 0)
inline int ldrsb(int Rd, int Rn, int Rm) { return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 1, 0, Rm); } {
inline int ldrsbi(int Rd, int Rn, int imm) { return XFER2I(AL, 1, calcU(imm), 0, 1, Rn, Rd, abs(imm)>>4 & 0xf, 1, 0, abs(imm)&0xf); } return DATA(AL, 0xa, 1, Rn, 0, shift, Sh, Rm);
}
inline int orr(int Rd, int Rn, int Rm, int Sh = 0, int shift = 0)
{
return DATA(AL, 0xc, 0, Rn, Rd, shift, Sh, Rm);
}
inline int mov(int Rd, int Rm, int Sh = 0, int shift = 0)
{
return DATA(AL, 0xd, 0, 0, Rd, shift, Sh, Rm);
}
inline int mvn(int Rd, int Rm, int Sh = 0, int shift = 0)
{
return DATA(AL, 0xf, 0, 0, Rd, shift, Sh, Rm);
}
inline int andi(int Rd, int Rn, int imm, int rot = 0)
{
return DATAI(AL, 0x0, 0, Rn, Rd, rot, imm);
}
inline int subi(int Rd, int Rn, int imm, int rot = 0)
{
return DATAI(AL, 0x2, 0, Rn, Rd, rot, imm);
}
inline int rsbi(int Rd, int Rn, int imm, int rot = 0)
{
return DATAI(AL, 0x3, 0, Rn, Rd, rot, imm);
}
inline int addi(int Rd, int Rn, int imm, int rot = 0)
{
return DATAI(AL, 0x4, 0, Rn, Rd, rot, imm);
}
inline int adci(int Rd, int Rn, int imm, int rot = 0)
{
return DATAI(AL, 0x5, 0, Rn, Rd, rot, imm);
}
inline int bici(int Rd, int Rn, int imm, int rot = 0)
{
return DATAI(AL, 0xe, 0, Rn, Rd, rot, imm);
}
inline int cmpi(int Rn, int imm, int rot = 0)
{
return DATAI(AL, 0xa, 1, Rn, 0, rot, imm);
}
inline int movi(int Rd, int imm, int rot = 0)
{
return DATAI(AL, 0xd, 0, 0, Rd, rot, imm);
}
inline int orrsh(int Rd, int Rn, int Rm, int Rs, int Sh)
{
return DATAS(AL, 0xc, 0, Rn, Rd, Rs, Sh, Rm);
}
inline int movsh(int Rd, int Rm, int Rs, int Sh)
{
return DATAS(AL, 0xd, 0, 0, Rd, Rs, Sh, Rm);
}
inline int mul(int Rd, int Rm, int Rs)
{
return MULTIPLY(AL, 0, 0, Rd, 0, Rs, Rm);
}
inline int mla(int Rd, int Rm, int Rs, int Rn)
{
return MULTIPLY(AL, 1, 0, Rd, Rn, Rs, Rm);
}
inline int umull(int RdLo, int RdHi, int Rm, int Rs)
{
return MULTIPLY(AL, 4, 0, RdHi, RdLo, Rs, Rm);
}
inline int ldr(int Rd, int Rn, int Rm, int W = 0)
{
return XFER(AL, 1, 1, 0, W, 1, Rn, Rd, 0, 0, Rm);
}
inline int ldri(int Rd, int Rn, int imm, int W = 0)
{
return XFERI(AL, 1, calcU(imm), 0, W, 1, Rn, Rd, abs(imm));
}
inline int ldrb(int Rd, int Rn, int Rm)
{
return XFER(AL, 1, 1, 1, 0, 1, Rn, Rd, 0, 0, Rm);
}
inline int ldrbi(int Rd, int Rn, int imm)
{
return XFERI(AL, 1, calcU(imm), 1, 0, 1, Rn, Rd, abs(imm));
}
inline int str(int Rd, int Rn, int Rm, int W = 0)
{
return XFER(AL, 1, 1, 0, W, 0, Rn, Rd, 0, 0, Rm);
}
inline int stri(int Rd, int Rn, int imm, int W = 0)
{
return XFERI(AL, 1, calcU(imm), 0, W, 0, Rn, Rd, abs(imm));
}
inline int strb(int Rd, int Rn, int Rm)
{
return XFER(AL, 1, 1, 1, 0, 0, Rn, Rd, 0, 0, Rm);
}
inline int strbi(int Rd, int Rn, int imm)
{
return XFERI(AL, 1, calcU(imm), 1, 0, 0, Rn, Rd, abs(imm));
}
inline int ldrh(int Rd, int Rn, int Rm)
{
return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 0, 1, Rm);
}
inline int ldrhi(int Rd, int Rn, int imm)
{
return XFER2I(AL,
1,
calcU(imm),
0,
1,
Rn,
Rd,
abs(imm) >> 4 & 0xf,
0,
1,
abs(imm) & 0xf);
}
inline int strh(int Rd, int Rn, int Rm)
{
return XFER2(AL, 1, 1, 0, 0, Rn, Rd, 0, 1, Rm);
}
inline int strhi(int Rd, int Rn, int imm)
{
return XFER2I(AL,
1,
calcU(imm),
0,
0,
Rn,
Rd,
abs(imm) >> 4 & 0xf,
0,
1,
abs(imm) & 0xf);
}
inline int ldrsh(int Rd, int Rn, int Rm)
{
return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 1, 1, Rm);
}
inline int ldrshi(int Rd, int Rn, int imm)
{
return XFER2I(AL,
1,
calcU(imm),
0,
1,
Rn,
Rd,
abs(imm) >> 4 & 0xf,
1,
1,
abs(imm) & 0xf);
}
inline int ldrsb(int Rd, int Rn, int Rm)
{
return XFER2(AL, 1, 1, 0, 1, Rn, Rd, 1, 0, Rm);
}
inline int ldrsbi(int Rd, int Rn, int imm)
{
return XFER2I(AL,
1,
calcU(imm),
0,
1,
Rn,
Rd,
abs(imm) >> 4 & 0xf,
1,
0,
abs(imm) & 0xf);
}
// breakpoint instruction, this really has its own instruction format // breakpoint instruction, this really has its own instruction format
inline int bkpt(int16_t immed) { return 0xe1200070 | (((unsigned)immed & 0xffff) >> 4 << 8) | (immed & 0xf); } inline int bkpt(int16_t immed)
{
return 0xe1200070 | (((unsigned)immed & 0xffff) >> 4 << 8) | (immed & 0xf);
}
// COPROCESSOR INSTRUCTIONS // COPROCESSOR INSTRUCTIONS
inline int mcr(int coproc, int opcode_1, int Rd, int CRn, int CRm, int opcode_2=0) { return COREG(AL, opcode_1, 0, CRn, Rd, coproc, opcode_2, CRm); } inline int mcr(int coproc,
inline int mcrr(int coproc, int opcode, int Rd, int Rn, int CRm) { return COREG2(AL, 0, Rn, Rd, coproc, opcode, CRm); } int opcode_1,
inline int mrc(int coproc, int opcode_1, int Rd, int CRn, int CRm, int opcode_2=0) { return COREG(AL, opcode_1, 1, CRn, Rd, coproc, opcode_2, CRm); } int Rd,
inline int mrrc(int coproc, int opcode, int Rd, int Rn, int CRm) { return COREG2(AL, 1, Rn, Rd, coproc, opcode, CRm); } int CRn,
int CRm,
int opcode_2 = 0)
{
return COREG(AL, opcode_1, 0, CRn, Rd, coproc, opcode_2, CRm);
}
inline int mcrr(int coproc, int opcode, int Rd, int Rn, int CRm)
{
return COREG2(AL, 0, Rn, Rd, coproc, opcode, CRm);
}
inline int mrc(int coproc,
int opcode_1,
int Rd,
int CRn,
int CRm,
int opcode_2 = 0)
{
return COREG(AL, opcode_1, 1, CRn, Rd, coproc, opcode_2, CRm);
}
inline int mrrc(int coproc, int opcode, int Rd, int Rn, int CRm)
{
return COREG2(AL, 1, Rn, Rd, coproc, opcode, CRm);
}
// VFP FLOATING-POINT INSTRUCTIONS // VFP FLOATING-POINT INSTRUCTIONS
inline int fmuls(int Sd, int Sn, int Sm) { return COOP(AL, (Sd&1)<<2|2, Sn>>1, Sd>>1, 10, (Sn&1)<<2|(Sm&1), Sm>>1); } inline int fmuls(int Sd, int Sn, int Sm)
inline int fadds(int Sd, int Sn, int Sm) { return COOP(AL, (Sd&1)<<2|3, Sn>>1, Sd>>1, 10, (Sn&1)<<2|(Sm&1), Sm>>1); } {
inline int fsubs(int Sd, int Sn, int Sm) { return COOP(AL, (Sd&1)<<2|3, Sn>>1, Sd>>1, 10, (Sn&1)<<2|(Sm&1)|2, Sm>>1); } return COOP(AL,
inline int fdivs(int Sd, int Sn, int Sm) { return COOP(AL, (Sd&1)<<2|8, Sn>>1, Sd>>1, 10, (Sn&1)<<2|(Sm&1), Sm>>1); } (Sd & 1) << 2 | 2,
inline int fmuld(int Dd, int Dn, int Dm) { return COOP(AL, 2, Dn, Dd, 11, 0, Dm); } Sn >> 1,
inline int faddd(int Dd, int Dn, int Dm) { return COOP(AL, 3, Dn, Dd, 11, 0, Dm); } Sd >> 1,
inline int fsubd(int Dd, int Dn, int Dm) { return COOP(AL, 3, Dn, Dd, 11, 2, Dm); } 10,
inline int fdivd(int Dd, int Dn, int Dm) { return COOP(AL, 8, Dn, Dd, 11, 0, Dm); } (Sn & 1) << 2 | (Sm & 1),
inline int fcpys(int Sd, int Sm) { return COOP(AL, 0xb|(Sd&1)<<2, 0, Sd>>1, 10, 2|(Sm&1), Sm>>1); } Sm >> 1);
inline int fabss(int Sd, int Sm) { return COOP(AL, 0xb|(Sd&1)<<2, 0, Sd>>1, 10, 6|(Sm&1), Sm>>1); } }
inline int fnegs(int Sd, int Sm) { return COOP(AL, 0xb|(Sd&1)<<2, 1, Sd>>1, 10, 2|(Sm&1), Sm>>1); } inline int fadds(int Sd, int Sn, int Sm)
inline int fsqrts(int Sd, int Sm) { return COOP(AL, 0xb|(Sd&1)<<2, 1, Sd>>1, 10, 6|(Sm&1), Sm>>1); } {
inline int fcmps(int Sd, int Sm) { return COOP(AL, 0xb|(Sd&1)<<2, 4, Sd>>1, 10, 2|(Sm&1), Sm>>1); } return COOP(AL,
inline int fcvtds(int Dd, int Sm) { return COOP(AL, 0xb, 7, Dd, 10, 6|(Sm&1), Sm>>1); } (Sd & 1) << 2 | 3,
inline int fsitos(int Sd, int Sm) { return COOP(AL, 0xb|(Sd&1)<<2, 8, Sd>>1, 10, 6|(Sm&1), Sm>>1); } Sn >> 1,
inline int ftosizs(int Sd, int Sm) { return COOP(AL, 0xb|(Sd&1)<<2, 0xd, Sd>>1, 10, 6|(Sm&1), Sm>>1); } Sd >> 1,
inline int fcpyd(int Dd, int Dm) { return COOP(AL, 0xb, 0, Dd, 11, 2, Dm); } 10,
inline int fabsd(int Dd, int Dm) { return COOP(AL, 0xb, 0, Dd, 11, 6, Dm); } (Sn & 1) << 2 | (Sm & 1),
inline int fnegd(int Dd, int Dm) { return COOP(AL, 0xb, 1, Dd, 11, 2, Dm); } Sm >> 1);
inline int fsqrtd(int Dd, int Dm) { return COOP(AL, 0xb, 1, Dd, 11, 6, Dm); } }
inline int fsubs(int Sd, int Sn, int Sm)
{
return COOP(AL,
(Sd & 1) << 2 | 3,
Sn >> 1,
Sd >> 1,
10,
(Sn & 1) << 2 | (Sm & 1) | 2,
Sm >> 1);
}
inline int fdivs(int Sd, int Sn, int Sm)
{
return COOP(AL,
(Sd & 1) << 2 | 8,
Sn >> 1,
Sd >> 1,
10,
(Sn & 1) << 2 | (Sm & 1),
Sm >> 1);
}
inline int fmuld(int Dd, int Dn, int Dm)
{
return COOP(AL, 2, Dn, Dd, 11, 0, Dm);
}
inline int faddd(int Dd, int Dn, int Dm)
{
return COOP(AL, 3, Dn, Dd, 11, 0, Dm);
}
inline int fsubd(int Dd, int Dn, int Dm)
{
return COOP(AL, 3, Dn, Dd, 11, 2, Dm);
}
inline int fdivd(int Dd, int Dn, int Dm)
{
return COOP(AL, 8, Dn, Dd, 11, 0, Dm);
}
inline int fcpys(int Sd, int Sm)
{
return COOP(AL, 0xb | (Sd & 1) << 2, 0, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1);
}
inline int fabss(int Sd, int Sm)
{
return COOP(AL, 0xb | (Sd & 1) << 2, 0, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1);
}
inline int fnegs(int Sd, int Sm)
{
return COOP(AL, 0xb | (Sd & 1) << 2, 1, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1);
}
inline int fsqrts(int Sd, int Sm)
{
return COOP(AL, 0xb | (Sd & 1) << 2, 1, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1);
}
inline int fcmps(int Sd, int Sm)
{
return COOP(AL, 0xb | (Sd & 1) << 2, 4, Sd >> 1, 10, 2 | (Sm & 1), Sm >> 1);
}
inline int fcvtds(int Dd, int Sm)
{
return COOP(AL, 0xb, 7, Dd, 10, 6 | (Sm & 1), Sm >> 1);
}
inline int fsitos(int Sd, int Sm)
{
return COOP(AL, 0xb | (Sd & 1) << 2, 8, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1);
}
inline int ftosizs(int Sd, int Sm)
{
return COOP(AL, 0xb | (Sd & 1) << 2, 0xd, Sd >> 1, 10, 6 | (Sm & 1), Sm >> 1);
}
inline int fcpyd(int Dd, int Dm)
{
return COOP(AL, 0xb, 0, Dd, 11, 2, Dm);
}
inline int fabsd(int Dd, int Dm)
{
return COOP(AL, 0xb, 0, Dd, 11, 6, Dm);
}
inline int fnegd(int Dd, int Dm)
{
return COOP(AL, 0xb, 1, Dd, 11, 2, Dm);
}
inline int fsqrtd(int Dd, int Dm)
{
return COOP(AL, 0xb, 1, Dd, 11, 6, Dm);
}
// double-precision comparison instructions // double-precision comparison instructions
inline int fcmpd(int Dd, int Dm) { return COOP(AL, 0xb, 4, Dd, 11, 2, Dm); } inline int fcmpd(int Dd, int Dm)
{
return COOP(AL, 0xb, 4, Dd, 11, 2, Dm);
}
// double-precision conversion instructions // double-precision conversion instructions
inline int fcvtsd(int Sd, int Dm) { return COOP(AL, 0xb|(Sd&1)<<2, 7, Sd>>1, 11, 6, Dm); } inline int fcvtsd(int Sd, int Dm)
inline int fsitod(int Dd, int Sm) { return COOP(AL, 0xb, 8, Dd, 11, 6|(Sm&1), Sm>>1); } {
inline int ftosizd(int Sd, int Dm) { return COOP(AL, 0xb|(Sd&1)<<2, 0xd, Sd>>1, 11, 6, Dm); } return COOP(AL, 0xb | (Sd & 1) << 2, 7, Sd >> 1, 11, 6, Dm);
}
inline int fsitod(int Dd, int Sm)
{
return COOP(AL, 0xb, 8, Dd, 11, 6 | (Sm & 1), Sm >> 1);
}
inline int ftosizd(int Sd, int Dm)
{
return COOP(AL, 0xb | (Sd & 1) << 2, 0xd, Sd >> 1, 11, 6, Dm);
}
// single load/store instructions for both precision types // single load/store instructions for both precision types
inline int flds(int Sd, int Rn, int offset=0) { return COXFER(AL, 1, 1, Sd&1, 0, 1, Rn, Sd>>1, 10, offset); }; inline int flds(int Sd, int Rn, int offset = 0)
inline int fldd(int Dd, int Rn, int offset=0) { return COXFER(AL, 1, 1, 0, 0, 1, Rn, Dd, 11, offset); }; {
inline int fsts(int Sd, int Rn, int offset=0) { return COXFER(AL, 1, 1, Sd&1, 0, 0, Rn, Sd>>1, 10, offset); }; return COXFER(AL, 1, 1, Sd & 1, 0, 1, Rn, Sd >> 1, 10, offset);
inline int fstd(int Dd, int Rn, int offset=0) { return COXFER(AL, 1, 1, 0, 0, 0, Rn, Dd, 11, offset); }; };
inline int fldd(int Dd, int Rn, int offset = 0)
{
return COXFER(AL, 1, 1, 0, 0, 1, Rn, Dd, 11, offset);
};
inline int fsts(int Sd, int Rn, int offset = 0)
{
return COXFER(AL, 1, 1, Sd & 1, 0, 0, Rn, Sd >> 1, 10, offset);
};
inline int fstd(int Dd, int Rn, int offset = 0)
{
return COXFER(AL, 1, 1, 0, 0, 0, Rn, Dd, 11, offset);
};
// move between GPRs and FPRs // move between GPRs and FPRs
inline int fmsr(int Sn, int Rd) { return mcr(10, 0, Rd, Sn>>1, 0, (Sn&1)<<2); } inline int fmsr(int Sn, int Rd)
inline int fmrs(int Rd, int Sn) { return mrc(10, 0, Rd, Sn>>1, 0, (Sn&1)<<2); } {
return mcr(10, 0, Rd, Sn >> 1, 0, (Sn & 1) << 2);
}
inline int fmrs(int Rd, int Sn)
{
return mrc(10, 0, Rd, Sn >> 1, 0, (Sn & 1) << 2);
}
// move to/from VFP system registers // move to/from VFP system registers
inline int fmrx(int Rd, int reg) { return mrc(10, 7, Rd, reg, 0); } inline int fmrx(int Rd, int reg)
{
return mrc(10, 7, Rd, reg, 0);
}
// these move around pairs of single-precision registers // these move around pairs of single-precision registers
inline int fmdrr(int Dm, int Rd, int Rn) { return mcrr(11, 1, Rd, Rn, Dm); } inline int fmdrr(int Dm, int Rd, int Rn)
inline int fmrrd(int Rd, int Rn, int Dm) { return mrrc(11, 1, Rd, Rn, Dm); } {
return mcrr(11, 1, Rd, Rn, Dm);
}
inline int fmrrd(int Rd, int Rn, int Dm)
{
return mrrc(11, 1, Rd, Rn, Dm);
}
// FLAG SETTERS // FLAG SETTERS
inline int SETCOND(int ins, int cond) { return ((ins&0x0fffffff) | (cond<<28)); } inline int SETCOND(int ins, int cond)
inline int SETS(int ins) { return ins | 1<<20; } {
return ((ins & 0x0fffffff) | (cond << 28));
}
inline int SETS(int ins)
{
return ins | 1 << 20;
}
// PSEUDO-INSTRUCTIONS // PSEUDO-INSTRUCTIONS
inline int lsl(int Rd, int Rm, int Rs) { return movsh(Rd, Rm, Rs, LSL); } inline int lsl(int Rd, int Rm, int Rs)
inline int lsli(int Rd, int Rm, int imm) { return mov(Rd, Rm, LSL, imm); } {
inline int lsr(int Rd, int Rm, int Rs) { return movsh(Rd, Rm, Rs, LSR); } return movsh(Rd, Rm, Rs, LSL);
inline int lsri(int Rd, int Rm, int imm) { return mov(Rd, Rm, LSR, imm); } }
inline int asr(int Rd, int Rm, int Rs) { return movsh(Rd, Rm, Rs, ASR); } inline int lsli(int Rd, int Rm, int imm)
inline int asri(int Rd, int Rm, int imm) { return mov(Rd, Rm, ASR, imm); } {
inline int beq(int offset) { return SETCOND(b(offset), EQ); } return mov(Rd, Rm, LSL, imm);
inline int bne(int offset) { return SETCOND(b(offset), NE); } }
inline int bls(int offset) { return SETCOND(b(offset), LS); } inline int lsr(int Rd, int Rm, int Rs)
inline int bhi(int offset) { return SETCOND(b(offset), HI); } {
inline int blt(int offset) { return SETCOND(b(offset), LT); } return movsh(Rd, Rm, Rs, LSR);
inline int bgt(int offset) { return SETCOND(b(offset), GT); } }
inline int ble(int offset) { return SETCOND(b(offset), LE); } inline int lsri(int Rd, int Rm, int imm)
inline int bge(int offset) { return SETCOND(b(offset), GE); } {
inline int blo(int offset) { return SETCOND(b(offset), CC); } return mov(Rd, Rm, LSR, imm);
inline int bhs(int offset) { return SETCOND(b(offset), CS); } }
inline int bpl(int offset) { return SETCOND(b(offset), PL); } inline int asr(int Rd, int Rm, int Rs)
inline int fmstat() { return fmrx(15, FPSCR); } {
return movsh(Rd, Rm, Rs, ASR);
}
inline int asri(int Rd, int Rm, int imm)
{
return mov(Rd, Rm, ASR, imm);
}
inline int beq(int offset)
{
return SETCOND(b(offset), EQ);
}
inline int bne(int offset)
{
return SETCOND(b(offset), NE);
}
inline int bls(int offset)
{
return SETCOND(b(offset), LS);
}
inline int bhi(int offset)
{
return SETCOND(b(offset), HI);
}
inline int blt(int offset)
{
return SETCOND(b(offset), LT);
}
inline int bgt(int offset)
{
return SETCOND(b(offset), GT);
}
inline int ble(int offset)
{
return SETCOND(b(offset), LE);
}
inline int bge(int offset)
{
return SETCOND(b(offset), GE);
}
inline int blo(int offset)
{
return SETCOND(b(offset), CC);
}
inline int bhs(int offset)
{
return SETCOND(b(offset), CS);
}
inline int bpl(int offset)
{
return SETCOND(b(offset), PL);
}
inline int fmstat()
{
return fmrx(15, FPSCR);
}
// todo: make this pretty: // todo: make this pretty:
inline int dmb() { return 0xf57ff05f; } inline int dmb()
{
return 0xf57ff05f;
}
} // namespace isa } // namespace isa
inline void emit(Context* con, int code) { con->code.append4(code); } inline void emit(Context* con, int code)
{
con->code.append4(code);
}
} // namespace arm } // namespace arm
} // namespace codegen } // namespace codegen

View File

@ -20,65 +20,78 @@ using namespace util;
unsigned padding(MyBlock*, unsigned); unsigned padding(MyBlock*, unsigned);
OffsetPromise::OffsetPromise(Context* con, MyBlock* block, unsigned offset, bool forTrace): OffsetPromise::OffsetPromise(Context* con,
con(con), block(block), offset(offset), forTrace(forTrace) MyBlock* block,
{ } unsigned offset,
bool forTrace)
: con(con), block(block), offset(offset), forTrace(forTrace)
{
}
bool OffsetPromise::resolved() { bool OffsetPromise::resolved()
{
return block->start != static_cast<unsigned>(~0); return block->start != static_cast<unsigned>(~0);
} }
int64_t OffsetPromise::value() { int64_t OffsetPromise::value()
{
assertT(con, resolved()); assertT(con, resolved());
unsigned o = offset - block->offset; unsigned o = offset - block->offset;
return block->start + padding return block->start
(block, forTrace ? o - vm::TargetBytesPerWord : o) + o; + padding(block, forTrace ? o - vm::TargetBytesPerWord : o) + o;
} }
Promise* offsetPromise(Context* con, bool forTrace)
Promise* offsetPromise(Context* con, bool forTrace) { {
return new(con->zone) OffsetPromise(con, con->lastBlock, con->code.length(), forTrace); return new (con->zone)
OffsetPromise(con, con->lastBlock, con->code.length(), forTrace);
} }
OffsetListener::OffsetListener(vm::System* s, uint8_t* instruction)
: s(s), instruction(instruction)
{
}
OffsetListener::OffsetListener(vm::System* s, uint8_t* instruction): bool OffsetListener::resolve(int64_t value, void** location)
s(s), {
instruction(instruction)
{ }
bool OffsetListener::resolve(int64_t value, void** location) {
void* p = updateOffset(s, instruction, value); void* p = updateOffset(s, instruction, value);
if (location) *location = p; if (location)
*location = p;
return false; return false;
} }
OffsetTask::OffsetTask(Task* next, Promise* promise, Promise* instructionOffset)
: Task(next), promise(promise), instructionOffset(instructionOffset)
{
}
OffsetTask::OffsetTask(Task* next, Promise* promise, Promise* instructionOffset): void OffsetTask::run(Context* con)
Task(next), {
promise(promise),
instructionOffset(instructionOffset)
{ }
void OffsetTask::run(Context* con) {
if (promise->resolved()) { if (promise->resolved()) {
updateOffset updateOffset(
(con->s, con->result + instructionOffset->value(), promise->value()); con->s, con->result + instructionOffset->value(), promise->value());
} else { } else {
new (promise->listen(sizeof(OffsetListener))) new (promise->listen(sizeof(OffsetListener)))
OffsetListener(con->s, con->result + instructionOffset->value()); OffsetListener(con->s, con->result + instructionOffset->value());
} }
} }
void appendOffsetTask(Context* con, Promise* promise, Promise* instructionOffset) { void appendOffsetTask(Context* con,
con->tasks = new(con->zone) OffsetTask(con->tasks, promise, instructionOffset); Promise* promise,
Promise* instructionOffset)
{
con->tasks = new (con->zone)
OffsetTask(con->tasks, promise, instructionOffset);
} }
bool bounded(int right, int left, int32_t v) { bool bounded(int right, int left, int32_t v)
{
return ((v << left) >> left) == v and ((v >> right) << right) == v; return ((v << left) >> left) == v and ((v >> right) << right) == v;
} }
void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value) { void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value)
{
// ARM's PC is two words ahead, and branches drop the bottom 2 bits. // ARM's PC is two words ahead, and branches drop the bottom 2 bits.
int32_t v = (reinterpret_cast<uint8_t*>(value) - (instruction + 8)) >> 2; int32_t v = (reinterpret_cast<uint8_t*>(value) - (instruction + 8)) >> 2;
@ -92,30 +105,39 @@ void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value) {
return instruction + 4; return instruction + 4;
} }
ConstantPoolEntry::ConstantPoolEntry(Context* con, Promise* constant, ConstantPoolEntry* next, ConstantPoolEntry::ConstantPoolEntry(Context* con,
Promise* callOffset): Promise* constant,
con(con), constant(constant), next(next), callOffset(callOffset), ConstantPoolEntry* next,
Promise* callOffset)
: con(con),
constant(constant),
next(next),
callOffset(callOffset),
address(0) address(0)
{ } {
}
int64_t ConstantPoolEntry::value() { int64_t ConstantPoolEntry::value()
{
assertT(con, resolved()); assertT(con, resolved());
return reinterpret_cast<int64_t>(address); return reinterpret_cast<int64_t>(address);
} }
bool ConstantPoolEntry::resolved() { bool ConstantPoolEntry::resolved()
{
return address != 0; return address != 0;
} }
ConstantPoolListener::ConstantPoolListener(vm::System* s, vm::target_uintptr_t* address, ConstantPoolListener::ConstantPoolListener(vm::System* s,
uint8_t* returnAddress): vm::target_uintptr_t* address,
s(s), uint8_t* returnAddress)
address(address), : s(s), address(address), returnAddress(returnAddress)
returnAddress(returnAddress) {
{ } }
bool ConstantPoolListener::resolve(int64_t value, void** location) { bool ConstantPoolListener::resolve(int64_t value, void** location)
{
*address = value; *address = value;
if (location) { if (location) {
*location = returnAddress ? static_cast<void*>(returnAddress) : address; *location = returnAddress ? static_cast<void*>(returnAddress) : address;
@ -123,32 +145,49 @@ bool ConstantPoolListener::resolve(int64_t value, void** location) {
return true; return true;
} }
PoolOffset::PoolOffset(MyBlock* block, ConstantPoolEntry* entry, unsigned offset): PoolOffset::PoolOffset(MyBlock* block,
block(block), entry(entry), next(0), offset(offset) ConstantPoolEntry* entry,
{ } unsigned offset)
: block(block), entry(entry), next(0), offset(offset)
{
}
PoolEvent::PoolEvent(PoolOffset* poolOffsetHead, PoolOffset* poolOffsetTail, PoolEvent::PoolEvent(PoolOffset* poolOffsetHead,
unsigned offset): PoolOffset* poolOffsetTail,
poolOffsetHead(poolOffsetHead), poolOffsetTail(poolOffsetTail), next(0), unsigned offset)
: poolOffsetHead(poolOffsetHead),
poolOffsetTail(poolOffsetTail),
next(0),
offset(offset) offset(offset)
{ } {
}
void appendConstantPoolEntry(Context* con, Promise* constant, Promise* callOffset) { void appendConstantPoolEntry(Context* con,
Promise* constant,
Promise* callOffset)
{
if (constant->resolved()) { if (constant->resolved()) {
// make a copy, since the original might be allocated on the // make a copy, since the original might be allocated on the
// stack, and we need our copy to live until assembly is complete // stack, and we need our copy to live until assembly is complete
constant = new(con->zone) ResolvedPromise(constant->value()); constant = new (con->zone) ResolvedPromise(constant->value());
} }
con->constantPool = new(con->zone) ConstantPoolEntry(con, constant, con->constantPool, callOffset); con->constantPool = new (con->zone)
ConstantPoolEntry(con, constant, con->constantPool, callOffset);
++ con->constantPoolCount; ++con->constantPoolCount;
PoolOffset* o = new(con->zone) PoolOffset(con->lastBlock, con->constantPool, con->code.length() - con->lastBlock->offset); PoolOffset* o = new (con->zone)
PoolOffset(con->lastBlock,
con->constantPool,
con->code.length() - con->lastBlock->offset);
if (DebugPool) { if (DebugPool) {
fprintf(stderr, "add pool offset %p %d to block %p\n", fprintf(stderr,
o, o->offset, con->lastBlock); "add pool offset %p %d to block %p\n",
o,
o->offset,
con->lastBlock);
} }
if (con->lastBlock->poolOffsetTail) { if (con->lastBlock->poolOffsetTail) {
@ -159,10 +198,13 @@ void appendConstantPoolEntry(Context* con, Promise* constant, Promise* callOffse
con->lastBlock->poolOffsetTail = o; con->lastBlock->poolOffsetTail = o;
} }
void appendPoolEvent(Context* con, MyBlock* b, unsigned offset, PoolOffset* head, void appendPoolEvent(Context* con,
MyBlock* b,
unsigned offset,
PoolOffset* head,
PoolOffset* tail) PoolOffset* tail)
{ {
PoolEvent* e = new(con->zone) PoolEvent(head, tail, offset); PoolEvent* e = new (con->zone) PoolEvent(head, tail, offset);
if (b->poolEventTail) { if (b->poolEventTail) {
b->poolEventTail->next = e; b->poolEventTail->next = e;

View File

@ -31,14 +31,16 @@ const int32_t PoolOffsetMask = 0xFFF;
class Task { class Task {
public: public:
Task(Task* next): next(next) { } Task(Task* next) : next(next)
{
}
virtual void run(Context* con) = 0; virtual void run(Context* con) = 0;
Task* next; Task* next;
}; };
class OffsetPromise: public Promise { class OffsetPromise : public Promise {
public: public:
OffsetPromise(Context* con, MyBlock* block, unsigned offset, bool forTrace); OffsetPromise(Context* con, MyBlock* block, unsigned offset, bool forTrace);
@ -54,7 +56,7 @@ class OffsetPromise: public Promise {
Promise* offsetPromise(Context* con, bool forTrace = false); Promise* offsetPromise(Context* con, bool forTrace = false);
class OffsetListener: public Promise::Listener { class OffsetListener : public Promise::Listener {
public: public:
OffsetListener(vm::System* s, uint8_t* instruction); OffsetListener(vm::System* s, uint8_t* instruction);
@ -64,7 +66,7 @@ class OffsetListener: public Promise::Listener {
uint8_t* instruction; uint8_t* instruction;
}; };
class OffsetTask: public Task { class OffsetTask : public Task {
public: public:
OffsetTask(Task* next, Promise* promise, Promise* instructionOffset); OffsetTask(Task* next, Promise* promise, Promise* instructionOffset);
@ -74,13 +76,17 @@ class OffsetTask: public Task {
Promise* instructionOffset; Promise* instructionOffset;
}; };
void appendOffsetTask(Context* con, Promise* promise, Promise* instructionOffset); void appendOffsetTask(Context* con,
Promise* promise,
Promise* instructionOffset);
void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value); void* updateOffset(vm::System* s, uint8_t* instruction, int64_t value);
class ConstantPoolEntry: public Promise { class ConstantPoolEntry : public Promise {
public: public:
ConstantPoolEntry(Context* con, Promise* constant, ConstantPoolEntry* next, ConstantPoolEntry(Context* con,
Promise* constant,
ConstantPoolEntry* next,
Promise* callOffset); Promise* callOffset);
virtual int64_t value(); virtual int64_t value();
@ -95,9 +101,10 @@ class ConstantPoolEntry: public Promise {
unsigned constantPoolCount; unsigned constantPoolCount;
}; };
class ConstantPoolListener: public Promise::Listener { class ConstantPoolListener : public Promise::Listener {
public: public:
ConstantPoolListener(vm::System* s, vm::target_uintptr_t* address, ConstantPoolListener(vm::System* s,
vm::target_uintptr_t* address,
uint8_t* returnAddress); uint8_t* returnAddress);
virtual bool resolve(int64_t value, void** location); virtual bool resolve(int64_t value, void** location);
@ -119,7 +126,8 @@ class PoolOffset {
class PoolEvent { class PoolEvent {
public: public:
PoolEvent(PoolOffset* poolOffsetHead, PoolOffset* poolOffsetTail, PoolEvent(PoolOffset* poolOffsetHead,
PoolOffset* poolOffsetTail,
unsigned offset); unsigned offset);
PoolOffset* poolOffsetHead; PoolOffset* poolOffsetHead;
@ -128,9 +136,14 @@ class PoolEvent {
unsigned offset; unsigned offset;
}; };
void appendConstantPoolEntry(Context* con, Promise* constant, Promise* callOffset); void appendConstantPoolEntry(Context* con,
Promise* constant,
Promise* callOffset);
void appendPoolEvent(Context* con, MyBlock* b, unsigned offset, PoolOffset* head, void appendPoolEvent(Context* con,
MyBlock* b,
unsigned offset,
PoolOffset* head,
PoolOffset* tail); PoolOffset* tail);
} // namespace arm } // namespace arm

View File

@ -25,8 +25,7 @@ unsigned index(ArchitectureContext*,
lir::OperandType operand1, lir::OperandType operand1,
lir::OperandType operand2) lir::OperandType operand2)
{ {
return operation return operation + (lir::BinaryOperationCount * operand1)
+ (lir::BinaryOperationCount * operand1)
+ (lir::BinaryOperationCount * lir::OperandTypeCount * operand2); + (lir::BinaryOperationCount * lir::OperandTypeCount * operand2);
} }
@ -39,13 +38,15 @@ unsigned index(ArchitectureContext* con UNUSED,
return operation + (lir::NonBranchTernaryOperationCount * operand1); return operation + (lir::NonBranchTernaryOperationCount * operand1);
} }
unsigned branchIndex(ArchitectureContext* con UNUSED, lir::OperandType operand1, unsigned branchIndex(ArchitectureContext* con UNUSED,
lir::OperandType operand1,
lir::OperandType operand2) lir::OperandType operand2)
{ {
return operand1 + (lir::OperandTypeCount * operand2); return operand1 + (lir::OperandTypeCount * operand2);
} }
void populateTables(ArchitectureContext* con) { void populateTables(ArchitectureContext* con)
{
const lir::OperandType C = lir::ConstantOperand; const lir::OperandType C = lir::ConstantOperand;
const lir::OperandType A = lir::AddressOperand; const lir::OperandType A = lir::AddressOperand;
const lir::OperandType R = lir::RegisterOperand; const lir::OperandType R = lir::RegisterOperand;

View File

@ -32,7 +32,8 @@ unsigned index(ArchitectureContext* con UNUSED,
lir::TernaryOperation operation, lir::TernaryOperation operation,
lir::OperandType operand1); lir::OperandType operand1);
unsigned branchIndex(ArchitectureContext* con UNUSED, lir::OperandType operand1, unsigned branchIndex(ArchitectureContext* con UNUSED,
lir::OperandType operand1,
lir::OperandType operand2); lir::OperandType operand2);
void populateTables(ArchitectureContext* con); void populateTables(ArchitectureContext* con);

File diff suppressed because it is too large Load Diff

View File

@ -25,51 +25,87 @@ class Context;
// shortcut functions // shortcut functions
inline int newTemp(Context* con) { inline int newTemp(Context* con)
{
return con->client->acquireTemporary(GPR_MASK); return con->client->acquireTemporary(GPR_MASK);
} }
inline int newTemp(Context* con, unsigned mask) { inline int newTemp(Context* con, unsigned mask)
{
return con->client->acquireTemporary(mask); return con->client->acquireTemporary(mask);
} }
inline void freeTemp(Context* con, int r) { inline void freeTemp(Context* con, int r)
{
con->client->releaseTemporary(r); con->client->releaseTemporary(r);
} }
inline int64_t getValue(lir::Constant* con) { inline int64_t getValue(lir::Constant* con)
{
return con->value->value(); return con->value->value();
} }
inline lir::Register makeTemp(Context* con) { inline lir::Register makeTemp(Context* con)
{
lir::Register tmp(newTemp(con)); lir::Register tmp(newTemp(con));
return tmp; return tmp;
} }
inline lir::Register makeTemp64(Context* con) { inline lir::Register makeTemp64(Context* con)
{
lir::Register tmp(newTemp(con), newTemp(con)); lir::Register tmp(newTemp(con), newTemp(con));
return tmp; return tmp;
} }
inline void freeTemp(Context* con, const lir::Register& tmp) { inline void freeTemp(Context* con, const lir::Register& tmp)
if (tmp.low != lir::NoRegister) freeTemp(con, tmp.low); {
if (tmp.high != lir::NoRegister) freeTemp(con, tmp.high); if (tmp.low != lir::NoRegister)
freeTemp(con, tmp.low);
if (tmp.high != lir::NoRegister)
freeTemp(con, tmp.high);
} }
void shiftLeftR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void shiftLeftR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void moveRR(Context* con, unsigned srcSize, lir::Register* src, void moveRR(Context* con,
unsigned dstSize, lir::Register* dst); unsigned srcSize,
lir::Register* src,
unsigned dstSize,
lir::Register* dst);
void shiftLeftC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t); void shiftLeftC(Context* con,
unsigned size UNUSED,
lir::Constant* a,
lir::Register* b,
lir::Register* t);
void shiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void shiftRightR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void shiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t); void shiftRightC(Context* con,
unsigned size UNUSED,
lir::Constant* a,
lir::Register* b,
lir::Register* t);
void unsignedShiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void unsignedShiftRightR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void unsignedShiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t); void unsignedShiftRightC(Context* con,
unsigned size UNUSED,
lir::Constant* a,
lir::Register* b,
lir::Register* t);
bool needJump(MyBlock* b); bool needJump(MyBlock* b);
@ -79,142 +115,297 @@ void resolve(MyBlock* b);
void jumpR(Context* con, unsigned size UNUSED, lir::Register* target); void jumpR(Context* con, unsigned size UNUSED, lir::Register* target);
void swapRR(Context* con, unsigned aSize, lir::Register* a, void swapRR(Context* con,
unsigned bSize, lir::Register* b); unsigned aSize,
lir::Register* a,
unsigned bSize,
lir::Register* b);
void moveRR(Context* con, unsigned srcSize, lir::Register* src, void moveRR(Context* con,
unsigned dstSize, lir::Register* dst); unsigned srcSize,
lir::Register* src,
unsigned dstSize,
lir::Register* dst);
void moveZRR(Context* con, unsigned srcSize, lir::Register* src, void moveZRR(Context* con,
unsigned, lir::Register* dst); unsigned srcSize,
lir::Register* src,
unsigned,
lir::Register* dst);
void moveCR(Context* con, unsigned size, lir::Constant* src, void moveCR(Context* con,
unsigned, lir::Register* dst); unsigned size,
lir::Constant* src,
unsigned,
lir::Register* dst);
void moveCR2(Context* con, unsigned size, lir::Constant* src, void moveCR2(Context* con,
lir::Register* dst, Promise* callOffset); unsigned size,
lir::Constant* src,
lir::Register* dst,
Promise* callOffset);
void moveCR(Context* con, unsigned size, lir::Constant* src, void moveCR(Context* con,
unsigned, lir::Register* dst); unsigned size,
lir::Constant* src,
unsigned,
lir::Register* dst);
void addR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void addR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void subR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void subR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void addC(Context* con, unsigned size, lir::Constant* a, void addC(Context* con,
lir::Register* b, lir::Register* dst); unsigned size,
lir::Constant* a,
lir::Register* b,
lir::Register* dst);
void subC(Context* con, unsigned size, lir::Constant* a, void subC(Context* con,
lir::Register* b, lir::Register* dst); unsigned size,
lir::Constant* a,
lir::Register* b,
lir::Register* dst);
void multiplyR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void multiplyR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void floatAbsoluteRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b); void floatAbsoluteRR(Context* con,
unsigned size,
lir::Register* a,
unsigned,
lir::Register* b);
void floatNegateRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b); void floatNegateRR(Context* con,
unsigned size,
lir::Register* a,
unsigned,
lir::Register* b);
void float2FloatRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b); void float2FloatRR(Context* con,
unsigned size,
lir::Register* a,
unsigned,
lir::Register* b);
void float2IntRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b); void float2IntRR(Context* con,
unsigned size,
lir::Register* a,
unsigned,
lir::Register* b);
void int2FloatRR(Context* con, unsigned, lir::Register* a, unsigned size, lir::Register* b); void int2FloatRR(Context* con,
unsigned,
lir::Register* a,
unsigned size,
lir::Register* b);
void floatSqrtRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b); void floatSqrtRR(Context* con,
unsigned size,
lir::Register* a,
unsigned,
lir::Register* b);
void floatAddR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void floatAddR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void floatSubtractR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void floatSubtractR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void floatMultiplyR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void floatMultiplyR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
void floatDivideR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t); void floatDivideR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* t);
int normalize(Context* con, int offset, int index, unsigned scale, int normalize(Context* con,
bool* preserveIndex, bool* release); int offset,
int index,
unsigned scale,
bool* preserveIndex,
bool* release);
void store(Context* con, unsigned size, lir::Register* src, void store(Context* con,
int base, int offset, int index, unsigned scale, bool preserveIndex); unsigned size,
lir::Register* src,
int base,
int offset,
int index,
unsigned scale,
bool preserveIndex);
void moveRM(Context* con, unsigned srcSize, lir::Register* src, void moveRM(Context* con,
unsigned dstSize UNUSED, lir::Memory* dst); unsigned srcSize,
lir::Register* src,
unsigned dstSize UNUSED,
lir::Memory* dst);
void load(Context* con, unsigned srcSize, int base, int offset, int index, void load(Context* con,
unsigned scale, unsigned dstSize, lir::Register* dst, unsigned srcSize,
bool preserveIndex, bool signExtend); int base,
int offset,
int index,
unsigned scale,
unsigned dstSize,
lir::Register* dst,
bool preserveIndex,
bool signExtend);
void moveMR(Context* con, unsigned srcSize, lir::Memory* src, void moveMR(Context* con,
unsigned dstSize, lir::Register* dst); unsigned srcSize,
lir::Memory* src,
unsigned dstSize,
lir::Register* dst);
void moveZMR(Context* con, unsigned srcSize, lir::Memory* src, void moveZMR(Context* con,
unsigned dstSize, lir::Register* dst); unsigned srcSize,
lir::Memory* src,
unsigned dstSize,
lir::Register* dst);
void andR(Context* con, unsigned size, lir::Register* a, void andR(Context* con,
lir::Register* b, lir::Register* dst); unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* dst);
void andC(Context* con, unsigned size, lir::Constant* a, void andC(Context* con,
lir::Register* b, lir::Register* dst); unsigned size,
lir::Constant* a,
lir::Register* b,
lir::Register* dst);
void orR(Context* con, unsigned size, lir::Register* a, void orR(Context* con,
lir::Register* b, lir::Register* dst); unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* dst);
void xorR(Context* con, unsigned size, lir::Register* a, void xorR(Context* con,
lir::Register* b, lir::Register* dst); unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* dst);
void moveAR2(Context* con, unsigned srcSize, lir::Address* src, void moveAR2(Context* con,
unsigned dstSize, lir::Register* dst); unsigned srcSize,
lir::Address* src,
unsigned dstSize,
lir::Register* dst);
void moveAR(Context* con, unsigned srcSize, lir::Address* src, void moveAR(Context* con,
unsigned dstSize, lir::Register* dst); unsigned srcSize,
lir::Address* src,
unsigned dstSize,
lir::Register* dst);
void compareRR(Context* con, unsigned aSize, lir::Register* a, void compareRR(Context* con,
unsigned bSize UNUSED, lir::Register* b); unsigned aSize,
lir::Register* a,
unsigned bSize UNUSED,
lir::Register* b);
void compareCR(Context* con, unsigned aSize, lir::Constant* a, void compareCR(Context* con,
unsigned bSize, lir::Register* b); unsigned aSize,
lir::Constant* a,
unsigned bSize,
lir::Register* b);
void compareCM(Context* con, unsigned aSize, lir::Constant* a, void compareCM(Context* con,
unsigned bSize, lir::Memory* b); unsigned aSize,
lir::Constant* a,
unsigned bSize,
lir::Memory* b);
void compareRM(Context* con, unsigned aSize, lir::Register* a, void compareRM(Context* con,
unsigned bSize, lir::Memory* b); unsigned aSize,
lir::Register* a,
unsigned bSize,
lir::Memory* b);
int32_t int32_t branch(Context* con, lir::TernaryOperation op);
branch(Context* con, lir::TernaryOperation op);
void conditional(Context* con, int32_t branch, lir::Constant* target); void conditional(Context* con, int32_t branch, lir::Constant* target);
void branch(Context* con, lir::TernaryOperation op, lir::Constant* target); void branch(Context* con, lir::TernaryOperation op, lir::Constant* target);
void branchLong(Context* con, lir::TernaryOperation op, lir::Operand* al, void branchLong(Context* con,
lir::Operand* ah, lir::Operand* bl, lir::TernaryOperation op,
lir::Operand* bh, lir::Constant* target, lir::Operand* al,
lir::Operand* ah,
lir::Operand* bl,
lir::Operand* bh,
lir::Constant* target,
BinaryOperationType compareSigned, BinaryOperationType compareSigned,
BinaryOperationType compareUnsigned); BinaryOperationType compareUnsigned);
void branchRR(Context* con, lir::TernaryOperation op, unsigned size, void branchRR(Context* con,
lir::Register* a, lir::Register* b, lir::TernaryOperation op,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Constant* target); lir::Constant* target);
void branchCR(Context* con, lir::TernaryOperation op, unsigned size, void branchCR(Context* con,
lir::Constant* a, lir::Register* b, lir::TernaryOperation op,
unsigned size,
lir::Constant* a,
lir::Register* b,
lir::Constant* target); lir::Constant* target);
void branchRM(Context* con, lir::TernaryOperation op, unsigned size, void branchRM(Context* con,
lir::Register* a, lir::Memory* b, lir::TernaryOperation op,
unsigned size,
lir::Register* a,
lir::Memory* b,
lir::Constant* target); lir::Constant* target);
void branchCM(Context* con, lir::TernaryOperation op, unsigned size, void branchCM(Context* con,
lir::Constant* a, lir::Memory* b, lir::TernaryOperation op,
unsigned size,
lir::Constant* a,
lir::Memory* b,
lir::Constant* target); lir::Constant* target);
ShiftMaskPromise* ShiftMaskPromise* shiftMaskPromise(Context* con,
shiftMaskPromise(Context* con, Promise* base, unsigned shift, int64_t mask); Promise* base,
unsigned shift,
int64_t mask);
void moveCM(Context* con, unsigned srcSize, lir::Constant* src, void moveCM(Context* con,
unsigned dstSize, lir::Memory* dst); unsigned srcSize,
lir::Constant* src,
unsigned dstSize,
lir::Memory* dst);
void negateRR(Context* con, unsigned srcSize, lir::Register* src, void negateRR(Context* con,
unsigned dstSize UNUSED, lir::Register* dst); unsigned srcSize,
lir::Register* src,
unsigned dstSize UNUSED,
lir::Register* dst);
void callR(Context* con, unsigned size UNUSED, lir::Register* target); void callR(Context* con, unsigned size UNUSED, lir::Register* target);
@ -241,4 +432,3 @@ void storeLoadBarrier(Context*);
} // namespace avian } // namespace avian
#endif // AVIAN_CODEGEN_ASSEMBLER_ARM_OPERATIONS_H #endif // AVIAN_CODEGEN_ASSEMBLER_ARM_OPERATIONS_H

View File

@ -18,7 +18,6 @@ namespace avian {
namespace codegen { namespace codegen {
namespace arm { namespace arm {
const uint64_t MASK_LO32 = 0xffffffff; const uint64_t MASK_LO32 = 0xffffffff;
const unsigned MASK_LO16 = 0xffff; const unsigned MASK_LO16 = 0xffff;
const unsigned MASK_LO8 = 0xff; const unsigned MASK_LO8 = 0xff;
@ -31,14 +30,27 @@ const uint32_t FPR_MASK = 0xffff0000;
const uint64_t GPR_MASK64 = GPR_MASK | (uint64_t)GPR_MASK << 32; const uint64_t GPR_MASK64 = GPR_MASK | (uint64_t)GPR_MASK << 32;
const uint64_t FPR_MASK64 = FPR_MASK | (uint64_t)FPR_MASK << 32; const uint64_t FPR_MASK64 = FPR_MASK | (uint64_t)FPR_MASK << 32;
inline bool isFpr(lir::Register* reg) { inline bool isFpr(lir::Register* reg)
{
return reg->low >= N_GPRS; return reg->low >= N_GPRS;
} }
inline int fpr64(int reg) { return reg - N_GPRS; } inline int fpr64(int reg)
inline int fpr64(lir::Register* reg) { return fpr64(reg->low); } {
inline int fpr32(int reg) { return fpr64(reg) << 1; } return reg - N_GPRS;
inline int fpr32(lir::Register* reg) { return fpr64(reg) << 1; } }
inline int fpr64(lir::Register* reg)
{
return fpr64(reg->low);
}
inline int fpr32(int reg)
{
return fpr64(reg) << 1;
}
inline int fpr32(lir::Register* reg)
{
return fpr64(reg) << 1;
}
const int ThreadRegister = 8; const int ThreadRegister = 8;
const int StackRegister = 13; const int StackRegister = 13;

View File

@ -11,13 +11,14 @@
#ifndef AVIAN_CODEGEN_TARGET_MULTIMETHOD_H #ifndef AVIAN_CODEGEN_TARGET_MULTIMETHOD_H
#define AVIAN_CODEGEN_TARGET_MULTIMETHOD_H #define AVIAN_CODEGEN_TARGET_MULTIMETHOD_H
namespace avian { namespace avian {
namespace codegen { namespace codegen {
class Multimethod { class Multimethod {
public: public:
inline static unsigned index(lir::UnaryOperation operation, lir::OperandType operand) { inline static unsigned index(lir::UnaryOperation operation,
lir::OperandType operand)
{
return operation + (lir::UnaryOperationCount * operand); return operation + (lir::UnaryOperationCount * operand);
} }
}; };
@ -26,4 +27,3 @@ public:
} // namespace avian } // namespace avian
#endif // AVIAN_CODEGEN_TARGET_MULTIMETHOD_H #endif // AVIAN_CODEGEN_TARGET_MULTIMETHOD_H

View File

@ -54,25 +54,30 @@ namespace x86 {
const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1); const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1);
const unsigned StackAlignmentInBytes = 16; const unsigned StackAlignmentInBytes = 16;
const unsigned StackAlignmentInWords = StackAlignmentInBytes / TargetBytesPerWord; const unsigned StackAlignmentInWords = StackAlignmentInBytes
/ TargetBytesPerWord;
unsigned unsigned argumentFootprint(unsigned footprint)
argumentFootprint(unsigned footprint)
{ {
return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords); return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords);
} }
uint32_t uint32_t read4(uint8_t* p)
read4(uint8_t* p)
{ {
uint32_t v; memcpy(&v, p, 4); uint32_t v;
memcpy(&v, p, 4);
return v; return v;
} }
void void nextFrame(ArchitectureContext* c UNUSED,
nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, uint8_t* start,
unsigned footprint, void*, bool mostRecent, unsigned size UNUSED,
int targetParameterFootprint, void** ip, void** stack) unsigned footprint,
void*,
bool mostRecent,
int targetParameterFootprint,
void** ip,
void** stack)
{ {
assertT(c, *ip >= start); assertT(c, *ip >= start);
assertT(c, *ip <= start + size); assertT(c, *ip <= start + size);
@ -124,16 +129,14 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
// $offset,%rsp": // $offset,%rsp":
if (TargetBytesPerWord == 4) { if (TargetBytesPerWord == 4) {
if ((*instruction == 0x83 or *instruction == 0x81) if ((*instruction == 0x83 or *instruction == 0x81)
and instruction[1] == 0xec) and instruction[1] == 0xec) {
{
offset offset
-= (*instruction == 0x83 ? instruction[2] : read4(instruction + 2)) -= (*instruction == 0x83 ? instruction[2] : read4(instruction + 2))
/ TargetBytesPerWord; / TargetBytesPerWord;
} }
} else if (*instruction == 0x48 } else if (*instruction == 0x48
and (instruction[1] == 0x83 or instruction[1] == 0x81) and (instruction[1] == 0x83 or instruction[1] == 0x81)
and instruction[2] == 0xec) and instruction[2] == 0xec) {
{
offset offset
-= (instruction[1] == 0x83 ? instruction[3] : read4(instruction + 3)) -= (instruction[1] == 0x83 ? instruction[3] : read4(instruction + 3))
/ TargetBytesPerWord; / TargetBytesPerWord;
@ -156,17 +159,18 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
*stack = static_cast<void**>(*stack) + offset; *stack = static_cast<void**>(*stack) + offset;
} }
class MyArchitecture: public Architecture { class MyArchitecture : public Architecture {
public: public:
MyArchitecture(System* system, bool useNativeFeatures): MyArchitecture(System* system, bool useNativeFeatures)
c(system, useNativeFeatures), : c(system, useNativeFeatures),
referenceCount(0), referenceCount(0),
myRegisterFile(GeneralRegisterMask, useSSE(&c) ? FloatRegisterMask : 0) myRegisterFile(GeneralRegisterMask, useSSE(&c) ? FloatRegisterMask : 0)
{ {
populateTables(&c); populateTables(&c);
} }
virtual unsigned floatRegisterSize() { virtual unsigned floatRegisterSize()
{
if (useSSE(&c)) { if (useSSE(&c)) {
return 8; return 8;
} else { } else {
@ -174,35 +178,43 @@ class MyArchitecture: public Architecture {
} }
} }
virtual const RegisterFile* registerFile() { virtual const RegisterFile* registerFile()
{
return &myRegisterFile; return &myRegisterFile;
} }
virtual int scratch() { virtual int scratch()
{
return rax; return rax;
} }
virtual int stack() { virtual int stack()
{
return rsp; return rsp;
} }
virtual int thread() { virtual int thread()
{
return rbx; return rbx;
} }
virtual int returnLow() { virtual int returnLow()
{
return rax; return rax;
} }
virtual int returnHigh() { virtual int returnHigh()
{
return (TargetBytesPerWord == 4 ? rdx : lir::NoRegister); return (TargetBytesPerWord == 4 ? rdx : lir::NoRegister);
} }
virtual int virtualCallTarget() { virtual int virtualCallTarget()
{
return rax; return rax;
} }
virtual int virtualCallIndex() { virtual int virtualCallIndex()
{
return rdx; return rdx;
} }
@ -211,15 +223,18 @@ class MyArchitecture: public Architecture {
return ir::TargetInfo(TargetBytesPerWord); return ir::TargetInfo(TargetBytesPerWord);
} }
virtual bool bigEndian() { virtual bool bigEndian()
{
return false; return false;
} }
virtual uintptr_t maximumImmediateJump() { virtual uintptr_t maximumImmediateJump()
{
return 0x7FFFFFFF; return 0x7FFFFFFF;
} }
virtual bool reserved(int register_) { virtual bool reserved(int register_)
{
switch (register_) { switch (register_) {
case rbp: case rbp:
return UseFramePointer; return UseFramePointer;
@ -233,38 +248,49 @@ class MyArchitecture: public Architecture {
} }
} }
virtual unsigned frameFootprint(unsigned footprint) { virtual unsigned frameFootprint(unsigned footprint)
{
#if AVIAN_TARGET_FORMAT == AVIAN_FORMAT_PE #if AVIAN_TARGET_FORMAT == AVIAN_FORMAT_PE
return max(footprint, StackAlignmentInWords); return max(footprint, StackAlignmentInWords);
#else #else
return max(footprint > argumentRegisterCount() ? return max(footprint > argumentRegisterCount()
footprint - argumentRegisterCount() : 0, ? footprint - argumentRegisterCount()
: 0,
StackAlignmentInWords); StackAlignmentInWords);
#endif #endif
} }
virtual unsigned argumentFootprint(unsigned footprint) { virtual unsigned argumentFootprint(unsigned footprint)
{
return x86::argumentFootprint(footprint); return x86::argumentFootprint(footprint);
} }
virtual bool argumentAlignment() { virtual bool argumentAlignment()
{
return false; return false;
} }
virtual bool argumentRegisterAlignment() { virtual bool argumentRegisterAlignment()
{
return false; return false;
} }
virtual unsigned argumentRegisterCount() { virtual unsigned argumentRegisterCount()
{
#if AVIAN_TARGET_FORMAT == AVIAN_FORMAT_PE #if AVIAN_TARGET_FORMAT == AVIAN_FORMAT_PE
if (TargetBytesPerWord == 8) return 4; else if (TargetBytesPerWord == 8)
return 4;
else
#else #else
if (TargetBytesPerWord == 8) return 6; else if (TargetBytesPerWord == 8)
return 6;
else
#endif #endif
return 0; return 0;
} }
virtual int argumentRegister(unsigned index) { virtual int argumentRegister(unsigned index)
{
assertT(&c, TargetBytesPerWord == 8); assertT(&c, TargetBytesPerWord == 8);
switch (index) { switch (index) {
#if AVIAN_TARGET_FORMAT == AVIAN_FORMAT_PE #if AVIAN_TARGET_FORMAT == AVIAN_FORMAT_PE
@ -295,23 +321,28 @@ class MyArchitecture: public Architecture {
} }
} }
virtual bool hasLinkRegister() { virtual bool hasLinkRegister()
{
return false; return false;
} }
virtual unsigned stackAlignmentInWords() { virtual unsigned stackAlignmentInWords()
{
return StackAlignmentInWords; return StackAlignmentInWords;
} }
virtual bool matchCall(void* returnAddress, void* target) { virtual bool matchCall(void* returnAddress, void* target)
{
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5; uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
int32_t actualOffset; memcpy(&actualOffset, instruction + 1, 4); int32_t actualOffset;
memcpy(&actualOffset, instruction + 1, 4);
void* actualTarget = static_cast<uint8_t*>(returnAddress) + actualOffset; void* actualTarget = static_cast<uint8_t*>(returnAddress) + actualOffset;
return *instruction == 0xE8 and actualTarget == target; return *instruction == 0xE8 and actualTarget == target;
} }
virtual void updateCall(lir::UnaryOperation op, void* returnAddress, virtual void updateCall(lir::UnaryOperation op,
void* returnAddress,
void* newTarget) void* newTarget)
{ {
bool assertTAlignment UNUSED; bool assertTAlignment UNUSED;
@ -378,43 +409,61 @@ class MyArchitecture: public Architecture {
} }
} }
virtual void setConstant(void* dst, uint64_t constant) { virtual void setConstant(void* dst, uint64_t constant)
{
target_uintptr_t v = targetVW(constant); target_uintptr_t v = targetVW(constant);
memcpy(dst, &v, TargetBytesPerWord); memcpy(dst, &v, TargetBytesPerWord);
} }
virtual unsigned alignFrameSize(unsigned sizeInWords) { virtual unsigned alignFrameSize(unsigned sizeInWords)
{
return pad(sizeInWords + FrameHeaderSize, StackAlignmentInWords) return pad(sizeInWords + FrameHeaderSize, StackAlignmentInWords)
- FrameHeaderSize; - FrameHeaderSize;
} }
virtual void nextFrame(void* start, unsigned size, unsigned footprint, virtual void nextFrame(void* start,
void* link, bool mostRecent, unsigned size,
int targetParameterFootprint, void** ip, unsigned footprint,
void* link,
bool mostRecent,
int targetParameterFootprint,
void** ip,
void** stack) void** stack)
{ {
x86::nextFrame(&c, static_cast<uint8_t*>(start), size, footprint, x86::nextFrame(&c,
link, mostRecent, targetParameterFootprint, ip, stack); static_cast<uint8_t*>(start),
size,
footprint,
link,
mostRecent,
targetParameterFootprint,
ip,
stack);
} }
virtual void* frameIp(void* stack) { virtual void* frameIp(void* stack)
{
return stack ? *static_cast<void**>(stack) : 0; return stack ? *static_cast<void**>(stack) : 0;
} }
virtual unsigned frameHeaderSize() { virtual unsigned frameHeaderSize()
{
return FrameHeaderSize; return FrameHeaderSize;
} }
virtual unsigned frameReturnAddressSize() { virtual unsigned frameReturnAddressSize()
{
return 1; return 1;
} }
virtual unsigned frameFooterSize() { virtual unsigned frameFooterSize()
{
return 0; return 0;
} }
virtual bool alwaysCondensed(lir::BinaryOperation op) { virtual bool alwaysCondensed(lir::BinaryOperation op)
switch(op) { {
switch (op) {
case lir::Float2Float: case lir::Float2Float:
case lir::Float2Int: case lir::Float2Int:
case lir::Int2Float: case lir::Int2Float:
@ -432,34 +481,39 @@ class MyArchitecture: public Architecture {
} }
} }
virtual bool alwaysCondensed(lir::TernaryOperation) { virtual bool alwaysCondensed(lir::TernaryOperation)
{
return true; return true;
} }
virtual int returnAddressOffset() { virtual int returnAddressOffset()
{
return 0; return 0;
} }
virtual int framePointerOffset() { virtual int framePointerOffset()
{
return UseFramePointer ? -1 : 0; return UseFramePointer ? -1 : 0;
} }
virtual void plan virtual void plan(lir::UnaryOperation,
(lir::UnaryOperation, unsigned,
unsigned, OperandMask& aMask, OperandMask& aMask,
bool* thunk) bool* thunk)
{ {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand) | (1 << lir::ConstantOperand); aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand)
| (1 << lir::ConstantOperand);
*thunk = false; *thunk = false;
} }
virtual void planSource virtual void planSource(lir::BinaryOperation op,
(lir::BinaryOperation op, unsigned aSize,
unsigned aSize, OperandMask& aMask, OperandMask& aMask,
unsigned bSize, bool* thunk) unsigned bSize,
bool* thunk)
{ {
aMask.registerMask = GeneralRegisterMask | aMask.registerMask = GeneralRegisterMask
(static_cast<uint64_t>(GeneralRegisterMask) << 32); | (static_cast<uint64_t>(GeneralRegisterMask) << 32);
*thunk = false; *thunk = false;
@ -501,7 +555,8 @@ class MyArchitecture: public Architecture {
case lir::FloatSquareRoot: case lir::FloatSquareRoot:
if (useSSE(&c)) { if (useSSE(&c)) {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); aMask.typeMask = (1 << lir::RegisterOperand)
| (1 << lir::MemoryOperand);
aMask.registerMask = (static_cast<uint64_t>(FloatRegisterMask) << 32) aMask.registerMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
| FloatRegisterMask; | FloatRegisterMask;
} else { } else {
@ -511,7 +566,8 @@ class MyArchitecture: public Architecture {
case lir::Float2Float: case lir::Float2Float:
if (useSSE(&c)) { if (useSSE(&c)) {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); aMask.typeMask = (1 << lir::RegisterOperand)
| (1 << lir::MemoryOperand);
aMask.registerMask = (static_cast<uint64_t>(FloatRegisterMask) << 32) aMask.registerMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
| FloatRegisterMask; | FloatRegisterMask;
} else { } else {
@ -525,7 +581,8 @@ class MyArchitecture: public Architecture {
// thunks or produce inline machine code which handles edge // thunks or produce inline machine code which handles edge
// cases properly. // cases properly.
if (false and useSSE(&c) and bSize <= TargetBytesPerWord) { if (false and useSSE(&c) and bSize <= TargetBytesPerWord) {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); aMask.typeMask = (1 << lir::RegisterOperand)
| (1 << lir::MemoryOperand);
aMask.registerMask = (static_cast<uint64_t>(FloatRegisterMask) << 32) aMask.registerMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
| FloatRegisterMask; | FloatRegisterMask;
} else { } else {
@ -535,8 +592,10 @@ class MyArchitecture: public Architecture {
case lir::Int2Float: case lir::Int2Float:
if (useSSE(&c) and aSize <= TargetBytesPerWord) { if (useSSE(&c) and aSize <= TargetBytesPerWord) {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); aMask.typeMask = (1 << lir::RegisterOperand)
aMask.registerMask = GeneralRegisterMask | (1 << lir::MemoryOperand);
aMask.registerMask
= GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32); | (static_cast<uint64_t>(GeneralRegisterMask) << 32);
} else { } else {
*thunk = true; *thunk = true;
@ -549,14 +608,16 @@ class MyArchitecture: public Architecture {
if (TargetBytesPerWord == 4) { if (TargetBytesPerWord == 4) {
if (aSize == 4 and bSize == 8) { if (aSize == 4 and bSize == 8) {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); aMask.typeMask = (1 << lir::RegisterOperand)
const uint32_t mask | (1 << lir::MemoryOperand);
= GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); const uint32_t mask = GeneralRegisterMask
& ~((1 << rax) | (1 << rdx));
aMask.registerMask = (static_cast<uint64_t>(mask) << 32) | mask; aMask.registerMask = (static_cast<uint64_t>(mask) << 32) | mask;
} else if (aSize == 1 or bSize == 1) { } else if (aSize == 1 or bSize == 1) {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); aMask.typeMask = (1 << lir::RegisterOperand)
const uint32_t mask | (1 << lir::MemoryOperand);
= (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx)
| (1 << rbx);
aMask.registerMask = (static_cast<uint64_t>(mask) << 32) | mask; aMask.registerMask = (static_cast<uint64_t>(mask) << 32) | mask;
} }
} }
@ -567,10 +628,11 @@ class MyArchitecture: public Architecture {
} }
} }
virtual void planDestination virtual void planDestination(lir::BinaryOperation op,
(lir::BinaryOperation op, unsigned aSize,
unsigned aSize, const OperandMask& aMask, const OperandMask& aMask,
unsigned bSize, OperandMask& bMask) unsigned bSize,
OperandMask& bMask)
{ {
bMask.typeMask = ~0; bMask.typeMask = ~0;
bMask.registerMask = GeneralRegisterMask bMask.registerMask = GeneralRegisterMask
@ -606,21 +668,25 @@ class MyArchitecture: public Architecture {
break; break;
case lir::Move: case lir::Move:
if (aMask.typeMask & ((1 << lir::MemoryOperand) | 1 << lir::AddressOperand)) { if (aMask.typeMask
& ((1 << lir::MemoryOperand) | 1 << lir::AddressOperand)) {
bMask.typeMask = (1 << lir::RegisterOperand); bMask.typeMask = (1 << lir::RegisterOperand);
bMask.registerMask = GeneralRegisterMask bMask.registerMask = GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32) | (static_cast<uint64_t>(GeneralRegisterMask)
| FloatRegisterMask; << 32) | FloatRegisterMask;
} else if (aMask.typeMask & (1 << lir::RegisterOperand)) { } else if (aMask.typeMask & (1 << lir::RegisterOperand)) {
bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); bMask.typeMask = (1 << lir::RegisterOperand)
| (1 << lir::MemoryOperand);
if (aMask.registerMask & FloatRegisterMask) { if (aMask.registerMask & FloatRegisterMask) {
bMask.registerMask = FloatRegisterMask; bMask.registerMask = FloatRegisterMask;
} else { } else {
bMask.registerMask = GeneralRegisterMask bMask.registerMask
= GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32); | (static_cast<uint64_t>(GeneralRegisterMask) << 32);
} }
} else { } else {
bMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); bMask.typeMask = (1 << lir::RegisterOperand)
| (1 << lir::MemoryOperand);
} }
if (TargetBytesPerWord == 4) { if (TargetBytesPerWord == 4) {
@ -628,8 +694,8 @@ class MyArchitecture: public Architecture {
bMask.registerMask = (static_cast<uint64_t>(1) << (rdx + 32)) bMask.registerMask = (static_cast<uint64_t>(1) << (rdx + 32))
| (static_cast<uint64_t>(1) << rax); | (static_cast<uint64_t>(1) << rax);
} else if (aSize == 1 or bSize == 1) { } else if (aSize == 1 or bSize == 1) {
const uint32_t mask const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx)
= (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); | (1 << rbx);
bMask.registerMask = (static_cast<uint64_t>(mask) << 32) | mask; bMask.registerMask = (static_cast<uint64_t>(mask) << 32) | mask;
} }
} }
@ -640,8 +706,8 @@ class MyArchitecture: public Architecture {
} }
} }
virtual void planMove virtual void planMove(unsigned size,
(unsigned size, OperandMask& srcMask, OperandMask& srcMask,
OperandMask& tmpMask, OperandMask& tmpMask,
const OperandMask& dstMask) const OperandMask& dstMask)
{ {
@ -653,20 +719,24 @@ class MyArchitecture: public Architecture {
if (dstMask.typeMask & (1 << lir::MemoryOperand)) { if (dstMask.typeMask & (1 << lir::MemoryOperand)) {
// can't move directly from memory to memory // can't move directly from memory to memory
srcMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); srcMask.typeMask = (1 << lir::RegisterOperand)
| (1 << lir::ConstantOperand);
tmpMask.typeMask = 1 << lir::RegisterOperand; tmpMask.typeMask = 1 << lir::RegisterOperand;
tmpMask.registerMask = GeneralRegisterMask tmpMask.registerMask
= GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32); | (static_cast<uint64_t>(GeneralRegisterMask) << 32);
} else if (dstMask.typeMask & (1 << lir::RegisterOperand)) { } else if (dstMask.typeMask & (1 << lir::RegisterOperand)) {
if (size > TargetBytesPerWord) { if (size > TargetBytesPerWord) {
// can't move directly from FPR to GPR or vice-versa for // can't move directly from FPR to GPR or vice-versa for
// values larger than the GPR size // values larger than the GPR size
if (dstMask.registerMask & FloatRegisterMask) { if (dstMask.registerMask & FloatRegisterMask) {
srcMask.registerMask = FloatRegisterMask srcMask.registerMask
= FloatRegisterMask
| (static_cast<uint64_t>(FloatRegisterMask) << 32); | (static_cast<uint64_t>(FloatRegisterMask) << 32);
tmpMask.typeMask = 1 << lir::MemoryOperand; tmpMask.typeMask = 1 << lir::MemoryOperand;
} else if (dstMask.registerMask & GeneralRegisterMask) { } else if (dstMask.registerMask & GeneralRegisterMask) {
srcMask.registerMask = GeneralRegisterMask srcMask.registerMask
= GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32); | (static_cast<uint64_t>(GeneralRegisterMask) << 32);
tmpMask.typeMask = 1 << lir::MemoryOperand; tmpMask.typeMask = 1 << lir::MemoryOperand;
} }
@ -677,19 +747,23 @@ class MyArchitecture: public Architecture {
if (size > TargetBytesPerWord) { if (size > TargetBytesPerWord) {
tmpMask.typeMask = 1 << lir::MemoryOperand; tmpMask.typeMask = 1 << lir::MemoryOperand;
} else { } else {
tmpMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); tmpMask.typeMask = (1 << lir::RegisterOperand)
tmpMask.registerMask = GeneralRegisterMask | (1 << lir::MemoryOperand);
tmpMask.registerMask
= GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32); | (static_cast<uint64_t>(GeneralRegisterMask) << 32);
} }
} }
} }
} }
virtual void planSource virtual void planSource(lir::TernaryOperation op,
(lir::TernaryOperation op, unsigned aSize,
unsigned aSize, OperandMask& aMask, OperandMask& aMask,
unsigned bSize, OperandMask& bMask, unsigned bSize,
unsigned, bool* thunk) OperandMask& bMask,
unsigned,
bool* thunk)
{ {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand);
aMask.registerMask = GeneralRegisterMask aMask.registerMask = GeneralRegisterMask
@ -707,11 +781,11 @@ class MyArchitecture: public Architecture {
case lir::FloatMultiply: case lir::FloatMultiply:
case lir::FloatDivide: case lir::FloatDivide:
if (useSSE(&c)) { if (useSSE(&c)) {
aMask.typeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); aMask.typeMask = (1 << lir::RegisterOperand)
| (1 << lir::MemoryOperand);
bMask.typeMask = (1 << lir::RegisterOperand); bMask.typeMask = (1 << lir::RegisterOperand);
const uint64_t mask const uint64_t mask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
= (static_cast<uint64_t>(FloatRegisterMask) << 32)
| FloatRegisterMask; | FloatRegisterMask;
aMask.registerMask = mask; aMask.registerMask = mask;
bMask.registerMask = mask; bMask.registerMask = mask;
@ -796,11 +870,13 @@ class MyArchitecture: public Architecture {
} }
} }
virtual void planDestination virtual void planDestination(lir::TernaryOperation op,
(lir::TernaryOperation op, unsigned,
unsigned, const OperandMask&, const OperandMask&,
unsigned, const OperandMask& bMask, unsigned,
unsigned, OperandMask& cMask) const OperandMask& bMask,
unsigned,
OperandMask& cMask)
{ {
if (isBranch(op)) { if (isBranch(op)) {
cMask.typeMask = (1 << lir::ConstantOperand); cMask.typeMask = (1 << lir::ConstantOperand);
@ -813,12 +889,14 @@ class MyArchitecture: public Architecture {
virtual Assembler* makeAssembler(util::Allocator* allocator, Zone* zone); virtual Assembler* makeAssembler(util::Allocator* allocator, Zone* zone);
virtual void acquire() { virtual void acquire()
++ referenceCount; {
++referenceCount;
} }
virtual void release() { virtual void release()
if (-- referenceCount == 0) { {
if (--referenceCount == 0) {
c.s->free(this); c.s->free(this);
} }
} }
@ -828,18 +906,21 @@ class MyArchitecture: public Architecture {
const RegisterFile myRegisterFile; const RegisterFile myRegisterFile;
}; };
class MyAssembler: public Assembler { class MyAssembler : public Assembler {
public: public:
MyAssembler(System* s, util::Allocator* a, Zone* zone, MyArchitecture* arch) MyAssembler(System* s, util::Allocator* a, Zone* zone, MyArchitecture* arch)
: c(s, a, zone, &(arch->c)), arch_(arch) : c(s, a, zone, &(arch->c)), arch_(arch)
{ } {
}
virtual void setClient(Client* client) { virtual void setClient(Client* client)
{
assertT(&c, c.client == 0); assertT(&c, c.client == 0);
c.client = client; c.client = client;
} }
virtual Architecture* arch() { virtual Architecture* arch()
{
return arch_; return arch_;
} }
@ -849,11 +930,16 @@ class MyAssembler: public Assembler {
lir::Register stack(rsp); lir::Register stack(rsp);
lir::Memory stackLimit(rbx, stackLimitOffsetFromThread); lir::Memory stackLimit(rbx, stackLimitOffsetFromThread);
lir::Constant handlerConstant(resolvedPromise(&c, handler)); lir::Constant handlerConstant(resolvedPromise(&c, handler));
branchRM(&c, lir::JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, branchRM(&c,
lir::JumpIfGreaterOrEqual,
TargetBytesPerWord,
&stack,
&stackLimit,
&handlerConstant); &handlerConstant);
} }
virtual void saveFrame(unsigned stackOffset, unsigned) { virtual void saveFrame(unsigned stackOffset, unsigned)
{
lir::Register stack(rsp); lir::Register stack(rsp);
lir::Memory stackDst(rbx, stackOffset); lir::Memory stackDst(rbx, stackOffset);
apply(lir::Move, apply(lir::Move,
@ -861,7 +947,8 @@ class MyAssembler: public Assembler {
OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &stackDst)); OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &stackDst));
} }
virtual void pushFrame(unsigned argumentCount, ...) { virtual void pushFrame(unsigned argumentCount, ...)
{
// TODO: Argument should be replaced by OperandInfo... // TODO: Argument should be replaced by OperandInfo...
struct Argument { struct Argument {
unsigned size; unsigned size;
@ -869,15 +956,16 @@ class MyAssembler: public Assembler {
lir::Operand* operand; lir::Operand* operand;
}; };
RUNTIME_ARRAY(Argument, arguments, argumentCount); RUNTIME_ARRAY(Argument, arguments, argumentCount);
va_list a; va_start(a, argumentCount); va_list a;
va_start(a, argumentCount);
unsigned footprint = 0; unsigned footprint = 0;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned); RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned);
RUNTIME_ARRAY_BODY(arguments)[i].type RUNTIME_ARRAY_BODY(arguments)[i].type
= static_cast<lir::OperandType>(va_arg(a, int)); = static_cast<lir::OperandType>(va_arg(a, int));
RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, lir::Operand*); RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, lir::Operand*);
footprint += ceilingDivide footprint += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size,
(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); TargetBytesPerWord);
} }
va_end(a); va_end(a);
@ -888,32 +976,31 @@ class MyAssembler: public Assembler {
if (i < arch_->argumentRegisterCount()) { if (i < arch_->argumentRegisterCount()) {
lir::Register dst(arch_->argumentRegister(i)); lir::Register dst(arch_->argumentRegister(i));
apply(lir::Move, apply(lir::Move,
OperandInfo( OperandInfo(RUNTIME_ARRAY_BODY(arguments)[i].size,
RUNTIME_ARRAY_BODY(arguments)[i].size,
RUNTIME_ARRAY_BODY(arguments)[i].type, RUNTIME_ARRAY_BODY(arguments)[i].type,
RUNTIME_ARRAY_BODY(arguments)[i].operand), RUNTIME_ARRAY_BODY(arguments)[i].operand),
OperandInfo( OperandInfo(pad(RUNTIME_ARRAY_BODY(arguments)[i].size,
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), TargetBytesPerWord),
lir::RegisterOperand, lir::RegisterOperand,
&dst)); &dst));
} else { } else {
lir::Memory dst(rsp, offset * TargetBytesPerWord); lir::Memory dst(rsp, offset * TargetBytesPerWord);
apply(lir::Move, apply(lir::Move,
OperandInfo( OperandInfo(RUNTIME_ARRAY_BODY(arguments)[i].size,
RUNTIME_ARRAY_BODY(arguments)[i].size,
RUNTIME_ARRAY_BODY(arguments)[i].type, RUNTIME_ARRAY_BODY(arguments)[i].type,
RUNTIME_ARRAY_BODY(arguments)[i].operand), RUNTIME_ARRAY_BODY(arguments)[i].operand),
OperandInfo( OperandInfo(pad(RUNTIME_ARRAY_BODY(arguments)[i].size,
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), TargetBytesPerWord),
lir::MemoryOperand, lir::MemoryOperand,
&dst)); &dst));
offset += ceilingDivide offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size,
(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); TargetBytesPerWord);
} }
} }
} }
virtual void allocateFrame(unsigned footprint) { virtual void allocateFrame(unsigned footprint)
{
lir::Register stack(rsp); lir::Register stack(rsp);
if (UseFramePointer) { if (UseFramePointer) {
@ -925,23 +1012,29 @@ class MyAssembler: public Assembler {
OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &base)); OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &base));
} }
lir::Constant footprintConstant(resolvedPromise(&c, footprint * TargetBytesPerWord)); lir::Constant footprintConstant(
resolvedPromise(&c, footprint * TargetBytesPerWord));
apply(lir::Subtract, apply(lir::Subtract,
OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &footprintConstant), OperandInfo(
TargetBytesPerWord, lir::ConstantOperand, &footprintConstant),
OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack),
OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack));
} }
virtual void adjustFrame(unsigned difference) { virtual void adjustFrame(unsigned difference)
{
lir::Register stack(rsp); lir::Register stack(rsp);
lir::Constant differenceConstant(resolvedPromise(&c, difference * TargetBytesPerWord)); lir::Constant differenceConstant(
resolvedPromise(&c, difference * TargetBytesPerWord));
apply(lir::Subtract, apply(lir::Subtract,
OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &differenceConstant), OperandInfo(
TargetBytesPerWord, lir::ConstantOperand, &differenceConstant),
OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack),
OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack));
} }
virtual void popFrame(unsigned frameFootprint) { virtual void popFrame(unsigned frameFootprint)
{
if (UseFramePointer) { if (UseFramePointer) {
lir::Register base(rbp); lir::Register base(rbp);
lir::Register stack(rsp); lir::Register stack(rsp);
@ -952,7 +1045,8 @@ class MyAssembler: public Assembler {
popR(&c, TargetBytesPerWord, &base); popR(&c, TargetBytesPerWord, &base);
} else { } else {
lir::Register stack(rsp); lir::Register stack(rsp);
lir::Constant footprint(resolvedPromise(&c, frameFootprint * TargetBytesPerWord)); lir::Constant footprint(
resolvedPromise(&c, frameFootprint * TargetBytesPerWord));
apply(lir::Add, apply(lir::Add,
OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &footprint), OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &footprint),
OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack),
@ -971,14 +1065,20 @@ class MyAssembler: public Assembler {
unsigned baseSize = UseFramePointer ? 1 : 0; unsigned baseSize = UseFramePointer ? 1 : 0;
lir::Memory returnAddressSrc lir::Memory returnAddressSrc(
(rsp, (frameFootprint + baseSize) * TargetBytesPerWord); rsp, (frameFootprint + baseSize) * TargetBytesPerWord);
moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, moveMR(&c,
TargetBytesPerWord,
&returnAddressSrc,
TargetBytesPerWord,
&tmp); &tmp);
lir::Memory returnAddressDst lir::Memory returnAddressDst(
(rsp, (frameFootprint - offset + baseSize) * TargetBytesPerWord); rsp, (frameFootprint - offset + baseSize) * TargetBytesPerWord);
moveRM(&c, TargetBytesPerWord, &tmp, TargetBytesPerWord, moveRM(&c,
TargetBytesPerWord,
&tmp,
TargetBytesPerWord,
&returnAddressDst); &returnAddressDst);
c.client->releaseTemporary(tmp.low); c.client->releaseTemporary(tmp.low);
@ -990,9 +1090,8 @@ class MyAssembler: public Assembler {
} }
lir::Register stack(rsp); lir::Register stack(rsp);
lir::Constant footprint lir::Constant footprint(resolvedPromise(
(resolvedPromise &c, (frameFootprint - offset + baseSize) * TargetBytesPerWord));
(&c, (frameFootprint - offset + baseSize) * TargetBytesPerWord));
addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack); addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack);
@ -1032,9 +1131,9 @@ class MyAssembler: public Assembler {
popR(&c, TargetBytesPerWord, &returnAddress); popR(&c, TargetBytesPerWord, &returnAddress);
lir::Register stack(rsp); lir::Register stack(rsp);
lir::Constant adjustment lir::Constant adjustment(resolvedPromise(
(resolvedPromise(&c, (argumentFootprint - StackAlignmentInWords) &c,
* TargetBytesPerWord)); (argumentFootprint - StackAlignmentInWords) * TargetBytesPerWord));
addCR(&c, TargetBytesPerWord, &adjustment, TargetBytesPerWord, &stack); addCR(&c, TargetBytesPerWord, &adjustment, TargetBytesPerWord, &stack);
jumpR(&c, TargetBytesPerWord, &returnAddress); jumpR(&c, TargetBytesPerWord, &returnAddress);
@ -1058,45 +1157,51 @@ class MyAssembler: public Assembler {
jumpR(&c, TargetBytesPerWord, &returnAddress); jumpR(&c, TargetBytesPerWord, &returnAddress);
} }
virtual void apply(lir::Operation op) { virtual void apply(lir::Operation op)
{
arch_->c.operations[op](&c); arch_->c.operations[op](&c);
} }
virtual void apply(lir::UnaryOperation op, OperandInfo a) virtual void apply(lir::UnaryOperation op, OperandInfo a)
{ {
arch_->c.unaryOperations[Multimethod::index(op, a.type)] arch_->c.unaryOperations[Multimethod::index(op, a.type)](
(&c, a.size, a.operand); &c, a.size, a.operand);
} }
virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b)
{ {
arch_->c.binaryOperations[index(&(arch_->c), op, a.type, b.type)] arch_->c.binaryOperations[index(&(arch_->c), op, a.type, b.type)](
(&c, a.size, a.operand, b.size, b.operand); &c, a.size, a.operand, b.size, b.operand);
} }
virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) virtual void apply(lir::TernaryOperation op,
OperandInfo a,
OperandInfo b,
OperandInfo c)
{ {
if (isBranch(op)) { if (isBranch(op)) {
assertT(&this->c, a.size == b.size); assertT(&this->c, a.size == b.size);
assertT(&this->c, c.size == TargetBytesPerWord); assertT(&this->c, c.size == TargetBytesPerWord);
assertT(&this->c, c.type == lir::ConstantOperand); assertT(&this->c, c.type == lir::ConstantOperand);
arch_->c.branchOperations[branchIndex(&(arch_->c), a.type, b.type)] arch_->c.branchOperations[branchIndex(&(arch_->c), a.type, b.type)](
(&this->c, op, a.size, a.operand, b.operand, c.operand); &this->c, op, a.size, a.operand, b.operand, c.operand);
} else { } else {
assertT(&this->c, b.size == c.size); assertT(&this->c, b.size == c.size);
assertT(&this->c, b.type == c.type); assertT(&this->c, b.type == c.type);
arch_->c.binaryOperations[index(&(arch_->c), op, a.type, b.type)] arch_->c.binaryOperations[index(&(arch_->c), op, a.type, b.type)](
(&this->c, a.size, a.operand, b.size, b.operand); &this->c, a.size, a.operand, b.size, b.operand);
} }
} }
virtual void setDestination(uint8_t* dst) { virtual void setDestination(uint8_t* dst)
{
c.result = dst; c.result = dst;
} }
virtual void write() { virtual void write()
{
uint8_t* dst = c.result; uint8_t* dst = c.result;
for (MyBlock* b = c.firstBlock; b; b = b->next) { for (MyBlock* b = c.firstBlock; b; b = b->next) {
unsigned index = 0; unsigned index = 0;
@ -1111,10 +1216,9 @@ class MyAssembler: public Assembler {
index += size; index += size;
while ((b->start + index + padding + p->instructionOffset) while ((b->start + index + padding + p->instructionOffset)
% p->alignment) % p->alignment) {
{
*(dst + b->start + index + padding) = 0x90; *(dst + b->start + index + padding) = 0x90;
++ padding; ++padding;
} }
} }
@ -1128,34 +1232,40 @@ class MyAssembler: public Assembler {
} }
} }
virtual Promise* offset(bool) { virtual Promise* offset(bool)
{
return x86::offsetPromise(&c); return x86::offsetPromise(&c);
} }
virtual Block* endBlock(bool startNew) { virtual Block* endBlock(bool startNew)
{
MyBlock* b = c.lastBlock; MyBlock* b = c.lastBlock;
b->size = c.code.length() - b->offset; b->size = c.code.length() - b->offset;
if (startNew) { if (startNew) {
c.lastBlock = new(c.zone) MyBlock(c.code.length()); c.lastBlock = new (c.zone) MyBlock(c.code.length());
} else { } else {
c.lastBlock = 0; c.lastBlock = 0;
} }
return b; return b;
} }
virtual void endEvent() { virtual void endEvent()
{
// ignore // ignore
} }
virtual unsigned length() { virtual unsigned length()
{
return c.code.length(); return c.code.length();
} }
virtual unsigned footerSize() { virtual unsigned footerSize()
{
return 0; return 0;
} }
virtual void dispose() { virtual void dispose()
{
c.code.dispose(); c.code.dispose();
} }
@ -1165,8 +1275,7 @@ class MyAssembler: public Assembler {
Assembler* MyArchitecture::makeAssembler(util::Allocator* allocator, Zone* zone) Assembler* MyArchitecture::makeAssembler(util::Allocator* allocator, Zone* zone)
{ {
return return new (zone) MyAssembler(c.s, allocator, zone, this);
new(zone) MyAssembler(c.s, allocator, zone, this);
} }
} // namespace x86 } // namespace x86

View File

@ -16,15 +16,23 @@ namespace avian {
namespace codegen { namespace codegen {
namespace x86 { namespace x86 {
unsigned unsigned padding(AlignmentPadding* p,
padding(AlignmentPadding* p, unsigned index, unsigned offset, AlignmentPadding* limit); unsigned index,
unsigned offset,
AlignmentPadding* limit);
MyBlock::MyBlock(unsigned offset): MyBlock::MyBlock(unsigned offset)
next(0), firstPadding(0), lastPadding(0), offset(offset), start(~0), : next(0),
firstPadding(0),
lastPadding(0),
offset(offset),
start(~0),
size(0) size(0)
{ } {
}
unsigned MyBlock::resolve(unsigned start, Assembler::Block* next) { unsigned MyBlock::resolve(unsigned start, Assembler::Block* next)
{
this->start = start; this->start = start;
this->next = static_cast<MyBlock*>(next); this->next = static_cast<MyBlock*>(next);

View File

@ -19,7 +19,7 @@ namespace x86 {
class AlignmentPadding; class AlignmentPadding;
class MyBlock: public Assembler::Block { class MyBlock : public Assembler::Block {
public: public:
MyBlock(unsigned offset); MyBlock(unsigned offset);

View File

@ -18,9 +18,10 @@ namespace avian {
namespace codegen { namespace codegen {
namespace x86 { namespace x86 {
ArchitectureContext::ArchitectureContext(vm::System* s, bool useNativeFeatures): ArchitectureContext::ArchitectureContext(vm::System* s, bool useNativeFeatures)
s(s), useNativeFeatures(useNativeFeatures) : s(s), useNativeFeatures(useNativeFeatures)
{ } {
}
Context::Context(vm::System* s, Context::Context(vm::System* s,
util::Allocator* a, util::Allocator* a,

View File

@ -47,12 +47,18 @@ typedef void (*OperationType)(Context*);
typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*); typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*);
typedef void (*BinaryOperationType) typedef void (*BinaryOperationType)(Context*,
(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*); unsigned,
lir::Operand*,
unsigned,
lir::Operand*);
typedef void (*BranchOperationType) typedef void (*BranchOperationType)(Context*,
(Context*, lir::TernaryOperation, unsigned, lir::Operand*, lir::TernaryOperation,
lir::Operand*, lir::Operand*); unsigned,
lir::Operand*,
lir::Operand*,
lir::Operand*);
class ArchitectureContext { class ArchitectureContext {
public: public:
@ -61,14 +67,12 @@ class ArchitectureContext {
vm::System* s; vm::System* s;
bool useNativeFeatures; bool useNativeFeatures;
OperationType operations[lir::OperationCount]; OperationType operations[lir::OperationCount];
UnaryOperationType unaryOperations[lir::UnaryOperationCount UnaryOperationType
* lir::OperandTypeCount]; unaryOperations[lir::UnaryOperationCount * lir::OperandTypeCount];
BinaryOperationType binaryOperations BinaryOperationType binaryOperations
[(lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) [(lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount)
* lir::OperandTypeCount * lir::OperandTypeCount * lir::OperandTypeCount];
* lir::OperandTypeCount]; BranchOperationType branchOperations[lir::BranchOperationCount
BranchOperationType branchOperations
[lir::BranchOperationCount
* lir::OperandTypeCount * lir::OperandTypeCount
* lir::OperandTypeCount]; * lir::OperandTypeCount];
}; };
@ -91,11 +95,13 @@ class Context {
ArchitectureContext* ac; ArchitectureContext* ac;
}; };
inline avian::util::Aborter* getAborter(Context* c) { inline avian::util::Aborter* getAborter(Context* c)
{
return c->s; return c->s;
} }
inline avian::util::Aborter* getAborter(ArchitectureContext* c) { inline avian::util::Aborter* getAborter(ArchitectureContext* c)
{
return c->s; return c->s;
} }

View File

@ -17,10 +17,10 @@ namespace avian {
namespace codegen { namespace codegen {
namespace x86 { namespace x86 {
extern "C" bool extern "C" bool detectFeature(unsigned ecx, unsigned edx);
detectFeature(unsigned ecx, unsigned edx);
bool useSSE(ArchitectureContext* c) { bool useSSE(ArchitectureContext* c)
{
if (vm::TargetBytesPerWord == 8) { if (vm::TargetBytesPerWord == 8) {
// amd64 implies SSE2 support // amd64 implies SSE2 support
return true; return true;

View File

@ -26,8 +26,7 @@ using namespace avian::util;
namespace { namespace {
int64_t int64_t signExtend(unsigned size, int64_t v)
signExtend(unsigned size, int64_t v)
{ {
if (size == 4) { if (size == 4) {
return static_cast<int32_t>(v); return static_cast<int32_t>(v);
@ -46,14 +45,19 @@ namespace avian {
namespace codegen { namespace codegen {
namespace x86 { namespace x86 {
#define REX_W 0x48 #define REX_W 0x48
#define REX_R 0x44 #define REX_R 0x44
#define REX_X 0x42 #define REX_X 0x42
#define REX_B 0x41 #define REX_B 0x41
#define REX_NONE 0x40 #define REX_NONE 0x40
void maybeRex(Context* c, unsigned size, int a, int index, int base, bool always) { void maybeRex(Context* c,
unsigned size,
int a,
int index,
int base,
bool always)
{
if (vm::TargetBytesPerWord == 8) { if (vm::TargetBytesPerWord == 8) {
uint8_t byte; uint8_t byte;
if (size == 8) { if (size == 8) {
@ -61,46 +65,60 @@ void maybeRex(Context* c, unsigned size, int a, int index, int base, bool always
} else { } else {
byte = REX_NONE; byte = REX_NONE;
} }
if (a != lir::NoRegister and (a & 8)) byte |= REX_R; if (a != lir::NoRegister and (a & 8))
if (index != lir::NoRegister and (index & 8)) byte |= REX_X; byte |= REX_R;
if (base != lir::NoRegister and (base & 8)) byte |= REX_B; if (index != lir::NoRegister and (index & 8))
if (always or byte != REX_NONE) c->code.append(byte); byte |= REX_X;
if (base != lir::NoRegister and (base & 8))
byte |= REX_B;
if (always or byte != REX_NONE)
c->code.append(byte);
} }
} }
void maybeRex(Context* c, unsigned size, lir::Register* a, lir::Register* b) { void maybeRex(Context* c, unsigned size, lir::Register* a, lir::Register* b)
{
maybeRex(c, size, a->low, lir::NoRegister, b->low, false); maybeRex(c, size, a->low, lir::NoRegister, b->low, false);
} }
void alwaysRex(Context* c, unsigned size, lir::Register* a, lir::Register* b) { void alwaysRex(Context* c, unsigned size, lir::Register* a, lir::Register* b)
{
maybeRex(c, size, a->low, lir::NoRegister, b->low, true); maybeRex(c, size, a->low, lir::NoRegister, b->low, true);
} }
void maybeRex(Context* c, unsigned size, lir::Register* a) { void maybeRex(Context* c, unsigned size, lir::Register* a)
{
maybeRex(c, size, lir::NoRegister, lir::NoRegister, a->low, false); maybeRex(c, size, lir::NoRegister, lir::NoRegister, a->low, false);
} }
void maybeRex(Context* c, unsigned size, lir::Register* a, lir::Memory* b) { void maybeRex(Context* c, unsigned size, lir::Register* a, lir::Memory* b)
{
maybeRex(c, size, a->low, b->index, b->base, size == 1 and (a->low & 4)); maybeRex(c, size, a->low, b->index, b->base, size == 1 and (a->low & 4));
} }
void maybeRex(Context* c, unsigned size, lir::Memory* a) { void maybeRex(Context* c, unsigned size, lir::Memory* a)
{
maybeRex(c, size, lir::NoRegister, a->index, a->base, false); maybeRex(c, size, lir::NoRegister, a->index, a->base, false);
} }
void modrm(Context* c, uint8_t mod, int a, int b) { void modrm(Context* c, uint8_t mod, int a, int b)
{
c->code.append(mod | (regCode(b) << 3) | regCode(a)); c->code.append(mod | (regCode(b) << 3) | regCode(a));
} }
void modrm(Context* c, uint8_t mod, lir::Register* a, lir::Register* b) { void modrm(Context* c, uint8_t mod, lir::Register* a, lir::Register* b)
{
modrm(c, mod, a->low, b->low); modrm(c, mod, a->low, b->low);
} }
void sib(Context* c, unsigned scale, int index, int base) { void sib(Context* c, unsigned scale, int index, int base)
c->code.append((util::log(scale) << 6) | (regCode(index) << 3) | regCode(base)); {
c->code.append((util::log(scale) << 6) | (regCode(index) << 3)
| regCode(base));
} }
void modrmSib(Context* c, int width, int a, int scale, int index, int base) { void modrmSib(Context* c, int width, int a, int scale, int index, int base)
{
if (index == lir::NoRegister) { if (index == lir::NoRegister) {
modrm(c, width, base, a); modrm(c, width, base, a);
if (regCode(base) == rsp) { if (regCode(base) == rsp) {
@ -112,7 +130,8 @@ void modrmSib(Context* c, int width, int a, int scale, int index, int base) {
} }
} }
void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset) { void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset)
{
if (offset == 0 and regCode(base) != rbp) { if (offset == 0 and regCode(base) != rbp) {
modrmSib(c, 0x00, a, scale, index, base); modrmSib(c, 0x00, a, scale, index, base);
} else if (vm::fitsInInt8(offset)) { } else if (vm::fitsInInt8(offset)) {
@ -124,35 +143,43 @@ void modrmSibImm(Context* c, int a, int scale, int index, int base, int offset)
} }
} }
void modrmSibImm(Context* c, lir::Register* a, lir::Memory* b) { void modrmSibImm(Context* c, lir::Register* a, lir::Memory* b)
{
modrmSibImm(c, a->low, b->scale, b->index, b->base, b->offset); modrmSibImm(c, a->low, b->scale, b->index, b->base, b->offset);
} }
void opcode(Context* c, uint8_t op) { void opcode(Context* c, uint8_t op)
{
c->code.append(op); c->code.append(op);
} }
void opcode(Context* c, uint8_t op1, uint8_t op2) { void opcode(Context* c, uint8_t op1, uint8_t op2)
{
c->code.append(op1); c->code.append(op1);
c->code.append(op2); c->code.append(op2);
} }
void unconditional(Context* c, unsigned jump, lir::Constant* a) { void unconditional(Context* c, unsigned jump, lir::Constant* a)
{
appendOffsetTask(c, a->value, offsetPromise(c), 5); appendOffsetTask(c, a->value, offsetPromise(c), 5);
opcode(c, jump); opcode(c, jump);
c->code.append4(0); c->code.append4(0);
} }
void conditional(Context* c, unsigned condition, lir::Constant* a) { void conditional(Context* c, unsigned condition, lir::Constant* a)
{
appendOffsetTask(c, a->value, offsetPromise(c), 6); appendOffsetTask(c, a->value, offsetPromise(c), 6);
opcode(c, 0x0f, condition); opcode(c, 0x0f, condition);
c->code.append4(0); c->code.append4(0);
} }
void sseMoveRR(Context* c, unsigned aSize, lir::Register* a, void sseMoveRR(Context* c,
unsigned bSize UNUSED, lir::Register* b) unsigned aSize,
lir::Register* a,
unsigned bSize UNUSED,
lir::Register* b)
{ {
assertT(c, aSize >= 4); assertT(c, aSize >= 4);
assertT(c, aSize == bSize); assertT(c, aSize == bSize);
@ -182,8 +209,11 @@ void sseMoveRR(Context* c, unsigned aSize, lir::Register* a,
} }
} }
void sseMoveCR(Context* c, unsigned aSize, lir::Constant* a, void sseMoveCR(Context* c,
unsigned bSize, lir::Register* b) unsigned aSize,
lir::Constant* a,
unsigned bSize,
lir::Register* b)
{ {
assertT(c, aSize <= vm::TargetBytesPerWord); assertT(c, aSize <= vm::TargetBytesPerWord);
lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask));
@ -192,8 +222,11 @@ void sseMoveCR(Context* c, unsigned aSize, lir::Constant* a,
c->client->releaseTemporary(tmp.low); c->client->releaseTemporary(tmp.low);
} }
void sseMoveMR(Context* c, unsigned aSize, lir::Memory* a, void sseMoveMR(Context* c,
unsigned bSize UNUSED, lir::Register* b) unsigned aSize,
lir::Memory* a,
unsigned bSize UNUSED,
lir::Register* b)
{ {
assertT(c, aSize >= 4); assertT(c, aSize >= 4);
@ -209,8 +242,11 @@ void sseMoveMR(Context* c, unsigned aSize, lir::Memory* a,
} }
} }
void sseMoveRM(Context* c, unsigned aSize, lir::Register* a, void sseMoveRM(Context* c,
UNUSED unsigned bSize, lir::Memory* b) unsigned aSize,
lir::Register* a,
UNUSED unsigned bSize,
lir::Memory* b)
{ {
assertT(c, aSize >= 4); assertT(c, aSize >= 4);
assertT(c, aSize == bSize); assertT(c, aSize == bSize);
@ -227,7 +263,8 @@ void sseMoveRM(Context* c, unsigned aSize, lir::Register* a,
} }
} }
void branch(Context* c, lir::TernaryOperation op, lir::Constant* target) { void branch(Context* c, lir::TernaryOperation op, lir::Constant* target)
{
switch (op) { switch (op) {
case lir::JumpIfEqual: case lir::JumpIfEqual:
conditional(c, 0x84, target); conditional(c, 0x84, target);
@ -258,7 +295,8 @@ void branch(Context* c, lir::TernaryOperation op, lir::Constant* target) {
} }
} }
void branchFloat(Context* c, lir::TernaryOperation op, lir::Constant* target) { void branchFloat(Context* c, lir::TernaryOperation op, lir::Constant* target)
{
switch (op) { switch (op) {
case lir::JumpIfFloatEqual: case lir::JumpIfFloatEqual:
// jp past the je so we don't jump to the target if unordered: // jp past the je so we don't jump to the target if unordered:
@ -313,8 +351,13 @@ void branchFloat(Context* c, lir::TernaryOperation op, lir::Constant* target) {
} }
} }
void floatRegOp(Context* c, unsigned aSize, lir::Register* a, unsigned bSize, void floatRegOp(Context* c,
lir::Register* b, uint8_t op, uint8_t mod) unsigned aSize,
lir::Register* a,
unsigned bSize,
lir::Register* b,
uint8_t op,
uint8_t mod)
{ {
if (aSize == 4) { if (aSize == 4) {
opcode(c, 0xf3); opcode(c, 0xf3);
@ -326,8 +369,12 @@ void floatRegOp(Context* c, unsigned aSize, lir::Register* a, unsigned bSize,
modrm(c, mod, a, b); modrm(c, mod, a, b);
} }
void floatMemOp(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, void floatMemOp(Context* c,
lir::Register* b, uint8_t op) unsigned aSize,
lir::Memory* a,
unsigned bSize,
lir::Register* b,
uint8_t op)
{ {
if (aSize == 4) { if (aSize == 4) {
opcode(c, 0xf3); opcode(c, 0xf3);
@ -339,11 +386,18 @@ void floatMemOp(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize,
modrmSibImm(c, b, a); modrmSibImm(c, b, a);
} }
void moveCR(Context* c, unsigned aSize, lir::Constant* a, void moveCR(Context* c,
unsigned bSize, lir::Register* b); unsigned aSize,
lir::Constant* a,
unsigned bSize,
lir::Register* b);
void moveCR2(Context* c, UNUSED unsigned aSize, lir::Constant* a, void moveCR2(Context* c,
UNUSED unsigned bSize, lir::Register* b, unsigned promiseOffset) UNUSED unsigned aSize,
lir::Constant* a,
UNUSED unsigned bSize,
lir::Register* b,
unsigned promiseOffset)
{ {
if (vm::TargetBytesPerWord == 4 and bSize == 8) { if (vm::TargetBytesPerWord == 4 and bSize == 8) {
int64_t v = signExtend(aSize, a->value->value()); int64_t v = signExtend(aSize, a->value->value());
@ -366,8 +420,8 @@ void moveCR2(Context* c, UNUSED unsigned aSize, lir::Constant* a,
} else { } else {
expect(c, aSize == vm::TargetBytesPerWord); expect(c, aSize == vm::TargetBytesPerWord);
appendImmediateTask appendImmediateTask(
(c, a->value, offsetPromise(c), vm::TargetBytesPerWord, promiseOffset); c, a->value, offsetPromise(c), vm::TargetBytesPerWord, promiseOffset);
c->code.appendTargetAddress(static_cast<vm::target_uintptr_t>(0)); c->code.appendTargetAddress(static_cast<vm::target_uintptr_t>(0));
} }
} }

Some files were not shown because too many files have changed in this diff Show More