changeset 1796:18c378513575

Merge
author kvn
date Thu, 16 Sep 2010 16:48:40 -0700
parents 97fbf5beff7b (diff) a8b66e00933b (current diff)
children a25394352030 c77e8f982901
files src/share/vm/runtime/arguments.cpp src/share/vm/runtime/globals.hpp src/share/vm/utilities/macros.hpp
diffstat 19 files changed, 221 insertions(+), 114 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Sep 14 17:19:35 2010 -0700
+++ b/.hgtags	Thu Sep 16 16:48:40 2010 -0700
@@ -114,4 +114,6 @@
 1b81ca701fa5fc30adc4cfdaa4bdd153df5e6c86 jdk7-b106
 cc3fdfeb54b049f18edcf3463e6ab051d0b7b609 hs19-b05
 688a538aa65412178286ae2a6b0c00b6711e121b hs19-b06
+bf496cbe9b74dda5975a1559da7ecfdd313e509e jdk7-b107
 0000000000000000000000000000000000000000 hs19-b06
+6c43216df13513a0f96532aa06f213066c49e27b hs19-b06
--- a/make/hotspot_version	Tue Sep 14 17:19:35 2010 -0700
+++ b/make/hotspot_version	Thu Sep 16 16:48:40 2010 -0700
@@ -33,9 +33,9 @@
 # Don't put quotes (fail windows build).
 HOTSPOT_VM_COPYRIGHT=Copyright 2010
 
-HS_MAJOR_VER=19
+HS_MAJOR_VER=20
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=06
+HS_BUILD_NUMBER=01
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/jprt.properties	Tue Sep 14 17:19:35 2010 -0700
+++ b/make/jprt.properties	Thu Sep 16 16:48:40 2010 -0700
@@ -47,6 +47,8 @@
 # Define the Solaris platforms we want for the various releases
 
 jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
+jprt.my.solaris.sparc.jdk7b107=solaris_sparc_5.10
+jprt.my.solaris.sparc.jdk7temp=solaris_sparc_5.10
 jprt.my.solaris.sparc.jdk6=solaris_sparc_5.8
 jprt.my.solaris.sparc.jdk6perf=solaris_sparc_5.8
 jprt.my.solaris.sparc.jdk6u10=solaris_sparc_5.8
@@ -56,6 +58,8 @@
 jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
 
 jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
+jprt.my.solaris.sparcv9.jdk7b107=solaris_sparcv9_5.10
+jprt.my.solaris.sparcv9.jdk7temp=solaris_sparcv9_5.10
 jprt.my.solaris.sparcv9.jdk6=solaris_sparcv9_5.8
 jprt.my.solaris.sparcv9.jdk6perf=solaris_sparcv9_5.8
 jprt.my.solaris.sparcv9.jdk6u10=solaris_sparcv9_5.8
@@ -65,6 +69,8 @@
 jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
 
 jprt.my.solaris.i586.jdk7=solaris_i586_5.10
+jprt.my.solaris.i586.jdk7b107=solaris_i586_5.10
+jprt.my.solaris.i586.jdk7temp=solaris_i586_5.10
 jprt.my.solaris.i586.jdk6=solaris_i586_5.8
 jprt.my.solaris.i586.jdk6perf=solaris_i586_5.8
 jprt.my.solaris.i586.jdk6u10=solaris_i586_5.8
@@ -74,6 +80,8 @@
 jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
 
 jprt.my.solaris.x64.jdk7=solaris_x64_5.10
+jprt.my.solaris.x64.jdk7b107=solaris_x64_5.10
+jprt.my.solaris.x64.jdk7temp=solaris_x64_5.10
 jprt.my.solaris.x64.jdk6=solaris_x64_5.10
 jprt.my.solaris.x64.jdk6perf=solaris_x64_5.10
 jprt.my.solaris.x64.jdk6u10=solaris_x64_5.10
@@ -83,6 +91,8 @@
 jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
 
 jprt.my.linux.i586.jdk7=linux_i586_2.6
