Skip to content

Commit

Permalink
added remote assertions
Browse files Browse the repository at this point in the history
  • Loading branch information
daumayr committed May 9, 2017
1 parent 700b8a7 commit e9dcd83
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 20 deletions.
39 changes: 39 additions & 0 deletions core-lib/Assertions.som
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class Assertions usingVmMirror: vmMirror usingKernel: kernel usingPlatform: plat
private system = platform system.
private ObjectMirror = platform mirrors ObjectMirror.
|

vmMirror setAssertionModule: self.

)(

public class ValueAssertions = Assertions <: Value(
Expand Down Expand Up @@ -107,6 +110,26 @@ class Assertions usingVmMirror: vmMirror usingKernel: kernel usingPlatform: plat
]
)

public assert: aBlock on: anotherActor = (
assert: aBlock on: anotherActor msg: 'Assertion failed'.
)

public assert: aBlock on: anotherActor msg: msg = (
assert: aBlock on: anotherActor handler: [
system error: msg.
].
)

public assert: aBlock on: anotherActor handler: anotherBlock = (
| pp |
(vmMirror AssertionsEnabled: self) ifFalse: [^ nil].

pp := createUntracedPromisePair.
vmMirror assert: aBlock on: anotherActor res: (pp resolver).

pp promise whenResolved: [ :r | r ifFalse: anotherBlock]
)

public next: aBlock = (
| pp |
pp := createUntracedPromisePair.
Expand Down Expand Up @@ -299,4 +322,20 @@ class Assertions usingVmMirror: vmMirror usingKernel: kernel usingPlatform: plat
^ moduleClass.
)
)

public class RemoteAssertion new: target = Assertions (
| target = target. |
)(
public perform: selector = (
^ (ObjectMirror reflecting: target) perform: selector.
)

public self = (
^ target.
)
)

public instantiateRemoteAssertion: target = (
^ RemoteAssertion new: target.
)
)
50 changes: 43 additions & 7 deletions src/som/primitives/AssertionPrims.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@
import som.interpreter.nodes.nary.BinaryExpressionNode;
import som.interpreter.nodes.nary.TernaryExpressionNode;
import som.interpreter.nodes.nary.UnaryBasicOperation;
import som.interpreter.nodes.nary.UnaryExpressionNode;
import som.vm.VmSettings;
import som.vm.constants.Nil;
import som.vmobjects.SBlock;
import som.vmobjects.SObject.SImmutableObject;
import som.vmobjects.SSymbol;
import tools.concurrency.Assertion;
import tools.concurrency.Assertion.FutureAssertion;
import tools.concurrency.Assertion.GloballyAssertion;
import tools.concurrency.Assertion.NextAssertion;
import tools.concurrency.Assertion.RemoteAssertion;
import tools.concurrency.Assertion.UntilAssertion;
import tools.concurrency.TracingActors.TracingActor;

Expand All @@ -45,7 +48,7 @@ protected AssertNextPrim(final boolean eagerlyWrapped, final SourceSection sourc

@Specialization
public final Object doSBlock(final SBlock statement, final SResolver resolver) {
addAssertion(new NextAssertion(statement, resolver));
addAssertion(getCurrentTracingActor(), new NextAssertion(statement, resolver));
return Nil.nilObject;
}
}
Expand All @@ -62,7 +65,7 @@ protected AssertFuturePrim(final boolean eagerlyWrapped, final SourceSection sou
@Specialization
public final Object doSBlock(final SBlock statement, final SResolver resolver) {
if (VmSettings.ENABLE_ASSERTIONS) {
addAssertion(new FutureAssertion(statement, resolver));
addAssertion(getCurrentTracingActor(), new FutureAssertion(statement, resolver));
}
return Nil.nilObject;
}
Expand All @@ -79,7 +82,7 @@ protected AssertGloballyPrim(final boolean eagerlyWrapped, final SourceSection s

@Specialization
public final Object doSBlock(final SBlock statement, final SResolver resolver) {
addAssertion(new GloballyAssertion(statement, resolver));
addAssertion(getCurrentTracingActor(), new GloballyAssertion(statement, resolver));
return Nil.nilObject;
}
}
Expand All @@ -95,7 +98,7 @@ protected AssertUntilPrim(final boolean eagerlyWrapped, final SourceSection sour

@Specialization
public final Object doSBlock(final SBlock statement, final SBlock until, final SResolver resolver) {
addAssertion(new UntilAssertion(statement, resolver, until));
addAssertion(getCurrentTracingActor(), new UntilAssertion(statement, resolver, until));
return Nil.nilObject;
}
}
Expand All @@ -111,7 +114,25 @@ protected AssertReleasePrim(final boolean eagerlyWrapped, final SourceSection so

@Specialization
public final Object doSBlock(final SBlock statement, final SBlock release, final SResolver resolver) {
addAssertion(new Assertion.ReleaseAssertion(statement, resolver, release));
addAssertion(getCurrentTracingActor(), new Assertion.ReleaseAssertion(statement, resolver, release));
return Nil.nilObject;
}
}

@GenerateNodeFactory
@ImportStatic(Nil.class)
@Primitive(primitive = "assert:on:res:")
public abstract static class AssertOnPrim extends TernaryExpressionNode{

protected AssertOnPrim(final boolean eagerlyWrapped, final SourceSection source) {
super(eagerlyWrapped, source);
}

@Specialization
public final Object doSBlock(final SBlock statement, final SFarReference target, final SResolver resolver) {
assert !statement.hasContext() : "assert:on: only supports blocks without context!";

addAssertion((TracingActor) target.getActor(), new RemoteAssertion(statement, resolver, target.getValue()));
return Nil.nilObject;
}
}
Expand Down Expand Up @@ -331,12 +352,27 @@ public final Object doSBlock(final SSymbol message, final SBlock aBlock) {
}
}

