Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Instrumentor
private: true
advanced: true
---
Registers callback to be executed at the begining of node/expression
Registers callback to be executed at the beginning of node/expression
execution. The callback `fn` gets UUID of the node/expression that is
being executed and can return `Nothing` to continue regular execution or
anything else to skip the execution and just return given value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private RuntimeOptions() {}
OptionDescriptor.newBuilder(JOB_PARALLELISM_KEY, JOB_PARALLELISM).build();

public static final String GUEST_PARALLELISM = interpreterOptionName("guestParallelism");
public static final OptionKey<Integer> GUEST_PARALLELISM_KEY = new OptionKey<>(1);
public static final OptionKey<Integer> GUEST_PARALLELISM_KEY = new OptionKey<>(2);
public static final OptionDescriptor GUEST_PARALLELISM_DESCRIPTOR =
OptionDescriptor.newBuilder(GUEST_PARALLELISM_KEY, GUEST_PARALLELISM)
.category(OptionCategory.EXPERT)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.enso.polyglot;

import java.util.UUID;

/**
* UUID that is externally accessible. Nodes with external UUID can be cached and visualizations can
* be attached to them.
*
* @param uuid unique identifier
* @param cached flag indicating if the value of the given UUID will be cached internally
*/
public record ExternalUUID(UUID uuid, boolean cached) implements RuntimeID {

public ExternalUUID(UUID uuid) {
this(uuid, true);
}

@Override
public boolean isExternal() {
return true;
}

@Override
public boolean isCached() {
return cached;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.enso.polyglot;

import java.util.UUID;

/**
* UUID that is only accessible. Nodes with internal UUID must not be cached.
*
* @param uuid unique identifier
*/
public record InternalUUID(UUID uuid) implements RuntimeID {

@Override
public boolean isExternal() {
return false;
}

@Override
public boolean isCached() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.enso.polyglot;

import java.util.UUID;

/** A wrapper around UUIDs differentiating between external and internal identifiers. */
public sealed interface RuntimeID permits InternalUUID, ExternalUUID {
/** The underlying UUID */
UUID uuid();

/** Indicates if UUID represents an externally-visible entity. */
boolean isExternal();

/** Indicates if the value of the given UUID will be cached internally. */
boolean isCached();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Predicate;
import org.enso.polyglot.RuntimeID;

public interface IdExecutionService {
String INSTRUMENT_ID = "id-value-extractor";

public abstract class Info {

/**
* @return UUID of the node, never {@code null}.
* @return UUID of the node, or {@code null} if no UUID has been assigned.
*/
public abstract UUID getId();
public abstract RuntimeID getId();

/**
* @return associated result or {@code null} if there is no associated result.
Expand Down Expand Up @@ -49,10 +50,12 @@ public interface Callbacks {
* execution of given node is skipped and the value is returned back.
*
* @param info info with UUID the node to be computed
* @param parentID ID of the parent of {@code info} for registering the relationship between the
* two nodes
* @return {@code null} should the execution of the node be performed; any other value to skip
* the execution and return the value as a result.
*/
Object findCachedResult(Info info);
Object findCachedResult(Info info, RuntimeID parentID);

/**
* Notifies when an execution of a node is over.
Expand Down Expand Up @@ -94,6 +97,32 @@ public interface Callbacks {
*/
void updateLocalExecutionEnvironment(
UUID uuid, Predicate<Object> shouldUpdate, Function<Object, Object> onSuccess);

/**
* Stores information about child-parent relationship between two instrumented nodes.
*
* @param child id of the child node
* @param parent id of the parent node
*/
void updateParent(RuntimeID child, RuntimeID parent);

/**
* Returns ID of the parent node of {@code nodeID} node. The call is not idempotent as once the
* information is retrieved, it is no longer available.
*
* @param nodeID uuid of the child node
* @return ID of the parent node, if available
*/
RuntimeID getAndRemoveParent(RuntimeID nodeID);

/**
* Indicates if full execution in the given context, while ignoring the cached values, is
* necessary. Full execution is necessary to recreate the context around specific UUIDs for
* expression evaluation.
*
* @return {@code true} if full execution, ignoring cached values, is necessary
*/
boolean needsFullExecution();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ private static boolean areResolvedNamesAllowedToClash(ResolvedName name1, Resolv
}
if (name1 instanceof BindingsMap.ResolvedModuleMethod &&
name2 instanceof BindingsMap.ResolvedModuleMethod) {
throw new AssertionError("Two module methods with the same name should not be allowed.");
throw new AssertionError("Two module methods with the same name (" + name1 + ") should not be allowed.");
}
if (name1 instanceof BindingsMap.ResolvedExtensionMethod && name2 instanceof BindingsMap.ResolvedModuleMethod) {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.enso.compiler.pass.analyse;

import java.util.UUID;
import java.util.stream.Stream;
import org.enso.compiler.context.LocalScope;
import org.enso.compiler.core.IR;
Expand Down Expand Up @@ -46,17 +47,22 @@ static void updateOccurrance(IR ir, Graph graph, Graph.Scope scope, GraphOccurre
var defLink = linkOpt.get();
var defId = defLink.target();
var defOcc = (GraphOccurrence.Def) graph.getOccurrence(defId).get();
UUID externalId = defOcc == null ? null : defOcc.externalId().getOrElse(() -> null);
UUID internalId = defOcc == null ? null : defOcc.identifier();
var defScope = graph.scopeFor(defId).get();
var parentLevel = getScopeDistance(defScope, scope);
var frameSlotIdx = getFrameSlotIdxInScope(graph, defScope, defOcc);
updateMetadata(ir, new FramePointer(parentLevel, frameSlotIdx));
updateMetadata(ir, new FramePointer(parentLevel, frameSlotIdx, externalId, internalId));
}
}
case GraphOccurrence.Def defn -> {
// The definition cannot write to parent's frame slots.
var parentLevel = 0;
var frameSlotIdx = getFrameSlotIdxInScope(graph, scope, defn);
FrameAnalysisMeta.updateMetadata(ir, new FramePointer(parentLevel, frameSlotIdx));
UUID externalId = defn.externalId().getOrElse(() -> null);
var internalId = defn.identifier();
FrameAnalysisMeta.updateMetadata(
ir, new FramePointer(parentLevel, frameSlotIdx, externalId, internalId));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.enso.compiler.pass.analyse;

import java.util.UUID;
import org.enso.compiler.core.CompilerStub;
import org.enso.compiler.core.ir.ProcessingPass;
import org.enso.persist.Persistable;
Expand All @@ -8,14 +9,23 @@
/**
* A representation of a pointer into a stack frame at a given number of levels above the current.
*/
@Persistable(clazz = FramePointer.class, id = 1283)
public record FramePointer(int parentLevel, int frameSlotIdx) implements FrameAnalysisMeta {
@Persistable(clazz = FramePointer.class, id = 1288)
public record FramePointer(int parentLevel, int frameSlotIdx, UUID externalId, UUID internalId)
implements FrameAnalysisMeta {

public FramePointer {
assert parentLevel >= 0;
assert frameSlotIdx >= 0;
}

public FramePointer(int parentLevel, int frameSlotIdx) {
this(parentLevel, frameSlotIdx, null, null);
}

public FramePointer(int parentLevel, int frameSlotIdx, UUID internalId) {
this(parentLevel, frameSlotIdx, null, internalId);
}

@Override
public String metadataName() {
return getClass().getSimpleName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,9 @@ class LocalScope(
scope.forEachOccurenceDefinition { x =>
parentResult += x.symbol -> new FramePointer(
level,
allFrameSlotIdxs(x.id)
allFrameSlotIdxs(x.id),
x.externalId().orNull,
x.identifier()
)
}
parentResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ case object FramePointerAnalysis extends IRPass {
case Name.Self(loc, synthetic, _) if loc == null && synthetic =>
// synthetic self argument has occurrence attached, but there is no Occurence.Def for it.
// So we have to handle it specially.
FrameAnalysisMeta.updateMetadata(arg, new FramePointer(0, 1))
FrameAnalysisMeta.updateMetadata(arg, new FramePointer(0, 1, null))
case _ =>
maybeAttachFramePointer(arg, graph)
}
Expand Down
Loading