limit time for getting a native (JIT) stack trace
It's possible for a deep recursion to be all in C instead of JIT-generated code, in which case the caching code for `current-continuation-mark' cannot kick in to make the operation effectively constant time. Bail out (to keep things constant time) if that happens.
This commit is contained in:
parent
012ef60cd5
commit
534886dbe4
|
@ -70,6 +70,14 @@ typedef void *(*Get_Stack_Proc)();
|
|||
|
||||
#define CACHE_STACK_MIN_TRIGGER 128
|
||||
|
||||
/* Normally, caching of a native trace on the stack ensures that
|
||||
`current-continuation-marks' is effectively constant-time.
|
||||
It's possible to have a deep stack section with no recognizable anchors
|
||||
for caching, however, in which case `current-continuation-marks'
|
||||
can become O(n); avoid that pathological case by limiting the
|
||||
number of non-anchor frames in a row that we're willing to traverse. */
|
||||
#define UNKNOWN_FRAME_LIMIT 64
|
||||
|
||||
#define USE_STACK_CHECK 0
|
||||
|
||||
#if USE_STACK_CHECK
|
||||
|
@ -134,6 +142,7 @@ Scheme_Object *scheme_native_stack_trace(void)
|
|||
int use_unw = 0;
|
||||
int shift_cache_to_next = 0;
|
||||
int added_list_elem;
|
||||
int unsuccess = 0;
|
||||
|
||||
if (!sjc.get_stack_pointer_code)
|
||||
return NULL;
|
||||
|
@ -180,7 +189,7 @@ Scheme_Object *scheme_native_stack_trace(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
while (1) {
|
||||
while (unsuccess < UNKNOWN_FRAME_LIMIT) {
|
||||
#ifdef MZ_USE_DWARF_LIBUNWIND
|
||||
if (use_unw) {
|
||||
q = (void *)unw_get_ip(&c);
|
||||
|
@ -270,9 +279,14 @@ Scheme_Object *scheme_native_stack_trace(void)
|
|||
shift_cache_to_next = 0;
|
||||
}
|
||||
added_list_elem = 1;
|
||||
} else
|
||||
} else
|
||||
added_list_elem = 0;
|
||||
|
||||
if (!name)
|
||||
unsuccess++;
|
||||
else
|
||||
unsuccess = 0;
|
||||
|
||||
/* Cache the result halfway up the stack, if possible. Only cache
|
||||
on frames where the previous frame had a return address with a
|
||||
name, because an arbitrary frame's return address on the stack
|
||||
|
@ -300,6 +314,8 @@ Scheme_Object *scheme_native_stack_trace(void)
|
|||
shift_cache_to_next = 1;
|
||||
|
||||
halfway = stack_end;
|
||||
|
||||
unsuccess = -100000; /* if we got halfway, no need to bail out later */
|
||||
}
|
||||
|
||||
prev_had_name = !!name;
|
||||
|
|
Loading…
Reference in New Issue
Block a user