+jprt.my.linux.i586.jdk7b107=linux_i586_2.6
+jprt.my.linux.i586.jdk7temp=linux_i586_2.6
 jprt.my.linux.i586.jdk6=linux_i586_2.4
 jprt.my.linux.i586.jdk6perf=linux_i586_2.4
 jprt.my.linux.i586.jdk6u10=linux_i586_2.4
@@ -92,6 +102,8 @@
 jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
 
 jprt.my.linux.x64.jdk7=linux_x64_2.6
+jprt.my.linux.x64.jdk7b107=linux_x64_2.6
+jprt.my.linux.x64.jdk7temp=linux_x64_2.6
 jprt.my.linux.x64.jdk6=linux_x64_2.4
 jprt.my.linux.x64.jdk6perf=linux_x64_2.4
 jprt.my.linux.x64.jdk6u10=linux_x64_2.4
@@ -100,7 +112,9 @@
 jprt.my.linux.x64.jdk6u20=linux_x64_2.4
 jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
 
-jprt.my.windows.i586.jdk7=windows_i586_5.0
+jprt.my.windows.i586.jdk7=windows_i586_5.1
+jprt.my.windows.i586.jdk7b107=windows_i586_5.0
+jprt.my.windows.i586.jdk7temp=windows_i586_5.0
 jprt.my.windows.i586.jdk6=windows_i586_5.0
 jprt.my.windows.i586.jdk6perf=windows_i586_5.0
 jprt.my.windows.i586.jdk6u10=windows_i586_5.0
@@ -110,6 +124,8 @@
 jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
 
 jprt.my.windows.x64.jdk7=windows_x64_5.2
+jprt.my.windows.x64.jdk7b107=windows_x64_5.2
+jprt.my.windows.x64.jdk7temp=windows_x64_5.2
 jprt.my.windows.x64.jdk6=windows_x64_5.2
 jprt.my.windows.x64.jdk6perf=windows_x64_5.2
 jprt.my.windows.x64.jdk6u10=windows_x64_5.2
--- a/make/linux/makefiles/sa.make	Tue Sep 14 17:19:35 2010 -0700
+++ b/make/linux/makefiles/sa.make	Thu Sep 16 16:48:40 2010 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2010, 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
@@ -48,6 +48,9 @@
 AGENT_FILES1 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES1))
 AGENT_FILES2 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES2))
 
+AGENT_FILES1_LIST := $(GENERATED)/agent1.classes.list
+AGENT_FILES2_LIST := $(GENERATED)/agent2.classes.list
+
 SA_CLASSDIR = $(GENERATED)/saclasses
 
 SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)"
@@ -65,7 +68,7 @@
 	   $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
 	fi
 
-$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
+$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2) agent_files_preclean
 	$(QUIETLY) echo "Making $@"
 	$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
 	  echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
@@ -79,10 +82,13 @@
 	$(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \
 	  mkdir -p $(SA_CLASSDIR);        \
 	fi
-
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
-	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
-
+	
+	$(foreach file,$(AGENT_FILES1),$(shell echo $(file) >> $(AGENT_FILES1_LIST)))
+	$(foreach file,$(AGENT_FILES2),$(shell echo $(file) >> $(AGENT_FILES2_LIST)))
+	
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES1_LIST)
+	$(QUIETLY) $(REMOTE) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES2_LIST)
+	
 	$(QUIETLY) $(REMOTE) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
 	$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
@@ -98,6 +104,10 @@
 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext
 
+agent_files_preclean:
+	rm -rf $(AGENT_FILES1_LIST) $(AGENT_FILES2_LIST)
+
 clean:
 	rm -rf $(SA_CLASSDIR)
 	rm -rf $(GENERATED)/sa-jdi.jar
+	rm -rf $(AGENT_FILES1_LIST) $(AGENT_FILES2_LIST)
--- a/make/solaris/makefiles/sa.make	Tue Sep 14 17:19:35 2010 -0700
+++ b/make/solaris/makefiles/sa.make	Thu Sep 16 16:48:40 2010 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2010, 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
@@ -44,6 +44,9 @@
 AGENT_FILES1 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES1))
 AGENT_FILES2 := $(shell /usr/bin/test -d $(AGENT_DIR) && /bin/ls $(AGENT_FILES2))
 