private static void addAssertion(final Assertion assertion) {
@GenerateNodeFactory
@Primitive(primitive = "setAssertionModule:")
public abstract static class SetAssertionModulePrim extends UnaryExpressionNode{

protected SetAssertionModulePrim(final boolean eagerlyWrapped, final SourceSection source) {
super(eagerlyWrapped, source);
}

@Specialization
public final Object doSBlock(final SImmutableObject assertionClass) {
Assertion.setAssertionModule(assertionClass);
return null;
}
}

private static void addAssertion(final TracingActor target, final Assertion assertion) {
if (!VmSettings.ENABLE_ASSERTIONS) {
return;
}

getCurrentTracingActor().addAssertion(assertion);
target.addAssertion(assertion);
}

private static TracingActor getCurrentTracingActor() {
Expand Down
4 changes: 4 additions & 0 deletions src/som/vmobjects/SBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public MaterializedFrame getContext() {
return context;
}

public boolean hasContext() {
return context != null;
}

public Object getOuterSelf() {
return SArguments.rcvr(getContext());
}
Expand Down
37 changes: 37 additions & 0 deletions src/tools/concurrency/Assertion.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.nodes.Node.Child;

import som.VM;
import som.interpreter.SomLanguage;
import som.interpreter.actors.EventualMessage;
import som.interpreter.actors.ResolvePromiseNode;
Expand All @@ -15,10 +16,14 @@
import som.interpreter.actors.SPromise.SResolver;
import som.interpreter.actors.WrapReferenceNode;
import som.interpreter.actors.WrapReferenceNodeGen;
import som.vm.Symbols;
import som.vmobjects.SBlock;
import som.vmobjects.SInvokable;
import som.vmobjects.SObject.SImmutableObject;
import tools.concurrency.TracingActors.TracingActor;

public class Assertion {
static SImmutableObject assertionModule;
SBlock statement;
SResolver result;

Expand All @@ -32,6 +37,10 @@ public Assertion(final SBlock statement, final SResolver result) {
wrapper = WrapReferenceNodeGen.create();
}

public static void setAssertionModule(final SImmutableObject assertionClass) {
Assertion.assertionModule = assertionClass;
}


/***
* @return returns a boolean indicating whether the Assertion should be checked again next time.
Expand All @@ -58,6 +67,34 @@ protected void success(final ForkJoinPool actorPool) {
result.getPromise().getOwner(), actorPool, false);
}

public static class RemoteAssertion extends Assertion {
final Object target;
public RemoteAssertion(final SBlock statement, final SResolver result, final Object target) {
super(statement, result);
this.target = target;
}

@Override
public boolean evaluate(final TracingActor actor, final EventualMessage msg, final ForkJoinPool actorPool) {
boolean result = (boolean) statement.getMethod().invoke(new Object[] {statement, createWrapper(target)});
if (!result) {
fail(actorPool);
} else {
success(actorPool);
}
return false;
}

private Object createWrapper(final Object target) {
CompilerDirectives.transferToInterpreter();
VM.thisMethodNeedsToBeOptimized("Should be optimized or on slowpath");
SInvokable disp = (SInvokable) assertionModule.getSOMClass().lookupPrivate(
Symbols.symbolFor("instantiateRemoteAssertion:"),
assertionModule.getSOMClass().getMixinDefinition().getMixinId());
return disp.invoke(new Object[] {assertionModule, target});
}
}

public static class UntilAssertion extends Assertion {
SBlock until;

Expand Down
30 changes: 17 additions & 13 deletions src/tools/concurrency/TracingActors.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ public void setActorType(final SSymbol actorType) {
}

public void addAssertion(final Assertion a) {
if (activeAssertions == null) {
activeAssertions = new ArrayList<>();
}
synchronized (this) {
if (activeAssertions == null) {
activeAssertions = new ArrayList<>();
}

activeAssertions.add(a);
activeAssertions.add(a);
}
}

@TruffleBoundary
Expand All @@ -85,16 +87,18 @@ public void addReceiveHook(final SSymbol msg, final SBlock block) {
}

public void checkAssertions(final EventualMessage msg, final VM vm) {
if (activeAssertions == null || activeAssertions.size() == 0) {
return;
}
synchronized (this) {
if (activeAssertions == null || activeAssertions.size() == 0) {
return;
}

// safe way for iterating and removing elements, for each caused concurrent modification exception for no reason.
Iterator<Assertion> iter = activeAssertions.iterator();
while (iter.hasNext()) {
Assertion a = iter.next();
if (!a.evaluate(this, msg, vm.getActorPool())) {
iter.remove();
// safe way for iterating and removing elements, for each caused concurrent modification exception for no reason.
Iterator<Assertion> iter = activeAssertions.iterator();
while (iter.hasNext()) {
Assertion a = iter.next();
if (!a.evaluate(this, msg, vm.getActorPool())) {
iter.remove();
}
}
}
}
Expand Down

0 comments on commit e9dcd83

Please sign in to comment.