changeset 4659:2efcfec8a6dc hs24-b43

Merge
author amurillo
date Thu, 02 May 2013 09:56:32 -0700
parents 0599c2274c79 12494ffb721b
children 944e87027dc7
files
diffstat 12 files changed, 125 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/make/hotspot_version	Wed May 01 14:50:51 2013 -0700
+++ b/make/hotspot_version	Thu May 02 09:56:32 2013 -0700
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=24
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=42
+HS_BUILD_NUMBER=43
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Thu May 02 09:56:32 2013 -0700
@@ -146,43 +146,6 @@
   verify();
 }
 
-uint CollectionSetChooser::calc_min_old_cset_length() {
-  // The min old CSet region bound is based on the maximum desired
-  // number of mixed GCs after a cycle. I.e., even if some old regions
-  // look expensive, we should add them to the CSet anyway to make
-  // sure we go through the available old regions in no more than the
-  // maximum desired number of mixed GCs.
-  //
-  // The calculation is based on the number of marked regions we added
-  // to the CSet chooser in the first place, not how many remain, so
-  // that the result is the same during all mixed GCs that follow a cycle.
-
-  const size_t region_num = (size_t) _length;
-  const size_t gc_num = (size_t) G1MixedGCCountTarget;
-  size_t result = region_num / gc_num;
-  // emulate ceiling
-  if (result * gc_num < region_num) {
-    result += 1;
-  }
-  return (uint) result;
-}
-
-uint CollectionSetChooser::calc_max_old_cset_length() {
-  // The max old CSet region bound is based on the threshold expressed
-  // as a percentage of the heap size. I.e., it should bound the
-  // number of old regions added to the CSet irrespective of how many
-  // of them are available.
-
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  const size_t region_num = g1h->n_regions();
-  const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
-  size_t result = region_num * perc / 100;
-  // emulate ceiling
-  if (100 * result < region_num * perc) {
-    result += 1;
-  }
-  return (uint) result;
-}
 
 void CollectionSetChooser::add_region(HeapRegion* hr) {
   assert(!hr->isHumongous(),
--- a/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Thu May 02 09:56:32 2013 -0700
@@ -51,6 +51,8 @@
   uint _curr_index;
 
   // The number of candidate old regions added to the CSet chooser.
+  // Note: this is not updated when removing a region using
+  // remove_and_move_to_next() below.
   uint _length;
 
   // Keeps track of the start of the next array chunk to be claimed by
@@ -111,13 +113,8 @@
             hr->live_bytes() < _region_live_threshold_bytes;
   }
 
-  // Calculate the minimum number of old regions we'll add to the CSet
-  // during a mixed GC.
-  uint calc_min_old_cset_length();
-
-  // Calculate the maximum number of old regions we'll add to the CSet
-  // during a mixed GC.
-  uint calc_max_old_cset_length();
+  // Returns the number candidate old regions added
+  uint length() { return _length; }
 
   // Serial version.
   void add_region(HeapRegion *hr);
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu May 02 09:56:32 2013 -0700
@@ -1809,6 +1809,14 @@
 }
 #endif // !PRODUCT
 
+double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) {
+  // Returns the given amount of reclaimable bytes (that represents
+  // the amount of reclaimable space still to be collected) as a
+  // percentage of the current heap capacity.
+  size_t capacity_bytes = _g1->capacity();
+  return (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
+}
+
 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
                                                 const char* false_action_str) {
   CollectionSetChooser* cset_chooser = _collectionSetChooser;
@@ -1818,19 +1826,21 @@
                   ergo_format_reason("candidate old regions not available"));
     return false;
   }
+
+  // Is the amount of uncollected reclaimable space above G1HeapWastePercent?
   size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes();
-  size_t capacity_bytes = _g1->capacity();
-  double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
+  double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes);
   double threshold = (double) G1HeapWastePercent;
-  if (perc < threshold) {
+  if (reclaimable_perc <= threshold) {
     ergo_verbose4(ErgoMixedGCs,
               false_action_str,
-              ergo_format_reason("reclaimable percentage lower than threshold")
+              ergo_format_reason("reclaimable percentage not over threshold")
               ergo_format_region("candidate old regions")
               ergo_format_byte_perc("reclaimable")
               ergo_format_perc("threshold"),
               cset_chooser->remaining_regions(),
-              reclaimable_bytes, perc, threshold);
+              reclaimable_bytes,
+              reclaimable_perc, threshold);
     return false;
   }
 
@@ -1841,10 +1851,49 @@
                 ergo_format_byte_perc("reclaimable")
                 ergo_format_perc("threshold"),
                 cset_chooser->remaining_regions(),
-                reclaimable_bytes, perc, threshold);
+                reclaimable_bytes,
+                reclaimable_perc, threshold);
   return true;
 }
 