+AGENT_FILES1_LIST := $(GENERATED)/agent1.classes.list
+AGENT_FILES2_LIST := $(GENERATED)/agent2.classes.list
+
 SA_CLASSDIR = $(GENERATED)/saclasses
 
 SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)"
@@ -56,7 +59,7 @@
 	   $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
 	fi
 
-$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2)
+$(GENERATED)/sa-jdi.jar: $(AGENT_FILES1) $(AGENT_FILES2) agent_files_preclean
 	$(QUIETLY) echo "Making $@";
 	$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
 	   echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
@@ -70,8 +73,12 @@
 	$(QUIETLY) if [ ! -d $(SA_CLASSDIR) ] ; then \
 	  mkdir -p $(SA_CLASSDIR);        \
 	fi
-	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES1)
-	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES2)
+	
+	$(foreach file,$(AGENT_FILES1),$(shell echo $(file) >> $(AGENT_FILES1_LIST)))
+	$(foreach file,$(AGENT_FILES2),$(shell echo $(file) >> $(AGENT_FILES2_LIST)))
+	
+	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES1_LIST)
+	$(QUIETLY) $(COMPILE.JAVAC) -source 1.4 -target 1.4 -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) @$(AGENT_FILES2_LIST)
 	
 	$(QUIETLY) $(COMPILE.RMIC)  -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
@@ -85,6 +92,10 @@
 	$(QUIETLY) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
 	$(QUIETLY) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
 
+agent_files_preclean:
+	rm -rf $(AGENT_FILES1_LIST) $(AGENT_FILES2_LIST)
+
 clean:
 	rm -rf $(SA_CLASSDIR)
 	rm -rf $(GENERATED)/sa-jdi.jar
