public static SpecializationGroup create(List<SpecializationData> specializations) { List<SpecializationGroup> groups = new ArrayList<>(); for (SpecializationData specialization : specializations) { groups.add(new SpecializationGroup(specialization)); } SpecializationGroup group1 = new SpecializationGroup(createCombinationalGroups(groups), Collections.<TypeGuard> emptyList(), Collections.<GuardExpression> emptyList()); SpecializationGroup group = group1; // trim groups while (group.isEmpty() && group.getChildren().size() == 1) { group = group.getChildren().iterator().next(); } return group; }
private SpecializationGroup createSpecializationGroups() { return SpecializationGroup.create(reachableSpecializations); }
private static boolean isReachableGroup(SpecializationGroup group, int ifCount) { if (ifCount != 0) { return true; } SpecializationGroup previous = group.getPreviousGroup(); if (previous == null || previous.findElseConnectableGuards().isEmpty()) { return true; } /* * Hacky else case. In this case the specialization is not reachable due to previous else * branch. This is only true if the minimum state is not checked. */ if (previous.getGuards().size() == 1 && previous.getTypeGuards().isEmpty() && (previous.getParent() == null || previous.getMaxSpecializationIndex() != previous.getParent().getMaxSpecializationIndex())) { return false; } return true; }
public boolean isLast() { SpecializationGroup p = getParent(); if (p == null) { return true; } if (p.getChildren().indexOf(this) == p.getChildren().size() - 1) { return p.isLast(); } return false; }
public SpecializationGroup getPrevious() { if (getParent() == null) { return null; } List<SpecializationGroup> parentChildren = getParent().getChildren(); int index = parentChildren.indexOf(this); if (index <= 0) { return null; } return parentChildren.get(index - 1); } }
private boolean hasFallthrough(SpecializationGroup group, TypeMirror forType, LocalContext currentValues, boolean fastPath, List<GuardExpression> ignoreGuards) { for (TypeGuard guard : group.getTypeGuards()) { if (currentValues.getValue(guard.getSignatureIndex()) == null) { List<GuardExpression> guards = new ArrayList<>(group.getGuards()); List<GuardExpression> elseConnectable = group.findElseConnectableGuards(); guards.removeAll(elseConnectable); if (ignoreGuards != null) { guards.removeAll(ignoreGuards); SpecializationData specialization = group.getSpecialization(); if (specialization != null && fastPath) { for (ListIterator<GuardExpression> iterator = guards.listIterator(); iterator.hasNext();) { SpecializationGroup previous = group.getPrevious(); if (previous != null && hasFallthrough(previous, forType, currentValues, fastPath, previous.getGuards())) { return true; List<SpecializationGroup> groupChildren = group.getChildren(); if (!groupChildren.isEmpty()) { return hasFallthrough(groupChildren.get(groupChildren.size() - 1), forType, currentValues, fastPath, ignoreGuards);
boolean hasImplicitCast = false; List<IfTriple> cachedTriples = new ArrayList<>(); for (TypeGuard guard : group.getTypeGuards()) { IfTriple triple = createTypeCheckOrCast(frameState, group, guard, mode, false, true); if (triple != null) { SpecializationData specialization = group.getSpecialization(); SpecializationData[] specializations = group.collectSpecializations().toArray(new SpecializationData[0]); List<GuardExpression> guardExpressions = new ArrayList<>(group.getGuards()); final boolean stateGuaranteed = group.isLast() && allowedSpecializations != null && allowedSpecializations.size() == 1 && group.getAllSpecializations().size() == allowedSpecializations.size(); if ((!group.isEmpty() || specialization != null)) { CodeTree stateCheck = state.createContains(frameState, specializations); CodeTree stateGuard = null; for (SpecializationGroup child : group.getChildren()) { if (prev != null && !prev.hasFallthrough()) { break; if (specialization != null && (prev == null || prev.hasFallthrough())) { builder.tree(createFastPathExecute(builder, forType, specialization, frameState)); for (SpecializationGroup child : group.getChildren()) { if (prev != null && !prev.hasFallthrough()) { break; for (SpecializationGroup child : group.getChildren()) { if (prev != null && !prev.hasFallthrough()) {
private List<GuardExpression> findElseConnectableGuards() { if (!getTypeGuards().isEmpty()) { return Collections.emptyList(); } if (getGuards().isEmpty()) { return Collections.emptyList(); } List<GuardExpression> elseConnectableGuards = new ArrayList<>(); int guardIndex = 0; while (guardIndex < getGuards().size() && findNegatedGuardInPrevious(getGuards().get(guardIndex)) != null) { elseConnectableGuards.add(getGuards().get(guardIndex)); guardIndex++; } return elseConnectableGuards; }
private GuardExpression findNegatedGuardInPrevious(GuardExpression guard) { SpecializationGroup previous = this.getPreviousGroup(); if (previous == null) { return null; } List<GuardExpression> elseConnectedGuards = previous.findElseConnectableGuards(); if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { return null; } /* Guard is else branch can be connected in previous specialization. */ if (elseConnectedGuards.contains(guard)) { return guard; } GuardExpression previousGuard = previous.getGuards().get(elseConnectedGuards.size()); if (guard.equalsNegated(previousGuard)) { return guard; } return null; }
private static List<SpecializationGroup> createCombinationalGroups(List<SpecializationGroup> groups) { if (groups.size() <= 1) { return groups; } List<SpecializationGroup> newGroups = new ArrayList<>(); int i = 0; for (i = 0; i < groups.size();) { SpecializationGroup combined = null; for (int j = groups.size(); j > i + 1; j--) { combined = combine(groups.subList(i, j)); if (combined != null) { break; } } SpecializationGroup newGroup; if (combined == null) { newGroup = groups.get(i); i++; } else { newGroup = combined; List<SpecializationGroup> originalGroups = new ArrayList<>(combined.children); combined.updateChildren(createCombinationalGroups(originalGroups)); i += originalGroups.size(); } newGroups.add(newGroup); } return newGroups; }
private boolean isTypeGuardUsedInAnyGuardOrCacheBelow(SpecializationGroup group, LocalContext currentValues, TypeGuard typeGuard, boolean fastPath) { String localName = currentValues.getValue(typeGuard.getSignatureIndex()).getName(); SpecializationData specialization = group.getSpecialization(); for (GuardExpression guard : group.getGuards()) { if (isVariableBoundIn(specialization, guard.getExpression(), localName, currentValues)) { return true; } } if (!fastPath && specialization != null) { for (CacheExpression cache : specialization.getCaches()) { if (isVariableBoundIn(specialization, cache.getExpression(), localName, currentValues)) { return true; } } } for (SpecializationGroup child : group.getChildren()) { if (isTypeGuardUsedInAnyGuardOrCacheBelow(child, currentValues, typeGuard, fastPath)) { return true; } } return false; }
public int getMaxSpecializationIndex() { if (specialization != null) { return specialization.getNode().getSpecializations().indexOf(specialization); } else { int max = Integer.MIN_VALUE; for (SpecializationGroup childGroup : getChildren()) { max = Math.max(max, childGroup.getMaxSpecializationIndex()); } return max; } }
public int getUncheckedSpecializationIndex() { int groupMaxIndex = getMaxSpecializationIndex(); int genericIndex = node.getSpecializations().indexOf(node.getGenericSpecialization()); if (groupMaxIndex >= genericIndex) { // no minimum state check for an generic index groupMaxIndex = -1; } if (groupMaxIndex > -1) { // no minimum state check if already checked by parent group int parentMaxIndex = -1; if (getParent() != null) { parentMaxIndex = getParent().getMaxSpecializationIndex(); } if (groupMaxIndex == parentMaxIndex) { groupMaxIndex = -1; } } return groupMaxIndex; }
public static SpecializationGroup create(List<SpecializationData> specializations) { List<SpecializationGroup> groups = new ArrayList<>(); for (SpecializationData specialization : specializations) { groups.add(new SpecializationGroup(specialization)); } return new SpecializationGroup(createCombinationalGroups(groups), Collections.<TypeGuard> emptyList(), Collections.<GuardExpression> emptyList()); }
builder.startReturn().tree(createCallDelegate("uninitialized", null, executableType, currentLocals)).end(); } else { SpecializationGroup group = SpecializationGroup.create(specialization); SpecializationBody executionFactory = new SpecializationBody(true, true) { @Override if (hasFallthrough(group, returnType, originalValues, true, null) || group.getSpecialization().isFallback()) { builder.tree(createCallNext(builder, executableType, node.getGenericExecutableType(executableType), originalValues));
public static SpecializationGroup create(SpecializationData specialization) { return new SpecializationGroup(specialization); }
List<SpecializationData> allSpecializations = group.collectSpecializations(); List<Set<TypeGuard>> signatures = new ArrayList<>(); List<List<SpecializationData>> signatureSpecializations = new ArrayList<>(); groups.add(new BoxingSplit(SpecializationGroup.create(groupedSpecialization), signatureMirrors));
public List<TypeGuard> getAllGuards() { List<TypeGuard> collectedGuards = new ArrayList<>(); collectedGuards.addAll(typeGuards); if (parent != null) { collectedGuards.addAll(parent.getAllGuards()); } return collectedGuards; }
for (TypeGuard castGuard : group.getTypeGuards()) { if (isTypeGuardUsedInAnyGuardOrCacheBelow(group, currentValues, castGuard, execution.isFastPath())) { castGuards.add(castGuard); SpecializationData specialization = group.getSpecialization(); CodeTree[] checkAndCast = createTypeCheckAndLocals(specialization, group.getTypeGuards(), castGuards, currentValues, execution); List<GuardExpression> elseGuardExpressions = group.findElseConnectableGuards(); List<GuardExpression> guardExpressions = new ArrayList<>(group.getGuards()); guardExpressions.removeAll(elseGuardExpressions); CodeTree[] methodGuardAndAssertions = createMethodGuardCheck(guardExpressions, specialization, currentValues, execution.isFastPath()); for (SpecializationGroup child : group.getChildren()) { builder.tree(createGuardAndCast(child, forType, currentValues.copy(), execution));
public List<GuardExpression> findElseConnectableGuards() { if (!getTypeGuards().isEmpty()) { return Collections.emptyList(); } if (getGuards().isEmpty()) { return Collections.emptyList(); } List<GuardExpression> elseConnectableGuards = new ArrayList<>(); int guardIndex = 0; while (guardIndex < getGuards().size() && findNegatedGuardInPrevious(getGuards().get(guardIndex)) != null) { elseConnectableGuards.add(getGuards().get(guardIndex)); guardIndex++; } return elseConnectableGuards; }