8173764: G1 BOT wrongly assumes that objects must always begin at the start of G1BlockOffsetTablePart
authorsjohanss
Fri, 24 Feb 2017 10:41:56 +0100
changeset 46286 c112671e114e
parent 46285 5b673a9fa682
child 46288 5104e67b9143
8173764: G1 BOT wrongly assumes that objects must always begin at the start of G1BlockOffsetTablePart Reviewed-by: tschatzl, kbarrett
hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp
hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp
hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp
hotspot/src/share/vm/gc/g1/heapRegion.cpp
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Wed Dec 07 13:51:20 2016 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Fri Feb 24 10:41:56 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,9 @@
   _space(gsp),
   _next_offset_threshold(NULL),
   _next_offset_index(0)
-{ }
+{
+  debug_only(_object_can_span = false;)
+}
 
 // The arguments follow the normal convention of denoting
 // a right-open interval: [start, end)
@@ -364,6 +366,12 @@
   }
 }
 
+#ifdef ASSERT
+void G1BlockOffsetTablePart::set_object_can_span(bool can_span) {
+  _object_can_span = can_span;
+}
+#endif
+
 #ifndef PRODUCT
 void
 G1BlockOffsetTablePart::print_on(outputStream* out) {
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Wed Dec 07 13:51:20 2016 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Fri Feb 24 10:41:56 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -117,6 +117,9 @@
   HeapWord* _next_offset_threshold;
   size_t    _next_offset_index;      // index corresponding to that boundary
 
+  // Indicates if an object can span into this G1BlockOffsetTablePart.
+  debug_only(bool _object_can_span;)
+
   // This is the global BlockOffsetTable.
   G1BlockOffsetTable* _bot;
 
@@ -224,6 +227,7 @@
   }
 
   void set_for_starts_humongous(HeapWord* obj_top, size_t fill_size);
+  void set_object_can_span(bool can_span) NOT_DEBUG_RETURN;
 
   void print_on(outputStream* out) PRODUCT_RETURN;
 };
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp	Wed Dec 07 13:51:20 2016 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp	Fri Feb 24 10:41:56 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -107,7 +107,9 @@
 inline HeapWord* G1BlockOffsetTablePart::block_at_or_preceding(const void* addr,
                                                                bool has_max_index,
                                                                size_t max_index) const {
-  assert(_bot->offset_array(0) == 0, "objects can't cross covered areas");
+  assert(_object_can_span || _bot->offset_array(_bot->index_for(_space->bottom())) == 0,
+         "Object crossed region boundary, found offset %u instead of 0",
+         (uint) _bot->offset_array(_bot->index_for(_space->bottom())));
   size_t index = _bot->index_for(addr);
   // We must make sure that the offset table entry we use is valid.  If
   // "addr" is past the end, start at the last known one and go forward.
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Wed Dec 07 13:51:20 2016 +0100
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Fri Feb 24 10:41:56 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -267,6 +267,8 @@
   report_region_type_change(G1HeapRegionTraceType::ContinuesHumongous);
   _type.set_continues_humongous();
   _humongous_start_region = first_hr;
+
+  _bot_part.set_object_can_span(true);
 }
 
 void HeapRegion::clear_humongous() {
@@ -274,6 +276,8 @@
 
   assert(capacity() == HeapRegion::GrainBytes, "pre-condition");
   _humongous_start_region = NULL;
+
+  _bot_part.set_object_can_span(false);
 }
 
 HeapRegion::HeapRegion(uint hrm_index,