Interface TraceMemoryOperations

All Known Subinterfaces:
InternalTraceMemoryOperations, TraceMemoryManager, TraceMemorySpace
All Known Implementing Classes:
DBTraceMemoryManager, DBTraceMemorySpace

public interface TraceMemoryOperations
Operations for mutating memory regions, values, and state within a trace

This models memory over the course of an arbitrary number of snaps. The duration between snaps is unspecified. However, the mapping of snaps to real time ought to be strictly monotonic. Observations of memory are recorded using the putBytes(long, Address, ByteBuffer) and related methods. Those observations, and some related deductions can be retrieved using the getBytes(long, Address, ByteBuffer) and related methods. Many of the get methods permit the retrieval of the most recent observations. This is useful as an observed value in memory is presumed unchanged until another observation is made. Observations of bytes in memory cause the state at the same location and snap to become TraceMemoryState.KNOWN. These states can be manipulated directly; however, this is recommended only to record read failures, using the state TraceMemoryState.ERROR. A state of null is equivalent to TraceMemoryState.UNKNOWN and indicates no observation has been made.

Negative snaps may have different semantics than positive, since negative snaps are used as "scratch space". These snaps are not presumed to have any temporal relation to their neighbors, or any other snap for that matter. Clients may use the description field of the TraceSnapshot to indicate a relationship to another snap. Operations which seek the "most-recent" data might not retrieve anything from scratch snaps, and writing to a scratch snap might not cause any changes to others. Note the "integrity" of data where the memory state is not TraceMemoryState.KNOWN may be neglected to some extent. For example, writing bytes to snap -10 may cause bytes in snap -9 to change, where the effected range at snap -9 has state TraceMemoryState.UNKNOWN. The time semantics are not necessarily prohibited in scratch space, but implementations may choose cheaper semantics if desired. Clients should be wary not to accidentally rely on implied temporal relationships in scratch space.

  • Method Details

    • isStateEntirely

      static boolean isStateEntirely(AddressRange range, Collection<Map.Entry<TraceAddressSnapRange,TraceMemoryState>> stateEntries, TraceMemoryState state)
      Check if the return value of getStates(long, AddressRange) or similar represents a single entry of the given state.

      This method returns false if there is not exactly one entry of the given state whose range covers the given range. As a special case, an empty collection will cause this method to return true iff state is TraceMemoryState.UNKNOWN.

      Parameters:
      range - the range to check, usually that passed to getStates(long, AddressRange).
      stateEntries - the collection returned by getStates(long, AddressRange).
      state - the expected state
      Returns:
      true if the state matches
    • getTrace

      Trace getTrace()
      Get the trace to which the memory manager belongs
      Returns:
      the trace
    • setState

      void setState(long snap, AddressRange range, TraceMemoryState state)
      Set the state of memory over a given time and address range

      Setting state to TraceMemoryState.KNOWN via this method is not recommended. Setting bytes will automatically update the state accordingly.

      Parameters:
      snap - the time
      range - the range
      state - the state
    • setState

      void setState(long snap, Address address, TraceMemoryState state)
      See Also:
    • setState

      void setState(long snap, Address start, Address end, TraceMemoryState state)
      See Also:
    • setState

      void setState(long snap, AddressSetView set, TraceMemoryState state)
      Set the state of memory over a given time and address set
      See Also:
    • getState

      TraceMemoryState getState(long snap, Address address)
      Get the state of memory at a given snap and address

      If the location's state has not been set, the result is null, which implies TraceMemoryState.UNKNOWN.

      Parameters:
      snap - the time
      address - the location
      Returns:
      the state
    • getViewState

      Map.Entry<Long,TraceMemoryState> getViewState(long snap, Address address)
      Get the state of memory at a given snap and address, following schedule forks
      Parameters:
      snap - the time
      address - the location
      Returns:
      the state, and the snap where it was found
    • getMostRecentStateEntry

      Map.Entry<TraceAddressSnapRange,TraceMemoryState> getMostRecentStateEntry(long snap, Address address)
      Get the entry recording the most recent state at the given snap and address

      The entry includes the entire entry at that snap. Parts occluded by more recent snaps are not subtracted from the entry's address range.

      Parameters:
      snap - the time
      address - the location
      Returns:
      the entry including the entire recorded range
    • getViewMostRecentStateEntry

      Map.Entry<TraceAddressSnapRange,TraceMemoryState> getViewMostRecentStateEntry(long snap, Address address)
      Get the entry recording the most recent state at the given snap and address, following schedule forks
      Parameters:
      snap - the latest time to consider
      address - the address
      Returns:
      the most-recent entry
    • getViewMostRecentStateEntry

      Map.Entry<TraceAddressSnapRange,TraceMemoryState> getViewMostRecentStateEntry(long snap, AddressRange range, Predicate<TraceMemoryState> predicate)
      Get the entry recording the most recent state since the given snap within the given range that satisfies a given predicate, following schedule forks
      Parameters:
      snap - the latest time to consider
      range - the range of addresses
      predicate - a predicate on the state
      Returns:
      the most-recent entry
    • getAddressesWithState

      default AddressSetView getAddressesWithState(long snap, AddressSetView set, Predicate<TraceMemoryState> predicate)
      Get at least the subset of addresses having state satisfying the given predicate
      Parameters:
      snap - the time
      set - the set to examine
      predicate - a predicate on state to search for
      Returns:
      the address set
      See Also:
    • getAddressesWithState

      AddressSetView getAddressesWithState(Lifespan span, AddressSetView set, Predicate<TraceMemoryState> predicate)
      Get at least the subset of addresses having state satisfying the given predicate

      The implementation may provide a larger view than requested, but within the requested set, only ranges satisfying the predicate may be present. Use AddressSetView.intersect(AddressSetView) with set if a strict subset is required.

      Because TraceMemoryState.UNKNOWN is not explicitly stored in the map, to compute the set of TraceMemoryState.UNKNOWN addresses, use the predicate state -> state != null && state != TraceMemoryState.UNKNOWN and subtract the result from set.

      Parameters:
      span - the range of time
      set - the set to examine
      predicate - a predicate on state to search for
      Returns:
      the address set
    • getAddressesWithState

      AddressSetView getAddressesWithState(long snap, Predicate<TraceMemoryState> predicate)
      Get the addresses having state satisfying the given predicate

      The implementation may provide a view that updates with changes. Behavior is not well defined for predicates testing for TraceMemoryState.UNKNOWN.

      Parameters:
      snap - the time
      predicate - a predicate on state to search for
      Returns:
      the address set
    • getAddressesWithState

      AddressSetView getAddressesWithState(Lifespan lifespan, Predicate<TraceMemoryState> predicate)
      Get the addresses having state satisfying the given predicate at any time in the specified lifespan

      The implementation may provide a view that updates with changes. Behavior is not well defined for predicates testing for TraceMemoryState.UNKNOWN .

      Parameters:
      lifespan - the span of time
      predicate - a predicate on state to search for
      Returns:
      the address set
    • getStates

      Break a range of addresses into smaller ranges each mapped to its state at the given snap

      Note that TraceMemoryState.UNKNOWN entries will not appear in the result. Gaps in the returned entries are implied to be TraceMemoryState.UNKNOWN.

      Parameters:
      snap - the time
      range - the range to examine
      Returns:
      the map of ranges to states
    • isKnown

      default boolean isKnown(long snap, AddressRange range)
      Check if a range addresses are all known
      Parameters:
      snap - the time
      range - the range to examine
      Returns:
      true if the entire range is TraceMemoryState.KNOWN
    • getMostRecentStates

      Break a range of addresses into smaller ranges each mapped to its most recent state at the given time

      Typically within is the box whose width is the address range to break down and whose height is from "negative infinity" to the "current" snap.

      In this context, "most recent" means the latest state other than TraceMemoryState.UNKNOWN.

      Parameters:
      within - a box intersecting entries to consider
      Returns:
      an iterable over the snap ranges and states
    • getMostRecentStates

      default Iterable<Map.Entry<TraceAddressSnapRange,TraceMemoryState>> getMostRecentStates(long snap, AddressRange range)
      See Also:
    • putBytes

      int putBytes(long snap, Address start, ByteBuffer buf)
      Write bytes at the given snap and address

      This will attempt to read Buffer.remaining() bytes starting at Buffer.position() from the source buffer buf and write them into memory at the specified time and location. The affected region is also updated to TraceMemoryState.KNOWN. The written bytes are assumed effective for all future snaps up to the next write.

      Parameters:
      snap - the time
      start - the location
      buf - the source buffer of bytes
      Returns:
      the number of bytes written
    • getBytes

      int getBytes(long snap, Address start, ByteBuffer buf)
      Read the most recent bytes from the given snap and address

      This will attempt to read Buffer.remaining() of the most recent bytes from memory at the specified time and location and write them into the destination buffer buf starting at Buffer.position(). Where bytes in memory have no defined value, values in the destination buffer are unspecified. The implementation may leave those bytes in the destination buffer unmodified, or it may write zeroes.

      Parameters:
      snap - the time
      start - the location
      buf - the destination buffer of bytes
      Returns:
      the number of bytes read
    • getViewBytes

      int getViewBytes(long snap, Address start, ByteBuffer buf)
      Read the most recent bytes from the given snap and address, following schedule forks

      This behaves similarly to getBytes(long, Address, ByteBuffer), except it checks for the TraceMemoryState.KNOWN state among each involved snap range and reads the applicable address ranges, preferring the most recent. Where memory is never known the buffer is left unmodified.

      Parameters:
      snap - the time
      start - the location
      buf - the destination buffer of bytes
      Returns:
      the number of bytes read
    • findBytes

      Address findBytes(long snap, AddressRange range, ByteBuffer data, ByteBuffer mask, boolean forward, TaskMonitor monitor)
      Search the given address range at the given snap for a given byte pattern
      Parameters:
      snap - the time to search
      range - the address range to search
      data - the values to search for
      mask - a mask on the bits of data; or null to match all bytes exactly
      forward - true to return the match with the lowest address in range, false for the highest address.
      monitor - a monitor for progress reporting and canceling
      Returns:
      the minimum address of the matched bytes, or null if not found
    • removeBytes

      void removeBytes(long snap, Address start, int len)
      Remove bytes from the given time and location

      This deletes all observed bytes from the given address through length at the given snap. If there were no observations in the range at exactly the given snap, this has no effect. If there were, then those observations are removed. The next time those bytes are read, they will have a value from a previous snap, or no value at all. The affected region's state is also deleted, i.e., set to null, implying TraceMemoryState.UNKNOWN.

      Note, use of this method is discouraged. The more observations within the same range that follow the deleted observation, the more expensive this operation typically is, since all of those observations may need to be updated.

      Parameters:
      snap - the time
      start - the location
      len - the number of bytes to remove
    • getBufferAt

      MemBuffer getBufferAt(long snap, Address start, ByteOrder byteOrder)
      Get a view of a particular snap as a memory buffer

      The bytes read by this buffer are the most recent bytes written before the given snap

      Parameters:
      snap - the snap
      start - the starting address
      byteOrder - the byte ordering for this buffer
      Returns:
      the memory buffer
    • getBufferAt

      default MemBuffer getBufferAt(long snap, Address start)
      Get a view of a particular snap as a memory buffer using the base language's byte order
      See Also:
    • getSnapOfMostRecentChangeToBlock

      Long getSnapOfMostRecentChangeToBlock(long snap, Address address)
      Find the internal storage block that most-recently defines the value at the given snap and address, and return the block's snap.

      This method reveals portions of the internal storage so that clients can optimize difference computations by eliminating corresponding ranges defined by the same block. If the underlying implementation cannot answer this question, this returns the given snap.

      Parameters:
      snap - the time
      address - the location
      Returns:
      the most snap for the most recent containing block
    • getBlockSize

      int getBlockSize()
      Get the block size used by internal storage.

      This method reveals portions of the internal storage so that clients can optimize searches. If the underlying implementation cannot answer this question, this returns 0.

      Returns:
      the block size
    • pack

      void pack()
      Optimize storage space

      This gives the implementation an opportunity to clean up garbage, apply compression, etc., in order to best use the storage space. Because memory observations can be sparse, a trace's memory is often compressible, and observations are not often modified or deleted, packing is recommended whenever the trace is saved to disk.

    • setState

      void setState(TracePlatform platform, long snap, Register register, TraceMemoryState state)
      Set the state of a given register at a given time

      Setting state to TraceMemoryState.KNOWN via this method is not recommended. Setting bytes will automatically update the state accordingly.

      Parameters:
      platform - the platform whose language defines the register
      snap - the time
      register - the register
      state - the state
    • setState

      default void setState(long snap, Register register, TraceMemoryState state)
      Set the state of a given register at a given time

      Setting state to TraceMemoryState.KNOWN via this method is not recommended. Setting bytes will automatically update the state accordingly.

      Parameters:
      snap - the time
      register - the register
      state - the state
    • getState

      TraceMemoryState getState(TracePlatform platform, long snap, Register register)
      Assert that a register's range has a single state at the given snap and get that state
      Parameters:
      platform - the platform whose language defines the register
      snap - the time
      register - the register to examine
      Returns:
      the state
      Throws:
      IllegalStateException - if the register is mapped to more than one state. See getStates(long, Register)
    • getState

      default TraceMemoryState getState(long snap, Register register)
      Assert that a register's range has a single state at the given snap and get that state
      Parameters:
      snap - the time
      register - the register to examine
      Returns:
      the state
      Throws:
      IllegalStateException - if the register is mapped to more than one state. See getStates(long, Register)
    • getStates

      Collection<Map.Entry<TraceAddressSnapRange,TraceMemoryState>> getStates(TracePlatform platform, long snap, Register register)
      Break the register's range into smaller ranges each mapped to its state at the given snap

      If the register is memory mapped, this will delegate to the appropriate space.

      Parameters:
      platform - the platform whose language defines the register
      snap - the time
      register - the register to examine
      Returns:
      the map of ranges to states
    • getStates

      default Collection<Map.Entry<TraceAddressSnapRange,TraceMemoryState>> getStates(long snap, Register register)
      Break the register's range into smaller ranges each mapped to its state at the given snap

      If the register is memory mapped, this will delegate to the appropriate space.

      Parameters:
      snap - the time
      register - the register to examine
      Returns:
      the map of ranges to states
    • setValue

      int setValue(TracePlatform platform, long snap, RegisterValue value)
      Parameters:
      platform - the platform whose language defines the register
      snap - the snap
      value - the register value
      Returns:
      the number of bytes written
      See Also:
    • setValue

      default int setValue(long snap, RegisterValue value)
      Set the value of a register at the given snap

      If the register is memory mapped, this will delegate to the appropriate space. In those cases, the assignment affects all threads.

      IMPORTANT: The trace database cannot track the state (TraceMemoryState.KNOWN, etc.) with per-bit accuracy. It only has byte precision. If the given value specifies, e.g., only a single bit, then the entire byte will become marked TraceMemoryState.KNOWN, even though the remaining 7 bits could technically be unknown.

      Parameters:
      snap - the snap
      value - the register value
      Returns:
      the number of bytes written
    • putBytes

      int putBytes(TracePlatform platform, long snap, Register register, ByteBuffer buf)
      Parameters:
      platform - the platform whose language defines the register
      snap - the snap
      register - the register to modify
      buf - the buffer of bytes to write
      Returns:
      the number of bytes written
      See Also:
    • putBytes

      default int putBytes(long snap, Register register, ByteBuffer buf)
      Write bytes at the given snap and register address

      If the register is memory mapped, this will delegate to the appropriate space. In those cases, the assignment affects all threads.

      Note that bit-masked registers are not properly heeded. If the caller wishes to preserve non-masked bits, it must first retrieve the current value and combine it with the desired value. The caller must also account for any bit shift in the passed buffer. Alternatively, consider setValue(long, RegisterValue).

      Parameters:
      snap - the snap
      register - the register to modify
      buf - the buffer of bytes to write
      Returns:
      the number of bytes written
    • getValue

      RegisterValue getValue(TracePlatform platform, long snap, Register register)
      Get the most-recent value of a given register at the given time

      If the register is memory mapped, this will delegate to the appropriate space.

      Parameters:
      platform - the platform whose language defines the register
      snap - the time
      register - the register
      Returns:
      the value
    • getValue

      default RegisterValue getValue(long snap, Register register)
      Get the most-recent value of a given register at the given time

      If the register is memory mapped, this will delegate to the appropriate space.

      Parameters:
      snap - the time
      register - the register
      Returns:
      the value
    • getViewValue

      RegisterValue getViewValue(TracePlatform platform, long snap, Register register)
      Get the most-recent value of a given register at the given time

      If the register is memory mapped, this will delegate to the appropriate space.

      Parameters:
      platform - the platform whose language defines the register
      snap - the time
      register - the register
      Returns:
      the value
    • getViewValue

      default RegisterValue getViewValue(long snap, Register register)
      Get the most-recent value of a given register at the given time, following schedule forks

      If the register is memory mapped, this will delegate to the appropriate space.

      Parameters:
      snap - the time
      register - the register
      Returns:
      the value
    • getBytes

      int getBytes(TracePlatform platform, long snap, Register register, ByteBuffer buf)
      Get the most-recent bytes of a given register at the given time

      If the register is memory mapped, this will delegate to the appropriate space.

      Parameters:
      platform - the platform whose language defines the register
      snap - the time
      register - the register
      buf - the destination buffer
      Returns:
      the number of bytes read
    • getBytes

      default int getBytes(long snap, Register register, ByteBuffer buf)
      Get the most-recent bytes of a given register at the given time

      If the register is memory mapped, this will delegate to the appropriate space.

      Parameters:
      snap - the time
      register - the register
      buf - the destination buffer
      Returns:
      the number of bytes read
    • removeValue

      void removeValue(TracePlatform platform, long snap, Register register)
      Parameters:
      platform - the platform whose language defines the register
      snap - the snap
      register - the register
      See Also:
    • removeValue

      default void removeValue(long snap, Register register)
      Remove a value from the given time and register

      If the register is memory mapped, this will delegate to the appropriate space.

      IMPORANT: The trace database cannot track the state (TraceMemoryState.KNOWN, etc.) with per-bit accuracy. It only has byte precision. If the given register specifies, e.g., only a single bit, then the entire byte will become marked TraceMemoryState.UNKNOWN, even though the remaining 7 bits could technically be known.

      Parameters:
      snap - the snap
      register - the register