+uint G1CollectorPolicy::calc_min_old_cset_length() {
+  // The min old CSet region bound is based on the maximum desired
+  // number of mixed GCs after a cycle. I.e., even if some old regions
+  // look expensive, we should add them to the CSet anyway to make
+  // sure we go through the available old regions in no more than the
+  // maximum desired number of mixed GCs.
+  //
+  // The calculation is based on the number of marked regions we added
+  // to the CSet chooser in the first place, not how many remain, so
+  // that the result is the same during all mixed GCs that follow a cycle.
+
+  const size_t region_num = (size_t) _collectionSetChooser->length();
+  const size_t gc_num = (size_t) MAX2(G1MixedGCCountTarget, (uintx) 1);
+  size_t result = region_num / gc_num;
+  // emulate ceiling
+  if (result * gc_num < region_num) {
+    result += 1;
+  }
+  return (uint) result;
+}
+
+uint G1CollectorPolicy::calc_max_old_cset_length() {
+  // The max old CSet region bound is based on the threshold expressed
+  // as a percentage of the heap size. I.e., it should bound the
+  // number of old regions added to the CSet irrespective of how many
+  // of them are available.
+
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  const size_t region_num = g1h->n_regions();
+  const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
+  size_t result = region_num * perc / 100;
+  // emulate ceiling
+  if (100 * result < region_num * perc) {
+    result += 1;
+  }
+  return (uint) result;
+}
+
 void G1CollectorPolicy::finalize_cset(double target_pause_time_ms, EvacuationInfo& evacuation_info) {
   double young_start_time_sec = os::elapsedTime();
 
@@ -1858,7 +1907,7 @@
 
   double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
   double predicted_pause_time_ms = base_time_ms;
-  double time_remaining_ms = target_pause_time_ms - base_time_ms;
+  double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
 
   ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
                 "start choosing CSet",
@@ -1896,7 +1945,7 @@
 
   _collection_set = _inc_cset_head;
   _collection_set_bytes_used_before = _inc_cset_bytes_used_before;
-  time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms;
+  time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0);
   predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms;
 
   ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
@@ -1920,8 +1969,8 @@
   if (!gcs_are_young()) {
     CollectionSetChooser* cset_chooser = _collectionSetChooser;
     cset_chooser->verify();
-    const uint min_old_cset_length = cset_chooser->calc_min_old_cset_length();
-    const uint max_old_cset_length = cset_chooser->calc_max_old_cset_length();
+    const uint min_old_cset_length = calc_min_old_cset_length();
+    const uint max_old_cset_length = calc_max_old_cset_length();
 
     uint expensive_region_num = 0;
     bool check_time_remaining = adaptive_young_list_length();
@@ -1939,6 +1988,30 @@
         break;
       }
 
+
+      // Stop adding regions if the remaining reclaimable space is
+      // not above G1HeapWastePercent.
+      size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes();
+      double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes);
+      double threshold = (double) G1HeapWastePercent;
+      if (reclaimable_perc <= threshold) {
+        // We've added enough old regions that the amount of uncollected
+        // reclaimable space is at or below the waste threshold. Stop
+        // adding old regions to the CSet.
+        ergo_verbose5(ErgoCSetConstruction,
+                      "finish adding old regions to CSet",
+                      ergo_format_reason("reclaimable percentage not over threshold")
+                      ergo_format_region("old")
+                      ergo_format_region("max")
+                      ergo_format_byte_perc("reclaimable")
+                      ergo_format_perc("threshold"),
+                      old_cset_region_length(),
+                      max_old_cset_length,
+                      reclaimable_bytes,
+                      reclaimable_perc, threshold);
+        break;
+      }
+
       double predicted_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
       if (check_time_remaining) {
         if (predicted_time_ms > time_remaining_ms) {
@@ -1978,7 +2051,7 @@
       }
 
       // We will add this region to the CSet.
-      time_remaining_ms -= predicted_time_ms;
+      time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
       predicted_pause_time_ms += predicted_time_ms;
       cset_chooser->remove_and_move_to_next(hr);
       _g1->old_set_remove(hr);
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Thu May 02 09:56:32 2013 -0700
@@ -620,6 +620,18 @@
   bool predict_will_fit(uint young_length, double base_time_ms,
                         uint base_free_regions, double target_pause_time_ms);
 
+  // Calculate the minimum number of old regions we'll add to the CSet
+  // during a mixed GC.
+  uint calc_min_old_cset_length();
+
+  // Calculate the maximum number of old regions we'll add to the CSet
+  // during a mixed GC.
+  uint calc_max_old_cset_length();
+
+  // Returns the given amount of uncollected reclaimable space
+  // as a percentage of the current heap capacity.
+  double reclaimable_bytes_perc(size_t reclaimable_bytes);
+
 public:
 
   G1CollectorPolicy();
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu May 02 09:56:32 2013 -0700
@@ -2173,12 +2173,13 @@
         // This kind of CP cache entry does not need to match the flags byte, because
         // there is a 1-1 relation between bytecode type and CP entry type.
         ConstantPoolCacheEntry* cache = cp->entry_at(index);
-        oop result = cache->f1_as_instance();
-        if (result == NULL) {
+        if (cache->f1_as_instance() == NULL) {
           CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode),
                   handle_exception);
-          result = cache->f1_as_instance();
+          // GC might move cache while returning from VM call.
+          cache = cp->entry_at(index); // reload
         }
