Skip to content

Commit

Permalink
Move Actor.wrapForUse to WrapReferenceNode
Browse files Browse the repository at this point in the history
- this moves the code closer together
- restructure code to more easily match the specializations

Signed-off-by: Stefan Marr <git@stefan-marr.de>
  • Loading branch information
smarr committed Jun 20, 2020
1 parent 32b27c4 commit 10d095a
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 67 deletions.
49 changes: 0 additions & 49 deletions src/som/interpreter/actors/Actor.java
@@ -1,6 +1,5 @@
package som.interpreter.actors;

import java.util.Map;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
import java.util.concurrent.ForkJoinWorkerThread;
Expand All @@ -17,13 +16,8 @@
import som.VM;
import som.interpreter.SomLanguage;
import som.interpreter.objectstorage.ObjectTransitionSafepoint;
import som.primitives.ObjectPrims.IsValue;
import som.vm.Activity;
import som.vm.VmSettings;
import som.vmobjects.SAbstractObject;
import som.vmobjects.SArray.STransferArray;
import som.vmobjects.SObject;
import som.vmobjects.SObjectWithClass.SObjectWithoutFields;
import tools.ObjectBuffer;
import tools.concurrency.KomposTrace;
import tools.concurrency.TracingActivityThread;
Expand Down Expand Up @@ -117,49 +111,6 @@ protected ExecAllMessages createExecutor(final VM vm) {
return new ExecAllMessages(this, vm);
}

public final Object wrapForUse(final Object o, final Actor owner,
final Map<SAbstractObject, SAbstractObject> transferedObjects) {
VM.thisMethodNeedsToBeOptimized("This should probably be optimized");

if (this == owner) {
return o;
}

if (o instanceof SFarReference) {
if (((SFarReference) o).getActor() == this) {
return ((SFarReference) o).getValue();
}
} else if (o instanceof SPromise) {
// promises cannot just be wrapped in far references, instead, other actors
// should get a new promise that is going to be resolved once the original
// promise gets resolved

SPromise orgProm = (SPromise) o;
// assert orgProm.getOwner() == owner; this can be another actor, which initialized a
// scheduled eventual send by resolving a promise, that's the promise pipelining...
if (orgProm.getOwner() == this) {
return orgProm;
}
return orgProm.getChainedPromiseFor(this);
} else if (!IsValue.isObjectValue(o)) {
// Corresponds to TransferObject.isTransferObject()
if ((o instanceof SObject && ((SObject) o).getSOMClass().isTransferObject())) {
return TransferObject.transfer((SObject) o, owner, this,
transferedObjects);
} else if (o instanceof STransferArray) {
return TransferObject.transfer((STransferArray) o, owner, this,
transferedObjects);
} else if (o instanceof SObjectWithoutFields
&& ((SObjectWithoutFields) o).getSOMClass().isTransferObject()) {
return TransferObject.transfer((SObjectWithoutFields) o, owner, this,
transferedObjects);
} else {
return new SFarReference(owner, o);
}
}
return o;
}

