changeset 10577:ca8e7407d350

Merge
author iignatyev
date Thu, 10 Mar 2016 14:15:15 +0100
parents 7ba5d575ff59 4c8ec9926913
children 35ffddb9c44d 47486cae8b00 55a9b972bc55
files
diffstat 11 files changed, 147 insertions(+), 122 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc/g1/g1HotCardCache.cpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/gc/g1/g1HotCardCache.cpp	Thu Mar 10 14:15:15 2016 +0100
@@ -36,7 +36,7 @@
     _use_cache = true;
 
     _hot_cache_size = (size_t)1 << G1ConcRSLogCacheSize;
-    _hot_cache = _hot_cache_memory.allocate(_hot_cache_size);
+    _hot_cache = ArrayAllocator<jbyte*, mtGC>::allocate(_hot_cache_size);
 
     reset_hot_cache_internal();
 
@@ -51,7 +51,7 @@
 G1HotCardCache::~G1HotCardCache() {
   if (default_use_cache()) {
     assert(_hot_cache != NULL, "Logic");
-    _hot_cache_memory.free();
+    ArrayAllocator<jbyte*, mtGC>::free(_hot_cache, _hot_cache_size);
     _hot_cache = NULL;
   }
 }
--- a/src/share/vm/gc/g1/g1HotCardCache.hpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/gc/g1/g1HotCardCache.hpp	Thu Mar 10 14:15:15 2016 +0100
@@ -61,7 +61,6 @@
 
   G1CardCounts      _card_counts;
 
-  ArrayAllocator<jbyte*, mtGC> _hot_cache_memory;
 
   // The card cache table
   jbyte**           _hot_cache;
--- a/src/share/vm/gc/shared/taskqueue.hpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/gc/shared/taskqueue.hpp	Thu Mar 10 14:15:15 2016 +0100
@@ -248,7 +248,6 @@
 
 template <class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
 class GenericTaskQueue: public TaskQueueSuper<N, F> {
-  ArrayAllocator<E, F> _array_allocator;
 protected:
   typedef typename TaskQueueSuper<N, F>::Age Age;
   typedef typename TaskQueueSuper<N, F>::idx_t idx_t;
--- a/src/share/vm/gc/shared/taskqueue.inline.hpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/gc/shared/taskqueue.inline.hpp	Thu Mar 10 14:15:15 2016 +0100
@@ -44,12 +44,13 @@
 
 template<class E, MEMFLAGS F, unsigned int N>
 inline void GenericTaskQueue<E, F, N>::initialize() {
-  _elems = _array_allocator.allocate(N);
+  _elems = ArrayAllocator<E, F>::allocate(N);
 }
 
 template<class E, MEMFLAGS F, unsigned int N>
 inline GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
-  FREE_C_HEAP_ARRAY(E, _elems);
+  assert(false, "This code is currently never called");
+  ArrayAllocator<E, F>::free(const_cast<E*>(_elems), N);
 }
 
 template<class E, MEMFLAGS F, unsigned int N>
--- a/src/share/vm/memory/allocation.hpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/memory/allocation.hpp	Thu Mar 10 14:15:15 2016 +0100
@@ -724,30 +724,23 @@
 // is set so that we always use malloc except for Solaris where we set the
 // limit to get mapped memory.
 template <class E, MEMFLAGS F>
