src/share/vm/gc_implementation/g1/heapRegionSet.cpp

Tue, 01 Mar 2011 14:56:48 -0800

author
iveresov
date
Tue, 01 Mar 2011 14:56:48 -0800
changeset 2606
0ac769a57c64
parent 2472
0fa27f37d4d4
child 2643
1216415d8e35
permissions
-rw-r--r--

6627983: G1: Bad oop deference during marking
Summary: Bulk zeroing reduction didn't work with G1, because arraycopy would call pre-barriers on uninitialized oops. The solution is to have version of arraycopy stubs that don't have pre-barriers. Also refactored arraycopy stubs generation on SPARC to be more readable and reduced the number of stubs necessary in some cases.
Reviewed-by: jrose, kvn, never

     1 /*
     2  * Copyright (c) 2011, 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 #include "precompiled.hpp"
    26 #include "gc_implementation/g1/heapRegionSet.inline.hpp"
    28 size_t HeapRegionSetBase::_unrealistically_long_length = 0;
    30 //////////////////// HeapRegionSetBase ////////////////////
    32 void HeapRegionSetBase::set_unrealistically_long_length(size_t len) {
    33   guarantee(_unrealistically_long_length == 0, "should only be set once");
    34   _unrealistically_long_length = len;
    35 }
    37 size_t HeapRegionSetBase::calculate_region_num(HeapRegion* hr) {
    38   assert(hr->startsHumongous(), "pre-condition");
    39   assert(hr->capacity() % HeapRegion::GrainBytes == 0, "invariant");
    40   size_t region_num = hr->capacity() >> HeapRegion::LogOfHRGrainBytes;
    41   assert(region_num > 0, "sanity");
    42   return region_num;
    43 }
    45 void HeapRegionSetBase::fill_in_ext_msg(hrl_ext_msg* msg, const char* message) {
    46   msg->append("[%s] %s "
    47               "ln: "SIZE_FORMAT" rn: "SIZE_FORMAT" "
    48               "cy: "SIZE_FORMAT" ud: "SIZE_FORMAT,
    49               name(), message, length(), region_num(),
    50               total_capacity_bytes(), total_used_bytes());
    51   fill_in_ext_msg_extra(msg);
    52 }
    54 bool HeapRegionSetBase::verify_region(HeapRegion* hr,
    55                                   HeapRegionSetBase* expected_containing_set) {
    56   const char* error_message = NULL;
    58   if (!regions_humongous()) {
    59     if (hr->isHumongous()) {
    60       error_message = "the region should not be humongous";
    61     }
    62   } else {
    63     if (!hr->isHumongous() || !hr->startsHumongous()) {
    64       error_message = "the region should be 'starts humongous'";
    65     }
    66   }
    68   if (!regions_empty()) {
    69     if (hr->is_empty()) {
    70       error_message = "the region should not be empty";
    71     }
    72   } else {
    73     if (!hr->is_empty()) {
    74       error_message = "the region should be empty";
    75     }
    76   }
    78 #ifdef ASSERT
    79   // The _containing_set field is only available when ASSERT is defined.
    80   if (hr->containing_set() != expected_containing_set) {
    81     error_message = "inconsistent containing set found";
    82   }
    83 #endif // ASSERT
    85   const char* extra_error_message = verify_region_extra(hr);
    86   if (extra_error_message != NULL) {
    87     error_message = extra_error_message;
    88   }
    90   if (error_message != NULL) {
    91     outputStream* out = tty;
    92     out->cr();
    93     out->print_cr("## [%s] %s", name(), error_message);
    94     out->print_cr("## Offending Region: "PTR_FORMAT, hr);
    95     out->print_cr("   "HR_FORMAT, HR_FORMAT_PARAMS(hr));
    96 #ifdef ASSERT
    97     out->print_cr("   containing set: "PTR_FORMAT, hr->containing_set());
    98 #endif // ASSERT
    99     out->print_cr("## Offending Region Set: "PTR_FORMAT, this);
   100     print_on(out);
   101     return false;
   102   } else {
   103     return true;
   104   }
   105 }
   107 void HeapRegionSetBase::verify() {
   108   // It's important that we also observe the MT safety protocol even
   109   // for the verification calls. If we do verification without the
   110   // appropriate locks and the set changes underneath our feet
   111   // verification might fail and send us on a wild goose chase.
   112   hrl_assert_mt_safety_ok(this);
   114   guarantee(( is_empty() && length() == 0 && region_num() == 0 &&
   115               total_used_bytes() == 0 && total_capacity_bytes() == 0) ||
   116             (!is_empty() && length() >= 0 && region_num() >= 0 &&
   117               total_used_bytes() >= 0 && total_capacity_bytes() >= 0),
   118             hrl_ext_msg(this, "invariant"));
   120   guarantee((!regions_humongous() && region_num() == length()) ||
   121             ( regions_humongous() && region_num() >= length()),
   122             hrl_ext_msg(this, "invariant"));
   124   guarantee(!regions_empty() || total_used_bytes() == 0,
   125             hrl_ext_msg(this, "invariant"));
   127   guarantee(total_used_bytes() <= total_capacity_bytes(),
   128             hrl_ext_msg(this, "invariant"));
   129 }
   131 void HeapRegionSetBase::verify_start() {
   132   // See comment in verify() about MT safety and verification.
   133   hrl_assert_mt_safety_ok(this);
   134   assert(!_verify_in_progress,
   135          hrl_ext_msg(this, "verification should not be in progress"));
   137   // Do the basic verification first before we do the checks over the regions.
   138   HeapRegionSetBase::verify();
   140   _calc_length               = 0;
   141   _calc_region_num           = 0;
   142   _calc_total_capacity_bytes = 0;
   143   _calc_total_used_bytes     = 0;
   144   _verify_in_progress        = true;
   145 }
   147 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) {
   148   // See comment in verify() about MT safety and verification.
   149   hrl_assert_mt_safety_ok(this);
   150   assert(_verify_in_progress,
   151          hrl_ext_msg(this, "verification should be in progress"));
   153   guarantee(verify_region(hr, this), hrl_ext_msg(this, "region verification"));
   155   _calc_length               += 1;
   156   if (!hr->isHumongous()) {
   157     _calc_region_num         += 1;
   158   } else {
   159     _calc_region_num         += calculate_region_num(hr);
   160   }
   161   _calc_total_capacity_bytes += hr->capacity();
   162   _calc_total_used_bytes     += hr->used();
   163 }
   165 void HeapRegionSetBase::verify_end() {
   166   // See comment in verify() about MT safety and verification.
   167   hrl_assert_mt_safety_ok(this);
   168   assert(_verify_in_progress,
   169          hrl_ext_msg(this, "verification should be in progress"));
   171   guarantee(length() == _calc_length,
   172             hrl_err_msg("[%s] length: "SIZE_FORMAT" should be == "
   173                         "calc length: "SIZE_FORMAT,
   174                         name(), length(), _calc_length));
   176   guarantee(region_num() == _calc_region_num,
   177             hrl_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
   178                         "calc region num: "SIZE_FORMAT,
   179                         name(), region_num(), _calc_region_num));
   181   guarantee(total_capacity_bytes() == _calc_total_capacity_bytes,
   182             hrl_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
   183                         "calc capacity bytes: "SIZE_FORMAT,
   184                         name(),
   185                         total_capacity_bytes(), _calc_total_capacity_bytes));
   187   guarantee(total_used_bytes() == _calc_total_used_bytes,
   188             hrl_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
   189                         "calc used bytes: "SIZE_FORMAT,
   190                         name(), total_used_bytes(), _calc_total_used_bytes));
   192   _verify_in_progress = false;
   193 }
   195 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
   196   out->cr();
   197   out->print_cr("Set: %s ("PTR_FORMAT")", name(), this);
   198   out->print_cr("  Region Assumptions");
   199   out->print_cr("    humongous         : %s", BOOL_TO_STR(regions_humongous()));
   200   out->print_cr("    empty             : %s", BOOL_TO_STR(regions_empty()));
   201   out->print_cr("  Attributes");
   202   out->print_cr("    length            : "SIZE_FORMAT_W(14), length());
   203   out->print_cr("    region num        : "SIZE_FORMAT_W(14), region_num());
   204   out->print_cr("    total capacity    : "SIZE_FORMAT_W(14)" bytes",
   205                 total_capacity_bytes());
   206   out->print_cr("    total used        : "SIZE_FORMAT_W(14)" bytes",
   207                 total_used_bytes());
   208 }
   210 void HeapRegionSetBase::clear() {
   211   _length           = 0;
   212   _region_num       = 0;
   213   _total_used_bytes = 0;
   214 }
   216 HeapRegionSetBase::HeapRegionSetBase(const char* name)
   217   : _name(name), _verify_in_progress(false),
   218     _calc_length(0), _calc_region_num(0),
   219     _calc_total_capacity_bytes(0), _calc_total_used_bytes(0) { }
   221 //////////////////// HeapRegionSet ////////////////////
   223 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) {
   224   hrl_assert_mt_safety_ok(this);
   225   hrl_assert_mt_safety_ok(proxy_set);
   226   hrl_assert_sets_match(this, proxy_set);
   228   verify_optional();
   229   proxy_set->verify_optional();
   231   if (proxy_set->is_empty()) return;
   233   assert(proxy_set->length() <= _length,
   234          hrl_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
   235                      "should be <= length: "SIZE_FORMAT,
   236                      name(), proxy_set->length(), _length));
   237   _length -= proxy_set->length();
   239   assert(proxy_set->region_num() <= _region_num,
   240          hrl_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
   241                      "should be <= region num: "SIZE_FORMAT,
   242                      name(), proxy_set->region_num(), _region_num));
   243   _region_num -= proxy_set->region_num();
   245   assert(proxy_set->total_used_bytes() <= _total_used_bytes,
   246          hrl_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
   247                      "should be <= used bytes: "SIZE_FORMAT,
   248                      name(), proxy_set->total_used_bytes(),
   249                      _total_used_bytes));
   250   _total_used_bytes -= proxy_set->total_used_bytes();
   252   proxy_set->clear();
   254   verify_optional();
   255   proxy_set->verify_optional();
   256 }
   258 //////////////////// HeapRegionLinkedList ////////////////////
   260 void HeapRegionLinkedList::fill_in_ext_msg_extra(hrl_ext_msg* msg) {
   261   msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
   262 }
   264 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) {
   265   hrl_assert_mt_safety_ok(this);
   266   hrl_assert_mt_safety_ok(from_list);
   268   verify_optional();
   269   from_list->verify_optional();
   271   if (from_list->is_empty()) return;
   273 #ifdef ASSERT
   274   HeapRegionLinkedListIterator iter(from_list);
   275   while (iter.more_available()) {
   276     HeapRegion* hr = iter.get_next();
   277     // In set_containing_set() we check that we either set the value
   278     // from NULL to non-NULL or vice versa to catch bugs. So, we have
   279     // to NULL it first before setting it to the value.
   280     hr->set_containing_set(NULL);
   281     hr->set_containing_set(this);
   282   }
   283 #endif // ASSERT
   285   if (_tail != NULL) {
   286     assert(length() >  0 && _head != NULL, hrl_ext_msg(this, "invariant"));
   287     _tail->set_next(from_list->_head);
   288   } else {
   289     assert(length() == 0 && _head == NULL, hrl_ext_msg(this, "invariant"));
   290     _head = from_list->_head;
   291   }
   292   _tail = from_list->_tail;
   294   _length           += from_list->length();
   295   _region_num       += from_list->region_num();
   296   _total_used_bytes += from_list->total_used_bytes();
   297   from_list->clear();
   299   verify_optional();
   300   from_list->verify_optional();
   301 }
   303 void HeapRegionLinkedList::remove_all() {
   304   hrl_assert_mt_safety_ok(this);
   305   verify_optional();
   307   HeapRegion* curr = _head;
   308   while (curr != NULL) {
   309     hrl_assert_region_ok(this, curr, this);
   311     HeapRegion* next = curr->next();
   312     curr->set_next(NULL);
   313     curr->set_containing_set(NULL);
   314     curr = next;
   315   }
   316   clear();
   318   verify_optional();
   319 }
   321 void HeapRegionLinkedList::remove_all_pending(size_t target_count) {
   322   hrl_assert_mt_safety_ok(this);
   323   assert(target_count > 1, hrl_ext_msg(this, "pre-condition"));
   324   assert(!is_empty(), hrl_ext_msg(this, "pre-condition"));
   326   verify_optional();
   327   DEBUG_ONLY(size_t old_length = length();)
   329   HeapRegion* curr = _head;
   330   HeapRegion* prev = NULL;
   331   size_t count = 0;
   332   while (curr != NULL) {
   333     hrl_assert_region_ok(this, curr, this);
   334     HeapRegion* next = curr->next();
   336     if (curr->pending_removal()) {
   337       assert(count < target_count,
   338              hrl_err_msg("[%s] should not come across more regions "
   339                          "pending for removal than target_count: "SIZE_FORMAT,
   340                          name(), target_count));
   342       if (prev == NULL) {
   343         assert(_head == curr, hrl_ext_msg(this, "invariant"));
   344         _head = next;
   345       } else {
   346         assert(_head != curr, hrl_ext_msg(this, "invariant"));
   347         prev->set_next(next);
   348       }
   349       if (next == NULL) {
   350         assert(_tail == curr, hrl_ext_msg(this, "invariant"));
   351         _tail = prev;
   352       } else {
   353         assert(_tail != curr, hrl_ext_msg(this, "invariant"));
   354       }
   356       curr->set_next(NULL);
   357       remove_internal(curr);
   358       curr->set_pending_removal(false);
   360       count += 1;
   362       // If we have come across the target number of regions we can
   363       // just bail out. However, for debugging purposes, we can just
   364       // carry on iterating to make sure there are not more regions
   365       // tagged with pending removal.
   366       DEBUG_ONLY(if (count == target_count) break;)
   367     } else {
   368       prev = curr;
   369     }
   370     curr = next;
   371   }
   373   assert(count == target_count,
   374          hrl_err_msg("[%s] count: "SIZE_FORMAT" should be == "
   375                      "target_count: "SIZE_FORMAT, name(), count, target_count));
   376   assert(length() + target_count == old_length,
   377          hrl_err_msg("[%s] new length should be consistent "
   378                      "new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" "
   379                      "target_count: "SIZE_FORMAT,
   380                      name(), length(), old_length, target_count));
   382   verify_optional();
   383 }
   385 void HeapRegionLinkedList::verify() {
   386   // See comment in HeapRegionSetBase::verify() about MT safety and
   387   // verification.
   388   hrl_assert_mt_safety_ok(this);
   390   // This will also do the basic verification too.
   391   verify_start();
   393   HeapRegion* curr  = _head;
   394   HeapRegion* prev1 = NULL;
   395   HeapRegion* prev0 = NULL;
   396   size_t      count = 0;
   397   while (curr != NULL) {
   398     verify_next_region(curr);
   400     count += 1;
   401     guarantee(count < _unrealistically_long_length,
   402               hrl_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
   403                           "seems very long, is there maybe a cycle? "
   404                           "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" "
   405                           "prev1: "PTR_FORMAT" length: "SIZE_FORMAT,
   406                           name(), count, curr, prev0, prev1, length()));
   408     prev1 = prev0;
   409     prev0 = curr;
   410     curr  = curr->next();
   411   }
   413   guarantee(_tail == prev0, hrl_ext_msg(this, "post-condition"));
   415   verify_end();
   416 }
   418 void HeapRegionLinkedList::clear() {
   419   HeapRegionSetBase::clear();
   420   _head = NULL;
   421   _tail = NULL;
   422 }
   424 void HeapRegionLinkedList::print_on(outputStream* out, bool print_contents) {
   425   HeapRegionSetBase::print_on(out, print_contents);
   426   out->print_cr("  Linking");
   427   out->print_cr("    head              : "PTR_FORMAT, _head);
   428   out->print_cr("    tail              : "PTR_FORMAT, _tail);
   430   if (print_contents) {
   431     out->print_cr("  Contents");
   432     HeapRegionLinkedListIterator iter(this);
   433     while (iter.more_available()) {
   434       HeapRegion* hr = iter.get_next();
   435       hr->print_on(out);
   436     }
   437   }
   438 }

mercurial