public T call() { assert getNext(oldNode) == null; assert getPrevious(oldNode) == null; assert newNodeDSL != null; Node uninitialized = (Node) uninitializedDSL; Node newNode = (Node) newNodeDSL; polymorphic.adoptChildren0(oldNode, (Node) currentCopy); updateSourceSection(oldNode, uninitialized); // new specialization updateSourceSection(oldNode, newNode); newNodeDSL.adoptChildren0(null, uninitialized); currentCopy.adoptChildren0(null, newNode); oldNode.replace(polymorphic, message); assert newNode != null ? currentCopy.getNext0() == newNode : currentCopy.getNext0() == uninitialized; assert uninitializedDSL.getNext0() == null; return polymorphic; } });
private static <T extends Node & DSLNode> T appendPolymorphic(Node uninitialized, T newNode) { Class<?>[] includes = newNode.getMetadata0().getIncludes(); Node cur = getPrevious(uninitialized); Node prev = uninitialized; int depth = 0; Class<?>[] types = null; while (cur != null) { if (containsClass(includes, cur)) { cur.replace(prev, "Included in other specialization"); cur = prev; } else { depth++; types = mergeTypes((DSLNode) cur, types); } prev = cur; cur = getPrevious(cur); } assert prev.getCost() == NodeCost.POLYMORPHIC; updateSourceSection(prev, newNode); if (depth <= 1) { newNode.adoptChildren0(prev, null); return prev.replace(newNode, "Polymorphic to monomorphic."); } else { newNode.adoptChildren0(null, uninitialized); ((DSLNode) prev).updateTypes0(mergeTypes(newNode, types)); return uninitialized.replace(newNode, "Appended polymorphic"); } }
public T call() { Node prev = getPrevious(uninitialized); if (prev == null) { newNode.adoptChildren0(uninitialized, null); return uninitialized.replace(newNode, "Uninitialized monomorphic"); } else { return appendPolymorphic(uninitialized, newNode); } } });
private static Class<?>[] mergeTypes(DSLNode node, Class<?>[] types) { Class<?>[] specializedTypes = node.getMetadata0().getSpecializedTypes(); if (specializedTypes.length == 0) { return null; } else if (types == null) { return Arrays.copyOf(specializedTypes, specializedTypes.length); } else { for (int i = 0; i < specializedTypes.length; i++) { if (specializedTypes[i] != types[i]) { types[i] = Object.class; } } return types; } }
private static Node getNext(Node node) { return ((DSLNode) node).getNext0(); }
public T call() { assert newNode != null; if (getNext(thisNode) != null || getPrevious(thisNode) != null) { // already polymorphic -> append return appendPolymorphic(findUninitialized(thisNode), newNode); } else if (includes(thisNode, newNode)) { // included -> remains monomorphic newNode.adoptChildren0(thisNode, null); return thisNode.replace(newNode, message); } else { // goto polymorphic return null; } } });
private static boolean includes(Node oldNode, DSLNode newNode) { return containsClass(newNode.getMetadata0().getIncludes(), oldNode); }