All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oracle.truffle.sl.nodes.call.SLDispatchNodeGen Maven / Gradle / Ivy

There is a newer version: 1.0.0-rc7
Show newest version
// CheckStyle: start generated
package com.oracle.truffle.sl.nodes.call;

import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.dsl.GeneratedBy;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeCost;
import com.oracle.truffle.api.nodes.ExplodeLoop.LoopExplosionKind;
import com.oracle.truffle.sl.nodes.interop.SLForeignToSLTypeNode;
import com.oracle.truffle.sl.runtime.SLFunction;
import java.util.concurrent.locks.Lock;

@GeneratedBy(SLDispatchNode.class)
public final class SLDispatchNodeGen extends SLDispatchNode {

    @CompilationFinal private int state_;
    @CompilationFinal private int exclude_;
    @Child private DirectData direct_cache;
    @Child private IndirectCallNode indirect_callNode_;
    @Child private Node foreign_crossLanguageCallNode_;
    @Child private SLForeignToSLTypeNode foreign_toSLTypeNode_;

    private SLDispatchNodeGen() {
    }

    @ExplodeLoop(kind = LoopExplosionKind.FULL_EXPLODE_UNTIL_RETURN)
    @Override
    public Object executeDispatch(Object arg0Value, Object[] arg1Value) {
        int state = state_;
        if (state != 0 /* is-active doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) || doIndirect(SLFunction, Object[], IndirectCallNode) || doForeign(TruffleObject, Object[], Node, SLForeignToSLTypeNode) || unknownFunction(Object, Object[]) */) {
            if ((state & 0b11) != 0 /* is-active doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) || doIndirect(SLFunction, Object[], IndirectCallNode) */ && arg0Value instanceof SLFunction) {
                SLFunction arg0Value_ = (SLFunction) arg0Value;
                if ((state & 0b1) != 0 /* is-active doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) */) {
                    DirectData s1_ = this.direct_cache;
                    while (s1_ != null) {
                        if (!isValid_(s1_.assumption0_)) {
                            CompilerDirectives.transferToInterpreterAndInvalidate();
                            removeDirect_(s1_);
                            return executeAndSpecialize(arg0Value_, arg1Value);
                        }
                        if ((arg0Value_.getCallTarget() == s1_.cachedTarget_)) {
                            return SLDispatchNode.doDirect(arg0Value_, arg1Value, s1_.callTargetStable_, s1_.cachedTarget_, s1_.callNode_);
                        }
                        s1_ = s1_.next_;
                    }
                }
                if ((state & 0b10) != 0 /* is-active doIndirect(SLFunction, Object[], IndirectCallNode) */) {
                    return SLDispatchNode.doIndirect(arg0Value_, arg1Value, this.indirect_callNode_);
                }
            }
            if ((state & 0b100) != 0 /* is-active doForeign(TruffleObject, Object[], Node, SLForeignToSLTypeNode) */ && arg0Value instanceof TruffleObject) {
                TruffleObject arg0Value_ = (TruffleObject) arg0Value;
                if ((SLDispatchNode.isForeignFunction(arg0Value_))) {
                    return doForeign(arg0Value_, arg1Value, this.foreign_crossLanguageCallNode_, this.foreign_toSLTypeNode_);
                }
            }
            if ((state & 0b1000) != 0 /* is-active unknownFunction(Object, Object[]) */) {
                if (fallbackGuard_(state, arg0Value, arg1Value)) {
                    return unknownFunction(arg0Value, arg1Value);
                }
            }
        }
        CompilerDirectives.transferToInterpreterAndInvalidate();
        return executeAndSpecialize(arg0Value, arg1Value);
    }