+	rm -rf $(AGENT_FILES1_LIST) $(AGENT_FILES2_LIST)
--- a/src/share/vm/classfile/stackMapTable.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/classfile/stackMapTable.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -152,6 +152,7 @@
 
 int32_t StackMapReader::chop(
     VerificationType* locals, int32_t length, int32_t chops) {
+  if (locals == NULL) return -1;
   int32_t pos = length - 1;
   for (int32_t i=0; i<chops; i++) {
     if (locals[pos].is_category2_2nd()) {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -256,7 +256,7 @@
 }
 
 TreeChunk* TreeList::first_available() {
-  guarantee(head() != NULL, "The head of the list cannot be NULL");
+  assert(head() != NULL, "The head of the list cannot be NULL");
   FreeChunk* fc = head()->next();
   TreeChunk* retTC;
   if (fc == NULL) {
@@ -272,7 +272,7 @@
 // those in the list for this size; potentially slow and expensive,
 // use with caution!
 TreeChunk* TreeList::largest_address() {
-  guarantee(head() != NULL, "The head of the list cannot be NULL");
+  assert(head() != NULL, "The head of the list cannot be NULL");
   FreeChunk* fc = head()->next();
   TreeChunk* retTC;
   if (fc == NULL) {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -1946,8 +1946,8 @@
 
 bool CompactibleFreeListSpace::no_allocs_since_save_marks() {
   assert(_promoInfo.tracking(), "No preceding save_marks?");
-  guarantee(SharedHeap::heap()->n_par_threads() == 0,
-            "Shouldn't be called (yet) during parallel part of gc.");
+  assert(SharedHeap::heap()->n_par_threads() == 0,
+         "Shouldn't be called if using parallel gc.");
   return _promoInfo.noPromotions();
 }
 
@@ -2569,7 +2569,7 @@
 
 HeapWord* CFLS_LAB::alloc(size_t word_sz) {
   FreeChunk* res;
-  guarantee(word_sz == _cfls->adjustObjectSize(word_sz), "Error");
+  assert(word_sz == _cfls->adjustObjectSize(word_sz), "Error");
   if (word_sz >=  CompactibleFreeListSpace::IndexSetSize) {
     // This locking manages sync with other large object allocations.
     MutexLockerEx x(_cfls->parDictionaryAllocLock(),
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -1332,7 +1332,7 @@
 // -----------------------------------------------------
 // FREE:      klass_word & 1 == 1; mark_word holds block size
 //
-// OBJECT:    klass_word installed; klass_word != 0 && klass_word & 0 == 0;
+// OBJECT:    klass_word installed; klass_word != 0 && klass_word & 1 == 0;
 //            obj->size() computes correct size
 //            [Perm Gen objects needs to be "parsable" before they can be navigated]
 //
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -165,13 +165,8 @@
        "Next of tail should be NULL");
    }
    decrement_count();
-#define TRAP_CODE 1
-#if TRAP_CODE
-   if (head() == NULL) {
-     guarantee(tail() == NULL, "INVARIANT");
-     guarantee(count() == 0, "INVARIANT");
-   }
-#endif
+   assert(((head() == NULL) + (tail() == NULL) + (count() == 0)) % 3 == 0,
+          "H/T/C Inconsistency");
    // clear next and prev fields of fc, debug only
    NOT_PRODUCT(
      fc->linkPrev(NULL);
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -253,8 +253,8 @@
        cur_spool = cur_spool->nextSpoolBlock) {
     // the first entry is just a self-pointer; indices 1 through
     // bufferSize - 1 are occupied (thus, bufferSize - 1 slots).
-    guarantee((void*)cur_spool->displacedHdr == (void*)&cur_spool->displacedHdr,
-              "first entry of displacedHdr should be self-referential");
+    assert((void*)cur_spool->displacedHdr == (void*)&cur_spool->displacedHdr,
+           "first entry of displacedHdr should be self-referential");
     slots += cur_spool->bufferSize - 1;
     blocks++;
   }
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -2148,7 +2148,7 @@
             body_summary->get_termination_seq()
           };
           NumberSeq calc_other_times_ms(body_summary->get_parallel_seq(),
-                                        7, other_parts);
+                                        6, other_parts);
           check_other_times(2, body_summary->get_parallel_other_seq(),
                             &calc_other_times_ms);
         }
@@ -2166,30 +2166,32 @@
     }
     print_summary(1, "Other", summary->get_other_seq());
     {
-      NumberSeq calc_other_times_ms;
-      if (parallel) {
-        // parallel
-        NumberSeq* other_parts[] = {
-          body_summary->get_satb_drain_seq(),
-          body_summary->get_parallel_seq(),
-          body_summary->get_clear_ct_seq()
-        };
-        calc_other_times_ms = NumberSeq(summary->get_total_seq(),
-                                        3, other_parts);
-      } else {
-        // serial
-        NumberSeq* other_parts[] = {
-          body_summary->get_satb_drain_seq(),
-          body_summary->get_update_rs_seq(),
-          body_summary->get_ext_root_scan_seq(),
-          body_summary->get_mark_stack_scan_seq(),
-          body_summary->get_scan_rs_seq(),
-          body_summary->get_obj_copy_seq()
-        };
-        calc_other_times_ms = NumberSeq(summary->get_total_seq(),
-                                        7, other_parts);
+      if (body_summary != NULL) {
+        NumberSeq calc_other_times_ms;
+        if (parallel) {
+          // parallel
+          NumberSeq* other_parts[] = {
+            body_summary->get_satb_drain_seq(),
+            body_summary->get_parallel_seq(),
+            body_summary->get_clear_ct_seq()
+          };
+          calc_other_times_ms = NumberSeq(summary->get_total_seq(),
+                                                3, other_parts);
+        } else {
+          // serial
+          NumberSeq* other_parts[] = {
+            body_summary->get_satb_drain_seq(),
+            body_summary->get_update_rs_seq(),
+            body_summary->get_ext_root_scan_seq(),
+            body_summary->get_mark_stack_scan_seq(),
+            body_summary->get_scan_rs_seq(),
+            body_summary->get_obj_copy_seq()
+          };
+          calc_other_times_ms = NumberSeq(summary->get_total_seq(),
+                                                6, other_parts);
+        }
+        check_other_times(1,  summary->get_other_seq(), &calc_other_times_ms);
       }
-      check_other_times(1,  summary->get_other_seq(), &calc_other_times_ms);
     }
   } else {
     print_indent(0);
--- a/src/share/vm/runtime/arguments.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -2863,6 +2863,13 @@
       CommandLineFlags::printFlags();
       vm_exit(0);
     }
+
+#ifndef PRODUCT
+    if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) {
+      CommandLineFlags::printFlags(true);
+      vm_exit(0);
+    }
+#endif
   }
 
   if (IgnoreUnrecognizedVMOptions) {
--- a/src/share/vm/runtime/globals.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/runtime/globals.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -68,30 +68,38 @@
 // Length of format string (e.g. "%.1234s") for printing ccstr below
 #define FORMAT_BUFFER_LEN 16
 
-void Flag::print_on(outputStream* st) {
-  st->print("%5s %-35s %c= ", type, name, (origin != DEFAULT ? ':' : ' '));
+void Flag::print_on(outputStream* st, bool withComments) {
+  st->print("%9s %-40s %c= ", type, name, (origin != DEFAULT ? ':' : ' '));
   if (is_bool())     st->print("%-16s", get_bool() ? "true" : "false");
   if (is_intx())     st->print("%-16ld", get_intx());
   if (is_uintx())    st->print("%-16lu", get_uintx());
   if (is_uint64_t()) st->print("%-16lu", get_uint64_t());
+  if (is_double())   st->print("%-16f", get_double());
+
   if (is_ccstr()) {
-    const char* cp = get_ccstr();
-    if (cp != NULL) {
-      const char* eol;
-      while ((eol = strchr(cp, '\n')) != NULL) {
-        char format_buffer[FORMAT_BUFFER_LEN];
-        size_t llen = pointer_delta(eol, cp, sizeof(char));
-        jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
+     const char* cp = get_ccstr();
+     if (cp != NULL) {
+       const char* eol;
+       while ((eol = strchr(cp, '\n')) != NULL) {
+         char format_buffer[FORMAT_BUFFER_LEN];
+         size_t llen = pointer_delta(eol, cp, sizeof(char));
+         jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
                      "%%." SIZE_FORMAT "s", llen);
-        st->print(format_buffer, cp);
-        st->cr();
-        cp = eol+1;
-        st->print("%5s %-35s += ", "", name);
-      }
-      st->print("%-16s", cp);
-    }
+         st->print(format_buffer, cp);
+         st->cr();
+         cp = eol+1;
+         st->print("%5s %-35s += ", "", name);
+       }
+       st->print("%-16s", cp);
+     }
+     else st->print("%-16s", "");
   }
-  st->print(" %s", kind);
+  st->print("%-20s", kind);
+  if (withComments) {
+#ifndef PRODUCT
+    st->print("%s", doc );
+#endif
+  }
   st->cr();
 }
 
@@ -131,67 +139,67 @@
 // 4991491 do not "optimize out" the was_set false values: omitting them
 // tickles a Microsoft compiler bug causing flagTable to be malformed
 
-#define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{product}", DEFAULT },
-#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{pd product}", DEFAULT },
-#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{diagnostic}", DEFAULT },
-#define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{experimental}", DEFAULT },
-#define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{manageable}", DEFAULT },
-#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{product rw}", DEFAULT },
+#define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product}", DEFAULT },
+#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{pd product}", DEFAULT },
+#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{diagnostic}", DEFAULT },
+#define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{experimental}", DEFAULT },
+#define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{manageable}", DEFAULT },
+#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product rw}", DEFAULT },
 
 #ifdef PRODUCT
   #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
   #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
   #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
 #else
-  #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "", DEFAULT },
-  #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{pd}", DEFAULT },
-  #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{notproduct}", DEFAULT },
+  #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "", DEFAULT },
+  #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{pd}", DEFAULT },
+  #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{notproduct}", DEFAULT },
 #endif
 
 #ifdef _LP64
-  #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{lp64_product}", DEFAULT },
+  #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{lp64_product}", DEFAULT },
 #else
   #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
 #endif // _LP64
 
-#define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1 product}", DEFAULT },
-#define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{C1 pd product}", DEFAULT },
+#define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 product}", DEFAULT },
+#define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 pd product}", DEFAULT },
 #ifdef PRODUCT
   #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
   #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
   #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
 #else
-  #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1}", DEFAULT },
-  #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{C1 pd}", DEFAULT },
-  #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1 notproduct}", DEFAULT },
+  #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1}", DEFAULT },
+  #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{C1 pd}", DEFAULT },
+  #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1 notproduct}", DEFAULT },
 #endif
 
 
-#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 product}", DEFAULT },
-#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{C2 pd product}", DEFAULT },
-#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 diagnostic}", DEFAULT },
-#define C2_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 experimental}", DEFAULT },
+#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 product}", DEFAULT },
+#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 pd product}", DEFAULT },
+#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 diagnostic}", DEFAULT },
+#define C2_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 experimental}", DEFAULT },
 #ifdef PRODUCT
   #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
   #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
   #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
 #else
-  #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2}", DEFAULT },
-  #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{C2 pd}", DEFAULT },
-  #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 notproduct}", DEFAULT },
+  #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2}", DEFAULT },
+  #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{C2 pd}", DEFAULT },
+  #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2 notproduct}", DEFAULT },
 #endif
 
-#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark product}", DEFAULT },
-#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{Shark pd product}", DEFAULT },
-#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark diagnostic}", DEFAULT },
+#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark product}", DEFAULT },
+#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark pd product}", DEFAULT },
+#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark diagnostic}", DEFAULT },
 #ifdef PRODUCT
   #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
   #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
   #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
 #else
-  #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark}", DEFAULT },
-  #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, "{Shark pd}", DEFAULT },
-  #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark notproduct}", DEFAULT },
+  #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark}", DEFAULT },
+  #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{Shark pd}", DEFAULT },
+  #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark notproduct}", DEFAULT },
 #endif
 
 static Flag flagTable[] = {
@@ -485,7 +493,7 @@
 
 #endif // PRODUCT
 
-void CommandLineFlags::printFlags() {
+void CommandLineFlags::printFlags(bool withComments) {
   // Print the flags sorted by name
   // note: this method is called before the thread structure is in place
   //       which means resource allocation cannot be used.
@@ -505,7 +513,7 @@
   tty->print_cr("[Global flags]");
   for (int i = 0; i < length; i++) {
     if (array[i]->is_unlocked()) {
-      array[i]->print_on(tty);
+      array[i]->print_on(tty, withComments);
     }
   }
   FREE_C_HEAP_ARRAY(Flag*, array);
--- a/src/share/vm/runtime/globals.hpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/runtime/globals.hpp	Thu Sep 16 16:48:40 2010 -0700
@@ -83,6 +83,9 @@
   const char *type;
   const char *name;
   void*       addr;
+
+  NOT_PRODUCT(const char *doc;)
+
   const char *kind;
   FlagValueOrigin origin;
 
@@ -124,7 +127,7 @@
   bool is_writeable() const;
   bool is_external() const;
 
-  void print_on(outputStream* st);
+  void print_on(outputStream* st, bool withComments = false );
   void print_as_flag(outputStream* st);
 };
 
@@ -204,7 +207,7 @@
   static bool wasSetOnCmdline(const char* name, bool* value);
   static void printSetFlags();
 
-  static void printFlags();
+  static void printFlags(bool withComments = false );
 
   static void verify() PRODUCT_RETURN;
 };
@@ -1534,13 +1537,13 @@
           "Use BinaryTreeDictionary as default in the CMS generation")      \
                                                                             \
   product(uintx, CMSIndexedFreeListReplenish, 4,                            \
-          "Replenish and indexed free list with this number of chunks")     \
+          "Replenish an indexed free list with this number of chunks")     \
                                                                             \
   product(bool, CMSReplenishIntermediate, true,                             \
           "Replenish all intermediate free-list caches")                    \
                                                                             \
   product(bool, CMSSplitIndexedFreeListBlocks, true,                        \
-          "When satisfying batched demand, splot blocks from the "          \
+          "When satisfying batched demand, split blocks from the "          \
           "IndexedFreeList whose size is a multiple of requested size")     \
                                                                             \
   product(bool, CMSLoopWarn, false,                                         \
@@ -2396,6 +2399,9 @@
   product(bool, PrintFlagsFinal, false,                                     \
          "Print all VM flags after argument and ergonomic processing")      \
                                                                             \
+  notproduct(bool, PrintFlagsWithComments, false,                           \
+         "Print all VM flags with default values and descriptions and exit")\
+                                                                            \
   diagnostic(bool, SerializeVMOutput, true,                                 \
          "Use a mutex to serialize output to tty and hotspot.log")          \
                                                                             \
--- a/src/share/vm/services/heapDumper.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/services/heapDumper.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -1305,6 +1305,8 @@
   static VM_HeapDumper* _global_dumper;
   static DumpWriter*    _global_writer;
   DumpWriter*           _local_writer;
+  JavaThread*           _oome_thread;
+  methodOop             _oome_constructor;
   bool _gc_before_heap_dump;
   bool _is_segmented_dump;
   jlong _dump_start;
@@ -1366,7 +1368,7 @@
   void end_of_dump();
 
  public:
-  VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump) :
+  VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) :
     VM_GC_Operation(0 /* total collections,      dummy, ignored */,
                     0 /* total full collections, dummy, ignored */,
                     gc_before_heap_dump) {
@@ -1377,6 +1379,18 @@
     _klass_map = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
     _stack_traces = NULL;
     _num_threads = 0;
+    if (oome) {
+      assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");
+      // get OutOfMemoryError zero-parameter constructor
+      instanceKlass* oome_ik = instanceKlass::cast(SystemDictionary::OutOfMemoryError_klass());
+      _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(),
+                                                          vmSymbols::void_method_signature());
+      // get thread throwing OOME when generating the heap dump at OOME
+      _oome_thread = JavaThread::current();
+    } else {
+      _oome_thread = NULL;
+      _oome_constructor = NULL;
+    }
   }
   ~VM_HeapDumper() {
     if (_stack_traces != NULL) {
@@ -1557,7 +1571,11 @@
     frame f = java_thread->last_frame();
     vframe* vf = vframe::new_vframe(&f, &reg_map, java_thread);
     frame* last_entry_frame = NULL;
+    int extra_frames = 0;
 
+    if (java_thread == _oome_thread && _oome_constructor != NULL) {
+      extra_frames++;
+    }
     while (vf != NULL) {
       blk.set_frame_number(stack_depth);
       if (vf->is_java_frame()) {
@@ -1574,7 +1592,7 @@
                 writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME);
                 writer()->write_objectID(o);
                 writer()->write_u4(thread_serial_num);
-                writer()->write_u4((u4) stack_depth);
+                writer()->write_u4((u4) (stack_depth + extra_frames));
               }
             }
           }
