diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 4e1addb40a..b016422b19 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -877,6 +877,8 @@ static int common2(mz_jit_state *jitter, void *_data) jit_jmpr(JIT_R2); CHECK_LIMIT(); + scheme_jit_register_sub_func(jitter, sjc.stack_cache_pop_code, scheme_false); + /* *** bad_app_vals_target *** */ /* Non-proc is in R0 */ sjc.bad_app_vals_target = jit_get_ip(); diff --git a/racket/src/racket/src/jitstack.c b/racket/src/racket/src/jitstack.c index 9b54edadc8..81c219134b 100644 --- a/racket/src/racket/src/jitstack.c +++ b/racket/src/racket/src/jitstack.c @@ -161,10 +161,10 @@ static void set_cache(void *p, Scheme_Object *last) Scheme_Object *scheme_native_stack_trace(void) { - void *p, *q, *prev_frame_p; + void *p, *q, *cache_frame_p; uintptr_t stack_end, real_stack_end, stack_start, halfway; Scheme_Object *name, *last = NULL, *first = NULL, *tail; - int prev_had_name = 0; + int cache_had_name = 0; #ifdef MZ_USE_DWARF_LIBUNWIND unw_context_t cx; unw_cursor_t c; @@ -318,15 +318,14 @@ Scheme_Object *scheme_native_stack_trace(void) } #endif - prev_frame_p = NULL; + cache_frame_p = NULL; while (unsuccess < UNKNOWN_FRAME_LIMIT) { #ifdef MZ_USE_DWARF_LIBUNWIND - if (use_unw) { + if (use_unw) q = (void *)unw_get_ip(&c); - } else { + else q = NULL; - } #endif if (!use_unw) { @@ -407,6 +406,21 @@ Scheme_Object *scheme_native_stack_trace(void) name = NULL; } +#ifdef MZ_USE_DWARF_LIBUNWIND + if (use_unw) { + if (manual_unw) { + cache_frame_p = (void **)unw_get_frame_pointer(&c); + if (!(STK_COMP((uintptr_t)cache_frame_p, stack_end) + && STK_COMP(stack_start, (uintptr_t)cache_frame_p))) + break; + cache_had_name = name && (last || !SCHEME_NULLP(name)); + } else { + cache_frame_p = NULL; + cache_had_name = 0; + } + } +#endif + if (name && !SCHEME_NULLP(name)) { /* null is used to help unwind without a true name */ name = scheme_make_pair(name, scheme_null); if (last) @@ -433,16 +447,17 @@ Scheme_Object *scheme_native_stack_trace(void) might not be used (depending on how the C compiler optimized the code); any frame whose procedure has a name is JITted code, so it will use the return address from the stack. */ - if (STK_COMP((uintptr_t)halfway, (uintptr_t)prev_frame_p) - && prev_had_name) { - set_cache(prev_frame_p, last); + if (STK_COMP((uintptr_t)halfway, (uintptr_t)cache_frame_p) + && cache_had_name) { + set_cache(cache_frame_p, last); if (!added_list_elem) shift_cache_to_next = 1; halfway = stack_end; - unsuccess = -100000; /* if we got halfway, no need to bail out later */ + unsuccess = -8 * UNKNOWN_FRAME_LIMIT; /* if we got halfway, less likely to bail out later */ } - prev_had_name = !!name; + if (!use_unw) + cache_had_name = !!name; #ifdef MZ_USE_DWARF_LIBUNWIND if (use_unw) { @@ -453,7 +468,6 @@ Scheme_Object *scheme_native_stack_trace(void) if (!(STK_COMP((uintptr_t)pp, stack_end) && STK_COMP(stack_start, (uintptr_t)pp))) break; - prev_frame_p = pp; # ifdef MZ_USE_JIT_ARM stack_addr = (unw_word_t)&(pp[JIT_NEXT_FP_OFFSET+2]); unw_manual_step(&c, @@ -468,7 +482,6 @@ Scheme_Object *scheme_native_stack_trace(void) # endif manual_unw = 0; } else { - prev_frame_p = NULL; unw_step(&c); q = (void *)unw_get_ip(&c); if (unw_reset_bad_ptr_flag(&c)) @@ -482,12 +495,12 @@ Scheme_Object *scheme_native_stack_trace(void) if (STK_COMP((uintptr_t)q, (uintptr_t)p)) break; p = q; - prev_frame_p = p; + cache_frame_p = p; } } if (shift_cache_to_next) - stack_cache_stack[stack_cache_stack_pos].cache = scheme_null; + stack_cache_stack[stack_cache_stack_pos].cache = tail; #ifdef MZ_USE_DWARF_LIBUNWIND unw_destroy_local(&c);