Merge

Mon, 15 Jul 2013 06:27:46 -0700

author
morris
date
Mon, 15 Jul 2013 06:27:46 -0700
changeset 5438
34ce0b5acb81
parent 5397
bd1dc81da579
parent 5437
fcf521c3fbc6
child 5439
0f57ccdb9084

Merge

     1.1 --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp	Fri Jul 12 17:08:52 2013 -0700
     1.2 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp	Mon Jul 15 06:27:46 2013 -0700
     1.3 @@ -138,6 +138,16 @@
     1.4    return false;
     1.5  }
     1.6  
     1.7 +// return true if all argument elements of vars are returned
     1.8 +bool BCEscapeAnalyzer::returns_all(ArgumentMap vars) {
     1.9 +  for (int i = 0; i < _arg_size; i++) {
    1.10 +    if (vars.contains(i) && !_arg_returned.test(i)) {
    1.11 +      return false;
    1.12 +    }
    1.13 +  }
    1.14 +  return true;
    1.15 +}
    1.16 +
    1.17  void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) {
    1.18    for (int i = 0; i < _arg_size; i++) {
    1.19      if (vars.contains(i)) {
    1.20 @@ -166,6 +176,11 @@
    1.21      if (vars.contains_unknown() || vars.contains_vars()) {
    1.22        _return_allocated = false;
    1.23      }
    1.24 +    if (_return_local && vars.contains_vars() && !returns_all(vars)) {
    1.25 +      // Return result should be invalidated if args in new
    1.26 +      // state are not recorded in return state.
    1.27 +      _return_local = false;
    1.28 +    }
    1.29    }
    1.30  }
    1.31  
     2.1 --- a/src/share/vm/ci/bcEscapeAnalyzer.hpp	Fri Jul 12 17:08:52 2013 -0700
     2.2 +++ b/src/share/vm/ci/bcEscapeAnalyzer.hpp	Mon Jul 15 06:27:46 2013 -0700
     2.3 @@ -80,6 +80,7 @@
     2.4    void set_returned(ArgumentMap vars);
     2.5    bool is_argument(ArgumentMap vars);
     2.6    bool is_arg_stack(ArgumentMap vars);
     2.7 +  bool returns_all(ArgumentMap vars);
     2.8    void clear_bits(ArgumentMap vars, VectorSet &bs);
     2.9    void set_method_escape(ArgumentMap vars);
    2.10    void set_global_escape(ArgumentMap vars, bool merge = false);
     3.1 --- a/src/share/vm/opto/matcher.cpp	Fri Jul 12 17:08:52 2013 -0700
     3.2 +++ b/src/share/vm/opto/matcher.cpp	Mon Jul 15 06:27:46 2013 -0700
     3.3 @@ -2305,26 +2305,26 @@
     3.4  // atomic instruction acting as a store_load barrier without any
     3.5  // intervening volatile load, and thus we don't need a barrier here.
     3.6  // We retain the Node to act as a compiler ordering barrier.
     3.7 -bool Matcher::post_store_load_barrier(const Node *vmb) {
     3.8 -  Compile *C = Compile::current();
     3.9 -  assert( vmb->is_MemBar(), "" );
    3.10 -  assert( vmb->Opcode() != Op_MemBarAcquire, "" );
    3.11 -  const MemBarNode *mem = (const MemBarNode*)vmb;
    3.12 +bool Matcher::post_store_load_barrier(const Node* vmb) {
    3.13 +  Compile* C = Compile::current();
    3.14 +  assert(vmb->is_MemBar(), "");
    3.15 +  assert(vmb->Opcode() != Op_MemBarAcquire, "");
    3.16 +  const MemBarNode* membar = vmb->as_MemBar();
    3.17  
    3.18 -  // Get the Proj node, ctrl, that can be used to iterate forward
    3.19 -  Node *ctrl = NULL;
    3.20 -  DUIterator_Fast imax, i = mem->fast_outs(imax);
    3.21 -  while( true ) {
    3.22 -    ctrl = mem->fast_out(i);            // Throw out-of-bounds if proj not found
    3.23 -    assert( ctrl->is_Proj(), "only projections here" );
    3.24 -    ProjNode *proj = (ProjNode*)ctrl;
    3.25 -    if( proj->_con == TypeFunc::Control &&
    3.26 -        !C->node_arena()->contains(ctrl) ) // Unmatched old-space only
    3.27 +  // Get the Ideal Proj node, ctrl, that can be used to iterate forward
    3.28 +  Node* ctrl = NULL;
    3.29 +  for (DUIterator_Fast imax, i = membar->fast_outs(imax); i < imax; i++) {
    3.30 +    Node* p = membar->fast_out(i);
    3.31 +    assert(p->is_Proj(), "only projections here");
    3.32 +    if ((p->as_Proj()->_con == TypeFunc::Control) &&
    3.33 +        !C->node_arena()->contains(p)) { // Unmatched old-space only
    3.34 +      ctrl = p;
    3.35        break;
    3.36 -    i++;
    3.37 +    }
    3.38    }
    3.39 +  assert((ctrl != NULL), "missing control projection");
    3.40  
    3.41 -  for( DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++ ) {
    3.42 +  for (DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++) {
    3.43      Node *x = ctrl->fast_out(j);
    3.44      int xop = x->Opcode();
    3.45  
    3.46 @@ -2336,37 +2336,36 @@
    3.47      // that a monitor exit operation contains a serializing instruction.
    3.48  
    3.49      if (xop == Op_MemBarVolatile ||
    3.50 -        xop == Op_FastLock ||
    3.51          xop == Op_CompareAndSwapL ||
    3.52          xop == Op_CompareAndSwapP ||
    3.53          xop == Op_CompareAndSwapN ||
    3.54 -        xop == Op_CompareAndSwapI)
    3.55 +        xop == Op_CompareAndSwapI) {
    3.56        return true;
    3.57 +    }
    3.58 +
    3.59 +    // Op_FastLock previously appeared in the Op_* list above.
    3.60 +    // With biased locking we're no longer guaranteed that a monitor
    3.61 +    // enter operation contains a serializing instruction.
    3.62 +    if ((xop == Op_FastLock) && !UseBiasedLocking) {
    3.63 +      return true;
    3.64 +    }
    3.65  
    3.66      if (x->is_MemBar()) {
    3.67        // We must retain this membar if there is an upcoming volatile
    3.68 -      // load, which will be preceded by acquire membar.
    3.69 -      if (xop == Op_MemBarAcquire)
    3.70 +      // load, which will be followed by acquire membar.
    3.71 +      if (xop == Op_MemBarAcquire) {
    3.72          return false;
    3.73 -      // For other kinds of barriers, check by pretending we
    3.74 -      // are them, and seeing if we can be removed.
    3.75 -      else
    3.76 -        return post_store_load_barrier((const MemBarNode*)x);
    3.77 +      } else {
    3.78 +        // For other kinds of barriers, check by pretending we
    3.79 +        // are them, and seeing if we can be removed.
    3.80 +        return post_store_load_barrier(x->as_MemBar());
    3.81 +      }
    3.82      }
    3.83  
    3.84 -    // Delicate code to detect case of an upcoming fastlock block
    3.85 -    if( x->is_If() && x->req() > 1 &&
    3.86 -        !C->node_arena()->contains(x) ) { // Unmatched old-space only
    3.87 -      Node *iff = x;
    3.88 -      Node *bol = iff->in(1);
    3.89 -      // The iff might be some random subclass of If or bol might be Con-Top
    3.90 -      if (!bol->is_Bool())  return false;
    3.91 -      assert( bol->req() > 1, "" );
    3.92 -      return (bol->in(1)->Opcode() == Op_FastUnlock);
    3.93 +    // probably not necessary to check for these
    3.94 +    if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) {
    3.95 +      return false;
    3.96      }
    3.97 -    // probably not necessary to check for these
    3.98 -    if (x->is_Call() || x->is_SafePoint() || x->is_block_proj())
    3.99 -      return false;
   3.100    }
   3.101    return false;
   3.102  }
     4.1 --- a/src/share/vm/opto/parse3.cpp	Fri Jul 12 17:08:52 2013 -0700
     4.2 +++ b/src/share/vm/opto/parse3.cpp	Mon Jul 15 06:27:46 2013 -0700
     4.3 @@ -294,25 +294,7 @@
     4.4    // If reference is volatile, prevent following volatiles ops from
     4.5    // floating up before the volatile write.
     4.6    if (is_vol) {
     4.7 -    // First place the specific membar for THIS volatile index. This first
     4.8 -    // membar is dependent on the store, keeping any other membars generated
     4.9 -    // below from floating up past the store.
    4.10 -    int adr_idx = C->get_alias_index(adr_type);
    4.11 -    insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx, store);
    4.12 -
    4.13 -    // Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed
    4.14 -    // volatile alias indices. Skip this if the membar is redundant.
    4.15 -    if (adr_idx != Compile::AliasIdxBot) {
    4.16 -      insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot, store);
    4.17 -    }
    4.18 -
    4.19 -    // Finally, place alias-index-specific membars for each volatile index
    4.20 -    // that isn't the adr_idx membar. Typically there's only 1 or 2.
    4.21 -    for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) {
    4.22 -      if (i != adr_idx && C->alias_type(i)->is_volatile()) {
    4.23 -        insert_mem_bar_volatile(Op_MemBarVolatile, i, store);
    4.24 -      }
    4.25 -    }
    4.26 +    insert_mem_bar(Op_MemBarVolatile); // Use fat membar
    4.27    }
    4.28  
    4.29    // If the field is final, the rules of Java say we are in <init> or <clinit>.
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/compiler/EscapeAnalysis/Test8020215.java	Mon Jul 15 06:27:46 2013 -0700
     5.3 @@ -0,0 +1,82 @@
     5.4 +/*
     5.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.23 + * or visit www.oracle.com if you need additional information or have any
    5.24 + * questions.
    5.25 + */
    5.26 +
    5.27 +/*
    5.28 + * @test
    5.29 + * @bug 8020215
    5.30 + * @summary Different execution plan when using JIT vs interpreter
    5.31 + * @run main Test8020215
    5.32 + */
    5.33 +
    5.34 +import java.util.ArrayList;
    5.35 +import java.util.List;
    5.36 +
    5.37 +public class Test8020215 {
    5.38 +    public static class NamedObject {
    5.39 +        public int id;
    5.40 +        public String name;
    5.41 +        public NamedObject(int id, String name) {
    5.42 +            this.id = id;
    5.43 +            this.name = name;
    5.44 +        }
    5.45 +    }
    5.46 +
    5.47 +    public static class NamedObjectList {
    5.48 +        public List<NamedObject> namedObjectList = new ArrayList<NamedObject>();
    5.49 +
    5.50 +        public NamedObject getBest(int id) {
    5.51 +            NamedObject bestObject = null;
    5.52 +            for (NamedObject o : namedObjectList) {
    5.53 +                bestObject = id==o.id ? getBetter(bestObject, o) : bestObject;
    5.54 +            }
    5.55 +            return (bestObject != null) ? bestObject : null;
    5.56 +        }
    5.57 +
    5.58 +        private static NamedObject getBetter(NamedObject p1, NamedObject p2) {
    5.59 +            return (p1 == null) ? p2 : (p2 == null) ? p1 : (p2.name.compareTo(p1.name) >= 0) ? p2 : p1;
    5.60 +        }
    5.61 +    }
    5.62 +
    5.63 +    static void test(NamedObjectList b, int i) {
    5.64 +        NamedObject x = b.getBest(2);
    5.65 +        // test
    5.66 +        if (x == null) {
    5.67 +            throw new RuntimeException("x should never be null here! (i=" + i + ")");
    5.68 +        }
    5.69 +    }
    5.70 +
    5.71 +    public static void main(String[] args) {
    5.72 +        // setup
    5.73 +        NamedObjectList b = new NamedObjectList();
    5.74 +        for (int i = 0; i < 10000; i++) {
    5.75 +            b.namedObjectList.add(new NamedObject(1, "2012-12-31"));
    5.76 +        }
    5.77 +        b.namedObjectList.add(new NamedObject(2, "2013-12-31"));
    5.78 +
    5.79 +        // execution
    5.80 +        for (int i = 0; i < 12000; i++) {
    5.81 +            test(b, i);
    5.82 +        }
    5.83 +        System.out.println("PASSED");
    5.84 +    }
    5.85 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/compiler/membars/DekkerTest.java	Mon Jul 15 06:27:46 2013 -0700
     6.3 @@ -0,0 +1,163 @@
     6.4 +/*
     6.5 + * Copyright 2013 SAP AG.  All Rights Reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.
    6.11 + *
    6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.15 + * version 2 for more details (a copy is included in the LICENSE file that
    6.16 + * accompanied this code).
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License version
    6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.21 + *
    6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.23 + * or visit www.oracle.com if you need additional information or have any
    6.24 + * questions.
    6.25 + */
    6.26 +
    6.27 +/**
    6.28 + * @test
    6.29 + * @bug 8007898
    6.30 + * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
    6.31 + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
    6.32 + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
    6.33 + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
    6.34 + * @author Martin Doerr martin DOT doerr AT sap DOT com
    6.35 + *
    6.36 + * Run 3 times since the failure is intermittent.
    6.37 + */
    6.38 +
    6.39 +public class DekkerTest {
    6.40 +
    6.41 +    /*
    6.42 +      Read After Write Test (basically a simple Dekker test with volatile variables)
    6.43 +      Derived from the original jcstress test, available at:
    6.44 +        http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/
    6.45 +        tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java
    6.46 +     */
    6.47 +
    6.48 +    static final int ITERATIONS = 1000000;
    6.49 +
    6.50 +    static class TestData {
    6.51 +        public volatile int a;
    6.52 +        public volatile int b;
    6.53 +    }
    6.54 +
    6.55 +    static class ResultData {
    6.56 +        public int a;
    6.57 +        public int b;
    6.58 +    }
    6.59 +
    6.60 +    TestData[]   testDataArray;
    6.61 +    ResultData[] results;
    6.62 +
    6.63 +    volatile boolean start;
    6.64 +
    6.65 +    public DekkerTest() {
    6.66 +        testDataArray = new TestData[ITERATIONS];
    6.67 +        results = new ResultData[ITERATIONS];
    6.68 +        for (int i = 0; i < ITERATIONS; ++i) {
    6.69 +            testDataArray[i] = new TestData();
    6.70 +            results[i] = new ResultData();
    6.71 +        }
    6.72 +        start = false;
    6.73 +    }
    6.74 +
    6.75 +    public void reset() {
    6.76 +        for (int i = 0; i < ITERATIONS; ++i) {
    6.77 +            testDataArray[i].a = 0;
    6.78 +            testDataArray[i].b = 0;
    6.79 +            results[i].a = 0;
    6.80 +            results[i].b = 0;
    6.81 +        }
    6.82 +        start = false;
    6.83 +    }
    6.84 +
    6.85 +    int actor1(TestData t) {
    6.86 +        t.a = 1;
    6.87 +        return t.b;
    6.88 +    }
    6.89 +
    6.90 +    int actor2(TestData t) {
    6.91 +        t.b = 1;
    6.92 +        return t.a;
    6.93 +    }
    6.94 +
    6.95 +    class Runner1 extends Thread {
    6.96 +        public void run() {
    6.97 +            do {} while (!start);
    6.98 +            for (int i = 0; i < ITERATIONS; ++i) {
    6.99 +                results[i].a = actor1(testDataArray[i]);
   6.100 +            }
   6.101 +        }
   6.102 +    }
   6.103 +
   6.104 +    class Runner2 extends Thread {
   6.105 +        public void run() {
   6.106 +            do {} while (!start);
   6.107 +            for (int i = 0; i < ITERATIONS; ++i) {
   6.108 +                results[i].b = actor2(testDataArray[i]);
   6.109 +            }
   6.110 +        }
   6.111 +    }
   6.112 +
   6.113 +    void testRunner() {
   6.114 +        Thread thread1 = new Runner1();
   6.115 +        Thread thread2 = new Runner2();
   6.116 +        thread1.start();
   6.117 +        thread2.start();
   6.118 +        do {} while (!thread1.isAlive());
   6.119 +        do {} while (!thread2.isAlive());
   6.120 +        start = true;
   6.121 +        Thread.yield();
   6.122 +        try {
   6.123 +            thread1.join();
   6.124 +            thread2.join();
   6.125 +        } catch (InterruptedException e) {
   6.126 +            System.out.println("interrupted!");
   6.127 +            System.exit(1);
   6.128 +        }
   6.129 +    }
   6.130 +
   6.131 +    boolean printResult() {
   6.132 +        int[] count = new int[4];
   6.133 +        for (int i = 0; i < ITERATIONS; ++i) {
   6.134 +            int event_kind = (results[i].a << 1) + results[i].b;
   6.135 +            ++count[event_kind];
   6.136 +        }
   6.137 +        if (count[0] == 0 && count[3] == 0) {
   6.138 +            System.out.println("[not interesting]");
   6.139 +            return false; // not interesting
   6.140 +        }
   6.141 +        String error = (count[0] == 0) ? " ok" : " disallowed!";
   6.142 +        System.out.println("[0,0] " + count[0] + error);
   6.143 +        System.out.println("[0,1] " + count[1]);
   6.144 +        System.out.println("[1,0] " + count[2]);
   6.145 +        System.out.println("[1,1] " + count[3]);
   6.146 +        return (count[0] != 0);
   6.147 +    }
   6.148 +
   6.149 +    public static void main(String args[]) {
   6.150 +        DekkerTest test = new DekkerTest();
   6.151 +        final int runs = 30;
   6.152 +        int failed = 0;
   6.153 +        for (int c = 0; c < runs; ++c) {
   6.154 +            test.testRunner();
   6.155 +            if (test.printResult()) {
   6.156 +                failed++;
   6.157 +            }
   6.158 +            test.reset();
   6.159 +        }
   6.160 +        if (failed > 0) {
   6.161 +            throw new InternalError("FAILED. Got " + failed + " failed ITERATIONS");
   6.162 +        }
   6.163 +        System.out.println("PASSED.");
   6.164 +    }
   6.165 +
   6.166 +}

mercurial