Merge

Thu, 18 Feb 2016 10:02:52 -0800

author
asaha
date
Thu, 18 Feb 2016 10:02:52 -0800
changeset 8470
20dbd8a8e6b7
parent 8468
3f03f54d9e9f
parent 8469
d14e327c9b6a
child 8472
edff9941089d

Merge

.hgtags file | annotate | diff | comparison | revisions
src/share/vm/prims/jni.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Wed Feb 10 13:34:14 2016 +0000
     1.2 +++ b/.hgtags	Thu Feb 18 10:02:52 2016 -0800
     1.3 @@ -818,6 +818,8 @@
     1.4  32b682649973231b54740c09b10889660f6ebde5 jdk8u75-b04
     1.5  1f43bd4fab06d2ca5d1964611df14d8506d6b36e jdk8u75-b05
     1.6  916712f178c39d0acbc590f38802133fc86a7346 jdk8u75-b06
     1.7 +8c791dd1c24d85ebd18b03d49185c2a25263c129 jdk8u75-b07
     1.8 +e4a935cb6f7178912fd653e2a9514eadec7935ab jdk8u75-b08
     1.9  d7b01fb81aa8a5437cb03bc36afe15cf0e55fb89 jdk8u76-b00
    1.10  c1679cc87ba045219169cabb6b9b378c2b5cc578 jdk8u76-b01
    1.11  218483967e52b419d885d34af4488a81c5133804 jdk8u76-b02
    1.12 @@ -825,4 +827,6 @@
    1.13  16f7b676725aadafb79ea105b22df112e2593a78 jdk8u76-b04
    1.14  35bfaf7f9021b5c1e86effbeac075753a82e9a0c jdk8u76-b05
    1.15  6449ee3bf707225372709ac830524c00984c601f jdk8u76-b06
    1.16 +7d1074c74d6000ec8257917ebfcee3fed4249f7d jdk8u76-b07
    1.17 +392f8722fc513e28f78c5c563d51af7dc8466b29 jdk8u76-b08
    1.18  b374548dcb4834eb8731a06b52faddd0f10bd45d jdk8u81-b00
     2.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Feb 10 13:34:14 2016 +0000
     2.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Feb 18 10:02:52 2016 -0800
     2.3 @@ -3839,6 +3839,16 @@
     2.4    _surviving_young_words = NULL;
     2.5  }
     2.6  
     2.7 +class VerifyRegionRemSetClosure : public HeapRegionClosure {
     2.8 +  public:
     2.9 +    bool doHeapRegion(HeapRegion* hr) {
    2.10 +      if (!hr->continuesHumongous()) {
    2.11 +        hr->verify_rem_set();
    2.12 +      }
    2.13 +      return false;
    2.14 +    }
    2.15 +};
    2.16 +
    2.17  #ifdef ASSERT
    2.18  class VerifyCSetClosure: public HeapRegionClosure {
    2.19  public:
    2.20 @@ -4015,6 +4025,14 @@
    2.21        increment_total_collections(false /* full gc */);
    2.22        increment_gc_time_stamp();
    2.23  
    2.24 +      if (VerifyRememberedSets) {
    2.25 +        if (!VerifySilently) {
    2.26 +          gclog_or_tty->print_cr("[Verifying RemSets before GC]");
    2.27 +        }
    2.28 +        VerifyRegionRemSetClosure v_cl;
    2.29 +        heap_region_iterate(&v_cl);
    2.30 +      }
    2.31 +
    2.32        verify_before_gc();
    2.33        check_bitmaps("GC Start");
    2.34  
    2.35 @@ -4246,6 +4264,14 @@
    2.36          // scanning cards (see CR 7039627).
    2.37          increment_gc_time_stamp();
    2.38  
    2.39 +        if (VerifyRememberedSets) {
    2.40 +          if (!VerifySilently) {
    2.41 +            gclog_or_tty->print_cr("[Verifying RemSets after GC]");
    2.42 +          }
    2.43 +          VerifyRegionRemSetClosure v_cl;
    2.44 +          heap_region_iterate(&v_cl);
    2.45 +        }
    2.46 +
    2.47          verify_after_gc();
    2.48          check_bitmaps("GC End");
    2.49  
     3.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Feb 10 13:34:14 2016 +0000
     3.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu Feb 18 10:02:52 2016 -0800
     3.3 @@ -639,8 +639,8 @@
     3.4    G1OffsetTableContigSpace::print_on(st);
     3.5  }
     3.6  
     3.7 -class VerifyLiveClosure: public OopClosure {
     3.8 -private:
     3.9 +class G1VerificationClosure : public OopClosure {
    3.10 +protected:
    3.11    G1CollectedHeap* _g1h;
    3.12    CardTableModRefBS* _bs;
    3.13    oop _containing_obj;
    3.14 @@ -651,7 +651,7 @@
    3.15    // _vo == UsePrevMarking -> use "prev" marking information,
    3.16    // _vo == UseNextMarking -> use "next" marking information,
    3.17    // _vo == UseMarkWord    -> use mark word from object header.
    3.18 -  VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
    3.19 +  G1VerificationClosure(G1CollectedHeap* g1h, VerifyOption vo) :
    3.20      _g1h(g1h), _bs(NULL), _containing_obj(NULL),
    3.21      _failures(false), _n_failures(0), _vo(vo)
    3.22    {
    3.23 @@ -667,9 +667,6 @@
    3.24    bool failures() { return _failures; }
    3.25    int n_failures() { return _n_failures; }
    3.26  
    3.27 -  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
    3.28 -  virtual void do_oop(      oop* p) { do_oop_work(p); }
    3.29 -
    3.30    void print_object(outputStream* out, oop obj) {
    3.31  #ifdef PRODUCT
    3.32      Klass* k = obj->klass();
    3.33 @@ -679,19 +676,31 @@
    3.34      obj->print_on(out);
    3.35  #endif // PRODUCT
    3.36    }
    3.37 +};
    3.38 +
    3.39 +class VerifyLiveClosure : public G1VerificationClosure {
    3.40 +public:
    3.41 +  VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) : G1VerificationClosure(g1h, vo) {}
    3.42 +  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
    3.43 +  virtual void do_oop(oop* p) { do_oop_work(p); }
    3.44  
    3.45    template <class T>
    3.46    void do_oop_work(T* p) {
    3.47      assert(_containing_obj != NULL, "Precondition");
    3.48      assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
    3.49 -           "Precondition");
    3.50 +      "Precondition");
    3.51 +    verify_liveness(p);
    3.52 +  }
    3.53 +
    3.54 +  template <class T>
    3.55 +  void verify_liveness(T* p) {
    3.56      T heap_oop = oopDesc::load_heap_oop(p);
    3.57      if (!oopDesc::is_null(heap_oop)) {
    3.58        oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
    3.59        bool failed = false;
    3.60        if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) {
    3.61          MutexLockerEx x(ParGCRareEvent_lock,
    3.62 -                        Mutex::_no_safepoint_check_flag);
    3.63 +          Mutex::_no_safepoint_check_flag);
    3.64  
    3.65          if (!_failures) {
    3.66            gclog_or_tty->cr();
    3.67 @@ -727,50 +736,71 @@
    3.68          failed = true;
    3.69          _n_failures++;
    3.70        }
    3.71 +    }
    3.72 +  }
    3.73 +};
    3.74  
    3.75 -      if (!_g1h->full_collection() || G1VerifyRSetsDuringFullGC) {
    3.76 -        HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
    3.77 -        HeapRegion* to   = _g1h->heap_region_containing(obj);
    3.78 -        if (from != NULL && to != NULL &&
    3.79 -            from != to &&
    3.80 -            !to->isHumongous()) {
    3.81 -          jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
    3.82 -          jbyte cv_field = *_bs->byte_for_const(p);
    3.83 -          const jbyte dirty = CardTableModRefBS::dirty_card_val();
    3.84 +class VerifyRemSetClosure : public G1VerificationClosure {
    3.85 +public:
    3.86 +  VerifyRemSetClosure(G1CollectedHeap* g1h, VerifyOption vo) : G1VerificationClosure(g1h, vo) {}
    3.87 +  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
    3.88 +  virtual void do_oop(oop* p) { do_oop_work(p); }
    3.89  
    3.90 -          bool is_bad = !(from->is_young()
    3.91 -                          || to->rem_set()->contains_reference(p)
    3.92 -                          || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
    3.93 -                              (_containing_obj->is_objArray() ?
    3.94 -                                  cv_field == dirty
    3.95 -                               : cv_obj == dirty || cv_field == dirty));
    3.96 -          if (is_bad) {
    3.97 -            MutexLockerEx x(ParGCRareEvent_lock,
    3.98 -                            Mutex::_no_safepoint_check_flag);
    3.99 +  template <class T>
   3.100 +  void do_oop_work(T* p) {
   3.101 +    assert(_containing_obj != NULL, "Precondition");
   3.102 +    assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
   3.103 +      "Precondition");
   3.104 +    verify_remembered_set(p);
   3.105 +  }
   3.106  
   3.107 -            if (!_failures) {
   3.108 -              gclog_or_tty->cr();
   3.109 -              gclog_or_tty->print_cr("----------");
   3.110 -            }
   3.111 -            gclog_or_tty->print_cr("Missing rem set entry:");
   3.112 -            gclog_or_tty->print_cr("Field "PTR_FORMAT" "
   3.113 -                                   "of obj "PTR_FORMAT", "
   3.114 -                                   "in region "HR_FORMAT,
   3.115 -                                   p, (void*) _containing_obj,
   3.116 -                                   HR_FORMAT_PARAMS(from));
   3.117 -            _containing_obj->print_on(gclog_or_tty);
   3.118 -            gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
   3.119 -                                   "in region "HR_FORMAT,
   3.120 -                                   (void*) obj,
   3.121 -                                   HR_FORMAT_PARAMS(to));
   3.122 -            obj->print_on(gclog_or_tty);
   3.123 -            gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
   3.124 -                          cv_obj, cv_field);
   3.125 +  template <class T>
   3.126 +  void verify_remembered_set(T* p) {
   3.127 +    T heap_oop = oopDesc::load_heap_oop(p);
   3.128 +    if (!oopDesc::is_null(heap_oop)) {
   3.129 +      oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
   3.130 +      bool failed = false;
   3.131 +      HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
   3.132 +      HeapRegion* to   = _g1h->heap_region_containing(obj);
   3.133 +      if (from != NULL && to != NULL &&
   3.134 +          from != to &&
   3.135 +          !to->isHumongous()) {
   3.136 +        jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
   3.137 +        jbyte cv_field = *_bs->byte_for_const(p);
   3.138 +        const jbyte dirty = CardTableModRefBS::dirty_card_val();
   3.139 +
   3.140 +        bool is_bad = !(from->is_young()
   3.141 +                        || to->rem_set()->contains_reference(p)
   3.142 +                        || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
   3.143 +                            (_containing_obj->is_objArray() ?
   3.144 +                                cv_field == dirty
   3.145 +                             : cv_obj == dirty || cv_field == dirty));
   3.146 +        if (is_bad) {
   3.147 +          MutexLockerEx x(ParGCRareEvent_lock,
   3.148 +                          Mutex::_no_safepoint_check_flag);
   3.149 +
   3.150 +          if (!_failures) {
   3.151 +            gclog_or_tty->cr();
   3.152              gclog_or_tty->print_cr("----------");
   3.153 -            gclog_or_tty->flush();
   3.154 -            _failures = true;
   3.155 -            if (!failed) _n_failures++;
   3.156            }
   3.157 +          gclog_or_tty->print_cr("Missing rem set entry:");
   3.158 +          gclog_or_tty->print_cr("Field "PTR_FORMAT" "
   3.159 +                                 "of obj "PTR_FORMAT", "
   3.160 +                                 "in region "HR_FORMAT,
   3.161 +                                 p, (void*) _containing_obj,
   3.162 +                                 HR_FORMAT_PARAMS(from));
   3.163 +          _containing_obj->print_on(gclog_or_tty);
   3.164 +          gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
   3.165 +                                 "in region "HR_FORMAT,
   3.166 +                                 (void*) obj,
   3.167 +                                 HR_FORMAT_PARAMS(to));
   3.168 +          obj->print_on(gclog_or_tty);
   3.169 +          gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
   3.170 +                        cv_obj, cv_field);
   3.171 +          gclog_or_tty->print_cr("----------");
   3.172 +          gclog_or_tty->flush();
   3.173 +          _failures = true;
   3.174 +          if (!failed) _n_failures++;
   3.175          }
   3.176        }
   3.177      }
   3.178 @@ -787,6 +817,7 @@
   3.179    HeapWord* p = bottom();
   3.180    HeapWord* prev_p = NULL;
   3.181    VerifyLiveClosure vl_cl(g1, vo);
   3.182 +  VerifyRemSetClosure vr_cl(g1, vo);
   3.183    bool is_humongous = isHumongous();
   3.184    bool do_bot_verify = !is_young();
   3.185    size_t object_num = 0;
   3.186 @@ -832,7 +863,23 @@
   3.187            return;
   3.188          } else {
   3.189            vl_cl.set_containing_obj(obj);
   3.190 -          obj->oop_iterate_no_header(&vl_cl);
   3.191 +          if (!g1->full_collection() || G1VerifyRSetsDuringFullGC) {
   3.192 +            // verify liveness and rem_set
   3.193 +            vr_cl.set_containing_obj(obj);
   3.194 +            G1Mux2Closure mux(&vl_cl, &vr_cl);
   3.195 +            obj->oop_iterate_no_header(&mux);
   3.196 +
   3.197 +            if (vr_cl.failures()) {
   3.198 +              *failures = true;
   3.199 +            }
   3.200 +            if (G1MaxVerifyFailures >= 0 &&
   3.201 +              vr_cl.n_failures() >= G1MaxVerifyFailures) {
   3.202 +              return;
   3.203 +            }
   3.204 +          } else {
   3.205 +            // verify only liveness
   3.206 +            obj->oop_iterate_no_header(&vl_cl);
   3.207 +          }
   3.208            if (vl_cl.failures()) {
   3.209              *failures = true;
   3.210            }
   3.211 @@ -842,7 +889,7 @@
   3.212            }
   3.213          }
   3.214        } else {
   3.215 -        gclog_or_tty->print_cr(PTR_FORMAT" no an oop", (void *)obj);
   3.216 +        gclog_or_tty->print_cr(PTR_FORMAT" not an oop", (void *)obj);
   3.217          *failures = true;
   3.218          return;
   3.219        }
   3.220 @@ -930,6 +977,46 @@
   3.221    verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
   3.222  }
   3.223  
   3.224 +void HeapRegion::verify_rem_set(VerifyOption vo, bool* failures) const {
   3.225 +  G1CollectedHeap* g1 = G1CollectedHeap::heap();
   3.226 +  *failures = false;
   3.227 +  HeapWord* p = bottom();
   3.228 +  HeapWord* prev_p = NULL;
   3.229 +  VerifyRemSetClosure vr_cl(g1, vo);
   3.230 +  while (p < top()) {
   3.231 +    oop obj = oop(p);
   3.232 +    size_t obj_size = block_size(p);
   3.233 +
   3.234 +    if (!g1->is_obj_dead_cond(obj, this, vo)) {
   3.235 +      if (obj->is_oop()) {
   3.236 +        vr_cl.set_containing_obj(obj);
   3.237 +        obj->oop_iterate_no_header(&vr_cl);
   3.238 +
   3.239 +        if (vr_cl.failures()) {
   3.240 +          *failures = true;
   3.241 +        }
   3.242 +        if (G1MaxVerifyFailures >= 0 &&
   3.243 +          vr_cl.n_failures() >= G1MaxVerifyFailures) {
   3.244 +          return;
   3.245 +        }
   3.246 +      } else {
   3.247 +        gclog_or_tty->print_cr(PTR_FORMAT " not an oop", p2i(obj));
   3.248 +        *failures = true;
   3.249 +        return;
   3.250 +      }
   3.251 +    }
   3.252 +
   3.253 +    prev_p = p;
   3.254 +    p += obj_size;
   3.255 +  }
   3.256 +}
   3.257 +
   3.258 +void HeapRegion::verify_rem_set() const {
   3.259 +  bool failures = false;
   3.260 +  verify_rem_set(VerifyOption_G1UsePrevMarking, &failures);
   3.261 +  guarantee(!failures, "HeapRegion RemSet verification failed");
   3.262 +}
   3.263 +
   3.264  // G1OffsetTableContigSpace code; copied from space.cpp.  Hope this can go
   3.265  // away eventually.
   3.266  
     4.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Feb 10 13:34:14 2016 +0000
     4.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu Feb 18 10:02:52 2016 -0800
     4.3 @@ -779,6 +779,9 @@
     4.4  
     4.5    // Override; it uses the "prev" marking information
     4.6    virtual void verify() const;
     4.7 +
     4.8 +  void verify_rem_set(VerifyOption vo, bool *failures) const;
     4.9 +  void verify_rem_set() const;
    4.10  };
    4.11  
    4.12  // HeapRegionClosure is used for iterating over regions.
     5.1 --- a/test/compiler/loopopts/CountedLoopProblem.java	Wed Feb 10 13:34:14 2016 +0000
     5.2 +++ b/test/compiler/loopopts/CountedLoopProblem.java	Thu Feb 18 10:02:52 2016 -0800
     5.3 @@ -36,18 +36,22 @@
     5.4      public static void main(String[] args) throws Exception {
     5.5          Random r = new Random(42);
     5.6          int x = 0;
     5.7 -        StringBuilder sb = new StringBuilder();
     5.8 -        for(int i = 0; i < 1000000; ++i) {
     5.9 -            int v = Math.abs(r.nextInt());
    5.10 -            sb.append('+').append(v).append('\n');
    5.11 -            x += v;
    5.12 -            // To trigger the problem we must OSR in the following loop
    5.13 -            // To make the problem 100% reproducible run with -XX:-TieredCompilation -XX:OSROnlyBCI=62
    5.14 -            while(x < 0) x += 1000000000;
    5.15 -            sb.append('=').append(x).append('\n');
    5.16 -        }
    5.17 -        if (sb.toString().hashCode() != 0xaba94591) {
    5.18 -            throw new Exception("Unexpected result");
    5.19 +        try {
    5.20 +            StringBuilder sb = new StringBuilder();
    5.21 +            for(int i = 0; i < 1000000; ++i) {
    5.22 +                int v = Math.abs(r.nextInt());
    5.23 +                sb.append('+').append(v).append('\n');
    5.24 +                x += v;
    5.25 +                // To trigger the problem we must OSR in the following loop
    5.26 +                // To make the problem 100% reproducible run with -XX:-TieredCompilation -XX:OSROnlyBCI=62
    5.27 +                while(x < 0) x += 1000000000;
    5.28 +                sb.append('=').append(x).append('\n');
    5.29 +            }
    5.30 +            if (sb.toString().hashCode() != 0xaba94591) {
    5.31 +                throw new Exception("Unexpected result");
    5.32 +            }
    5.33 +        } catch(OutOfMemoryError e) {
    5.34 +            // small heap, ignore
    5.35          }
    5.36      }
    5.37  }
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/stress/gc/TestStressRSetCoarsening.java	Thu Feb 18 10:02:52 2016 -0800
     6.3 @@ -0,0 +1,334 @@
     6.4 +/*
     6.5 + * Copyright (c) 2016, Oracle and/or its affiliates. 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 +import java.util.concurrent.TimeoutException;
    6.28 +import sun.hotspot.WhiteBox;
    6.29 +
    6.30 +/*
    6.31 + * @test TestStressRSetCoarsening.java
    6.32 + * @key stress
    6.33 + * @bug 8146984 8147087
    6.34 + * @requires vm.gc=="G1" | vm.gc=="null"
    6.35 + * @requires os.maxMemory > 3G
    6.36 + *
    6.37 + * @summary Stress G1 Remembered Set by creating a lot of cross region links
    6.38 + * @library /testlibrary /testlibrary/whitebox
    6.39 + * @build sun.hotspot.WhiteBox
    6.40 + * @run main ClassFileInstaller sun.hotspot.WhiteBox
    6.41 + *                              sun.hotspot.WhiteBox$WhiteBoxPermission
    6.42 + * @run main/othervm/timeout=300
    6.43 + *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
    6.44 + *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
    6.45 + *     -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening  1  0 300
    6.46 + * @run main/othervm/timeout=300
    6.47 + *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
    6.48 + *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
    6.49 + *     -Xmx500m -XX:G1HeapRegionSize=8m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening  1 10 300
    6.50 + * @run main/othervm/timeout=300
    6.51 + *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
    6.52 + *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
    6.53 + *     -Xmx500m -XX:G1HeapRegionSize=32m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 42 10 300
    6.54 + * @run main/othervm/timeout=300
    6.55 + *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
    6.56 + *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
    6.57 + *     -Xmx500m -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening  2 0 300
    6.58 + * @run main/othervm/timeout=1800
    6.59 + *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
    6.60 + *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
    6.61 + *     -Xmx1G -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 500 0  1800
    6.62 + * @run main/othervm/timeout=1800
    6.63 + *     -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC
    6.64 + *     -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGC -XX:+PrintGCTimeStamps -Xlog:gc
    6.65 + *     -Xmx1G -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=1000 TestStressRSetCoarsening 10  10 1800
    6.66 + */
    6.67 +
    6.68 +/**
    6.69 + * What the test does.
    6.70 + * Preparation stage:
    6.71 + *   Fill out ~90% of the heap with objects, each object is an object array.
    6.72 + *   If we want to allocate K objects per region, we calculate N to meet:
    6.73 + *      sizeOf(Object[N]) ~= regionSize / K
    6.74 + * Stress stage:
    6.75 + *   No more allocation, so no more GC.
    6.76 + *   We will perform a number of  iterations. On each iteration i,
    6.77 + *   for each pair of regions Rx and Ry we will set c[i] references
    6.78 + *   from Rx to Ry. If c[i] less than c[i-1] at the end of iteration
    6.79 + *   concurrent mark cycle will be initiated (to recalculate remembered sets).
    6.80 + *   As the result RSet will be growing up and down, up and down many times.
    6.81 + *
    6.82 + * The test expects: no crash and no timeouts.
    6.83 + *
    6.84 + * Test Parameters:
    6.85 + *   args[0] - number of objects per Heap Region (1 - means humongous)
    6.86 + *   args[1] - number of regions to refresh to provoke GC at the end of cycle.
    6.87 + *             (0 - means no GC, i.e. no reading from RSet)
    6.88 + *   args[2] - timeout in seconds (to stop execution to avoid jtreg timeout)
    6.89 + */
    6.90 +public class TestStressRSetCoarsening {
    6.91 +
    6.92 +    public static void main(String... args) throws InterruptedException {
    6.93 +        if (args.length != 3) {
    6.94 +            throw new IllegalArgumentException("Wrong number of arguments " + args.length);
    6.95 +        }
    6.96 +        int objectsPerRegion = Integer.parseInt(args[0]); // 1 means humongous
    6.97 +        int regsToRefresh = Integer.parseInt(args[1]);  // 0 means no regions to refresh at the end of cycle
    6.98 +        int timeout = Integer.parseInt(args[2]); // in seconds, test should stop working eariler
    6.99 +        new TestStressRSetCoarsening(objectsPerRegion, regsToRefresh, timeout).go();
   6.100 +    }
   6.101 +
   6.102 +    private static final long KB = 1024;
   6.103 +    private static final long MB = 1024 * KB;
   6.104 +
   6.105 +    private static final WhiteBox WB = WhiteBox.getWhiteBox();
   6.106 +
   6.107 +    public final Object[][] storage;
   6.108 +
   6.109 +    /**
   6.110 +     * Number of objects per region. This is a test parameter.
   6.111 +     */
   6.112 +    public final int K;
   6.113 +
   6.114 +    /**
   6.115 +     * Length of object array: sizeOf(Object[N]) ~= regionSize / K
   6.116 +     * N will be calculated as function of K.
   6.117 +     */
   6.118 +    public final int N;
   6.119 +
   6.120 +    /**
   6.121 +     * How many regions involved into testing.
   6.122 +     * Will be calculated as heapFractionToAllocate * freeRegionCount.
   6.123 +     */
   6.124 +    public final int regionCount;
   6.125 +
   6.126 +    /**
   6.127 +     * How much heap to use.
   6.128 +     */
   6.129 +    public final float heapFractionToAllocate = 0.9f;
   6.130 +
   6.131 +    /**
   6.132 +     * How many regions to be refreshed at the end of cycle.
   6.133 +     * This is a test parameter.
   6.134 +     */
   6.135 +    public final int regsToRefresh;
   6.136 +
   6.137 +    /**
   6.138 +     * Initial time.
   6.139 +     */
   6.140 +    public final long start;
   6.141 +
   6.142 +    /**
   6.143 +     * Time when the test should stop working.
   6.144 +     */
   6.145 +    public final long finishAt;
   6.146 +
   6.147 +    /**
   6.148 +     * Does pre-calculation and allocate necessary objects.
   6.149 +     *
   6.150 +     * @param objPerRegions how many objects per G1 heap region
   6.151 +     */
   6.152 +    TestStressRSetCoarsening(int objPerRegions, int regsToRefresh, int timeout) {
   6.153 +        this.K = objPerRegions;
   6.154 +        this.regsToRefresh = regsToRefresh;
   6.155 +        this.start = System.currentTimeMillis();
   6.156 +        this.finishAt = start + timeout * 900; // 10% ahead of jtreg timeout
   6.157 +
   6.158 +        long regionSize = WB.g1RegionSize();
   6.159 +
   6.160 +        // How many free regions
   6.161 +        Runtime rt = Runtime.getRuntime();
   6.162 +        long used = rt.totalMemory() - rt.freeMemory();
   6.163 +        long totalFree = rt.maxMemory() - used;
   6.164 +        regionCount = (int) ((totalFree / regionSize) * heapFractionToAllocate);
   6.165 +        long toAllocate = regionCount * regionSize;
   6.166 +        System.out.println("%% Test parameters");
   6.167 +        System.out.println("%%   Objects per region              : " + K);
   6.168 +        System.out.println("%%   Heap fraction to allocate       : " + (int) (heapFractionToAllocate * 100) + "%");
   6.169 +        System.out.println("%%   Regions to refresh to provoke GC: " + regsToRefresh);
   6.170 +
   6.171 +        System.out.println("%% Memory");
   6.172 +        System.out.println("%%   used          :        " + used / MB + "M");
   6.173 +        System.out.println("%%   available     :        " + totalFree / MB + "M");
   6.174 +        System.out.println("%%   to allocate   :        " + toAllocate / MB + "M");
   6.175 +        System.out.println("%%     (in regs)   :        " + regionCount);
   6.176 +        System.out.println("%%   G1 Region Size:        " + regionSize / MB + "M");
   6.177 +
   6.178 +        int refSize = WB.getHeapOopSize();
   6.179 +
   6.180 +        // Calculate N:    K*sizeOf(Object[N]) ~= regionSize
   6.181 +        //                 sizeOf(Object[N]) ~=  (N+4)*refSize
   6.182 +        // ==>
   6.183 +        //                 N = regionSize / K / refSize - 4;
   6.184 +        N = (int) ((regionSize / K) / refSize) - 5;
   6.185 +
   6.186 +        /*
   6.187 +         *   --------------
   6.188 +         *   region0   storage[0]        = new Object[N]
   6.189 +         *             ...
   6.190 +         *             storage[K-1]      = new Object[N]
   6.191 +         *   ---------------
   6.192 +         *   region1   storage[K]        = new Object[N]
   6.193 +         *             ...
   6.194 +         *             storage[2*K - 1]  = new Object[N]
   6.195 +         *   --------------
   6.196 +         *   ...
   6.197 +         *   --------------
   6.198 +         *   regionX   storage[X*K]         = new Object[N]
   6.199 +         *             ...
   6.200 +         *             storage[(X+1)*K -1]  = new Object[N]
   6.201 +         *    where X = HeapFraction * TotalRegions
   6.202 +         *   -------------
   6.203 +         */
   6.204 +        System.out.println("%% Objects");
   6.205 +        System.out.println("%%   N (array length)      : " + N);
   6.206 +        System.out.println("%%   K (objects in regions): " + K);
   6.207 +        System.out.println("%%   Reference size        : " + refSize);
   6.208 +        System.out.println("%%   Approximate obj size  : " + (N + 2) * refSize / KB + "K)");
   6.209 +
   6.210 +        storage = new Object[regionCount * K][];
   6.211 +        for (int i = 0; i < storage.length; i++) {
   6.212 +            storage[i] = new Object[N];
   6.213 +        }
   6.214 +    }
   6.215 +
   6.216 +    public void go() throws InterruptedException {
   6.217 +        // threshold for sparce -> fine
   6.218 +        final int FINE = WB.getIntxVMFlag("G1RSetSparseRegionEntries").intValue();
   6.219 +
   6.220 +        // threshold for fine -> coarse
   6.221 +        final int COARSE = WB.getIntxVMFlag("G1RSetRegionEntries").intValue();
   6.222 +
   6.223 +        // regToRegRefCounts - array of reference counts from region to region
   6.224 +        // at the the end of iteration.
   6.225 +        // The number of test iterations is array length - 1.
   6.226 +        // If c[i] > c[i-1] then during the iteration i more references will
   6.227 +        // be created.
   6.228 +        // If c[i] < c[i-1] then some referenes will be cleaned.
   6.229 +        int[] regToRegRefCounts = {0, FINE / 2, 0, FINE, (FINE + COARSE) / 2, 0,
   6.230 +            COARSE, COARSE + 10, FINE + 1, FINE / 2, 0};
   6.231 +
   6.232 +        // For progress tracking
   6.233 +        int[] progress = new int[regToRegRefCounts.length];
   6.234 +        progress[0] = 0;
   6.235 +        for (int i = 1; i < regToRegRefCounts.length; i++) {
   6.236 +            progress[i] = progress[i - 1] + Math.abs(regToRegRefCounts[i] - regToRegRefCounts[i - 1]);
   6.237 +        }
   6.238 +        try {
   6.239 +            for (int i = 1; i < regToRegRefCounts.length; i++) {
   6.240 +                int pre = regToRegRefCounts[i - 1];
   6.241 +                int cur = regToRegRefCounts[i];
   6.242 +                float prog = ((float) progress[i - 1] / progress[progress.length - 1]);
   6.243 +
   6.244 +                System.out.println("%% step " + i
   6.245 +                        + " out of " + (regToRegRefCounts.length - 1)
   6.246 +                        + " (~" + (int) (100 * prog) + "% done)");
   6.247 +                System.out.println("%%      " + pre + "  --> " + cur);
   6.248 +                for (int to = 0; to < regionCount; to++) {
   6.249 +                    // Select a celebrity object that we will install references to.
   6.250 +                    // The celebrity will be referred from all other regions.
   6.251 +                    // If the number of references after should be less than they
   6.252 +                    // were before, select NULL.
   6.253 +                    Object celebrity = cur > pre ? storage[to * K] : null;
   6.254 +                    for (int from = 0; from < regionCount; from++) {
   6.255 +                        if (to == from) {
   6.256 +                            continue; // no need to refer to itself
   6.257 +                        }
   6.258 +
   6.259 +                        int step = cur > pre ? +1 : -1;
   6.260 +                        for (int rn = pre; rn != cur; rn += step) {
   6.261 +                            storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity;
   6.262 +                            if (System.currentTimeMillis() > finishAt) {
   6.263 +                                throw new TimeoutException();
   6.264 +                            }
   6.265 +                        }
   6.266 +                    }
   6.267 +                }
   6.268 +                if (pre > cur) {
   6.269 +                    // Number of references went down.
   6.270 +                    // Need to provoke recalculation of RSet.
   6.271 +                    WB.g1StartConcMarkCycle();
   6.272 +                    while (WB.g1InConcurrentMark()) {
   6.273 +                        Thread.sleep(1);
   6.274 +                    }
   6.275 +                }
   6.276 +
   6.277 +                // To force the use of rememebered set entries we need to provoke a GC.
   6.278 +                // To induce some fragmentation, and some mixed GCs, we need
   6.279 +                // to make a few objects unreachable.
   6.280 +                for (int toClean = i * regsToRefresh; toClean < (i + 1) * regsToRefresh; toClean++) {
   6.281 +                    int to = toClean % regionCount;
   6.282 +                    // Need to remove all references from all regions to the region 'to'
   6.283 +                    for (int from = 0; from < regionCount; from++) {
   6.284 +                        if (to == from) {
   6.285 +                            continue; // no need to refer to itself
   6.286 +                        }
   6.287 +                        for (int rn = 0; rn <= cur; rn++) {
   6.288 +                            storage[getY(to, from, rn)][getX(to, from, rn)] = null;
   6.289 +                        }
   6.290 +                    }
   6.291 +                    // 'Refresh' storage elements for the region 'to'
   6.292 +                    // After that loop all 'old' objects in the region 'to'
   6.293 +                    // should become unreachable.
   6.294 +                    for (int k = 0; k < K; k++) {
   6.295 +                        storage[(to * K + k) % storage.length] = new Object[N];
   6.296 +                    }
   6.297 +                }
   6.298 +            }
   6.299 +        } catch (TimeoutException e) {
   6.300 +            System.out.println("%% TIMEOUT!!!");
   6.301 +        }
   6.302 +        long now = System.currentTimeMillis();
   6.303 +        System.out.println("%% Summary");
   6.304 +        System.out.println("%%   Time spent          : " + ((now - start) / 1000) + " seconds");
   6.305 +        System.out.println("%%   Free memory left    : " + Runtime.getRuntime().freeMemory() / KB + "K");
   6.306 +        System.out.println("%% Test passed");
   6.307 +    }
   6.308 +
   6.309 +    /**
   6.310 +     * Returns X index in the Storage of the reference #rn from the region
   6.311 +     * 'from' to the region 'to'.
   6.312 +     *
   6.313 +     * @param to region # to refer to
   6.314 +     * @param from region # to refer from
   6.315 +     * @param rn number of reference
   6.316 +     *
   6.317 +     * @return X index in the range: [0 ... N-1]
   6.318 +     */
   6.319 +    private int getX(int to, int from, int rn) {
   6.320 +        return (rn * regionCount + to) % N;
   6.321 +    }
   6.322 +
   6.323 +    /**
   6.324 +     * Returns Y index in the Storage of the reference #rn from the region
   6.325 +     * 'from' to the region 'to'.
   6.326 +     *
   6.327 +     * @param to region # to refer to
   6.328 +     * @param from region # to refer from
   6.329 +     * @param rn number of reference
   6.330 +     *
   6.331 +     * @return Y index in the range: [0 ... K*regionCount -1]
   6.332 +     */
   6.333 +    private int getY(int to, int from, int rn) {
   6.334 +        return ((rn * regionCount + to) / N + from * K) % (regionCount * K);
   6.335 +    }
   6.336 +}
   6.337 +

mercurial