@Override
public void setStepToJoin(final boolean val) {
throw new UnsupportedOperationException(
Expand Down
6 changes: 3 additions & 3 deletions src/som/interpreter/actors/EventualMessage.java
Expand Up @@ -208,7 +208,7 @@ protected static Actor determineTargetAndWrapArguments(final Object[] arguments,
// however, if a promise gets resolved to a far reference
// we need to redirect the message to the owner of that far reference

Object receiver = target.wrapForUse(arguments[0], currentSender, null);
Object receiver = WrapReferenceNode.wrapForUse(target, arguments[0], currentSender, null);
assert !(receiver instanceof SPromise) : "TODO: handle this case as well?? Is it possible? didn't think about it";

if (receiver instanceof SFarReference) {
Expand All @@ -224,7 +224,7 @@ protected static Actor determineTargetAndWrapArguments(final Object[] arguments,
assert !(receiver instanceof SPromise);

for (int i = 1; i < arguments.length; i++) {
arguments[i] = target.wrapForUse(arguments[i], originalSender, null);
arguments[i] = WrapReferenceNode.wrapForUse(target, arguments[i], originalSender, null);
}

return target;
Expand Down Expand Up @@ -396,7 +396,7 @@ public void resolve(final Object rcvr, final Actor target, final Actor sendingAc
* @param resolvingActor - the owner of the value, the promise was resolved to.
*/
private void setPromiseValue(final Object value, final Actor resolvingActor) {
args[1] = originalSender.wrapForUse(value, resolvingActor, null);
args[1] = WrapReferenceNode.wrapForUse(originalSender, value, resolvingActor, null);
if (VmSettings.SNAPSHOTS_ENABLED) {
this.messageId = Math.min(this.messageId,
ActorProcessingThread.currentThread().getSnapshotId());
Expand Down
4 changes: 2 additions & 2 deletions src/som/interpreter/actors/SPromise.java
Expand Up @@ -441,7 +441,7 @@ protected static void resolveChainedPromisesUnsync(final Resolution type,
if (promise.chainedPromise != null) {
SPromise chainedPromise = promise.chainedPromise;
promise.chainedPromise = null;
Object wrapped = chainedPromise.owner.wrapForUse(result, current, null);
Object wrapped = WrapReferenceNode.wrapForUse(chainedPromise.owner, result, current, null);
resolveAndTriggerListenersUnsynced(type, result, wrapped,
chainedPromise, current, actorPool,
chainedPromise.haltOnResolution, whenResolvedProfile);
Expand All @@ -463,7 +463,7 @@ private static void resolveMoreChainedPromisesUnsynced(final Resolution type,
promise.chainedPromiseExt = null;

for (SPromise p : chainedPromiseExt) {
Object wrapped = p.owner.wrapForUse(result, current, null);
Object wrapped = WrapReferenceNode.wrapForUse(p.owner, result, current, null);
resolveAndTriggerListenersUnsynced(type, result, wrapped, p, current,
actorPool, haltOnResolution, whenResolvedProfile);
}
Expand Down
6 changes: 3 additions & 3 deletions src/som/interpreter/actors/TransferObject.java
Expand Up @@ -71,7 +71,7 @@ public static SObject transfer(final SObject obj, final Actor origin,
// if it was already transfered, take it from the map, otherwise, handle it
Object trnfObj = transferMap.get(orgObj);
if (trnfObj == null) {
trnfObj = target.wrapForUse(orgObj, origin, transferMap);
trnfObj = WrapReferenceNode.wrapForUse(target, orgObj, origin, transferMap);
}
location.write(newObj, trnfObj);
}
Expand Down Expand Up @@ -107,7 +107,7 @@ public static STransferArray transfer(final STransferArray arr,
// if it was already transfered, take it from the map, otherwise, handle it
Object trnfObj = transferMap.get(orgObj);
if (trnfObj == null) {
trnfObj = target.wrapForUse(orgObj, origin, transferMap);
trnfObj = WrapReferenceNode.wrapForUse(target, orgObj, origin, transferMap);
}

storage[i] = trnfObj;
Expand All @@ -127,7 +127,7 @@ public static STransferArray transfer(final STransferArray arr,
// if it was already transfered, take it from the map, otherwise, handle it
Object trnfObj = transferMap.get(orgObj);
if (trnfObj == null) {
trnfObj = target.wrapForUse(orgObj, origin, transferMap);
trnfObj = WrapReferenceNode.wrapForUse(target, orgObj, origin, transferMap);
}

storage[i] = trnfObj;
Expand Down
84 changes: 74 additions & 10 deletions src/som/interpreter/actors/WrapReferenceNode.java
@@ -1,12 +1,17 @@
package som.interpreter.actors;

import java.util.Map;

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;

import som.VM;
import som.primitives.ObjectPrims.IsValue;
import som.primitives.ObjectPrimsFactory.IsValueFactory;
import som.vmobjects.SAbstractObject;
import som.vmobjects.SArray.STransferArray;
import som.vmobjects.SObject;
import som.vmobjects.SObjectWithClass.SObjectWithoutFields;


public abstract class WrapReferenceNode extends Node {
Expand All @@ -18,30 +23,30 @@ protected static final boolean notFarRef(final Object ref) {
}

@Specialization(guards = {"target == owner", "notFarRef(ref)"})
public Object inSameActor(final Object ref, final Actor target, final Actor owner) {
protected static Object inSameActor(final Object ref, final Actor target, final Actor owner) {
return ref;
}

@Specialization(guards = "ref.getActor() == target")
public Object farRefToTarget(final SFarReference ref, final Actor target,
protected static Object farRefToTarget(final SFarReference ref, final Actor target,
final Actor owner) {
return ref.getValue();
}

@Specialization(guards = "ref.getActor() != target")
public SFarReference farRefNotToTarget(final SFarReference ref, final Actor target,
protected static SFarReference farRefNotToTarget(final SFarReference ref, final Actor target,
final Actor owner) {
return ref;
}

@Specialization(guards = "promise.getOwner() == target")
public SPromise promiseOwnedByTarget(final SPromise promise, final Actor target,
protected static SPromise promiseOwnedByTarget(final SPromise promise, final Actor target,
final Actor owner) {
return promise;
}

@Specialization(guards = "promise.getOwner() != target")
public SPromise promiseNotOwnedByTarget(final SPromise promise, final Actor target,
protected static SPromise promiseNotOwnedByTarget(final SPromise promise, final Actor target,
final Actor owner) {
return promise.getChainedPromiseFor(target);
}
Expand All @@ -57,29 +62,88 @@ protected final boolean isValue(final Object obj) {
}

@Specialization(guards = {"isNeitherFarRefNorPromise(obj)", "isValue(obj)"})
public Object isValueObject(final Object obj, final Actor target, final Actor owner) {
protected Object isValueButNeitherFarRefNorPromiseObject(final Object obj,
final Actor target, final Actor owner) {
return obj;
}

protected final boolean isTransferObj(final Object obj) {
protected static final boolean isTransferObj(final Object obj) {
// TODO: optimize!
return TransferObject.isTransferObject(obj);
}

@Specialization(
guards = {"isNeitherFarRefNorPromise(obj)", "!isValue(obj)", "!isTransferObj(obj)"})
public Object isNotValueObject(final Object obj, final Actor target, final Actor owner) {
protected Object isNotValueNotFarRefNotPromiseObject(final Object obj, final Actor target,
final Actor owner) {
return new SFarReference(owner, obj);
}

@Specialization(guards = {"isTransferObj(obj)"})
public Object isTransferObject(final SObject obj, final Actor target, final Actor owner) {
protected static Object isTransferObject(final SObject obj, final Actor target,
final Actor owner) {
return TransferObject.transfer(obj, owner, target, null);
}

@Specialization
public Object isTransferArray(final STransferArray obj, final Actor target,
protected static Object isTransferArray(final STransferArray obj, final Actor target,
final Actor owner) {
return TransferObject.transfer(obj, owner, target, null);
}

public static final Object wrapForUse(final Actor target, final Object o, final Actor owner,
final Map<SAbstractObject, SAbstractObject> transferedObjects) {
VM.thisMethodNeedsToBeOptimized("This should probably be optimized");

// inSameActor
if (target == owner) {
return o;
}

if (o instanceof SFarReference) {
SFarReference ref = (SFarReference) o;
if (ref.getActor() == target) {
// farRefToTarget
return ref.getValue();
} else {
// farRefNotToTarget
return ref;
}
}

if (o instanceof SPromise) {
// promises cannot just be wrapped in far references, instead, other actors
// should get a new promise that is going to be resolved once the original
// promise gets resolved

SPromise orgProm = (SPromise) o;
// assert orgProm.getOwner() == owner; this can be another actor, which initialized a
// scheduled eventual send by resolving a promise, that's the promise pipelining...
if (orgProm.getOwner() == target) {
// promiseOwnedByTarget
return orgProm;
} else {
// promiseNotOwnedByTarget
return orgProm.getChainedPromiseFor(target);
}
}

if (IsValue.isObjectValue(o)) {
// isValueButNeitherFarRefNorPromiseObject
return o;
}

// Corresponds to TransferObject.isTransferObject()
if ((o instanceof SObject && ((SObject) o).getSOMClass().isTransferObject())) {
return TransferObject.transfer((SObject) o, owner, target, transferedObjects);
} else if (o instanceof STransferArray) {
return TransferObject.transfer((STransferArray) o, owner, target, transferedObjects);
} else if (o instanceof SObjectWithoutFields
&& ((SObjectWithoutFields) o).getSOMClass().isTransferObject()) {
return TransferObject.transfer((SObjectWithoutFields) o, owner, target,
transferedObjects);
} else {
return new SFarReference(owner, o);
}
}
}

0 comments on commit 10d095a

Please sign in to comment.