================
@@ -21,10 +21,40 @@
class StateMatchContext:
"""Class that holds any state needed for matching state nodes to debugger
state across a run."""
- def __init__(self):
+ def __init__(self, check_condition: Callable[[StepIR, int, str], bool]):
self.where_hit_counts: Counter[Where] = Counter()
self.expired_wheres: Set[Where] = set()
self._last_match_result: Optional[StateMatchResult] = None
+ # To avoid constantly re-evaluating conditions above the current
function, and potentially causing them to
+ # be unfulfillable if we have imperfect stack unwinding, we track
conditions that have been found True for state
+ # nodes above the current function and consider those conditions true
until we return to/pass that frame.
+ # Key is a frame index counting from the root upwards, to keep stable
as we grow and shrink the stack.
+ self._cached_frame_conditions: Dict[int, Dict[str, bool]] =
defaultdict(dict)
+ self._check_condition = check_condition
+
+ def check_condition(self, step: StepIR, frame_idx: int, condition: str) ->
bool:
+ reverse_frame_idx = step.num_frames - frame_idx - 1
+ cached_conditions = self._cached_frame_conditions[reverse_frame_idx]
+ if condition in cached_conditions:
+ return cached_conditions[condition]
+ # In an ideal world we would always cache conditions in a callee frame
before moving to a called frame, but
+ # some optimized code makes this infeasible, so we settle for
computing it after reaching the called frame
+ # instead.
+ result = self._check_condition(step, frame_idx, condition)
+ # We cache this now, but we won't actually use it *unless* we end up
stepping into a lower frame next step.
----------------
OCHyams wrote:
lower -> root/leaf child/parent etc would be clearer
https://github.com/llvm/llvm-project/pull/203847
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits