< prev index next >

src/share/vm/gc/g1/g1BlockOffsetTable.cpp

Print this page
rev 12504 : 8173764: G1 BOT wrongly assumes that objects must always begin at the start of G1BlockOffsetTablePart
Reviewed-by:
rev 12505 : [mq]: 8173764-rev-tschatzl
   1 /*
   2  * Copyright (c) 2001, 2016, 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  *


  62          "%s - index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
  63          msg, (index), (_reserved.word_size() >> BOTConstants::LogN_words));
  64   assert(G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)),
  65          "Index " SIZE_FORMAT " corresponding to " PTR_FORMAT
  66          " (%u) is not in committed area.",
  67          (index),
  68          p2i(address_for_index_raw(index)),
  69          G1CollectedHeap::heap()->addr_to_region(address_for_index_raw(index)));
  70 }
  71 #endif // ASSERT
  72 
  73 //////////////////////////////////////////////////////////////////////
  74 // G1BlockOffsetTablePart
  75 //////////////////////////////////////////////////////////////////////
  76 
  77 G1BlockOffsetTablePart::G1BlockOffsetTablePart(G1BlockOffsetTable* array, G1ContiguousSpace* gsp) :
  78   _bot(array),
  79   _space(gsp),
  80   _next_offset_threshold(NULL),
  81   _next_offset_index(0)
  82 { }


  83 
  84 // The arguments follow the normal convention of denoting
  85 // a right-open interval: [start, end)
  86 void G1BlockOffsetTablePart:: set_remainder_to_point_to_start(HeapWord* start, HeapWord* end) {
  87 
  88   if (start >= end) {
  89     // The start address is equal to the end address (or to
  90     // the right of the end address) so there are not cards
  91     // that need to be updated..
  92     return;
  93   }
  94 
  95   // Write the backskip value for each region.
  96   //
  97   //    offset
  98   //    card             2nd                       3rd
  99   //     | +- 1st        |                         |
 100   //     v v             v                         v
 101   //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-
 102   //    |x|0|0|0|0|0|0|0|1|1|1|1|1|1| ... |1|1|1|1|2|2|2|2|2|2| ...


 348       // Because we refine the BOT based on which cards are dirty there is not much we can verify here.
 349       // We need to make sure that we are going backwards and that we don't pass the start of the
 350       // corresponding heap region. But that is about all we can verify.
 351       size_t backskip = BOTConstants::entry_to_cards_back(entry);
 352       guarantee(backskip >= 1, "Must be going back at least one card.");
 353 
 354       size_t max_backskip = current_card - start_card;
 355       guarantee(backskip <= max_backskip,
 356                 "Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT,
 357                 start_card, current_card, backskip);
 358 
 359       HeapWord* backskip_address = _bot->address_for_index(current_card - backskip);
 360       guarantee(backskip_address >= _space->bottom(),
 361                 "Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT,
 362                 p2i(_space->bottom()), p2i(backskip_address));
 363     }
 364   }
 365 }
 366 
 367 #ifndef PRODUCT




 368 void
 369 G1BlockOffsetTablePart::print_on(outputStream* out) {
 370   size_t from_index = _bot->index_for(_space->bottom());
 371   size_t to_index = _bot->index_for(_space->end());
 372   out->print_cr(">> BOT for area [" PTR_FORMAT "," PTR_FORMAT ") "
 373                 "cards [" SIZE_FORMAT "," SIZE_FORMAT ")",
 374                 p2i(_space->bottom()), p2i(_space->end()), from_index, to_index);
 375   for (size_t i = from_index; i < to_index; ++i) {
 376     out->print_cr("  entry " SIZE_FORMAT_W(8) " | " PTR_FORMAT " : %3u",
 377                   i, p2i(_bot->address_for_index(i)),
 378                   (uint) _bot->offset_array(i));
 379   }
 380   out->print_cr("  next offset threshold: " PTR_FORMAT, p2i(_next_offset_threshold));
 381   out->print_cr("  next offset index:     " SIZE_FORMAT, _next_offset_index);
 382 }
 383 #endif // !PRODUCT
 384 
 385 HeapWord* G1BlockOffsetTablePart::initialize_threshold_raw() {
 386   assert(!G1CollectedHeap::heap()->is_in_reserved(_bot->_offset_array),
 387          "just checking");


   1 /*
   2  * Copyright (c) 2001, 2017, 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  *


  62          "%s - index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
  63          msg, (index), (_reserved.word_size() >> BOTConstants::LogN_words));
  64   assert(G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)),
  65          "Index " SIZE_FORMAT " corresponding to " PTR_FORMAT
  66          " (%u) is not in committed area.",
  67          (index),
  68          p2i(address_for_index_raw(index)),
  69          G1CollectedHeap::heap()->addr_to_region(address_for_index_raw(index)));
  70 }
  71 #endif // ASSERT
  72 
  73 //////////////////////////////////////////////////////////////////////
  74 // G1BlockOffsetTablePart
  75 //////////////////////////////////////////////////////////////////////
  76 
  77 G1BlockOffsetTablePart::G1BlockOffsetTablePart(G1BlockOffsetTable* array, G1ContiguousSpace* gsp) :
  78   _bot(array),
  79   _space(gsp),
  80   _next_offset_threshold(NULL),
  81   _next_offset_index(0)
  82 {
  83   debug_only(_object_can_span = false;)
  84 }
  85 
  86 // The arguments follow the normal convention of denoting
  87 // a right-open interval: [start, end)
  88 void G1BlockOffsetTablePart:: set_remainder_to_point_to_start(HeapWord* start, HeapWord* end) {
  89 
  90   if (start >= end) {
  91     // The start address is equal to the end address (or to
  92     // the right of the end address) so there are not cards
  93     // that need to be updated..
  94     return;
  95   }
  96 
  97   // Write the backskip value for each region.
  98   //
  99   //    offset
 100   //    card             2nd                       3rd
 101   //     | +- 1st        |                         |
 102   //     v v             v                         v
 103   //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-
 104   //    |x|0|0|0|0|0|0|0|1|1|1|1|1|1| ... |1|1|1|1|2|2|2|2|2|2| ...


 350       // Because we refine the BOT based on which cards are dirty there is not much we can verify here.
 351       // We need to make sure that we are going backwards and that we don't pass the start of the
 352       // corresponding heap region. But that is about all we can verify.
 353       size_t backskip = BOTConstants::entry_to_cards_back(entry);
 354       guarantee(backskip >= 1, "Must be going back at least one card.");
 355 
 356       size_t max_backskip = current_card - start_card;
 357       guarantee(backskip <= max_backskip,
 358                 "Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT,
 359                 start_card, current_card, backskip);
 360 
 361       HeapWord* backskip_address = _bot->address_for_index(current_card - backskip);
 362       guarantee(backskip_address >= _space->bottom(),
 363                 "Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT,
 364                 p2i(_space->bottom()), p2i(backskip_address));
 365     }
 366   }
 367 }
 368 
 369 #ifndef PRODUCT
 370 void G1BlockOffsetTablePart::set_object_can_span(bool can_span) {
 371   _object_can_span = can_span;
 372 }
 373 
 374 void
 375 G1BlockOffsetTablePart::print_on(outputStream* out) {
 376   size_t from_index = _bot->index_for(_space->bottom());
 377   size_t to_index = _bot->index_for(_space->end());
 378   out->print_cr(">> BOT for area [" PTR_FORMAT "," PTR_FORMAT ") "
 379                 "cards [" SIZE_FORMAT "," SIZE_FORMAT ")",
 380                 p2i(_space->bottom()), p2i(_space->end()), from_index, to_index);
 381   for (size_t i = from_index; i < to_index; ++i) {
 382     out->print_cr("  entry " SIZE_FORMAT_W(8) " | " PTR_FORMAT " : %3u",
 383                   i, p2i(_bot->address_for_index(i)),
 384                   (uint) _bot->offset_array(i));
 385   }
 386   out->print_cr("  next offset threshold: " PTR_FORMAT, p2i(_next_offset_threshold));
 387   out->print_cr("  next offset index:     " SIZE_FORMAT, _next_offset_index);
 388 }
 389 #endif // !PRODUCT
 390 
 391 HeapWord* G1BlockOffsetTablePart::initialize_threshold_raw() {
 392   assert(!G1CollectedHeap::heap()->is_in_reserved(_bot->_offset_array),
 393          "just checking");


< prev index next >