Merge
authorjmasa
Fri, 09 May 2014 19:47:41 -0700
changeset 24466 562ad028a0d8
parent 24358 8528b67f6562 (current diff)
parent 24465 3e732f375909 (diff)
child 24467 886598231964
Merge
hotspot/src/share/vm/memory/metaspace.cpp
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp	Fri May 09 08:34:22 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp	Fri May 09 19:47:41 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, 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
@@ -194,23 +194,16 @@
 }
 
 bool RSHashTable::get_cards(RegionIdx_t region_ind, CardIdx_t* cards) {
-  int ind = (int) (region_ind & capacity_mask());
-  int cur_ind = _buckets[ind];
-  SparsePRTEntry* cur;
-  while (cur_ind != NullEntry &&
-         (cur = entry(cur_ind))->r_ind() != region_ind) {
-    cur_ind = cur->next_index();
+  SparsePRTEntry* entry = get_entry(region_ind);
+  if (entry == NULL) {
+    return false;
   }
-
-  if (cur_ind == NullEntry) return false;
   // Otherwise...
-  assert(cur->r_ind() == region_ind, "Postcondition of loop + test above.");
-  assert(cur->num_valid_cards() > 0, "Inv");
-  cur->copy_cards(cards);
+  entry->copy_cards(cards);
   return true;
 }
 
-SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) {
+SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) const {
   int ind = (int) (region_ind & capacity_mask());
   int cur_ind = _buckets[ind];
   SparsePRTEntry* cur;
@@ -247,27 +240,8 @@
 }
 
 SparsePRTEntry*
-RSHashTable::entry_for_region_ind(RegionIdx_t region_ind) const {
-  assert(occupied_entries() < capacity(), "Precondition");
-  int ind = (int) (region_ind & capacity_mask());
-  int cur_ind = _buckets[ind];
-  SparsePRTEntry* cur;
-  while (cur_ind != NullEntry &&
-         (cur = entry(cur_ind))->r_ind() != region_ind) {
-    cur_ind = cur->next_index();
-  }
-
-  if (cur_ind != NullEntry) {
-    assert(cur->r_ind() == region_ind, "Loop postcondition + test");
-    return cur;
-  } else {
-    return NULL;
-  }
-}
-
-SparsePRTEntry*
 RSHashTable::entry_for_region_ind_create(RegionIdx_t region_ind) {
-  SparsePRTEntry* res = entry_for_region_ind(region_ind);
+  SparsePRTEntry* res = get_entry(region_ind);
   if (res == NULL) {
     int new_ind = alloc_entry();
     assert(0 <= new_ind && (size_t)new_ind < capacity(), "There should be room.");
@@ -365,7 +339,7 @@
 }
 
 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
-  SparsePRTEntry* e = entry_for_region_ind(region_index);
+  SparsePRTEntry* e = get_entry(region_index);
   return (e != NULL && e->contains_card(card_index));
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp	Fri May 09 08:34:22 2014 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp	Fri May 09 19:47:41 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, 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
@@ -122,12 +122,6 @@
   // Requires that the caller hold a lock preventing parallel modifying
   // operations, and that the the table be less than completely full.  If
   // an entry for "region_ind" is already in the table, finds it and
-  // returns its address; otherwise returns "NULL."
-  SparsePRTEntry* entry_for_region_ind(RegionIdx_t region_ind) const;
-
-  // Requires that the caller hold a lock preventing parallel modifying
-  // operations, and that the the table be less than completely full.  If
-  // an entry for "region_ind" is already in the table, finds it and
   // returns its address; otherwise allocates, initializes, inserts and
   // returns a new entry for "region_ind".
   SparsePRTEntry* entry_for_region_ind_create(RegionIdx_t region_ind);
@@ -158,7 +152,7 @@
 
   void add_entry(SparsePRTEntry* e);
 
-  SparsePRTEntry* get_entry(RegionIdx_t region_id);
+  SparsePRTEntry* get_entry(RegionIdx_t region_id) const;
 
   void clear();
 
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Fri May 09 08:34:22 2014 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Fri May 09 19:47:41 2014 -0700
@@ -1431,10 +1431,9 @@
   }
 
   size_t capacity_until_gc = capacity_until_GC();
-
-  if (capacity_until_gc <= committed_bytes) {
-    return 0;
-  }
+  assert(capacity_until_gc >= committed_bytes,
+         err_msg("capacity_until_gc: " SIZE_FORMAT " < committed_bytes: " SIZE_FORMAT,
+                 capacity_until_gc, committed_bytes));
 
   size_t left_until_GC = capacity_until_gc - committed_bytes;
   size_t left_to_commit = MIN2(left_until_GC, left_until_max);
@@ -1447,7 +1446,15 @@
   uint current_shrink_factor = _shrink_factor;
   _shrink_factor = 0;
 
-  const size_t used_after_gc = MetaspaceAux::capacity_bytes();
+  // Using committed_bytes() for used_after_gc is an overestimation, since the
+  // chunk free lists are included in committed_bytes() and the memory in an
+  // un-fragmented chunk free list is available for future allocations.
+  // However, if the chunk free lists becomes fragmented, then the memory may
+  // not be available for future allocations and the memory is therefore "in use".
+  // Including the chunk free lists in the definition of "in use" is therefore
+  // necessary. Not including the chunk free lists can cause capacity_until_GC to
+  // shrink below committed_bytes() and this has caused serious bugs in the past.
+  const size_t used_after_gc = MetaspaceAux::committed_bytes();
   const size_t capacity_until_GC = MetaspaceGC::capacity_until_GC();
 
   const double minimum_free_percentage = MinMetaspaceFreeRatio / 100.0;