6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)

Mon, 14 Sep 2009 09:49:54 -0700

author
cfang
date
Mon, 14 Sep 2009 09:49:54 -0700
changeset 1420
685e959d09ea
parent 1393
c7e94e8fff43
child 1421
62001a362ce9

6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
Summary: design StoreCMNode::Ideal to promote its oopStore input if the input is a MergeMem node
Reviewed-by: kvn, never

src/share/vm/opto/graphKit.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/graphKit.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/idealKit.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/idealKit.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/memnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/memnode.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/superword.cpp file | annotate | diff | comparison | revisions
test/compiler/6877254/Test.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/graphKit.cpp	Thu Sep 10 18:18:06 2009 -0700
     1.2 +++ b/src/share/vm/opto/graphKit.cpp	Mon Sep 14 09:49:54 2009 -0700
     1.3 @@ -1450,7 +1450,7 @@
     1.4  
     1.5      case BarrierSet::CardTableModRef:
     1.6      case BarrierSet::CardTableExtension:
     1.7 -      write_barrier_post(store, obj, adr, val, use_precise);
     1.8 +      write_barrier_post(store, obj, adr, adr_idx, val, use_precise);
     1.9        break;
    1.10  
    1.11      case BarrierSet::ModRef:
    1.12 @@ -3165,6 +3165,7 @@
    1.13  void GraphKit::write_barrier_post(Node* oop_store,
    1.14                                    Node* obj,
    1.15                                    Node* adr,
    1.16 +                                  uint  adr_idx,
    1.17                                    Node* val,
    1.18                                    bool use_precise) {
    1.19    // No store check needed if we're storing a NULL or an old object
    1.20 @@ -3214,7 +3215,7 @@
    1.21      __ store(__ ctrl(), card_adr, zero, bt, adr_type);
    1.22    } else {
    1.23      // Specialized path for CM store barrier
    1.24 -    __ storeCM(__ ctrl(), card_adr, zero, oop_store, bt, adr_type);
    1.25 +    __ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, bt, adr_type);
    1.26    }
    1.27  
    1.28    // Final sync IdealKit and GraphKit.
    1.29 @@ -3314,6 +3315,7 @@
    1.30  void GraphKit::g1_mark_card(IdealKit& ideal,
    1.31                              Node* card_adr,
    1.32                              Node* oop_store,
    1.33 +                            uint oop_alias_idx,
    1.34                              Node* index,
    1.35                              Node* index_adr,
    1.36                              Node* buffer,
    1.37 @@ -3323,7 +3325,7 @@
    1.38    Node* no_base = __ top();
    1.39    BasicType card_bt = T_BYTE;
    1.40    // Smash zero into card. MUST BE ORDERED WRT TO STORE
    1.41 -  __ storeCM(__ ctrl(), card_adr, zero, oop_store, card_bt, Compile::AliasIdxRaw);
    1.42 +  __ storeCM(__ ctrl(), card_adr, zero, oop_store, oop_alias_idx, card_bt, Compile::AliasIdxRaw);
    1.43  
    1.44    //  Now do the queue work
    1.45    __ if_then(index, BoolTest::ne, zero); {
    1.46 @@ -3435,13 +3437,13 @@
    1.47          Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
    1.48  
    1.49          __ if_then(card_val, BoolTest::ne, zero); {
    1.50 -          g1_mark_card(ideal, card_adr, oop_store, index, index_adr, buffer, tf);
    1.51 +          g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
    1.52          } __ end_if();
    1.53        } __ end_if();
    1.54      } __ end_if();
    1.55    } else {
    1.56      // Object.clone() instrinsic uses this path.
    1.57 -    g1_mark_card(ideal, card_adr, oop_store, index, index_adr, buffer, tf);
    1.58 +    g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
    1.59    }
    1.60  
    1.61    // Final sync IdealKit and GraphKit.
     2.1 --- a/src/share/vm/opto/graphKit.hpp	Thu Sep 10 18:18:06 2009 -0700
     2.2 +++ b/src/share/vm/opto/graphKit.hpp	Mon Sep 14 09:49:54 2009 -0700
     2.3 @@ -603,7 +603,8 @@
     2.4    void sync_kit(IdealKit& ideal);
     2.5  
     2.6    // vanilla/CMS post barrier
     2.7 -  void write_barrier_post(Node *store, Node* obj, Node* adr, Node* val, bool use_precise);
     2.8 +  void write_barrier_post(Node *store, Node* obj,
     2.9 +                          Node* adr,  uint adr_idx, Node* val, bool use_precise);
    2.10  
    2.11    // G1 pre/post barriers
    2.12    void g1_write_barrier_pre(Node* obj,
    2.13 @@ -622,7 +623,8 @@
    2.14                               bool use_precise);
    2.15    // Helper function for g1
    2.16    private:
    2.17 -  void g1_mark_card(IdealKit& ideal, Node* card_adr, Node* store,  Node* index, Node* index_adr,
    2.18 +  void g1_mark_card(IdealKit& ideal, Node* card_adr, Node* store, uint oop_alias_idx,
    2.19 +                    Node* index, Node* index_adr,
    2.20                      Node* buffer, const TypeFunc* tf);
    2.21  
    2.22    public:
     3.1 --- a/src/share/vm/opto/idealKit.cpp	Thu Sep 10 18:18:06 2009 -0700
     3.2 +++ b/src/share/vm/opto/idealKit.cpp	Mon Sep 14 09:49:54 2009 -0700
     3.3 @@ -378,7 +378,7 @@
     3.4  
     3.5  // Card mark store. Must be ordered so that it will come after the store of
     3.6  // the oop.
     3.7 -Node* IdealKit::storeCM(Node* ctl, Node* adr, Node *val, Node* oop_store,
     3.8 +Node* IdealKit::storeCM(Node* ctl, Node* adr, Node *val, Node* oop_store, int oop_adr_idx,
     3.9                          BasicType bt,
    3.10                          int adr_idx) {
    3.11    assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
    3.12 @@ -388,7 +388,7 @@
    3.13  
    3.14    // Add required edge to oop_store, optimizer does not support precedence edges.
    3.15    // Convert required edge to precedence edge before allocation.
    3.16 -  Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store);
    3.17 +  Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx);
    3.18  
    3.19    st = transform(st);
    3.20    set_memory(st, adr_idx);
     4.1 --- a/src/share/vm/opto/idealKit.hpp	Thu Sep 10 18:18:06 2009 -0700
     4.2 +++ b/src/share/vm/opto/idealKit.hpp	Mon Sep 14 09:49:54 2009 -0700
     4.3 @@ -216,6 +216,7 @@
     4.4                  Node* adr,
     4.5                  Node* val,
     4.6                  Node* oop_store,
     4.7 +                int oop_adr_idx,
     4.8                  BasicType bt,
     4.9                  int adr_idx);
    4.10  
     5.1 --- a/src/share/vm/opto/memnode.cpp	Thu Sep 10 18:18:06 2009 -0700
     5.2 +++ b/src/share/vm/opto/memnode.cpp	Mon Sep 14 09:49:54 2009 -0700
     5.3 @@ -2313,6 +2313,22 @@
     5.4    return this;
     5.5  }
     5.6  
     5.7 +//=============================================================================
     5.8 +//------------------------------Ideal---------------------------------------
     5.9 +Node *StoreCMNode::Ideal(PhaseGVN *phase, bool can_reshape){
    5.10 +  Node* progress = StoreNode::Ideal(phase, can_reshape);
    5.11 +  if (progress != NULL) return progress;
    5.12 +
    5.13 +  Node* my_store = in(MemNode::OopStore);
    5.14 +  if (my_store->is_MergeMem()) {
    5.15 +    Node* mem = my_store->as_MergeMem()->memory_at(oop_alias_idx());
    5.16 +    set_req(MemNode::OopStore, mem);
    5.17 +    return this;
    5.18 +  }
    5.19 +
    5.20 +  return NULL;
    5.21 +}
    5.22 +
    5.23  //------------------------------Value-----------------------------------------
    5.24  const Type *StoreCMNode::Value( PhaseTransform *phase ) const {
    5.25    // Either input is TOP ==> the result is TOP
     6.1 --- a/src/share/vm/opto/memnode.hpp	Thu Sep 10 18:18:06 2009 -0700
     6.2 +++ b/src/share/vm/opto/memnode.hpp	Mon Sep 14 09:49:54 2009 -0700
     6.3 @@ -582,12 +582,16 @@
     6.4  // The last StoreCM before a SafePoint must be preserved and occur after its "oop" store
     6.5  // Preceeding equivalent StoreCMs may be eliminated.
     6.6  class StoreCMNode : public StoreNode {
     6.7 + private:
     6.8 +  int _oop_alias_idx;   // The alias_idx of OopStore
     6.9  public:
    6.10 -  StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store ) : StoreNode(c,mem,adr,at,val,oop_store) {}
    6.11 +  StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) : StoreNode(c,mem,adr,at,val,oop_store), _oop_alias_idx(oop_alias_idx) {}
    6.12    virtual int Opcode() const;
    6.13    virtual Node *Identity( PhaseTransform *phase );
    6.14 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
    6.15    virtual const Type *Value( PhaseTransform *phase ) const;
    6.16    virtual BasicType memory_type() const { return T_VOID; } // unspecific
    6.17 +  int oop_alias_idx() const { return _oop_alias_idx; }
    6.18  };
    6.19  
    6.20  //------------------------------LoadPLockedNode---------------------------------
     7.1 --- a/src/share/vm/opto/superword.cpp	Thu Sep 10 18:18:06 2009 -0700
     7.2 +++ b/src/share/vm/opto/superword.cpp	Mon Sep 14 09:49:54 2009 -0700
     7.3 @@ -457,10 +457,6 @@
     7.4          } else if (out->Opcode() == Op_StoreCM && out->in(MemNode::OopStore) == n) {
     7.5            // StoreCM has an input edge used as a precedence edge.
     7.6            // Maybe an issue when oop stores are vectorized.
     7.7 -        } else if( out->is_MergeMem() && prev &&
     7.8 -                   prev->Opcode() == Op_StoreCM && out == prev->in(MemNode::OopStore)) {
     7.9 -          // Oop store is a MergeMem! This should not happen. Temporarily remove the assertion
    7.10 -          // for this case because it could not be superwordized anyway.
    7.11          } else {
    7.12            assert(out == prev || prev == NULL, "no branches off of store slice");
    7.13          }
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/compiler/6877254/Test.java	Mon Sep 14 09:49:54 2009 -0700
     8.3 @@ -0,0 +1,51 @@
     8.4 +/*
     8.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    8.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    8.24 + * have any questions.
    8.25 + */
    8.26 +
    8.27 +/**
    8.28 + * @test
    8.29 + * @bug 6877254
    8.30 + * @summary Implement StoreCMNode::Ideal to promote its OopStore above the MergeMem
    8.31 + *
    8.32 + * @run main/othervm -server -Xcomp -XX:+UseConcMarkSweepGC Test
    8.33 + */
    8.34 +
    8.35 +public class Test {
    8.36 +    static byte var_1;
    8.37 +    static String var_2 = "";
    8.38 +    static byte var_3;
    8.39 +    static float var_4 = 0;
    8.40 +
    8.41 +    public static void main(String[] args) {
    8.42 +        int i = 0;
    8.43 +
    8.44 +        for (String var_tmp = var_2; i < 11; var_1 = 0, i++) {
    8.45 +            var_2 = var_2;
    8.46 +            var_4 *= (var_4 *= (var_3 = 0));
    8.47 +        }
    8.48 +
    8.49 +        System.out.println("var_1 = " + var_1);
    8.50 +        System.out.println("var_2 = " + var_2);
    8.51 +        System.out.println("var_3 = " + var_3);
    8.52 +        System.out.println("var_4 = " + var_4);
    8.53 +    }
    8.54 +}

mercurial