< 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  *


  61   assert((index) < (_reserved.word_size() >> BOTConstants::LogN_words),
  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   _object_can_span(false)
  83 { }

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


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




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


 402   _bot->set_offset_array_raw(bottom_index, 0);
 403 }
 404 
 405 HeapWord* G1BlockOffsetTablePart::initialize_threshold() {
 406   assert(!G1CollectedHeap::heap()->is_in_reserved(_bot->_offset_array),
 407          "just checking");
 408   _next_offset_index = _bot->index_for(_space->bottom());
 409   _next_offset_index++;
 410   _next_offset_threshold =
 411     _bot->address_for_index(_next_offset_index);
 412   return _next_offset_threshold;
 413 }
 414 
 415 void G1BlockOffsetTablePart::set_for_starts_humongous(HeapWord* obj_top, size_t fill_size) {
 416   // The first BOT entry should have offset 0.
 417   reset_bot();
 418   alloc_block(_space->bottom(), obj_top);
 419   if (fill_size > 0) {
 420     alloc_block(obj_top, fill_size);
 421   }
 422 }
 423 
 424 void G1BlockOffsetTablePart::set_continues_humongous(bool is_humongous) {
 425   _object_can_span = is_humongous;
 426 }
   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  *


  61   assert((index) < (_reserved.word_size() >> BOTConstants::LogN_words),
  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");


 407   _bot->set_offset_array_raw(bottom_index, 0);
 408 }
 409 
 410 HeapWord* G1BlockOffsetTablePart::initialize_threshold() {
 411   assert(!G1CollectedHeap::heap()->is_in_reserved(_bot->_offset_array),
 412          "just checking");
 413   _next_offset_index = _bot->index_for(_space->bottom());
 414   _next_offset_index++;
 415   _next_offset_threshold =
 416     _bot->address_for_index(_next_offset_index);
 417   return _next_offset_threshold;
 418 }
 419 
 420 void G1BlockOffsetTablePart::set_for_starts_humongous(HeapWord* obj_top, size_t fill_size) {
 421   // The first BOT entry should have offset 0.
 422   reset_bot();
 423   alloc_block(_space->bottom(), obj_top);
 424   if (fill_size > 0) {
 425     alloc_block(obj_top, fill_size);
 426   }




 427 }
< prev index next >