From 482d93a87c7c0cfac7baefe1665fbd29d9cb5348 Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Mon, 23 Sep 2024 13:52:49 +0200 Subject: [PATCH 01/10] DataflowError.withDefaultTrace has BranchProfile as parameter --- .../builtin/error/ThrowErrorNode.java | 5 ++- .../builtin/number/decimal/FloatNode.java | 4 ++- .../builtin/number/integer/BitShiftNode.java | 32 ++++++++++++++----- .../builtin/number/integer/GreaterNode.java | 5 +-- .../number/integer/GreaterOrEqualNode.java | 5 +-- .../builtin/number/integer/LessNode.java | 5 +-- .../number/integer/LessOrEqualNode.java | 5 +-- .../builtin/number/integer/ModNode.java | 7 ++-- .../number/integer/ParseIntegerNode.java | 3 +- .../expression/constant/LazyObjectNode.java | 4 ++- .../runtime/data/hash/HashMapRemoveNode.java | 6 ++-- .../runtime/error/DataflowError.java | 13 ++++++-- 12 files changed, 68 insertions(+), 26 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java index 83591700b211..80984d6c7c05 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java @@ -2,6 +2,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.error.DataflowError; import org.enso.interpreter.runtime.state.State; @@ -12,7 +13,9 @@ description = "Returns a new value error with given payload.", inlineable = true) public class ThrowErrorNode extends Node { + private final BranchProfile attachFullStackTraceProfile = BranchProfile.create(); + public Object execute(VirtualFrame giveMeAStackFrame, State state, Object payload) { - return DataflowError.withDefaultTrace(state, payload, this); + return DataflowError.withDefaultTrace(state, payload, this, attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/decimal/FloatNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/decimal/FloatNode.java index 5d454e06eed5..b2ed57290c22 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/decimal/FloatNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/decimal/FloatNode.java @@ -4,6 +4,7 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.error.DataflowError; @@ -12,6 +13,7 @@ abstract class FloatNode extends Node { static final String INTEROP_LIMIT = "3"; + private final BranchProfile attachFullStackTraceProfile = BranchProfile.create(); final boolean isForeignNumber(InteropLibrary iop, TruffleObject obj) { if (obj instanceof EnsoBigInteger) { @@ -48,6 +50,6 @@ final PanicException panicOtherwise(double self, Object that) { final DataflowError incomparableError(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableErr, this); + return DataflowError.withDefaultTrace(incomparableErr, this, attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java index cb954b73455e..6250e4be0746 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java @@ -2,6 +2,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; +import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; @@ -9,6 +10,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.CountingConditionProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; @@ -40,14 +42,17 @@ long doLongShiftLeft(long self, long that) { } @Specialization(guards = "that >= 0", replaces = "doLongShiftLeft") - Object doLongShiftLeftExplicit(long self, long that) { + Object doLongShiftLeftExplicit( + long self, long that, @Shared @Cached BranchProfile attachFullStackTraceProfile) { if (canShiftLeftInLongProfile.profile(canShiftLeftInLong(self, that))) { return doLongShiftLeft(self, that); } else if (positiveFitsInInt.profile(BigIntegerOps.fitsInInt(that))) { return toEnsoNumberNode.execute(BigIntegerOps.bitShiftLeft(self, (int) that)); } else { return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), + this, + attachFullStackTraceProfile); } } @@ -70,13 +75,16 @@ long doLongShiftRightExplicit(long self, long that) { } @Specialization - Object doBigInteger(long self, EnsoBigInteger that) { + Object doBigInteger( + long self, EnsoBigInteger that, @Cached BranchProfile attachFullStackTraceProfile) { if (!BigIntegerOps.nonNegative(that.getValue())) { return self >= 0 ? 0L : -1L; } else { // Note [Well-Formed BigIntegers] return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), + this, + attachFullStackTraceProfile); } } @@ -89,12 +97,15 @@ EnsoBigInteger doBigIntShiftLeft(EnsoBigInteger self, long that) { Object doBigIntShiftLeftExplicit( EnsoBigInteger self, long that, - @Exclusive @Cached CountingConditionProfile fitsInIntProfileLeftShift) { + @Exclusive @Cached CountingConditionProfile fitsInIntProfileLeftShift, + @Cached BranchProfile attachFullStackTraceProfile) { if (fitsInIntProfileLeftShift.profile(BigIntegerOps.fitsInInt(that))) { return doBigIntShiftLeft(self, that); } else { return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), + this, + attachFullStackTraceProfile); } } @@ -116,12 +127,17 @@ Object doBigIntShiftRightExplicit( } @Specialization - Object doBigIntThat(EnsoBigInteger self, EnsoBigInteger that) { + Object doBigIntThat( + EnsoBigInteger self, + EnsoBigInteger that, + @Shared @Cached BranchProfile attachFullStackTraceProfile) { if (!BigIntegerOps.nonNegative(that.getValue())) { return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L; } else { return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), + this, + attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java index 1fbc3bfc5336..6a33b03ade49 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java @@ -6,6 +6,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; @@ -61,9 +62,9 @@ Object doInterop( } @Fallback - Object doOther(Object self, Object that) { + Object doOther(Object self, Object that, @Cached BranchProfile attachFullStackTraceProfile) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableValsErr, this); + return DataflowError.withDefaultTrace(incomparableValsErr, this, attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java index e4afeb78c0f4..8cfa09719c03 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java @@ -6,6 +6,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; @@ -61,9 +62,9 @@ Object doInterop( } @Fallback - Object doOther(Object self, Object that) { + Object doOther(Object self, Object that, @Cached BranchProfile attachFullStackTraceProfile) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableValsErr, this); + return DataflowError.withDefaultTrace(incomparableValsErr, this, attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java index e4698d6645e4..cee544861f59 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java @@ -6,6 +6,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; @@ -61,9 +62,9 @@ Object doInterop( } @Fallback - Object doOther(Object self, Object that) { + Object doOther(Object self, Object that, @Cached BranchProfile attachFullStackTraceProfile) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableValsErr, this); + return DataflowError.withDefaultTrace(incomparableValsErr, this, attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java index 0c25add201ea..df5adef42579 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java @@ -6,6 +6,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; @@ -62,9 +63,9 @@ Object doInterop( } @Fallback - Object doOther(Object self, Object that) { + Object doOther(Object self, Object that, @Cached BranchProfile attachFullStackTraceProfile) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableValsErr, this); + return DataflowError.withDefaultTrace(incomparableValsErr, this, attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java index 0439dee64b69..9b6cc87dd21f 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java @@ -7,6 +7,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.profiles.BranchProfile; import java.math.BigInteger; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; @@ -53,12 +54,14 @@ Object doBigInteger(long self, EnsoBigInteger that) { } @Specialization - Object doLong(EnsoBigInteger self, long that) { + Object doLong(EnsoBigInteger self, long that, @Cached BranchProfile attachFullStackTraceProfile) { try { return toEnsoNumberNode.execute(BigIntegerOps.modulo(self.getValue(), that)); } catch (ArithmeticException e) { return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this); + EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), + this, + attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ParseIntegerNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ParseIntegerNode.java index 8e7d70c63fd5..dc497b0498b5 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ParseIntegerNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ParseIntegerNode.java @@ -20,6 +20,7 @@ public final class ParseIntegerNode extends IntegerNode { @Child ToJavaStringNode toJavaString = ToJavaStringNode.build(); private final BranchProfile noEx1 = BranchProfile.create(); private final BranchProfile noEx2 = BranchProfile.create(); + private final BranchProfile attachFullStackTraceProfile = BranchProfile.create(); Object execute(Text value, long radix) { var r = Math.toIntExact(radix); @@ -36,7 +37,7 @@ Object execute(Text value, long radix) { noEx2.enter(); var errors = EnsoContext.get(this).getBuiltins().error(); var err = errors.makeNumberParseError(ex.getMessage()); - return DataflowError.withDefaultTrace(err, this); + return DataflowError.withDefaultTrace(err, this, attachFullStackTraceProfile); } } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/constant/LazyObjectNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/constant/LazyObjectNode.java index 0c7dda52705d..6321b174510d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/constant/LazyObjectNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/constant/LazyObjectNode.java @@ -3,6 +3,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.api.profiles.BranchProfile; import java.util.function.Supplier; import org.enso.interpreter.node.ExpressionNode; import org.enso.interpreter.runtime.data.text.Text; @@ -16,6 +17,7 @@ public final class LazyObjectNode extends ExpressionNode { private final String error; private final CachingSupplier supply; + private final BranchProfile attachFullStackTraceProfile = BranchProfile.create(); private LazyObjectNode(String error, Supplier supply) { this.error = error; @@ -39,6 +41,6 @@ public Object executeGeneric(VirtualFrame frame) { if (result instanceof TruffleObject) { return result; } - return DataflowError.withDefaultTrace(Text.create(error), this); + return DataflowError.withDefaultTrace(Text.create(error), this, attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapRemoveNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapRemoveNode.java index 3f1673e27b8d..d5b6d211e4b7 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapRemoveNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapRemoveNode.java @@ -13,6 +13,7 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.meta.EqualsNode; import org.enso.interpreter.node.expression.builtin.meta.HashCodeNode; @@ -39,12 +40,13 @@ EnsoHashMap removeFromEnsoMap( EnsoHashMap ensoMap, Object key, @Shared("hash") @Cached HashCodeNode hashCodeNode, - @Shared("equals") @Cached EqualsNode equalsNode) { + @Shared("equals") @Cached EqualsNode equalsNode, + @Cached BranchProfile attachFullStackTraceProfile) { var mapBuilder = ensoMap.getMapBuilder(frame, false, hashCodeNode, equalsNode); if (mapBuilder.remove(frame, key, hashCodeNode, equalsNode)) { return mapBuilder.build(); } else { - throw DataflowError.withDefaultTrace("No such key", null); + throw DataflowError.withDefaultTrace("No such key", null, attachFullStackTraceProfile); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java index 1d65eac65161..676726f55f1b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java @@ -15,6 +15,7 @@ import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; import java.util.Objects; import org.enso.interpreter.node.callable.IndirectInvokeMethodNode; import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode; @@ -49,9 +50,11 @@ public final class DataflowError extends AbstractTruffleException implements Ens * * @param payload the user-provided value carried by the error * @param location the node in which the error was created + * @param attachFullStackTraceProfile * @return a new dataflow error */ - public static DataflowError withDefaultTrace(State state, Object payload, Node location) { + public static DataflowError withDefaultTrace( + State state, Object payload, Node location, BranchProfile attachFullStackTraceProfile) { assert payload != null; boolean attachFullStackTrace = state == null @@ -59,6 +62,7 @@ public static DataflowError withDefaultTrace(State state, Object payload, Node l .getExecutionEnvironment() .hasContextEnabled("Dataflow_Stack_Trace"); if (attachFullStackTrace) { + attachFullStackTraceProfile.enter(); var result = new DataflowError(payload, UNLIMITED_STACK_TRACE, location); TruffleStackTrace.fillIn(result); return result; @@ -68,8 +72,13 @@ public static DataflowError withDefaultTrace(State state, Object payload, Node l } } + public static DataflowError withDefaultTrace( + Object payload, Node location, BranchProfile attachFullStackTraceProfile) { + return withDefaultTrace(null, payload, location, attachFullStackTraceProfile); + } + public static DataflowError withDefaultTrace(Object payload, Node location) { - return withDefaultTrace(null, payload, location); + return withDefaultTrace(null, payload, location, BranchProfile.getUncached()); } /** From b63021a1ef6c8010c9c5619f56aba7a213c81de0 Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Mon, 14 Oct 2024 15:56:00 +0200 Subject: [PATCH 02/10] Revert "DataflowError.withDefaultTrace has BranchProfile as parameter" This reverts commit baeddd03e4d24d78ab2a8cdb5b0fa95b5517f116. --- .../builtin/error/ThrowErrorNode.java | 5 +-- .../builtin/number/decimal/FloatNode.java | 4 +-- .../builtin/number/integer/BitShiftNode.java | 32 +++++-------------- .../builtin/number/integer/GreaterNode.java | 5 ++- .../number/integer/GreaterOrEqualNode.java | 5 ++- .../builtin/number/integer/LessNode.java | 5 ++- .../number/integer/LessOrEqualNode.java | 5 ++- .../builtin/number/integer/ModNode.java | 7 ++-- .../number/integer/ParseIntegerNode.java | 3 +- .../expression/constant/LazyObjectNode.java | 4 +-- .../runtime/data/hash/HashMapRemoveNode.java | 6 ++-- .../runtime/error/DataflowError.java | 13 ++------ 12 files changed, 26 insertions(+), 68 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java index 80984d6c7c05..83591700b211 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.error.DataflowError; import org.enso.interpreter.runtime.state.State; @@ -13,9 +12,7 @@ description = "Returns a new value error with given payload.", inlineable = true) public class ThrowErrorNode extends Node { - private final BranchProfile attachFullStackTraceProfile = BranchProfile.create(); - public Object execute(VirtualFrame giveMeAStackFrame, State state, Object payload) { - return DataflowError.withDefaultTrace(state, payload, this, attachFullStackTraceProfile); + return DataflowError.withDefaultTrace(state, payload, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/decimal/FloatNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/decimal/FloatNode.java index b2ed57290c22..5d454e06eed5 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/decimal/FloatNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/decimal/FloatNode.java @@ -4,7 +4,6 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.error.DataflowError; @@ -13,7 +12,6 @@ abstract class FloatNode extends Node { static final String INTEROP_LIMIT = "3"; - private final BranchProfile attachFullStackTraceProfile = BranchProfile.create(); final boolean isForeignNumber(InteropLibrary iop, TruffleObject obj) { if (obj instanceof EnsoBigInteger) { @@ -50,6 +48,6 @@ final PanicException panicOtherwise(double self, Object that) { final DataflowError incomparableError(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableErr, this, attachFullStackTraceProfile); + return DataflowError.withDefaultTrace(incomparableErr, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java index 6250e4be0746..cb954b73455e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; @@ -10,7 +9,6 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.CountingConditionProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; @@ -42,17 +40,14 @@ long doLongShiftLeft(long self, long that) { } @Specialization(guards = "that >= 0", replaces = "doLongShiftLeft") - Object doLongShiftLeftExplicit( - long self, long that, @Shared @Cached BranchProfile attachFullStackTraceProfile) { + Object doLongShiftLeftExplicit(long self, long that) { if (canShiftLeftInLongProfile.profile(canShiftLeftInLong(self, that))) { return doLongShiftLeft(self, that); } else if (positiveFitsInInt.profile(BigIntegerOps.fitsInInt(that))) { return toEnsoNumberNode.execute(BigIntegerOps.bitShiftLeft(self, (int) that)); } else { return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), - this, - attachFullStackTraceProfile); + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); } } @@ -75,16 +70,13 @@ long doLongShiftRightExplicit(long self, long that) { } @Specialization - Object doBigInteger( - long self, EnsoBigInteger that, @Cached BranchProfile attachFullStackTraceProfile) { + Object doBigInteger(long self, EnsoBigInteger that) { if (!BigIntegerOps.nonNegative(that.getValue())) { return self >= 0 ? 0L : -1L; } else { // Note [Well-Formed BigIntegers] return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), - this, - attachFullStackTraceProfile); + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); } } @@ -97,15 +89,12 @@ EnsoBigInteger doBigIntShiftLeft(EnsoBigInteger self, long that) { Object doBigIntShiftLeftExplicit( EnsoBigInteger self, long that, - @Exclusive @Cached CountingConditionProfile fitsInIntProfileLeftShift, - @Cached BranchProfile attachFullStackTraceProfile) { + @Exclusive @Cached CountingConditionProfile fitsInIntProfileLeftShift) { if (fitsInIntProfileLeftShift.profile(BigIntegerOps.fitsInInt(that))) { return doBigIntShiftLeft(self, that); } else { return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), - this, - attachFullStackTraceProfile); + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); } } @@ -127,17 +116,12 @@ Object doBigIntShiftRightExplicit( } @Specialization - Object doBigIntThat( - EnsoBigInteger self, - EnsoBigInteger that, - @Shared @Cached BranchProfile attachFullStackTraceProfile) { + Object doBigIntThat(EnsoBigInteger self, EnsoBigInteger that) { if (!BigIntegerOps.nonNegative(that.getValue())) { return BigIntegerOps.nonNegative(self.getValue()) ? 0L : -1L; } else { return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), - this, - attachFullStackTraceProfile); + EnsoContext.get(this).getBuiltins().error().getShiftAmountTooLargeError(), this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java index 6a33b03ade49..1fbc3bfc5336 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java @@ -6,7 +6,6 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; @@ -62,9 +61,9 @@ Object doInterop( } @Fallback - Object doOther(Object self, Object that, @Cached BranchProfile attachFullStackTraceProfile) { + Object doOther(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableValsErr, this, attachFullStackTraceProfile); + return DataflowError.withDefaultTrace(incomparableValsErr, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java index 8cfa09719c03..e4afeb78c0f4 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java @@ -6,7 +6,6 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; @@ -62,9 +61,9 @@ Object doInterop( } @Fallback - Object doOther(Object self, Object that, @Cached BranchProfile attachFullStackTraceProfile) { + Object doOther(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableValsErr, this, attachFullStackTraceProfile); + return DataflowError.withDefaultTrace(incomparableValsErr, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java index cee544861f59..e4698d6645e4 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java @@ -6,7 +6,6 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; @@ -62,9 +61,9 @@ Object doInterop( } @Fallback - Object doOther(Object self, Object that, @Cached BranchProfile attachFullStackTraceProfile) { + Object doOther(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableValsErr, this, attachFullStackTraceProfile); + return DataflowError.withDefaultTrace(incomparableValsErr, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java index df5adef42579..0c25add201ea 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java @@ -6,7 +6,6 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; @@ -63,9 +62,9 @@ Object doInterop( } @Fallback - Object doOther(Object self, Object that, @Cached BranchProfile attachFullStackTraceProfile) { + Object doOther(Object self, Object that) { var builtins = EnsoContext.get(this).getBuiltins(); var incomparableValsErr = builtins.error().makeIncomparableValues(self, that); - return DataflowError.withDefaultTrace(incomparableValsErr, this, attachFullStackTraceProfile); + return DataflowError.withDefaultTrace(incomparableValsErr, this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java index 9b6cc87dd21f..0439dee64b69 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ModNode.java @@ -7,7 +7,6 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.profiles.BranchProfile; import java.math.BigInteger; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; @@ -54,14 +53,12 @@ Object doBigInteger(long self, EnsoBigInteger that) { } @Specialization - Object doLong(EnsoBigInteger self, long that, @Cached BranchProfile attachFullStackTraceProfile) { + Object doLong(EnsoBigInteger self, long that) { try { return toEnsoNumberNode.execute(BigIntegerOps.modulo(self.getValue(), that)); } catch (ArithmeticException e) { return DataflowError.withDefaultTrace( - EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), - this, - attachFullStackTraceProfile); + EnsoContext.get(this).getBuiltins().error().getDivideByZeroError(), this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ParseIntegerNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ParseIntegerNode.java index dc497b0498b5..8e7d70c63fd5 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ParseIntegerNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ParseIntegerNode.java @@ -20,7 +20,6 @@ public final class ParseIntegerNode extends IntegerNode { @Child ToJavaStringNode toJavaString = ToJavaStringNode.build(); private final BranchProfile noEx1 = BranchProfile.create(); private final BranchProfile noEx2 = BranchProfile.create(); - private final BranchProfile attachFullStackTraceProfile = BranchProfile.create(); Object execute(Text value, long radix) { var r = Math.toIntExact(radix); @@ -37,7 +36,7 @@ Object execute(Text value, long radix) { noEx2.enter(); var errors = EnsoContext.get(this).getBuiltins().error(); var err = errors.makeNumberParseError(ex.getMessage()); - return DataflowError.withDefaultTrace(err, this, attachFullStackTraceProfile); + return DataflowError.withDefaultTrace(err, this); } } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/constant/LazyObjectNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/constant/LazyObjectNode.java index 6321b174510d..0c7dda52705d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/constant/LazyObjectNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/constant/LazyObjectNode.java @@ -3,7 +3,6 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.NodeInfo; -import com.oracle.truffle.api.profiles.BranchProfile; import java.util.function.Supplier; import org.enso.interpreter.node.ExpressionNode; import org.enso.interpreter.runtime.data.text.Text; @@ -17,7 +16,6 @@ public final class LazyObjectNode extends ExpressionNode { private final String error; private final CachingSupplier supply; - private final BranchProfile attachFullStackTraceProfile = BranchProfile.create(); private LazyObjectNode(String error, Supplier supply) { this.error = error; @@ -41,6 +39,6 @@ public Object executeGeneric(VirtualFrame frame) { if (result instanceof TruffleObject) { return result; } - return DataflowError.withDefaultTrace(Text.create(error), this, attachFullStackTraceProfile); + return DataflowError.withDefaultTrace(Text.create(error), this); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapRemoveNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapRemoveNode.java index d5b6d211e4b7..3f1673e27b8d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapRemoveNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/hash/HashMapRemoveNode.java @@ -13,7 +13,6 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.BranchProfile; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.meta.EqualsNode; import org.enso.interpreter.node.expression.builtin.meta.HashCodeNode; @@ -40,13 +39,12 @@ EnsoHashMap removeFromEnsoMap( EnsoHashMap ensoMap, Object key, @Shared("hash") @Cached HashCodeNode hashCodeNode, - @Shared("equals") @Cached EqualsNode equalsNode, - @Cached BranchProfile attachFullStackTraceProfile) { + @Shared("equals") @Cached EqualsNode equalsNode) { var mapBuilder = ensoMap.getMapBuilder(frame, false, hashCodeNode, equalsNode); if (mapBuilder.remove(frame, key, hashCodeNode, equalsNode)) { return mapBuilder.build(); } else { - throw DataflowError.withDefaultTrace("No such key", null, attachFullStackTraceProfile); + throw DataflowError.withDefaultTrace("No such key", null); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java index 676726f55f1b..1d65eac65161 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java @@ -15,7 +15,6 @@ import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.BranchProfile; import java.util.Objects; import org.enso.interpreter.node.callable.IndirectInvokeMethodNode; import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode; @@ -50,11 +49,9 @@ public final class DataflowError extends AbstractTruffleException implements Ens * * @param payload the user-provided value carried by the error * @param location the node in which the error was created - * @param attachFullStackTraceProfile * @return a new dataflow error */ - public static DataflowError withDefaultTrace( - State state, Object payload, Node location, BranchProfile attachFullStackTraceProfile) { + public static DataflowError withDefaultTrace(State state, Object payload, Node location) { assert payload != null; boolean attachFullStackTrace = state == null @@ -62,7 +59,6 @@ public static DataflowError withDefaultTrace( .getExecutionEnvironment() .hasContextEnabled("Dataflow_Stack_Trace"); if (attachFullStackTrace) { - attachFullStackTraceProfile.enter(); var result = new DataflowError(payload, UNLIMITED_STACK_TRACE, location); TruffleStackTrace.fillIn(result); return result; @@ -72,13 +68,8 @@ public static DataflowError withDefaultTrace( } } - public static DataflowError withDefaultTrace( - Object payload, Node location, BranchProfile attachFullStackTraceProfile) { - return withDefaultTrace(null, payload, location, attachFullStackTraceProfile); - } - public static DataflowError withDefaultTrace(Object payload, Node location) { - return withDefaultTrace(null, payload, location, BranchProfile.getUncached()); + return withDefaultTrace(null, payload, location); } /** From 1e58228e898014bd38e5e6ad59aadab56dcad4b4 Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Tue, 15 Oct 2024 12:49:28 +0200 Subject: [PATCH 03/10] Do not use hardcoded string --- .../java/org/enso/interpreter/runtime/error/DataflowError.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java index 1d65eac65161..cc9122c4aedd 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java @@ -17,6 +17,7 @@ import com.oracle.truffle.api.nodes.Node; import java.util.Objects; import org.enso.interpreter.node.callable.IndirectInvokeMethodNode; +import org.enso.interpreter.node.expression.builtin.runtime.Context; import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.callable.UnresolvedSymbol; @@ -57,7 +58,7 @@ public static DataflowError withDefaultTrace(State state, Object payload, Node l state == null || EnsoContext.get(location) .getExecutionEnvironment() - .hasContextEnabled("Dataflow_Stack_Trace"); + .hasContextEnabled(Context.DATAFLOW_STACK_TRACE_NAME); if (attachFullStackTrace) { var result = new DataflowError(payload, UNLIMITED_STACK_TRACE, location); TruffleStackTrace.fillIn(result); From 243847c3ab36605142c03d3ce37b6113165c9314 Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Wed, 16 Oct 2024 13:27:43 +0200 Subject: [PATCH 04/10] Permissions in ExecutionEnvironment is a final record --- .../builtin/runtime/ContextIsEnabledNode.java | 2 +- .../runtime/error/DataflowError.java | 11 ++- .../runtime/state/ExecutionEnvironment.java | 93 ++++++++----------- 3 files changed, 49 insertions(+), 57 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java index b2e74dbf2d72..fb990c842fdb 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java @@ -26,6 +26,6 @@ Object execute(Atom self, Object environmentName) { .makeUnimplemented("execution environment mismatch"); throw new PanicException(error, this); } - return currentEnv.hasContextEnabled(self.getConstructor().getName()); + return currentEnv.hasContextEnabled(self.getConstructor(), EnsoContext.get(this)); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java index cc9122c4aedd..bd0b14832a0a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java @@ -2,6 +2,7 @@ import static org.enso.interpreter.runtime.error.PanicException.handleExceptionMessage; +import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.TruffleStackTrace; import com.oracle.truffle.api.TruffleStackTraceElement; @@ -17,7 +18,6 @@ import com.oracle.truffle.api.nodes.Node; import java.util.Objects; import org.enso.interpreter.node.callable.IndirectInvokeMethodNode; -import org.enso.interpreter.node.expression.builtin.runtime.Context; import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.callable.UnresolvedSymbol; @@ -54,11 +54,14 @@ public final class DataflowError extends AbstractTruffleException implements Ens */ public static DataflowError withDefaultTrace(State state, Object payload, Node location) { assert payload != null; + var ensoCtx = EnsoContext.get(location); + var dataflowStacktraceCtx = ensoCtx.getBuiltins().context().getDataflowStackTrace(); + // dataflowStacktraceCtx is a compiler constant, because it is a constructor of a builtin + // type. + CompilerAsserts.partialEvaluationConstant(dataflowStacktraceCtx); boolean attachFullStackTrace = state == null - || EnsoContext.get(location) - .getExecutionEnvironment() - .hasContextEnabled(Context.DATAFLOW_STACK_TRACE_NAME); + || ensoCtx.getExecutionEnvironment().hasContextEnabled(dataflowStacktraceCtx, ensoCtx); if (attachFullStackTrace) { var result = new DataflowError(payload, UNLIMITED_STACK_TRACE, location); TruffleStackTrace.fillIn(result); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java index c66715c636fa..a18d5fbb334d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java @@ -1,18 +1,15 @@ package org.enso.interpreter.runtime.state; -import org.enso.interpreter.node.expression.builtin.runtime.Context; +import com.oracle.truffle.api.CompilerDirectives; import org.enso.interpreter.runtime.EnsoContext; import org.enso.interpreter.runtime.data.atom.Atom; +import org.enso.interpreter.runtime.data.atom.AtomConstructor; public class ExecutionEnvironment { private final String name; - // Ideally we would "just" use a map here. But that leads - // to native image build problems. This in turn leads to - // TruffleBoundary annotations which in turn leads to slow path. - private final String[] keys; - private final Boolean[] permissions; + private final Permissions permissions; public static final String LIVE_ENVIRONMENT_NAME = "live"; @@ -22,21 +19,18 @@ public class ExecutionEnvironment { public static final ExecutionEnvironment DESIGN = new ExecutionEnvironment(DESIGN_ENVIRONMENT_NAME); - private static final ExecutionEnvironment initLive(String name) { - String[] keys = new String[] {Context.INPUT_NAME, Context.OUTPUT_NAME}; - Boolean[] permissions = new Boolean[] {true, true}; - return new ExecutionEnvironment(name, keys, permissions); + private static ExecutionEnvironment initLive(String name) { + var permissions = new Permissions(true, true, false); + return new ExecutionEnvironment(name, permissions); } public ExecutionEnvironment(String name) { this.name = name; - this.keys = new String[0]; - this.permissions = new Boolean[0]; + this.permissions = new Permissions(false, false, false); } - private ExecutionEnvironment(String name, String[] keys, Boolean[] permissions) { + private ExecutionEnvironment(String name, Permissions permissions) { this.name = name; - this.keys = keys; this.permissions = permissions; } @@ -53,49 +47,39 @@ public ExecutionEnvironment withContextDisabled(Atom context) { } private ExecutionEnvironment update(Atom context, boolean value) { - assert context.getConstructor().getType() - == EnsoContext.get(null).getBuiltins().context().getType(); - int keyFound = -1; - for (int i = 0; i < keys.length; i++) { - if (keys[i].equals(context.getConstructor().getName())) { - keyFound = i; - } - } - String[] keys1; - Boolean[] permissions1; - if (keyFound != -1) { - keys1 = cloneArray(keys, new String[keys.length]); - permissions1 = cloneArray(permissions, new Boolean[keys.length]); - permissions1[keyFound] = value; + var contextBuiltin = EnsoContext.get(null).getBuiltins().context(); + assert context.getConstructor().getType() == contextBuiltin.getType(); + var ctor = context.getConstructor(); + Permissions newPermissions; + if (ctor == contextBuiltin.getInput()) { + newPermissions = new Permissions(value, permissions.output, permissions.dataflowStacktrace); + } else if (ctor == contextBuiltin.getOutput()) { + newPermissions = new Permissions(permissions.input, value, permissions.dataflowStacktrace); + } else if (ctor == contextBuiltin.getDataflowStackTrace()) { + newPermissions = new Permissions(permissions.input, permissions.output, value); } else { - keys1 = cloneArray(keys, new String[keys.length + 1]); - permissions1 = cloneArray(permissions, new Boolean[keys.length + 1]); - keyFound = keys.length; - keys1[keyFound] = context.getConstructor().getName(); - permissions1[keyFound] = value; + throw CompilerDirectives.shouldNotReachHere("Unknown context `" + ctor.getName() + "`"); } - return new ExecutionEnvironment(name, keys1, permissions1); + return new ExecutionEnvironment(name, newPermissions); } - private T[] cloneArray(T[] fromArray, T[] toArray) { - for (int i = 0; i < fromArray.length; i++) { - toArray[i] = fromArray[i]; - } - return toArray; - } - - public Boolean hasContextEnabled(String context) { - int keyFound = -1; - for (int i = 0; i < keys.length; i++) { - if (keys[i].equals(context)) { - keyFound = i; - } - } - if (keyFound != -1) { - return permissions[keyFound]; - } else { - return false; + /** + * Checks if the context is enabled in this execution environment. + * + * @param runtimeCtx Constructor of {@code Standard.Base.Runtime.Context} builtin type. + * @return {@code true} if the context is enabled in this execution environment. + */ + public boolean hasContextEnabled(AtomConstructor runtimeCtx, EnsoContext ensoCtx) { + var contextBuiltin = ensoCtx.getBuiltins().context(); + if (runtimeCtx == contextBuiltin.getInput()) { + return permissions.input; + } else if (runtimeCtx == contextBuiltin.getOutput()) { + return permissions.output; + } else if (runtimeCtx == contextBuiltin.getDataflowStackTrace()) { + return permissions.dataflowStacktrace; } + throw CompilerDirectives.shouldNotReachHere( + "Unknown runtimeCtx `" + runtimeCtx.getName() + "`"); } public static ExecutionEnvironment forName(String name) { @@ -108,4 +92,9 @@ public static ExecutionEnvironment forName(String name) { throw new IllegalArgumentException("Unsupported Execution Environment `" + name + "`"); } } + + /** + * Fields correspond to the constructors of {@code Standard.Base.Runtime.Context} builtin type. + */ + private record Permissions(boolean input, boolean output, boolean dataflowStacktrace) {} } From dd25a6f256918a675898e23ca95172ab3d5d463a Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Thu, 17 Oct 2024 14:15:26 +0200 Subject: [PATCH 05/10] hasContextEnabled and update exec env are nodes --- .../builtin/error/ThrowErrorNode.java | 5 +- .../builtin/runtime/ContextIsEnabledNode.java | 4 +- .../enso/interpreter/runtime/EnsoContext.java | 9 ++- .../runtime/error/DataflowError.java | 13 ++-- .../runtime/state/ContextPermissions.java | 4 ++ .../runtime/state/ExecutionEnvironment.java | 67 ++++++------------- .../runtime/state/HasContextEnabledNode.java | 46 +++++++++++++ .../runtime/state/WithContextNode.java | 44 ++++++++++++ 8 files changed, 138 insertions(+), 54 deletions(-) create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ContextPermissions.java create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java create mode 100644 engine/runtime/src/main/java/org/enso/interpreter/runtime/state/WithContextNode.java diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java index 83591700b211..2bcd75787b8a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/error/ThrowErrorNode.java @@ -4,6 +4,7 @@ import com.oracle.truffle.api.nodes.Node; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.error.DataflowError; +import org.enso.interpreter.runtime.state.HasContextEnabledNode; import org.enso.interpreter.runtime.state.State; @BuiltinMethod( @@ -12,7 +13,9 @@ description = "Returns a new value error with given payload.", inlineable = true) public class ThrowErrorNode extends Node { + private @Child HasContextEnabledNode hasContextEnabledNode = HasContextEnabledNode.create(); + public Object execute(VirtualFrame giveMeAStackFrame, State state, Object payload) { - return DataflowError.withDefaultTrace(state, payload, this); + return DataflowError.withDefaultTrace(state, payload, this, hasContextEnabledNode); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java index fb990c842fdb..330cb3c9c6e0 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/runtime/ContextIsEnabledNode.java @@ -7,6 +7,7 @@ import org.enso.interpreter.runtime.data.atom.Atom; import org.enso.interpreter.runtime.error.PanicException; import org.enso.interpreter.runtime.state.ExecutionEnvironment; +import org.enso.interpreter.runtime.state.HasContextEnabledNode; @BuiltinMethod( type = "Context", @@ -14,6 +15,7 @@ description = "Check if the context is enabled in the provided execution environment.") public class ContextIsEnabledNode extends Node { private @Child ExpectStringNode expectStringNode = ExpectStringNode.build(); + private @Child HasContextEnabledNode hasContextEnabledNode = HasContextEnabledNode.create(); Object execute(Atom self, Object environmentName) { String envName = expectStringNode.execute(environmentName); @@ -26,6 +28,6 @@ Object execute(Atom self, Object environmentName) { .makeUnimplemented("execution environment mismatch"); throw new PanicException(error, this); } - return currentEnv.hasContextEnabled(self.getConstructor(), EnsoContext.get(this)); + return hasContextEnabledNode.executeHasContextEnabled(currentEnv, self.getConstructor()); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java index 1f44b23295d7..531a116cc317 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java @@ -59,6 +59,7 @@ import org.enso.interpreter.runtime.scope.TopLevelScope; import org.enso.interpreter.runtime.state.ExecutionEnvironment; import org.enso.interpreter.runtime.state.State; +import org.enso.interpreter.runtime.state.WithContextNode; import org.enso.interpreter.runtime.util.TruffleFileSystem; import org.enso.librarymanager.ProjectLoadingFailure; import org.enso.librarymanager.resolved.LibraryRoot; @@ -894,7 +895,9 @@ public void setExecutionEnvironment(ExecutionEnvironment executionEnvironment) { public ExecutionEnvironment enableExecutionEnvironment(Atom context, String environmentName) { ExecutionEnvironment original = globalExecutionEnvironment; if (original.getName().equals(environmentName)) { - setExecutionEnvironment(original.withContextEnabled(context)); + var newExecEnv = + WithContextNode.getUncached().executeEnvironmentUpdate(original, context, true); + setExecutionEnvironment(newExecEnv); } return original; } @@ -909,7 +912,9 @@ public ExecutionEnvironment enableExecutionEnvironment(Atom context, String envi public ExecutionEnvironment disableExecutionEnvironment(Atom context, String environmentName) { ExecutionEnvironment original = globalExecutionEnvironment; if (original.getName().equals(environmentName)) { - setExecutionEnvironment(original.withContextDisabled(context)); + var newExecEnv = + WithContextNode.getUncached().executeEnvironmentUpdate(original, context, false); + setExecutionEnvironment(newExecEnv); } return original; } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java index bd0b14832a0a..ea7db94f7cb2 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java @@ -25,6 +25,7 @@ import org.enso.interpreter.runtime.data.Type; import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers; import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; +import org.enso.interpreter.runtime.state.HasContextEnabledNode; import org.enso.interpreter.runtime.state.State; /** @@ -52,7 +53,8 @@ public final class DataflowError extends AbstractTruffleException implements Ens * @param location the node in which the error was created * @return a new dataflow error */ - public static DataflowError withDefaultTrace(State state, Object payload, Node location) { + public static DataflowError withDefaultTrace( + State state, Object payload, Node location, HasContextEnabledNode hasContextEnabledNode) { assert payload != null; var ensoCtx = EnsoContext.get(location); var dataflowStacktraceCtx = ensoCtx.getBuiltins().context().getDataflowStackTrace(); @@ -61,9 +63,11 @@ public static DataflowError withDefaultTrace(State state, Object payload, Node l CompilerAsserts.partialEvaluationConstant(dataflowStacktraceCtx); boolean attachFullStackTrace = state == null - || ensoCtx.getExecutionEnvironment().hasContextEnabled(dataflowStacktraceCtx, ensoCtx); + || hasContextEnabledNode.executeHasContextEnabled( + ensoCtx.getExecutionEnvironment(), dataflowStacktraceCtx); if (attachFullStackTrace) { - var result = new DataflowError(payload, UNLIMITED_STACK_TRACE, location); + var result = + new DataflowError(payload, AbstractTruffleException.UNLIMITED_STACK_TRACE, location); TruffleStackTrace.fillIn(result); return result; } else { @@ -72,8 +76,9 @@ public static DataflowError withDefaultTrace(State state, Object payload, Node l } } + /** Slow version of {@link #withDefaultTrace(State, Object, Node, HasContextEnabledNode)}. */ public static DataflowError withDefaultTrace(Object payload, Node location) { - return withDefaultTrace(null, payload, location); + return withDefaultTrace(null, payload, location, HasContextEnabledNode.getUncached()); } /** diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ContextPermissions.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ContextPermissions.java new file mode 100644 index 000000000000..452539b28389 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ContextPermissions.java @@ -0,0 +1,4 @@ +package org.enso.interpreter.runtime.state; + +/** Fields correspond to the constructors of {@code Standard.Base.Runtime.Context} builtin type. */ +record ContextPermissions(boolean input, boolean output, boolean dataflowStacktrace) {} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java index a18d5fbb334d..49cd7c992b69 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java @@ -1,15 +1,14 @@ package org.enso.interpreter.runtime.state; import com.oracle.truffle.api.CompilerDirectives; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.data.atom.Atom; +import org.enso.interpreter.node.expression.builtin.runtime.Context; import org.enso.interpreter.runtime.data.atom.AtomConstructor; public class ExecutionEnvironment { private final String name; - private final Permissions permissions; + final ContextPermissions permissions; public static final String LIVE_ENVIRONMENT_NAME = "live"; @@ -20,16 +19,16 @@ public class ExecutionEnvironment { new ExecutionEnvironment(DESIGN_ENVIRONMENT_NAME); private static ExecutionEnvironment initLive(String name) { - var permissions = new Permissions(true, true, false); + var permissions = new ContextPermissions(true, true, false); return new ExecutionEnvironment(name, permissions); } public ExecutionEnvironment(String name) { this.name = name; - this.permissions = new Permissions(false, false, false); + this.permissions = new ContextPermissions(false, false, false); } - private ExecutionEnvironment(String name, Permissions permissions) { + ExecutionEnvironment(String name, ContextPermissions permissions) { this.name = name; this.permissions = permissions; } @@ -38,50 +37,31 @@ public String getName() { return this.name; } - public ExecutionEnvironment withContextEnabled(Atom context) { - return update(context, true); - } - - public ExecutionEnvironment withContextDisabled(Atom context) { - return update(context, false); - } - - private ExecutionEnvironment update(Atom context, boolean value) { - var contextBuiltin = EnsoContext.get(null).getBuiltins().context(); - assert context.getConstructor().getType() == contextBuiltin.getType(); - var ctor = context.getConstructor(); - Permissions newPermissions; + /** + * Returns copy of this {@link ExecutionEnvironment} with new permissions for the given context. + * + * @param ctor Constructor of {@code Standard.Base.Runtime.Context} type. + * @param contextBuiltin The builtin type of {@code Standard.Base.Runtime.Context}. + * @param value The new value for the permissions. + * @return A copy of the execution environment with the new permissions. + */ + ExecutionEnvironment update(AtomConstructor ctor, Context contextBuiltin, boolean value) { + assert ctor.getType() == contextBuiltin.getType(); + ContextPermissions newPermissions; if (ctor == contextBuiltin.getInput()) { - newPermissions = new Permissions(value, permissions.output, permissions.dataflowStacktrace); + newPermissions = + new ContextPermissions(value, permissions.output(), permissions.dataflowStacktrace()); } else if (ctor == contextBuiltin.getOutput()) { - newPermissions = new Permissions(permissions.input, value, permissions.dataflowStacktrace); + newPermissions = + new ContextPermissions(permissions.input(), value, permissions.dataflowStacktrace()); } else if (ctor == contextBuiltin.getDataflowStackTrace()) { - newPermissions = new Permissions(permissions.input, permissions.output, value); + newPermissions = new ContextPermissions(permissions.input(), permissions.output(), value); } else { throw CompilerDirectives.shouldNotReachHere("Unknown context `" + ctor.getName() + "`"); } return new ExecutionEnvironment(name, newPermissions); } - /** - * Checks if the context is enabled in this execution environment. - * - * @param runtimeCtx Constructor of {@code Standard.Base.Runtime.Context} builtin type. - * @return {@code true} if the context is enabled in this execution environment. - */ - public boolean hasContextEnabled(AtomConstructor runtimeCtx, EnsoContext ensoCtx) { - var contextBuiltin = ensoCtx.getBuiltins().context(); - if (runtimeCtx == contextBuiltin.getInput()) { - return permissions.input; - } else if (runtimeCtx == contextBuiltin.getOutput()) { - return permissions.output; - } else if (runtimeCtx == contextBuiltin.getDataflowStackTrace()) { - return permissions.dataflowStacktrace; - } - throw CompilerDirectives.shouldNotReachHere( - "Unknown runtimeCtx `" + runtimeCtx.getName() + "`"); - } - public static ExecutionEnvironment forName(String name) { switch (name) { case LIVE_ENVIRONMENT_NAME: @@ -92,9 +72,4 @@ public static ExecutionEnvironment forName(String name) { throw new IllegalArgumentException("Unsupported Execution Environment `" + name + "`"); } } - - /** - * Fields correspond to the constructors of {@code Standard.Base.Runtime.Context} builtin type. - */ - private record Permissions(boolean input, boolean output, boolean dataflowStacktrace) {} } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java new file mode 100644 index 000000000000..4b51f8a6bffb --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java @@ -0,0 +1,46 @@ +package org.enso.interpreter.runtime.state; + +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.data.atom.AtomConstructor; + +/** + * A node representing the functionality done by {@code Standard.Base.Runtime.Context.is_enabled}. + */ +@GenerateUncached +public abstract class HasContextEnabledNode extends Node { + + public static HasContextEnabledNode getUncached() { + return HasContextEnabledNodeGen.getUncached(); + } + + public static HasContextEnabledNode create() { + return HasContextEnabledNodeGen.create(); + } + + /** + * Returns true if the context represented by the given {@code runtimeCtxCtor} is enabled in the + * given {@code executionEnvironment}. + * + * @param runtimeCtxCtor Constructor of {@code Standard.Base.Runtime.Context}. + */ + public abstract boolean executeHasContextEnabled( + ExecutionEnvironment executionEnvironment, AtomConstructor runtimeCtxCtor); + + @Specialization + boolean doIt(ExecutionEnvironment executionEnvironment, AtomConstructor runtimeCtxCtor) { + var ensoCtx = EnsoContext.get(this); + var contextBuiltin = ensoCtx.getBuiltins().context(); + if (runtimeCtxCtor == contextBuiltin.getInput()) { + return executionEnvironment.permissions.input(); + } else if (runtimeCtxCtor == contextBuiltin.getOutput()) { + return executionEnvironment.permissions.output(); + } else if (runtimeCtxCtor == contextBuiltin.getDataflowStackTrace()) { + return executionEnvironment.permissions.dataflowStacktrace(); + } else { + throw ensoCtx.raiseAssertionPanic(this, "Unknown context: " + runtimeCtxCtor, null); + } + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/WithContextNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/WithContextNode.java new file mode 100644 index 000000000000..1f99e77a3dc7 --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/WithContextNode.java @@ -0,0 +1,44 @@ +package org.enso.interpreter.runtime.state; + +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.data.atom.Atom; + +/** + * A node representing functionality done by {@code Standard.Base.Runtime.Context.with_enabled} and + * {@code Standard.Base.Runtime.Context.with_disabled}. That is, it enables or disables the given + * context in the current {@link ExecutionEnvironment execution environment}. + */ +@GenerateUncached +public abstract class WithContextNode extends Node { + public static WithContextNode getUncached() { + return WithContextNodeGen.getUncached(); + } + + public static WithContextNode create() { + return WithContextNodeGen.create(); + } + + /** + * Returns a new {@link ExecutionEnvironment} with the given context enabled or disabled. + * + * @param current Current execution environment. + * @param context Atom of type {@code Standard.Base.Runtime.Context}. + * @param enabled Whether to enable or disable the context. + */ + public abstract ExecutionEnvironment executeEnvironmentUpdate( + ExecutionEnvironment current, Atom context, boolean enabled); + + @Specialization + ExecutionEnvironment doIt(ExecutionEnvironment current, Atom context, boolean enabled) { + var ensoCtx = EnsoContext.get(this); + var contextBuiltin = ensoCtx.getBuiltins().context(); + if (context.getConstructor().getType() != contextBuiltin.getType()) { + throw ensoCtx.raiseAssertionPanic(this, "Invalid context type", null); + } + var ctor = context.getConstructor(); + return current.update(ctor, contextBuiltin, enabled); + } +} From 3020fe839ff32dba204f967321d6070b1c67fdc8 Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Thu, 17 Oct 2024 14:20:04 +0200 Subject: [PATCH 06/10] Remove unnecessary CompilerAssert. --- .../org/enso/interpreter/runtime/error/DataflowError.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java index ea7db94f7cb2..d56c735b6e6e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/error/DataflowError.java @@ -2,7 +2,6 @@ import static org.enso.interpreter.runtime.error.PanicException.handleExceptionMessage; -import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.TruffleStackTrace; import com.oracle.truffle.api.TruffleStackTraceElement; @@ -58,9 +57,6 @@ public static DataflowError withDefaultTrace( assert payload != null; var ensoCtx = EnsoContext.get(location); var dataflowStacktraceCtx = ensoCtx.getBuiltins().context().getDataflowStackTrace(); - // dataflowStacktraceCtx is a compiler constant, because it is a constructor of a builtin - // type. - CompilerAsserts.partialEvaluationConstant(dataflowStacktraceCtx); boolean attachFullStackTrace = state == null || hasContextEnabledNode.executeHasContextEnabled( From 6ccf3042335aca40e00eb030851ea74c3a0949cc Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Thu, 17 Oct 2024 16:34:57 +0200 Subject: [PATCH 07/10] Cache executionEnvironment in the node --- .../runtime/state/HasContextEnabledNode.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java index 4b51f8a6bffb..b3d752610e4b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java @@ -1,5 +1,6 @@ package org.enso.interpreter.runtime.state; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; @@ -29,16 +30,19 @@ public static HasContextEnabledNode create() { public abstract boolean executeHasContextEnabled( ExecutionEnvironment executionEnvironment, AtomConstructor runtimeCtxCtor); - @Specialization - boolean doIt(ExecutionEnvironment executionEnvironment, AtomConstructor runtimeCtxCtor) { + @Specialization(guards = "executionEnvironment == cachedEnv", limit = "3") + boolean doIt( + ExecutionEnvironment executionEnvironment, + AtomConstructor runtimeCtxCtor, + @Cached("executionEnvironment") ExecutionEnvironment cachedEnv) { var ensoCtx = EnsoContext.get(this); var contextBuiltin = ensoCtx.getBuiltins().context(); if (runtimeCtxCtor == contextBuiltin.getInput()) { - return executionEnvironment.permissions.input(); + return cachedEnv.permissions.input(); } else if (runtimeCtxCtor == contextBuiltin.getOutput()) { - return executionEnvironment.permissions.output(); + return cachedEnv.permissions.output(); } else if (runtimeCtxCtor == contextBuiltin.getDataflowStackTrace()) { - return executionEnvironment.permissions.dataflowStacktrace(); + return cachedEnv.permissions.dataflowStacktrace(); } else { throw ensoCtx.raiseAssertionPanic(this, "Unknown context: " + runtimeCtxCtor, null); } From ee54f74d6b7d4d230c63e90f2fc83b41e955a401 Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Mon, 21 Oct 2024 16:39:02 +0200 Subject: [PATCH 08/10] Move execution context update functionality to WithContextNode --- .../runtime/state/ExecutionEnvironment.java | 29 ------------------- .../runtime/state/WithContextNode.java | 18 +++++++++++- 2 files changed, 17 insertions(+), 30 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java index 49cd7c992b69..86421b3aa64b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/ExecutionEnvironment.java @@ -1,9 +1,5 @@ package org.enso.interpreter.runtime.state; -import com.oracle.truffle.api.CompilerDirectives; -import org.enso.interpreter.node.expression.builtin.runtime.Context; -import org.enso.interpreter.runtime.data.atom.AtomConstructor; - public class ExecutionEnvironment { private final String name; @@ -37,31 +33,6 @@ public String getName() { return this.name; } - /** - * Returns copy of this {@link ExecutionEnvironment} with new permissions for the given context. - * - * @param ctor Constructor of {@code Standard.Base.Runtime.Context} type. - * @param contextBuiltin The builtin type of {@code Standard.Base.Runtime.Context}. - * @param value The new value for the permissions. - * @return A copy of the execution environment with the new permissions. - */ - ExecutionEnvironment update(AtomConstructor ctor, Context contextBuiltin, boolean value) { - assert ctor.getType() == contextBuiltin.getType(); - ContextPermissions newPermissions; - if (ctor == contextBuiltin.getInput()) { - newPermissions = - new ContextPermissions(value, permissions.output(), permissions.dataflowStacktrace()); - } else if (ctor == contextBuiltin.getOutput()) { - newPermissions = - new ContextPermissions(permissions.input(), value, permissions.dataflowStacktrace()); - } else if (ctor == contextBuiltin.getDataflowStackTrace()) { - newPermissions = new ContextPermissions(permissions.input(), permissions.output(), value); - } else { - throw CompilerDirectives.shouldNotReachHere("Unknown context `" + ctor.getName() + "`"); - } - return new ExecutionEnvironment(name, newPermissions); - } - public static ExecutionEnvironment forName(String name) { switch (name) { case LIVE_ENVIRONMENT_NAME: diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/WithContextNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/WithContextNode.java index 1f99e77a3dc7..2c7140d6080b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/WithContextNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/WithContextNode.java @@ -39,6 +39,22 @@ ExecutionEnvironment doIt(ExecutionEnvironment current, Atom context, boolean en throw ensoCtx.raiseAssertionPanic(this, "Invalid context type", null); } var ctor = context.getConstructor(); - return current.update(ctor, contextBuiltin, enabled); + ContextPermissions newPermissions; + if (ctor == contextBuiltin.getInput()) { + newPermissions = + new ContextPermissions( + enabled, current.permissions.output(), current.permissions.dataflowStacktrace()); + } else if (ctor == contextBuiltin.getOutput()) { + newPermissions = + new ContextPermissions( + current.permissions.input(), enabled, current.permissions.dataflowStacktrace()); + } else if (ctor == contextBuiltin.getDataflowStackTrace()) { + newPermissions = + new ContextPermissions( + current.permissions.input(), current.permissions.output(), enabled); + } else { + throw ensoCtx.raiseAssertionPanic(this, "Unknown context: " + ctor, null); + } + return new ExecutionEnvironment(current.getName(), newPermissions); } } From d3f4c8c812728cf8b5a60a91f664f9aba32a93e3 Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Mon, 21 Oct 2024 16:43:02 +0200 Subject: [PATCH 09/10] transfer to interpreter before string concatenation --- .../enso/interpreter/runtime/state/HasContextEnabledNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java index b3d752610e4b..c5bf6dfb6899 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java @@ -1,5 +1,6 @@ package org.enso.interpreter.runtime.state; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; @@ -44,6 +45,7 @@ boolean doIt( } else if (runtimeCtxCtor == contextBuiltin.getDataflowStackTrace()) { return cachedEnv.permissions.dataflowStacktrace(); } else { + CompilerDirectives.transferToInterpreter(); throw ensoCtx.raiseAssertionPanic(this, "Unknown context: " + runtimeCtxCtor, null); } } From be57ead87b0220517a18abb0d2a213e926c02a3d Mon Sep 17 00:00:00 2001 From: Pavel Marek Date: Tue, 22 Oct 2024 09:40:23 +0200 Subject: [PATCH 10/10] FIx UnsupportedSpecializationException --- .../runtime/state/HasContextEnabledNode.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java index c5bf6dfb6899..9a494dcf679d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/state/HasContextEnabledNode.java @@ -32,18 +32,28 @@ public abstract boolean executeHasContextEnabled( ExecutionEnvironment executionEnvironment, AtomConstructor runtimeCtxCtor); @Specialization(guards = "executionEnvironment == cachedEnv", limit = "3") - boolean doIt( + boolean cachedHasContextEnabled( ExecutionEnvironment executionEnvironment, AtomConstructor runtimeCtxCtor, @Cached("executionEnvironment") ExecutionEnvironment cachedEnv) { + return doIt(cachedEnv, runtimeCtxCtor); + } + + @Specialization(replaces = "cachedHasContextEnabled") + boolean uncachedHasContextEnabled( + ExecutionEnvironment executionEnvironment, AtomConstructor runtimeCtxCtor) { + return doIt(executionEnvironment, runtimeCtxCtor); + } + + private boolean doIt(ExecutionEnvironment executionEnvironment, AtomConstructor runtimeCtxCtor) { var ensoCtx = EnsoContext.get(this); var contextBuiltin = ensoCtx.getBuiltins().context(); if (runtimeCtxCtor == contextBuiltin.getInput()) { - return cachedEnv.permissions.input(); + return executionEnvironment.permissions.input(); } else if (runtimeCtxCtor == contextBuiltin.getOutput()) { - return cachedEnv.permissions.output(); + return executionEnvironment.permissions.output(); } else if (runtimeCtxCtor == contextBuiltin.getDataflowStackTrace()) { - return cachedEnv.permissions.dataflowStacktrace(); + return executionEnvironment.permissions.dataflowStacktrace(); } else { CompilerDirectives.transferToInterpreter(); throw ensoCtx.raiseAssertionPanic(this, "Unknown context: " + runtimeCtxCtor, null);