mirror of
https://github.com/corda/corda.git
synced 2025-02-07 19:40:25 +00:00
more work on frame-pointer-less unwinding
This fixes the tails=true build (at least for x86_64) and eliminates the need for a frame table in the tails=false build. In the tails=true build, we still need a frame table on x86(_64) to help determine whether we've caught a thread executing code to do a tail call or pop arguments off the stack. However, I've not yet written the code to actually use this table, and it is only needed to handle asynchronous unwinds via Thread.getStackTrace.
This commit is contained in:
parent
966650f105
commit
c1a0d8b6fc
155
src/arm.cpp
155
src/arm.cpp
@ -164,13 +164,13 @@ inline int carry16(intptr_t v) { return static_cast<int16_t>(v) < 0 ? 1 : 0; }
|
||||
inline bool isOfWidth(long long i, int size) { return static_cast<unsigned long long>(i) >> size == 0; }
|
||||
inline bool isOfWidth(int i, int size) { return static_cast<unsigned>(i) >> size == 0; }
|
||||
|
||||
const unsigned FrameFooterSize = 2;
|
||||
const unsigned FrameHeaderSize = 0;
|
||||
const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1);
|
||||
|
||||
const unsigned StackAlignmentInBytes = 8;
|
||||
const unsigned StackAlignmentInWords = StackAlignmentInBytes / BytesPerWord;
|
||||
|
||||
const int ThreadRegister = 8;
|
||||
const int FrameRegister = 12;
|
||||
const int StackRegister = 13;
|
||||
const int LinkRegister = 14;
|
||||
const int ProgramCounter = 15;
|
||||
@ -1701,6 +1701,9 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
|
||||
virtual bool reserved(int register_) {
|
||||
switch (register_) {
|
||||
case FrameRegister:
|
||||
return UseFramePointer;
|
||||
|
||||
case LinkRegister:
|
||||
case StackRegister:
|
||||
case ThreadRegister:
|
||||
@ -1781,8 +1784,8 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
|
||||
virtual unsigned alignFrameSize(unsigned sizeInWords) {
|
||||
const unsigned alignment = StackAlignmentInBytes / BytesPerWord;
|
||||
return (ceiling(sizeInWords + FrameFooterSize, alignment) * alignment);
|
||||
return pad(sizeInWords + FrameHeaderSize, StackAlignmentInWords)
|
||||
- FrameHeaderSize;
|
||||
}
|
||||
|
||||
virtual void* frameIp(void* stack) {
|
||||
@ -1798,15 +1801,15 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
|
||||
virtual unsigned frameFooterSize() {
|
||||
return FrameFooterSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int returnAddressOffset() {
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual int framePointerOffset() {
|
||||
return 0;
|
||||
return -2;
|
||||
}
|
||||
|
||||
virtual void nextFrame(void** stack, void**) {
|
||||
@ -2006,11 +2009,14 @@ class MyAssembler: public Assembler {
|
||||
return arch_;
|
||||
}
|
||||
|
||||
virtual void saveFrame(unsigned stackOffset, unsigned) {
|
||||
virtual void saveFrame(unsigned stackOffset) {
|
||||
appendFrameSizeEvent(&c, FrameSizePoison);
|
||||
|
||||
// ???
|
||||
Register returnAddress(LinkRegister);
|
||||
Memory returnAddressDst
|
||||
(StackRegister, arch_->returnAddressOffset() * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst);
|
||||
Memory returnAddressDst(StackRegister, - BytesPerWord);
|
||||
moveAndUpdateRM(&c, BytesPerWord, &returnAddress, BytesPerWord,
|
||||
&returnAddressDst);
|
||||
|
||||
Register stack(StackRegister);
|
||||
Memory stackDst(ThreadRegister, stackOffset);
|
||||
@ -2059,33 +2065,53 @@ class MyAssembler: public Assembler {
|
||||
}
|
||||
|
||||
virtual void allocateFrame(unsigned footprint) {
|
||||
Register returnAddress(LinkRegister);
|
||||
Register stack(StackRegister);
|
||||
Constant footprintConstant(resolved(&c, footprint * BytesPerWord));
|
||||
subCR(&c, BytesPerWord, &footprintConstant, BytesPerWord, &stack,
|
||||
BytesPerWord, &stack);
|
||||
|
||||
Memory returnAddressDst(StackRegister, arch_->returnAddressOffset() * BytesPerWord);
|
||||
appendFrameSizeEvent(&c, footprint);
|
||||
|
||||
Register returnAddress(LinkRegister);
|
||||
Memory returnAddressDst(StackRegister, (footprint - 1) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst);
|
||||
|
||||
Register stack(StackRegister);
|
||||
Memory stackDst(StackRegister, -footprint * BytesPerWord);
|
||||
moveAndUpdateRM(&c, BytesPerWord, &stack, BytesPerWord, &stackDst);
|
||||
if (UseFramePointer) {
|
||||
Register frame(FrameRegister);
|
||||
Memory frameDst(StackRegister, (footprint - 2) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &frame, BytesPerWord, &frameDst);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void adjustFrame(unsigned footprint) {
|
||||
Register nextStack(5);
|
||||
Memory stackSrc(StackRegister, 0);
|
||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &nextStack);
|
||||
virtual void adjustFrame(unsigned difference) {
|
||||
appendFrameSizeEvent(&c, - difference);
|
||||
|
||||
Memory stackDst(StackRegister, -footprint * BytesPerWord);
|
||||
moveAndUpdateRM(&c, BytesPerWord, &nextStack, BytesPerWord, &stackDst);
|
||||
Register stack(StackRegister);
|
||||
Constant differenceConstant(resolved(&c, difference * BytesPerWord));
|
||||
subCR(&c, BytesPerWord, &differenceConstant, BytesPerWord, &stack,
|
||||
BytesPerWord, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, difference);
|
||||
}
|
||||
|
||||
virtual void popFrame() {
|
||||
Register stack(StackRegister);
|
||||
Memory stackSrc(StackRegister, arch_->framePointerOffset() * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &stack);
|
||||
virtual void popFrame(unsigned frameFootprint) {
|
||||
if (UseFramePointer) {
|
||||
Register frame(FrameRegister);
|
||||
Memory frameSrc(StackRegister, (frameFootprint - 1) * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &frameSrc, BytesPerWord, &frame);
|
||||
}
|
||||
|
||||
Register returnAddress(LinkRegister);
|
||||
Memory returnAddressSrc(StackRegister, arch_->returnAddressOffset() * BytesPerWord);
|
||||
Memory returnAddressSrc
|
||||
(StackRegister, (frameFootprint - 1) * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &returnAddress);
|
||||
|
||||
Register stack(StackRegister);
|
||||
Constant differenceConstant(resolved(&c, frameFootprint * BytesPerWord));
|
||||
addCR(&c, BytesPerWord, &differenceConstant, BytesPerWord, &stack,
|
||||
BytesPerWord, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, - frameFootprint);
|
||||
}
|
||||
|
||||
virtual void popFrameForTailCall(unsigned footprint,
|
||||
@ -2095,80 +2121,85 @@ class MyAssembler: public Assembler {
|
||||
{
|
||||
if (TailCalls) {
|
||||
if (offset) {
|
||||
if (UseFramePointer) {
|
||||
Register frame(FrameRegister);
|
||||
Memory frameSrc(StackRegister, (footprint - 1) * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &frameSrc, BytesPerWord, &frame);
|
||||
}
|
||||
|
||||
Register link(LinkRegister);
|
||||
Memory returnAddressSrc
|
||||
(StackRegister, BytesPerWord + (footprint * BytesPerWord));
|
||||
(StackRegister, (footprint - 1) * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &link);
|
||||
|
||||
Register tmp(c.client->acquireTemporary());
|
||||
Memory stackSrc(StackRegister, footprint * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp);
|
||||
Register stack(StackRegister);
|
||||
Constant footprintConstant
|
||||
(resolved(&c, (footprint - offset + 1) * BytesPerWord));
|
||||
addCR(&c, BytesPerWord, &footprintConstant, BytesPerWord, &stack);
|
||||
|
||||
Memory stackDst(StackRegister, (footprint - offset) * BytesPerWord);
|
||||
moveAndUpdateRM(&c, BytesPerWord, &tmp, BytesPerWord, &stackDst);
|
||||
|
||||
c.client->releaseTemporary(tmp.low);
|
||||
appendFrameSizeEvent(&c, - (frameFootprint - offset + 1));
|
||||
|
||||
if (returnAddressSurrogate != NoRegister) {
|
||||
assert(&c, offset > 0);
|
||||
|
||||
Register ras(returnAddressSurrogate);
|
||||
Memory dst(StackRegister, BytesPerWord + (offset * BytesPerWord));
|
||||
Memory dst(StackRegister, (offset - 1) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &ras, BytesPerWord, &dst);
|
||||
}
|
||||
|
||||
if (framePointerSurrogate != NoRegister) {
|
||||
assert(&c, offset > 0);
|
||||
|
||||
Register fps(framePointerSurrogate);
|
||||
Memory dst(StackRegister, offset * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &fps, BytesPerWord, &dst);
|
||||
Register las(framePointerSurrogate);
|
||||
Memory dst(StackRegister, (offset - 2) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &las, BytesPerWord, &dst);
|
||||
}
|
||||
} else {
|
||||
popFrame();
|
||||
popFrame(footprint);
|
||||
}
|
||||
} else {
|
||||
abort(&c);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void popFrameAndPopArgumentsAndReturn(unsigned argumentFootprint) {
|
||||
popFrame();
|
||||
virtual void popFrameAndPopArgumentsAndReturn(unsigned frameFootprint,
|
||||
unsigned argumentFootprint)
|
||||
{
|
||||
popFrame(frameFootprint);
|
||||
|
||||
assert(&c, argumentFootprint >= StackAlignmentInWords);
|
||||
assert(&c, (argumentFootprint % StackAlignmentInWords) == 0);
|
||||
|
||||
unsigned offset;
|
||||
if (TailCalls and argumentFootprint > StackAlignmentInWords) {
|
||||
Register tmp(5);
|
||||
Memory stackSrc(StackRegister, 0);
|
||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp);
|
||||
offset = argumentFootprint - StackAlignmentInWords;
|
||||
|
||||
Memory stackDst(StackRegister,
|
||||
(argumentFootprint - StackAlignmentInWords)
|
||||
* BytesPerWord);
|
||||
moveAndUpdateRM(&c, BytesPerWord, &tmp, BytesPerWord, &stackDst);
|
||||
Register stack(StackRegister);
|
||||
Constant adjustment(resolved(&c, offset * BytesPerWord));
|
||||
addCR(&c, BytesPerWord, &adjustment, BytesPerWord, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, - offset);
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
return_(&c);
|
||||
|
||||
// todo: this is not necessary if there are no instructions to
|
||||
// follow:
|
||||
appendFrameSizeEvent(&c, frameFootprint + offset);
|
||||
}
|
||||
|
||||
virtual void popFrameAndUpdateStackAndReturn(unsigned stackOffsetFromThread)
|
||||
virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint,
|
||||
unsigned stackOffsetFromThread)
|
||||
{
|
||||
popFrame();
|
||||
appendFrameSizeEvent(&c, FrameSizePoison);
|
||||
|
||||
Register tmp1(6);
|
||||
Memory stackSrc(StackRegister, 0);
|
||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp1);
|
||||
|
||||
Register tmp2(5);
|
||||
Memory newStackSrc(ThreadRegister, stackOffsetFromThread);
|
||||
moveMR(&c, BytesPerWord, &newStackSrc, BytesPerWord, &tmp2);
|
||||
popFrame(frameFootprint);
|
||||
|
||||
Register stack(StackRegister);
|
||||
subR(&c, BytesPerWord, &stack, &tmp2, &tmp2);
|
||||
|
||||
Memory stackDst(StackRegister, 0, tmp2.low);
|
||||
moveAndUpdateRM(&c, BytesPerWord, &tmp1, BytesPerWord, &stackDst);
|
||||
Memory newStackSrc(ThreadRegister, stackOffsetFromThread);
|
||||
moveMR(&c, BytesPerWord, &newStackSrc, BytesPerWord, &stack);
|
||||
|
||||
return_(&c);
|
||||
}
|
||||
|
@ -304,11 +304,10 @@ class Assembler {
|
||||
virtual unsigned resolve(unsigned start, Block* next) = 0;
|
||||
};
|
||||
|
||||
class FrameSizeEvent {
|
||||
class FrameEvent {
|
||||
public:
|
||||
virtual unsigned offset() = 0;
|
||||
virtual int change() = 0;
|
||||
virtual FrameSizeEvent* next() = 0;
|
||||
virtual FrameEvent* next() = 0;
|
||||
};
|
||||
|
||||
class Architecture {
|
||||
@ -351,6 +350,10 @@ class Assembler {
|
||||
|
||||
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
|
||||
|
||||
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
|
||||
int32_t* frameTable, void* link, void* stackLimit,
|
||||
unsigned targetParameterFootprint, void** ip,
|
||||
void** stack) = 0;
|
||||
virtual void* frameIp(void* stack) = 0;
|
||||
virtual unsigned frameHeaderSize() = 0;
|
||||
virtual unsigned frameReturnAddressSize() = 0;
|
||||
@ -437,9 +440,9 @@ class Assembler {
|
||||
|
||||
virtual unsigned length() = 0;
|
||||
|
||||
virtual unsigned frameSizeEventCount() = 0;
|
||||
virtual unsigned frameEventCount() = 0;
|
||||
|
||||
virtual FrameSizeEvent* firstFrameSizeEvent() = 0;
|
||||
virtual FrameEvent* firstFrameEvent() = 0;
|
||||
|
||||
virtual void dispose() = 0;
|
||||
};
|
||||
|
@ -295,9 +295,9 @@ LOCAL(vmJumpAndInvoke_argumentTest):
|
||||
|
||||
#define THREAD_STACK 2148
|
||||
#define THREAD_SCRATCH 2152
|
||||
|
||||
|
||||
#define CALLEE_SAVED_REGISTER_FOOTPRINT 16
|
||||
|
||||
|
||||
.globl GLOBAL(vmInvoke)
|
||||
GLOBAL(vmInvoke):
|
||||
pushl %ebp
|
||||
|
146
src/compile.cpp
146
src/compile.cpp
@ -153,14 +153,18 @@ class MyThread: public Thread {
|
||||
CallTrace* trace):
|
||||
Context(t, ip, stack, continuation, trace),
|
||||
t(t),
|
||||
link(0),
|
||||
javaStackLimit(0),
|
||||
next(t->traceContext)
|
||||
{
|
||||
t->traceContext = this;
|
||||
}
|
||||
|
||||
TraceContext(MyThread* t):
|
||||
TraceContext(MyThread* t, void* link):
|
||||
Context(t, t->ip, t->stack, t->continuation, t->trace),
|
||||
t(t),
|
||||
link(link),
|
||||
javaStackLimit(0),
|
||||
next(t->traceContext)
|
||||
{
|
||||
t->traceContext = this;
|
||||
@ -171,6 +175,8 @@ class MyThread: public Thread {
|
||||
}
|
||||
|
||||
MyThread* t;
|
||||
void* link;
|
||||
void* javaStackLimit;
|
||||
TraceContext* next;
|
||||
};
|
||||
|
||||
@ -414,56 +420,42 @@ getTableValue(Thread* t, object table, unsigned base, unsigned max,
|
||||
(&intArrayBody(t, table, base), bits, index * bits);
|
||||
}
|
||||
|
||||
unsigned
|
||||
frameSize(MyThread* t, intptr_t ip, object method)
|
||||
void
|
||||
nextFrame(MyThread* t, void** ip, void** sp, object method, object target)
|
||||
{
|
||||
object code = methodCode(t, method);
|
||||
object table = codeFrameSizeTable(t, code);
|
||||
unsigned count = intArrayBody(t, table, 0);
|
||||
unsigned max = alignedFrameSize(t, method);
|
||||
object table = codeFrameTable(t, code);
|
||||
intptr_t start = codeCompiled(t, code);
|
||||
int codeSize = compiledSize(start);
|
||||
unsigned indexSize = ceiling(count * bitsNeeded(codeSize), 32);
|
||||
|
||||
assert(t, ip >= start);
|
||||
assert(t, ip <= start + codeSize);
|
||||
void* link;
|
||||
void* javaStackLimit;
|
||||
|
||||
unsigned offset = ip - start;
|
||||
unsigned bottom = 0;
|
||||
unsigned top = count;
|
||||
for (unsigned span = top - bottom; span; span = top - bottom) {
|
||||
unsigned middle = bottom + (span / 2);
|
||||
unsigned candidate = getTableValue(t, table, 1, codeSize, middle);
|
||||
|
||||
if (offset >= candidate
|
||||
and (middle + 1 == count
|
||||
or offset < getTableValue(t, table, 1, codeSize, middle + 1)))
|
||||
{
|
||||
return getTableValue(t, table, 1 + indexSize, max, middle);
|
||||
} else if (offset < candidate) {
|
||||
top = middle;
|
||||
} else if (offset > candidate) {
|
||||
bottom = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (top == 0) {
|
||||
return 0;
|
||||
} else if (top < count) {
|
||||
return getTableValue(t, table, 1 + indexSize, max, top);
|
||||
} else if (top == count && count > 0) {
|
||||
return getTableValue(t, table, 1 + indexSize, max, top - 1);
|
||||
if (t->traceContext) {
|
||||
link = t->traceContext->link;
|
||||
javaStackLimit = t->traceContext->javaStackLimit;
|
||||
} else {
|
||||
abort(t);
|
||||
link = 0;
|
||||
javaStackLimit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
nextFrame(MyThread* t, void* ip, void* sp, object method)
|
||||
{
|
||||
return reinterpret_cast<void**>(sp) + local::frameSize
|
||||
(t, reinterpret_cast<intptr_t>(ip), method)
|
||||
+ t->arch->frameReturnAddressSize();
|
||||
// fprintf(stderr, "nextFrame %s.%s%s target %s.%s%s\n",
|
||||
// &byteArrayBody(t, className(t, methodClass(t, method)), 0),
|
||||
// &byteArrayBody(t, methodName(t, method), 0),
|
||||
// &byteArrayBody(t, methodSpec(t, method), 0),
|
||||
// target
|
||||
// ? &byteArrayBody(t, className(t, methodClass(t, target)), 0)
|
||||
// : 0,
|
||||
// target
|
||||
// ? &byteArrayBody(t, methodName(t, target), 0)
|
||||
// : 0,
|
||||
// target
|
||||
// ? &byteArrayBody(t, methodSpec(t, target), 0)
|
||||
// : 0);
|
||||
|
||||
t->arch->nextFrame
|
||||
(reinterpret_cast<void*>(start), compiledSize(start),
|
||||
alignedFrameSize(t, method), table ? &intArrayBody(t, table, 0) : 0,
|
||||
link, javaStackLimit, target ? methodParameterFootprint(t, target) : -1,
|
||||
ip, sp);
|
||||
}
|
||||
|
||||
class MyStackWalker: public Processor::StackWalker {
|
||||
@ -486,6 +478,7 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
|
||||
virtual void visit(Heap::Visitor* v) {
|
||||
v->visit(&(walker->method_));
|
||||
v->visit(&(walker->target));
|
||||
v->visit(&(walker->continuation));
|
||||
}
|
||||
|
||||
@ -496,6 +489,7 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
t(t),
|
||||
state(Start),
|
||||
method_(0),
|
||||
target(0),
|
||||
protector(this)
|
||||
{
|
||||
if (t->traceContext) {
|
||||
@ -518,6 +512,7 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
stack(w->stack),
|
||||
trace(w->trace),
|
||||
method_(w->method_),
|
||||
target(w->target),
|
||||
continuation(w->continuation),
|
||||
protector(this)
|
||||
{ }
|
||||
@ -551,6 +546,7 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
|
||||
case Next:
|
||||
if (stack) {
|
||||
target = method_;
|
||||
method_ = methodForIp(t, ip_);
|
||||
if (method_) {
|
||||
state = Method;
|
||||
@ -599,8 +595,7 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
break;
|
||||
|
||||
case Method:
|
||||
stack = nextFrame(t, ip_, stack, method_);
|
||||
ip_ = t->arch->frameIp(stack);
|
||||
nextFrame(t, &ip_, &stack, method_, target);
|
||||
break;
|
||||
|
||||
case NativeMethod:
|
||||
@ -654,6 +649,7 @@ class MyStackWalker: public Processor::StackWalker {
|
||||
void* stack;
|
||||
MyThread::CallTrace* trace;
|
||||
object method_;
|
||||
object target;
|
||||
object continuation;
|
||||
MyProtector protector;
|
||||
};
|
||||
@ -2028,7 +2024,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetStack,
|
||||
if (handler) {
|
||||
*targetIp = handler;
|
||||
|
||||
stack = nextFrame(t, ip, stack, method);
|
||||
nextFrame(t, &ip, &stack, method, target);
|
||||
|
||||
void** sp = static_cast<void**>(stackForFrame(t, stack, method))
|
||||
+ t->arch->frameReturnAddressSize();
|
||||
@ -2040,8 +2036,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetStack,
|
||||
|
||||
t->exception = 0;
|
||||
} else {
|
||||
stack = nextFrame(t, ip, stack, method);
|
||||
ip = t->arch->frameIp(stack);
|
||||
nextFrame(t, &ip, &stack, method, target);
|
||||
|
||||
if (t->exception) {
|
||||
releaseLock(t, method, stack);
|
||||
@ -2126,7 +2121,8 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetStack)
|
||||
top += argumentFootprint - alignment;
|
||||
}
|
||||
|
||||
stack = nextFrame(t, ip, stack, method);
|
||||
void* nextIp = ip;
|
||||
nextFrame(t, &nextIp, &stack, method, target);
|
||||
|
||||
void** bottom = static_cast<void**>(stack)
|
||||
+ t->arch->frameReturnAddressSize();
|
||||
@ -2156,7 +2152,7 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetStack)
|
||||
}
|
||||
last = c;
|
||||
|
||||
ip = t->arch->frameIp(stack);
|
||||
ip = nextIp;
|
||||
|
||||
target = method;
|
||||
} else {
|
||||
@ -5224,20 +5220,21 @@ translateLineNumberTable(MyThread* t, Compiler* c, object code, intptr_t start)
|
||||
}
|
||||
|
||||
object
|
||||
makeFrameSizeTable(MyThread* t, Context* c, unsigned codeSize)
|
||||
makeFrameTable(MyThread* t, Context* c, unsigned codeSize)
|
||||
{
|
||||
Assembler* a = c->assembler;
|
||||
unsigned count = a->frameSizeEventCount();
|
||||
int max = alignedFrameSize(t, c->method);
|
||||
unsigned indexSize = ceiling(count * bitsNeeded(codeSize), 32);
|
||||
unsigned tableSize = ceiling(count * bitsNeeded(max), 32);
|
||||
object table = makeIntArray(t, 1 + indexSize + tableSize);
|
||||
unsigned count = a->frameEventCount();
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned size = ceiling(count * bitsNeeded(codeSize), 32);
|
||||
object table = makeIntArray(t, 1 + size);
|
||||
|
||||
intArrayBody(t, table, 0) = count;
|
||||
|
||||
unsigned index = 0;
|
||||
int value = 0;
|
||||
for (Assembler::FrameSizeEvent* e = a->firstFrameSizeEvent();
|
||||
for (Assembler::FrameEvent* e = a->firstFrameEvent();
|
||||
e; e = e->next())
|
||||
{
|
||||
assert(t, index < count);
|
||||
@ -5245,17 +5242,8 @@ makeFrameSizeTable(MyThread* t, Context* c, unsigned codeSize)
|
||||
unsigned offset = e->offset();
|
||||
assert(t, offset <= codeSize);
|
||||
|
||||
value += e->change();
|
||||
|
||||
fprintf(stderr, "offset %d change %d value %d\n",
|
||||
offset, e->change(), value);
|
||||
|
||||
assert(t, value >= 0);
|
||||
assert(t, value <= max);
|
||||
|
||||
setTableValue(t, table, 1, codeSize, index, offset);
|
||||
setTableValue(t, table, 1 + indexSize, max, index, value);
|
||||
|
||||
|
||||
++ index;
|
||||
}
|
||||
|
||||
@ -5950,12 +5938,12 @@ finish(MyThread* t, Allocator* allocator, Context* context)
|
||||
|
||||
PROTECT(t, newLineNumberTable);
|
||||
|
||||
object frameSizeTable = makeFrameSizeTable(t, context, codeSize);
|
||||
object frameTable = makeFrameTable(t, context, codeSize);
|
||||
|
||||
object code = methodCode(t, context->method);
|
||||
|
||||
code = makeCode
|
||||
(t, 0, newExceptionHandlerTable, newLineNumberTable, frameSizeTable,
|
||||
(t, 0, newExceptionHandlerTable, newLineNumberTable, frameTable,
|
||||
reinterpret_cast<uintptr_t>(start), codeMaxStack(t, code),
|
||||
codeMaxLocals(t, code), 0);
|
||||
|
||||
@ -6700,6 +6688,7 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
||||
|
||||
MyThread::CallTrace* trace = t->trace;
|
||||
object targetMethod = (trace ? trace->targetMethod : 0);
|
||||
object target = targetMethod;
|
||||
|
||||
while (stack) {
|
||||
if (targetMethod) {
|
||||
@ -6711,11 +6700,14 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
||||
if (method) {
|
||||
PROTECT(t, method);
|
||||
|
||||
stack = nextFrame(t, ip, stack, method);
|
||||
void* nextIp = ip;
|
||||
nextFrame(t, &nextIp, &stack, method, target);
|
||||
|
||||
visitStackAndLocals(t, v, stack, method, ip);
|
||||
|
||||
ip = t->arch->frameIp(stack);
|
||||
ip = nextIp;
|
||||
|
||||
target = method;
|
||||
} else if (trace) {
|
||||
stack = trace->stack;
|
||||
ip = t->arch->frameIp(stack);
|
||||
@ -6723,6 +6715,9 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
||||
|
||||
if (trace) {
|
||||
targetMethod = trace->targetMethod;
|
||||
target = targetMethod;
|
||||
} else {
|
||||
target = 0;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
@ -7665,13 +7660,14 @@ class MyProcessor: public Processor {
|
||||
t(t), p(p), target(target), trace(0)
|
||||
{ }
|
||||
|
||||
virtual void visit(void* ip, void* stack) {
|
||||
MyThread::TraceContext c(target);
|
||||
virtual void visit(void* ip, void* stack, void* link) {
|
||||
MyThread::TraceContext c(target, link);
|
||||
|
||||
if (methodForIp(t, ip)) {
|
||||
// we caught the thread in Java code - use the register values
|
||||
c.ip = ip;
|
||||
c.stack = stack;
|
||||
c.javaStackLimit = stack;
|
||||
} else if (target->transition) {
|
||||
// we caught the thread in native code while in the middle
|
||||
// of updating the context fields (MyThread::stack, etc.)
|
||||
|
@ -834,6 +834,7 @@ handleSignal(int signal, siginfo_t* info, void* context)
|
||||
void* ip = reinterpret_cast<void*>(IP_REGISTER(c));
|
||||
void* stack = reinterpret_cast<void*>(STACK_REGISTER(c));
|
||||
void* thread = reinterpret_cast<void*>(THREAD_REGISTER(c));
|
||||
void* link = reinterpret_cast<void*>(LINK_REGISTER(c));
|
||||
|
||||
unsigned index;
|
||||
|
||||
@ -841,7 +842,7 @@ handleSignal(int signal, siginfo_t* info, void* context)
|
||||
case VisitSignal: {
|
||||
index = VisitSignalIndex;
|
||||
|
||||
system->threadVisitor->visit(ip, stack);
|
||||
system->threadVisitor->visit(ip, stack, link);
|
||||
|
||||
System::Thread* t = system->visitTarget;
|
||||
system->visitTarget = 0;
|
||||
|
@ -35,7 +35,7 @@ class System {
|
||||
|
||||
class ThreadVisitor {
|
||||
public:
|
||||
virtual void visit(void* ip, void* stack) = 0;
|
||||
virtual void visit(void* ip, void* stack, void* link) = 0;
|
||||
};
|
||||
|
||||
class Runnable {
|
||||
|
@ -86,7 +86,7 @@
|
||||
(object pool)
|
||||
(object exceptionHandlerTable)
|
||||
(object lineNumberTable)
|
||||
(object frameSizeTable)
|
||||
(object frameTable)
|
||||
(intptr_t compiled)
|
||||
(uint16_t maxStack)
|
||||
(uint16_t maxLocals)
|
||||
|
222
src/x86.cpp
222
src/x86.cpp
@ -72,8 +72,6 @@ const int LongJumpRegister = r10;
|
||||
const unsigned StackAlignmentInBytes = 16;
|
||||
const unsigned StackAlignmentInWords = StackAlignmentInBytes / BytesPerWord;
|
||||
|
||||
const int FrameSizePoison = -2147483647;
|
||||
|
||||
bool
|
||||
isInt8(intptr_t v)
|
||||
{
|
||||
@ -88,7 +86,7 @@ isInt32(intptr_t v)
|
||||
|
||||
class Task;
|
||||
class AlignmentPadding;
|
||||
class MyFrameSizeEvent;
|
||||
class MyFrameEvent;
|
||||
|
||||
unsigned
|
||||
padding(AlignmentPadding* p, unsigned index, unsigned offset,
|
||||
@ -97,17 +95,14 @@ padding(AlignmentPadding* p, unsigned index, unsigned offset,
|
||||
class Context;
|
||||
class MyBlock;
|
||||
|
||||
void
|
||||
appendFrameSizeEvent(Context* c, MyBlock* b, Promise* offset, int change);
|
||||
|
||||
ResolvedPromise*
|
||||
resolved(Context* c, int64_t value);
|
||||
resolved(Context* c, int64_t value);
|
||||
|
||||
class MyBlock: public Assembler::Block {
|
||||
public:
|
||||
MyBlock(unsigned offset):
|
||||
next(0), firstPadding(0), lastPadding(0), firstFrameSizeEvent(0),
|
||||
lastFrameSizeEvent(0), offset(offset), start(~0), size(0)
|
||||
next(0), firstPadding(0), lastPadding(0), firstFrameEvent(0),
|
||||
lastFrameEvent(0), offset(offset), start(~0), size(0)
|
||||
{ }
|
||||
|
||||
virtual unsigned resolve(unsigned start, Assembler::Block* next) {
|
||||
@ -120,8 +115,8 @@ class MyBlock: public Assembler::Block {
|
||||
MyBlock* next;
|
||||
AlignmentPadding* firstPadding;
|
||||
AlignmentPadding* lastPadding;
|
||||
MyFrameSizeEvent* firstFrameSizeEvent;
|
||||
MyFrameSizeEvent* lastFrameSizeEvent;
|
||||
MyFrameEvent* firstFrameEvent;
|
||||
MyFrameEvent* lastFrameEvent;
|
||||
unsigned offset;
|
||||
unsigned start;
|
||||
unsigned size;
|
||||
@ -164,8 +159,8 @@ class Context {
|
||||
Context(System* s, Allocator* a, Zone* zone, ArchitectureContext* ac):
|
||||
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
|
||||
firstBlock(new (zone->allocate(sizeof(MyBlock))) MyBlock(0)),
|
||||
lastBlock(firstBlock), firstFrameSizeEvent(0), lastFrameSizeEvent(0),
|
||||
ac(ac), frameSizeEventCount(0)
|
||||
lastBlock(firstBlock), firstFrameEvent(0), lastFrameEvent(0),
|
||||
ac(ac), frameEventCount(0)
|
||||
{ }
|
||||
|
||||
System* s;
|
||||
@ -176,10 +171,10 @@ class Context {
|
||||
uint8_t* result;
|
||||
MyBlock* firstBlock;
|
||||
MyBlock* lastBlock;
|
||||
MyFrameSizeEvent* firstFrameSizeEvent;
|
||||
MyFrameSizeEvent* lastFrameSizeEvent;
|
||||
MyFrameEvent* firstFrameEvent;
|
||||
MyFrameEvent* lastFrameEvent;
|
||||
ArchitectureContext* ac;
|
||||
unsigned frameSizeEventCount;
|
||||
unsigned frameEventCount;
|
||||
};
|
||||
|
||||
void NO_RETURN
|
||||
@ -466,52 +461,45 @@ padding(AlignmentPadding* p, unsigned start, unsigned offset,
|
||||
return padding;
|
||||
}
|
||||
|
||||
class MyFrameSizeEvent: public Assembler::FrameSizeEvent {
|
||||
class MyFrameEvent: public Assembler::FrameEvent {
|
||||
public:
|
||||
MyFrameSizeEvent(Context* c, Promise* offset, int change):
|
||||
c(c), next_(0), offset_(offset), change_(change)
|
||||
MyFrameEvent(Context* c, Promise* offset):
|
||||
c(c), next_(0), offset_(offset)
|
||||
{ }
|
||||
|
||||
virtual unsigned offset() {
|
||||
return offset_->value();
|
||||
}
|
||||
|
||||
virtual int change() {
|
||||
expect(c, change_ != FrameSizePoison);
|
||||
|
||||
return change_;
|
||||
}
|
||||
|
||||
virtual Assembler::FrameSizeEvent* next() {
|
||||
virtual Assembler::FrameEvent* next() {
|
||||
return next_;
|
||||
}
|
||||
|
||||
Context* c;
|
||||
MyFrameSizeEvent* next_;
|
||||
MyFrameEvent* next_;
|
||||
Promise* offset_;
|
||||
int change_;
|
||||
};
|
||||
|
||||
void
|
||||
appendFrameSizeEvent(Context* c, MyBlock* b, Promise* offset, int change)
|
||||
appendFrameEvent(Context* c, MyBlock* b, Promise* offset)
|
||||
{
|
||||
MyFrameSizeEvent* e = new (c->zone->allocate(sizeof(MyFrameSizeEvent)))
|
||||
MyFrameSizeEvent(c, offset, change);
|
||||
MyFrameEvent* e = new (c->zone->allocate(sizeof(MyFrameEvent)))
|
||||
MyFrameEvent(c, offset);
|
||||
|
||||
if (b->firstFrameSizeEvent) {
|
||||
b->lastFrameSizeEvent->next_ = e;
|
||||
if (b->firstFrameEvent) {
|
||||
b->lastFrameEvent->next_ = e;
|
||||
} else {
|
||||
b->firstFrameSizeEvent = e;
|
||||
b->firstFrameEvent = e;
|
||||
}
|
||||
b->lastFrameSizeEvent = e;
|
||||
b->lastFrameEvent = e;
|
||||
|
||||
++ c->frameSizeEventCount;
|
||||
++ c->frameEventCount;
|
||||
}
|
||||
|
||||
void
|
||||
appendFrameSizeEvent(Context* c, int change)
|
||||
appendFrameEvent(Context* c)
|
||||
{
|
||||
appendFrameSizeEvent(c, c->lastBlock, offset(c), change);
|
||||
appendFrameEvent(c, c->lastBlock, offset(c));
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
@ -2574,6 +2562,93 @@ absoluteRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
c->client->releaseTemporary(rdx);
|
||||
}
|
||||
|
||||
unsigned
|
||||
argumentFootprint(unsigned footprint)
|
||||
{
|
||||
return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
read4(uint8_t* p)
|
||||
{
|
||||
uint32_t v; memcpy(&v, p, 4);
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
nextFrame(ArchitectureContext* c, uint8_t* start, unsigned size,
|
||||
unsigned footprint, int32_t*, void*, void* stackLimit,
|
||||
unsigned targetParameterFootprint, void** ip, void** stack)
|
||||
{
|
||||
assert(c, *ip >= start);
|
||||
assert(c, *ip <= start + size);
|
||||
|
||||
uint8_t* instruction = static_cast<uint8_t*>(*ip);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
if (*start == 0x39) {
|
||||
// skip stack overflow check
|
||||
start += 11;
|
||||
}
|
||||
} else if (*start == 0x48 and start[1] == 0x39) {
|
||||
// skip stack overflow check
|
||||
start += 12;
|
||||
}
|
||||
|
||||
if (instruction <= start) {
|
||||
*ip = reinterpret_cast<void**>(*stack)[0];
|
||||
return;
|
||||
}
|
||||
|
||||
if (UseFramePointer) {
|
||||
// skip preamble
|
||||
start += (BytesPerWord == 4 ? 3 : 4);
|
||||
|
||||
if (instruction <= start or *instruction == 0x5d) {
|
||||
*ip = reinterpret_cast<void**>(*stack)[1];
|
||||
*stack = reinterpret_cast<void**>(*stack) + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (*instruction == 0xc3) {
|
||||
*ip = reinterpret_cast<void**>(*stack)[0];
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned offset = footprint + FrameHeaderSize
|
||||
- (stackLimit == *stack ? 1 : 0);
|
||||
|
||||
if (TailCalls) {
|
||||
if (argumentFootprint(targetParameterFootprint) > StackAlignmentInWords) {
|
||||
offset += argumentFootprint(targetParameterFootprint)
|
||||
- StackAlignmentInWords;
|
||||
}
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
if ((*instruction == 0x83 or *instruction == 0x81)
|
||||
and instruction[1] == 0xec)
|
||||
{
|
||||
offset
|
||||
-= (*instruction == 0x83 ? instruction[2] : read4(instruction + 2))
|
||||
/ BytesPerWord;
|
||||
}
|
||||
} else if (*instruction == 0x48
|
||||
and (instruction[1] == 0x83 or instruction[1] == 0x81)
|
||||
and instruction[2] == 0xec)
|
||||
{
|
||||
offset
|
||||
-= (instruction[1] == 0x83 ? instruction[3] : read4(instruction + 3))
|
||||
/ BytesPerWord;
|
||||
}
|
||||
|
||||
// todo: use frameTable to check for and handle tail calls
|
||||
}
|
||||
|
||||
*ip = reinterpret_cast<void**>(*stack)[offset];
|
||||
*stack = reinterpret_cast<void**>(*stack) + offset;
|
||||
}
|
||||
|
||||
void
|
||||
populateTables(ArchitectureContext* c)
|
||||
{
|
||||
@ -2771,7 +2846,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
|
||||
virtual unsigned argumentFootprint(unsigned footprint) {
|
||||
return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords);
|
||||
return local::argumentFootprint(footprint);
|
||||
}
|
||||
|
||||
virtual bool argumentAlignment() {
|
||||
@ -2900,6 +2975,16 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
- FrameHeaderSize;
|
||||
}
|
||||
|
||||
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
|
||||
int32_t* frameTable, void* link, void* stackLimit,
|
||||
unsigned targetParameterFootprint, void** ip,
|
||||
void** stack)
|
||||
{
|
||||
local::nextFrame(&c, static_cast<uint8_t*>(start), size, footprint,
|
||||
frameTable, link, stackLimit, targetParameterFootprint,
|
||||
ip, stack);
|
||||
}
|
||||
|
||||
virtual void* frameIp(void* stack) {
|
||||
return stack ? *static_cast<void**>(stack) : 0;
|
||||
}
|
||||
@ -3397,28 +3482,20 @@ class MyAssembler: public Assembler {
|
||||
|
||||
apply(Move, BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &base);
|
||||
|
||||
appendFrameSizeEvent(&c, 1);
|
||||
}
|
||||
|
||||
Constant footprintConstant(resolved(&c, footprint * BytesPerWord));
|
||||
apply(Subtract, BytesPerWord, ConstantOperand, &footprintConstant,
|
||||
BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, footprint);
|
||||
}
|
||||
|
||||
virtual void adjustFrame(unsigned difference) {
|
||||
appendFrameSizeEvent(&c, - difference);
|
||||
|
||||
Register stack(rsp);
|
||||
Constant differenceConstant(resolved(&c, difference * BytesPerWord));
|
||||
apply(Subtract, BytesPerWord, ConstantOperand, &differenceConstant,
|
||||
BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, difference);
|
||||
}
|
||||
|
||||
virtual void popFrame(unsigned frameFootprint) {
|
||||
@ -3428,19 +3505,13 @@ class MyAssembler: public Assembler {
|
||||
apply(Move, BytesPerWord, RegisterOperand, &base,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, - frameFootprint);
|
||||
|
||||
popR(&c, BytesPerWord, &base);
|
||||
|
||||
appendFrameSizeEvent(&c, - 1);
|
||||
} else {
|
||||
Register stack(rsp);
|
||||
Constant footprint(resolved(&c, frameFootprint * BytesPerWord));
|
||||
apply(Add, BytesPerWord, ConstantOperand, &footprint,
|
||||
BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, - frameFootprint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3451,13 +3522,18 @@ class MyAssembler: public Assembler {
|
||||
{
|
||||
if (TailCalls) {
|
||||
if (offset) {
|
||||
appendFrameEvent(&c);
|
||||
|
||||
Register tmp(c.client->acquireTemporary());
|
||||
|
||||
Memory returnAddressSrc(rsp, (frameFootprint + 1) * BytesPerWord);
|
||||
unsigned baseSize = UseFramePointer ? 1 : 0;
|
||||
|
||||
Memory returnAddressSrc
|
||||
(rsp, (frameFootprint + baseSize) * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp);
|
||||
|
||||
Memory returnAddressDst
|
||||
(rsp, (frameFootprint - offset + 1) * BytesPerWord);
|
||||
(rsp, (frameFootprint - offset + baseSize) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &tmp, BytesPerWord, &returnAddressDst);
|
||||
|
||||
c.client->releaseTemporary(tmp.low);
|
||||
@ -3470,11 +3546,9 @@ class MyAssembler: public Assembler {
|
||||
|
||||
Register stack(rsp);
|
||||
Constant footprint
|
||||
(resolved(&c, (frameFootprint - offset + 1) * BytesPerWord));
|
||||
(resolved(&c, (frameFootprint - offset + baseSize) * BytesPerWord));
|
||||
addCR(&c, BytesPerWord, &footprint, BytesPerWord, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, - (frameFootprint - offset + 1));
|
||||
|
||||
if (returnAddressSurrogate != NoRegister) {
|
||||
assert(&c, offset > 0);
|
||||
|
||||
@ -3507,6 +3581,8 @@ class MyAssembler: public Assembler {
|
||||
assert(&c, (argumentFootprint % StackAlignmentInWords) == 0);
|
||||
|
||||
if (TailCalls and argumentFootprint > StackAlignmentInWords) {
|
||||
appendFrameEvent(&c);
|
||||
|
||||
Register returnAddress(rcx);
|
||||
popR(&c, BytesPerWord, &returnAddress);
|
||||
|
||||
@ -3516,16 +3592,10 @@ class MyAssembler: public Assembler {
|
||||
* BytesPerWord));
|
||||
addCR(&c, BytesPerWord, &adjustment, BytesPerWord, &stack);
|
||||
|
||||
appendFrameSizeEvent(&c, - (argumentFootprint - StackAlignmentInWords));
|
||||
|
||||
jumpR(&c, BytesPerWord, &returnAddress);
|
||||
} else {
|
||||
return_(&c);
|
||||
}
|
||||
|
||||
// todo: this is not necessary if there are no instructions to
|
||||
// follow:
|
||||
appendFrameSizeEvent(&c, frameFootprint);
|
||||
}
|
||||
|
||||
virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint,
|
||||
@ -3536,16 +3606,10 @@ class MyAssembler: public Assembler {
|
||||
Register returnAddress(rcx);
|
||||
popR(&c, BytesPerWord, &returnAddress);
|
||||
|
||||
appendFrameSizeEvent(&c, -1);
|
||||
|
||||
Register stack(rsp);
|
||||
Memory stackSrc(rbx, stackOffsetFromThread);
|
||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &stack);
|
||||
|
||||
// we can't statically determine the frame size at this point, so
|
||||
// we poison any attempt to query for it:
|
||||
appendFrameSizeEvent(&c, FrameSizePoison);
|
||||
|
||||
jumpR(&c, BytesPerWord, &returnAddress);
|
||||
}
|
||||
|
||||
@ -3594,13 +3658,13 @@ class MyAssembler: public Assembler {
|
||||
c.result = dst;
|
||||
|
||||
for (MyBlock* b = c.firstBlock; b; b = b->next) {
|
||||
if (b->firstFrameSizeEvent) {
|
||||
if (c.firstFrameSizeEvent) {
|
||||
c.lastFrameSizeEvent->next_ = b->firstFrameSizeEvent;
|
||||
if (b->firstFrameEvent) {
|
||||
if (c.firstFrameEvent) {
|
||||
c.lastFrameEvent->next_ = b->firstFrameEvent;
|
||||
} else {
|
||||
c.firstFrameSizeEvent = b->firstFrameSizeEvent;
|
||||
c.firstFrameEvent = b->firstFrameEvent;
|
||||
}
|
||||
c.lastFrameSizeEvent = b->lastFrameSizeEvent;
|
||||
c.lastFrameEvent = b->lastFrameEvent;
|
||||
}
|
||||
|
||||
unsigned index = 0;
|
||||
@ -3656,12 +3720,12 @@ class MyAssembler: public Assembler {
|
||||
return c.code.length();
|
||||
}
|
||||
|
||||
virtual unsigned frameSizeEventCount() {
|
||||
return c.frameSizeEventCount;
|
||||
virtual unsigned frameEventCount() {
|
||||
return c.frameEventCount;
|
||||
}
|
||||
|
||||
virtual FrameSizeEvent* firstFrameSizeEvent() {
|
||||
return c.firstFrameSizeEvent;
|
||||
virtual FrameEvent* firstFrameEvent() {
|
||||
return c.firstFrameEvent;
|
||||
}
|
||||
|
||||
virtual void dispose() {
|
||||
|
12
src/x86.h
12
src/x86.h
@ -29,20 +29,20 @@
|
||||
# ifdef __APPLE__
|
||||
# if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32)
|
||||
# define IP_REGISTER(context) (context->uc_mcontext->__ss.__eip)
|
||||
# define BASE_REGISTER(context) (context->uc_mcontext->__ss.__ebp)
|
||||
# define STACK_REGISTER(context) (context->uc_mcontext->__ss.__esp)
|
||||
# define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__ebx)
|
||||
# define LINK_REGISTER(context) (context->uc_mcontext->__ss.__ecx)
|
||||
# else
|
||||
# define IP_REGISTER(context) (context->uc_mcontext->ss.eip)
|
||||
# define BASE_REGISTER(context) (context->uc_mcontext->ss.ebp)
|
||||
# define STACK_REGISTER(context) (context->uc_mcontext->ss.esp)
|
||||
# define THREAD_REGISTER(context) (context->uc_mcontext->ss.ebx)
|
||||
# define LINK_REGISTER(context) (context->uc_mcontext->ss.ecx)
|
||||
# endif
|
||||
# else
|
||||
# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_EIP])
|
||||
# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_EBP])
|
||||
# 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])
|
||||
# endif
|
||||
|
||||
extern "C" uint64_t
|
||||
@ -65,20 +65,20 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t*,
|
||||
# ifdef __APPLE__
|
||||
# if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32)
|
||||
# define IP_REGISTER(context) (context->uc_mcontext->__ss.__rip)
|
||||
# define BASE_REGISTER(context) (context->uc_mcontext->__ss.__rbp)
|
||||
# define STACK_REGISTER(context) (context->uc_mcontext->__ss.__rsp)
|
||||
# define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__rbx)
|
||||
# define LINK_REGISTER(context) (context->uc_mcontext->__ss.__rcx)
|
||||
# else
|
||||
# define IP_REGISTER(context) (context->uc_mcontext->ss.rip)
|
||||
# define BASE_REGISTER(context) (context->uc_mcontext->ss.rbp)
|
||||
# define STACK_REGISTER(context) (context->uc_mcontext->ss.rsp)
|
||||
# define THREAD_REGISTER(context) (context->uc_mcontext->ss.rbx)
|
||||
# define LINK_REGISTER(context) (context->uc_mcontext->ss.rcx)
|
||||
# endif
|
||||
# else
|
||||
# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP])
|
||||
# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP])
|
||||
# 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])
|
||||
# endif
|
||||
|
||||
extern "C" uint64_t
|
||||
|
Loading…
x
Reference in New Issue
Block a user