-class ArrayAllocator VALUE_OBJ_CLASS_SPEC {
-  char* _addr;
-  bool _use_malloc;
-  size_t _size;
-  bool _free_in_destructor;
+class ArrayAllocator : public AllStatic {
+ private:
+  static bool should_use_malloc(size_t length);
 
-  static bool should_use_malloc(size_t size) {
-    return size < ArrayAllocatorMallocLimit;
-  }
+  static size_t size_for_malloc(size_t length);
+  static size_t size_for_mmap(size_t length);
 
-  static char* allocate_inner(size_t& size, bool& use_malloc);
+  static E* allocate_malloc(size_t length);
+  static E* allocate_mmap(size_t length);
+
+  static void free_malloc(E* addr, size_t length);
+  static void free_mmap(E* addr, size_t length);
+
  public:
-  ArrayAllocator(bool free_in_destructor = true) :
-    _addr(NULL), _use_malloc(false), _size(0), _free_in_destructor(free_in_destructor) { }
-
-  ~ArrayAllocator() {
-    if (_free_in_destructor) {
-      free();
-    }
-  }
-
-  E* allocate(size_t length);
-  E* reallocate(size_t new_length);
-  void free();
+  static E* allocate(size_t length);
+  static E* reallocate(E* old_addr, size_t old_length, size_t new_length);
+  static void free(E* addr, size_t length);
 };
 
 #endif // SHARE_VM_MEMORY_ALLOCATION_HPP
--- a/src/share/vm/memory/allocation.inline.hpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/memory/allocation.inline.hpp	Thu Mar 10 14:15:15 2016 +0100
@@ -151,66 +151,87 @@
 }
 
 template <class E, MEMFLAGS F>
-char* ArrayAllocator<E, F>::allocate_inner(size_t &size, bool &use_malloc) {
-  char* addr = NULL;
+size_t ArrayAllocator<E, F>::size_for_malloc(size_t length) {
+  return length * sizeof(E);
+}
 
-  if (use_malloc) {
-    addr = AllocateHeap(size, F);
-    if (addr == NULL && size >= (size_t)os::vm_allocation_granularity()) {
-      // malloc failed let's try with mmap instead
-      use_malloc = false;
-    } else {
-      return addr;
-    }
-  }
+template <class E, MEMFLAGS F>
+size_t ArrayAllocator<E, F>::size_for_mmap(size_t length) {
+  size_t size = length * sizeof(E);
+  int alignment = os::vm_allocation_granularity();
+  return align_size_up(size, alignment);
+}
 
+template <class E, MEMFLAGS F>
+bool ArrayAllocator<E, F>::should_use_malloc(size_t length) {
+  return size_for_malloc(length) < ArrayAllocatorMallocLimit;
+}
+
+template <class E, MEMFLAGS F>
+E* ArrayAllocator<E, F>::allocate_malloc(size_t length) {
+  return (E*)AllocateHeap(size_for_malloc(length), F);
+}
+
+template <class E, MEMFLAGS F>
+E* ArrayAllocator<E, F>::allocate_mmap(size_t length) {
+  size_t size = size_for_mmap(length);
   int alignment = os::vm_allocation_granularity();
-  size = align_size_up(size, alignment);
 
-  addr = os::reserve_memory(size, NULL, alignment, F);
+  char* addr = os::reserve_memory(size, NULL, alignment, F);
   if (addr == NULL) {
     vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "Allocator (reserve)");
   }
 
   os::commit_memory_or_exit(addr, size, !ExecMem, "Allocator (commit)");
-  return addr;
+
+  return (E*)addr;
 }
 
 template <class E, MEMFLAGS F>
 E* ArrayAllocator<E, F>::allocate(size_t length) {
-  assert(_addr == NULL, "Already in use");
+  if (should_use_malloc(length)) {
+    return allocate_malloc(length);
+  }
 
-  _size = sizeof(E) * length;
-  _use_malloc = should_use_malloc(_size);
-  _addr = allocate_inner(_size, _use_malloc);
-
-  return (E*)_addr;
+  return allocate_mmap(length);
 }
 
 template <class E, MEMFLAGS F>
