src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp

Fri, 10 Oct 2014 15:51:58 +0200

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 7208
7baf47cb97cb
child 7535
7ae4e26cb1e0
child 7658
c3fcc09c9239
permissions
-rw-r--r--

8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso

     1 /*
     2  * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
    28 #include "memory/allocation.hpp"
    29 #include "gc_interface/gcCause.hpp"
    31 template <class T>
    32 class WorkerDataArray  : public CHeapObj<mtGC> {
    33   T*          _data;
    34   uint        _length;
    35   const char* _print_format;
    36   bool        _print_sum;
    38   NOT_PRODUCT(static const T _uninitialized;)
    40   // We are caching the sum and average to only have to calculate them once.
    41   // This is not done in an MT-safe way. It is intended to allow single
    42   // threaded code to call sum() and average() multiple times in any order
    43   // without having to worry about the cost.
    44   bool   _has_new_data;
    45   T      _sum;
    46   double _average;
    48  public:
    49   WorkerDataArray(uint length, const char* print_format, bool print_sum = true) :
    50   _length(length), _print_format(print_format), _print_sum(print_sum), _has_new_data(true) {
    51     assert(length > 0, "Must have some workers to store data for");
    52     _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
    53   }
    55   ~WorkerDataArray() {
    56     FREE_C_HEAP_ARRAY(T, _data, mtGC);
    57   }
    59   void set(uint worker_i, T value) {
    60     assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
    61     assert(_data[worker_i] == (T)-1, err_msg("Overwriting data for worker %d", worker_i));
    62     _data[worker_i] = value;
    63     _has_new_data = true;
    64   }
    66   T get(uint worker_i) {
    67     assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
    68     assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
    69     return _data[worker_i];
    70   }
    72   void add(uint worker_i, T value) {
    73     assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
    74     assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
    75     _data[worker_i] += value;
    76     _has_new_data = true;
    77   }
    79   double average(){
    80     if (_has_new_data) {
    81       calculate_totals();
    82     }
    83     return _average;
    84   }
    86   T sum() {
    87     if (_has_new_data) {
    88       calculate_totals();
    89     }
    90     return _sum;
    91   }
    93   void print(int level, const char* title);
    95   void reset() PRODUCT_RETURN;
    96   void verify() PRODUCT_RETURN;
    98  private:
   100   void calculate_totals(){
   101     _sum = (T)0;
   102     for (uint i = 0; i < _length; ++i) {
   103       _sum += _data[i];
   104     }
   105     _average = (double)_sum / (double)_length;
   106     _has_new_data = false;
   107   }
   108 };
   110 class G1GCPhaseTimes : public CHeapObj<mtGC> {
   112  private:
   113   uint _active_gc_threads;
   114   uint _max_gc_threads;
   116   WorkerDataArray<double> _last_gc_worker_start_times_ms;
   117   WorkerDataArray<double> _last_ext_root_scan_times_ms;
   118   WorkerDataArray<double> _last_satb_filtering_times_ms;
   119   WorkerDataArray<double> _last_update_rs_times_ms;
   120   WorkerDataArray<int>    _last_update_rs_processed_buffers;
   121   WorkerDataArray<double> _last_scan_rs_times_ms;
   122   WorkerDataArray<double> _last_strong_code_root_scan_times_ms;
   123   WorkerDataArray<double> _last_obj_copy_times_ms;
   124   WorkerDataArray<double> _last_termination_times_ms;
   125   WorkerDataArray<size_t> _last_termination_attempts;
   126   WorkerDataArray<double> _last_gc_worker_end_times_ms;
   127   WorkerDataArray<double> _last_gc_worker_times_ms;
   128   WorkerDataArray<double> _last_gc_worker_other_times_ms;
   130   double _cur_collection_par_time_ms;
   131   double _cur_collection_code_root_fixup_time_ms;
   132   double _cur_strong_code_root_purge_time_ms;
   134   double _cur_evac_fail_recalc_used;
   135   double _cur_evac_fail_restore_remsets;
   136   double _cur_evac_fail_remove_self_forwards;
   138   double                  _cur_string_dedup_fixup_time_ms;
   139   WorkerDataArray<double> _cur_string_dedup_queue_fixup_worker_times_ms;
   140   WorkerDataArray<double> _cur_string_dedup_table_fixup_worker_times_ms;
   142   double _cur_clear_ct_time_ms;
   143   double _cur_ref_proc_time_ms;
   144   double _cur_ref_enq_time_ms;
   146   double _cur_collection_start_sec;
   147   double _root_region_scan_wait_time_ms;
   149   double _recorded_young_cset_choice_time_ms;
   150   double _recorded_non_young_cset_choice_time_ms;
   152   WorkerDataArray<double> _last_redirty_logged_cards_time_ms;
   153   WorkerDataArray<size_t> _last_redirty_logged_cards_processed_cards;
   154   double _recorded_redirty_logged_cards_time_ms;
   156   double _recorded_young_free_cset_time_ms;
   157   double _recorded_non_young_free_cset_time_ms;
   159   double _cur_fast_reclaim_humongous_time_ms;
   160   size_t _cur_fast_reclaim_humongous_total;
   161   size_t _cur_fast_reclaim_humongous_candidates;
   162   size_t _cur_fast_reclaim_humongous_reclaimed;
   164   double _cur_verify_before_time_ms;
   165   double _cur_verify_after_time_ms;
   167   // Helper methods for detailed logging
   168   void print_stats(int level, const char* str, double value);
   169   void print_stats(int level, const char* str, size_t value);
   170   void print_stats(int level, const char* str, double value, uint workers);
   172  public:
   173   G1GCPhaseTimes(uint max_gc_threads);
   174   void note_gc_start(uint active_gc_threads);
   175   void note_gc_end();
   176   void print(double pause_time_sec);
   178   void record_gc_worker_start_time(uint worker_i, double ms) {
   179     _last_gc_worker_start_times_ms.set(worker_i, ms);
   180   }
   182   void record_ext_root_scan_time(uint worker_i, double ms) {
   183     _last_ext_root_scan_times_ms.set(worker_i, ms);
   184   }
   186   void record_satb_filtering_time(uint worker_i, double ms) {
   187     _last_satb_filtering_times_ms.set(worker_i, ms);
   188   }
   190   void record_update_rs_time(uint worker_i, double ms) {
   191     _last_update_rs_times_ms.set(worker_i, ms);
   192   }
   194   void record_update_rs_processed_buffers(uint worker_i, int processed_buffers) {
   195     _last_update_rs_processed_buffers.set(worker_i, processed_buffers);
   196   }
   198   void record_scan_rs_time(uint worker_i, double ms) {
   199     _last_scan_rs_times_ms.set(worker_i, ms);
   200   }
   202   void record_strong_code_root_scan_time(uint worker_i, double ms) {
   203     _last_strong_code_root_scan_times_ms.set(worker_i, ms);
   204   }
   206   void record_obj_copy_time(uint worker_i, double ms) {
   207     _last_obj_copy_times_ms.set(worker_i, ms);
   208   }
   210   void add_obj_copy_time(uint worker_i, double ms) {
   211     _last_obj_copy_times_ms.add(worker_i, ms);
   212   }
   214   void record_termination(uint worker_i, double ms, size_t attempts) {
   215     _last_termination_times_ms.set(worker_i, ms);
   216     _last_termination_attempts.set(worker_i, attempts);
   217   }
   219   void record_gc_worker_end_time(uint worker_i, double ms) {
   220     _last_gc_worker_end_times_ms.set(worker_i, ms);
   221   }
   223   void record_clear_ct_time(double ms) {
   224     _cur_clear_ct_time_ms = ms;
   225   }
   227   void record_par_time(double ms) {
   228     _cur_collection_par_time_ms = ms;
   229   }
   231   void record_code_root_fixup_time(double ms) {
   232     _cur_collection_code_root_fixup_time_ms = ms;
   233   }
   235   void record_strong_code_root_purge_time(double ms) {
   236     _cur_strong_code_root_purge_time_ms = ms;
   237   }
   239   void record_evac_fail_recalc_used_time(double ms) {
   240     _cur_evac_fail_recalc_used = ms;
   241   }
   243   void record_evac_fail_restore_remsets(double ms) {
   244     _cur_evac_fail_restore_remsets = ms;
   245   }
   247   void record_evac_fail_remove_self_forwards(double ms) {
   248     _cur_evac_fail_remove_self_forwards = ms;
   249   }
   251   void note_string_dedup_fixup_start();
   252   void note_string_dedup_fixup_end();
   254   void record_string_dedup_fixup_time(double ms) {
   255     _cur_string_dedup_fixup_time_ms = ms;
   256   }
   258   void record_string_dedup_queue_fixup_worker_time(uint worker_id, double ms) {
   259     _cur_string_dedup_queue_fixup_worker_times_ms.set(worker_id, ms);
   260   }
   262   void record_string_dedup_table_fixup_worker_time(uint worker_id, double ms) {
   263     _cur_string_dedup_table_fixup_worker_times_ms.set(worker_id, ms);
   264   }
   266   void record_ref_proc_time(double ms) {
   267     _cur_ref_proc_time_ms = ms;
   268   }
   270   void record_ref_enq_time(double ms) {
   271     _cur_ref_enq_time_ms = ms;
   272   }
   274   void record_root_region_scan_wait_time(double time_ms) {
   275     _root_region_scan_wait_time_ms = time_ms;
   276   }
   278   void record_young_free_cset_time_ms(double time_ms) {
   279     _recorded_young_free_cset_time_ms = time_ms;
   280   }
   282   void record_non_young_free_cset_time_ms(double time_ms) {
   283     _recorded_non_young_free_cset_time_ms = time_ms;
   284   }
   286   void record_fast_reclaim_humongous_stats(size_t total, size_t candidates) {
   287     _cur_fast_reclaim_humongous_total = total;
   288     _cur_fast_reclaim_humongous_candidates = candidates;
   289   }
   291   void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) {
   292     _cur_fast_reclaim_humongous_time_ms = value;
   293     _cur_fast_reclaim_humongous_reclaimed = reclaimed;
   294   }
   296   void record_young_cset_choice_time_ms(double time_ms) {
   297     _recorded_young_cset_choice_time_ms = time_ms;
   298   }
   300   void record_non_young_cset_choice_time_ms(double time_ms) {
   301     _recorded_non_young_cset_choice_time_ms = time_ms;
   302   }
   304   void record_redirty_logged_cards_time_ms(uint worker_i, double time_ms) {
   305     _last_redirty_logged_cards_time_ms.set(worker_i, time_ms);
   306   }
   308   void record_redirty_logged_cards_processed_cards(uint worker_i, size_t processed_buffers) {
   309     _last_redirty_logged_cards_processed_cards.set(worker_i, processed_buffers);
   310   }
   312   void record_redirty_logged_cards_time_ms(double time_ms) {
   313     _recorded_redirty_logged_cards_time_ms = time_ms;
   314   }
   316   void record_cur_collection_start_sec(double time_ms) {
   317     _cur_collection_start_sec = time_ms;
   318   }
   320   void record_verify_before_time_ms(double time_ms) {
   321     _cur_verify_before_time_ms = time_ms;
   322   }
   324   void record_verify_after_time_ms(double time_ms) {
   325     _cur_verify_after_time_ms = time_ms;
   326   }
   328   double accounted_time_ms();
   330   double cur_collection_start_sec() {
   331     return _cur_collection_start_sec;
   332   }
   334   double cur_collection_par_time_ms() {
   335     return _cur_collection_par_time_ms;
   336   }
   338   double cur_clear_ct_time_ms() {
   339     return _cur_clear_ct_time_ms;
   340   }
   342   double root_region_scan_wait_time_ms() {
   343     return _root_region_scan_wait_time_ms;
   344   }
   346   double young_cset_choice_time_ms() {
   347     return _recorded_young_cset_choice_time_ms;
   348   }
   350   double young_free_cset_time_ms() {
   351     return _recorded_young_free_cset_time_ms;
   352   }
   354   double non_young_cset_choice_time_ms() {
   355     return _recorded_non_young_cset_choice_time_ms;
   356   }
   358   double non_young_free_cset_time_ms() {
   359     return _recorded_non_young_free_cset_time_ms;
   360   }
   362   double fast_reclaim_humongous_time_ms() {
   363     return _cur_fast_reclaim_humongous_time_ms;
   364   }
   366   double average_last_update_rs_time() {
   367     return _last_update_rs_times_ms.average();
   368   }
   370   int sum_last_update_rs_processed_buffers() {
   371     return _last_update_rs_processed_buffers.sum();
   372   }
   374   double average_last_scan_rs_time(){
   375     return _last_scan_rs_times_ms.average();
   376   }
   378   double average_last_strong_code_root_scan_time(){
   379     return _last_strong_code_root_scan_times_ms.average();
   380   }
   382   double average_last_obj_copy_time() {
   383     return _last_obj_copy_times_ms.average();
   384   }
   386   double average_last_termination_time() {
   387     return _last_termination_times_ms.average();
   388   }
   390   double average_last_ext_root_scan_time() {
   391     return _last_ext_root_scan_times_ms.average();
   392   }
   394   double average_last_satb_filtering_times_ms() {
   395     return _last_satb_filtering_times_ms.average();
   396   }
   397 };
   399 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP

mercurial