Merge
authorrbackman
Fri, 24 Feb 2017 15:42:47 +0100
changeset 46288 5104e67b9143
parent 46287 ebfe616a604b (current diff)
parent 46286 c112671e114e (diff)
child 46289 1904e7ec236e
Merge
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.cpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.cpp	Fri Feb 24 15:42:47 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -27,7 +27,6 @@
 #include "gc/g1/g1AllocRegion.inline.hpp"
 #include "gc/g1/g1EvacStats.inline.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/g1/g1MarkSweep.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
 
@@ -333,11 +332,14 @@
   }
 }
 
+bool G1ArchiveAllocator::_archive_check_enabled = false;
+G1ArchiveRegionMap G1ArchiveAllocator::_archive_region_map;
+
 G1ArchiveAllocator* G1ArchiveAllocator::create_allocator(G1CollectedHeap* g1h) {
   // Create the archive allocator, and also enable archive object checking
   // in mark-sweep, since we will be creating archive regions.
   G1ArchiveAllocator* result =  new G1ArchiveAllocator(g1h);
-  G1MarkSweep::enable_archive_object_check();
+  enable_archive_object_check();
   return result;
 }
 
@@ -362,7 +364,7 @@
   _max = _bottom + HeapRegion::min_region_size_in_words();
 
   // Tell mark-sweep that objects in this region are not to be marked.
-  G1MarkSweep::set_range_archive(MemRegion(_bottom, HeapRegion::GrainWords), true);
+  set_range_archive(MemRegion(_bottom, HeapRegion::GrainWords), true);
 
   // Since we've modified the old set, call update_sizes.
   _g1h->g1mm()->update_sizes();
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.hpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.hpp	Fri Feb 24 15:42:47 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -312,12 +312,19 @@
   virtual void waste(size_t& wasted, size_t& undo_wasted);
 };
 
+// G1ArchiveRegionMap is a boolean array used to mark G1 regions as
+// archive regions.  This allows a quick check for whether an object
+// should not be marked because it is in an archive region.
+class G1ArchiveRegionMap : public G1BiasedMappedArray<bool> {
+protected:
+  bool default_value() const { return false; }
+};
+
 // G1ArchiveAllocator is used to allocate memory in archive
 // regions. Such regions are not modifiable by GC, being neither
 // scavenged nor compacted, or even marked in the object header.
 // They can contain no pointers to non-archive heap regions,
 class G1ArchiveAllocator : public CHeapObj<mtGC> {
-
 protected:
   G1CollectedHeap* _g1h;
 
@@ -378,6 +385,24 @@
     _summary_bytes_used = 0;
   }
 
+  // Create the _archive_region_map which is used to identify archive objects.
+  static inline void enable_archive_object_check();
+
+  // Set the regions containing the specified address range as archive/non-archive.
+  static inline void set_range_archive(MemRegion range, bool is_archive);
+
+  static inline bool is_archive_object(oop object);
+
+private:
+  static bool _archive_check_enabled;
+  static G1ArchiveRegionMap  _archive_region_map;
+
+  // Check if an object is in an archive region using the _archive_region_map.
+  static inline bool in_archive_range(oop object);
+
+  // Check if archive object checking is enabled, to avoid calling in_archive_range
+  // unnecessarily.
+  static inline bool archive_check_enabled();
 };
 
 #endif // SHARE_VM_GC_G1_G1ALLOCATOR_HPP
--- a/hotspot/src/share/vm/gc/g1/g1Allocator.inline.hpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1Allocator.inline.hpp	Fri Feb 24 15:42:47 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -55,4 +55,37 @@
   }
 }
 