-E* ArrayAllocator<E, F>::reallocate(size_t new_length) {
-  size_t new_size = sizeof(E) * new_length;
-  bool use_malloc = should_use_malloc(new_size);
-  char* new_addr = allocate_inner(new_size, use_malloc);
+E* ArrayAllocator<E, F>::reallocate(E* old_addr, size_t old_length, size_t new_length) {
+  E* new_addr = (new_length > 0)
+      ? allocate(new_length)
+      : NULL;
 
-  memcpy(new_addr, _addr, MIN2(new_size, _size));
+  if (new_addr != NULL && old_addr != NULL) {
+    memcpy(new_addr, old_addr, MIN2(old_length, new_length) * sizeof(E));
+  }
 
-  free();
-  _size = new_size;
-  _use_malloc = use_malloc;
-  _addr = new_addr;
-  return (E*)new_addr;
+  if (old_addr != NULL) {
+    free(old_addr, old_length);
+  }
+
+  return new_addr;
 }
 
 template<class E, MEMFLAGS F>
-void ArrayAllocator<E, F>::free() {
-  if (_addr != NULL) {
-    if (_use_malloc) {
-      FreeHeap(_addr);
+void ArrayAllocator<E, F>::free_malloc(E* addr, size_t /*length*/) {
+  FreeHeap(addr);
+}
+
+template<class E, MEMFLAGS F>
+void ArrayAllocator<E, F>::free_mmap(E* addr, size_t length) {
+  bool result = os::release_memory((char*)addr, size_for_mmap(length));
+  assert(result, "Failed to release memory");
+}
+
+template<class E, MEMFLAGS F>
+void ArrayAllocator<E, F>::free(E* addr, size_t length) {
+  if (addr != NULL) {
+    if (should_use_malloc(length)) {
+      free_malloc(addr, length);
     } else {
-      os::release_memory(_addr, _size);
+      free_mmap(addr, length);
     }
-    _addr = NULL;
   }
 }
 
--- a/src/share/vm/utilities/bitMap.cpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/utilities/bitMap.cpp	Thu Mar 10 14:15:15 2016 +0100
@@ -29,19 +29,25 @@
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/copy.hpp"
 
-BitMap::BitMap(bm_word_t* map, idx_t size_in_bits) :
-  _map(map), _size(size_in_bits), _map_allocator(false)
+STATIC_ASSERT(sizeof(BitMap::bm_word_t) == BytesPerWord); // "Implementation assumption."
+
+BitMap::BitMap(idx_t size_in_bits, bool in_resource_area) :
+  _map(NULL), _size(0)
 {
-  assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
+  resize(size_in_bits, in_resource_area);
 }
 
+#ifdef ASSERT
+void BitMap::verify_index(idx_t index) const {
+  assert(index < _size, "BitMap index out of bounds");
+}
 
-BitMap::BitMap(idx_t size_in_bits, bool in_resource_area) :
-  _map(NULL), _size(0), _map_allocator(false)
-{
-  assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
-  resize(size_in_bits, in_resource_area);
+void BitMap::verify_range(idx_t beg_index, idx_t end_index) const {
+  assert(beg_index <= end_index, "BitMap range error");
+  // Note that [0,0) and [size,size) are both valid ranges.
+  if (end_index != _size) verify_index(end_index);
 }
+#endif // #ifdef ASSERT
 
 void BitMap::resize(idx_t size_in_bits, bool in_resource_area) {
   idx_t old_size_in_words = size_in_words();
@@ -54,7 +60,7 @@
     Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) _map,
                          MIN2(old_size_in_words, new_size_in_words));
   } else {
-    _map = _map_allocator.reallocate(new_size_in_words);
+    _map = ArrayAllocator<bm_word_t, mtInternal>::reallocate(old_map, old_size_in_words, new_size_in_words);
   }
 
   if (new_size_in_words > old_size_in_words) {
--- a/src/share/vm/utilities/bitMap.hpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/utilities/bitMap.hpp	Thu Mar 10 14:15:15 2016 +0100
@@ -48,7 +48,6 @@
   } RangeSizeHint;
 
  private:
-  ArrayAllocator<bm_word_t, mtInternal> _map_allocator;
   bm_word_t* _map;     // First word in bitmap
   idx_t      _size;    // Size of bitmap (in bits)
 
@@ -101,9 +100,8 @@
   idx_t word_index_round_up(idx_t bit) const;
 
   // Verification.
-  inline void verify_index(idx_t index) const NOT_DEBUG_RETURN;
-  inline void verify_range(idx_t beg_index, idx_t end_index) const
-    NOT_DEBUG_RETURN;
+  void verify_index(idx_t index) const NOT_DEBUG_RETURN;
+  void verify_range(idx_t beg_index, idx_t end_index) const NOT_DEBUG_RETURN;
 
   // Statistics.
   static idx_t* _pop_count_table;
@@ -114,10 +112,10 @@
  public:
 
   // Constructs a bitmap with no map, and size 0.
-  BitMap() : _map(NULL), _size(0), _map_allocator(false) {}
+  BitMap() : _map(NULL), _size(0) {}
 
   // Constructs a bitmap with the given map and size.
-  BitMap(bm_word_t* map, idx_t size_in_bits);
+  BitMap(bm_word_t* map, idx_t size_in_bits) :_map(map), _size(size_in_bits) {}
 
   // Constructs an empty bitmap of the given size (that is, this clears the
   // new bitmap).  Allocates the map array in resource area if
@@ -307,36 +305,12 @@
     return _map.size() / _bits_per_slot;
   }
 
-  bool is_valid_index(idx_t slot_index, idx_t bit_within_slot_index) {
-    verify_bit_within_slot_index(bit_within_slot_index);
-    return (bit_index(slot_index, bit_within_slot_index) < size_in_bits());
-  }
-
-  bool at(idx_t slot_index, idx_t bit_within_slot_index) const {
-    verify_bit_within_slot_index(bit_within_slot_index);
-    return _map.at(bit_index(slot_index, bit_within_slot_index));
-  }
-
-  void set_bit(idx_t slot_index, idx_t bit_within_slot_index) {
-    verify_bit_within_slot_index(bit_within_slot_index);
-    _map.set_bit(bit_index(slot_index, bit_within_slot_index));
-  }
-
-  void clear_bit(idx_t slot_index, idx_t bit_within_slot_index) {
-    verify_bit_within_slot_index(bit_within_slot_index);
-    _map.clear_bit(bit_index(slot_index, bit_within_slot_index));
-  }
-
-  void at_put(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
-    verify_bit_within_slot_index(bit_within_slot_index);
-    _map.at_put(bit_index(slot_index, bit_within_slot_index), value);
-  }
-
-  void at_put_grow(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
-    verify_bit_within_slot_index(bit_within_slot_index);
-    _map.at_put_grow(bit_index(slot_index, bit_within_slot_index), value);
-  }
-
+  bool is_valid_index(idx_t slot_index, idx_t bit_within_slot_index);
+  bool at(idx_t slot_index, idx_t bit_within_slot_index) const;
+  void set_bit(idx_t slot_index, idx_t bit_within_slot_index);
+  void clear_bit(idx_t slot_index, idx_t bit_within_slot_index);
+  void at_put(idx_t slot_index, idx_t bit_within_slot_index, bool value);
+  void at_put_grow(idx_t slot_index, idx_t bit_within_slot_index, bool value);
   void clear();
 };
 
--- a/src/share/vm/utilities/bitMap.inline.hpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/utilities/bitMap.inline.hpp	Thu Mar 10 14:15:15 2016 +0100
@@ -28,18 +28,6 @@
 #include "runtime/atomic.inline.hpp"
 #include "utilities/bitMap.hpp"
 
-#ifdef ASSERT
-inline void BitMap::verify_index(idx_t index) const {
-  assert(index < _size, "BitMap index out of bounds");
-}
-
-inline void BitMap::verify_range(idx_t beg_index, idx_t end_index) const {
-  assert(beg_index <= end_index, "BitMap range error");
-  // Note that [0,0) and [size,size) are both valid ranges.
-  if (end_index != _size) verify_index(end_index);
-}
-#endif // #ifdef ASSERT
-
 inline void BitMap::set_bit(idx_t bit) {
   verify_index(bit);
   *word_addr(bit) |= bit_mask(bit);
@@ -344,6 +332,36 @@
   return get_next_zero_offset_inline(l_offset, r_offset);
 }
 
+inline bool BitMap2D::is_valid_index(idx_t slot_index, idx_t bit_within_slot_index) {
+  verify_bit_within_slot_index(bit_within_slot_index);
+  return (bit_index(slot_index, bit_within_slot_index) < size_in_bits());
+}
+
+inline bool BitMap2D::at(idx_t slot_index, idx_t bit_within_slot_index) const {
+  verify_bit_within_slot_index(bit_within_slot_index);
+  return _map.at(bit_index(slot_index, bit_within_slot_index));
+}
+
+inline void BitMap2D::set_bit(idx_t slot_index, idx_t bit_within_slot_index) {
+  verify_bit_within_slot_index(bit_within_slot_index);
+  _map.set_bit(bit_index(slot_index, bit_within_slot_index));
+}
+
+inline void BitMap2D::clear_bit(idx_t slot_index, idx_t bit_within_slot_index) {
+  verify_bit_within_slot_index(bit_within_slot_index);
+  _map.clear_bit(bit_index(slot_index, bit_within_slot_index));
+}
+
+inline void BitMap2D::at_put(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
+  verify_bit_within_slot_index(bit_within_slot_index);
+  _map.at_put(bit_index(slot_index, bit_within_slot_index), value);
+}
+
+inline void BitMap2D::at_put_grow(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
+  verify_bit_within_slot_index(bit_within_slot_index);
+  _map.at_put_grow(bit_index(slot_index, bit_within_slot_index), value);
+}
+
 inline void BitMap2D::clear() {
   _map.clear();
 }
--- a/src/share/vm/utilities/globalDefinitions.cpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/utilities/globalDefinitions.cpp	Thu Mar 10 14:15:15 2016 +0100
@@ -358,6 +358,20 @@
     return size_t(result);
 }
 