@@ -1764,6 +1782,17 @@
       // write HPROF_FRAME records for this thread's stack trace
       int depth = stack_trace->get_stack_depth();
       int thread_frame_start = frame_serial_num;
+      int extra_frames = 0;
+      // write fake frame that makes it look like the thread, which caused OOME,
+      // is in the OutOfMemoryError zero-parameter constructor
+      if (thread == _oome_thread && _oome_constructor != NULL) {
+        int oome_serial_num = _klass_map->find(Klass::cast(_oome_constructor->method_holder()));
+        // the class serial number starts from 1
+        assert(oome_serial_num > 0, "OutOfMemoryError class not found");
+        DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, oome_serial_num,
+                                        _oome_constructor, 0);
+        extra_frames++;
+      }
       for (int j=0; j < depth; j++) {
         StackFrameInfo* frame = stack_trace->stack_frame_at(j);
         methodOop m = frame->method();
@@ -1772,6 +1801,7 @@
         assert(class_serial_num > 0, "class not found");
         DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci());
       }
+      depth += extra_frames;
 
       // write HPROF_TRACE record for one thread
       DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4) + depth*oopSize);
@@ -1808,7 +1838,7 @@
   }
 
   // generate the dump
-  VM_HeapDumper dumper(&writer, _gc_before_heap_dump);
+  VM_HeapDumper dumper(&writer, _gc_before_heap_dump, _oome);
   if (Thread::current()->is_VM_thread()) {
     assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint");
     dumper.doit();
@@ -1869,12 +1899,22 @@
   }
 }
 
