Merge
authorjprovino
Sat, 14 Nov 2015 18:26:35 +0000
changeset 34140 43b8383b63e2
parent 33814 7d2d5871559d (current diff)
parent 34139 0728fe06ccf8 (diff)
child 34141 1030e4216817
child 34142 5a9fb81665b3
Merge
--- a/hotspot/src/share/vm/gc/cms/promotionInfo.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/cms/promotionInfo.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -233,41 +233,11 @@
   _tracking = true;
 }
 
-#define CMSPrintPromoBlockInfo 1
-
 void PromotionInfo::stopTrackingPromotions(uint worker_id) {
   assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
          "spooling inconsistency?");
   _firstIndex = _nextIndex = 1;
   _tracking = false;
-  if (CMSPrintPromoBlockInfo > 1) {
-    print_statistics(worker_id);
-  }
-}
-
-void PromotionInfo::print_statistics(uint worker_id) const {
-  assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex,
-         "Else will undercount");
-  assert(CMSPrintPromoBlockInfo > 0, "Else unnecessary call");
-  // Count the number of blocks and slots in the free pool
-  size_t slots  = 0;
-  size_t blocks = 0;
-  for (SpoolBlock* cur_spool = _spareSpool;
-       cur_spool != NULL;
-       cur_spool = cur_spool->nextSpoolBlock) {
-    // the first entry is just a self-pointer; indices 1 through
-    // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
-    assert((void*)cur_spool->displacedHdr == (void*)&cur_spool->displacedHdr,
-           "first entry of displacedHdr should be self-referential");
-    slots += cur_spool->bufferSize - 1;
-    blocks++;
-  }
-  if (_spoolHead != NULL) {
-    slots += _spoolHead->bufferSize - 1;
-    blocks++;
-  }
-  gclog_or_tty->print_cr(" [worker %d] promo_blocks = " SIZE_FORMAT ", promo_slots = " SIZE_FORMAT,
-                         worker_id, blocks, slots);
 }
 
 // When _spoolTail is not NULL, then the slot <_spoolTail, _nextIndex>
--- a/hotspot/src/share/vm/gc/cms/promotionInfo.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/cms/promotionInfo.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -207,7 +207,6 @@
   }
 
   void print_on(outputStream* st) const;
-  void print_statistics(uint worker_id) const;
 };
 
 
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -2278,6 +2278,10 @@
   // And as a result the region we'll allocate will be humongous.
   guarantee(is_humongous(word_size), "sanity");
 
+  // _filler_array_max_size is set to humongous object threshold
+  // but temporarily change it to use CollectedHeap::fill_with_object().
+  SizeTFlagSetting fs(_filler_array_max_size, word_size);
+
   for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) {
     // Let's use the existing mechanism for the allocation
     HeapWord* dummy_obj = humongous_obj_allocate(word_size,
@@ -3561,6 +3565,9 @@
             }
           }
         }
+        assert(hrrs.n_yielded() == r->rem_set()->occupied(),
+               "Remembered set hash maps out of sync, cur: " SIZE_FORMAT " entries, next: " SIZE_FORMAT " entries",
+               hrrs.n_yielded(), r->rem_set()->occupied());
         r->rem_set()->clear_locked();
       }
       assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
@@ -3848,6 +3855,13 @@
 
         evacuation_info.set_collectionset_regions(g1_policy()->cset_region_length());
 
+        // Make sure the remembered sets are up to date. This needs to be
+        // done before register_humongous_regions_with_cset(), because the
+        // remembered sets are used there to choose eager reclaim candidates.
+        // If the remembered sets are not up to date we might miss some
+        // entries that need to be handled.
+        g1_rem_set()->cleanupHRRS();
+
         register_humongous_regions_with_cset();
 
         assert(check_cset_fast_test(), "Inconsistency in the InCSetState table.");
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -467,8 +467,19 @@
   }
 
   size_t free_bytes = (base_free_regions - young_length) * HeapRegion::GrainBytes;