+// Create the _archive_region_map which is used to identify archive objects.
+inline void G1ArchiveAllocator::enable_archive_object_check() {
+  assert(!_archive_check_enabled, "archive range check already enabled");
+  _archive_check_enabled = true;
+  size_t length = Universe::heap()->max_capacity();
+  _archive_region_map.initialize((HeapWord*)Universe::heap()->base(),
+                                 (HeapWord*)Universe::heap()->base() + length,
+                                 HeapRegion::GrainBytes);
+}
+
+// Set the regions containing the specified address range as archive/non-archive.
+inline void G1ArchiveAllocator::set_range_archive(MemRegion range, bool is_archive) {
+  assert(_archive_check_enabled, "archive range check not enabled");
+  _archive_region_map.set_by_address(range, is_archive);
+}
+
+// Check if an object is in an archive region using the _archive_region_map.
+inline bool G1ArchiveAllocator::in_archive_range(oop object) {
+  // This is the out-of-line part of is_archive_object test, done separately
+  // to avoid additional performance impact when the check is not enabled.
+  return _archive_region_map.get_by_address((HeapWord*)object);
+}
+
+// Check if archive object checking is enabled, to avoid calling in_archive_range
+// unnecessarily.
+inline bool G1ArchiveAllocator::archive_check_enabled() {
+  return _archive_check_enabled;
+}
+
+inline bool G1ArchiveAllocator::is_archive_object(oop object) {
+  return (archive_check_enabled() && in_archive_range(object));
+}
+
 #endif // SHARE_VM_GC_G1_G1ALLOCATOR_HPP
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Fri Feb 24 15:42:47 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	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Fri Feb 24 15:42:47 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	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.inline.hpp	Fri Feb 24 15:42:47 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/g1CollectedHeap.cpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Fri Feb 24 15:42:47 2017 +0100
@@ -699,9 +699,9 @@
   // when mmap'ing archived heap data in, so pre-touching is wasted.
   FlagSetting fs(AlwaysPreTouch, false);
 
-  // Enable archive object checking in G1MarkSweep. We have to let it know
+  // Enable archive object checking used by G1MarkSweep. We have to let it know
   // about each archive range, so that objects in those ranges aren't marked.
-  G1MarkSweep::enable_archive_object_check();
+  G1ArchiveAllocator::enable_archive_object_check();
 
   // For each specified MemRegion range, allocate the corresponding G1
   // regions and mark them as archive regions. We expect the ranges in
@@ -773,7 +773,7 @@
     }
 
     // Notify mark-sweep of the archive range.
-    G1MarkSweep::set_range_archive(curr_range, true);
+    G1ArchiveAllocator::set_range_archive(curr_range, true);
   }
   return true;
 }
@@ -924,7 +924,7 @@
     }
 
     // Notify mark-sweep that this is no longer an archive range.
-    G1MarkSweep::set_range_archive(ranges[i], false);
+    G1ArchiveAllocator::set_range_archive(ranges[i], false);
   }
 
   if (uncommitted_regions != 0) {
--- a/hotspot/src/share/vm/gc/g1/g1HeapVerifier.cpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1HeapVerifier.cpp	Fri Feb 24 15:42:47 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -25,10 +25,10 @@
 #include "precompiled.hpp"
 #include "logging/log.hpp"
 #include "gc/g1/concurrentMarkThread.hpp"
+#include "gc/g1/g1Allocator.inline.hpp"
 #include "gc/g1/g1CollectedHeap.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1HeapVerifier.hpp"
-#include "gc/g1/g1MarkSweep.hpp"
 #include "gc/g1/g1Policy.hpp"
 #include "gc/g1/g1RemSet.hpp"
 #include "gc/g1/g1RootProcessor.hpp"
@@ -239,7 +239,7 @@
 
   template <class T> void do_oop_work(T *p) {
     oop obj = oopDesc::load_decode_heap_oop(p);
-    guarantee(obj == NULL || G1MarkSweep::in_archive_range(obj),
+    guarantee(obj == NULL || G1ArchiveAllocator::is_archive_object(obj),
               "Archive object at " PTR_FORMAT " references a non-archive object at " PTR_FORMAT,
               p2i(p), p2i(obj));
   }
--- a/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp	Fri Feb 24 15:42:47 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
@@ -56,9 +56,6 @@
 
 class HeapRegion;
 
-bool G1MarkSweep::_archive_check_enabled = false;
-G1ArchiveRegionMap G1MarkSweep::_archive_region_map;
-
 void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
                                       bool clear_all_softrefs) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
@@ -314,26 +311,6 @@
 
 }
 