+// Called by out-of-memory error reporting by a single Java thread
+// outside of a JVM safepoint
+void HeapDumper::dump_heap_from_oome() {
+  HeapDumper::dump_heap(true);
+}
+
 // Called by error reporting by a single Java thread outside of a JVM safepoint,
 // or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various
 // callers are strictly serialized and guaranteed not to interfere below. For more
 // general use, however, this method will need modification to prevent
 // inteference when updating the static variables base_path and dump_file_seq below.
 void HeapDumper::dump_heap() {
+  HeapDumper::dump_heap(false);
+}
+
+void HeapDumper::dump_heap(bool oome) {
   static char base_path[JVM_MAXPATHLEN] = {'\0'};
   static uint dump_file_seq = 0;
   char   my_path[JVM_MAXPATHLEN] = {'\0'};
@@ -1930,6 +1970,7 @@
   dump_file_seq++;   // increment seq number for next time we dump
 
   HeapDumper dumper(false /* no GC before heap dump */,
-                    true  /* send to tty */);
+                    true  /* send to tty */,
+                    oome  /* pass along out-of-memory-error flag */);
   dumper.dump(my_path);
 }
--- a/src/share/vm/services/heapDumper.hpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/services/heapDumper.hpp	Thu Sep 16 16:48:40 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -39,8 +39,12 @@
   char* _error;
   bool _print_to_tty;
   bool _gc_before_heap_dump;
