GP-1222: Added comparison between times in a trace.

This commit is contained in:
Dan 2021-12-06 14:42:35 -05:00
parent ab05672653
commit d6c1c3cf85
43 changed files with 2622 additions and 519 deletions

View file

@ -19,7 +19,6 @@ import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.BiConsumer;

View file

@ -327,6 +327,17 @@ public class DBTraceMemoryManager
return delegateRead(start.getAddressSpace(), m -> m.getBufferAt(snap, start, byteOrder));
}
@Override
public Long getSnapOfMostRecentChangeToBlock(long snap, Address address) {
return delegateRead(address.getAddressSpace(),
m -> m.getSnapOfMostRecentChangeToBlock(snap, address));
}
@Override
public int getBlockSize() {
return DBTraceMemorySpace.BLOCK_SIZE;
}
@Override
public void pack() {
delegateWriteAll(getActiveSpaces(), m -> m.pack());

View file

@ -875,6 +875,26 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
return false;
}
@Override
public Long getSnapOfMostRecentChangeToBlock(long snap, Address address) {
assertInSpace(address);
try (LockHold hold = LockHold.lock(lock.readLock())) {
long offset = address.getOffset();
long roundOffset = offset & BLOCK_MASK;
OffsetSnap loc = new OffsetSnap(roundOffset, snap);
DBTraceMemoryBlockEntry ent = findMostRecentBlockEntry(loc, true);
if (ent == null) {
return null;
}
return ent.getSnap();
}
}
@Override
public int getBlockSize() {
return BLOCK_SIZE;
}
public long getFirstChange(Range<Long> span, AddressRange range) {
assertInSpace(range);
long lower = DBTraceUtils.lowerEndpoint(span);

View file

@ -472,6 +472,32 @@ public interface TraceMemoryOperations {
: ByteOrder.LITTLE_ENDIAN);
}
/**
* Find the internal storage block that most-recently defines the value at the given snap and
* address, and return the block's snap.
*
* <p>
* 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.
*
* @param snap the time
* @param address the location
* @return the most snap for the most recent containing block
*/
Long getSnapOfMostRecentChangeToBlock(long snap, Address address);
/**
* Get the block size used by internal storage.
*
* <p>
* 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.
*
* @return the block size
*/
int getBlockSize();
/**
* Optimize storage space
*

View file

@ -368,7 +368,7 @@ public class Sequence implements Comparable<Sequence> {
*
* @param trace the trace to which the machine is bound
* @param eventThread the thread for the first step, if it applies to the "last thread"
* @param machine the machine to step
* @param machine the machine to step, or null to validate the sequence
* @param action the action to step each thread
* @param monitor a monitor for cancellation and progress reports
* @return the last trace thread stepped during execution
@ -384,6 +384,22 @@ public class Sequence implements Comparable<Sequence> {
return thread;
}
/**
* Validate this sequence for the given trace
*
* @param trace the trace
* @param eventThread the thread for the first step, if it applies to the "last thread"
* @return the last trace thread that would be stepped by this sequence
*/
public TraceThread validate(Trace trace, TraceThread eventThread) {
try {
return execute(trace, eventThread, null, null, null);
}
catch (CancelledException e) {
throw new AssertionError(e);
}
}
/**
* Get the key of the last thread stepped
*

View file

@ -91,8 +91,8 @@ public interface Step extends Comparable<Step> {
TraceThread thread = isEventThread() ? eventThread : tm.getThread(getThreadKey());
if (thread == null) {
if (isEventThread()) {
throw new IllegalArgumentException(
"Thread key -1 can only be used if last/event thread is given");
throw new IllegalArgumentException("Thread must be given, e.g., 0:t1-3, " +
"since the last thread or snapshot event thread is not given.");
}
throw new IllegalArgumentException(
"Thread with key " + getThreadKey() + " does not exist in given trace");
@ -160,6 +160,10 @@ public interface Step extends Comparable<Step> {
PcodeMachine<T> machine, Consumer<PcodeThread<T>> stepAction, TaskMonitor monitor)
throws CancelledException {
TraceThread thread = getThread(tm, eventThread);
if (machine == null) {
// Just performing validation (specifically thread parts)
return thread;
}
PcodeThread<T> emuThread = machine.getThread(thread.getPath(), true);
execute(emuThread, stepAction, monitor);
return thread;

View file

@ -344,6 +344,22 @@ public class TraceSchedule implements Comparable<TraceSchedule> {
pSteps.execute(trace, lastThread, machine, PcodeThread::stepPcodeOp, monitor);
}
/**
* Validate this schedule for the given trace
*
* <p>
* 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.
*
* @param trace the trace against which to validate this schedule
*/
public void validate(Trace trace) {
TraceThread lastThread = getEventThread(trace);
lastThread = steps.validate(trace, lastThread);
lastThread = pSteps.validate(trace, lastThread);
}
/**
* Realize the machine state for this schedule using the given trace and pre-positioned machine
*
@ -385,13 +401,13 @@ public class TraceSchedule implements Comparable<TraceSchedule> {
* This schedule is left unmodified. If it had any p-code steps, those steps are dropped in the
* resulting schedule.
*
* @param thread the thread to step
* @param thread the thread to step, or null for the "last thread"
* @param tickCount the number of ticks to take the thread forward
* @return the resulting schedule
*/
public TraceSchedule steppedForward(TraceThread thread, long tickCount) {
Sequence steps = this.steps.clone();
steps.advance(new TickStep(thread.getKey(), tickCount));
steps.advance(new TickStep(thread == null ? -1 : thread.getKey(), tickCount));
return new TraceSchedule(snap, steps, new Sequence());
}
@ -441,13 +457,13 @@ public class TraceSchedule implements Comparable<TraceSchedule> {
* Returns the equivalent of executing the schedule followed by stepping the given thread
* {@code pTickCount} more p-code operations
*
* @param thread the thread to step
* @param thread the thread to step, or null for the "last thread"
* @param pTickCount the number of p-code ticks to take the thread forward
* @return the resulting schedule
*/
public TraceSchedule steppedPcodeForward(TraceThread thread, int pTickCount) {
Sequence pTicks = this.pSteps.clone();
pTicks.advance(new TickStep(thread.getKey(), pTickCount));
pTicks.advance(new TickStep(thread == null ? -1 : thread.getKey(), pTickCount));
return new TraceSchedule(snap, steps.clone(), pTicks);
}