mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 12:31:44 +03:00
Speeding up Ordering_Comparator (#10593)
This commit is contained in:
parent
451d7cb452
commit
c0f5759e07
@ -69,16 +69,16 @@ assert_same_comparators this that ~action =
|
||||
False -> Error.throw (Incomparable_Values.Error this that)
|
||||
|
||||
compare_with_comparators this that -> Ordering ! Incomparable_Values =
|
||||
any_result = Panic.catch Type_Error handler=identity <|
|
||||
yield_an_error _ = Error.throw (Incomparable_Values.Error this that)
|
||||
Panic.catch Type_Error handler=yield_an_error <|
|
||||
comp_this = Comparable.from this
|
||||
comp_that = Comparable.from that
|
||||
|
||||
if Meta.is_same_object comp_this.comparator comp_that.comparator then
|
||||
any_result = if Meta.is_same_object comp_this.comparator comp_that.comparator then
|
||||
comp_this.comparator.compare comp_this.value comp_that.value
|
||||
|
||||
case any_result of
|
||||
result:Ordering -> result
|
||||
_ -> Error.throw (Incomparable_Values.Error this that)
|
||||
result = any_result:Ordering
|
||||
result
|
||||
|
||||
## PRIVATE
|
||||
type Positive_Integer_Comparator
|
||||
@ -92,7 +92,10 @@ type Positive_Integer_Comparator
|
||||
## PRIVATE
|
||||
type Ordering_Comparator
|
||||
## PRIVATE
|
||||
compare x:Ordering y:Ordering = Ordering.compare x.to_sign y.to_sign
|
||||
compare x:Ordering y:Ordering = if Meta.is_same_object x y then Ordering.Equal else
|
||||
if Meta.is_same_object x Ordering.Equal . not then x else
|
||||
if Meta.is_same_object y Ordering.Less then Ordering.Greater else
|
||||
Ordering.Less
|
||||
|
||||
## PRIVATE
|
||||
hash x:Ordering = x.to_sign
|
||||
|
@ -155,9 +155,8 @@ final class BinaryOperatorNode extends ExpressionNode {
|
||||
for (var thatType : multi.allTypes()) {
|
||||
var fn = findSymbol(symbol, thatType);
|
||||
if (fn != null) {
|
||||
var result =
|
||||
doDispatch(
|
||||
frame, self, multi.castTo(thatType), thatType, fn, convertNode, invokeNode);
|
||||
var thatCasted = EnsoMultiValue.CastToNode.getUncached().executeCast(thatType, multi);
|
||||
var result = doDispatch(frame, self, thatCasted, thatType, fn, convertNode, invokeNode);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
@ -179,9 +179,10 @@ public abstract class InvokeConversionNode extends BaseNode {
|
||||
UnresolvedConversion conversion,
|
||||
Object self,
|
||||
EnsoMultiValue that,
|
||||
Object[] arguments) {
|
||||
Object[] arguments,
|
||||
@Cached EnsoMultiValue.CastToNode castTo) {
|
||||
var type = extractType(self);
|
||||
var result = that.castTo(type);
|
||||
var result = castTo.executeCast(type, that);
|
||||
if (result == null) {
|
||||
throw new PanicException(
|
||||
EnsoContext.get(this).getBuiltins().error().makeNoSuchConversion(type, self, conversion),
|
||||
|
@ -294,10 +294,11 @@ public abstract class InvokeMethodNode extends BaseNode {
|
||||
UnresolvedSymbol symbol,
|
||||
EnsoMultiValue self,
|
||||
Object[] arguments,
|
||||
@Shared("methodResolverNode") @Cached MethodResolverNode methodResolverNode) {
|
||||
@Shared("methodResolverNode") @Cached MethodResolverNode methodResolverNode,
|
||||
@Cached EnsoMultiValue.CastToNode castTo) {
|
||||
var fnAndType = self.resolveSymbol(methodResolverNode, symbol);
|
||||
if (fnAndType != null) {
|
||||
var unwrapSelf = self.castTo(fnAndType.getRight());
|
||||
var unwrapSelf = castTo.executeCast(fnAndType.getRight(), self);
|
||||
if (unwrapSelf != null) {
|
||||
assert arguments[0] == self;
|
||||
arguments[0] = unwrapSelf;
|
||||
|
@ -287,6 +287,7 @@ public abstract class ReadArgumentCheckNode extends Node {
|
||||
@Child IsValueOfTypeNode checkType;
|
||||
@CompilerDirectives.CompilationFinal private String expectedTypeMessage;
|
||||
@CompilerDirectives.CompilationFinal private LazyCheckRootNode lazyCheck;
|
||||
@Child private EnsoMultiValue.CastToNode castTo;
|
||||
|
||||
TypeCheckNode(String name, Type expectedType) {
|
||||
super(name);
|
||||
@ -354,7 +355,11 @@ public abstract class ReadArgumentCheckNode extends Node {
|
||||
return lazyCheckFn;
|
||||
}
|
||||
if (v instanceof EnsoMultiValue mv) {
|
||||
var result = mv.castTo(expectedType);
|
||||
if (castTo == null) {
|
||||
CompilerDirectives.transferToInterpreter();
|
||||
castTo = insert(EnsoMultiValue.CastToNode.create());
|
||||
}
|
||||
var result = castTo.executeCast(expectedType, mv);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
@ -2,7 +2,11 @@ package org.enso.interpreter.runtime.data;
|
||||
|
||||
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
|
||||
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
||||
import com.oracle.truffle.api.dsl.Cached;
|
||||
import com.oracle.truffle.api.dsl.Cached.Shared;
|
||||
import com.oracle.truffle.api.dsl.GenerateUncached;
|
||||
import com.oracle.truffle.api.dsl.NeverDefault;
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.interop.ArityException;
|
||||
import com.oracle.truffle.api.interop.InteropLibrary;
|
||||
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
||||
@ -12,6 +16,7 @@ import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
||||
import com.oracle.truffle.api.library.CachedLibrary;
|
||||
import com.oracle.truffle.api.library.ExportLibrary;
|
||||
import com.oracle.truffle.api.library.ExportMessage;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import java.math.BigInteger;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
@ -413,19 +418,40 @@ public final class EnsoMultiValue implements EnsoObject {
|
||||
return Arrays.stream(types).map(t -> t.getName()).collect(Collectors.joining(" & "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts value in this multi value into specific t.
|
||||
*
|
||||
* @param type the requested t
|
||||
* @return instance of the {@code t} or {@code null} if no suitable value was found
|
||||
*/
|
||||
public final Object castTo(Type type) {
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
if (types[i] == type) {
|
||||
return values[i];
|
||||
}
|
||||
/** Casts {@link EnsoMultiValue} to requested type effectively. */
|
||||
@GenerateUncached
|
||||
public abstract static class CastToNode extends Node {
|
||||
/**
|
||||
* Casts value in a multi value into specific type.
|
||||
*
|
||||
* @param type the requested t
|
||||
* @param mv a multi value
|
||||
* @return instance of the {@code t} or {@code null} if no suitable value was found
|
||||
*/
|
||||
public abstract Object executeCast(Type type, EnsoMultiValue mv);
|
||||
|
||||
@NeverDefault
|
||||
public static CastToNode create() {
|
||||
return EnsoMultiValueFactory.CastToNodeGen.create();
|
||||
}
|
||||
|
||||
@NeverDefault
|
||||
public static CastToNode getUncached() {
|
||||
return EnsoMultiValueFactory.CastToNodeGen.getUncached();
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Object castsToAType(
|
||||
Type type,
|
||||
EnsoMultiValue mv,
|
||||
@Cached(value = "type", allowUncached = true, neverDefault = true) Type cachedType) {
|
||||
for (var i = 0; i < mv.types.length; i++) {
|
||||
if (mv.types[i] == cachedType) {
|
||||
return mv.values[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user