+  bool _oome;
   elapsedTimer _t;
 
+  HeapDumper(bool gc_before_heap_dump, bool print_to_tty, bool oome) :
+    _gc_before_heap_dump(gc_before_heap_dump), _error(NULL), _print_to_tty(print_to_tty), _oome(oome) { }
+
   // string representation of error
   char* error() const                   { return _error; }
   void set_error(char* error);
@@ -51,11 +55,11 @@
   // internal timer.
   elapsedTimer* timer()                 { return &_t; }
 
+  static void dump_heap(bool oome);
+
  public:
   HeapDumper(bool gc_before_heap_dump) :
-    _gc_before_heap_dump(gc_before_heap_dump), _error(NULL), _print_to_tty(false) { }
-  HeapDumper(bool gc_before_heap_dump, bool print_to_tty) :
-    _gc_before_heap_dump(gc_before_heap_dump), _error(NULL), _print_to_tty(print_to_tty) { }
+    _gc_before_heap_dump(gc_before_heap_dump), _error(NULL), _print_to_tty(false), _oome(false) { }
 
   ~HeapDumper();
 
@@ -66,4 +70,6 @@
   char* error_as_C_string() const;
 
   static void dump_heap()    KERNEL_RETURN;
+
+  static void dump_heap_from_oome()    KERNEL_RETURN;
 };