    private Object executeAndSpecialize(Object arg0Value, Object[] arg1Value) {
        Lock lock = getLock();
        boolean hasLock = true;
        lock.lock();
        int state = state_;
        int exclude = exclude_;
        int oldState = state;
        int oldExclude = exclude;
        int oldCacheCount = state == 0 ? 0 : countCaches();
        try {
            if (arg0Value instanceof SLFunction) {
                SLFunction arg0Value_ = (SLFunction) arg0Value;
                if ((exclude) == 0 /* is-not-excluded doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) */) {
                    int count1_ = 0;
                    DirectData s1_ = this.direct_cache;
                    if ((state & 0b1) != 0 /* is-active doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) */) {
                        while (s1_ != null) {
                            if ((arg0Value_.getCallTarget() == s1_.cachedTarget_) && (s1_.assumption0_ == null || isValid_(s1_.assumption0_))) {
                                break;
                            }
                            s1_ = s1_.next_;
                            count1_++;
                        }
                    }
                    if (s1_ == null) {
                        {
                            RootCallTarget cachedTarget__ = (arg0Value_.getCallTarget());
                            if ((arg0Value_.getCallTarget() == cachedTarget__)) {
                                Assumption callTargetStable__ = (arg0Value_.getCallTargetStable());
                                Assumption assumption0 = (callTargetStable__);
                                if (isValid_(assumption0)) {
                                    if (count1_ < (SLDispatchNode.INLINE_CACHE_SIZE)) {
                                        s1_ = new DirectData(direct_cache);
                                        s1_.callTargetStable_ = callTargetStable__;
                                        s1_.cachedTarget_ = cachedTarget__;
                                        s1_.callNode_ = (DirectCallNode.create(cachedTarget__));
                                        s1_.assumption0_ = assumption0;
                                        this.direct_cache = super.insert(s1_);
                                        this.state_ = state = state | 0b1 /* add-active doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) */;
                                    }
                                }
                            }
                        }
                    }
                    if (s1_ != null) {
                        lock.unlock();
                        hasLock = false;
                        return SLDispatchNode.doDirect(arg0Value_, arg1Value, s1_.callTargetStable_, s1_.cachedTarget_, s1_.callNode_);
                    }
                }
                this.indirect_callNode_ = super.insert((IndirectCallNode.create()));
                this.exclude_ = exclude = exclude | 0b1 /* add-excluded doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) */;
                this.direct_cache = null;
                state = state & 0xfffffffe /* remove-active doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) */;
                this.state_ = state = state | 0b10 /* add-active doIndirect(SLFunction, Object[], IndirectCallNode) */;
                lock.unlock();
                hasLock = false;
                return SLDispatchNode.doIndirect(arg0Value_, arg1Value, this.indirect_callNode_);
            }
            if (arg0Value instanceof TruffleObject) {
                TruffleObject arg0Value_ = (TruffleObject) arg0Value;
                if ((SLDispatchNode.isForeignFunction(arg0Value_))) {
                    this.foreign_crossLanguageCallNode_ = super.insert((SLDispatchNode.createCrossLanguageCallNode(arg1Value)));
                    this.foreign_toSLTypeNode_ = super.insert((SLDispatchNode.createToSLTypeNode()));
                    this.state_ = state = state | 0b100 /* add-active doForeign(TruffleObject, Object[], Node, SLForeignToSLTypeNode) */;
                    lock.unlock();
                    hasLock = false;
                    return doForeign(arg0Value_, arg1Value, this.foreign_crossLanguageCallNode_, this.foreign_toSLTypeNode_);
                }
            }
            this.state_ = state = state | 0b1000 /* add-active unknownFunction(Object, Object[]) */;
            lock.unlock();
            hasLock = false;
            return unknownFunction(arg0Value, arg1Value);
        } finally {
            if (oldState != 0 || oldExclude != 0) {
                checkForPolymorphicSpecialize(oldState, oldExclude, oldCacheCount);
            }
            if (hasLock) {
                lock.unlock();
            }
        }
    }

    private void checkForPolymorphicSpecialize(int oldState, int oldExclude, int oldCacheCount) {
        int newState = this.state_;
        int newExclude = this.exclude_;
        if ((oldState ^ newState) != 0 || (oldExclude ^ newExclude) != 0 || oldCacheCount < countCaches()) {
            this.reportPolymorphicSpecialize();
        }
    }

    private int countCaches() {
        int cacheCount = 0;
        DirectData s1_ = this.direct_cache;
        while (s1_ != null) {
            cacheCount++;
            s1_= s1_.next_;
        }
        return cacheCount;
    }

    @Override
    public NodeCost getCost() {
        int state = state_;
        if (state == 0b0) {
            return NodeCost.UNINITIALIZED;
        } else if ((state & (state - 1)) == 0 /* is-single-active  */) {
            DirectData s1_ = this.direct_cache;
            if ((s1_ == null || s1_.next_ == null)) {
                return NodeCost.MONOMORPHIC;
            }
        }
        return NodeCost.POLYMORPHIC;
    }

    void removeDirect_(Object s1_) {
        Lock lock = getLock();
        lock.lock();
        try {
            DirectData prev = null;
            DirectData cur = this.direct_cache;
            while (cur != null) {
                if (cur == s1_) {
                    if (prev == null) {
                        this.direct_cache = cur.next_;
                        this.adoptChildren();
                    } else {
                        prev.next_ = cur.next_;
                        prev.adoptChildren();
                    }
                    break;
                }
                prev = cur;
                cur = cur.next_;
            }
            if (this.direct_cache == null) {
                this.state_ = this.state_ & 0xfffffffe /* remove-active doDirect(SLFunction, Object[], Assumption, RootCallTarget, DirectCallNode) */;
            }
        } finally {
            lock.unlock();
        }
    }

    @SuppressWarnings("unused")
    private static boolean fallbackGuard_(int state, Object arg0Value, Object[] arg1Value) {
        if (((state & 0b10)) == 0 /* is-not-active doIndirect(SLFunction, Object[], IndirectCallNode) */ && arg0Value instanceof SLFunction) {
            return false;
        }
        if (arg0Value instanceof TruffleObject) {
            TruffleObject arg0Value_ = (TruffleObject) arg0Value;
            if ((SLDispatchNode.isForeignFunction(arg0Value_))) {
                return false;
            }
        }
        return true;
    }

    private static boolean isValid_(Assumption assumption) {
        return assumption != null && assumption.isValid();
    }

    public static SLDispatchNode create() {
        return new SLDispatchNodeGen();
    }

    @GeneratedBy(SLDispatchNode.class)
    private static final class DirectData extends Node {

        @Child DirectData next_;
        @CompilationFinal Assumption callTargetStable_;
        @CompilationFinal RootCallTarget cachedTarget_;
        @Child DirectCallNode callNode_;
        @CompilationFinal Assumption assumption0_;

        DirectData(DirectData next_) {
            this.next_ = next_;
        }

        @Override
        public NodeCost getCost() {
            return NodeCost.NONE;
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy