Skip to content

Commit

Permalink
Merge PR #312: Restore performance of replay
Browse files Browse the repository at this point in the history
  • Loading branch information
smarr committed Aug 31, 2019
2 parents 28fc0fd + 15ee8fb commit 6e77b0a
Show file tree
Hide file tree
Showing 27 changed files with 7,365 additions and 360 deletions.
28 changes: 28 additions & 0 deletions src/som/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import tools.debugger.WebDebugger;
import tools.debugger.session.Breakpoints;
import tools.dym.DynamicMetrics;
import tools.replay.TraceParser;
import tools.snapshot.SnapshotBackend;
import tools.superinstructions.CandidateIdentifier;

Expand Down Expand Up @@ -83,6 +84,8 @@ public final class VM {
@CompilationFinal private SObjectWithoutFields vmMirror;
@CompilationFinal private Actor mainActor;

private final TraceParser traceParser;

private static final int MAX_THREADS = 0x7fff;

public VM(final VmOptions vmOptions) {
Expand All @@ -96,6 +99,12 @@ public VM(final VmOptions vmOptions) {
new ForkJoinThreadFactory(this), new UncaughtExceptions(this), false);
threadPool = new ForkJoinPool(MAX_THREADS,
new ForkJoinThreadFactory(this), new UncaughtExceptions(this), false);

if (VmSettings.REPLAY) {
traceParser = new TraceParser(VmSettings.TRACE_FILE);
} else {
traceParser = null;
}
}

/**
Expand All @@ -109,6 +118,13 @@ public VM(final VmOptions vmOptions, final boolean languageServer) {
processesPool = null;
forkJoinPool = null;
threadPool = null;

traceParser = null;
}

public TraceParser getTraceParser() {
assert VmSettings.REPLAY : "Is expected to be used only for replay";
return traceParser;
}

public WebDebugger getWebDebugger() {
Expand Down Expand Up @@ -271,6 +287,14 @@ public void shutdown() {
}

shutdownPools();

if (VmSettings.REPLAY) {
try {
traceParser.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

public boolean isShutdown() {
Expand Down Expand Up @@ -309,6 +333,10 @@ public void initalize(final SomLanguage lang) throws IOException {
assert vmMirror == null : "VM seems to be initialized already";
assert mainActor == null : "VM seems to be initialized already";

if (VmSettings.REPLAY) {
traceParser.initialize();
}

mainActor = Actor.createActor(this);
vmMirror = objectSystem.initialize();

Expand Down
2 changes: 1 addition & 1 deletion src/som/interpreter/actors/EventualMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected EventualMessage(final Object[] args,
this.haltOnReceive = haltOnReceive;
this.haltOnResolver = haltOnResolver;
if (VmSettings.KOMPOS_TRACING) {
this.messageId = TracingActivityThread.newEntityId();
this.messageId = TracingActivityThread.newEntityId(null);
if (VmSettings.ASSISTED_DEBUGGING) {
if (KomposTraceParser.isMessageInErrorStackTrace(this.messageId)
|| this.messageId == 0) {
Expand Down
17 changes: 8 additions & 9 deletions src/som/primitives/ActivitySpawn.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
import tools.debugger.entities.BreakpointType;
import tools.debugger.nodes.AbstractBreakpointNode;
import tools.debugger.session.Breakpoints;
import tools.replay.actors.ActorExecutionTrace;
import tools.replay.TraceRecord;
import tools.replay.nodes.RecordEventNodes.RecordOneEvent;


Expand Down Expand Up @@ -82,11 +82,11 @@ private static SomThreadTask createThread(final Object[] argArray,

private static Process createProcess(final SObjectWithClass obj,
final SourceSection origin, final boolean stopOnRoot,
final RecordOneEvent traceProcCreation) {
final RecordOneEvent traceProcCreation, final VM vm) {
if (VmSettings.REPLAY) {
return new ReplayProcess(obj, stopOnRoot);
return new ReplayProcess(obj, stopOnRoot, vm);
} else if (VmSettings.KOMPOS_TRACING || VmSettings.ACTOR_TRACING) {
TracingProcess result = new TracingProcess(obj, stopOnRoot);
TracingProcess result = new TracingProcess(obj, stopOnRoot, vm);
if (VmSettings.KOMPOS_TRACING) {
KomposTrace.activityCreation(ActivityType.PROCESS,
result.getId(), result.getProcObject().getSOMClass().getName(), origin);
Expand Down Expand Up @@ -117,7 +117,7 @@ public abstract static class SpawnPrim extends BinarySystemOperation {
@Child protected AbstractBreakpointNode onExec;
@Child protected ExceptionSignalingNode notAValue;
@Child RecordOneEvent traceProcCreation =
new RecordOneEvent(ActorExecutionTrace.PROCESS_CREATE);
new RecordOneEvent(TraceRecord.PROCESS_CREATION);

@Override
public final SpawnPrim initialize(final VM vm) {
Expand Down Expand Up @@ -168,7 +168,7 @@ private void spawnProcess(final SClass procCls, final RecordOneEvent traceProcCr
SObjectWithClass obj = (SObjectWithClass) disp.invoke(new Object[] {procCls});

processesPool.submit(createProcess(obj, sourceSection,
onExec.executeShouldHalt(), traceProcCreation));
onExec.executeShouldHalt(), traceProcCreation, vm));
}

@Override
Expand Down Expand Up @@ -202,8 +202,7 @@ public abstract static class SpawnWithPrim extends TernarySystemOperation {

@Child protected ExceptionSignalingNode notAValue;

@Child RecordOneEvent traceProcCreation =
new RecordOneEvent(ActorExecutionTrace.PROCESS_CREATE);
@Child RecordOneEvent traceProcCreation = new RecordOneEvent(TraceRecord.PROCESS_CREATION);

@Override
public final SpawnWithPrim initialize(final VM vm) {
Expand Down Expand Up @@ -258,7 +257,7 @@ private void spawnProcess(final SClass procCls, final Object[] argArr,
SObjectWithClass obj = (SObjectWithClass) disp.invoke(argArr);

processesPool.submit(createProcess(obj, sourceSection,
onExec.executeShouldHalt(), traceProcCreation));
onExec.executeShouldHalt(), traceProcCreation, vm));
}

@Override
Expand Down
29 changes: 24 additions & 5 deletions src/som/primitives/SystemPrims.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.instrumentation.Tag;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
Expand Down Expand Up @@ -61,7 +62,7 @@
import som.vmobjects.SSymbol;
import tools.concurrency.TracingActors.TracingActor;
import tools.concurrency.TracingBackend;
import tools.replay.TraceParser;
import tools.dym.Tags.BasicPrimitiveOperation;
import tools.replay.actors.ActorExecutionTrace;
import tools.replay.nodes.TraceContextNode;
import tools.replay.nodes.TraceContextNodeGen;
Expand Down Expand Up @@ -335,13 +336,13 @@ public final Object doSObject(final Object receiver) {

@GenerateNodeFactory
@Primitive(primitive = "systemTime:")
public abstract static class TimePrim extends UnaryBasicOperation {
public abstract static class TimePrim extends UnarySystemOperation {
@Child TraceContextNode tracer = TraceContextNodeGen.create();

@Specialization
public final long doSObject(final Object receiver) {
if (VmSettings.REPLAY) {
return TraceParser.getLongSysCallResult();
return vm.getTraceParser().getLongSysCallResult();
}

long res = System.currentTimeMillis() - startTime;
Expand All @@ -350,6 +351,15 @@ public final long doSObject(final Object receiver) {
}
return res;
}

@Override
protected boolean hasTagIgnoringEagerness(final Class<? extends Tag> tag) {
if (tag == BasicPrimitiveOperation.class) {
return true;
} else {
return super.hasTagIgnoringEagerness(tag);
}
}
}

/**
Expand Down Expand Up @@ -416,13 +426,13 @@ public boolean matches(final Object[] args, final ExpressionNode[] argNodes) {
@GenerateNodeFactory
@Primitive(primitive = "systemTicks:", selector = "ticks",
specializer = IsSystemModule.class, noWrapper = true)
public abstract static class TicksPrim extends UnaryBasicOperation implements Operation {
public abstract static class TicksPrim extends UnarySystemOperation implements Operation {
@Child TraceContextNode tracer = TraceContextNodeGen.create();

@Specialization
public final long doSObject(final Object receiver) {
if (VmSettings.REPLAY) {
return TraceParser.getLongSysCallResult();
return vm.getTraceParser().getLongSysCallResult();
}

long res = System.nanoTime() / 1000L - startMicroTime;
Expand All @@ -442,6 +452,15 @@ public String getOperation() {
public int getNumArguments() {
return 1;
}

@Override
protected boolean hasTagIgnoringEagerness(final Class<? extends Tag> tag) {
if (tag == BasicPrimitiveOperation.class) {
return true;
} else {
return super.hasTagIgnoringEagerness(tag);
}
}
}

@GenerateNodeFactory
Expand Down
4 changes: 3 additions & 1 deletion src/som/primitives/TimerPrim.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public abstract class TimerPrim extends BinarySystemOperation {

@CompilationFinal private static List<Integer> todoList;
@CompilationFinal private static HashMap<Integer, SFarReference> replayTargetMap;
@CompilationFinal private static TraceParser traceParser;

public static void initializeTimer(final VM vm) {
timer = new Timer();
Expand All @@ -68,6 +69,7 @@ public static void initializeTimer(final VM vm) {
((ReplayActor) vm.getMainActor()).setDataSource(new TimeDataSource());
todoList = new ArrayList<>();
replayTargetMap = new HashMap<>();
traceParser = vm.getTraceParser();
}
}

Expand Down Expand Up @@ -112,7 +114,7 @@ private void performOnReplay(final Object target, final Actor targetActor) {
SFarReference ref = new SFarReference(targetActor, target);

synchronized (REPLAY_LOCK) {
int m = TraceParser.getIntegerSysCallResult();
int m = traceParser.getIntegerSysCallResult();
if (todoList.contains(m)) {
todoList.remove((Integer) m);
TimerPrim.sendMessage(ref);
Expand Down
34 changes: 22 additions & 12 deletions src/som/primitives/processes/ChannelPrimitives.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import som.VM;
import som.compiler.AccessModifier;
import som.compiler.MixinBuilder.MixinDefinitionId;
import som.interpreter.SomLanguage;
import som.interpreter.actors.SuspendExecutionNodeGen;
import som.interpreter.nodes.ExceptionSignalingNode;
import som.interpreter.nodes.nary.BinaryComplexOperation.BinarySystemOperation;
Expand Down Expand Up @@ -48,6 +47,7 @@
import tools.debugger.session.Breakpoints;
import tools.replay.ReplayRecord;
import tools.replay.TraceParser;
import tools.replay.TraceRecord;
import tools.replay.actors.ActorExecutionTrace;
import tools.replay.nodes.RecordEventNodes.RecordOneEvent;
import tools.replay.nodes.RecordEventNodes.RecordTwoEvent;
Expand Down Expand Up @@ -156,12 +156,16 @@ public static class TracingProcess extends Process {
private final boolean stopOnRootNode;
private boolean stopOnJoin;

protected final VM vm;

private final TraceContextNode trace = TraceContextNodeGen.create();

public TracingProcess(final SObjectWithClass obj, final boolean stopOnRootNode) {
public TracingProcess(final SObjectWithClass obj, final boolean stopOnRootNode,
final VM vm) {
super(obj);
this.stopOnRootNode = stopOnRootNode;
processId = TracingActivityThread.newEntityId();
processId = TracingActivityThread.newEntityId(vm);
this.vm = vm;
}

@Override
Expand All @@ -174,7 +178,7 @@ public int getNextTraceBufferId() {
@Override
protected void beforeExec(final SInvokable disp) {
if (VmSettings.TRUFFLE_DEBUGGER_ENABLED && stopOnRootNode) {
WebDebugger dbg = SomLanguage.getVM(disp.getInvokable()).getWebDebugger();
WebDebugger dbg = vm.getWebDebugger();
dbg.prepareSteppingUntilNextRootNode(Thread.currentThread());
}

Expand Down Expand Up @@ -210,9 +214,10 @@ public static class ReplayProcess extends TracingProcess {
private final Queue<ReplayRecord> replayEvents;
private int children = 0;

public ReplayProcess(final SObjectWithClass obj, final boolean stopOnRootNode) {
super(obj, stopOnRootNode);
replayEvents = TraceParser.getReplayEventsForEntity(processId);
public ReplayProcess(final SObjectWithClass obj, final boolean stopOnRootNode,
final VM vm) {
super(obj, stopOnRootNode, vm);
replayEvents = vm.getTraceParser().getReplayEventsForEntity(processId);
}

@Override
Expand All @@ -221,8 +226,13 @@ public int addChild() {
}

@Override
public ReplayRecord getNextReplayEvent() {
return replayEvents.poll();
public Queue<ReplayRecord> getReplayEventBuffer() {
return this.replayEvents;
}

@Override
public TraceParser getTraceParser() {
return vm.getTraceParser();
}
}

Expand All @@ -245,7 +255,7 @@ public abstract static class ReadPrim extends UnarySystemOperation {
@Child protected AbstractBreakpointNode afterWrite;

@Child protected RecordTwoEvent traceRead =
new RecordTwoEvent(ActorExecutionTrace.CHANNEL_READ);
new RecordTwoEvent(TraceRecord.CHANNEL_READ.value);

@Override
public final ReadPrim initialize(final VM vm) {
Expand Down Expand Up @@ -294,7 +304,7 @@ public abstract static class WritePrim extends BinarySystemOperation {
@Child protected ExceptionSignalingNode notAValue;

@Child protected RecordTwoEvent traceWrite =
new RecordTwoEvent(ActorExecutionTrace.CHANNEL_WRITE);
new RecordTwoEvent(TraceRecord.CHANNEL_WRITE.value);

@Override
public final WritePrim initialize(final VM vm) {
Expand Down Expand Up @@ -347,7 +357,7 @@ public static final SChannelInput getInt(final SChannel channel) {
@GenerateNodeFactory
public abstract static class ChannelNewPrim extends UnaryExpressionNode {

@Child RecordOneEvent trace = new RecordOneEvent(ActorExecutionTrace.CHANNEL_CREATE);
@Child RecordOneEvent trace = new RecordOneEvent(TraceRecord.CHANNEL_CREATION);

@Specialization
public final SChannel newChannel(final Object module) {
Expand Down
17 changes: 17 additions & 0 deletions src/som/vm/Activity.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package som.vm;

import java.util.Queue;

import tools.debugger.entities.ActivityType;
import tools.replay.ReplayRecord;
import tools.replay.TraceParser;


public interface Activity {
Expand Down Expand Up @@ -32,7 +35,21 @@ default int addChild() {

ActivityType getType();

default TraceParser getTraceParser() {
assert VmSettings.REPLAY;
throw new UnsupportedOperationException();
}

default ReplayRecord getNextReplayEvent() {
Queue<ReplayRecord> q = getReplayEventBuffer();
if (q.isEmpty()) {
getTraceParser().getMoreEventsForEntity(getId());
}

return q.remove();
}

default Queue<ReplayRecord> getReplayEventBuffer() {
return null;
}

Expand Down
Loading

0 comments on commit 6e77b0a

Please sign in to comment.