Mercurial > hg > truffle
diff truffle/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java @ 21951:9c8c0937da41
Moving all sources into truffle subdirectory
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Wed, 17 Jun 2015 10:58:08 +0200 |
parents | graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java@b1530a6cce8c |
children | dc83cc1f94f2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java Wed Jun 17 10:58:08 2015 +0200 @@ -0,0 +1,866 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.dsl.internal; + +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent0; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent1; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent2; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent3; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent4; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEvent5; +import com.oracle.truffle.api.dsl.internal.SlowPathEvent.SlowPathEventN; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Internal implementation dependent base class for generated specialized nodes. + */ +@NodeInfo(cost = NodeCost.NONE) +@SuppressWarnings("unused") +public abstract class SpecializationNode extends Node { + + @Child protected SpecializationNode next; + + final int index; + + public SpecializationNode() { + this(-1); + } + + public SpecializationNode(int index) { + this.index = index; + } + + @Override + public final NodeCost getCost() { + return NodeCost.NONE; + } + + public void reset() { + SpecializationNode start = findStart(); + SpecializationNode end = findEnd(); + if (start != end) { + start.replace(end, "reset specialization"); + } + } + + public static Node updateRoot(Node node) { + updateRootImpl(((SpecializedNode) node).getSpecializationNode(), node); + return node; + } + + private static void updateRootImpl(SpecializationNode start, Node node) { + NodeFieldAccessor[] fields = NodeClass.get(start).getFields(); + for (int i = fields.length - 1; i >= 0; i--) { + NodeFieldAccessor f = fields[i]; + if (f.getName().equals("root")) { + f.putObject(start, node); + break; + } + } + if (start.next != null) { + updateRootImpl(start.next, node); + } + } + + protected final SpecializationNode polymorphicMerge(SpecializationNode newNode, SpecializationNode merged) { + if (merged == newNode && count() <= 2) { + return removeSame(new SlowPathEvent0(this, "merged polymorphic to monomorphic", null)); + } + return merged; + } + + public final NodeCost getNodeCost() { + switch (count()) { + case 0: + case 1: + return NodeCost.UNINITIALIZED; + case 2: + return NodeCost.MONOMORPHIC; + default: + return NodeCost.POLYMORPHIC; + } + } + + protected abstract Node[] getSuppliedChildren(); + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame) { + if (isIdentical(newNode, frame)) { + return this; + } + return next != null ? next.merge(newNode, frame) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1) { + if (isIdentical(newNode, frame, o1)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2) { + if (isIdentical(newNode, frame, o1, o2)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1, o2) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3) { + if (isIdentical(newNode, frame, o1, o2, o3)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1, o2, o3) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4) { + if (isIdentical(newNode, frame, o1, o2, o3, o4)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1, o2, o3, o4) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + if (isIdentical(newNode, frame, o1, o2, o3, o4, o5)) { + return this; + } + return next != null ? next.merge(newNode, frame, o1, o2, o3, o4, o5) : newNode; + } + + protected SpecializationNode merge(SpecializationNode newNode, Frame frame, Object... args) { + if (isIdentical(newNode, frame, args)) { + return this; + } + return next != null ? next.merge(newNode, frame, args) : newNode; + } + + protected boolean isSame(SpecializationNode other) { + return getClass() == other.getClass(); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + return isSame(newNode); + } + + protected boolean isIdentical(SpecializationNode newNode, Frame frame, Object... args) { + return isSame(newNode); + } + + protected final int countSame(SpecializationNode node) { + return findStart().countSameImpl(node); + } + + private int countSameImpl(SpecializationNode node) { + if (next != null) { + return next.countSameImpl(node) + (isSame(node) ? 1 : 0); + } else { + return 0; + } + } + + @Override + public final boolean equals(Object obj) { + if (obj instanceof SpecializationNode) { + return ((SpecializationNode) obj).isSame(this); + } + return super.equals(obj); + } + + @Override + public final int hashCode() { + return index; + } + + private int count() { + return next != null ? next.count() + 1 : 1; + } + + private SpecializationNode findEnd() { + SpecializationNode node = this; + while (node.next != null) { + node = node.next; + } + return node; + } + + protected final Object removeThis(final CharSequence reason, Frame frame) { + return removeThisImpl(reason).acceptAndExecute(frame); + } + + protected final Object removeThis(final CharSequence reason, Frame frame, Object o1) { + return removeThisImpl(reason).acceptAndExecute(frame, o1); + } + + protected final Object removeThis(final CharSequence reason, Frame frame, Object o1, Object o2) { + return removeThisImpl(reason).acceptAndExecute(frame, o1, o2); + } + + protected final Object removeThis(final CharSequence reason, Frame frame, Object o1, Object o2, Object o3) { + return removeThisImpl(reason).acceptAndExecute(frame, o1, o2, o3); + } + + protected final Object removeThis(final CharSequence reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { + return removeThisImpl(reason).acceptAndExecute(frame, o1, o2, o3, o4); + } + + protected final Object removeThis(final CharSequence reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + return removeThisImpl(reason).acceptAndExecute(frame, o1, o2, o3, o4, o5); + } + + protected final Object removeThis(final CharSequence reason, Frame frame, Object... args) { + return removeThisImpl(reason).acceptAndExecute(frame, args); + } + + private SpecializationNode removeThisImpl(final CharSequence reason) { + this.replace(this.next, reason); + return findEnd().findStart(); + } + + protected final SpecializationNode removeSame(final CharSequence reason) { + SpecializationNode start = SpecializationNode.this.findStart(); + SpecializationNode current = start; + while (current != null) { + if (current.isSame(SpecializationNode.this)) { + NodeUtil.nonAtomicReplace(current, current.next, reason); + if (current == start) { + start = start.next; + } + } + current = current.next; + } + return SpecializationNode.this.findEnd().findStart(); + } + + /** Find the topmost of the specialization chain. */ + private SpecializationNode findStart() { + SpecializationNode node = this; + Node parent = this.getParent(); + while (parent instanceof SpecializationNode) { + SpecializationNode parentCast = ((SpecializationNode) parent); + if (parentCast.next != node) { + break; + } + node = parentCast; + parent = node.getParent(); + } + return node; + } + + private Node findRoot() { + return findStart().getParent(); + } + + private SpecializedNode findSpecializedNode() { + return (SpecializedNode) findEnd().findStart().getParent(); + } + + private static SpecializationNode removeSameImpl(SpecializationNode toRemove, CharSequence reason) { + SpecializationNode start = toRemove.findStart(); + SpecializationNode current = start; + while (current != null) { + if (current.isSame(toRemove)) { + NodeUtil.nonAtomicReplace(current, current.next, reason); + if (current == start) { + start = start.next; + } + } + current = current.next; + } + return toRemove.findEnd().findStart(); + } + + public Object acceptAndExecute(Frame frame) { + throw new UnsupportedOperationException(); + } + + public Object acceptAndExecute(Frame frame, Object o1) { + throw new UnsupportedOperationException(); + } + + public Object acceptAndExecute(Frame frame, Object o1, Object o2) { + throw new UnsupportedOperationException(); + } + + public Object acceptAndExecute(Frame frame, Object o1, Object o2, Object o3) { + throw new UnsupportedOperationException(); + } + + public Object acceptAndExecute(Frame frame, Object o1, Object o2, Object o3, Object o4) { + throw new UnsupportedOperationException(); + } + + public Object acceptAndExecute(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + throw new UnsupportedOperationException(); + } + + public Object acceptAndExecute(Frame frame, Object... args) { + throw new UnsupportedOperationException(); + } + + protected SpecializationNode createFallback() { + return null; + } + + protected SpecializationNode createPolymorphic() { + return null; + } + + protected SpecializationNode createNext(Frame frame) { + throw new UnsupportedOperationException(); + } + + protected SpecializationNode createNext(Frame frame, Object o1) { + throw new UnsupportedOperationException(); + } + + protected SpecializationNode createNext(Frame frame, Object o1, Object o2) { + throw new UnsupportedOperationException(); + } + + protected SpecializationNode createNext(Frame frame, Object o1, Object o2, Object o3) { + throw new UnsupportedOperationException(); + } + + protected SpecializationNode createNext(Frame frame, Object o1, Object o2, Object o3, Object o4) { + throw new UnsupportedOperationException(); + } + + protected SpecializationNode createNext(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + throw new UnsupportedOperationException(); + } + + protected SpecializationNode createNext(Frame frame, Object... args) { + throw new UnsupportedOperationException(); + } + + protected final Object uninitialized(Frame frame) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + SpecializationNode newNode = atomic(new InsertionEvent0(this, "insert new specialization", frame)); + if (newNode == null) { + return unsupported(frame); + } + return newNode.acceptAndExecute(frame); + } + + protected final Object uninitialized(Frame frame, Object o1) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + SpecializationNode newNode = atomic(new InsertionEvent1(this, "insert new specialization", frame, o1)); + if (newNode == null) { + return unsupported(frame, o1); + } + return newNode.acceptAndExecute(frame, o1); + } + + protected final Object uninitialized(Frame frame, Object o1, Object o2) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + SpecializationNode newNode = atomic(new InsertionEvent2(this, "insert new specialization", frame, o1, o2)); + if (newNode == null) { + return unsupported(frame, o1, o2); + } + return newNode.acceptAndExecute(frame, o1, o2); + } + + protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + SpecializationNode newNode = atomic(new InsertionEvent3(this, "insert new specialization", frame, o1, o2, o3)); + if (newNode == null) { + return unsupported(frame, o1, o2, o3); + } + return newNode.acceptAndExecute(frame, o1, o2, o3); + } + + protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3, Object o4) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + SpecializationNode newNode = atomic(new InsertionEvent4(this, "insert new specialization", frame, o1, o2, o3, o4)); + if (newNode == null) { + return unsupported(frame, o1, o2, o3, o4); + } + return newNode.acceptAndExecute(frame, o1, o2, o3, o4); + } + + protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + SpecializationNode newNode = atomic(new InsertionEvent5(this, "insert new specialization", frame, o1, o2, o3, o4, o5)); + if (newNode == null) { + return unsupported(frame, o1, o2, o3, o4, o5); + } + return newNode.acceptAndExecute(frame, o1, o2, o3, o4, o5); + } + + protected final Object uninitialized(Frame frame, Object... args) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + SpecializationNode newNode = atomic(new InsertionEventN(this, "insert new specialization", frame, args)); + if (newNode == null) { + return unsupported(frame, args); + } + return newNode.acceptAndExecute(frame, args); + } + + protected final Object remove(String reason, Frame frame) { + return atomic(new RemoveEvent0(this, reason, frame)).acceptAndExecute(frame); + } + + protected final Object remove(String reason, Frame frame, Object o1) { + return atomic(new RemoveEvent1(this, reason, frame, o1)).acceptAndExecute(frame, o1); + } + + protected final Object remove(String reason, Frame frame, Object o1, Object o2) { + return atomic(new RemoveEvent2(this, reason, frame, o1, o2)).acceptAndExecute(frame, o1, o2); + } + + protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3) { + return atomic(new RemoveEvent3(this, reason, frame, o1, o2, o3)).acceptAndExecute(frame, o1, o2, o3); + } + + protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { + return atomic(new RemoveEvent4(this, reason, frame, o1, o2, o3, o4)).acceptAndExecute(frame, o1, o2, o3, o4); + } + + protected final Object remove(String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + return atomic(new RemoveEvent5(this, reason, frame, o1, o2, o3, o4, o5)).acceptAndExecute(frame, o1, o2, o3, o4, o5); + } + + protected final Object remove(String reason, Frame frame, Object... args) { + return atomic(new RemoveEventN(this, reason, frame, args)).acceptAndExecute(frame, args); + } + + protected Object unsupported(Frame frame) { + throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren()); + } + + protected Object unsupported(Frame frame, Object o1) { + throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1); + } + + protected Object unsupported(Frame frame, Object o1, Object o2) { + throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1, o2); + } + + protected Object unsupported(Frame frame, Object o1, Object o2, Object o3) { + throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1, o2, o3); + } + + protected Object unsupported(Frame frame, Object o1, Object o2, Object o3, Object o4) { + throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1, o2, o3, o4); + } + + protected Object unsupported(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), o1, o2, o3, o4, o5); + } + + protected Object unsupported(Frame frame, Object... args) { + throw new UnsupportedSpecializationException(findRoot(), getSuppliedChildren(), args); + } + + static SpecializationNode insertSorted(SpecializationNode start, final SpecializationNode generated, final CharSequence message, final SpecializationNode merged) { + if (merged == generated) { + // new node + if (start.count() == 2) { + SpecializationNode polymorphic = start.createPolymorphic(); + /* + * For nodes with all parameters evaluated in the execute method we do not need a + * polymorphic node. the generated code returns null in createPolymorphic in this + * case. + */ + if (polymorphic != null) { + insertAt(start, polymorphic, "insert polymorphic"); + } + } + SpecializationNode current = start; + while (current != null && current.index < generated.index) { + current = current.next; + } + return insertAt(current, generated, message); + } else { + // existing node + return start; + } + } + + static <T> SpecializationNode insertAt(SpecializationNode node, SpecializationNode insertBefore, CharSequence reason) { + insertBefore.next = node; + // always guaranteed to be executed inside of an atomic block + return NodeUtil.nonAtomicReplace(node, insertBefore, reason); + } + + @Override + public final String toString() { + Class<?> clazz = getClass(); + StringBuilder b = new StringBuilder(); + b.append(clazz.getSimpleName()); + + appendFields(b, clazz); + if (next != null) { + b.append("\n -> ").append(next.toString()); + } + return b.toString(); + } + + private void appendFields(StringBuilder b, Class<?> clazz) { + Field[] fields = clazz.getDeclaredFields(); + if (fields.length == 0) { + return; + } + b.append("("); + String sep = ""; + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + b.append(sep); + String name = field.getName(); + if (name.equals("root")) { + continue; + } + b.append(field.getName()); + b.append(" = "); + try { + field.setAccessible(true); + Object value = field.get(this); + if (value instanceof Object[]) { + b.append(Arrays.toString((Object[]) field.get(this))); + } else { + b.append(field.get(this)); + } + } catch (IllegalArgumentException e) { + b.append(e.toString()); + } catch (IllegalAccessException e) { + b.append(e.toString()); + } + sep = ", "; + } + b.append(")"); + } + + protected static void check(Assumption assumption) throws InvalidAssumptionException { + if (assumption != null) { + assumption.check(); + } + } + + @ExplodeLoop + protected static void check(Assumption[] assumptions) throws InvalidAssumptionException { + if (assumptions != null) { + CompilerAsserts.compilationConstant(assumptions.length); + for (Assumption assumption : assumptions) { + check(assumption); + } + } + } + + protected static boolean isValid(Assumption assumption) { + if (assumption != null) { + return assumption.isValid(); + } + return true; + } + + protected static boolean isValid(Assumption[] assumptions) { + if (assumptions != null) { + for (Assumption assumption : assumptions) { + if (!isValid(assumption)) { + return false; + } + } + } + return true; + } + + private static final class InsertionEvent0 extends SlowPathEvent0 implements Callable<SpecializationNode> { + + public InsertionEvent0(SpecializationNode source, String reason, Frame frame) { + super(source, reason, frame); + } + + public SpecializationNode call() throws Exception { + SpecializationNode next = source.createNext(frame); + if (next == null) { + next = source.createFallback(); + } + if (next == null) { + return null; + } + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame)); + } + } + + } + + private static final class InsertionEvent1 extends SlowPathEvent1 implements Callable<SpecializationNode> { + + public InsertionEvent1(SpecializationNode source, String reason, Frame frame, Object o1) { + super(source, reason, frame, o1); + } + + public SpecializationNode call() throws Exception { + SpecializationNode next = source.createNext(frame, o1); + if (next == null) { + next = source.createFallback(); + } + if (next == null) { + return null; + } + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1)); + } + } + + } + + private static final class InsertionEvent2 extends SlowPathEvent2 implements Callable<SpecializationNode> { + + public InsertionEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2) { + super(source, reason, frame, o1, o2); + } + + public SpecializationNode call() throws Exception { + SpecializationNode next = source.createNext(frame, o1, o2); + if (next == null) { + next = source.createFallback(); + } + if (next == null) { + return null; + } + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1, o2)); + } + } + + } + + private static final class InsertionEvent3 extends SlowPathEvent3 implements Callable<SpecializationNode> { + + public InsertionEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3) { + super(source, reason, frame, o1, o2, o3); + } + + public SpecializationNode call() throws Exception { + SpecializationNode next = source.createNext(frame, o1, o2, o3); + if (next == null) { + next = source.createFallback(); + } + if (next == null) { + return null; + } + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3)); + } + } + + } + + private static final class InsertionEvent4 extends SlowPathEvent4 implements Callable<SpecializationNode> { + + public InsertionEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { + super(source, reason, frame, o1, o2, o3, o4); + } + + public SpecializationNode call() throws Exception { + SpecializationNode next = source.createNext(frame, o1, o2, o3, o4); + if (next == null) { + next = source.createFallback(); + } + if (next == null) { + return null; + } + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3, o4)); + } + } + + } + + private static final class InsertionEvent5 extends SlowPathEvent5 implements Callable<SpecializationNode> { + + public InsertionEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + super(source, reason, frame, o1, o2, o3, o4, o5); + } + + public SpecializationNode call() throws Exception { + SpecializationNode next = source.createNext(frame, o1, o2, o3, o4, o5); + if (next == null) { + next = source.createFallback(); + } + if (next == null) { + return null; + } + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, o1, o2, o3, o4, o5)); + } + } + + } + + private static final class InsertionEventN extends SlowPathEventN implements Callable<SpecializationNode> { + + public InsertionEventN(SpecializationNode source, String reason, Frame frame, Object[] args) { + super(source, reason, frame, args); + } + + public SpecializationNode call() throws Exception { + SpecializationNode next = source.createNext(frame, args); + if (next == null) { + next = source.createFallback(); + } + if (next == null) { + return null; + } + SpecializationNode start = source.findStart(); + if (start.index == Integer.MAX_VALUE) { + return insertAt(start, next, this); + } else { + return insertSorted(start, next, this, start.merge(next, frame, args)); + } + } + } + + private static final class RemoveEvent0 extends SlowPathEvent0 implements Callable<SpecializationNode> { + + public RemoveEvent0(SpecializationNode source, String reason, Frame frame) { + super(source, reason, frame); + } + + public SpecializationNode call() throws Exception { + return source.removeSame(this); + } + + } + + private static final class RemoveEvent1 extends SlowPathEvent1 implements Callable<SpecializationNode> { + + public RemoveEvent1(SpecializationNode source, String reason, Frame frame, Object o1) { + super(source, reason, frame, o1); + } + + public SpecializationNode call() throws Exception { + return source.removeSame(this); + } + + } + + private static final class RemoveEvent2 extends SlowPathEvent2 implements Callable<SpecializationNode> { + + public RemoveEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2) { + super(source, reason, frame, o1, o2); + } + + public SpecializationNode call() throws Exception { + return source.removeSame(this); + } + + } + + private static final class RemoveEvent3 extends SlowPathEvent3 implements Callable<SpecializationNode> { + + public RemoveEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3) { + super(source, reason, frame, o1, o2, o3); + } + + public SpecializationNode call() throws Exception { + return source.removeSame(this); + } + + } + + private static final class RemoveEvent4 extends SlowPathEvent4 implements Callable<SpecializationNode> { + + public RemoveEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) { + super(source, reason, frame, o1, o2, o3, o4); + } + + public SpecializationNode call() throws Exception { + return source.removeSame(this); + } + + } + + private static final class RemoveEvent5 extends SlowPathEvent5 implements Callable<SpecializationNode> { + + public RemoveEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) { + super(source, reason, frame, o1, o2, o3, o4, o5); + } + + public SpecializationNode call() throws Exception { + return source.removeSame(this); + } + + } + + private static final class RemoveEventN extends SlowPathEventN implements Callable<SpecializationNode> { + + public RemoveEventN(SpecializationNode source, String reason, Frame frame, Object[] args) { + super(source, reason, frame, args); + } + + public SpecializationNode call() throws Exception { + return source.removeSame(this); + } + } + +}