From 09c4add469afc98bc462f02501fe6c3531d6b853 Mon Sep 17 00:00:00 2001 From: carmen Date: Fri, 18 Oct 2019 17:12:19 +0200 Subject: [PATCH] Add support for pausing an actor - add static map in in Tracing actors to keep all the actors created in the system. One actor is added to the map every time an actor is created by the createActorFromValue primitive. - add a new incomming message for the request of pausing an actor (PauseActorRequest) - add a method in the WebDebugger that get the actor by its id accessing the map created in TracingActor class - make public the log method of the FrontendConnector to notify by console the actor will pause before processing the next message --- .../primitives/actors/CreateActorPrim.java | 2 ++ src/tools/concurrency/TracingActors.java | 19 ++++++++++---- src/tools/debugger/FrontendConnector.java | 17 ++++++------- .../RuntimeReflectionRegistration.java | 18 ++----------- src/tools/debugger/WebDebugger.java | 6 +++++ .../debugger/message/PauseActorRequest.java | 25 +++++++++++++++++++ 6 files changed, 56 insertions(+), 31 deletions(-) create mode 100644 src/tools/debugger/message/PauseActorRequest.java diff --git a/src/som/primitives/actors/CreateActorPrim.java b/src/som/primitives/actors/CreateActorPrim.java index dc318c334..3343cd04d 100644 --- a/src/som/primitives/actors/CreateActorPrim.java +++ b/src/som/primitives/actors/CreateActorPrim.java @@ -52,6 +52,8 @@ public final SFarReference createActor(final VirtualFrame frame, final Object re final SClass actorClass = (SClass) argument; KomposTrace.activityCreation(ActivityType.ACTOR, actor.getId(), actorClass.getName(), sourceSection); + //to keep all the created actors, this information is needed for example when pausing a running actor without specifying a breakpoint + TracingActor.saveActor(actor); } return ref; } diff --git a/src/tools/concurrency/TracingActors.java b/src/tools/concurrency/TracingActors.java index 7d09f5352..0a02eeeab 100644 --- a/src/tools/concurrency/TracingActors.java +++ b/src/tools/concurrency/TracingActors.java @@ -1,10 +1,6 @@ package tools.concurrency; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; -import java.util.WeakHashMap; +import java.util.*; import java.util.concurrent.ForkJoinPool; import java.util.function.BiConsumer; @@ -42,6 +38,11 @@ public static class TracingActor extends Actor { */ protected boolean stepToNextTurn; + /** + * Saves all ids and the instances of the actors created in the system. + */ + private static Map allActors = new HashMap<>(); + public TracingActor(final VM vm) { super(vm); this.activityId = TracingActivityThread.newEntityId(vm); @@ -120,6 +121,14 @@ public static void handleBreakpointsAndStepping(final EventualMessage msg, public DeserializationBuffer getDeserializationBuffer() { return null; } + + public static void saveActor(Actor actor) { + allActors.put(actor.getId(), actor); + } + + public static Actor getActorById(long actorId){ + return allActors.get(actorId); + } } public static final class ReplayActor extends TracingActor { diff --git a/src/tools/debugger/FrontendConnector.java b/src/tools/debugger/FrontendConnector.java index be87a92c8..ed1032dd2 100644 --- a/src/tools/debugger/FrontendConnector.java +++ b/src/tools/debugger/FrontendConnector.java @@ -24,6 +24,7 @@ import bd.source.SourceCoordinate; import bd.source.TaggedSourceCoordinate; +import som.interpreter.actors.Actor; import som.vm.VmSettings; import som.vmobjects.SSymbol; import tools.Tagging; @@ -41,18 +42,10 @@ import tools.debugger.entities.SendOp; import tools.debugger.entities.SteppingType; import tools.debugger.frontend.Suspension; -import tools.debugger.message.InitializationResponse; -import tools.debugger.message.Message; +import tools.debugger.message.*; import tools.debugger.message.Message.OutgoingMessage; -import tools.debugger.message.ProgramInfoResponse; -import tools.debugger.message.ScopesResponse; -import tools.debugger.message.SourceMessage; import tools.debugger.message.SourceMessage.SourceData; -import tools.debugger.message.StackTraceResponse; -import tools.debugger.message.StoppedMessage; -import tools.debugger.message.SymbolMessage; import tools.debugger.message.VariablesRequest.FilterType; -import tools.debugger.message.VariablesResponse; import tools.debugger.session.Breakpoints; import tools.debugger.session.LineBreakpoint; @@ -320,7 +313,11 @@ public Suspension getSuspensionForGlobalId(final long globalId) { return webDebugger.getSuspension(TraceData.getActivityIdFromGlobalValId(globalId)); } - static void log(final String str) { + public Actor getActorById(final long activityId) { + return webDebugger.getActorById(activityId); + } + + public static void log(final String str) { // Checkstyle: stop System.out.println(str); // Checkstyle: resume diff --git a/src/tools/debugger/RuntimeReflectionRegistration.java b/src/tools/debugger/RuntimeReflectionRegistration.java index a3a642e25..94f95ddc4 100644 --- a/src/tools/debugger/RuntimeReflectionRegistration.java +++ b/src/tools/debugger/RuntimeReflectionRegistration.java @@ -14,24 +14,9 @@ import com.google.gson.GsonBuilder; import com.oracle.svm.core.annotate.AutomaticFeature; -import tools.debugger.message.InitializationResponse; -import tools.debugger.message.InitializeConnection; +import tools.debugger.message.*; import tools.debugger.message.Message.IncommingMessage; import tools.debugger.message.Message.OutgoingMessage; -import tools.debugger.message.ProgramInfoRequest; -import tools.debugger.message.ProgramInfoResponse; -import tools.debugger.message.ScopesRequest; -import tools.debugger.message.ScopesResponse; -import tools.debugger.message.SourceMessage; -import tools.debugger.message.StackTraceRequest; -import tools.debugger.message.StackTraceResponse; -import tools.debugger.message.StepMessage; -import tools.debugger.message.StoppedMessage; -import tools.debugger.message.SymbolMessage; -import tools.debugger.message.TraceDataRequest; -import tools.debugger.message.UpdateBreakpoint; -import tools.debugger.message.VariablesRequest; -import tools.debugger.message.VariablesResponse; import tools.debugger.session.BreakpointInfo; import tools.debugger.session.LineBreakpoint; import tools.debugger.session.SectionBreakpoint; @@ -91,6 +76,7 @@ public void register(final String name, final Class klass) { inMsgs.register(VariablesRequest.class); inMsgs.register(ProgramInfoRequest.class); inMsgs.register(TraceDataRequest.class); + inMsgs.register("pauseActorMessageReceiver", PauseActorRequest.class); ClassGroup bps = new ClassGroup(BreakpointInfo.class, "type", true); bps.register(LineBreakpoint.class); diff --git a/src/tools/debugger/WebDebugger.java b/src/tools/debugger/WebDebugger.java index 593e19bf1..3da030237 100644 --- a/src/tools/debugger/WebDebugger.java +++ b/src/tools/debugger/WebDebugger.java @@ -25,10 +25,12 @@ import bd.source.SourceCoordinate; import som.VM; +import som.interpreter.actors.Actor; import som.vm.Activity; import som.vm.Symbols; import tools.TraceData; import tools.concurrency.TracingActivityThread; +import tools.concurrency.TracingActors; import tools.debugger.frontend.Suspension; import tools.debugger.session.Breakpoints; @@ -178,5 +180,9 @@ public Breakpoints getBreakpoints() { return breakpoints; } + public Actor getActorById(long actorId) { + return TracingActors.TracingActor.getActorById(actorId); + } + private static Gson jsonProcessor = RuntimeReflectionRegistration.createJsonProcessor(); } diff --git a/src/tools/debugger/message/PauseActorRequest.java b/src/tools/debugger/message/PauseActorRequest.java new file mode 100644 index 000000000..93a3af1ce --- /dev/null +++ b/src/tools/debugger/message/PauseActorRequest.java @@ -0,0 +1,25 @@ +package tools.debugger.message; + +import org.java_websocket.WebSocket; +import som.interpreter.actors.Actor; +import tools.debugger.FrontendConnector; + +public class PauseActorRequest extends Message.IncommingMessage { + private final long actorId; + + public PauseActorRequest() { + actorId = -1; + } + + public PauseActorRequest(long actorId) { + this.actorId = actorId; + } + + @Override + public void process(FrontendConnector connector, WebSocket conn) { + Actor actor = connector.getActorById(this.actorId); + assert actor != null : "Failed to get actor for activityId: " + this.actorId; + actor.setStepToNextTurn(true); + FrontendConnector.log("[DEBUGGER] Actor "+actor.getId() +" will pause before processing the next message."); + } +}