+
+// Test that nth_bit macro and friends behave as
+// expected, even with low-precedence operators.
+
+STATIC_ASSERT(nth_bit(3)   == 0x8);
+STATIC_ASSERT(nth_bit(1|2) == 0x8);
+
+STATIC_ASSERT(right_n_bits(3)   == 0x7);
+STATIC_ASSERT(right_n_bits(1|2) == 0x7);
+
+STATIC_ASSERT(left_n_bits(3)   == (intptr_t) LP64_ONLY(0xE000000000000000) NOT_LP64(0xE0000000));
+STATIC_ASSERT(left_n_bits(1|2) == (intptr_t) LP64_ONLY(0xE000000000000000) NOT_LP64(0xE0000000));
+
+
 #ifndef PRODUCT
 // For unit testing only
 class GlobalDefinitions {
--- a/src/share/vm/utilities/globalDefinitions.hpp	Tue Mar 01 20:30:28 2016 +0400
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Thu Mar 10 14:15:15 2016 +0100
@@ -1083,9 +1083,9 @@
 
 // get a word with the n.th or the right-most or left-most n bits set
 // (note: #define used only so that they can be used in enum constant definitions)
-#define nth_bit(n)        (n >= BitsPerWord ? 0 : OneBit << (n))
+#define nth_bit(n)        (((n) >= BitsPerWord) ? 0 : (OneBit << (n)))
 #define right_n_bits(n)   (nth_bit(n) - 1)
-#define left_n_bits(n)    (right_n_bits(n) << (n >= BitsPerWord ? 0 : (BitsPerWord - n)))
+#define left_n_bits(n)    (right_n_bits(n) << (((n) >= BitsPerWord) ? 0 : (BitsPerWord - (n))))
 
 // bit-operations using a mask m
 inline void   set_bits    (intptr_t& x, intptr_t m) { x |= m; }