Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make suspended atom fields work for boxed atoms #8712

Merged
merged 36 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4aa19cc
Four tests showing difference between four and five atom fields
JaroslavTulach Jan 9, 2024
c227a5b
Separate evalCode and execute
JaroslavTulach Jan 9, 2024
9bc1af4
Avoid public BoxingAtom constructor
JaroslavTulach Jan 9, 2024
597599a
Keeping atoms in the same package allows packge private communication
JaroslavTulach Jan 9, 2024
22f22ae
Merge remote-tracking branch 'origin/develop' into wip/jtulach/RichAt…
JaroslavTulach Jan 12, 2024
b543c7c
Using Layout to access BoxingAtom
JaroslavTulach Jan 12, 2024
bb6116b
Explicitly force creation of BoxedLayout
JaroslavTulach Jan 12, 2024
4b3e245
Moving everything Atom related into org.enso.interpreter.runtime.data…
JaroslavTulach Jan 12, 2024
7146ee8
Always use StructsLibrary when accessing fields
JaroslavTulach Jan 12, 2024
6d890de
Put creation of a node behind @TruffleBoundary for now
JaroslavTulach Jan 13, 2024
7ff995e
Merging with latest develop and resolving AssertNode conflict
JaroslavTulach Jan 13, 2024
580c3d8
Turn getMaxUnboxingLayouts into static constant
JaroslavTulach Jan 13, 2024
03ed29e
Moving the instantiation logic into own class
JaroslavTulach Jan 13, 2024
85c396f
Refactoring AtomNewInstanceNode and co.
JaroslavTulach Jan 13, 2024
d433218
AtomConstructorTest to check consistency of various allocations strat…
JaroslavTulach Jan 14, 2024
561d8be
Verify values in Atom instances
JaroslavTulach Jan 14, 2024
8675747
Uncached veriant of newInstance that uses existing UnboxingLayouts
JaroslavTulach Jan 14, 2024
f8d8a98
Uncached variant also optimizes unboxling layouts
JaroslavTulach Jan 14, 2024
1d8bd1a
Simplify StructsLibrary by removing getFields()
JaroslavTulach Jan 15, 2024
95cece3
ConstantNode has nothing to do with atoms
JaroslavTulach Jan 15, 2024
afa9ad2
Layout doesn't have to be public
JaroslavTulach Jan 15, 2024
97ef02e
Don't expose QualifiedAccessorNode to public
JaroslavTulach Jan 15, 2024
fbfc319
scalafmtAll
JaroslavTulach Jan 15, 2024
57fdd05
InstantiateNode doesn't have to be public
JaroslavTulach Jan 15, 2024
a28daff
Exposing only four classes from the org.enso.interpreter.runtime.data…
JaroslavTulach Jan 15, 2024
b6a1c2a
Use AtomNewInstanceNode.newInstance to instantiate AtomConstructor
JaroslavTulach Jan 15, 2024
0c5955a
Pass cons into newInstance as first parameter
JaroslavTulach Jan 15, 2024
fff48c5
Support endless specializations
JaroslavTulach Jan 15, 2024
2fe3a87
AtomConstructorInstanceNode must be able to handle unlimited number o…
JaroslavTulach Jan 15, 2024
08df824
FieldsAsArrayNode to speed conversions up
JaroslavTulach Jan 15, 2024
6bb2725
Fixing javadoc typo
JaroslavTulach Jan 15, 2024
33e79e1
It is @see tag
JaroslavTulach Jan 16, 2024
a5b169c
CompilerDirectives.shouldNotReachHere
JaroslavTulach Jan 16, 2024
3addd39
Test getUncached() with priming
JaroslavTulach Jan 16, 2024
2eee9fa
Merge remote-tracking branch 'origin/develop' into wip/jtulach/RichAt…
JaroslavTulach Jan 16, 2024
d62e6b9
Removing leftover comment
JaroslavTulach Jan 16, 2024
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 @@ -33,15 +33,14 @@
import org.enso.interpreter.instrument.profiling.ProfilingInfo;
import org.enso.interpreter.node.MethodRootNode;
import org.enso.interpreter.node.callable.FunctionCallInstrumentationNode;
import org.enso.interpreter.node.expression.atom.QualifiedAccessorNode;
import org.enso.interpreter.node.expression.builtin.BuiltinRootNode;
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.Module;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.callable.function.FunctionSchema;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.scope.ModuleScope;
import org.enso.interpreter.runtime.state.State;
Expand Down Expand Up @@ -739,6 +738,10 @@ public static FunctionPointer fromAtomConstructor(AtomConstructor atomConstructo
}

