mirror of
https://github.com/corda/corda.git
synced 2025-06-01 23:20:54 +00:00
fix many JIT GC bugs; GC.java now passes
This commit is contained in:
parent
f58c6ef4e8
commit
5c99edd90e
2
makefile
2
makefile
@ -34,7 +34,7 @@ src = src
|
|||||||
classpath = classpath
|
classpath = classpath
|
||||||
test = test
|
test = test
|
||||||
|
|
||||||
input = $(cls)/Exceptions.class
|
input = $(cls)/GC.class
|
||||||
|
|
||||||
cxx = g++
|
cxx = g++
|
||||||
cc = gcc
|
cc = gcc
|
||||||
|
520
src/compile.cpp
520
src/compile.cpp
@ -146,7 +146,8 @@ class StackMapper {
|
|||||||
PopLong,
|
PopLong,
|
||||||
PopInt,
|
PopInt,
|
||||||
PopObject,
|
PopObject,
|
||||||
PopIntOrObject,
|
StoreLong,
|
||||||
|
StoreInt,
|
||||||
StoreObject,
|
StoreObject,
|
||||||
Return,
|
Return,
|
||||||
Jump,
|
Jump,
|
||||||
@ -161,7 +162,8 @@ class StackMapper {
|
|||||||
index(codeSize() ? static_cast<uint32_t*>
|
index(codeSize() ? static_cast<uint32_t*>
|
||||||
(t->m->system->allocate(codeSize() * 4)) : 0),
|
(t->m->system->allocate(codeSize() * 4)) : 0),
|
||||||
log(t->m->system, 1024),
|
log(t->m->system, 1024),
|
||||||
callCount(0)
|
callCount(0),
|
||||||
|
protector(this)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~StackMapper() {
|
~StackMapper() {
|
||||||
@ -232,13 +234,25 @@ class StackMapper {
|
|||||||
log.append(PopObject);
|
log.append(PopObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void poppedIntOrObject() {
|
void storedLong(unsigned index) {
|
||||||
log.append(PopIntOrObject);
|
if (index >= parameterFootprint()) {
|
||||||
|
log.append(StoreLong);
|
||||||
|
log.append2(index - parameterFootprint());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void storedInt(unsigned index) {
|
||||||
|
if (index >= parameterFootprint()) {
|
||||||
|
log.append(StoreInt);
|
||||||
|
log.append2(index - parameterFootprint());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void storedObject(unsigned index) {
|
void storedObject(unsigned index) {
|
||||||
log.append(StoreObject);
|
if (index >= parameterFootprint()) {
|
||||||
log.append2(index - parameterFootprint());
|
log.append(StoreObject);
|
||||||
|
log.append2(index - parameterFootprint());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void exited() {
|
void exited() {
|
||||||
@ -311,6 +325,16 @@ class StackMapper {
|
|||||||
memcpy(calls + (callIndex * (mapSizeInWords() + 1)) + 1,
|
memcpy(calls + (callIndex * (mapSizeInWords() + 1)) + 1,
|
||||||
map, mapSizeInBytes());
|
map, mapSizeInBytes());
|
||||||
++ callIndex;
|
++ callIndex;
|
||||||
|
|
||||||
|
// fprintf(stderr,
|
||||||
|
// "call stack and locals 0x%x of size %d at %d of %s.%s\n",
|
||||||
|
// *map,
|
||||||
|
// mapSize(),
|
||||||
|
// machineIp,
|
||||||
|
// &byteArrayBody
|
||||||
|
// (t, className(t, methodClass(t, method)), 0),
|
||||||
|
// &byteArrayBody(t, methodName(t, method), 0));
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case PushLong:
|
case PushLong:
|
||||||
@ -372,11 +396,18 @@ class StackMapper {
|
|||||||
clearBit(map, -- sp);
|
clearBit(map, -- sp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PopIntOrObject:
|
case StoreLong: {
|
||||||
assert(t, sp >= 1);
|
unsigned index = log.get2(i); i += 2;
|
||||||
assert(t, sp - 1 >= localSize());
|
assert(t, index + 1 < localSize());
|
||||||
clearBit(map, -- sp);
|
clearBit(map, index);
|
||||||
break;
|
clearBit(map, index + 1);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case StoreInt: {
|
||||||
|
unsigned index = log.get2(i); i += 2;
|
||||||
|
assert(t, index < localSize());
|
||||||
|
clearBit(map, index);
|
||||||
|
} break;
|
||||||
|
|
||||||
case StoreObject: {
|
case StoreObject: {
|
||||||
unsigned index = log.get2(i); i += 2;
|
unsigned index = log.get2(i); i += 2;
|
||||||
@ -429,7 +460,7 @@ class StackMapper {
|
|||||||
memset(mask, 0, ceiling(codeSize(), BytesPerWord) * BytesPerWord);
|
memset(mask, 0, ceiling(codeSize(), BytesPerWord) * BytesPerWord);
|
||||||
|
|
||||||
uintptr_t map[mapSizeInWords()];
|
uintptr_t map[mapSizeInWords()];
|
||||||
memset(map, 0, mapSizeInWords());
|
memset(map, 0, mapSizeInBytes());
|
||||||
|
|
||||||
unsigned callIndex = 0;
|
unsigned callIndex = 0;
|
||||||
|
|
||||||
@ -472,6 +503,17 @@ class StackMapper {
|
|||||||
uint32_t* index;
|
uint32_t* index;
|
||||||
Buffer log;
|
Buffer log;
|
||||||
unsigned callCount;
|
unsigned callCount;
|
||||||
|
|
||||||
|
class MyProtector: public Thread::Protector {
|
||||||
|
public:
|
||||||
|
MyProtector(StackMapper* mapper): Protector(mapper->t), mapper(mapper) { }
|
||||||
|
|
||||||
|
virtual void visit(Heap::Visitor* v) {
|
||||||
|
v->visit(&(mapper->method));
|
||||||
|
}
|
||||||
|
|
||||||
|
StackMapper* mapper;
|
||||||
|
} protector;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyThread: public Thread {
|
class MyThread: public Thread {
|
||||||
@ -641,8 +683,8 @@ makeCompiled(Thread* t, object method, Buffer* code,
|
|||||||
* sizeof(NativeExceptionHandler))
|
* sizeof(NativeExceptionHandler))
|
||||||
+ pad(stackMapper->callTableSize())));
|
+ pad(stackMapper->callTableSize())));
|
||||||
|
|
||||||
compiledMaxLocals(c) = maxStack;
|
compiledMaxLocals(c) = maxLocals;
|
||||||
compiledMaxStack(c) = maxLocals;
|
compiledMaxStack(c) = maxStack;
|
||||||
compiledParameterFootprint(c) = parameterFootprint;
|
compiledParameterFootprint(c) = parameterFootprint;
|
||||||
compiledCodeLength(c) = code->length();
|
compiledCodeLength(c) = code->length();
|
||||||
|
|
||||||
@ -881,14 +923,27 @@ visitStackAndLocals(MyThread* t, Heap::Visitor* v, void* frame)
|
|||||||
Compiled* code = reinterpret_cast<Compiled*>
|
Compiled* code = reinterpret_cast<Compiled*>
|
||||||
(methodCompiled(t, frameMethod(frame)));
|
(methodCompiled(t, frameMethod(frame)));
|
||||||
|
|
||||||
unsigned stack = compiledMaxStack(code);
|
unsigned parameterFootprint = compiledParameterFootprint(code);
|
||||||
unsigned parameters = compiledParameterFootprint(code);
|
unsigned count = compiledMaxStack(code)
|
||||||
unsigned locals = compiledMaxLocals(code);
|
+ compiledMaxLocals(code)
|
||||||
|
- parameterFootprint;
|
||||||
|
|
||||||
uintptr_t* stackMap = frameStackMap(t, frame);
|
if (count) {
|
||||||
for (unsigned i = parameters; i < stack + locals; ++i) {
|
uintptr_t* stackMap = frameStackMap(t, frame);
|
||||||
if (getBit(stackMap, i)) {
|
|
||||||
v->visit(frameLocalObject(t, frame, i));
|
// fprintf(stderr, "visit stack and locals 0x%x of size %d, at %d of %s.%s\n",
|
||||||
|
// *stackMap,
|
||||||
|
// count,
|
||||||
|
// static_cast<uint8_t*>(frameAddress(frame))
|
||||||
|
// - compiledCode(code),
|
||||||
|
// &byteArrayBody
|
||||||
|
// (t, className(t, methodClass(t, frameMethod(frame))), 0),
|
||||||
|
// &byteArrayBody(t, methodName(t, frameMethod(frame)), 0));
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
|
if (getBit(stackMap, i)) {
|
||||||
|
v->visit(frameLocalObject(t, frame, i + parameterFootprint));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -896,6 +951,10 @@ visitStackAndLocals(MyThread* t, Heap::Visitor* v, void* frame)
|
|||||||
void
|
void
|
||||||
visitStack(MyThread* t, Heap::Visitor* v)
|
visitStack(MyThread* t, Heap::Visitor* v)
|
||||||
{
|
{
|
||||||
|
if (frameValid(t->frame)) {
|
||||||
|
v->visit(&frameMethod(t->frame));
|
||||||
|
}
|
||||||
|
|
||||||
for (void* f = t->frame; frameValid(f); f = frameNext(f)) {
|
for (void* f = t->frame; frameValid(f); f = frameNext(f)) {
|
||||||
// we only need to visit the parameters of this method if the
|
// we only need to visit the parameters of this method if the
|
||||||
// caller is native. Otherwise, the caller owns them.
|
// caller is native. Otherwise, the caller owns them.
|
||||||
@ -910,8 +969,6 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
|||||||
visitParameters(t, v, f);
|
visitParameters(t, v, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
v->visit(&frameMethod(f));
|
|
||||||
|
|
||||||
object method = frameMethod(f);
|
object method = frameMethod(f);
|
||||||
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
|
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
|
||||||
|
|
||||||
@ -1853,7 +1910,7 @@ class JavaCompiler: public Compiler {
|
|||||||
stackMapper.pushedObject();
|
stackMapper.pushedObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushLong(uint64_t v) {
|
void pushLongQuiet(uint64_t v) {
|
||||||
if (BytesPerWord == 8) {
|
if (BytesPerWord == 8) {
|
||||||
pushAddress(v);
|
pushAddress(v);
|
||||||
sub(8, rsp);
|
sub(8, rsp);
|
||||||
@ -1861,6 +1918,10 @@ class JavaCompiler: public Compiler {
|
|||||||
push((v >> 32) & 0xFFFFFFFF);
|
push((v >> 32) & 0xFFFFFFFF);
|
||||||
push((v ) & 0xFFFFFFFF);
|
push((v ) & 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushLong(uint64_t v) {
|
||||||
|
pushLongQuiet(v);
|
||||||
stackMapper.pushedLong();
|
stackMapper.pushedLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1871,10 +1932,14 @@ class JavaCompiler: public Compiler {
|
|||||||
stackMapper.pushedLong();
|
stackMapper.pushedLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushLong(Register r, int32_t offset) {
|
void pushLongQuiet(Register r, int32_t offset) {
|
||||||
assert(t, BytesPerWord == 8);
|
assert(t, BytesPerWord == 8);
|
||||||
push(r, offset);
|
push(r, offset);
|
||||||
sub(8, rsp);
|
sub(8, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushLong(Register r, int32_t offset) {
|
||||||
|
pushLongQuiet(r, offset);
|
||||||
stackMapper.pushedLong();
|
stackMapper.pushedLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1885,12 +1950,18 @@ class JavaCompiler: public Compiler {
|
|||||||
stackMapper.pushedLong();
|
stackMapper.pushedLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushLong(Register low, int32_t lowOffset,
|
void pushLongQuiet(Register low, int32_t lowOffset,
|
||||||
Register high, int32_t highOffset)
|
Register high, int32_t highOffset)
|
||||||
{
|
{
|
||||||
assert(t, BytesPerWord == 4);
|
assert(t, BytesPerWord == 4);
|
||||||
push(high, highOffset);
|
push(high, highOffset);
|
||||||
push(low, lowOffset);
|
push(low, lowOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushLong(Register low, int32_t lowOffset,
|
||||||
|
Register high, int32_t highOffset)
|
||||||
|
{
|
||||||
|
pushLongQuiet(low, lowOffset, high, highOffset);
|
||||||
stackMapper.pushedLong();
|
stackMapper.pushedLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1973,6 +2044,7 @@ class JavaCompiler: public Compiler {
|
|||||||
|
|
||||||
void storeInt(unsigned index) {
|
void storeInt(unsigned index) {
|
||||||
popInt(rbp, localOffset(t, index, method));
|
popInt(rbp, localOffset(t, index, method));
|
||||||
|
stackMapper.storedInt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void storeObject(unsigned index) {
|
void storeObject(unsigned index) {
|
||||||
@ -1987,6 +2059,7 @@ class JavaCompiler: public Compiler {
|
|||||||
popLong(rbp, localOffset(t, index, method),
|
popLong(rbp, localOffset(t, index, method),
|
||||||
rbp, localOffset(t, index + 1, method));
|
rbp, localOffset(t, index + 1, method));
|
||||||
}
|
}
|
||||||
|
stackMapper.storedLong(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushReturnValue(unsigned code) {
|
void pushReturnValue(unsigned code) {
|
||||||
@ -2033,86 +2106,128 @@ class JavaCompiler: public Compiler {
|
|||||||
|
|
||||||
callAlignedAddress(compiledCode(code));
|
callAlignedAddress(compiledCode(code));
|
||||||
|
|
||||||
|
stackMapper.called(this->code.length());
|
||||||
|
poolRegisterClobbered = true;
|
||||||
|
|
||||||
add(footprint, rsp); // pop arguments
|
add(footprint, rsp); // pop arguments
|
||||||
stackMapper.popped(methodParameterFootprint(t, target));
|
stackMapper.popped(methodParameterFootprint(t, target));
|
||||||
|
|
||||||
pushReturnValue(methodReturnCode(t, target));
|
pushReturnValue(methodReturnCode(t, target));
|
||||||
}
|
}
|
||||||
|
|
||||||
void compileCall2(void* function, unsigned argCount) {
|
void compileThrowNew(Machine::Type type) {
|
||||||
if (BytesPerWord == 4) {
|
object class_ = arrayBody(t, t->m->types, type);
|
||||||
push(rbp, FrameThread);
|
|
||||||
} else {
|
if (BytesPerWord == 8) {
|
||||||
|
mov(poolRegister(), poolReference(class_), rsi);
|
||||||
mov(rbp, FrameThread, rdi);
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(poolRegister(), poolReference(class_));
|
||||||
|
push(rbp, FrameThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
mov(reinterpret_cast<uintptr_t>(function), rbx);
|
indirectCall(reinterpret_cast<void*>(throwNew));
|
||||||
|
}
|
||||||
|
|
||||||
|
void directCall(void* function) {
|
||||||
|
callAddress(function);
|
||||||
|
|
||||||
|
poolRegisterClobbered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void indirectCall(void* function) {
|
||||||
|
mov(reinterpret_cast<uintptr_t>(function), rbx);
|
||||||
callAddress(compiledCode(caller(t)));
|
callAddress(compiledCode(caller(t)));
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
stackMapper.called(code.length());
|
||||||
add(BytesPerWord * argCount, rsp);
|
poolRegisterClobbered = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void compileCall(void* function) {
|
void compileCall(bool direct, void* function, Register arg1, Register arg2) {
|
||||||
compileCall2(function, 1);
|
if (BytesPerWord == 8) {
|
||||||
}
|
|
||||||
|
|
||||||
void compileCall(void* function, object arg1) {
|
|
||||||
if (BytesPerWord == 4) {
|
|
||||||
push(poolRegister(), poolReference(arg1));
|
|
||||||
} else {
|
|
||||||
mov(poolRegister(), poolReference(arg1), rsi);
|
|
||||||
}
|
|
||||||
|
|
||||||
compileCall2(function, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void compileCall(void* function, Register arg1) {
|
|
||||||
if (BytesPerWord == 4) {
|
|
||||||
push(arg1);
|
|
||||||
} else {
|
|
||||||
mov(arg1, rsi);
|
|
||||||
}
|
|
||||||
|
|
||||||
compileCall2(function, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void compileCall(void* function, object arg1, Register arg2) {
|
|
||||||
if (BytesPerWord == 4) {
|
|
||||||
push(arg2);
|
|
||||||
push(poolRegister(), poolReference(arg1));
|
|
||||||
} else {
|
|
||||||
mov(arg2, rdx);
|
|
||||||
mov(poolRegister(), poolReference(arg1), rsi);
|
|
||||||
}
|
|
||||||
|
|
||||||
compileCall2(function, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void compileCall(void* function, void* arg1, Register arg2) {
|
|
||||||
if (BytesPerWord == 4) {
|
|
||||||
push(arg2);
|
|
||||||
pushAddress(reinterpret_cast<uintptr_t>(arg1));
|
|
||||||
} else {
|
|
||||||
mov(arg2, rdx);
|
|
||||||
mov(reinterpret_cast<uintptr_t>(arg1), rsi);
|
|
||||||
}
|
|
||||||
|
|
||||||
compileCall2(function, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void compileCall(void* function, Register arg1, Register arg2) {
|
|
||||||
if (BytesPerWord == 4) {
|
|
||||||
push(arg2);
|
|
||||||
push(arg1);
|
|
||||||
} else {
|
|
||||||
mov(arg2, rdx);
|
mov(arg2, rdx);
|
||||||
mov(arg1, rsi);
|
mov(arg1, rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(arg2);
|
||||||
|
push(arg1);
|
||||||
|
push(rbp, FrameThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileCall2(function, 3);
|
if (direct) {
|
||||||
|
directCall(function);
|
||||||
|
} else {
|
||||||
|
indirectCall(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 3, rsp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compileCall(bool direct, void* function, uintptr_t arg1, Register arg2)
|
||||||
|
{
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
mov(arg2, rdx);
|
||||||
|
mov(arg1, rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(arg2);
|
||||||
|
push(arg1);
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direct) {
|
||||||
|
directCall(function);
|
||||||
|
} else {
|
||||||
|
indirectCall(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 3, rsp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compileCall(bool direct, void* function, object arg1, Register arg2) {
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
mov(arg2, rdx);
|
||||||
|
mov(poolRegister(), poolReference(arg1), rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(arg2);
|
||||||
|
push(poolRegister(), poolReference(arg1));
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direct) {
|
||||||
|
directCall(function);
|
||||||
|
} else {
|
||||||
|
indirectCall(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 3, rsp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compileCall(bool direct, void* function, object arg1) {
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
mov(poolRegister(), poolReference(arg1), rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(poolRegister(), poolReference(arg1));
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direct) {
|
||||||
|
directCall(function);
|
||||||
|
} else {
|
||||||
|
indirectCall(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 2, rsp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiled* compile() {
|
Compiled* compile() {
|
||||||
@ -2234,11 +2349,7 @@ class JavaCompiler: public Compiler {
|
|||||||
jmp(next);
|
jmp(next);
|
||||||
|
|
||||||
outOfBounds.mark();
|
outOfBounds.mark();
|
||||||
int3();
|
compileThrowNew(Machine::ArrayIndexOutOfBoundsExceptionType);
|
||||||
compileCall
|
|
||||||
(reinterpret_cast<void*>(throwNew),
|
|
||||||
arrayBody
|
|
||||||
(t, t->m->types, Machine::ArrayIndexOutOfBoundsExceptionType));
|
|
||||||
|
|
||||||
next.mark();
|
next.mark();
|
||||||
} break;
|
} break;
|
||||||
@ -2276,6 +2387,11 @@ class JavaCompiler: public Compiler {
|
|||||||
|
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
case aastore:
|
case aastore:
|
||||||
|
shl(log(BytesPerWord), rcx);
|
||||||
|
add(rcx, rax);
|
||||||
|
compileCall(true, reinterpret_cast<void*>(set), rax, rbx);
|
||||||
|
break;
|
||||||
|
|
||||||
case fastore:
|
case fastore:
|
||||||
case iastore:
|
case iastore:
|
||||||
shl(log(BytesPerWord), rcx);
|
shl(log(BytesPerWord), rcx);
|
||||||
@ -2307,10 +2423,7 @@ class JavaCompiler: public Compiler {
|
|||||||
jmp(next);
|
jmp(next);
|
||||||
|
|
||||||
outOfBounds.mark();
|
outOfBounds.mark();
|
||||||
compileCall
|
compileThrowNew(Machine::ArrayIndexOutOfBoundsExceptionType);
|
||||||
(reinterpret_cast<void*>(throwNew),
|
|
||||||
arrayBody
|
|
||||||
(t, t->m->types, Machine::ArrayIndexOutOfBoundsExceptionType));
|
|
||||||
|
|
||||||
next.mark();
|
next.mark();
|
||||||
} break;
|
} break;
|
||||||
@ -2351,13 +2464,13 @@ class JavaCompiler: public Compiler {
|
|||||||
cmp(0, rax);
|
cmp(0, rax);
|
||||||
jge(nonnegative);
|
jge(nonnegative);
|
||||||
|
|
||||||
compileCall
|
compileThrowNew(Machine::NegativeArraySizeExceptionType);
|
||||||
(reinterpret_cast<void*>(throwNew),
|
|
||||||
arrayBody(t, t->m->types, Machine::NegativeArraySizeExceptionType));
|
|
||||||
|
|
||||||
nonnegative.mark();
|
nonnegative.mark();
|
||||||
compileCall(reinterpret_cast<void*>(makeBlankObjectArray),
|
|
||||||
|
compileCall(false, reinterpret_cast<void*>(makeBlankObjectArray),
|
||||||
class_, rax);
|
class_, rax);
|
||||||
|
|
||||||
pushObject(rax);
|
pushObject(rax);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -2395,8 +2508,14 @@ class JavaCompiler: public Compiler {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case athrow:
|
case athrow:
|
||||||
popObject(rax);
|
if (BytesPerWord == 8) {
|
||||||
compileCall(reinterpret_cast<void*>(throw_), rax);
|
popObject(rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
indirectCall(reinterpret_cast<void*>(throw_));
|
||||||
stackMapper.exited();
|
stackMapper.exited();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2421,13 +2540,12 @@ class JavaCompiler: public Compiler {
|
|||||||
cmp(rcx, rax);
|
cmp(rcx, rax);
|
||||||
je(next);
|
je(next);
|
||||||
|
|
||||||
compileCall(reinterpret_cast<void*>(isAssignableFrom), rcx, rax);
|
compileCall(true, reinterpret_cast<void*>(isAssignableFrom), rcx, rax);
|
||||||
|
|
||||||
cmp(0, rax);
|
cmp(0, rax);
|
||||||
jne(next);
|
jne(next);
|
||||||
|
|
||||||
compileCall
|
compileThrowNew(Machine::ClassCastExceptionType);
|
||||||
(reinterpret_cast<void*>(throwNew),
|
|
||||||
arrayBody(t, t->m->types, Machine::ClassCastExceptionType));
|
|
||||||
|
|
||||||
next.mark();
|
next.mark();
|
||||||
} break;
|
} break;
|
||||||
@ -2509,13 +2627,14 @@ class JavaCompiler: public Compiler {
|
|||||||
cmp(0, rax);
|
cmp(0, rax);
|
||||||
je(zero);
|
je(zero);
|
||||||
|
|
||||||
pushInt(rax, IntValue);
|
push(rax, IntValue);
|
||||||
jmp(next);
|
jmp(next);
|
||||||
|
|
||||||
zero.mark();
|
zero.mark();
|
||||||
pushInt(0);
|
push(0);
|
||||||
|
|
||||||
next.mark();
|
next.mark();
|
||||||
|
stackMapper.pushedInt();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
@ -2526,13 +2645,19 @@ class JavaCompiler: public Compiler {
|
|||||||
cmp(0, rax);
|
cmp(0, rax);
|
||||||
je(zero);
|
je(zero);
|
||||||
|
|
||||||
pushLong(rax, LongValue);
|
if (BytesPerWord == 8) {
|
||||||
|
pushLongQuiet(rax, LongValue);
|
||||||
|
} else {
|
||||||
|
pushLongQuiet(rax, LongValue);
|
||||||
|
pushLongQuiet(rax, LongValue + 4);
|
||||||
|
}
|
||||||
jmp(next);
|
jmp(next);
|
||||||
|
|
||||||
zero.mark();
|
zero.mark();
|
||||||
pushLong(0);
|
pushLongQuiet(0);
|
||||||
|
|
||||||
next.mark();
|
next.mark();
|
||||||
|
stackMapper.pushedLong();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ObjectField: {
|
case ObjectField: {
|
||||||
@ -2836,7 +2961,9 @@ class JavaCompiler: public Compiler {
|
|||||||
jmp(next);
|
jmp(next);
|
||||||
|
|
||||||
call.mark();
|
call.mark();
|
||||||
compileCall(reinterpret_cast<void*>(isAssignableFrom), rcx, rax);
|
|
||||||
|
compileCall(true, reinterpret_cast<void*>(isAssignableFrom), rcx, rax);
|
||||||
|
|
||||||
push(rax);
|
push(rax);
|
||||||
jmp(next);
|
jmp(next);
|
||||||
|
|
||||||
@ -2903,8 +3030,8 @@ class JavaCompiler: public Compiler {
|
|||||||
add(CompiledBody, rax);
|
add(CompiledBody, rax);
|
||||||
call(rax); // call compiled code
|
call(rax); // call compiled code
|
||||||
|
|
||||||
poolRegisterClobbered = true;
|
|
||||||
stackMapper.called(this->code.length());
|
stackMapper.called(this->code.length());
|
||||||
|
poolRegisterClobbered = true;
|
||||||
|
|
||||||
add(footprint, rsp); // pop arguments
|
add(footprint, rsp); // pop arguments
|
||||||
stackMapper.popped(methodParameterFootprint(t, target));
|
stackMapper.popped(methodParameterFootprint(t, target));
|
||||||
@ -3087,7 +3214,7 @@ class JavaCompiler: public Compiler {
|
|||||||
Assembler::idiv(rcx);
|
Assembler::idiv(rcx);
|
||||||
pushLong(rax);
|
pushLong(rax);
|
||||||
} else {
|
} else {
|
||||||
compileCall(reinterpret_cast<void*>(divideLong));
|
directCall(reinterpret_cast<void*>(divideLong));
|
||||||
popLong();
|
popLong();
|
||||||
mov(rax, rsp, 0);
|
mov(rax, rsp, 0);
|
||||||
mov(rdx, rsp, 4);
|
mov(rdx, rsp, 4);
|
||||||
@ -3159,7 +3286,7 @@ class JavaCompiler: public Compiler {
|
|||||||
Assembler::idiv(rcx);
|
Assembler::idiv(rcx);
|
||||||
pushLong(rdx);
|
pushLong(rdx);
|
||||||
} else {
|
} else {
|
||||||
compileCall(reinterpret_cast<void*>(moduloLong));
|
directCall(reinterpret_cast<void*>(moduloLong));
|
||||||
popLong();
|
popLong();
|
||||||
mov(rax, rsp, 0);
|
mov(rax, rsp, 0);
|
||||||
mov(rdx, rsp, 4);
|
mov(rdx, rsp, 4);
|
||||||
@ -3208,9 +3335,10 @@ class JavaCompiler: public Compiler {
|
|||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
if (classVmFlags(t, class_) & WeakReferenceFlag) {
|
if (classVmFlags(t, class_) & WeakReferenceFlag) {
|
||||||
compileCall(reinterpret_cast<void*>(makeNewWeakReference), class_);
|
compileCall(false, reinterpret_cast<void*>(makeNewWeakReference),
|
||||||
|
class_);
|
||||||
} else {
|
} else {
|
||||||
compileCall(reinterpret_cast<void*>(makeNew), class_);
|
compileCall(false, reinterpret_cast<void*>(makeNew), class_);
|
||||||
}
|
}
|
||||||
|
|
||||||
pushObject(rax);
|
pushObject(rax);
|
||||||
@ -3225,10 +3353,7 @@ class JavaCompiler: public Compiler {
|
|||||||
cmp(0, rax);
|
cmp(0, rax);
|
||||||
jge(nonnegative);
|
jge(nonnegative);
|
||||||
|
|
||||||
compileCall
|
compileThrowNew(Machine::NegativeArraySizeExceptionType);
|
||||||
(reinterpret_cast<void*>(throwNew),
|
|
||||||
arrayBody
|
|
||||||
(t, t->m->types, Machine::NegativeArraySizeExceptionType));
|
|
||||||
|
|
||||||
nonnegative.mark();
|
nonnegative.mark();
|
||||||
|
|
||||||
@ -3269,14 +3394,15 @@ class JavaCompiler: public Compiler {
|
|||||||
default: abort(t);
|
default: abort(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileCall(reinterpret_cast<void*>(makeBlankArray),
|
compileCall(false, reinterpret_cast<void*>(makeBlankArray),
|
||||||
reinterpret_cast<void*>(constructor), rax);
|
reinterpret_cast<uintptr_t>(constructor), rax);
|
||||||
|
|
||||||
pushObject(rax);
|
pushObject(rax);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case pop_: {
|
case pop_: {
|
||||||
add(BytesPerWord, rsp);
|
add(BytesPerWord, rsp);
|
||||||
stackMapper.poppedIntOrObject();
|
stackMapper.popped(1);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case putfield: {
|
case putfield: {
|
||||||
@ -3328,9 +3454,25 @@ class JavaCompiler: public Compiler {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ObjectField: {
|
case ObjectField: {
|
||||||
popObject(rcx);
|
if (BytesPerWord == 8) {
|
||||||
popObject(rax);
|
popObject(rdx);
|
||||||
mov(rcx, rax, fieldOffset(t, field));
|
popObject(rsi);
|
||||||
|
add(fieldOffset(t, field), rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
popObject(rdx);
|
||||||
|
popObject(rsi);
|
||||||
|
add(fieldOffset(t, field), rsi);
|
||||||
|
push(rdx);
|
||||||
|
push(rsi);
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
directCall(reinterpret_cast<void*>(set));
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 3, rsp);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: abort(t);
|
default: abort(t);
|
||||||
@ -3356,34 +3498,105 @@ class JavaCompiler: public Compiler {
|
|||||||
case ShortField:
|
case ShortField:
|
||||||
case FloatField:
|
case FloatField:
|
||||||
case IntField: {
|
case IntField: {
|
||||||
compileCall(reinterpret_cast<void*>(makeNew),
|
object intType = arrayBody(t, t->m->types, Machine::IntType);
|
||||||
arrayBody(t, t->m->types, Machine::IntType));
|
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
mov(poolRegister(), poolReference(intType), rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(poolRegister(), poolReference(intType));
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
indirectCall(reinterpret_cast<void*>(makeNew));
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 2, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
popInt(rax, IntValue);
|
popInt(rax, IntValue);
|
||||||
|
|
||||||
mov(poolRegister(), poolReference(table), rcx);
|
if (BytesPerWord == 8) {
|
||||||
mov(rax, rcx, offset);
|
mov(rax, rdx);
|
||||||
|
mov(poolRegister(), poolReference(table), rsi);
|
||||||
|
add(offset, rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(rax);
|
||||||
|
mov(poolRegister(), poolReference(table), rsi);
|
||||||
|
add(offset, rsi);
|
||||||
|
push(rsi);
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
directCall(reinterpret_cast<void*>(set));
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 3, rsp);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
case LongField: {
|
case LongField: {
|
||||||
compileCall(reinterpret_cast<void*>(makeNew),
|
object longType = arrayBody(t, t->m->types, Machine::LongType);
|
||||||
arrayBody(t, t->m->types, Machine::LongType));
|
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
mov(poolRegister(), poolReference(longType), rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(poolRegister(), poolReference(longType));
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
indirectCall(reinterpret_cast<void*>(makeNew));
|
||||||
|
|
||||||
if (BytesPerWord == 8) {
|
if (BytesPerWord == 8) {
|
||||||
popLong(rax, LongValue);
|
popLong(rax, LongValue);
|
||||||
} else {
|
} else {
|
||||||
|
add(BytesPerWord * 2, rsp);
|
||||||
popLong(rax, LongValue,
|
popLong(rax, LongValue,
|
||||||
rax, LongValue + 4);
|
rax, LongValue + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
mov(poolRegister(), poolReference(table), rcx);
|
if (BytesPerWord == 8) {
|
||||||
mov(rax, rcx, offset);
|
mov(rax, rdx);
|
||||||
|
mov(poolRegister(), poolReference(table), rsi);
|
||||||
|
add(offset, rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
push(rax);
|
||||||
|
mov(poolRegister(), poolReference(table), rsi);
|
||||||
|
add(offset, rsi);
|
||||||
|
push(rsi);
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
directCall(reinterpret_cast<void*>(set));
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 3, rsp);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
mov(poolRegister(), poolReference(table), rax);
|
if (BytesPerWord == 8) {
|
||||||
popObject(rax, offset);
|
popObject(rdx);
|
||||||
|
mov(poolRegister(), poolReference(table), rsi);
|
||||||
|
add(offset, rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
} else {
|
||||||
|
mov(poolRegister(), poolReference(table), rsi);
|
||||||
|
add(offset, rsi);
|
||||||
|
push(rsi);
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
directCall(reinterpret_cast<void*>(set));
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 3, rsp);
|
||||||
|
stackMapper.poppedObject();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: abort(t);
|
default: abort(t);
|
||||||
@ -3485,20 +3698,6 @@ class JavaCompiler: public Compiler {
|
|||||||
return pool.length() + BytesPerWord;
|
return pool.length() + BytesPerWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
void callAddress(void* function) {
|
|
||||||
Compiler::callAddress(function);
|
|
||||||
|
|
||||||
stackMapper.called(code.length());
|
|
||||||
poolRegisterClobbered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void callAlignedAddress(void* function) {
|
|
||||||
Compiler::callAlignedAddress(function);
|
|
||||||
|
|
||||||
stackMapper.called(code.length());
|
|
||||||
poolRegisterClobbered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
object method;
|
object method;
|
||||||
StackMapper stackMapper;
|
StackMapper stackMapper;
|
||||||
bool poolRegisterClobbered;
|
bool poolRegisterClobbered;
|
||||||
@ -3598,13 +3797,18 @@ updateCaller(MyThread* t, object method)
|
|||||||
void
|
void
|
||||||
compileMethod(MyThread* t, object method)
|
compileMethod(MyThread* t, object method)
|
||||||
{
|
{
|
||||||
compileMethod2(t, method);
|
{ PROTECT(t, method);
|
||||||
|
compileMethod2(t, method);
|
||||||
if (UNLIKELY(t->exception)) {
|
|
||||||
unwind(t);
|
if (LIKELY(t->exception == 0)) {
|
||||||
} else if (not methodVirtual(t, method)) {
|
if (not methodVirtual(t, method)) {
|
||||||
updateCaller(t, method);
|
updateCaller(t, method);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unwind(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArgumentList {
|
class ArgumentList {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user