From fb5c0bfebd762258f7dc66baae85270a9a353e31 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sat, 29 Jan 2011 11:10:54 -0700 Subject: [PATCH] fix ARM stack unwinding --- src/arm.cpp | 48 ++++++++++++++++++++++++----------------------- src/compile-arm.S | 23 ++++++++--------------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/arm.cpp b/src/arm.cpp index 990c08f89a..8db2de4692 100644 --- a/src/arm.cpp +++ b/src/arm.cpp @@ -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(*stack)[offset]; + *ip = reinterpret_cast(*stack)[offset - 1]; *stack = reinterpret_cast(*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() { diff --git a/src/compile-arm.S b/src/compile-arm.S index 102db1a541..a7b0963a49 100644 --- a/src/compile-arm.S +++ b/src/compile-arm.S @@ -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):