-  if ((2.0 /* magic */ * _predictor.sigma()) * bytes_to_copy > free_bytes) {
-    // end condition 3: out-of-space (conservatively!)
+
+  // When copying, we will likely need more bytes free than is live in the region.
+  // Add some safety margin to factor in the confidence of our guess, and the
+  // natural expected waste.
+  // (100.0 / G1ConfidencePercent) is a scale factor that expresses the uncertainty
+  // of the calculation: the lower the confidence, the more headroom.
+  // (100 + TargetPLABWastePct) represents the increase in expected bytes during
+  // copying due to anticipated waste in the PLABs.
+  double safety_factor = (100.0 / G1ConfidencePercent) * (100 + TargetPLABWastePct) / 100.0;
+  size_t expected_bytes_to_copy = safety_factor * bytes_to_copy;
+
+  if (expected_bytes_to_copy > free_bytes) {
+    // end condition 3: out-of-space
     return false;
   }
 
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -272,7 +272,7 @@
   size_t _pending_cards;
 
 public:
-  G1Predictions& predictor() { return _predictor; }
+  const G1Predictions& predictor() const { return _predictor; }
 
   // Accessors
 
--- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -84,7 +84,7 @@
 
  public:
   G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id, size_t young_cset_length);
-  ~G1ParScanThreadState();
+  virtual ~G1ParScanThreadState();
 
   void set_ref_processor(ReferenceProcessor* rp) { _scanner.set_ref_processor(rp); }
 
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -307,7 +307,6 @@
 }
 
 void G1RemSet::prepare_for_oops_into_collection_set_do() {
-  cleanupHRRS();
   _g1->set_refine_cte_cl_concurrency(false);
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   dcqs.concatenate_logs();
--- a/hotspot/src/share/vm/gc/parallel/pcTasks.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/parallel/pcTasks.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -52,8 +52,6 @@
 
   ResourceMark rm;
 
-  NOT_PRODUCT(GCTraceTime tm("ThreadRootsMarkingTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
 
@@ -81,8 +79,6 @@
 void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
   ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm);
@@ -152,8 +148,6 @@
 {
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(GCTraceTime tm("RefProcTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
   ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm);
@@ -208,9 +202,6 @@
 void StealMarkingTask::do_it(GCTaskManager* manager, uint which) {
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(GCTraceTime tm("StealMarkingTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
-
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
   ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm);
@@ -240,9 +231,6 @@
 void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(GCTraceTime tm("StealRegionCompactionTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
-
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
 
@@ -307,9 +295,6 @@
 
 void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
 
-  NOT_PRODUCT(GCTraceTime tm("UpdateDensePrefixTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
-
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
 
@@ -322,9 +307,6 @@
 void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
   assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
 
-  NOT_PRODUCT(GCTraceTime tm("DrainStacksCompactionTask",
-    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
-
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(which);
 
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -1319,3 +1319,11 @@
   }
   return retVal;
 }
+
+void GenCollectedHeap::stop() {
+#if INCLUDE_ALL_GCS
+  if (UseConcMarkSweepGC) {
+    ConcurrentMarkSweepThread::stop();
+  }
+#endif
+}
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -499,6 +499,9 @@
 protected:
   void gc_prologue(bool full);
   void gc_epilogue(bool full);
+
+public:
+  void stop();
 };
 
 #endif // SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
--- a/hotspot/src/share/vm/logging/logPrefix.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/logging/logPrefix.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -27,12 +27,17 @@
 #include "gc/shared/gcId.hpp"
 #include "logging/logTag.hpp"
 
-// Prefixes prepend each log message for a specified tagset with the given prefix.
-// A prefix consists of a format string and a value or callback. Prefixes are added
-// after the decorations but before the log message.
+// Prefixes prepend each log message for a specified tagset with a given prefix.
+// These prefixes are written before the log message but after the log decorations.
+//
+// A prefix is defined as a function that takes a buffer (with some size) as argument.
+// This function will be called for each log message, and should write the prefix
+// to the given buffer. The function should return how many characters it wrote,
+// which should never exceed the given size.
 //
 // List of prefixes for specific tags and/or tagsets.
-// Syntax: LOG_PREFIX(<printf format>, <value/callback for value>, LOG_TAGS(<chosen log tags>))
+// Syntax: LOG_PREFIX(<name of prefixer function>, LOG_TAGS(<chosen log tags>))
+// Where the prefixer function matches the following signature: size_t (*)(char*, size_t)
 #define LOG_PREFIX_LIST // Currently unused/empty
 
 // The empty prefix, used when there's no prefix defined.
@@ -44,12 +49,12 @@
   }
 };
 
-#define LOG_PREFIX(fmt, fn, ...) \
+#define LOG_PREFIX(fn, ...) \
 template <> struct LogPrefix<__VA_ARGS__> { \
   static size_t prefix(char* buf, size_t len) { \
-    int ret = jio_snprintf(buf, len, fmt, fn); \
-    assert(ret >= 0, \
-           "Failed to prefix log message using prefix ('%s', '%s'), log buffer too small?", fmt, #fn); \
+    DEBUG_ONLY(buf[0] = '\0';) \
+    size_t ret = fn(buf, len); \
+    assert(ret == strlen(buf), "Length mismatch ret (" SIZE_FORMAT ") != buf length (" SIZE_FORMAT ")", ret, strlen(buf)); \
     return ret; \
   } \
 };
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -74,6 +74,7 @@
   }                                                                   \
 } while(0)
 
+char*  Arguments::_jvm_flags_file               = NULL;
 char** Arguments::_jvm_flags_array              = NULL;
 int    Arguments::_num_jvm_flags                = 0;
 char** Arguments::_jvm_args_array               = NULL;
@@ -3932,7 +3933,6 @@
 #endif // PRODUCT
 
 jint Arguments::insert_vm_options_file(const JavaVMInitArgs* args,
-                                       char** flags_file,
                                        char** vm_options_file,
                                        const int vm_options_file_pos,
                                        ScopedVMInitArgs *vm_options_file_args,
@@ -3951,13 +3951,12 @@
 }
 
 jint Arguments::match_special_option_and_act(const JavaVMInitArgs* args,
-                                             char ** flags_file,
                                              char ** vm_options_file,
-                                             ScopedVMInitArgs* vm_options_file_args,
                                              ScopedVMInitArgs* args_out) {
   // Remaining part of option string
   const char* tail;
   int   vm_options_file_pos = -1;
+  ScopedVMInitArgs vm_options_file_args;
 
   for (int index = 0; index < args->nOptions; index++) {
     const JavaVMOption* option = args->options + index;
@@ -3965,12 +3964,7 @@
       continue;
     }
     if (match_option(option, "-XX:Flags=", &tail)) {
-      *flags_file = (char *) tail;
-      if (*flags_file == NULL) {
-        jio_fprintf(defaultStream::error_stream(),
-                    "Cannot copy flags_file name.\n");
-        return JNI_ENOMEM;
-      }
+      Arguments::set_jvm_flags_file(tail);
       continue;
     }
     if (match_option(option, "-XX:VMOptionsFile=", &tail)) {
@@ -3986,9 +3980,9 @@
         *vm_options_file = (char *) tail;
         vm_options_file_pos = index;  // save position of -XX:VMOptionsFile
         // If there's a VMOptionsFile, parse that (also can set flags_file)
-        jint code = insert_vm_options_file(args, flags_file, vm_options_file,
+        jint code = insert_vm_options_file(args, vm_options_file,
                                            vm_options_file_pos,
-                                           vm_options_file_args, args_out);
+                                           &vm_options_file_args, args_out);
         if (code != JNI_OK) {
           return code;
         }
@@ -4084,16 +4078,12 @@
 
   // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
   const char* hotspotrc = ".hotspotrc";
-  char* flags_file = NULL;
   char* vm_options_file = NULL;
   bool settings_file_specified = false;
   bool needs_hotspotrc_warning = false;
   ScopedVMInitArgs java_tool_options_args;
   ScopedVMInitArgs java_options_args;
   ScopedVMInitArgs modified_cmd_line_args;
-  // Pass in vm_options_file_args to keep memory for flags_file from being
-  // deallocated if found in the vm options file.
-  ScopedVMInitArgs vm_options_file_args;
 
   jint code =
       parse_java_tool_options_environment_variable(&java_tool_options_args);
@@ -4107,13 +4097,12 @@
   }
 
   code = match_special_option_and_act(java_tool_options_args.get(),
-                                      &flags_file, NULL, NULL, NULL);
+                                      NULL, NULL);
   if (code != JNI_OK) {
     return code;
   }
 
-  code = match_special_option_and_act(args, &flags_file, &vm_options_file,
-                                      &vm_options_file_args,
+  code = match_special_option_and_act(args, &vm_options_file,
                                       &modified_cmd_line_args);
   if (code != JNI_OK) {
     return code;
@@ -4125,12 +4114,13 @@
     args = modified_cmd_line_args.get();
   }
 
-  code = match_special_option_and_act(java_options_args.get(), &flags_file,
-                                      NULL, NULL, NULL);
+  code = match_special_option_and_act(java_options_args.get(),
+                                      NULL, NULL);
   if (code != JNI_OK) {
     return code;
   }
 
+  const char * flags_file = Arguments::get_jvm_flags_file();
   settings_file_specified = (flags_file != NULL);
 
   if (IgnoreUnrecognizedVMOptions) {
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -244,6 +244,8 @@
 
  private:
 
+  // a pointer to the flags file name if it is specified
+  static char*  _jvm_flags_file;
   // an array containing all flags specified in the .hotspotrc file
   static char** _jvm_flags_array;
   static int    _num_jvm_flags;
@@ -378,15 +380,12 @@
   static jint parse_vm_options_file(const char* file_name, ScopedVMInitArgs* vm_args);
   static jint parse_options_buffer(const char* name, char* buffer, const size_t buf_len, ScopedVMInitArgs* vm_args);
   static jint insert_vm_options_file(const JavaVMInitArgs* args,
-                                     char** flags_file,
                                      char** vm_options_file,
                                      const int vm_options_file_pos,
                                      ScopedVMInitArgs* vm_options_file_args,
                                      ScopedVMInitArgs* args_out);
   static jint match_special_option_and_act(const JavaVMInitArgs* args,
-                                           char** flags_file,
                                            char** vm_options_file,
-                                           ScopedVMInitArgs* vm_options_file_args,
                                            ScopedVMInitArgs* args_out);
 
   static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
@@ -514,6 +513,14 @@
   static void print_on(outputStream* st);
   static void print_summary_on(outputStream* st);
 
+  // convenient methods to get and set jvm_flags_file
+  static const char* get_jvm_flags_file()  { return _jvm_flags_file; }
+  static void set_jvm_flags_file(const char *value) {
+    if (_jvm_flags_file != NULL) {
+      os::free(_jvm_flags_file);
+    }
+    _jvm_flags_file = os::strdup_check_oom(value);
+  }
   // convenient methods to obtain / print jvm_flags and jvm_args
   static const char* jvm_flags()           { return build_resource_string(_jvm_flags_array, _num_jvm_flags); }
   static const char* jvm_args()            { return build_resource_string(_jvm_args_array, _num_jvm_args); }
--- a/hotspot/src/share/vm/runtime/globals.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -2523,9 +2523,6 @@
   develop(bool, TraceWorkGang, false,                                       \
           "Trace activities of work gangs")                                 \
                                                                             \
-  product(bool, TraceParallelOldGCTasks, false,                             \
-          "Trace multithreaded GC activity")                                \
-                                                                            \
   develop(bool, TraceBlockOffsetTable, false,                               \
           "Print BlockOffsetTable maps")                                    \
                                                                             \
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -56,6 +56,7 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SetVMFlagDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMInfoDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false));
@@ -323,6 +324,10 @@
   }
 }
 
+void VMInfoDCmd::execute(DCmdSource source, TRAPS) {
+  VMError::print_vm_info(_output);
+}
+
 void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
   if (!DisableExplicitGC) {
     Universe::heap()->collect(GCCause::_dcmd_gc_run);
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -213,6 +213,23 @@
   virtual void execute(DCmdSource source, TRAPS);
 };
 
+class VMInfoDCmd : public DCmd {
+public:
+  VMInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
+  static const char* name() { return "VM.info"; }
+  static const char* description() {
+    return "Print information about JVM environment and status.";
+  }
+  static const char* impact() { return "Low"; }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments() { return 0; }
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
 class SystemGCDCmd : public DCmd {
 public:
   SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Sat Nov 14 18:26:35 2015 +0000
@@ -201,7 +201,7 @@
 #endif // ZERO
 }
 
-void VMError::print_oom_reasons(outputStream* st) {
+static void print_oom_reasons(outputStream* st) {
   st->print_cr("# Possible reasons:");
   st->print_cr("#   The system is out of physical RAM or swap space");
   st->print_cr("#   In 32 bit mode, the process size limit was hit");
@@ -217,7 +217,7 @@
   st->print_cr("# This output file may be truncated or incomplete.");
 }
 
-const char* VMError::gc_mode() {
+static const char* gc_mode() {
   if (UseG1GC)            return "g1 gc";
   if (UseParallelGC)      return "parallel gc";
   if (UseConcMarkSweepGC) return "concurrent mark sweep gc";
@@ -225,6 +225,33 @@
   return "ERROR in GC mode";
 }
 
+static void report_vm_version(outputStream* st, char* buf, int buflen) {
+   // VM version
+   st->print_cr("#");
+   JDK_Version::current().to_string(buf, buflen);
+   const char* runtime_name = JDK_Version::runtime_name() != NULL ?
+                                JDK_Version::runtime_name() : "";
+   const char* runtime_version = JDK_Version::runtime_version() != NULL ?
+                                JDK_Version::runtime_version() : "";
+   st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version);
+   // This is the long version with some default settings added
+   st->print_cr("# Java VM: %s (%s, %s%s%s%s%s, %s, %s)",
+                 Abstract_VM_Version::vm_name(),
+                 Abstract_VM_Version::vm_release(),
+                 Abstract_VM_Version::vm_info_string(),
+                 TieredCompilation ? ", tiered" : "",
+#if INCLUDE_JVMCI
+                 EnableJVMCI ? ", jvmci" : "",
+                 UseJVMCICompiler ? ", jvmci compiler" : "",
+#else
+                 "", "",
+#endif
+                 UseCompressedOops ? ", compressed oops" : "",
+                 gc_mode(),
+                 Abstract_VM_Version::vm_platform_string()
+               );
+}
+
 // This is the main function to report a fatal error. Only one thread can
 // call this function, so we don't need to worry about MT-safety. But it's
 // possible that the error handler itself may crash or die on an internal
@@ -401,30 +428,7 @@
 
   STEP(90, "(printing Java version string)")
 
-     // VM version
-     st->print_cr("#");
-     JDK_Version::current().to_string(buf, sizeof(buf));
-     const char* runtime_name = JDK_Version::runtime_name() != NULL ?
-                                  JDK_Version::runtime_name() : "";
-     const char* runtime_version = JDK_Version::runtime_version() != NULL ?
-                                  JDK_Version::runtime_version() : "";
-     st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version);
-     // This is the long version with some default settings added
-     st->print_cr("# Java VM: %s (%s, %s%s%s%s%s, %s, %s)",
-                   Abstract_VM_Version::vm_name(),
-                   Abstract_VM_Version::vm_release(),
-                   Abstract_VM_Version::vm_info_string(),
-                   TieredCompilation ? ", tiered" : "",
-#if INCLUDE_JVMCI
-                   EnableJVMCI ? ", jvmci" : "",
-                   UseJVMCICompiler ? ", jvmci compiler" : "",
-#else
-                   "", "",
-#endif
-                   UseCompressedOops ? ", compressed oops" : "",
-                   gc_mode(),
-                   Abstract_VM_Version::vm_platform_string()
-                 );
+     report_vm_version(st, buf, sizeof(buf));
 
   STEP(100, "(printing problematic frame)")
 
@@ -715,7 +719,6 @@
      if (_verbose && Universe::is_fully_initialized()) {
        Universe::heap()->print_on_error(st);
        st->cr();
-
        st->print_cr("Polling page: " INTPTR_FORMAT, p2i(os::get_polling_page()));
        st->cr();
      }
@@ -826,6 +829,147 @@
 # undef END
 }
 
+// Report for the vm_info_cmd. This prints out the information above omitting
+// crash and thread specific information.  If output is added above, it should be added
+// here also, if it is safe to call during a running process.
+void VMError::print_vm_info(outputStream* st) {
+
+  char buf[O_BUFLEN];
+  report_vm_version(st, buf, sizeof(buf));
+
+  // STEP("(printing summary)")
+
+  st->cr();
+  st->print_cr("---------------  S U M M A R Y ------------");
+  st->cr();
+
+  // STEP("(printing VM option summary)")
+
+  // VM options
+  Arguments::print_summary_on(st);
+  st->cr();
+
+  // STEP("(printing summary machine and OS info)")
+
+  os::print_summary_info(st, buf, sizeof(buf));
+
+  // STEP("(printing date and time)")
+
+  os::print_date_and_time(st, buf, sizeof(buf));
+
+  // Skip: STEP("(printing thread)")
+
+  // STEP("(printing process)")
+
+  st->cr();
+  st->print_cr("---------------  P R O C E S S  ---------------");
+  st->cr();
+
+  // STEP("(printing number of OutOfMemoryError and StackOverflow exceptions)")
+
+  if (Exceptions::has_exception_counts()) {
+    st->print_cr("OutOfMemory and StackOverflow Exception counts:");
+    Exceptions::print_exception_counts_on_error(st);
+    st->cr();
+  }
+
+  // STEP("(printing compressed oops mode")
+
+  if (UseCompressedOops) {
+    Universe::print_compressed_oops_mode(st);
+    if (UseCompressedClassPointers) {
+      Metaspace::print_compressed_class_space(st);
+    }
+    st->cr();
+  }
+
+  // STEP("(printing heap information)")
+
+  if (Universe::is_fully_initialized()) {
+    Universe::heap()->print_on_error(st);
+    st->cr();
+    st->print_cr("Polling page: " INTPTR_FORMAT, p2i(os::get_polling_page()));
+    st->cr();
+  }
+
+  // STEP("(printing code cache information)")
+
+  if (Universe::is_fully_initialized()) {
+    // print code cache information before vm abort
+    CodeCache::print_summary(st);
+    st->cr();
+  }
+
+  // STEP("(printing ring buffers)")
+
+  Events::print_all(st);
+  st->cr();
+
+  // STEP("(printing dynamic libraries)")
+
+  // dynamic libraries, or memory map
+  os::print_dll_info(st);
+  st->cr();
+
+  // STEP("(printing VM options)")
+
+  // VM options
+  Arguments::print_on(st);
+  st->cr();
+
+  // STEP("(printing warning if internal testing API used)")
+
+  if (WhiteBox::used()) {
+    st->print_cr("Unsupported internal testing APIs have been used.");
+    st->cr();
+  }
+
+  // STEP("(printing all environment variables)")
+
+  os::print_environment_variables(st, env_list);
+  st->cr();
+
+  // STEP("(printing signal handlers)")
+
+  os::print_signal_handlers(st, buf, sizeof(buf));
+  st->cr();
+
+  // STEP("(Native Memory Tracking)")
+
+  MemTracker::error_report(st);
+
+  // STEP("(printing system)")
+
+  st->cr();
+  st->print_cr("---------------  S Y S T E M  ---------------");
+  st->cr();
+
+  // STEP("(printing OS information)")
+
+  os::print_os_info(st);
+  st->cr();
+
+  // STEP("(printing CPU info)")
+
+  os::print_cpu_info(st, buf, sizeof(buf));
+  st->cr();
+
+  // STEP("(printing memory info)")
+
+  os::print_memory_info(st);
+  st->cr();
+
+  // STEP("(printing internal vm info)")
+
+  st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string());
+  st->cr();
+
+  // print a defined marker to show that error handling finished correctly.
+  // STEP("(printing end marker)")
+
+  st->print_cr("END.");
+}
+
 volatile intptr_t VMError::first_error_tid = -1;
 
 // An error could happen before tty is initialized or after it has been
--- a/hotspot/src/share/vm/utilities/vmError.hpp	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.hpp	Sat Nov 14 18:26:35 2015 +0000
@@ -88,9 +88,6 @@
   static void print_stack_trace(outputStream* st, JavaThread* jt,
                                 char* buf, int buflen, bool verbose = false);
 
-  static const char* gc_mode();
-  static void print_oom_reasons(outputStream* st);
-
   static bool should_report_bug(unsigned int id) {
     return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR);
   }
@@ -110,6 +107,9 @@
   // Record status of core/minidump
   static void record_coredump_status(const char* message, bool status);
 
+  // support for VM.info diagnostic command
+  static void print_vm_info(outputStream* st);
+
   // main error reporting function
   static void report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args,
                              Thread* thread, address pc, void* siginfo, void* context,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java	Sat Nov 14 18:26:35 2015 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestNoEagerReclaimOfHumongousRegions
+ * @bug 8139424
+ * @summary Test to check that a live humongous object is not eagerly reclaimed. This is a regression test for
+ *          8139424 and the test will crash if an eager reclaim occur. The test is not 100% deterministic and
+ *          might pass even if there are problems in the code, but it will never crash unless there is a problem.
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @key gc
+ * @library /testlibrary /test/lib
+ * @modules java.base/sun.misc
+ * @build TestNoEagerReclaimOfHumongousRegions
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+PrintGC -XX:+UseG1GC -XX:MaxTenuringThreshold=0 -XX:G1RSetSparseRegionEntries=32 -XX:G1HeapRegionSize=1m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+G1TraceEagerReclaimHumongousObjects TestNoEagerReclaimOfHumongousRegions
+ */
+
+import java.util.LinkedList;
+
+import sun.hotspot.WhiteBox;
+
+public class TestNoEagerReclaimOfHumongousRegions {
+    // Helper class to keep reference to humongous byte[].
+    static class LargeRef {
+        private byte[] _ref;
+
+        LargeRef(byte[] ref) {
+            _ref = ref;
+        }
+
+        byte[] ref() { return _ref; }
+    }
+
+    static LargeRef humongous_reference_holder;
+
+    public static void main(String[] args) throws InterruptedException{
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        LinkedList<Object> garbageAndRefList = new LinkedList<Object>();
+        // Creating a 1M large byte array. Since the test specifies the heap
+        // region size to be 1m this will be a humongous object. We then
+        // store a pointer to the array in the static object to keep it live
+        // during the whole test.
+        humongous_reference_holder = new LargeRef(new byte[1 * 1024 * 1024]);
+
+        // Create some garbage and a reference to the humongous object each round.
+        for (int i = 0; i < 32; i++) {
+            garbageAndRefList.add(new byte[400*1000]);
+            garbageAndRefList.add(new LargeRef(humongous_reference_holder.ref()));
+
+            // Promote to old, goal is to get rem-set entries for the humongous
+            // object from different regions. The test specifies MaxTenuringThreshold=0,
+            // this will make sure we get objects promoted to old at once.
+            wb.youngGC();
+        }
+        // Clear the garbage and reference list.
+        garbageAndRefList.clear();
+
+        // Run a concurrent mark cycle to mark all references but the static one as dead.
+        wb.g1StartConcMarkCycle();
+        while (wb.g1InConcurrentMark()) {
+            Thread.sleep(100);
+        }
+
+        // Run a young collection to make sure humongous object still can't be eagerly reclaimed.
+        wb.youngGC();
+        // Will crash/assert if humongous object has been reclaimed.
+        wb.fullGC();
+    }
+}
--- a/hotspot/test/runtime/logging/SafepointTest.java	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/test/runtime/logging/SafepointTest.java	Sat Nov 14 18:26:35 2015 +0000
@@ -41,11 +41,9 @@
             "-Xlog:safepoint=trace", "SafepointTestMain");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Safepoint synchronization initiated. (");
-        output.shouldContain(" thread(s) to block");
         output.shouldContain("Entering safepoint region: ");
         output.shouldContain("Leaving safepoint region");
         output.shouldContain("_at_poll_safepoint");
-        output.shouldContain("... found polling page ");
         output.shouldHaveExitValue(0);
     }
 }
