fix ARM stack unwinding

This commit is contained in:
Joel Dice 2011-01-29 11:10:54 -07:00
parent 17449eaf1b
commit fb5c0bfebd
2 changed files with 33 additions and 38 deletions

View File

@ -872,19 +872,13 @@ addC(Context* c, unsigned size, Assembler::Constant* a,
int32_t v = a->value->value(); int32_t v = a->value->value();
if (v) { if (v) {
if (v > 0 and v < 1024 and v % 4 == 0) { if (v > 0 and v < 256) {
emit(c, addi(dst->low, b->low, v));
} else if (v > 0 and v < 1024 and v % 4 == 0) {
emit(c, addi(dst->low, b->low, v >> 2, 15)); emit(c, addi(dst->low, b->low, v >> 2, 15));
} else { } else {
emit(c, addi(dst->low, b->low, lo8(v))); // todo
if (not isOfWidth(v, 8)) { abort(c);
emit(c, addi(dst->low, b->low, hi8(v), 12));
if (not isOfWidth(v, 16)) {
emit(c, addi(dst->low, b->low, lo8(hi16(v)), 8));
if (not isOfWidth(v, 24)) {
emit(c, addi(dst->low, b->low, hi8(hi16(v)), 4));
}
}
}
} }
} else { } else {
moveRR(c, size, b, size, dst); moveRR(c, size, b, size, dst);
@ -898,14 +892,17 @@ subC(Context* c, unsigned size, Assembler::Constant* a,
assert(c, size == BytesPerWord); assert(c, size == BytesPerWord);
int32_t v = a->value->value(); int32_t v = a->value->value();
if (v) {
if (v > 0 and v < 256) { if (v > 0 and v < 256) {
emit(c, subi(dst->low, b->low, v)); emit(c, subi(dst->low, b->low, v));
} else if (v > 0 and v < 1024 and v % 4 == 0) { } else if (v > 0 and v < 1024 and v % 4 == 0) {
emit(c, subi(dst->low, b->low, v >> 2, 15)); emit(c, subi(dst->low, b->low, v >> 2, 15));
} else { } else {
ResolvedPromise promise(- v); // todo
Assembler::Constant constant(&promise); abort(c);
addC(c, size, &constant, b, dst); }
} else {
moveRR(c, size, b, size, dst);
} }
} }
@ -1613,9 +1610,15 @@ memoryBarrier(Context*) {}
// END OPERATION COMPILERS // END OPERATION COMPILERS
unsigned
argumentFootprint(unsigned footprint)
{
return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords);
}
void void
nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED, nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
unsigned footprint, int32_t*, void* link, void* stackLimit, unsigned footprint, int32_t*, void* link, void*,
unsigned targetParameterFootprint UNUSED, void** ip, void** stack) unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
{ {
assert(c, *ip >= start); assert(c, *ip >= start);
@ -1633,8 +1636,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
return; return;
} }
unsigned offset = footprint + FrameHeaderSize unsigned offset = footprint + FrameHeaderSize;
- (stackLimit == *stack ? 1 : 0);
if (instruction <= start + 2) { if (instruction <= start + 2) {
*ip = link; *ip = link;
@ -1658,7 +1660,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
// todo: use frameTable to check for and handle tail calls // todo: use frameTable to check for and handle tail calls
} }
*ip = reinterpret_cast<void**>(*stack)[offset]; *ip = reinterpret_cast<void**>(*stack)[offset - 1];
*stack = reinterpret_cast<void**>(*stack) + offset; *stack = reinterpret_cast<void**>(*stack) + offset;
} }
@ -1810,7 +1812,7 @@ class MyArchitecture: public Assembler::Architecture {
} }
virtual unsigned argumentFootprint(unsigned footprint) { virtual unsigned argumentFootprint(unsigned footprint) {
return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords); return ::argumentFootprint(footprint);
} }
virtual bool argumentAlignment() { virtual bool argumentAlignment() {

View File

@ -23,6 +23,7 @@
#endif #endif
#define THREAD_STACK 2148 #define THREAD_STACK 2148
#define THREAD_SCRATCH 2152
#define THREAD_CONTINUATION 2156 #define THREAD_CONTINUATION 2156
#define THREAD_EXCEPTION 44 #define THREAD_EXCEPTION 44
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2160 #define THREAD_EXCEPTION_STACK_ADJUSTMENT 2160
@ -50,18 +51,14 @@ GLOBAL(vmInvoke):
[sp, #4] : returnType [sp, #4] : returnType
*/ */
// save stack frame
mov ip, sp
// save all non-volatile registers // save all non-volatile registers
stmfd sp!, {r4-r11, lr} stmfd sp!, {r4-r11, lr}
// save return type // save return type
ldr r4, [ip, #4] ldr r4, [sp, #4]
str r4, [sp, #-4]! str r4, [sp, #-4]!
// we're at the bottom of our local stack frame; save it str sp, [r0, #THREAD_SCRATCH]
mov ip, sp
// align stack, if necessary // align stack, if necessary
eor r4, sp, r3 eor r4, sp, r3
@ -82,9 +79,6 @@ LOCAL(vmInvoke_argumentTest):
cmp r4, r3 cmp r4, r3
blt LOCAL(vmInvoke_argumentLoop) blt LOCAL(vmInvoke_argumentLoop)
// save frame
str ip, [sp, #-8]!
// we use r8 to hold the thread pointer, by convention // we use r8 to hold the thread pointer, by convention
mov r8, r0 mov r8, r0
@ -93,17 +87,16 @@ LOCAL(vmInvoke_argumentTest):
.globl GLOBAL(vmInvoke_returnAddress) .globl GLOBAL(vmInvoke_returnAddress)
GLOBAL(vmInvoke_returnAddress): GLOBAL(vmInvoke_returnAddress):
// restore stack pointer
// restore frame ldr sp, [r8, #THREAD_SCRATCH]
ldr sp, [sp]
// clear MyThread::stack to avoid confusing another thread calling // clear MyThread::stack to avoid confusing another thread calling
// java.lang.Thread.getStackTrace on this one. See // java.lang.Thread.getStackTrace on this one. See
// MyProcess::getStackTrace in compile.cpp for details on how we get // MyProcess::getStackTrace in compile.cpp for details on how we get
// a reliable stack trace from a thread that might be interrupted at // a reliable stack trace from a thread that might be interrupted at
// any point in its execution. // any point in its execution.
mov r5,#0 mov r5, #0
str r5,[r8,#THREAD_STACK] str r5, [r8, #THREAD_STACK]
.globl GLOBAL(vmInvoke_safeStack) .globl GLOBAL(vmInvoke_safeStack)
GLOBAL(vmInvoke_safeStack): GLOBAL(vmInvoke_safeStack):