# HG changeset patch # User kvn # Date 1373662897 25200 # Node ID c90c698831d7cadcd4041674ec5a4850af6a942d # Parent dec841e0c9aaa12e9bfa0c8a943c88047e3f7737 8020215: Different execution plan when using JIT vs interpreter Summary: fix bytecode analyzer Reviewed-by: twisti diff -r dec841e0c9aa -r c90c698831d7 src/share/vm/ci/bcEscapeAnalyzer.cpp --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Wed Jul 10 13:33:56 2013 -0700 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Jul 12 14:01:37 2013 -0700 @@ -138,6 +138,16 @@ return false; } +// return true if all argument elements of vars are returned +bool BCEscapeAnalyzer::returns_all(ArgumentMap vars) { + for (int i = 0; i < _arg_size; i++) { + if (vars.contains(i) && !_arg_returned.test(i)) { + return false; + } + } + return true; +} + void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) { for (int i = 0; i < _arg_size; i++) { if (vars.contains(i)) { @@ -166,6 +176,11 @@ if (vars.contains_unknown() || vars.contains_vars()) { _return_allocated = false; } + if (_return_local && vars.contains_vars() && !returns_all(vars)) { + // Return result should be invalidated if args in new + // state are not recorded in return state. + _return_local = false; + } } } diff -r dec841e0c9aa -r c90c698831d7 src/share/vm/ci/bcEscapeAnalyzer.hpp --- a/src/share/vm/ci/bcEscapeAnalyzer.hpp Wed Jul 10 13:33:56 2013 -0700 +++ b/src/share/vm/ci/bcEscapeAnalyzer.hpp Fri Jul 12 14:01:37 2013 -0700 @@ -80,6 +80,7 @@ void set_returned(ArgumentMap vars); bool is_argument(ArgumentMap vars); bool is_arg_stack(ArgumentMap vars); + bool returns_all(ArgumentMap vars); void clear_bits(ArgumentMap vars, VectorSet &bs); void set_method_escape(ArgumentMap vars); void set_global_escape(ArgumentMap vars, bool merge = false); diff -r dec841e0c9aa -r c90c698831d7 test/compiler/EscapeAnalysis/Test8020215.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/EscapeAnalysis/Test8020215.java Fri Jul 12 14:01:37 2013 -0700 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, 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. + * + * 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 8020215 + * @summary Different execution plan when using JIT vs interpreter + * @run main Test8020215 + */ + +import java.util.ArrayList; +import java.util.List; + +public class Test8020215 { + public static class NamedObject { + public int id; + public String name; + public NamedObject(int id, String name) { + this.id = id; + this.name = name; + } + } + + public static class NamedObjectList { + public List namedObjectList = new ArrayList(); + + public NamedObject getBest(int id) { + NamedObject bestObject = null; + for (NamedObject o : namedObjectList) { + bestObject = id==o.id ? getBetter(bestObject, o) : bestObject; + } + return (bestObject != null) ? bestObject : null; + } + + private static NamedObject getBetter(NamedObject p1, NamedObject p2) { + return (p1 == null) ? p2 : (p2 == null) ? p1 : (p2.name.compareTo(p1.name) >= 0) ? p2 : p1; + } + } + + static void test(NamedObjectList b, int i) { + NamedObject x = b.getBest(2); + // test + if (x == null) { + throw new RuntimeException("x should never be null here! (i=" + i + ")"); + } + } + + public static void main(String[] args) { + // setup + NamedObjectList b = new NamedObjectList(); + for (int i = 0; i < 10000; i++) { + b.namedObjectList.add(new NamedObject(1, "2012-12-31")); + } + b.namedObjectList.add(new NamedObject(2, "2013-12-31")); + + // execution + for (int i = 0; i < 12000; i++) { + test(b, i); + } + System.out.println("PASSED"); + } +}