--- a/hotspot/test/runtime/logging/SafepointTestMain.java	Fri Nov 13 10:35:26 2015 -0800
+++ b/hotspot/test/runtime/logging/SafepointTestMain.java	Sat Nov 14 18:26:35 2015 +0000
@@ -24,21 +24,6 @@
 import java.lang.ref.WeakReference;
 
 public class SafepointTestMain {
-    public static class B {
-        static int count = 0;
-        public static volatile boolean stop = false;
-        static void localSleep(int time) {
-          try{
-            Thread.currentThread().sleep(time);
-          } catch(InterruptedException ie) {
-          }
-        }
-
-        public static void infinite() {
-            while (!stop) { count++; }
-        }
-    }
-
     public static byte[] garbage;
     public static volatile WeakReference<Object> weakref;
 
@@ -48,16 +33,7 @@
     }
 
     public static void main(String[] args) throws Exception {
-        // Run function in separate thread to force compilation and pint safepoint
-        // message for compiled method
-        new Thread() {
-            public void run() {
-                B.infinite();
-            }
-        }.start();
-        B.localSleep(1000);
-        // Cause several safepoints to run GC while the compiled method is running,
-        // to see safepoint messages
+        // Cause several safepoints to run GC to see safepoint messages
         for (int i = 0; i < 2; i++) {
             createweakref();
             while(weakref.get() != null) {
@@ -65,6 +41,5 @@
                 System.gc();
             }
         }
-        B.stop = true;
     }
 }