From 7e5c68bad987aede7420ef0345a32cf2ebc7b34d Mon Sep 17 00:00:00 2001 From: daumayr Date: Mon, 20 Mar 2017 10:32:20 +0100 Subject: [PATCH] restructuring --- src/som/interpreter/actors/Actor.java | 98 +------------ .../interpreter/actors/EventualSendNode.java | 17 ++- src/som/interpreter/actors/SPromise.java | 2 +- src/som/primitives/AssertionPrims.java | 134 ++++-------------- .../primitives/actors/CreateActorPrim.java | 3 +- src/som/vm/VmSettings.java | 2 +- src/tools/concurrency/Assertion.java | 14 +- src/tools/concurrency/TracingActors.java | 93 ++++++++++++ 8 files changed, 150 insertions(+), 213 deletions(-) diff --git a/src/som/interpreter/actors/Actor.java b/src/som/interpreter/actors/Actor.java index 1172c175d..74f7e4926 100644 --- a/src/som/interpreter/actors/Actor.java +++ b/src/som/interpreter/actors/Actor.java @@ -1,9 +1,6 @@ package som.interpreter.actors; import java.lang.Thread.UncaughtExceptionHandler; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory; @@ -14,7 +11,6 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import som.VM; -import som.interpreter.SArguments; import som.interpreter.objectstorage.ObjectTransitionSafepoint; import som.primitives.ObjectPrims.IsValue; import som.vm.Activity; @@ -22,14 +18,11 @@ import som.vm.VmSettings; import som.vmobjects.SAbstractObject; import som.vmobjects.SArray.STransferArray; -import som.vmobjects.SBlock; import som.vmobjects.SObject; import som.vmobjects.SObjectWithClass.SObjectWithoutFields; -import som.vmobjects.SSymbol; import tools.ObjectBuffer; import tools.TraceData; import tools.concurrency.ActorExecutionTrace; -import tools.concurrency.Assertion; import tools.concurrency.TracingActivityThread; import tools.concurrency.TracingActors.ReplayActor; import tools.concurrency.TracingActors.TracingActor; @@ -84,8 +77,6 @@ public static Actor createActor() { /** Is scheduled on the pool, and executes messages to this actor. */ protected final ExecAllMessages executor; - private SSymbol actorType = null; - // used to collect absolute numbers from the threads private static Object statsLock = new Object(); private static long numCreatedMessages = 0; @@ -94,9 +85,6 @@ public static Actor createActor() { private static long numResolvedPromises = 0; private static long numRuinedPromises = 0; - private List activeAssertions; - private HashMap sendHooks; - private HashMap receiveHooks; /** * Possible roles for an actor. */ @@ -199,88 +187,6 @@ protected static void handleBreakPoints(final EventualMessage msg, final WebDebu dbg.prepareSteppingUntilNextRootNode(); } } - public void addAssertion(final Assertion a) { - if (activeAssertions == null) { - activeAssertions = new ArrayList<>(); - } - activeAssertions.add(a); - } - - @TruffleBoundary - public void addSendHook(final SSymbol msg, final SBlock block) { - if (sendHooks == null) { - sendHooks = new HashMap<>(); - } - sendHooks.put(msg, block); - } - - @TruffleBoundary - public void addReceiveHook(final SSymbol msg, final SBlock block) { - if (receiveHooks == null) { - receiveHooks = new HashMap<>(); - } - receiveHooks.put(msg, block); - } - - public SSymbol getActorType() { - return actorType; - } - - public void setActorType(final SSymbol actorType) { - this.actorType = actorType; - } - - private void checkAssertions(final EventualMessage msg) { - if (activeAssertions == null || activeAssertions.size() == 0) { - return; - } - - List temp = activeAssertions; - - activeAssertions = new ArrayList<>(); - - - for (Assertion a : temp) { - a.evaluate(this, msg); - } - } - - @TruffleBoundary - public void checkSendHooks(final EventualMessage msg) { - if (sendHooks != null) { - if (sendHooks.containsKey(msg.getSelector())) { - SBlock block = sendHooks.get(msg.getSelector()); - sendHooks.clear(); - if (receiveHooks != null) { - receiveHooks.clear(); - } - - if (block.getMethod().getNumberOfArguments() > 0) { - block.getMethod().invoke(new Object[] {block, SArguments.getArgumentsWithoutReceiver(msg.getArgs())}); - } else { - block.getMethod().invoke(new Object[] {block}); - } - } else if (sendHooks.size() > 0) { - throw new AssertionError("sending Message: " + msg.getSelector() + " violates the message protocol!"); - } - } - } - - @TruffleBoundary - private void checkReceiveHooks(final EventualMessage msg) { - if (receiveHooks != null) { - if (receiveHooks.containsKey(msg.getSelector())) { - SBlock block = receiveHooks.get(msg.getSelector()); - receiveHooks.clear(); - if (sendHooks != null) { - sendHooks.clear(); - } - block.getMethod().invoke(new Object[] {block, SArguments.getArgumentsWithoutReceiver(msg.getArgs())}); - } else if (receiveHooks.size() > 0) { - throw new AssertionError("receiving Message: " + msg.getSelector() + " violates the message protocol!"); - } - } - } /** * Is scheduled on the fork/join pool and executes messages for a specific @@ -356,8 +262,8 @@ private void execute(final EventualMessage msg, currentThread.currentMessage = msg; handleBreakPoints(msg, dbg); if (VmSettings.ENABLE_ASSERTIONS) { - actor.checkReceiveHooks(msg); - actor.checkAssertions(msg); + ((TracingActor) actor).checkReceiveHooks(msg); + ((TracingActor) actor).checkAssertions(msg); } if (i >= 0 && VmSettings.MESSAGE_TIMESTAMPS) { diff --git a/src/som/interpreter/actors/EventualSendNode.java b/src/som/interpreter/actors/EventualSendNode.java index a839606be..624e22469 100644 --- a/src/som/interpreter/actors/EventualSendNode.java +++ b/src/som/interpreter/actors/EventualSendNode.java @@ -33,6 +33,7 @@ import tools.SourceCoordinate.FullSourceCoordinate; import tools.concurrency.Tags.EventualMessageSend; import tools.concurrency.Tags.ExpressionBreakpoint; +import tools.concurrency.TracingActors.TracingActor; import tools.debugger.nodes.AbstractBreakpointNode; import tools.debugger.nodes.BreakpointNodeGen; import tools.debugger.nodes.DisabledBreakpointNode; @@ -193,7 +194,9 @@ protected void sendDirectMessage(final Object[] args, final Actor owner, messageReceiverBreakpoint.executeCheckIsSetAndEnabled(), promiseResolverBreakpoint.executeCheckIsSetAndEnabled(), promiseResolutionBreakpoint.executeCheckIsSetAndEnabled()); - owner.checkSendHooks(msg); + if (VmSettings.ENABLE_ASSERTIONS) { + ((TracingActor) owner).checkSendHooks(msg); + } target.send(msg); } @@ -207,7 +210,9 @@ protected void sendPromiseMessage(final Object[] args, final SPromise rcvr, messageReceiverBreakpoint.executeCheckIsSetAndEnabled(), promiseResolverBreakpoint.executeCheckIsSetAndEnabled(), promiseResolutionBreakpoint.executeCheckIsSetAndEnabled()); - EventualMessage.getActorCurrentMessageIsExecutionOn().checkSendHooks(msg); + if (VmSettings.ENABLE_ASSERTIONS) { + ((TracingActor) EventualMessage.getActorCurrentMessageIsExecutionOn()).checkSendHooks(msg); + } registerNode.register(rcvr, msg, rcvr.getOwner()); } @@ -255,7 +260,9 @@ public final SPromise toNearRefWithResultPromise(final Object[] args) { messageReceiverBreakpoint.executeCheckIsSetAndEnabled(), promiseResolverBreakpoint.executeCheckIsSetAndEnabled(), promiseResolutionBreakpoint.executeCheckIsSetAndEnabled()); - current.checkSendHooks(msg); + if (VmSettings.ENABLE_ASSERTIONS) { + ((TracingActor) current).checkSendHooks(msg); + } current.send(msg); return result; @@ -287,7 +294,9 @@ public final Object toNearRefWithoutResultPromise(final Object[] args) { messageReceiverBreakpoint.executeCheckIsSetAndEnabled(), promiseResolverBreakpoint.executeCheckIsSetAndEnabled(), promiseResolutionBreakpoint.executeCheckIsSetAndEnabled()); - current.checkSendHooks(msg); + if (VmSettings.ENABLE_ASSERTIONS) { + ((TracingActor) current).checkSendHooks(msg); + } current.send(msg); return Nil.nilObject; } diff --git a/src/som/interpreter/actors/SPromise.java b/src/som/interpreter/actors/SPromise.java index 73e468731..588c7cb55 100644 --- a/src/som/interpreter/actors/SPromise.java +++ b/src/som/interpreter/actors/SPromise.java @@ -80,7 +80,7 @@ public final boolean isValue() { return false; } - public boolean isResultUsed(){ + public boolean isResultUsed() { return resultUsed; } diff --git a/src/som/primitives/AssertionPrims.java b/src/som/primitives/AssertionPrims.java index feeaffa8c..cf135ddcd 100644 --- a/src/som/primitives/AssertionPrims.java +++ b/src/som/primitives/AssertionPrims.java @@ -5,7 +5,6 @@ import com.oracle.truffle.api.source.SourceSection; import som.interpreter.SArguments; -import som.interpreter.actors.Actor; import som.interpreter.actors.Actor.ActorProcessingThread; import som.interpreter.actors.EventualMessage; import som.interpreter.actors.EventualMessage.PromiseMessage; @@ -24,6 +23,7 @@ import tools.concurrency.Assertion.GloballyAssertion; import tools.concurrency.Assertion.NextAssertion; import tools.concurrency.Assertion.UntilAssertion; +import tools.concurrency.TracingActors.TracingActor; public class AssertionPrims { @@ -37,29 +37,13 @@ protected AssertNextPrim(final boolean eagerlyWrapped, final SourceSection sourc @Specialization (guards = "msg==null") public final Object doSBlock(final SBlock statement, final Object msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new NextAssertion(statement)); - + addAssertion(new NextAssertion(statement)); return Nil.nilObject; } @Specialization public final Object doSBlockWithMessage(final SBlock statement, final String msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new NextAssertion(statement, msg)); - + addAssertion(new NextAssertion(statement, msg)); return Nil.nilObject; } } @@ -109,29 +93,13 @@ protected AssertFuturePrim(final boolean eagerlyWrapped, final SourceSection sou @Specialization(guards = "msg==null") public final Object doSBlock(final SBlock statement, final Object msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new FutureAssertion(statement)); - + addAssertion(new FutureAssertion(statement)); return Nil.nilObject; } @Specialization public final Object doSBlockWithMessage(final SBlock statement, final String msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new FutureAssertion(statement, msg)); - + addAssertion(new FutureAssertion(statement, msg)); return Nil.nilObject; } } @@ -146,29 +114,13 @@ protected AssertGloballyPrim(final boolean eagerlyWrapped, final SourceSection s @Specialization(guards = "msg==null") public final Object doSBlock(final SBlock statement, final Object msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new GloballyAssertion(statement)); - + addAssertion(new GloballyAssertion(statement)); return Nil.nilObject; } @Specialization public final Object doSBlockWithMessage(final SBlock statement, final String msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new GloballyAssertion(statement, msg)); - + addAssertion(new GloballyAssertion(statement, msg)); return Nil.nilObject; } } @@ -183,29 +135,13 @@ protected AssertUntilPrim(final boolean eagerlyWrapped, final SourceSection sour @Specialization(guards = "msg == null") public final Object doSBlock(final SBlock statement, final SBlock until, final Object msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new UntilAssertion(statement, until)); - + addAssertion(new UntilAssertion(statement, until)); return Nil.nilObject; } @Specialization public final Object doSBlockWithMessage(final SBlock statement, final SBlock until, final String msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new UntilAssertion(statement, until, msg)); - + addAssertion(new UntilAssertion(statement, until, msg)); return Nil.nilObject; } } @@ -220,28 +156,13 @@ protected AssertReleasePrim(final boolean eagerlyWrapped, final SourceSection so @Specialization(guards = "msg==null") public final Object doSBlock(final SBlock statement, final SBlock release, final Object msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new Assertion.ReleaseAssertion(statement, release)); - + addAssertion(new Assertion.ReleaseAssertion(statement, release)); return Nil.nilObject; } @Specialization public final Object doSBlockWithMessage(final SBlock statement, final SBlock release, final String msg) { - if (!VmSettings.ENABLE_ASSERTIONS) { - return Nil.nilObject; - } - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addAssertion(new Assertion.ReleaseAssertion(statement, release, msg)); - + addAssertion(new Assertion.ReleaseAssertion(statement, release, msg)); return Nil.nilObject; } } @@ -306,10 +227,10 @@ protected IsSenderPrim(final boolean eagerlyWrapped, final SourceSection source) @Specialization public final Object doSSymbol(final SSymbol actorClass) { assert Thread.currentThread() instanceof ActorProcessingThread; - if (EventualMessage.getCurrentExecutingMessage().getSender().getActorType() == null) { + if (((TracingActor) EventualMessage.getCurrentExecutingMessage().getSender()).getActorType() == null) { return actorClass.toString().equals("#main"); } - return EventualMessage.getCurrentExecutingMessage().getSender().getActorType().equals(actorClass); + return ((TracingActor) EventualMessage.getCurrentExecutingMessage().getSender()).getActorType().equals(actorClass); } @Specialization @@ -321,7 +242,7 @@ public final Object doReference(final SFarReference actor) { @Specialization public final Object doString(final String actorType) { assert Thread.currentThread() instanceof ActorProcessingThread; - return EventualMessage.getCurrentExecutingMessage().getSender().getActorType().getString().equals(actorType); + return ((TracingActor) EventualMessage.getCurrentExecutingMessage().getSender()).getActorType().getString().equals(actorType); } } @@ -336,7 +257,7 @@ protected GetSenderPrim(final boolean eagerlyWrapped, final SourceSection source @Specialization public final Object dovoid(final Object receiver) { assert Thread.currentThread() instanceof ActorProcessingThread; - //TODO sending object + // TODO sending object return EventualMessage.getCurrentExecutingMessage().getSender(); } } @@ -391,7 +312,7 @@ public final Object dovoid(final Object receiver) { throw new AssertionError("Message result is unused"); } - EventualMessage.getActorCurrentMessageIsExecutionOn().addAssertion(new Assertion.ResultUsedAssertion(current.getResolver().getPromise(), "Message result is unused")); + getCurrentTracingActor().addAssertion(new Assertion.ResultUsedAssertion(current.getResolver().getPromise(), "Message result is unused")); return null; } } @@ -410,10 +331,7 @@ public final Object doSBlock(final SSymbol message, final SBlock aBlock) { return Nil.nilObject; } - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addSendHook(message, aBlock); + getCurrentTracingActor().addSendHook(message, aBlock); return Nil.nilObject; } @@ -433,12 +351,22 @@ public final Object doSBlock(final SSymbol message, final SBlock aBlock) { return Nil.nilObject; } - assert Thread.currentThread() instanceof ActorProcessingThread; - ActorProcessingThread apt = (ActorProcessingThread) Thread.currentThread(); - Actor a = apt.getCurrentlyExecutingActor(); - a.addReceiveHook(message, aBlock); + getCurrentTracingActor().addReceiveHook(message, aBlock); return Nil.nilObject; } } + + private static void addAssertion(final Assertion assertion) { + if (!VmSettings.ENABLE_ASSERTIONS) { + return; + } + + getCurrentTracingActor().addAssertion(assertion); + } + + private static TracingActor getCurrentTracingActor() { + assert Thread.currentThread() instanceof ActorProcessingThread; + return (TracingActor) ((ActorProcessingThread) Thread.currentThread()).getCurrentlyExecutingActor(); + } } diff --git a/src/som/primitives/actors/CreateActorPrim.java b/src/som/primitives/actors/CreateActorPrim.java index c707df50a..31cfa44e0 100644 --- a/src/som/primitives/actors/CreateActorPrim.java +++ b/src/som/primitives/actors/CreateActorPrim.java @@ -15,6 +15,7 @@ import som.vm.constants.KernelObj; import som.vmobjects.SClass; import tools.concurrency.ActorExecutionTrace; +import tools.concurrency.TracingActors.TracingActor; @GenerateNodeFactory @@ -35,9 +36,9 @@ public final SFarReference createActor(final Object receiver, final Object argum assert argument instanceof SClass; SClass actorClass = (SClass) argument; - actor.setActorType(actorClass.getName()); if (VmSettings.ACTOR_TRACING) { + ((TracingActor) actor).setActorType(actorClass.getName()); ActorExecutionTrace.actorCreation(ref, sourceSection); } return ref; diff --git a/src/som/vm/VmSettings.java b/src/som/vm/VmSettings.java index cccfbac7b..46af4f328 100644 --- a/src/som/vm/VmSettings.java +++ b/src/som/vm/VmSettings.java @@ -59,7 +59,7 @@ public class VmSettings { PROMISE_RESOLVED_WITH = !al.contains("prw") && filter; ACTOR_TRACING = TRUFFLE_DEBUGGER_ENABLED || getBool("som.actorTracing", false) || - REPLAY || MESSAGE_TIMESTAMPS || MESSAGE_PARAMETERS || PROMISE_CREATION; + REPLAY || MESSAGE_TIMESTAMPS || MESSAGE_PARAMETERS || PROMISE_CREATION || ENABLE_ASSERTIONS; boolean dm = getBool("som.dynamicMetrics", false); DYNAMIC_METRICS = dm; diff --git a/src/tools/concurrency/Assertion.java b/src/tools/concurrency/Assertion.java index cebd923ed..f41e71fbb 100644 --- a/src/tools/concurrency/Assertion.java +++ b/src/tools/concurrency/Assertion.java @@ -3,10 +3,10 @@ import java.util.HashSet; import java.util.Set; -import som.interpreter.actors.Actor; import som.interpreter.actors.EventualMessage; import som.interpreter.actors.SPromise; import som.vmobjects.SBlock; +import tools.concurrency.TracingActors.TracingActor; public class Assertion { SBlock statement; @@ -23,7 +23,7 @@ public Assertion(final SBlock statement, final String msg) { this.statement = statement; } - public void evaluate(final Actor actor, final EventualMessage msg) { + public void evaluate(final TracingActor actor, final EventualMessage msg) { boolean result = (boolean) statement.getMethod().invoke(new Object[] {statement}); if (!result) { throwError(); @@ -53,7 +53,7 @@ public UntilAssertion(final SBlock statement, final SBlock until, final String m } @Override - public void evaluate(final Actor actor, final EventualMessage msg) { + public void evaluate(final TracingActor actor, final EventualMessage msg) { boolean result = (boolean) until.getMethod().invoke(new Object[] {until}); if (!result) { boolean result2 = (boolean) statement.getMethod().invoke(new Object[] {statement}); @@ -80,7 +80,7 @@ public ReleaseAssertion(final SBlock statement, final SBlock release, final Stri } @Override - public void evaluate(final Actor actor, final EventualMessage msg) { + public void evaluate(final TracingActor actor, final EventualMessage msg) { boolean result = (boolean) release.getMethod().invoke(new Object[] {release}); if (!result) { throwError(); @@ -121,7 +121,7 @@ public FutureAssertion(final SBlock statement, final String msg) { } @Override - public void evaluate(final Actor actor, final EventualMessage msg) { + public void evaluate(final TracingActor actor, final EventualMessage msg) { boolean result = (boolean) statement.getMethod().invoke(new Object[] {statement}); if (result) { synchronized (futureAssertions) { @@ -149,7 +149,7 @@ public GloballyAssertion(final SBlock statement, final String msg) { } @Override - public void evaluate(final Actor actor, final EventualMessage msg) { + public void evaluate(final TracingActor actor, final EventualMessage msg) { boolean result = (boolean) statement.getMethod().invoke(new Object[] {statement}); if (!result) { throwError(); @@ -173,7 +173,7 @@ public ResultUsedAssertion(final SPromise statement, final String msg) { } @Override - public void evaluate(final Actor actor, final EventualMessage msg) { + public void evaluate(final TracingActor actor, final EventualMessage msg) { synchronized (checkedPromise) { if (checkedPromise.isResultUsed()) { synchronized (futureAssertions) { diff --git a/src/tools/concurrency/TracingActors.java b/src/tools/concurrency/TracingActors.java index b808c57b2..935f1c2d3 100644 --- a/src/tools/concurrency/TracingActors.java +++ b/src/tools/concurrency/TracingActors.java @@ -1,6 +1,7 @@ package tools.concurrency; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Queue; @@ -8,10 +9,13 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import som.VM; +import som.interpreter.SArguments; import som.interpreter.actors.Actor; import som.interpreter.actors.EventualMessage; import som.interpreter.actors.EventualMessage.PromiseMessage; import som.vm.VmSettings; +import som.vmobjects.SBlock; +import som.vmobjects.SSymbol; import tools.concurrency.TraceParser.MessageRecord; import tools.debugger.WebDebugger; @@ -20,6 +24,12 @@ public static class TracingActor extends Actor { protected final long actorId; protected int mailboxNumber; + private SSymbol actorType = null; + + private List activeAssertions; + private HashMap sendHooks; + private HashMap receiveHooks; + public TracingActor() { super(); if (Thread.currentThread() instanceof TracingActivityThread) { @@ -36,6 +46,89 @@ public int getAndIncrementMailboxNumber() { @Override public long getId() { return actorId; } + + public SSymbol getActorType() { + return actorType; + } + + public void setActorType(final SSymbol actorType) { + this.actorType = actorType; + } + + public void addAssertion(final Assertion a) { + if (activeAssertions == null) { + activeAssertions = new ArrayList<>(); + } + activeAssertions.add(a); + } + + @TruffleBoundary + public void addSendHook(final SSymbol msg, final SBlock block) { + if (sendHooks == null) { + sendHooks = new HashMap<>(); + } + sendHooks.put(msg, block); + } + + @TruffleBoundary + public void addReceiveHook(final SSymbol msg, final SBlock block) { + if (receiveHooks == null) { + receiveHooks = new HashMap<>(); + } + receiveHooks.put(msg, block); + } + + public void checkAssertions(final EventualMessage msg) { + if (activeAssertions == null || activeAssertions.size() == 0) { + return; + } + + List temp = activeAssertions; + + activeAssertions = new ArrayList<>(); + + + for (Assertion a : temp) { + a.evaluate(this, msg); + } + } + + @TruffleBoundary + public void checkSendHooks(final EventualMessage msg) { + if (sendHooks != null) { + if (sendHooks.containsKey(msg.getSelector())) { + SBlock block = sendHooks.get(msg.getSelector()); + sendHooks.clear(); + if (receiveHooks != null) { + receiveHooks.clear(); + } + + if (block.getMethod().getNumberOfArguments() > 0) { + block.getMethod().invoke(new Object[] {block, SArguments.getArgumentsWithoutReceiver(msg.getArgs())}); + } else { + block.getMethod().invoke(new Object[] {block}); + } + } else if (sendHooks.size() > 0) { + throw new AssertionError("sending Message: " + msg.getSelector() + " violates the message protocol!"); + } + } + } + + @TruffleBoundary + public void checkReceiveHooks(final EventualMessage msg) { + if (receiveHooks != null) { + if (receiveHooks.containsKey(msg.getSelector())) { + SBlock block = receiveHooks.get(msg.getSelector()); + receiveHooks.clear(); + if (sendHooks != null) { + sendHooks.clear(); + } + block.getMethod().invoke(new Object[] {block, SArguments.getArgumentsWithoutReceiver(msg.getArgs())}); + } else if (receiveHooks.size() > 0) { + throw new AssertionError("receiving Message: " + msg.getSelector() + " violates the message protocol!"); + } + } + } } public static final class ReplayActor extends TracingActor {