-void G1MarkSweep::enable_archive_object_check() {
-  assert(!_archive_check_enabled, "archive range check already enabled");
-  _archive_check_enabled = true;
-  size_t length = Universe::heap()->max_capacity();
-  _archive_region_map.initialize((HeapWord*)Universe::heap()->base(),
-                                 (HeapWord*)Universe::heap()->base() + length,
-                                 HeapRegion::GrainBytes);
-}
-
-void G1MarkSweep::set_range_archive(MemRegion range, bool is_archive) {
-  assert(_archive_check_enabled, "archive range check not enabled");
-  _archive_region_map.set_by_address(range, is_archive);
-}
-
-bool G1MarkSweep::in_archive_range(oop object) {
-  // This is the out-of-line part of is_archive_object test, done separately
-  // to avoid additional performance impact when the check is not enabled.
-  return _archive_region_map.get_by_address((HeapWord*)object);
-}
-
 void G1MarkSweep::prepare_compaction_work(G1PrepareCompactClosure* blk) {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   g1h->heap_region_iterate(blk);
--- a/hotspot/src/share/vm/gc/g1/g1MarkSweep.hpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1MarkSweep.hpp	Fri Feb 24 15:42:47 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, 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
@@ -55,23 +55,7 @@
   static STWGCTimer* gc_timer() { return GenMarkSweep::_gc_timer; }
   static SerialOldTracer* gc_tracer() { return GenMarkSweep::_gc_tracer; }
 
-  // Create the _archive_region_map which is used to identify archive objects.
-  static void enable_archive_object_check();
-
-  // Set the regions containing the specified address range as archive/non-archive.
-  static void set_range_archive(MemRegion range, bool is_archive);
-
-  // Check if an object is in an archive region using the _archive_region_map.
-  static bool in_archive_range(oop object);
-
-  // Check if archive object checking is enabled, to avoid calling in_archive_range
-  // unnecessarily.
-  static bool archive_check_enabled() { return G1MarkSweep::_archive_check_enabled; }
-
- private:
-  static bool _archive_check_enabled;
-  static G1ArchiveRegionMap  _archive_region_map;
-
+private:
   // Mark live objects
   static void mark_sweep_phase1(bool& marked_for_deopt,
                                 bool clear_all_softrefs);
@@ -109,12 +93,4 @@
   bool doHeapRegion(HeapRegion* hr);
 };
 
-// G1ArchiveRegionMap is a boolean array used to mark G1 regions as
-// archive regions.  This allows a quick check for whether an object
-// should not be marked because it is in an archive region.
-class G1ArchiveRegionMap : public G1BiasedMappedArray<bool> {
-protected:
-  bool default_value() const { return false; }
-};
-
 #endif // SHARE_VM_GC_G1_G1MARKSWEEP_HPP
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Fri Feb 24 15:42:47 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,
--- a/hotspot/src/share/vm/gc/serial/markSweep.inline.hpp	Fri Feb 24 13:48:16 2017 +0100
+++ b/hotspot/src/share/vm/gc/serial/markSweep.inline.hpp	Fri Feb 24 15:42:47 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -30,13 +30,12 @@
 #include "oops/markOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #if INCLUDE_ALL_GCS
-#include "gc/g1/g1MarkSweep.hpp"
+#include "gc/g1/g1Allocator.inline.hpp"
 #endif // INCLUDE_ALL_GCS
 
 inline bool MarkSweep::is_archive_object(oop object) {
 #if INCLUDE_ALL_GCS
-  return (G1MarkSweep::archive_check_enabled() &&
-          G1MarkSweep::in_archive_range(object));
+  return G1ArchiveAllocator::is_archive_object(object);
 #else
   return false;
 #endif