mirror of
https://github.com/corda/corda.git
synced 2025-01-22 12:28:11 +00:00
Merge branch 'master' of oss.readytalk.com:/var/local/git/avian
This commit is contained in:
commit
f5490b800a
@ -266,7 +266,7 @@ doAccept(JNIEnv* e, int s)
|
||||
int r = ::accept(s, &address, &length);
|
||||
if (r >= 0) {
|
||||
return r;
|
||||
} else {
|
||||
} else if (errno != EINTR) {
|
||||
throwIOException(e);
|
||||
}
|
||||
return -1;
|
||||
|
@ -47,7 +47,14 @@ public class ServerSocketChannel extends SelectableChannel {
|
||||
}
|
||||
|
||||
private int doAccept() throws IOException {
|
||||
return natDoAccept(channel.socket);
|
||||
while (true) {
|
||||
int s = natDoAccept(channel.socket);
|
||||
if (s != -1) {
|
||||
return s;
|
||||
}
|
||||
// todo: throw ClosedByInterruptException if this thread was
|
||||
// interrupted during the accept call
|
||||
}
|
||||
}
|
||||
|
||||
private int doListen(String host, int port) throws IOException {
|
||||
|
@ -38,8 +38,6 @@ public class ArrayList<T> extends AbstractList<T> {
|
||||
private void shrink() {
|
||||
if (array.length / 2 >= MinimumCapacity && size <= array.length / 3) {
|
||||
resize(array.length / 2);
|
||||
} else if (size == 0) {
|
||||
resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,6 @@ public class HashMap<K, V> implements Map<K, V> {
|
||||
private void shrink() {
|
||||
if (array.length / 2 >= MinimumCapacity && size <= array.length / 3) {
|
||||
resize(array.length / 2);
|
||||
} else if (size == 0) {
|
||||
resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
9
makefile
9
makefile
@ -101,7 +101,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
|
||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
|
||||
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(native-build) \
|
||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||
$(gnu-cflags)
|
||||
-DUSE_ATOMIC_OPERATIONS $(gnu-cflags)
|
||||
|
||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
||||
@ -240,6 +240,13 @@ ifeq ($(mode),small)
|
||||
cflags += -Os -g3 -DNDEBUG
|
||||
endif
|
||||
|
||||
ifneq ($(platform),darwin)
|
||||
ifeq ($(arch),i386)
|
||||
# this is necessary to support __sync_bool_compare_and_swap:
|
||||
cflags += -march=i486
|
||||
endif
|
||||
endif
|
||||
|
||||
output = -o $(1)
|
||||
as := $(cc)
|
||||
ld := $(cc)
|
||||
|
@ -14,7 +14,11 @@
|
||||
#include "string.h"
|
||||
|
||||
#include "sys/stat.h"
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include "sys/mman.h"
|
||||
#endif
|
||||
#include "fcntl.h"
|
||||
#include "unistd.h"
|
||||
|
||||
@ -152,8 +156,29 @@ main(int argc, const char** argv)
|
||||
struct stat s;
|
||||
int r = fstat(fd, &s);
|
||||
if (r != -1) {
|
||||
#ifdef WIN32
|
||||
HANDLE fm;
|
||||
HANDLE h = (HANDLE) _get_osfhandle (fd);
|
||||
|
||||
fm = CreateFileMapping(
|
||||
h,
|
||||
NULL,
|
||||
PAGE_READONLY,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
data = static_cast<uint8_t*>(MapViewOfFile(
|
||||
fm,
|
||||
FILE_MAP_READ,
|
||||
0,
|
||||
0,
|
||||
s.st_size));
|
||||
|
||||
CloseHandle(fm);
|
||||
#else
|
||||
data = static_cast<uint8_t*>
|
||||
(mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
|
||||
#endif
|
||||
size = s.st_size;
|
||||
}
|
||||
close(fd);
|
||||
@ -173,7 +198,11 @@ main(int argc, const char** argv)
|
||||
fprintf(stderr, "unable to open %s\n", argv[2]);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
UnmapViewOfFile(data);
|
||||
#else
|
||||
munmap(data, size);
|
||||
#endif
|
||||
} else {
|
||||
perror(argv[0]);
|
||||
}
|
||||
|
@ -7260,7 +7260,7 @@ class MyProcessor: public Processor {
|
||||
class Visitor: public System::ThreadVisitor {
|
||||
public:
|
||||
Visitor(MyThread* t, MyProcessor* p, MyThread* target):
|
||||
t(t), p(p), target(target)
|
||||
t(t), p(p), target(target), trace(0)
|
||||
{ }
|
||||
|
||||
virtual void visit(void* ip, void* base, void* stack) {
|
||||
|
104
src/heap.cpp
104
src/heap.cpp
@ -11,6 +11,7 @@
|
||||
#include "heap.h"
|
||||
#include "system.h"
|
||||
#include "common.h"
|
||||
#include "arch.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -69,6 +70,16 @@ System* system(Context*);
|
||||
void* tryAllocate(Context* c, unsigned size);
|
||||
void free(Context* c, const void* p, unsigned size);
|
||||
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
inline void
|
||||
markBitAtomic(uintptr_t* map, unsigned i)
|
||||
{
|
||||
uintptr_t* p = map + wordOf(i);
|
||||
uintptr_t v = static_cast<uintptr_t>(1) << bitOf(i);
|
||||
while (not atomicCompareAndSwap(p, *p, *p | v)) { }
|
||||
}
|
||||
#endif // USE_ATOMIC_OPERATIONS
|
||||
|
||||
inline void*
|
||||
get(void* o, unsigned offsetInWords)
|
||||
{
|
||||
@ -303,6 +314,15 @@ class Segment {
|
||||
if (child) child->set(p, v);
|
||||
}
|
||||
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
void markAtomic(void* p) {
|
||||
assert(segment->context, bitsPerRecord == 1);
|
||||
markBitAtomic(data, indexOf(p));
|
||||
assert(segment->context, getBit(data, indexOf(p)));
|
||||
if (child) child->markAtomic(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned get(void* p) {
|
||||
return getBits(data, bitsPerRecord, indexOf(p));
|
||||
}
|
||||
@ -1013,8 +1033,14 @@ void
|
||||
markDirty(Context* c, Fixie* f)
|
||||
{
|
||||
if (not f->dirty) {
|
||||
f->dirty = true;
|
||||
f->move(c, &(c->dirtyTenuredFixies));
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
ACQUIRE(c->lock);
|
||||
#endif
|
||||
|
||||
if (not f->dirty) {
|
||||
f->dirty = true;
|
||||
f->move(c, &(c->dirtyTenuredFixies));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1784,7 +1810,7 @@ class MyHeap: public Heap {
|
||||
Fixie(&c, sizeInWords, objectMask, 0, true))->body();
|
||||
}
|
||||
|
||||
virtual bool needsMark(void* p) {
|
||||
bool needsMark(void* p) {
|
||||
assert(&c, c.client->isFixed(p) or (not immortalHeapContains(&c, p)));
|
||||
|
||||
if (c.client->isFixed(p)) {
|
||||
@ -1794,11 +1820,6 @@ class MyHeap: public Heap {
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool needsMark(void* p, unsigned offset) {
|
||||
return needsMark(p) and targetNeedsMark
|
||||
(mask(*(static_cast<void**>(p) + offset)));
|
||||
}
|
||||
|
||||
bool targetNeedsMark(void* target) {
|
||||
return target
|
||||
and not c.gen2.contains(target)
|
||||
@ -1809,38 +1830,53 @@ class MyHeap: public Heap {
|
||||
}
|
||||
|
||||
virtual void mark(void* p, unsigned offset, unsigned count) {
|
||||
if (c.client->isFixed(p)) {
|
||||
Fixie* f = fixie(p);
|
||||
assert(&c, offset == 0 or f->hasMask);
|
||||
if (needsMark(p)) {
|
||||
#ifndef USE_ATOMIC_OPERATIONS
|
||||
ACQUIRE(c.lock);
|
||||
#endif
|
||||
|
||||
bool dirty = false;
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
void** target = static_cast<void**>(p) + offset + i;
|
||||
if (targetNeedsMark(mask(*target))) {
|
||||
if (DebugFixies) {
|
||||
fprintf(stderr, "dirty fixie %p at %d (%p): %p\n",
|
||||
f, offset, f->body() + offset, mask(*target));
|
||||
if (c.client->isFixed(p)) {
|
||||
Fixie* f = fixie(p);
|
||||
assert(&c, offset == 0 or f->hasMask);
|
||||
|
||||
bool dirty = false;
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
void** target = static_cast<void**>(p) + offset + i;
|
||||
if (targetNeedsMark(mask(*target))) {
|
||||
if (DebugFixies) {
|
||||
fprintf(stderr, "dirty fixie %p at %d (%p): %p\n",
|
||||
f, offset, f->body() + offset, mask(*target));
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
markBitAtomic(f->mask(), offset + i);
|
||||
#else
|
||||
markBit(f->mask(), offset + i);
|
||||
#endif
|
||||
assert(&c, getBit(f->mask(), offset + i));
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
markBit(f->mask(), offset + i);
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty) markDirty(&c, f);
|
||||
} else {
|
||||
Segment::Map* map;
|
||||
if (c.gen2.contains(p)) {
|
||||
map = &(c.heapMap);
|
||||
if (dirty) markDirty(&c, f);
|
||||
} else {
|
||||
assert(&c, c.nextGen2.contains(p));
|
||||
map = &(c.nextHeapMap);
|
||||
}
|
||||
Segment::Map* map;
|
||||
if (c.gen2.contains(p)) {
|
||||
map = &(c.heapMap);
|
||||
} else {
|
||||
assert(&c, c.nextGen2.contains(p));
|
||||
map = &(c.nextHeapMap);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
void** target = static_cast<void**>(p) + offset + i;
|
||||
if (targetNeedsMark(mask(*target))) {
|
||||
map->set(target);
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
void** target = static_cast<void**>(p) + offset + i;
|
||||
if (targetNeedsMark(mask(*target))) {
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
map->markAtomic(target);
|
||||
#else
|
||||
map->set(target);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +59,6 @@ class Heap: public Allocator {
|
||||
virtual void* allocateImmortalFixed(Allocator* allocator,
|
||||
unsigned sizeInWords, bool objectMask,
|
||||
unsigned* totalInBytes) = 0;
|
||||
virtual bool needsMark(void* p) = 0;
|
||||
virtual bool needsMark(void* p, unsigned offset) = 0;
|
||||
virtual void mark(void* p, unsigned offset, unsigned count) = 0;
|
||||
virtual void pad(void* p) = 0;
|
||||
virtual void* follow(void* p) = 0;
|
||||
|
@ -195,6 +195,8 @@ GetArrayLength(Thread* t, jarray array)
|
||||
jstring JNICALL
|
||||
NewString(Thread* t, const jchar* chars, jsize size)
|
||||
{
|
||||
if (chars == 0) return 0;
|
||||
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
object a = 0;
|
||||
@ -210,6 +212,8 @@ NewString(Thread* t, const jchar* chars, jsize size)
|
||||
jstring JNICALL
|
||||
NewStringUTF(Thread* t, const char* chars)
|
||||
{
|
||||
if (chars == 0) return 0;
|
||||
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
object a = 0;
|
||||
|
@ -1584,19 +1584,13 @@ allocate(Thread* t, unsigned sizeInBytes, bool objectMask)
|
||||
inline void
|
||||
mark(Thread* t, object o, unsigned offset, unsigned count)
|
||||
{
|
||||
if (t->m->heap->needsMark(o)) {
|
||||
ACQUIRE_RAW(t, t->m->heapLock);
|
||||
t->m->heap->mark(o, offset / BytesPerWord, count);
|
||||
}
|
||||
t->m->heap->mark(o, offset / BytesPerWord, count);
|
||||
}
|
||||
|
||||
inline void
|
||||
mark(Thread* t, object o, unsigned offset)
|
||||
{
|
||||
if (t->m->heap->needsMark(o, offset / BytesPerWord)) {
|
||||
ACQUIRE_RAW(t, t->m->heapLock);
|
||||
t->m->heap->mark(o, offset / BytesPerWord, 1);
|
||||
}
|
||||
t->m->heap->mark(o, offset / BytesPerWord, 1);
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -90,6 +90,36 @@ syncInstructionCache(const void* start, unsigned size)
|
||||
__asm__ __volatile__("isync");
|
||||
}
|
||||
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
inline bool
|
||||
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
|
||||
{
|
||||
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
||||
return __sync_bool_compare_and_swap(p, old, new_);
|
||||
#else // not GCC >= 4.1
|
||||
bool result;
|
||||
|
||||
__asm__ __volatile__(" sync\n"
|
||||
"1:\n"
|
||||
" lwarx %0,0,%2\n"
|
||||
" cmpw %0,%3\n"
|
||||
" bne- 2f\n"
|
||||
" stwcx. %4,0,%2\n"
|
||||
" bne- 1b\n"
|
||||
" isync \n"
|
||||
"2:\n"
|
||||
" xor %0,%0,%3\n"
|
||||
" cntlzw %0,%0\n"
|
||||
" srwi %0,%0,5\n"
|
||||
: "=&r"(result), "+m"(*p)
|
||||
: "r"(p), "r"(old), "r"(new_)
|
||||
: "cc", "memory");
|
||||
|
||||
return result;
|
||||
#endif // not GCC >= 4.1
|
||||
}
|
||||
#endif // USE_ATOMIC_OPERATIONS
|
||||
|
||||
inline uint64_t
|
||||
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
unsigned argumentCount, unsigned argumentsSize,
|
||||
|
@ -616,26 +616,32 @@ class MySystem: public System {
|
||||
|
||||
ACQUIRE(this, mutex);
|
||||
|
||||
bool success = false;
|
||||
int rv = SuspendThread(target->thread);
|
||||
expect(this, rv != -1);
|
||||
if (rv != -1) {
|
||||
CONTEXT context;
|
||||
memset(&context, 0, sizeof(CONTEXT));
|
||||
context.ContextFlags = CONTEXT_CONTROL;
|
||||
rv = GetThreadContext(target->thread, &context);
|
||||
|
||||
CONTEXT context;
|
||||
rv = GetThreadContext(target->thread, &context);
|
||||
expect(this, rv);
|
||||
if (rv) {
|
||||
#ifdef ARCH_x86_32
|
||||
visitor->visit(reinterpret_cast<void*>(context.Eip),
|
||||
reinterpret_cast<void*>(context.Ebp),
|
||||
reinterpret_cast<void*>(context.Esp));
|
||||
visitor->visit(reinterpret_cast<void*>(context.Eip),
|
||||
reinterpret_cast<void*>(context.Ebp),
|
||||
reinterpret_cast<void*>(context.Esp));
|
||||
#elif defined ARCH_x86_64
|
||||
visitor->visit(reinterpret_cast<void*>(context.Rip),
|
||||
reinterpret_cast<void*>(context.Rbp),
|
||||
reinterpret_cast<void*>(context.Rsp));
|
||||
visitor->visit(reinterpret_cast<void*>(context.Rip),
|
||||
reinterpret_cast<void*>(context.Rbp),
|
||||
reinterpret_cast<void*>(context.Rsp));
|
||||
#endif
|
||||
success = true;
|
||||
}
|
||||
|
||||
rv = ResumeThread(target->thread);
|
||||
expect(this, rv != -1);
|
||||
rv = ResumeThread(target->thread);
|
||||
expect(this, rv != -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (success ? 0 : 1);
|
||||
}
|
||||
|
||||
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
|
||||
|
34
src/x86.h
34
src/x86.h
@ -188,6 +188,40 @@ syncInstructionCache(const void*, unsigned)
|
||||
// ignore
|
||||
}
|
||||
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
inline bool
|
||||
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
# ifdef ARCH_x86_32
|
||||
InterlockedCompareExchange(p, new_, old);
|
||||
# elif defined ARCH_x86_64
|
||||
InterlockedCompareExchange64(p, new_, old);
|
||||
# endif // ARCH_x86_64
|
||||
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
||||
return __sync_bool_compare_and_swap(p, old, new_);
|
||||
#elif defined ARCH_x86_32
|
||||
uint8_t result;
|
||||
|
||||
__asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
|
||||
: "=m"(*p), "=q"(result)
|
||||
: "r"(new_), "a"(old), "m"(*p)
|
||||
: "memory");
|
||||
|
||||
return result != 0;
|
||||
#elif defined ARCH_x86_64
|
||||
uint8_t result;
|
||||
|
||||
__asm__ __volatile__("lock; cmpxchgq %2, %0; setz %1"
|
||||
: "=m"(*p), "=q"(result)
|
||||
: "r"(new_), "a"(old), "m"(*p)
|
||||
: "memory");
|
||||
|
||||
return result != 0;
|
||||
#endif // ARCH_x86_64
|
||||
}
|
||||
#endif // USE_ATOMIC_OPERATIONS
|
||||
|
||||
} // namespace vm
|
||||
|
||||
#endif//X86_H
|
||||
|
Loading…
Reference in New Issue
Block a user