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

View File

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