public static FunctionPointer fromFunction(Function function) {
var cons = AtomConstructor.accessorFor(function);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introducing the accessorFor method allows us to make QualifiedAccessorNode package private, @4e6.

if (cons != null) {
return fromAtomConstructor(cons);
}
RootNode rootNode = function.getCallTarget().getRootNode();

QualifiedName moduleName;
Expand All @@ -751,12 +754,6 @@ public static FunctionPointer fromFunction(Function function) {
typeName = methodNode.getType().getQualifiedName();
functionName = methodNode.getMethodName();
}
case QualifiedAccessorNode qualifiedAccessor -> {
AtomConstructor atomConstructor = qualifiedAccessor.getAtomConstructor();
moduleName = atomConstructor.getDefinitionScope().getModule().getName();
typeName = atomConstructor.getType().getQualifiedName();
functionName = atomConstructor.getName();
}
case BuiltinRootNode builtinRootNode -> {
moduleName = builtinRootNode.getModuleName();
typeName = builtinRootNode.getTypeName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.enso.interpreter.instrument.profiling.ExecutionTime
import org.enso.interpreter.node.callable.FunctionCallInstrumentationNode.FunctionCall
import org.enso.interpreter.node.expression.builtin.meta.TypeOfNode
import org.enso.interpreter.runtime.`type`.{Types, TypesGen}
import org.enso.interpreter.runtime.callable.atom.AtomConstructor
import org.enso.interpreter.runtime.data.atom.AtomConstructor
import org.enso.interpreter.runtime.callable.function.Function
import org.enso.interpreter.runtime.control.ThreadInterruptedException
import org.enso.interpreter.runtime.error.{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.enso.interpreter.node.ProgramRootNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.IrToTruffle;
import org.enso.interpreter.runtime.data.atom.AtomNewInstanceNode;
import org.enso.interpreter.runtime.state.ExecutionEnvironment;
import org.enso.interpreter.runtime.tag.AvoidIdInstrumentationTag;
import org.enso.interpreter.runtime.tag.IdentifiedTag;
Expand Down Expand Up @@ -355,7 +356,8 @@ protected Object getScope(EnsoContext context) {
protected Object getLanguageView(EnsoContext context, Object value) {
if (value instanceof Boolean b) {
var bool = context.getBuiltins().bool();
return b ? bool.getTrue().newInstance() : bool.getFalse().newInstance();
var cons = b ? bool.getTrue() : bool.getFalse();
return AtomNewInstanceNode.getUncached().newInstance(cons);
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.enso.interpreter.node.expression.atom;
package org.enso.interpreter.node;

import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.RootNode;

public class ConstantNode extends RootNode {
public final class ConstantNode extends RootNode {
private final Object constant;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import com.oracle.truffle.api.source.SourceSection;
import java.util.UUID;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.scope.DebugLocalScope;
import org.enso.interpreter.runtime.tag.AvoidIdInstrumentationTag;
import org.enso.interpreter.runtime.tag.IdentifiedTag;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.error.PanicSentinel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
import org.enso.interpreter.runtime.callable.UnresolvedConversion;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.control.TailCallException;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.error.PanicSentinel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
import org.enso.interpreter.node.callable.InvokeCallableNodeGen;
import org.enso.interpreter.runtime.callable.CallerInfo;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.callable.function.FunctionSchema;
import org.enso.interpreter.runtime.control.TailCallException;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.state.State;

/** Handles runtime function currying and oversaturated (eta-expanded) calls. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
import org.enso.interpreter.node.callable.InvokeCallableNode;
import org.enso.interpreter.runtime.callable.CallerInfo;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.callable.function.FunctionSchema;
import org.enso.interpreter.runtime.control.TailCallException;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.state.State;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package org.enso.interpreter.node.controlflow.caseexpr;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.profiles.CountingConditionProfile;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.atom.StructsLibrary;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.atom.StructsLibrary;

/** An implementation of the case expression specialised to working on constructors. */
@NodeInfo(shortName = "ConstructorMatch")
Expand All @@ -36,15 +40,38 @@ public static ConstructorBranchNode build(

@Specialization
void doAtom(
VirtualFrame frame,
Object state,
Atom target,
@CachedLibrary(limit = "10") StructsLibrary structs) {
VirtualFrame frame, Object state, Atom target, @Cached FieldsAsArrayNode toArrayNode) {
if (profile.profile(matcher == target.getConstructor())) {
accept(frame, state, structs.getFields(target));
var arr = toArrayNode.executeFields(target);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The benchmarks regressed a bit after removal of getFields, but introduction of FieldsAsArrayNode that provides a polymorphic cache for each AtomConstructor (up to limit 3 - usually there is only one anyway) and explodes the loop that reads the fields one by one seems to deliver the same results.

Example of AtomBenchmark

accept(frame, state, arr);
}
}

@Fallback
void doFallback(VirtualFrame frame, Object state, Object target) {}

abstract static class FieldsAsArrayNode extends Node {
abstract Object[] executeFields(Atom target);

@Specialization(
limit = "3",
guards = {"atom.getConstructor() == cons"})
@ExplodeLoop
Object[] fieldsFromAtomCached(
Atom atom,
@Cached("atom.getConstructor()") AtomConstructor cons,
@CachedLibrary(limit = "3") StructsLibrary structs) {
var arr = new Object[cons.getArity()];
for (var i = 0; i < arr.length; i++) {
arr[i] = structs.getField(atom, i);
}
return arr;
}

@Specialization
@TruffleBoundary
Object[] fieldsFromAtomUncached(Atom atom) {
return fieldsFromAtomCached(atom, atom.getConstructor(), StructsLibrary.getUncached());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import org.enso.interpreter.node.expression.builtin.meta.TypeOfNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.error.PanicException;

/** An implementation of the case expression specialised to working on polyglot types. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.util.List;
import org.enso.interpreter.dsl.BuiltinType;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;

// Note that Boolean BuiltinType cannot be moved to `.expression.builtin.bool`
// because it currently breaks a lot of code generation for builtin methods.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import java.util.stream.IntStream;
import org.enso.interpreter.EnsoLanguage;
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.scope.ModuleScope;

/** A base class for all classes annotated with @BuiltinType */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import com.oracle.truffle.api.CompilerDirectives;
import java.util.List;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.atom.AtomNewInstanceNode;

public abstract class UniquelyConstructibleBuiltin extends Builtin {
private @CompilerDirectives.CompilationFinal AtomConstructor uniqueConstructor;
Expand All @@ -29,6 +30,6 @@ protected void postInitialize() {
}

public final Atom newInstance(Object... params) {
return uniqueConstructor.newInstance(params);
return AtomNewInstanceNode.getUncached().newInstance(uniqueConstructor, params);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to hide AtomConstructor.newInstance as package private and expose AtomNewInstanceNode.getUncached() instead. It was not clear that AtomConstructor.newInstance was slow (and only allocating BoxedAtom!). Now, when we follow standard Truffle conventions, it is clear getUncached() is the slow path version of AtomNewInstanceNode.create(). Functionally they are identical as AtomConstructorTest demonstrates.

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
import org.enso.interpreter.node.expression.builtin.meta.IsValueOfTypeNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.data.atom.AtomNewInstanceNode;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.state.State;

Expand Down Expand Up @@ -81,9 +80,10 @@ private Object executeCallbackOrRethrow(
InteropLibrary interopLibrary) {

if (profile.profile(isValueOfTypeNode.execute(panicType, payload))) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
Atom caughtPanic =
builtins.caughtPanic().getUniqueConstructor().newInstance(payload, originalException);
var builtins = EnsoContext.get(this).getBuiltins();
var cons = builtins.caughtPanic().getUniqueConstructor();
var caughtPanic =
AtomNewInstanceNode.getUncached().newInstance(cons, payload, originalException);
return invokeCallableNode.execute(handler, frame, state, new Object[] {caughtPanic});
} else {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.StructsLibrary;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.StructsLibrary;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.state.State;
Expand All @@ -32,9 +32,8 @@ Object doExecute(
@CachedLibrary(limit = "5") InteropLibrary interopLibrary,
@CachedLibrary(limit = "5") StructsLibrary structs) {
Builtins builtins = EnsoContext.get(this).getBuiltins();
var fields = structs.getFields(self);
Object payload = fields[0];
Object originalException = fields[1];
var payload = structs.getField(self, 0);
var originalException = structs.getField(self, 1);
if (interopLibrary.isException(originalException)) {
return DataflowError.withTrace(payload, (AbstractTruffleException) originalException);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import java.util.List;
import org.enso.interpreter.dsl.BuiltinType;
import org.enso.interpreter.node.expression.builtin.Builtin;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.AtomNewInstanceNode;

@BuiltinType
public final class NumberParseError extends Builtin {
Expand All @@ -13,6 +14,6 @@ protected final List<Cons> getDeclaredConstructors() {
}

public final Atom newInstance(Object... params) {
return getConstructors()[0].newInstance(params);
return AtomNewInstanceNode.getUncached().newInstance(getConstructors()[0], params);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.StructsLibrary;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.StructsLibrary;
import org.enso.interpreter.runtime.error.PanicException;

@BuiltinMethod(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.dsl.BuiltinMethod;
import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.callable.atom.StructsLibrary;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.AtomConstructor;
import org.enso.interpreter.runtime.data.atom.StructsLibrary;
import org.enso.interpreter.runtime.data.text.Text;

@BuiltinMethod(type = "Invalid_Conversion_Target", name = "to_display_text")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
import org.enso.interpreter.runtime.callable.Annotation;
import org.enso.interpreter.runtime.callable.argument.ArgumentDefinition;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.atom.Atom;
import org.enso.interpreter.runtime.callable.atom.StructsLibrary;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.callable.function.FunctionSchema;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.StructsLibrary;
import org.enso.interpreter.runtime.data.vector.ArrayLikeHelpers;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.state.State;
Expand Down Expand Up @@ -173,13 +173,12 @@ static SwapAtomFieldNode create() {
}

int findHoleIndex(Atom atom, HoleInAtom lazy) {
var arr = structs.getFields(atom);
if (lastIndex >= 0 && lastIndex < arr.length) {
if (arr[lastIndex] == lazy) {
if (lastIndex >= 0 && lastIndex < atom.getConstructor().getArity()) {
if (structs.getField(atom, lastIndex) == lazy) {
return lastIndex;
}
}
int index = findHoleIndexLoop(arr, lazy);
int index = findHoleIndexLoop(atom, lazy);
if (index == -1) {
return -1;
}
Expand All @@ -197,9 +196,9 @@ int findHoleIndex(Atom atom, HoleInAtom lazy) {
}

@CompilerDirectives.TruffleBoundary
JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
private int findHoleIndexLoop(Object[] arr, HoleInAtom lazy) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == lazy) {
private int findHoleIndexLoop(Atom atom, HoleInAtom lazy) {
for (int i = 0; i < atom.getConstructor().getArity(); i++) {
if (structs.getField(atom, i) == lazy) {
return i;
}
}
Expand Down
Loading
Loading