# HG changeset patch # User lana # Date 1437690465 25200 # Node ID 827915d1e55eac4f2e138f9b8c79d154862c2284 # Parent 4b7f5ea468d1a6de8599fd94f4162a83a8a518e2# Parent 70c852df047c280475b940c1a51d2ef0384d8602 Merge diff -r 4b7f5ea468d1 -r 827915d1e55e src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java Thu Jul 23 11:54:33 2015 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java Thu Jul 23 15:27:45 2015 -0700 @@ -151,32 +151,57 @@ * directed graph in linear time. Works on TarjanNode. */ public static > List> tarjan(Iterable nodes) { - ListBuffer> cycles = new ListBuffer<>(); - ListBuffer stack = new ListBuffer<>(); + Tarjan tarjan = new Tarjan<>(); + return tarjan.findSCC(nodes); + } + //where + private static class Tarjan> { + + /** Unique node identifier. */ int index = 0; - for (N node: nodes) { - if (node.index == -1) { - index += tarjan(node, index, stack, cycles); + + /** List of SCCs found fso far. */ + ListBuffer> sccs = new ListBuffer<>(); + + /** Stack of all reacheable nodes from given root. */ + ListBuffer stack = new ListBuffer<>(); + + private List> findSCC(Iterable nodes) { + for (N node : nodes) { + if (node.index == -1) { + findSCC(node); + } + } + return sccs.toList(); + } + + private void findSCC(N v) { + visitNode(v); + for (N n: v.getAllDependencies()) { + if (n.index == -1) { + //it's the first time we see this node + findSCC(n); + v.lowlink = Math.min(v.lowlink, n.lowlink); + } else if (stack.contains(n)) { + //this node is already reachable from current root + v.lowlink = Math.min(v.lowlink, n.index); + } + } + if (v.lowlink == v.index) { + //v is the root of a SCC + addSCC(v); } } - return cycles.toList(); - } - private static > int tarjan(N v, int index, ListBuffer stack, ListBuffer> cycles) { - v.index = index; - v.lowlink = index; - index++; - stack.prepend(v); - v.active = true; - for (N n: v.getAllDependencies()) { - if (n.index == -1) { - tarjan(n, index, stack, cycles); - v.lowlink = Math.min(v.lowlink, n.lowlink); - } else if (stack.contains(n)) { - v.lowlink = Math.min(v.lowlink, n.index); - } + private void visitNode(N n) { + n.index = index; + n.lowlink = index; + index++; + stack.prepend(n); + n.active = true; } - if (v.lowlink == v.index) { + + private void addSCC(N v) { N n; ListBuffer cycle = new ListBuffer<>(); do { @@ -184,9 +209,8 @@ n.active = false; cycle.add(n); } while (n != v); - cycles.add(cycle.toList()); + sccs.add(cycle.toList()); } - return index; } /** diff -r 4b7f5ea468d1 -r 827915d1e55e test/tools/javac/generics/inference/8130304/T8130304.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/8130304/T8130304.java Thu Jul 23 15:27:45 2015 -0700 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015, 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. + */ + +/** + * @test + * @bug 8130304 + * @summary Inference: NodeNotFoundException thrown with deep generic method call chain + * @compile T8130304.java + */ +class T8130304 { + + void test() { + outer( + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner(), + inner()); + } + + void outer(T... ts) { } + + T inner() { + return null; + } +}