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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,7 +19,8 @@ namespace avian {
namespace classpath {
namespace sockets {
int last_socket_error() {
int last_socket_error()
{
#ifdef PLATFORM_WINDOWS
int error = WSAGetLastError();
#else
@ -28,8 +29,8 @@ int last_socket_error() {
return error;
}
void init(JNIEnv* ONLY_ON_WINDOWS(e)) {
void init(JNIEnv* ONLY_ON_WINDOWS(e))
{
#ifdef PLATFORM_WINDOWS
static bool wsaInitialized = false;
if (not wsaInitialized) {
@ -44,18 +45,21 @@ void init(JNIEnv* ONLY_ON_WINDOWS(e)) {
#endif
}
SOCKET create(JNIEnv* e) {
SOCKET create(JNIEnv* e)
{
SOCKET sock;
if (INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
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);
return 0; // This doesn't matter cause we have risen an exception
}
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;
adr.sin_family = AF_INET;
#ifdef PLATFORM_WINDOWS
@ -63,18 +67,19 @@ void connect(JNIEnv* e, SOCKET sock, long addr, short port) {
#else
adr.sin_addr.s_addr = htonl(addr);
#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];
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);
return;
}
}
void bind(JNIEnv* e, SOCKET sock, long addr, short port) {
void bind(JNIEnv* e, SOCKET sock, long addr, short port)
{
sockaddr_in adr;
adr.sin_family = AF_INET;
#ifdef PLATFORM_WINDOWS
@ -82,10 +87,9 @@ void bind(JNIEnv* e, SOCKET sock, long addr, short port) {
#else
adr.sin_addr.s_addr = htonl(addr);
#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];
sprintf(buf, "Can't bind a socket. System error: %d", last_socket_error());
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;
SOCKET client_socket = ::accept(sock, (sockaddr* )&adr, NULL);
SOCKET client_socket = ::accept(sock, (sockaddr*)&adr, NULL);
if (INVALID_SOCKET == client_socket) {
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);
return INVALID_SOCKET;
}
if (client_addr != NULL) {
#ifdef PLATFORM_WINDOWS
#ifdef PLATFORM_WINDOWS
*client_addr = ntohl(adr.sin_addr.S_un.S_addr);
#else
#else
*client_addr = ntohl(adr.sin_addr.s_addr);
#endif
#endif
}
if (client_port != NULL) {
*client_port = ntohs (adr.sin_port);
*client_port = ntohs(adr.sin_port);
}
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)) {
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);
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);
if (SOCKET_ERROR == length) {
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);
return 0; // This doesn't matter cause we have risen an exception
}
return length;
}
void abort(JNIEnv* e, SOCKET sock) {
void abort(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::closesocket(sock)) {
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);
}
}
void close(JNIEnv* e, SOCKET sock) {
void close(JNIEnv* e, SOCKET sock)
{
if (SOCKET_ERROR == ::shutdown(sock, SD_BOTH)) {
int errcode = last_socket_error();
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)) {
int errcode = last_socket_error();
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)) {
int errcode = last_socket_error();
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
details. */
/*
* This file represents a simple cross-platform JNI sockets API
* It is used from different classes of the default Avian classpath
@ -22,28 +21,28 @@
#include "jni-util.h"
#ifdef PLATFORM_WINDOWS
# include <winsock2.h>
#include <winsock2.h>
# define ONLY_ON_WINDOWS(x) x
#define ONLY_ON_WINDOWS(x) x
# ifndef ENOTCONN
# define ENOTCONN WSAENOTCONN
# endif
#ifndef ENOTCONN
#define ENOTCONN WSAENOTCONN
#endif
#else
# include <netdb.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
# define ONLY_ON_WINDOWS(x)
# define SOCKET int
# define INVALID_SOCKET -1
# define SOCKET_ERROR -1
# define closesocket(x) close(x)
#define ONLY_ON_WINDOWS(x)
#define SOCKET int
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(x) close(x)
# define SD_RECEIVE SHUT_RD
# define SD_SEND SHUT_WR
# define SD_BOTH SHUT_RDWR
#define SD_RECEIVE SHUT_RD
#define SD_SEND SHUT_WR
#define SD_BOTH SHUT_RDWR
#endif
@ -69,7 +68,6 @@ void abort(JNIEnv* e, SOCKET sock);
void close(JNIEnv* e, SOCKET sock);
void close_input(JNIEnv* e, SOCKET sock);
void close_output(JNIEnv* e, SOCKET sock);
}
}
}

View File

@ -30,113 +30,123 @@ class Assembler;
class RegisterFile;
class OperandMask {
public:
public:
uint8_t typeMask;
uint64_t registerMask;
OperandMask(uint8_t typeMask, uint64_t registerMask):
typeMask(typeMask),
registerMask(registerMask)
{ }
OperandMask(uint8_t typeMask, uint64_t registerMask)
: typeMask(typeMask), registerMask(registerMask)
{
}
OperandMask():
typeMask(~0),
registerMask(~static_cast<uint64_t>(0))
{ }
OperandMask() : typeMask(~0), registerMask(~static_cast<uint64_t>(0))
{
}
};
class Architecture {
public:
virtual unsigned floatRegisterSize() = 0;
public:
virtual unsigned floatRegisterSize() = 0;
virtual const RegisterFile* registerFile() = 0;
virtual const RegisterFile* registerFile() = 0;
virtual int scratch() = 0;
virtual int stack() = 0;
virtual int thread() = 0;
virtual int returnLow() = 0;
virtual int returnHigh() = 0;
virtual int virtualCallTarget() = 0;
virtual int virtualCallIndex() = 0;
virtual int scratch() = 0;
virtual int stack() = 0;
virtual int thread() = 0;
virtual int returnLow() = 0;
virtual int returnHigh() = 0;
virtual int virtualCallTarget() = 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::TernaryOperation op) = 0;
virtual bool alwaysCondensed(lir::BinaryOperation 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 argumentFootprint(unsigned footprint) = 0;
virtual bool argumentAlignment() = 0;
virtual bool argumentRegisterAlignment() = 0;
virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0;
virtual unsigned frameFootprint(unsigned footprint) = 0;
virtual unsigned argumentFootprint(unsigned footprint) = 0;
virtual bool argumentAlignment() = 0;
virtual bool argumentRegisterAlignment() = 0;
virtual unsigned argumentRegisterCount() = 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;
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,
void* link, bool mostRecent,
int targetParameterFootprint, void** ip,
virtual void nextFrame(void* start,
unsigned size,
unsigned footprint,
void* link,
bool mostRecent,
int targetParameterFootprint,
void** ip,
void** stack) = 0;
virtual void* frameIp(void* stack) = 0;
virtual unsigned frameHeaderSize() = 0;
virtual unsigned frameReturnAddressSize() = 0;
virtual unsigned frameFooterSize() = 0;
virtual int returnAddressOffset() = 0;
virtual int framePointerOffset() = 0;
virtual void* frameIp(void* stack) = 0;
virtual unsigned frameHeaderSize() = 0;
virtual unsigned frameReturnAddressSize() = 0;
virtual unsigned frameFooterSize() = 0;
virtual int returnAddressOffset() = 0;
virtual int framePointerOffset() = 0;
virtual void plan
(lir::UnaryOperation op,
unsigned aSize, OperandMask& aMask,
virtual void plan(lir::UnaryOperation op,
unsigned aSize,
OperandMask& aMask,
bool* thunk) = 0;
virtual void planSource
(lir::BinaryOperation op,
unsigned aSize, OperandMask& aMask,
unsigned bSize, bool* thunk) = 0;
virtual void planSource(lir::BinaryOperation op,
unsigned aSize,
OperandMask& aMask,
unsigned bSize,
bool* thunk) = 0;
virtual void planDestination
(lir::BinaryOperation op,
unsigned aSize, const OperandMask& aMask,
unsigned bSize, OperandMask& bMask) = 0;
virtual void planDestination(lir::BinaryOperation op,
unsigned aSize,
const OperandMask& aMask,
unsigned bSize,
OperandMask& bMask) = 0;
virtual void planMove
(unsigned size, OperandMask& src,
virtual void planMove(unsigned size,
OperandMask& src,
OperandMask& tmp,
const OperandMask& dst) = 0;
virtual void planSource
(lir::TernaryOperation op,
unsigned aSize, OperandMask& aMask,
unsigned bSize, OperandMask& bMask,
unsigned cSize, bool* thunk) = 0;
virtual void planSource(lir::TernaryOperation op,
unsigned aSize,
OperandMask& aMask,
unsigned bSize,
OperandMask& bMask,
unsigned cSize,
bool* thunk) = 0;
virtual void planDestination
(lir::TernaryOperation op,
unsigned aSize, const OperandMask& aMask,
unsigned bSize, const OperandMask& bMask,
unsigned cSize, OperandMask& cMask) = 0;
virtual void planDestination(lir::TernaryOperation op,
unsigned aSize,
const OperandMask& aMask,
unsigned bSize,
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 release() = 0;
virtual void acquire() = 0;
virtual void release() = 0;
};
} // namespace codegen

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,7 +20,8 @@ namespace codegen {
class Architecture;
Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures);
Architecture* makeArchitectureNative(vm::System* system,
bool useNativeFeatures);
Architecture* makeArchitectureX86(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 {
public:
enum CollectionType {
MinorCollection,
MajorCollection
};
enum CollectionType { MinorCollection, MajorCollection };
enum Status {
Null,
Reachable,
Unreachable,
Tenured
};
enum Status { Null, Reachable, Unreachable, Tenured };
class Visitor {
public:
@ -62,7 +54,8 @@ class Heap : public avian::util::Allocator {
virtual unsigned remaining() = 0;
virtual unsigned limit() = 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;
virtual unsigned fixedFootprint(unsigned sizeInWords, bool objectMask) = 0;
virtual void* allocateFixed(avian::util::Allocator* allocator,
@ -92,4 +85,4 @@ Heap* makeHeap(System* system, unsigned limit);
} // namespace vm
#endif//HEAP_H
#endif // HEAP_H

View File

@ -21,7 +21,8 @@ namespace system {
// order to trigger the crash dump logic.
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"
// register. Use a thread-local variable instead.
class SignalRegistrar {
@ -40,7 +41,6 @@ class SignalRegistrar {
// "Segmentation fault" exceptions (mostly null pointer dereference, but
// generally access to any non-mapped memory)
SegFault,
DivideByZero,
};
@ -72,7 +72,6 @@ class SignalRegistrar {
struct Data;
private:
Data* data;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,38 +17,43 @@ namespace avian {
namespace util {
class String {
public:
public:
const char* text;
size_t length;
String(const char* text):
text(text),
length(strlen(text)) {}
String(const char* text) : text(text), length(strlen(text))
{
}
inline String(const char* text, size_t length):
text(text),
length(length) {}
inline String(const char* text, size_t length) : text(text), length(length)
{
}
};
class Tokenizer {
public:
Tokenizer(const char* s, char delimiter)
: s(s), limit(0), delimiter(delimiter)
{
}
Tokenizer(const char* s, char delimiter):
s(s), limit(0), delimiter(delimiter)
{ }
Tokenizer(String str, char delimiter)
: s(str.text), limit(str.text + str.length), delimiter(delimiter)
{
}
Tokenizer(String str, char delimiter):
s(str.text), limit(str.text + str.length), delimiter(delimiter)
{ }
bool hasMore() {
while (s != limit and *s == delimiter) ++s;
bool hasMore()
{
while (s != limit and *s == delimiter)
++s;
return s != limit and *s != 0;
}
String next() {
String next()
{
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);
}
@ -60,4 +65,4 @@ class Tokenizer {
} // namespace util
} // 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);
};
void
JniConstants::init(_JNIEnv*)
void JniConstants::init(_JNIEnv*)
{
// ignore
}

View File

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

View File

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

View File

@ -16,61 +16,62 @@
#include <avian/util/runtime-array.h>
#ifdef __APPLE__
# include "libkern/OSAtomic.h"
# include "libkern/OSCacheControl.h"
# include "mach/mach_types.h"
# include "mach/thread_act.h"
# include "mach/thread_status.h"
#include "libkern/OSAtomic.h"
#include "libkern/OSCacheControl.h"
#include "mach/mach_types.h"
#include "mach/thread_act.h"
#include "mach/thread_status.h"
# define THREAD_STATE ARM_THREAD_STATE
# define THREAD_STATE_TYPE arm_thread_state_t
# define THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT
#define THREAD_STATE ARM_THREAD_STATE
#define THREAD_STATE_TYPE arm_thread_state_t
#define THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT
# if __DARWIN_UNIX03 && defined(_STRUCT_ARM_EXCEPTION_STATE)
# 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])
#if __DARWIN_UNIX03 && defined(_STRUCT_ARM_EXCEPTION_STATE)
#define FIELD(x) __##x
#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)
#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
#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
#define VA_LIST(x) (&(x))
extern "C" uint64_t
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
unsigned memoryCount, void* gprTable, void* vfpTable,
extern "C" uint64_t vmNativeCall(void* function,
unsigned stackTotal,
void* memoryTable,
unsigned memoryCount,
void* gprTable,
void* vfpTable,
unsigned returnType);
namespace vm {
inline void
trap()
inline void trap()
{
#ifdef _MSC_VER
__debugbreak();
@ -86,23 +87,21 @@ trap()
// performant choice.
#ifndef _MSC_VER
inline void
memoryBarrier()
inline void memoryBarrier()
{
#ifdef __APPLE__
OSMemoryBarrier();
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
#elif(__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
return __sync_synchronize();
#elif (! defined AVIAN_ASSUME_ARMV6)
__asm__ __volatile__ ("dmb" : : : "memory");
#elif(!defined AVIAN_ASSUME_ARMV6)
__asm__ __volatile__("dmb" : : : "memory");
#else
__asm__ __volatile__ ("" : : : "memory");
__asm__ __volatile__("" : : : "memory");
#endif
}
#endif
inline void
storeStoreMemoryBarrier()
inline void storeStoreMemoryBarrier()
{
#ifdef _MSC_VER
_ReadWriteBarrier();
@ -111,8 +110,7 @@ storeStoreMemoryBarrier()
#endif
}
inline void
storeLoadMemoryBarrier()
inline void storeLoadMemoryBarrier()
{
#ifdef _MSC_VER
MemoryBarrier();
@ -121,8 +119,7 @@ storeLoadMemoryBarrier()
#endif
}
inline void
loadMemoryBarrier()
inline void loadMemoryBarrier()
{
#ifdef _MSC_VER
_ReadWriteBarrier();
@ -135,18 +132,18 @@ loadMemoryBarrier()
#if defined(__ANDROID__)
// 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
inline void
syncInstructionCache(const void* start, unsigned size)
inline void syncInstructionCache(const void* start, unsigned size)
{
#ifdef __APPLE__
sys_icache_invalidate(const_cast<void*>(start), size);
#elif (defined __QNX__)
#elif(defined __QNX__)
msync(const_cast<void*>(start), size, MS_INVALIDATE_ICACHE);
#else
__clear_cache
(const_cast<void*>(start),
__clear_cache(
const_cast<void*>(start),
const_cast<uint8_t*>(static_cast<const uint8_t*>(start) + size));
#endif
}
@ -154,32 +151,34 @@ syncInstructionCache(const void* start, unsigned size)
#endif // AVIAN_AOT_ONLY
#ifndef __APPLE__
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
typedef int(__kernel_cmpxchg_t)(int oldval, int newval, int* ptr);
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t*)0xffff0fc0)
#endif
inline bool
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
inline bool atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
{
#ifdef __APPLE__
return OSAtomicCompareAndSwap32Barrier(old, new_, reinterpret_cast<int32_t*>(p));
#elif (defined __QNX__)
return OSAtomicCompareAndSwap32Barrier(
old, new_, reinterpret_cast<int32_t*>(p));
#elif(defined __QNX__)
return old == _smp_cmpxchg(p, old, new_);
#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);
#endif
}
inline bool
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
inline bool atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
{
return atomicCompareAndSwap32(reinterpret_cast<uint32_t*>(p), old, new_);
}
inline uint64_t
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned argumentCount, unsigned argumentsSize UNUSED,
inline uint64_t dynamicCall(void* function,
uintptr_t* arguments,
uint8_t* argumentTypes,
unsigned argumentCount,
unsigned argumentsSize UNUSED,
unsigned returnType)
{
#ifdef __APPLE__
@ -197,11 +196,14 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned vfpIndex = 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 ai = 0;
for (unsigned ati = 0; ati < argumentCount; ++ ati) {
for (unsigned ati = 0; ati < argumentCount; ++ati) {
switch (argumentTypes[ati]) {
case DOUBLE_TYPE:
#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) {
vfpBackfillIndex = vfpIndex;
++ vfpIndex;
++vfpIndex;
}
memcpy(vfpTable + vfpIndex, arguments + ai, 8);
@ -217,7 +219,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
} else {
vfpIndex = VfpCount;
if (stackIndex % Alignment) {
++ stackIndex;
++stackIndex;
}
memcpy(RUNTIME_ARRAY_BODY(stack) + stackIndex, arguments + ai, 8);
@ -235,15 +237,13 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
} else {
RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai];
}
++ ai;
++ai;
break;
#endif
case INT64_TYPE: {
if (gprIndex + Alignment <= GprCount) { // pass argument in register(s)
if (Alignment == 1
and BytesPerWord < 8
and gprIndex + Alignment == GprCount)
{
if (Alignment == 1 and BytesPerWord < 8
and gprIndex + Alignment == GprCount) {
gprTable[gprIndex++] = arguments[ai];
RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai + 1];
} else {
@ -272,25 +272,28 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
} else {
RUNTIME_ARRAY_BODY(stack)[stackIndex++] = arguments[ai];
}
++ ai;
++ai;
} break;
}
}
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;
}
if (vfpIndex < VfpCount) {
memset(vfpTable + vfpIndex, 0, (VfpCount-vfpIndex)*4);
memset(vfpTable + vfpIndex, 0, (VfpCount - vfpIndex) * 4);
vfpIndex = VfpCount;
}
unsigned stackSize = stackIndex*BytesPerWord + ((stackIndex & 1) << 2);
return vmNativeCall
(function, stackSize, RUNTIME_ARRAY_BODY(stack), stackIndex * BytesPerWord,
unsigned stackSize = stackIndex * BytesPerWord + ((stackIndex & 1) << 2);
return vmNativeCall(function,
stackSize,
RUNTIME_ARRAY_BODY(stack),
stackIndex * BytesPerWord,
(gprIndex ? gprTable : 0),
(vfpIndex ? vfpTable : 0), returnType);
(vfpIndex ? vfpTable : 0),
returnType);
}
} // namespace vm

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,9 +11,8 @@
#ifndef AVIAN_TARGET_FIELDS_H
#define AVIAN_TARGET_FIELDS_H
#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_EXCEPTIONSTACKADJUSTMENT 2264
@ -33,7 +32,7 @@
#define TARGET_THREAD_THUNKTABLE 2328
#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_EXCEPTIONSTACKADJUSTMENT 2168
@ -53,12 +52,11 @@
#define TARGET_THREAD_THUNKTABLE 2200
#define TARGET_THREAD_STACKLIMIT 2224
# else
# error
# endif
#else
# error
#error
#endif
#else
#error
#endif
#endif

View File

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

View File

@ -20,4 +20,4 @@
#define DOUBLE_TYPE 6
#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
hashMapIteratorNext(Thread* t, object it);
object hashMapIteratorNext(Thread* t, object it);
void listAppend(Thread* t, GcList* list, object value);
GcVector* vectorAppend(Thread* t, GcVector* vector, object value);
object
growArray(Thread* t, object array);
object growArray(Thread* t, object array);
object treeQuery(Thread* t,
GcTreeNode* tree,
@ -115,7 +113,7 @@ void treeUpdate(Thread* t,
GcTreeNode* sentinal,
intptr_t (*compare)(Thread* t, intptr_t key, object b));
class HashMapIterator: public Thread::Protector {
class HashMapIterator : public Thread::Protector {
public:
HashMapIterator(Thread* t, GcHashMap* map)
: Protector(t), map(map), node(0), index(0)
@ -123,7 +121,8 @@ class HashMapIterator: public Thread::Protector {
find();
}
void find() {
void find()
{
GcArray* array = map->array();
if (array) {
for (unsigned i = index; i < array->length(); ++i) {
@ -137,7 +136,8 @@ class HashMapIterator: public Thread::Protector {
node = 0;
}
bool hasMore() {
bool hasMore()
{
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(&node);
}
@ -168,4 +169,4 @@ class HashMapIterator: public Thread::Protector {
} // vm
#endif//UTIL_H
#endif // UTIL_H

View File

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

View File

@ -13,11 +13,19 @@
#ifdef inflateInit2
#undef inflateInit2
#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
#ifdef deflateInit2
#undef deflateInit2
#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

View File

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

View File

@ -12,26 +12,23 @@
#ifdef BOOT_JAVAHOME
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_javahome_jar_##x
#if (!defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
#define SYMBOL(x) binary_javahome_jar_##x
#else
# define SYMBOL(x) _binary_javahome_jar_##x
#define SYMBOL(x) _binary_javahome_jar_##x
#endif
extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
AVIAN_EXPORT const uint8_t*
javahomeJar(unsigned* size)
{
AVIAN_EXPORT const uint8_t* javahomeJar(unsigned* size)
{
*size = SYMBOL(end) - SYMBOL(start);
return SYMBOL(start);
}
}
}
#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
// ourselves:
extern "C" void __cxa_pure_virtual(void) { abort(); }
extern "C" void __cxa_pure_virtual(void)
{
abort();
}
#ifdef BOOT_IMAGE
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define BOOTIMAGE_SYMBOL(x) binary_bootimage_bin_##x
# define CODEIMAGE_SYMBOL(x) binary_codeimage_bin_##x
#if (!defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
#define BOOTIMAGE_SYMBOL(x) binary_bootimage_bin_##x
#define CODEIMAGE_SYMBOL(x) binary_codeimage_bin_##x
#else
# define BOOTIMAGE_SYMBOL(x) _binary_bootimage_bin_##x
# define CODEIMAGE_SYMBOL(x) _binary_codeimage_bin_##x
#define BOOTIMAGE_SYMBOL(x) _binary_bootimage_bin_##x
#define CODEIMAGE_SYMBOL(x) _binary_codeimage_bin_##x
#endif
extern "C" {
extern const uint8_t BOOTIMAGE_SYMBOL(start)[];
extern const uint8_t BOOTIMAGE_SYMBOL(end)[];
extern const uint8_t BOOTIMAGE_SYMBOL(start)[];
extern const uint8_t BOOTIMAGE_SYMBOL(end)[];
AVIAN_EXPORT const uint8_t*
bootimageBin(unsigned* size)
{
AVIAN_EXPORT const uint8_t* bootimageBin(unsigned* size)
{
*size = BOOTIMAGE_SYMBOL(end) - BOOTIMAGE_SYMBOL(start);
return BOOTIMAGE_SYMBOL(start);
}
}
extern const uint8_t CODEIMAGE_SYMBOL(start)[];
extern const uint8_t CODEIMAGE_SYMBOL(end)[];
extern const uint8_t CODEIMAGE_SYMBOL(start)[];
extern const uint8_t CODEIMAGE_SYMBOL(end)[];
AVIAN_EXPORT const uint8_t*
codeimageBin(unsigned* size)
{
AVIAN_EXPORT const uint8_t* codeimageBin(unsigned* size)
{
*size = CODEIMAGE_SYMBOL(end) - CODEIMAGE_SYMBOL(start);
return CODEIMAGE_SYMBOL(start);
}
}
}
#undef SYMBOL
#endif//BOOT_IMAGE
#endif // BOOT_IMAGE
#ifdef BOOT_CLASSPATH
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_classpath_jar_##x
#if (!defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
#define SYMBOL(x) binary_classpath_jar_##x
#else
# define SYMBOL(x) _binary_classpath_jar_##x
#define SYMBOL(x) _binary_classpath_jar_##x
#endif
extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
AVIAN_EXPORT const uint8_t*
classpathJar(unsigned* size)
{
AVIAN_EXPORT const uint8_t* classpathJar(unsigned* size)
{
*size = SYMBOL(end) - SYMBOL(start);
return SYMBOL(start);
}
}
}
#undef SYMBOL
#endif//BOOT_CLASSPATH
#endif // BOOT_CLASSPATH

View File

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

View File

@ -37,8 +37,9 @@ class ConstantPoolNode;
class ForkState;
class Block;
template<class T>
List<T>* reverseDestroy(List<T>* cell) {
template <class T>
List<T>* reverseDestroy(List<T>* cell)
{
List<T>* previous = 0;
while (cell) {
List<T>* next = cell->next;
@ -93,7 +94,9 @@ class LogicalCode {
class Context {
public:
Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
Context(vm::System* system,
Assembler* assembler,
vm::Zone* zone,
Compiler::Client* client);
vm::System* system;
@ -128,12 +131,14 @@ class Context {
ir::TargetInfo targetInfo;
};
inline Aborter* getAborter(Context* c) {
inline Aborter* getAborter(Context* c)
{
return c->system;
}
template<class T>
List<T>* cons(Context* c, const T& value, List<T>* next) {
template <class T>
List<T>* cons(Context* c, const T& value, List<T>* 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 bool isBranch() { return false; }
virtual bool allExits() { return false; }
virtual Local* locals() { return localsBefore; }
virtual bool isBranch()
{
return false;
}
virtual bool allExits()
{
return false;
}
virtual Local* locals()
{
return localsBefore;
}
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);
void addReads(Context* c, Value* v, unsigned size,
const SiteMask& lowMask, Value* lowSuccessor,
const SiteMask& highMask, Value* highSuccessor);
void addReads(Context* c,
Value* v,
unsigned size,
const SiteMask& lowMask,
Value* lowSuccessor,
const SiteMask& highMask,
Value* highSuccessor);
void addReads(Context* c, Value* v, unsigned size,
const SiteMask& lowMask, const SiteMask& highMask);
void addReads(Context* c,
Value* v,
unsigned size,
const SiteMask& lowMask,
const SiteMask& highMask);
CodePromise* makeCodePromise(Context* c);
@ -82,7 +98,9 @@ class StubReadPair {
class JunctionState {
public:
JunctionState(unsigned frameFootprint): frameFootprint(frameFootprint) { }
JunctionState(unsigned frameFootprint) : frameFootprint(frameFootprint)
{
}
unsigned frameFootprint;
StubReadPair reads[0];
@ -90,12 +108,19 @@ class JunctionState {
class Link {
public:
Link(Event* predecessor, Link* nextPredecessor, Event* successor,
Link* nextSuccessor, ForkState* forkState):
predecessor(predecessor), nextPredecessor(nextPredecessor),
successor(successor), nextSuccessor(nextSuccessor), forkState(forkState),
Link(Event* predecessor,
Link* nextPredecessor,
Event* successor,
Link* nextSuccessor,
ForkState* forkState)
: predecessor(predecessor),
nextPredecessor(nextPredecessor),
successor(successor),
nextSuccessor(nextSuccessor),
forkState(forkState),
junctionState(0)
{ }
{
}
unsigned countPredecessors();
Link* lastPredecessor();
@ -109,9 +134,12 @@ class Link {
JunctionState* junctionState;
};
Link*
link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor,
Link* nextSuccessor, ForkState* forkState);
Link* link(Context* c,
Event* predecessor,
Link* nextPredecessor,
Event* successor,
Link* nextSuccessor,
ForkState* forkState);
void appendCall(Context* c,
Value* address,
@ -142,12 +170,14 @@ void appendTranslate(Context* c,
Value* first,
Value* result);
void
appendOperation(Context* c, lir::Operation op);
void appendOperation(Context* c, lir::Operation op);
void
appendMemory(Context* c, Value* base, int displacement, Value* index,
unsigned scale, Value* result);
void appendMemory(Context* c,
Value* base,
int displacement,
Value* index,
unsigned scale,
Value* result);
void appendBranch(Context* c,
lir::TernaryOperation op,
@ -161,18 +191,17 @@ void appendJump(Context* c,
bool exit = false,
bool cleanLocals = false);
void
appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset,
Value* index, intptr_t handler);
void appendBoundsCheck(Context* c,
Value* object,
unsigned lengthOffset,
Value* index,
intptr_t handler);
void
appendFrameSite(Context* c, Value* value, int index);
void appendFrameSite(Context* c, Value* value, int index);
void
appendSaveLocals(Context* c);
void appendSaveLocals(Context* c);
void
appendDummy(Context* c);
void appendDummy(Context* c);
void appendBuddy(Context* c, Value* original, Value* buddy);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,8 +15,7 @@ namespace avian {
namespace codegen {
namespace compiler {
class CodePromise: public Promise {
class CodePromise : public Promise {
public:
CodePromise(Context* c, CodePromise* next);
@ -33,7 +32,10 @@ class CodePromise: public Promise {
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);

View File

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

View File

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

View File

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

View File

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

View File

@ -18,154 +18,173 @@ namespace compiler {
const bool DebugResources = false;
void steal(Context* c, Resource* r, Value* thief);
void decrementAvailableGeneralRegisterCount(Context* c) {
void decrementAvailableGeneralRegisterCount(Context* c)
{
assertT(c, c->availableGeneralRegisterCount);
-- c->availableGeneralRegisterCount;
--c->availableGeneralRegisterCount;
if (DebugResources) {
fprintf(stderr, "%d registers available\n",
c->availableGeneralRegisterCount);
fprintf(
stderr, "%d registers available\n", c->availableGeneralRegisterCount);
}
}
void incrementAvailableGeneralRegisterCount(Context* c) {
++ c->availableGeneralRegisterCount;
void incrementAvailableGeneralRegisterCount(Context* c)
{
++c->availableGeneralRegisterCount;
if (DebugResources) {
fprintf(stderr, "%d registers available\n",
c->availableGeneralRegisterCount);
fprintf(
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) {
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);
}
++ 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 (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);
}
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):
value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0),
referenceCount(0), reserved(reserved)
{ }
RegisterResource::RegisterResource(bool reserved) : Resource(reserved)
{
}
RegisterResource::RegisterResource(bool reserved):
Resource(reserved)
{ }
void RegisterResource::freeze(Context* c, Value* v) {
void RegisterResource::freeze(Context* c, Value* v)
{
if (not reserved) {
freezeResource(c, this, v);
if (freezeCount == 1
and ((1 << index(c)) & c->regFile->generalRegisters.mask))
{
and ((1 << index(c)) & c->regFile->generalRegisters.mask)) {
decrementAvailableGeneralRegisterCount(c);
}
}
}
void RegisterResource::thaw(Context* c, Value* v) {
void RegisterResource::thaw(Context* c, Value* v)
{
if (not reserved) {
thawResource(c, this, v);
if (freezeCount == 0
and ((1 << index(c)) & c->regFile->generalRegisters.mask))
{
and ((1 << index(c)) & c->regFile->generalRegisters.mask)) {
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));
}
unsigned RegisterResource::index(Context* c) {
unsigned RegisterResource::index(Context* c)
{
return this - c->registerResources;
}
void RegisterResource::increment(Context* c) {
void RegisterResource::increment(Context* c)
{
if (not this->reserved) {
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);
}
++ this->referenceCount;
++this->referenceCount;
if (this->referenceCount == 1
and ((1 << this->index(c)) & c->regFile->generalRegisters.mask))
{
and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) {
decrementAvailableGeneralRegisterCount(c);
}
}
}
void RegisterResource::decrement(Context* c) {
void RegisterResource::decrement(Context* c)
{
if (not this->reserved) {
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);
}
assertT(c, this->referenceCount > 0);
-- this->referenceCount;
--this->referenceCount;
if (this->referenceCount == 0
and ((1 << this->index(c)) & c->regFile->generalRegisters.mask))
{
and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) {
incrementAvailableGeneralRegisterCount(c);
}
}
}
void FrameResource::freeze(Context* c, Value* v) {
void FrameResource::freeze(Context* c, Value* v)
{
freezeResource(c, this, v);
}
void FrameResource::thaw(Context* c, Value* v) {
void FrameResource::thaw(Context* c, Value* 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));
}
unsigned FrameResource::index(Context* c) {
unsigned FrameResource::index(Context* c)
{
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, site);
if (not resource->reserved) {
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);
}
@ -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 (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);
}
@ -220,7 +244,6 @@ void release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNU
}
}
} // namespace compiler
} // namespace codegen
} // namespace avian

View File

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

View File

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

View File

@ -30,23 +30,29 @@ const unsigned CopyPenalty = 10;
class SiteMask {
public:
SiteMask(): typeMask(~0), registerMask(~0), frameIndex(AnyFrameIndex) { }
SiteMask() : typeMask(~0), registerMask(~0), frameIndex(AnyFrameIndex)
{
}
SiteMask(uint8_t typeMask, uint32_t registerMask, int frameIndex):
typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex)
{ }
SiteMask(uint8_t typeMask, uint32_t registerMask, int frameIndex)
: typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex)
{
}
SiteMask intersectionWith(const SiteMask& b);
static SiteMask fixedRegisterMask(int number) {
static SiteMask fixedRegisterMask(int number)
{
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);
}
static SiteMask highPart(const OperandMask& mask) {
static SiteMask highPart(const OperandMask& mask)
{
return SiteMask(mask.typeMask, mask.registerMask >> 32, AnyFrameIndex);
}
@ -57,9 +63,14 @@ class SiteMask {
class Site {
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;
@ -71,15 +82,26 @@ class Site {
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;
@ -99,16 +121,24 @@ class Site {
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;
};
class SiteIterator {
public:
SiteIterator(Context* c, Value* v, bool includeBuddies = true,
SiteIterator(Context* c,
Value* v,
bool includeBuddies = true,
bool includeNextWord = true);
Site** findNext(Site** p);
@ -130,43 +160,52 @@ Site* constantSite(Context* c, Promise* value);
Site* constantSite(Context* c, int64_t value);
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:
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()) {
return vm::snprintf
(buffer, bufferSize, "constant %" LLD, value->value());
return vm::snprintf(buffer, bufferSize, "constant %" LLD, value->value());
} else {
return vm::snprintf(buffer, bufferSize, "constant unresolved");
}
}
virtual unsigned copyCost(Context*, Site* s) {
virtual unsigned copyCost(Context*, Site* s)
{
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);
}
virtual bool loneMatch(Context*, const SiteMask&) {
virtual bool loneMatch(Context*, const SiteMask&)
{
return true;
}
virtual bool matchNextWord(Context* c, Site* s, unsigned) {
virtual bool matchNextWord(Context* c, Site* s, unsigned)
{
return s->type(c) == lir::ConstantOperand;
}
virtual lir::OperandType type(Context*) {
virtual lir::OperandType type(Context*)
{
return lir::ConstantOperand;
}
virtual void asAssemblerOperand(Context* c, Site* high,
lir::Operand* result)
virtual void asAssemblerOperand(Context* c, Site* high, lir::Operand* result)
{
Promise* v = value;
if (high != this) {
@ -175,27 +214,33 @@ class ConstantSite: public Site {
new (result) lir::Constant(v);
}
virtual Site* copy(Context* c) {
virtual Site* copy(Context* c)
{
return constantSite(c, value);
}
virtual Site* copyLow(Context* c) {
virtual Site* copyLow(Context* c)
{
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));
}
virtual Site* makeNextWord(Context* c, unsigned) {
virtual Site* makeNextWord(Context* c, unsigned)
{
abort(c);
}
virtual SiteMask mask(Context*) {
virtual SiteMask mask(Context*)
{
return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex);
}
virtual SiteMask nextWordMask(Context*, unsigned) {
virtual SiteMask nextWordMask(Context*, unsigned)
{
return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex);
}
@ -204,7 +249,7 @@ class ConstantSite: public Site {
Site* addressSite(Context* c, Promise* address);
class RegisterSite: public Site {
class RegisterSite : public Site {
public:
RegisterSite(uint32_t mask, int number);
@ -230,7 +275,8 @@ class RegisterSite: public Site {
virtual lir::OperandType type(Context*);
virtual void asAssemblerOperand(Context* c UNUSED, Site* high,
virtual void asAssemblerOperand(Context* c UNUSED,
Site* high,
lir::Operand* result);
virtual Site* copy(Context* c);
@ -256,8 +302,7 @@ class RegisterSite: public Site {
Site* registerSite(Context* c, int number);
Site* freeRegisterSite(Context* c, uint32_t mask);
class MemorySite: public Site {
class MemorySite : public Site {
public:
MemorySite(int base, int offset, int index, unsigned scale);
@ -285,7 +330,8 @@ class MemorySite: public Site {
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);
virtual Site* copy(Context* c);
@ -311,7 +357,11 @@ class MemorySite: public Site {
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);
} // 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) {
if (s == site) return true;
if (s == site)
return true;
}
return false;
}
bool Value::isBuddyOf(Value* b) {
bool Value::isBuddyOf(Value* b)
{
Value* a = this;
if (a == b) return true;
if (a == b)
return true;
for (Value* p = a->buddy; p != a; p = p->buddy) {
if (p == b) return true;
if (p == b)
return true;
}
return false;
}
void Value::addSite(Context* c, Site* s) {
void Value::addSite(Context* c, Site* s)
{
if (not this->findSite(s)) {
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);
}
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);
Value* next = value(c, this->type);
@ -69,14 +76,15 @@ void Value::grow(Context* c) {
next->wordIndex = 1;
}
void Value::maybeSplit(Context* c) {
void Value::maybeSplit(Context* c)
{
if (this->nextWord == this) {
this->split(c);
}
}
void Value::split(Context* c) {
void Value::split(Context* c)
{
this->grow(c);
for (SiteIterator it(c, this); it.hasMore();) {
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();) {
if (s == it.next()) {
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);
}
it.remove(c);
@ -104,12 +114,14 @@ void Value::removeSite(Context* c, Site* s) {
assertT(c, not this->findSite(s));
}
bool Value::hasSite(Context* c) {
bool Value::hasSite(Context* c)
{
SiteIterator it(c, this);
return it.hasMore();
}
bool Value::uniqueSite(Context* c, Site* s) {
bool Value::uniqueSite(Context* c, Site* s)
{
SiteIterator it(c, this);
Site* p UNUSED = it.next();
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) {
fprintf(stderr, "clear sites for %p\n", this);
}
@ -143,9 +156,9 @@ void Value::clearSites(Context* c) {
}
}
#ifndef NDEBUG
bool Value::hasBuddy(Context* c, Value* b) {
bool Value::hasBuddy(Context* c, Value* b)
{
Value* a = this;
if (a == b) {
return true;
@ -166,7 +179,7 @@ bool Value::hasBuddy(Context* c, Value* b) {
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -57,38 +57,52 @@ typedef void (*OperationType)(Context*);
typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*);
typedef void (*BinaryOperationType)
(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*);
typedef void (*TernaryOperationType)
(Context*, unsigned, lir::Operand*, lir::Operand*,
typedef void (*BinaryOperationType)(Context*,
unsigned,
lir::Operand*,
unsigned,
lir::Operand*);
typedef void (*BranchOperationType)
(Context*, lir::TernaryOperation, unsigned, lir::Operand*,
lir::Operand*, lir::Operand*);
typedef void (*TernaryOperationType)(Context*,
unsigned,
lir::Operand*,
lir::Operand*,
lir::Operand*);
typedef void (*BranchOperationType)(Context*,
lir::TernaryOperation,
unsigned,
lir::Operand*,
lir::Operand*,
lir::Operand*);
class ArchitectureContext {
public:
ArchitectureContext(vm::System* s): s(s) { }
ArchitectureContext(vm::System* s) : s(s)
{
}
vm::System* s;
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];
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;
}
inline avian::util::Aborter* getAborter(ArchitectureContext* c) {
inline avian::util::Aborter* getAborter(ArchitectureContext* c)
{
return c->s;
}

View File

@ -25,159 +25,665 @@ const int FPSID = 0x0;
const int FPSCR = 0x1;
const int FPEXC = 0x8;
// 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 };
// INSTRUCTION FORMATS
inline int DATA(int cond, int opcode, int S, int Rn, int Rd, int shift, int Sh, int 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
DATA(int cond, int opcode, int S, int Rn, int Rd, int shift, int Sh, int 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)
{ 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)
{ 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)
{ 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)
{ 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 | 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;}
{
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 | 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
inline int calcU(int imm) { return imm >= 0 ? 1 : 0; }
inline int calcU(int imm)
{
return imm >= 0 ? 1 : 0;
}
// INSTRUCTIONS
// 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 bl(int offset) { return BRANCH(AL, 1, offset); }
inline int bx(int Rm) { return BRANCHX(AL, 0, Rm); }
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 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); }
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 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); }
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); }
inline int b(int offset)
{
return BRANCH(AL, 0, offset);
}
inline int bl(int offset)
{
return BRANCH(AL, 1, offset);
}
inline int bx(int Rm)
{
return BRANCHX(AL, 0, Rm);
}
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 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);
}
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 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);
}
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
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
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 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); }
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 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
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 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); }
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); }
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 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);
}
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
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
inline int fcvtsd(int Sd, int 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); }
inline int fcvtsd(int Sd, int 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
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 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); };
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 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
inline int fmsr(int Sn, int Rd) { 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); }
inline int fmsr(int Sn, int Rd)
{
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
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
inline int fmdrr(int Dm, int Rd, int Rn) { return mcrr(11, 1, Rd, Rn, Dm); }
inline int fmrrd(int Rd, int Rn, int Dm) { return mrrc(11, 1, Rd, Rn, Dm); }
inline int fmdrr(int Dm, int Rd, int Rn)
{
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
inline int SETCOND(int ins, int cond) { return ((ins&0x0fffffff) | (cond<<28)); }
inline int SETS(int ins) { return ins | 1<<20; }
inline int SETCOND(int ins, int cond)
{
return ((ins & 0x0fffffff) | (cond << 28));
}
inline int SETS(int ins)
{
return ins | 1 << 20;
}
// PSEUDO-INSTRUCTIONS
inline int lsl(int Rd, int Rm, int Rs) { return movsh(Rd, Rm, Rs, LSL); }
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); }
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 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); }
inline int lsl(int Rd, int Rm, int Rs)
{
return movsh(Rd, Rm, Rs, LSL);
}
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);
}
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 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:
inline int dmb() { return 0xf57ff05f; }
inline int dmb()
{
return 0xf57ff05f;
}
} // 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 codegen

View File

@ -20,65 +20,78 @@ using namespace util;
unsigned padding(MyBlock*, unsigned);
OffsetPromise::OffsetPromise(Context* con, MyBlock* block, unsigned offset, bool forTrace):
con(con), block(block), offset(offset), forTrace(forTrace)
{ }
OffsetPromise::OffsetPromise(Context* con,
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);
}
int64_t OffsetPromise::value() {
int64_t OffsetPromise::value()
{
assertT(con, resolved());
unsigned o = offset - block->offset;
return block->start + padding
(block, forTrace ? o - vm::TargetBytesPerWord : o) + o;
return block->start
+ padding(block, forTrace ? o - vm::TargetBytesPerWord : o) + o;
}
Promise* offsetPromise(Context* con, bool forTrace) {
return new(con->zone) OffsetPromise(con, con->lastBlock, con->code.length(), forTrace);
Promise* offsetPromise(Context* con, bool 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):
s(s),
instruction(instruction)
{ }
bool OffsetListener::resolve(int64_t value, void** location) {
bool OffsetListener::resolve(int64_t value, void** location)
{
void* p = updateOffset(s, instruction, value);
if (location) *location = p;
if (location)
*location = p;
return false;
}
OffsetTask::OffsetTask(Task* next, Promise* promise, Promise* instructionOffset)
: Task(next), promise(promise), instructionOffset(instructionOffset)
{
}
OffsetTask::OffsetTask(Task* next, Promise* promise, Promise* instructionOffset):
Task(next),
promise(promise),
instructionOffset(instructionOffset)
{ }
void OffsetTask::run(Context* con) {
void OffsetTask::run(Context* con)
{
if (promise->resolved()) {
updateOffset
(con->s, con->result + instructionOffset->value(), promise->value());
updateOffset(
con->s, con->result + instructionOffset->value(), promise->value());
} else {
new (promise->listen(sizeof(OffsetListener)))
OffsetListener(con->s, con->result + instructionOffset->value());
}
}
void appendOffsetTask(Context* con, Promise* promise, Promise* instructionOffset) {
con->tasks = new(con->zone) OffsetTask(con->tasks, promise, instructionOffset);
void appendOffsetTask(Context* con,
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;
}
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.
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;
}
ConstantPoolEntry::ConstantPoolEntry(Context* con, Promise* constant, ConstantPoolEntry* next,
Promise* callOffset):
con(con), constant(constant), next(next), callOffset(callOffset),
ConstantPoolEntry::ConstantPoolEntry(Context* con,
Promise* constant,
ConstantPoolEntry* next,
Promise* callOffset)
: con(con),
constant(constant),
next(next),
callOffset(callOffset),
address(0)
{ }
{
}
int64_t ConstantPoolEntry::value() {
int64_t ConstantPoolEntry::value()
{
assertT(con, resolved());
return reinterpret_cast<int64_t>(address);
}
bool ConstantPoolEntry::resolved() {
bool ConstantPoolEntry::resolved()
{
return address != 0;
}
ConstantPoolListener::ConstantPoolListener(vm::System* s, vm::target_uintptr_t* address,
uint8_t* returnAddress):
s(s),
address(address),
returnAddress(returnAddress)
{ }
ConstantPoolListener::ConstantPoolListener(vm::System* s,
vm::target_uintptr_t* address,
uint8_t* returnAddress)
: s(s), address(address), returnAddress(returnAddress)
{
}
bool ConstantPoolListener::resolve(int64_t value, void** location) {
bool ConstantPoolListener::resolve(int64_t value, void** location)
{
*address = value;
if (location) {
*location = returnAddress ? static_cast<void*>(returnAddress) : address;
@ -123,32 +145,49 @@ bool ConstantPoolListener::resolve(int64_t value, void** location) {
return true;
}
PoolOffset::PoolOffset(MyBlock* block, ConstantPoolEntry* entry, unsigned offset):
block(block), entry(entry), next(0), offset(offset)
{ }
PoolOffset::PoolOffset(MyBlock* block,
ConstantPoolEntry* entry,
unsigned offset)
: block(block), entry(entry), next(0), offset(offset)
{
}
PoolEvent::PoolEvent(PoolOffset* poolOffsetHead, PoolOffset* poolOffsetTail,
unsigned offset):
poolOffsetHead(poolOffsetHead), poolOffsetTail(poolOffsetTail), next(0),
PoolEvent::PoolEvent(PoolOffset* poolOffsetHead,
PoolOffset* poolOffsetTail,
unsigned offset)
: poolOffsetHead(poolOffsetHead),
poolOffsetTail(poolOffsetTail),
next(0),
offset(offset)
{ }
{
}
void appendConstantPoolEntry(Context* con, Promise* constant, Promise* callOffset) {
void appendConstantPoolEntry(Context* con,
Promise* constant,
Promise* callOffset)
{
if (constant->resolved()) {
// make a copy, since the original might be allocated on the
// 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) {
fprintf(stderr, "add pool offset %p %d to block %p\n",
o, o->offset, con->lastBlock);
fprintf(stderr,
"add pool offset %p %d to block %p\n",
o,
o->offset,
con->lastBlock);
}
if (con->lastBlock->poolOffsetTail) {
@ -159,10 +198,13 @@ void appendConstantPoolEntry(Context* con, Promise* constant, Promise* callOffse
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)
{
PoolEvent* e = new(con->zone) PoolEvent(head, tail, offset);
PoolEvent* e = new (con->zone) PoolEvent(head, tail, offset);
if (b->poolEventTail) {
b->poolEventTail->next = e;

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -25,51 +25,87 @@ class Context;
// shortcut functions
inline int newTemp(Context* con) {
inline int newTemp(Context* con)
{
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);
}
inline void freeTemp(Context* con, int r) {
inline void freeTemp(Context* con, int r)
{
con->client->releaseTemporary(r);
}
inline int64_t getValue(lir::Constant* con) {
inline int64_t getValue(lir::Constant* con)
{
return con->value->value();
}
inline lir::Register makeTemp(Context* con) {
inline lir::Register makeTemp(Context* con)
{
lir::Register tmp(newTemp(con));
return tmp;
}
inline lir::Register makeTemp64(Context* con) {
inline lir::Register makeTemp64(Context* con)
{
lir::Register tmp(newTemp(con), newTemp(con));
return 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);
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);
}
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,
unsigned dstSize, lir::Register* dst);
void moveRR(Context* con,
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);
@ -79,142 +115,297 @@ void resolve(MyBlock* b);
void jumpR(Context* con, unsigned size UNUSED, lir::Register* target);
void swapRR(Context* con, unsigned aSize, lir::Register* a,
unsigned bSize, lir::Register* b);
void swapRR(Context* con,
unsigned aSize,
lir::Register* a,
unsigned bSize,
lir::Register* b);
void moveRR(Context* con, unsigned srcSize, lir::Register* src,
unsigned dstSize, lir::Register* dst);
void moveRR(Context* con,
unsigned srcSize,
lir::Register* src,
unsigned dstSize,
lir::Register* dst);
void moveZRR(Context* con, unsigned srcSize, lir::Register* src,
unsigned, lir::Register* dst);
void moveZRR(Context* con,
unsigned srcSize,
lir::Register* src,
unsigned,
lir::Register* dst);
void moveCR(Context* con, unsigned size, lir::Constant* src,
unsigned, lir::Register* dst);
void moveCR(Context* con,
unsigned size,
lir::Constant* src,
unsigned,
lir::Register* dst);
void moveCR2(Context* con, unsigned size, lir::Constant* src,
lir::Register* dst, Promise* callOffset);
void moveCR2(Context* con,
unsigned size,
lir::Constant* src,
lir::Register* dst,
Promise* callOffset);
void moveCR(Context* con, unsigned size, lir::Constant* src,
unsigned, lir::Register* dst);
void moveCR(Context* con,
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,
lir::Register* b, lir::Register* dst);
void addC(Context* con,
unsigned size,
lir::Constant* a,
lir::Register* b,
lir::Register* dst);
void subC(Context* con, unsigned size, lir::Constant* a,
lir::Register* b, lir::Register* dst);
void subC(Context* con,
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,
bool* preserveIndex, bool* release);
int normalize(Context* con,
int offset,
int index,
unsigned scale,
bool* preserveIndex,
bool* release);
void store(Context* con, unsigned size, lir::Register* src,
int base, int offset, int index, unsigned scale, bool preserveIndex);
void store(Context* con,
unsigned size,
lir::Register* src,
int base,
int offset,
int index,
unsigned scale,
bool preserveIndex);
void moveRM(Context* con, unsigned srcSize, lir::Register* src,
unsigned dstSize UNUSED, lir::Memory* dst);
void moveRM(Context* con,
unsigned srcSize,
lir::Register* src,
unsigned dstSize UNUSED,
lir::Memory* dst);
void load(Context* con, unsigned srcSize, int base, int offset, int index,
unsigned scale, unsigned dstSize, lir::Register* dst,
bool preserveIndex, bool signExtend);
void load(Context* con,
unsigned srcSize,
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,
unsigned dstSize, lir::Register* dst);
void moveMR(Context* con,
unsigned srcSize,
lir::Memory* src,
unsigned dstSize,
lir::Register* dst);
void moveZMR(Context* con, unsigned srcSize, lir::Memory* src,
unsigned dstSize, lir::Register* dst);
void moveZMR(Context* con,
unsigned srcSize,
lir::Memory* src,
unsigned dstSize,
lir::Register* dst);
void andR(Context* con, unsigned size, lir::Register* a,
lir::Register* b, lir::Register* dst);
void andR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* dst);
void andC(Context* con, unsigned size, lir::Constant* a,
lir::Register* b, lir::Register* dst);
void andC(Context* con,
unsigned size,
lir::Constant* a,
lir::Register* b,
lir::Register* dst);
void orR(Context* con, unsigned size, lir::Register* a,
lir::Register* b, lir::Register* dst);
void orR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* dst);
void xorR(Context* con, unsigned size, lir::Register* a,
lir::Register* b, lir::Register* dst);
void xorR(Context* con,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Register* dst);
void moveAR2(Context* con, unsigned srcSize, lir::Address* src,
unsigned dstSize, lir::Register* dst);
void moveAR2(Context* con,
unsigned srcSize,
lir::Address* src,
unsigned dstSize,
lir::Register* dst);
void moveAR(Context* con, unsigned srcSize, lir::Address* src,
unsigned dstSize, lir::Register* dst);
void moveAR(Context* con,
unsigned srcSize,
lir::Address* src,
unsigned dstSize,
lir::Register* dst);
void compareRR(Context* con, unsigned aSize, lir::Register* a,
unsigned bSize UNUSED, lir::Register* b);
void compareRR(Context* con,
unsigned aSize,
lir::Register* a,
unsigned bSize UNUSED,
lir::Register* b);
void compareCR(Context* con, unsigned aSize, lir::Constant* a,
unsigned bSize, lir::Register* b);
void compareCR(Context* con,
unsigned aSize,
lir::Constant* a,
unsigned bSize,
lir::Register* b);
void compareCM(Context* con, unsigned aSize, lir::Constant* a,
unsigned bSize, lir::Memory* b);
void compareCM(Context* con,
unsigned aSize,
lir::Constant* a,
unsigned bSize,
lir::Memory* b);
void compareRM(Context* con, unsigned aSize, lir::Register* a,
unsigned bSize, lir::Memory* b);
void compareRM(Context* con,
unsigned aSize,
lir::Register* a,
unsigned bSize,
lir::Memory* b);
int32_t
branch(Context* con, lir::TernaryOperation op);
int32_t branch(Context* con, lir::TernaryOperation op);
void conditional(Context* con, int32_t branch, lir::Constant* target);
void branch(Context* con, lir::TernaryOperation op, lir::Constant* target);
void branchLong(Context* con, lir::TernaryOperation op, lir::Operand* al,
lir::Operand* ah, lir::Operand* bl,
lir::Operand* bh, lir::Constant* target,
void branchLong(Context* con,
lir::TernaryOperation op,
lir::Operand* al,
lir::Operand* ah,
lir::Operand* bl,
lir::Operand* bh,
lir::Constant* target,
BinaryOperationType compareSigned,
BinaryOperationType compareUnsigned);
void branchRR(Context* con, lir::TernaryOperation op, unsigned size,
lir::Register* a, lir::Register* b,
void branchRR(Context* con,
lir::TernaryOperation op,
unsigned size,
lir::Register* a,
lir::Register* b,
lir::Constant* target);
void branchCR(Context* con, lir::TernaryOperation op, unsigned size,
lir::Constant* a, lir::Register* b,
void branchCR(Context* con,
lir::TernaryOperation op,
unsigned size,
lir::Constant* a,
lir::Register* b,
lir::Constant* target);
void branchRM(Context* con, lir::TernaryOperation op, unsigned size,
lir::Register* a, lir::Memory* b,
void branchRM(Context* con,
lir::TernaryOperation op,
unsigned size,
lir::Register* a,
lir::Memory* b,
lir::Constant* target);
void branchCM(Context* con, lir::TernaryOperation op, unsigned size,
lir::Constant* a, lir::Memory* b,
void branchCM(Context* con,
lir::TernaryOperation op,
unsigned size,
lir::Constant* a,
lir::Memory* b,
lir::Constant* target);
ShiftMaskPromise*
shiftMaskPromise(Context* con, Promise* base, unsigned shift, int64_t mask);
ShiftMaskPromise* shiftMaskPromise(Context* con,
Promise* base,
unsigned shift,
int64_t mask);
void moveCM(Context* con, unsigned srcSize, lir::Constant* src,
unsigned dstSize, lir::Memory* dst);
void moveCM(Context* con,
unsigned srcSize,
lir::Constant* src,
unsigned dstSize,
lir::Memory* dst);
void negateRR(Context* con, unsigned srcSize, lir::Register* src,
unsigned dstSize UNUSED, lir::Register* dst);
void negateRR(Context* con,
unsigned srcSize,
lir::Register* src,
unsigned dstSize UNUSED,
lir::Register* dst);
void callR(Context* con, unsigned size UNUSED, lir::Register* target);
@ -241,4 +432,3 @@ void storeLoadBarrier(Context*);
} // namespace avian
#endif // AVIAN_CODEGEN_ASSEMBLER_ARM_OPERATIONS_H

View File

@ -18,7 +18,6 @@ namespace avian {
namespace codegen {
namespace arm {
const uint64_t MASK_LO32 = 0xffffffff;
const unsigned MASK_LO16 = 0xffff;
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 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;
}
inline int fpr64(int reg) { return reg - N_GPRS; }
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; }
inline int fpr64(int reg)
{
return reg - N_GPRS;
}
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 StackRegister = 13;

View File

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

View File

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

View File

@ -16,15 +16,23 @@ namespace avian {
namespace codegen {
namespace x86 {
unsigned
padding(AlignmentPadding* p, unsigned index, unsigned offset, AlignmentPadding* limit);
unsigned padding(AlignmentPadding* p,
unsigned index,
unsigned offset,
AlignmentPadding* limit);
MyBlock::MyBlock(unsigned offset):
next(0), firstPadding(0), lastPadding(0), offset(offset), start(~0),
MyBlock::MyBlock(unsigned offset)
: next(0),
firstPadding(0),
lastPadding(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->next = static_cast<MyBlock*>(next);

View File

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

View File

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

View File

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

View File

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

View File

@ -26,8 +26,7 @@ using namespace avian::util;
namespace {
int64_t
signExtend(unsigned size, int64_t v)
int64_t signExtend(unsigned size, int64_t v)
{
if (size == 4) {
return static_cast<int32_t>(v);
@ -46,14 +45,19 @@ namespace avian {
namespace codegen {
namespace x86 {
#define REX_W 0x48
#define REX_R 0x44
#define REX_X 0x42
#define REX_B 0x41
#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) {
uint8_t byte;
if (size == 8) {
@ -61,46 +65,60 @@ void maybeRex(Context* c, unsigned size, int a, int index, int base, bool always
} else {
byte = REX_NONE;
}
if (a != lir::NoRegister and (a & 8)) byte |= REX_R;
if (index != lir::NoRegister and (index & 8)) byte |= REX_X;
if (base != lir::NoRegister and (base & 8)) byte |= REX_B;
if (always or byte != REX_NONE) c->code.append(byte);
if (a != lir::NoRegister and (a & 8))
byte |= REX_R;
if (index != lir::NoRegister and (index & 8))
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);
}
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);
}
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);
}
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));
}
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);
}
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));
}
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);
}
void sib(Context* c, unsigned scale, int index, int base) {
c->code.append((util::log(scale) << 6) | (regCode(index) << 3) | regCode(base));
void sib(Context* c, unsigned scale, int index, int 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) {
modrm(c, width, base, a);
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) {
modrmSib(c, 0x00, a, scale, index, base);
} 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);
}
void opcode(Context* c, uint8_t op) {
void opcode(Context* c, uint8_t 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(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);
opcode(c, jump);
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);
opcode(c, 0x0f, condition);
c->code.append4(0);
}
void sseMoveRR(Context* c, unsigned aSize, lir::Register* a,
unsigned bSize UNUSED, lir::Register* b)
void sseMoveRR(Context* c,
unsigned aSize,
lir::Register* a,
unsigned bSize UNUSED,
lir::Register* b)
{
assertT(c, aSize >= 4);
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,
unsigned bSize, lir::Register* b)
void sseMoveCR(Context* c,
unsigned aSize,
lir::Constant* a,
unsigned bSize,
lir::Register* b)
{
assertT(c, aSize <= vm::TargetBytesPerWord);
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);
}
void sseMoveMR(Context* c, unsigned aSize, lir::Memory* a,
unsigned bSize UNUSED, lir::Register* b)
void sseMoveMR(Context* c,
unsigned aSize,
lir::Memory* a,
unsigned bSize UNUSED,
lir::Register* b)
{
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,
UNUSED unsigned bSize, lir::Memory* b)
void sseMoveRM(Context* c,
unsigned aSize,
lir::Register* a,
UNUSED unsigned bSize,
lir::Memory* b)
{
assertT(c, aSize >= 4);
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) {
case lir::JumpIfEqual:
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) {
case lir::JumpIfFloatEqual:
// 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,
lir::Register* b, uint8_t op, uint8_t mod)
void floatRegOp(Context* c,
unsigned aSize,
lir::Register* a,
unsigned bSize,
lir::Register* b,
uint8_t op,
uint8_t mod)
{
if (aSize == 4) {
opcode(c, 0xf3);
@ -326,8 +369,12 @@ void floatRegOp(Context* c, unsigned aSize, lir::Register* a, unsigned bSize,
modrm(c, mod, a, b);
}
void floatMemOp(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize,
lir::Register* b, uint8_t op)
void floatMemOp(Context* c,
unsigned aSize,
lir::Memory* a,
unsigned bSize,
lir::Register* b,
uint8_t op)
{
if (aSize == 4) {
opcode(c, 0xf3);
@ -339,11 +386,18 @@ void floatMemOp(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize,
modrmSibImm(c, b, a);
}
void moveCR(Context* c, unsigned aSize, lir::Constant* a,
unsigned bSize, lir::Register* b);
void moveCR(Context* c,
unsigned aSize,
lir::Constant* a,
unsigned bSize,
lir::Register* b);
void moveCR2(Context* c, UNUSED unsigned aSize, lir::Constant* a,
UNUSED unsigned bSize, lir::Register* b, unsigned promiseOffset)
void moveCR2(Context* c,
UNUSED unsigned aSize,
lir::Constant* a,
UNUSED unsigned bSize,
lir::Register* b,
unsigned promiseOffset)
{
if (vm::TargetBytesPerWord == 4 and bSize == 8) {
int64_t v = signExtend(aSize, a->value->value());
@ -366,8 +420,8 @@ void moveCR2(Context* c, UNUSED unsigned aSize, lir::Constant* a,
} else {
expect(c, aSize == vm::TargetBytesPerWord);
appendImmediateTask
(c, a->value, offsetPromise(c), vm::TargetBytesPerWord, promiseOffset);
appendImmediateTask(
c, a->value, offsetPromise(c), vm::TargetBytesPerWord, promiseOffset);
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