+        oop result = cache->f1_as_instance();
 
         VERIFY_OOP(result);
         SET_STACK_OBJECT(result, 0);
@@ -2197,23 +2198,19 @@
 
         u4 index = Bytes::get_native_u4(pc+1);
         ConstantPoolCacheEntry* cache = cp->secondary_entry_at(index);
-        oop result = cache->f1_as_instance();
 
         // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
         // This kind of CP cache entry does not need to match the flags byte, because
         // there is a 1-1 relation between bytecode type and CP entry type.
         assert(constantPoolCacheOopDesc::is_secondary_index(index), "incorrect format");
-        if (! cache->is_resolved((Bytecodes::Code) opcode)) {
+        if (cache->is_f1_null()) {
           CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD),
                   handle_exception);
-          result = cache->f1_as_instance();
+          // GC might move cache while returning from VM call.
+          cache = cp->secondary_entry_at(index); // reload
         }
 
-        VERIFY_OOP(result);
-        oop method_handle = java_lang_invoke_CallSite::target(result);
-        CHECK_NULL(method_handle);
-
-        methodOop method = cache->f1_as_method();
+        methodOop method = cache->f2_as_vfinal_method();
         VERIFY_OOP(method);
 
         if (cache->has_appendix()) {
@@ -2241,10 +2238,11 @@
         if (! cache->is_resolved((Bytecodes::Code) opcode)) {
           CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD),
                   handle_exception);
-          cache = cp->entry_at(index);
+          // GC might move cache while returning from VM call.
+          cache = cp->entry_at(index); // reload
         }
 
-        methodOop method = cache->f1_as_method();
+        methodOop method = cache->f2_as_vfinal_method();
 
         VERIFY_OOP(method);
 
--- a/src/share/vm/runtime/arguments.cpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Thu May 02 09:56:32 2013 -0700
@@ -1157,7 +1157,6 @@
     set_parnew_gc_flags();
   }
 
-  // MaxHeapSize is aligned down in collectorPolicy
   size_t max_heap = align_size_down(MaxHeapSize,
                                     CardTableRS::ct_max_alignment_constraint());
 
@@ -1195,10 +1194,6 @@
     }
 
     // Code along this path potentially sets NewSize and OldSize
-
-    assert(max_heap >= InitialHeapSize, "Error");
-    assert(max_heap >= NewSize, "Error");
-
     if (PrintGCDetails && Verbose) {
       // Too early to use gclog_or_tty
       tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT
--- a/src/share/vm/runtime/thread.cpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/runtime/thread.cpp	Thu May 02 09:56:32 2013 -0700
@@ -238,7 +238,6 @@
   CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
   _jvmti_env_iteration_count = 0;
   set_allocated_bytes(0);
-  set_trace_buffer(NULL);
   _vm_operation_started_count = 0;
   _vm_operation_completed_count = 0;
   _current_pending_monitor = NULL;
--- a/src/share/vm/runtime/thread.hpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/runtime/thread.hpp	Thu May 02 09:56:32 2013 -0700
@@ -254,7 +254,7 @@
   jlong _allocated_bytes;                       // Cumulative number of bytes allocated on
                                                 // the Java heap
 
-  TRACE_BUFFER _trace_buffer;                   // Thread-local buffer for tracing
+  TRACE_DATA _trace_data;                       // Thread-local data for tracing
 
   int   _vm_operation_started_count;            // VM_Operation support
   int   _vm_operation_completed_count;          // VM_Operation support
@@ -442,8 +442,7 @@
     return allocated_bytes;
   }
 
-  TRACE_BUFFER trace_buffer()              { return _trace_buffer; }
-  void set_trace_buffer(TRACE_BUFFER buf)  { _trace_buffer = buf; }
+  TRACE_DATA* trace_data()              { return &_trace_data; }
 
   // VM operation support
   int vm_operation_ticket()                      { return ++_vm_operation_started_count; }
--- a/src/share/vm/trace/noTraceBackend.hpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/trace/noTraceBackend.hpp	Thu May 02 09:56:32 2013 -0700
@@ -36,6 +36,11 @@
   }
 };
 
+class TraceThreadData {
+public:
+    TraceThreadData() {}
+};
+
 typedef NoTraceBackend Tracing;
 
 #endif
--- a/src/share/vm/trace/traceBackend.hpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/trace/traceBackend.hpp	Thu May 02 09:56:32 2013 -0700
@@ -52,6 +52,11 @@
   }
 };
 
+class TraceThreadData {
+public:
+    TraceThreadData() {}
+};
+
 typedef TraceBackend Tracing;
 
 #else /* INCLUDE_TRACE */
--- a/src/share/vm/trace/traceMacros.hpp	Wed May 01 14:50:51 2013 -0700
+++ b/src/share/vm/trace/traceMacros.hpp	Thu May 02 09:56:32 2013 -0700
@@ -28,7 +28,7 @@
 #define EVENT_THREAD_EXIT(thread)
 
 #define TRACE_INIT_ID(k)
-#define TRACE_BUFFER void*
+#define TRACE_DATA TraceThreadData
 
 #define TRACE_START() JNI_OK
 #define TRACE_INITIALIZE() JNI_OK