Package ghidra.trace.model.time.schedule

# Class TraceSchedule

java.lang.Object
ghidra.trace.model.time.schedule.TraceSchedule

All Implemented Interfaces:
  `Comparable<TraceSchedule>`

public class TraceSchedule extends Object implements Comparable<TraceSchedule>
A sequence of emulator stepping commands, essentially comprising a "point in time."

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static enum`
  `TraceSchedule.ScheduleForm`
  Specifies forms of a stepping schedule.
  `static enum`
  `TraceSchedule.Source`
  `static final record`
  `TraceSchedule.StepAndKind`
  Indicates a step and which kind (instruction or p-code)
  `static enum`
  `TraceSchedule.TimeRadix`
  Format for rendering and parsing snaps and step counts

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final TraceSchedule`
  `ZERO`
  The initial snapshot (with no steps)

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `TraceSchedule(long snap, Sequence steps, Sequence pSteps)`
  Construct the given schedule, but assumed abnormal
  `TraceSchedule(long snap, Sequence steps, Sequence pSteps, TraceSchedule.Source source)`
  Construct the given schedule

- ## Method Summary

  Modifier and Type
  Method
  Description
  `TraceSchedule`
  `advanced(TraceSchedule next)`
  Compute the schedule resulting from this schedule advanced by the given schedule
  `TraceSchedule`
  `assumeRecorded()`
  `CompareResult`
  `compareSchedule(TraceSchedule that)`
  Richly compare two schedules
  `int`
  `compareTo(TraceSchedule o)`
  `boolean`
  `differsOnlyByPatch(TraceSchedule that)`
  `protected TraceSchedule`
  `doSteppedBackward(Trace trace, long tickCount, Set<Long> visited)`
  `TraceSchedule`
  `dropLastStep()`
  Drop the last step
  `TraceSchedule`
  `dropPSteps()`
  Drop the p-code steps
  `boolean`
  `equals(Object obj)`
  `void`
  `execute(Trace trace, PcodeMachine<?> machine, TaskMonitor monitor)`
  Realize the machine state for this schedule using the given trace and machine
  `void`
  `finish(Trace trace, TraceSchedule position, PcodeMachine<?> machine, TaskMonitor monitor)`
  Realize the machine state for this schedule using the given trace and pre-positioned machine
  `TraceThread`
  `getEventThread(Trace trace)`
  Get the event thread for this schedule in the context of the given trace
  `TraceThread`
  `getLastThread(Trace trace)`
  Get the last thread stepped by this schedule in the context of the given trace
  `long`
  `getLastThreadKey()`
  Get the last thread key stepped by this schedule
  `long`
  `getSnap()`
  Get the source snapshot
  `Set<TraceThread>`
  `getThreads(Trace trace)`
  Get the threads involved in the schedule
  `int`
  `hashCode()`
  `boolean`
  `hasPSteps()`
  Check if this schedule has p-code steps
  `boolean`
  `hasSteps()`
  Check if this schedule has instruction steps
  `boolean`
  `isSnapOnly()`
  Check if this schedule requires any stepping
  `TraceSchedule.StepAndKind`
  `lastStep()`
  Returns the last step of the schedule.
  `static TraceSchedule`
  `parse(String spec)`
  As in `parse(String, TimeRadix)`, but with the `TraceSchedule.TimeRadix.DEFAULT` radix.
  `static TraceSchedule`
  `parse(String spec, TraceSchedule.Source source, TraceSchedule.TimeRadix radix)`
  Parse schedule in the form "`snap[:steps[.pSteps]]`"
  `static TraceSchedule`
  `parse(String spec, TraceSchedule.TimeRadix radix)`
  As in `parse(String, Source, TimeRadix)`, but assumed abnormal
  `long`
  `patchCount()`
  Compute the number of patches, excluding p-code patches
  `TraceSchedule`
  `patched(TraceThread thread, Language language, String sleigh)`
  Returns the equivalent of executing this schedule then performing a given patch
  `TraceSchedule`
  `patched(TraceThread thread, Language language, List<String> sleigh)`
  Returns the equivalent of executing this schedule then performing the given patches
  `long`
  `pPatchCount()`
  Compute the number of p-code patches applied
  `long`
  `pTickCount()`
  Compute the number of p-code ticks taken
  `TraceThread`
  `requireLastThread(Trace trace)`
  Get the last thread stepped by this schedule in the context of the given trace
  `TraceSchedule`
  `skippedForward(TraceThread thread, long tickCount)`
  Behaves as in `steppedForward(TraceThread, long)`, but by appending skips
  `TraceSchedule`
  `skippedPcodeForward(TraceThread thread, int pTickCount)`
  Behaves as in `steppedPcodeForward(TraceThread, int)`, but by appending skips
  `static final TraceSchedule`
  `snap(long snap)`
  Create a schedule that consists solely of a snapshot
  `int`
  `stepCount()`
  Count the number of steps, excluding p-code steps
  `TraceSchedule`
  `steppedBackward(Trace trace, long stepCount)`
  Returns the equivalent of executing count instructions (and all p-code operations) less than this schedule
  `TraceSchedule`
  `steppedForward(TraceThread thread, long tickCount)`
  Returns the equivalent of executing the schedule (ignoring p-code steps) followed by stepping the given thread count more instructions
  `TraceSchedule`
  `steppedPcodeBackward(int pStepCount)`
  Returns the equivalent of executing count p-code operations less than this schedule
  `TraceSchedule`
  `steppedPcodeForward(TraceThread thread, int pTickCount)`
  Returns the equivalent of executing the schedule followed by stepping the given thread `pTickCount` more p-code operations
  `long`
  `tickCount()`
  Compute the number of ticks taken, excluding p-code ticks
  `String`
  `toString()`
  `String`
  `toString(TraceSchedule.TimeRadix radix)`
  `long`
  `totalPatchCount()`
  Compute the total number of patches applied
  `long`
  `totalTickCount()`
  Compute the total number of ticks taken, including the p-code ticks
  `TraceSchedule`
  `truncateToSteps(int count)`
  Drop all p-code steps, if any, and enough instruction steps, such that `stepCount()` returns the given count.
  `void`
  `validate(Trace trace)`
  Validate this schedule for the given trace

  ### Methods inherited from class java.lang.Object

  `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### ZERO

    public static final TraceSchedule ZERO
    The initial snapshot (with no steps)

- ## Constructor Details

  - ### TraceSchedule

    public TraceSchedule(long snap, Sequence steps, Sequence pSteps, TraceSchedule.Source source)
    Construct the given schedule
    Parameters:
      `snap` - the initial trace snapshot
      `steps` - the step sequence
      `pSteps` - the p-code step sequence
      `source` - if the p-code steps are known not to exceed one instruction

  - ### TraceSchedule

    public TraceSchedule(long snap, Sequence steps, Sequence pSteps)
    Construct the given schedule, but assumed abnormal
    Parameters:
      `snap` - the initial trace snapshot
      `steps` - the step sequence
      `pSteps` - the p-code step sequence

- ## Method Details

  - ### snap

    public static final TraceSchedule snap(long snap)
    Create a schedule that consists solely of a snapshot
    Parameters:
      `snap` - the snapshot key
    Returns:
      the schedule

  - ### parse

    public static TraceSchedule parse(String spec, TraceSchedule.Source source, TraceSchedule.TimeRadix radix)
    Parse schedule in the form "`snap[:steps[.pSteps]]`"

    A schedule consists of a snap, a optional `Sequence` of thread instruction-level steps, and optional p-code-level steps (pSteps). The form of `steps` and `pSteps` is specified by `Sequence.parse(String, TimeRadix)`. Each sequence consists of stepping selected threads forward, and/or patching machine state.

    Parameters:
      `spec` - the string specification
      `source` - the presumed source of the schedule
      `radix` - the radix
    Returns:
      the parsed schedule

  - ### parse

    public static TraceSchedule parse(String spec, TraceSchedule.TimeRadix radix)
    As in `parse(String, Source, TimeRadix)`, but assumed abnormal
    Parameters:
      `spec` - the string specification
      `radix` - the radix
    Returns:
      the parsed schedule

  - ### parse

    public static TraceSchedule parse(String spec)
    As in `parse(String, TimeRadix)`, but with the `TraceSchedule.TimeRadix.DEFAULT` radix.
    Parameters:
      `spec` - the string specification
    Returns:
      the parse sequence

  - ### toString

    public String toString()
    Overrides:
      `toString` in class `Object`

  - ### toString

    public String toString(TraceSchedule.TimeRadix radix)

  - ### compareSchedule

    public CompareResult compareSchedule(TraceSchedule that)
    Richly compare two schedules

    Schedules starting at different snapshots are never related, because there is no emulator/simulator stepping action which advances to the next snapshot. Though p-code steps may comprise a partial step, we do not consider a partial step to be a prefix of a full step, since we cannot know a priori how many p-code steps comprise a full instruction step. Consider, e.g., the user may specify 100 p-code steps, which could effect 20 instruction steps.

    Parameters:
      `that` - the object of comparison (this being the subject)
    Returns:
      a result describing the relationship from subject to object

  - ### equals

    public boolean equals(Object obj)
    Overrides:
      `equals` in class `Object`

  - ### hashCode

    public int hashCode()
    Overrides:
      `hashCode` in class `Object`

  - ### compareTo

    public int compareTo(TraceSchedule o)
    Specified by:
      `compareTo` in interface `Comparable<TraceSchedule>`

  - ### isSnapOnly

    public boolean isSnapOnly()
    Check if this schedule requires any stepping
    Returns:
      true if no stepping is required, i.e., the resulting state can be realized simply by loading a snapshot

  - ### hasSteps

    public boolean hasSteps()
    Check if this schedule has instruction steps
    Returns:
      true if this indicates at least one instruction step

  - ### hasPSteps

    public boolean hasPSteps()
    Check if this schedule has p-code steps
    Returns:
      true if this indicates at least one instruction step

  - ### getSnap

    public long getSnap()
    Get the source snapshot
    Returns:
      the snapshot key

  - ### getLastThreadKey

    public long getLastThreadKey()
    Get the last thread key stepped by this schedule
    Returns:
      the thread key

  - ### getEventThread

    public TraceThread getEventThread(Trace trace)
    Get the event thread for this schedule in the context of the given trace

    This is the thread stepped when no thread is specified for the first step of the sequence.

    Parameters:
      `trace` - the trace containing the source snapshot and threads
    Returns:
      the thread to use as "last thread" for the sequence

  - ### getLastThread

    public TraceThread getLastThread(Trace trace)
    Get the last thread stepped by this schedule in the context of the given trace
    Parameters:
      `trace` - the trace containing the source snapshot and threads
    Returns:
      the thread last stepped, or the "event thread" when no steps are taken, or null

  - ### requireLastThread

    public TraceThread requireLastThread(Trace trace)
    Get the last thread stepped by this schedule in the context of the given trace
    Parameters:
      `trace` - the trace containing the source snapshot and threads
    Returns:
      the thread last stepped, or the "event thread" when no steps are taken
    Throws:
      `IllegalArgumentException` - if the last thread cannot be determined from this schedule and the given trace.

  - ### totalTickCount

    public long totalTickCount()
    Compute the total number of ticks taken, including the p-code ticks

    This is suitable for use with `TaskMonitor.initialize(long)`, where that monitor will be passed to `execute(Trace, PcodeMachine, TaskMonitor)` or similar. Note that patch steps do not count as ticks.

    Returns:
      the number of ticks

  - ### totalPatchCount

    public long totalPatchCount()
    Compute the total number of patches applied
    Returns:
      the number of patches

  - ### tickCount

    public long tickCount()
    Compute the number of ticks taken, excluding p-code ticks
    Returns:
      the number of ticks

  - ### stepCount

    public int stepCount()
    Count the number of steps, excluding p-code steps
    Returns:
      the number of steps

  - ### patchCount

    public long patchCount()
    Compute the number of patches, excluding p-code patches
    Returns:
      the number of patches

  - ### pTickCount

    public long pTickCount()
    Compute the number of p-code ticks taken
    Returns:
      the number of ticks

  - ### pPatchCount

    public long pPatchCount()
    Compute the number of p-code patches applied
    Returns:
      the number of patches

  - ### execute

    public void execute(Trace trace, PcodeMachine<?> machine, TaskMonitor monitor) throws CancelledException
    Realize the machine state for this schedule using the given trace and machine

    This method executes this schedule and trailing p-code steps on the given machine, assuming that machine is already "positioned" at the initial snapshot. Assuming successful execution, that machine is now said to be "positioned" at this schedule, and its state is the result of said execution.

    Parameters:
      `trace` - the trace containing the source snapshot and threads
      `machine` - a machine bound to the trace whose current state reflects the initial snapshot
      `monitor` - a monitor for cancellation and progress reporting
    Throws:
      `CancelledException` - if the execution is cancelled

  - ### validate

    public void validate(Trace trace)
    Validate this schedule for the given trace

    This performs a dry run of the sequence on the given trace. If the schedule starts on the "last thread," it verifies the snapshot gives the event thread. It also checks that every thread key in the sequence exists in the trace.

    Parameters:
      `trace` - the trace against which to validate this schedule

  - ### finish

    public void finish(Trace trace, TraceSchedule position, PcodeMachine<?> machine, TaskMonitor monitor) throws CancelledException
    Realize the machine state for this schedule using the given trace and pre-positioned machine

    This method executes the remaining steps of this schedule and trailing p-code steps on the given machine, assuming that machine is already "positioned" at another given schedule. Assuming successful execution, that machine is now said to be "positioned" at this schedule, and its state is the result of said execution.

    Parameters:
      `trace` - the trace containing the source snapshot and threads
      `position` - the current schedule of the given machine
      `machine` - a machine bound to the trace whose current state reflects the given position
      `monitor` - a monitor for cancellation and progress reporting
    Throws:
      `CancelledException` - if the execution is cancelled
      `IllegalArgumentException` - if the given position is not a prefix of this schedule

  - ### steppedForward

    public TraceSchedule steppedForward(TraceThread thread, long tickCount)
    Returns the equivalent of executing the schedule (ignoring p-code steps) followed by stepping the given thread count more instructions

    This schedule is left unmodified. If it had any p-code steps, those steps are dropped in the resulting schedule.

    Parameters:
      `thread` - the thread to step, or null for the "last thread"
      `tickCount` - the number of ticks to take the thread forward
    Returns:
      the resulting schedule

  - ### skippedForward

    public TraceSchedule skippedForward(TraceThread thread, long tickCount)
    Behaves as in `steppedForward(TraceThread, long)`, but by appending skips
    Parameters:
      `thread` - the thread to step, or null for the "last thread"
      `tickCount` - the number of skips to take the thread forward
    Returns:
      the resulting schedule

  - ### doSteppedBackward

    protected TraceSchedule doSteppedBackward(Trace trace, long tickCount, Set<Long> visited)

  - ### steppedBackward

    public TraceSchedule steppedBackward(Trace trace, long stepCount)
    Returns the equivalent of executing count instructions (and all p-code operations) less than this schedule

    This schedule is left unmodified. If it had any p-code steps, those steps and subsequent patches are dropped in the resulting schedule. If count exceeds this schedule's steps, it will try (recursively) to step the source snapshot's schedule backward, if known. Both ticks and patches counts as steps.

    Parameters:
      `trace` - the trace of this schedule, for context
      `stepCount` - the number of steps to take backward
    Returns:
      the resulting schedule or null if it cannot be computed

  - ### steppedPcodeForward

    public TraceSchedule steppedPcodeForward(TraceThread thread, int pTickCount)
    Returns the equivalent of executing the schedule followed by stepping the given thread `pTickCount` more p-code operations
    Parameters:
      `thread` - the thread to step, or null for the "last thread"
      `pTickCount` - the number of p-code ticks to take the thread forward
    Returns:
      the resulting schedule

  - ### skippedPcodeForward

    public TraceSchedule skippedPcodeForward(TraceThread thread, int pTickCount)
    Behaves as in `steppedPcodeForward(TraceThread, int)`, but by appending skips
    Parameters:
      `thread` - the thread to step, or null for the "last thread"
      `pTickCount` - the number of p-code skips to take the thread forward
    Returns:
      the resulting schedule

  - ### steppedPcodeBackward

    public TraceSchedule steppedPcodeBackward(int pStepCount)
    Returns the equivalent of executing count p-code operations less than this schedule

    If `pStepCount` exceeds the p-code steps of this schedule, null is returned, since we cannot know a priori how many p-code steps would be required to complete the preceding instruction step. Both p-code ticks and p-code patches counts as p-code steps.

    Parameters:
      `pStepCount` - the number of p-code steps to take backward
    Returns:
      the resulting schedule or null if it cannot be computed

  - ### patched

    public TraceSchedule patched(TraceThread thread, Language language, String sleigh)
    Returns the equivalent of executing this schedule then performing a given patch
    Parameters:
      `thread` - the thread context for the patch; cannot be null
      `language` - the sleigh language for the patch
      `sleigh` - a single line of sleigh, excluding the terminating semicolon.
    Returns:
      the resulting schedule

  - ### patched

    public TraceSchedule patched(TraceThread thread, Language language, List<String> sleigh)
    Returns the equivalent of executing this schedule then performing the given patches
    Parameters:
      `thread` - the thread context for the patch; cannot be null
      `language` - the sleigh language for the patch
      `sleigh` - the lines of sleigh, excluding the terminating semicolons
    Returns:
      the resulting schedule

  - ### advanced

    public TraceSchedule advanced(TraceSchedule next)
    Compute the schedule resulting from this schedule advanced by the given schedule

    This operation cannot be used to append instruction steps after p-code steps. Thus, if this schedule contains any p-code steps and `next` has instruction steps, an error will be

    Parameters:
      `next` - the schedule to append. Its snap is ignored.
    Returns:
      the complete schedule
    Throws:
      `IllegalArgumentException` - if the result would have instruction steps following p-code steps

  - ### dropPSteps

    public TraceSchedule dropPSteps()
    Drop the p-code steps
    Returns:
      the schedule without ops

  - ### dropLastStep

    public TraceSchedule dropLastStep()
    Drop the last step

    If there are p-code steps, this drops the last step there. Otherwise, this drops the last step from the instruction steps. A step includes all ticks in the step, e.g., `0:t0-20;t1-5` becomes `0:t0-20`. To remove a specific number of ticks, see `steppedBackward(Trace, long)`.

    Returns:
      the schedule with the last step removed
    Throws:
      `NoSuchElementException` - If there are neither instruction nor p-code steps.

  - ### lastStep

    public TraceSchedule.StepAndKind lastStep()
    Returns the last step of the schedule.
    Returns:
      the last step of the schedule

  - ### truncateToSteps

    public TraceSchedule truncateToSteps(int count)
    Drop all p-code steps, if any, and enough instruction steps, such that `stepCount()` returns the given count.
    Parameters:
      `count` - the desired step count
    Returns:
      the new schedule

  - ### getThreads

    public Set<TraceThread> getThreads(Trace trace)
    Get the threads involved in the schedule
    Parameters:
      `trace` - the trace whose threads to get
    Returns:
      the set of threads

  - ### assumeRecorded

    public TraceSchedule assumeRecorded()

  - ### differsOnlyByPatch

    public boolean differsOnlyByPatch(TraceSchedule that)