fix many JIT GC bugs; GC.java now passes

This commit is contained in:
Joel Dice 2007-10-13 15:48:40 -06:00
parent f58c6ef4e8
commit 5c99edd90e
2 changed files with 363 additions and 159 deletions

View File

@ -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

View File

@ -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 {