--- a/src/share/vm/utilities/debug.cpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/utilities/debug.cpp	Thu Sep 16 16:48:40 2010 -0700
@@ -234,7 +234,7 @@
     // create heap dump before OnOutOfMemoryError commands are executed
     if (HeapDumpOnOutOfMemoryError) {
       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
-      HeapDumper::dump_heap();
+      HeapDumper::dump_heap_from_oome();
     }
 
     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
--- a/src/share/vm/utilities/macros.hpp	Tue Sep 14 17:19:35 2010 -0700
+++ b/src/share/vm/utilities/macros.hpp	Thu Sep 16 16:48:40 2010 -0700
@@ -84,12 +84,14 @@
 #ifdef PRODUCT
 #define PRODUCT_ONLY(code) code
 #define NOT_PRODUCT(code)
+#define NOT_PRODUCT_ARG(arg)
 #define PRODUCT_RETURN  {}
 #define PRODUCT_RETURN0 { return 0; }
 #define PRODUCT_RETURN_(code) { code }
 #else // PRODUCT
 #define PRODUCT_ONLY(code)
 #define NOT_PRODUCT(code) code
+#define NOT_PRODUCT_ARG(arg) arg,
 #define PRODUCT_RETURN  /*next token must be ;*/
 #define PRODUCT_RETURN0 /*next token must be ;*/
 #define PRODUCT_RETURN_(code)  /*next token must be ;*/