changeset 6219:ca98c3e554cd

Merge
author asaha
date Tue, 14 Oct 2014 12:14:57 -0700
parents 69aa1c041e15 (current diff) 7d3ba5ccfc7c (diff)
children cd3fb27fc3fa
files .hgtags make/hotspot_version test/runtime/7051189/Xchecksig.sh
diffstat 43 files changed, 1691 insertions(+), 394 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Oct 14 10:33:26 2014 -0700
+++ b/.hgtags	Tue Oct 14 12:14:57 2014 -0700
@@ -690,6 +690,16 @@
 d006213be74730453cf5c3ce31f1d1d505334419 jdk7u65-b18
 1d8226b3e9896656451801393eb3ae394faeb638 jdk7u65-b19
 c43b0b843f897a4d8cf0a3566b017b87230dd3b4 jdk7u65-b32
+b92f390febd01615af4a736b4f830f6052aa1d09 hs24.80-b00
+1448ebfef4f1aae0174eca983ad05507730ca6fd hs24.80-b01
+b1d29549dca7e36a4d050af5a54f8f56963a5c7d hs24.80-b02
+ff18bcebe2943527cdbc094375c38c27ec7f2442 hs24.80-b03
+1b9722b5134a8e565d8b8fe851849e034beff057 hs24.80-b04
+04d6919c44db8c9d811ef0ac4775a579f854cdfc hs24.80-b05
+ee18e60e7e8da9f1912895af353564de0330a2b1 hs24.80-b06
+05fe7a87d14908eb3f21a0d29fc72cee2f996b7f jdk7u80-b00
+e2533d62ca887078e4b952a75a75680cfb7894b9 jdk7u80-b01
+bad107a5d096b070355c5a2d80aa50bc5576144b jdk7u80-b02
 d3c9265e12fa115052f18d1e3d379143b56bbf63 jdk7u65-b20
 39776d90970221dd260187acb4c37631e41a66a9 jdk7u67-b01
 1d8226b3e9896656451801393eb3ae394faeb638 jdk7u65-b40
@@ -745,5 +755,11 @@
 9096ac248b379a0f3012f18c7289ec47cdef8459 jdk7u75-b01
 a6964b2822d906eab9c923cdd723cf3dd4facfcd jdk7u75-b02
 6c1a8b7ed616311a932715428620e262076bb68a jdk7u75-b03
+2480d9d778301a3f88b0ab8ee35a585df82528e5 jdk7u75-b04
+3c01618f40c059bf192c0b16176b144113965ea7 jdk7u76-b00
+7b5d132c3a70f3c0667fe9df4cae045b46673267 jdk7u76-b01
+10c2cb5743cac7d6fedc9307af8450283367e5e2 jdk7u76-b02
+99a8d8e3f1c6311853bfc0a86de503830cd3db1a jdk7u76-b03
+15079dd9fd20f252d4c6dc6972508d3375cf5af2 jdk7u76-b04
 2480d9d778301a3f88b0ab8ee35a585df82528e5 jdk7u79-b00
-fe6e2414eb4df95041d17e721b75f30f030c2e92 jdk7u75-b04
+
--- a/make/jprt.properties	Tue Oct 14 10:33:26 2014 -0700
+++ b/make/jprt.properties	Tue Oct 14 12:14:57 2014 -0700
@@ -38,7 +38,7 @@
 
 # This tells jprt what default release we want to build
 
-jprt.hotspot.default.release=jdk7u40
+jprt.hotspot.default.release=jdk7u60
 
 jprt.tools.default.release=${jprt.submit.option.release?${jprt.submit.option.release}:${jprt.hotspot.default.release}}
 
@@ -54,97 +54,92 @@
 # Define the Solaris platforms we want for the various releases
 jprt.my.solaris.sparc.jdk8=solaris_sparc_5.10
 jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
-jprt.my.solaris.sparc.jdk7u40=${jprt.my.solaris.sparc.jdk7}
+jprt.my.solaris.sparc.jdk7u60=${jprt.my.solaris.sparc.jdk7}
 jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
 
 jprt.my.solaris.sparcv9.jdk8=solaris_sparcv9_5.10
 jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
-jprt.my.solaris.sparcv9.jdk7u40=${jprt.my.solaris.sparcv9.jdk7}
+jprt.my.solaris.sparcv9.jdk7u60=${jprt.my.solaris.sparcv9.jdk7}
 jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
 
 jprt.my.solaris.i586.jdk8=solaris_i586_5.10
 jprt.my.solaris.i586.jdk7=solaris_i586_5.10
-jprt.my.solaris.i586.jdk7u40=${jprt.my.solaris.i586.jdk7}
+jprt.my.solaris.i586.jdk7u60=${jprt.my.solaris.i586.jdk7}
 jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
 
 jprt.my.solaris.x64.jdk8=solaris_x64_5.10
 jprt.my.solaris.x64.jdk7=solaris_x64_5.10
-jprt.my.solaris.x64.jdk7u40=${jprt.my.solaris.x64.jdk7}
+jprt.my.solaris.x64.jdk7u60=${jprt.my.solaris.x64.jdk7}
 jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
 
 jprt.my.linux.i586.jdk8=linux_i586_2.6
 jprt.my.linux.i586.jdk7=linux_i586_2.6
-jprt.my.linux.i586.jdk7u40=${jprt.my.linux.i586.jdk7}
+jprt.my.linux.i586.jdk7u60=${jprt.my.linux.i586.jdk7}
 jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
 
 jprt.my.linux.x64.jdk8=linux_x64_2.6
 jprt.my.linux.x64.jdk7=linux_x64_2.6
-jprt.my.linux.x64.jdk7u40=${jprt.my.linux.x64.jdk7}
+jprt.my.linux.x64.jdk7u60=${jprt.my.linux.x64.jdk7}
 jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
 
 jprt.my.linux.ppc.jdk8=linux_ppc_2.6
 jprt.my.linux.ppc.jdk7=linux_ppc_2.6
-jprt.my.linux.ppc.jdk7u40=${jprt.my.linux.ppc.jdk7}
+jprt.my.linux.ppc.jdk7u60=${jprt.my.linux.ppc.jdk7}
 jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}}
 
 jprt.my.linux.ppcv2.jdk8=linux_ppcv2_2.6
 jprt.my.linux.ppcv2.jdk7=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.jdk7u40=${jprt.my.linux.ppcv2.jdk7}
+jprt.my.linux.ppcv2.jdk7u60=${jprt.my.linux.ppcv2.jdk7}
 jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}}
 
-jprt.my.linux.ppcsflt.jdk8=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.jdk7=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.jdk7u40=${jprt.my.linux.ppcsflt.jdk7}
-jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}}
-
 jprt.my.linux.armvfp.jdk8=linux_armvfp_2.6
 jprt.my.linux.armvfp.jdk7=linux_armvfp_2.6
-jprt.my.linux.armvfp.jdk7u40=${jprt.my.linux.armvfp.jdk7}
+jprt.my.linux.armvfp.jdk7u60=${jprt.my.linux.armvfp.jdk7}
 jprt.my.linux.armvfp=${jprt.my.linux.armvfp.${jprt.tools.default.release}}
 
 jprt.my.linux.armvfpsflt.jdk8=linux_armvfpsflt_2.6
 jprt.my.linux.armvfpsflt.jdk7=linux_armvfpsflt_2.6
-jprt.my.linux.armvfpsflt.jdk7u40=${jprt.my.linux.armvfpsflt.jdk7}
+jprt.my.linux.armvfpsflt.jdk7u60=${jprt.my.linux.armvfpsflt.jdk7}
 jprt.my.linux.armvfpsflt=${jprt.my.linux.armvfpsflt.${jprt.tools.default.release}}
 
 jprt.my.linux.armvfphflt.jdk8=linux_armvfphflt_2.6
 jprt.my.linux.armvfphflt.jdk7=linux_armvfphflt_2.6
-jprt.my.linux.armvfphflt.jdk7u40=${jprt.my.linux.armvfphflt.jdk7}
+jprt.my.linux.armvfphflt.jdk7u60=${jprt.my.linux.armvfphflt.jdk7}
 jprt.my.linux.armvfphflt=${jprt.my.linux.armvfphflt.${jprt.tools.default.release}}
 
 jprt.my.linux.armv6.jdk8=linux_armv6_2.6
 jprt.my.linux.armv6.jdk7=linux_armv6_2.6
-jprt.my.linux.armv6.jdk7u40=${jprt.my.linux.armv6.jdk7}
+jprt.my.linux.armv6.jdk7u60=${jprt.my.linux.armv6.jdk7}
 jprt.my.linux.armv6=${jprt.my.linux.armv6.${jprt.tools.default.release}}
 
 jprt.my.linux.armvs.jdk8=linux_armvs_2.6
 jprt.my.linux.armvs.jdk7=linux_armvs_2.6
-jprt.my.linux.armvs.jdk7u40=${jprt.my.linux.armvs.jdk7}
+jprt.my.linux.armvs.jdk7u60=${jprt.my.linux.armvs.jdk7}
 jprt.my.linux.armvs=${jprt.my.linux.armvs.${jprt.tools.default.release}}
 
 jprt.my.linux.armvh.jdk8=linux_armvh_2.6
 jprt.my.linux.armvh.jdk7=linux_armvh_2.6
-jprt.my.linux.armvh.jdk7u40=${jprt.my.linux.armvh.jdk7}
+jprt.my.linux.armvh.jdk7u60=${jprt.my.linux.armvh.jdk7}
 jprt.my.linux.armvh=${jprt.my.linux.armvh.${jprt.tools.default.release}}
 
 jprt.my.linux.armsflt.jdk8=linux_armsflt_2.6
 jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6
-jprt.my.linux.armsflt.jdk7u40=${jprt.my.linux.armsflt.jdk7}
+jprt.my.linux.armsflt.jdk7u60=${jprt.my.linux.armsflt.jdk7}
 jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}}
 
 jprt.my.macosx.x64.jdk8=macosx_x64_10.7
 jprt.my.macosx.x64.jdk7=macosx_x64_10.7
-jprt.my.macosx.x64.jdk7u40=${jprt.my.macosx.x64.jdk7}
+jprt.my.macosx.x64.jdk7u60=${jprt.my.macosx.x64.jdk7}
 jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}}
 
 jprt.my.windows.i586.jdk8=windows_i586_5.1
 jprt.my.windows.i586.jdk7=windows_i586_5.1
-jprt.my.windows.i586.jdk7u40=${jprt.my.windows.i586.jdk7}
+jprt.my.windows.i586.jdk7u60=${jprt.my.windows.i586.jdk7}
 jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
 
 jprt.my.windows.x64.jdk8=windows_x64_5.2
 jprt.my.windows.x64.jdk7=windows_x64_5.2
-jprt.my.windows.x64.jdk7u40=${jprt.my.windows.x64.jdk7}
+jprt.my.windows.x64.jdk7u60=${jprt.my.windows.x64.jdk7}
 jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
 
 # Standard list of jprt build targets for this source tree
@@ -172,7 +167,6 @@
     ${jprt.my.linux.i586}-{productEmb|fastdebugEmb|debugEmb}, \
     ${jprt.my.linux.ppc}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.ppcv2}-{productEmb|fastdebugEmb}, \
-    ${jprt.my.linux.ppcsflt}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.armvfp}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.armsflt}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.armvfpsflt}-{productEmb|fastdebugEmb}, \
@@ -183,7 +177,7 @@
 
 jprt.build.targets.jdk8=${jprt.build.targets.all}
 jprt.build.targets.jdk7=${jprt.build.targets.all}
-jprt.build.targets.jdk7u40=${jprt.build.targets.all}
+jprt.build.targets.jdk7u60=${jprt.build.targets.all}
 jprt.build.targets=${jprt.build.targets.${jprt.tools.default.release}}
 
 # Subset lists of test targets for this source tree
@@ -476,7 +470,7 @@
 
 jprt.test.targets.jdk8=${jprt.test.targets.standard}
 jprt.test.targets.jdk7=${jprt.test.targets.standard}
-jprt.test.targets.jdk7u40=${jprt.test.targets.jdk7}
+jprt.test.targets.jdk7u60=${jprt.test.targets.jdk7}
 jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}}
 
 # The default test/Makefile targets that should be run
@@ -536,7 +530,7 @@
 
 jprt.make.rule.test.targets.jdk8=${jprt.make.rule.test.targets.standard}
 jprt.make.rule.test.targets.jdk7=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk7u40=${jprt.make.rule.test.targets.jdk7}
+jprt.make.rule.test.targets.jdk7u60=${jprt.make.rule.test.targets.jdk7}
 jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}}
 
 # 7155453: Work-around to prevent popups on OSX from blocking test completion
--- a/src/os/bsd/vm/os_bsd.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/os/bsd/vm/os_bsd.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -4433,11 +4433,15 @@
     // and if UserSignalHandler is installed all bets are off
     if (CheckJNICalls) {
       if (libjsig_is_loaded) {
-        tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
+        if (PrintJNIResolving) {
+          tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
+        }
         check_signals = false;
       }
       if (AllowUserSignalHandlers) {
-        tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
+        if (PrintJNIResolving) {
+          tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
+        }
         check_signals = false;
       }
     }
--- a/src/share/vm/ci/bcEscapeAnalyzer.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -158,6 +158,9 @@
 
 void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) {
   clear_bits(vars, _arg_local);
+  if (vars.contains_allocated()) {
+    _allocated_escapes = true;
+  }
 }
 
 void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) {
--- a/src/share/vm/classfile/classFileParser.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/classfile/classFileParser.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -2676,7 +2676,7 @@
   ClassFileStream* cfs = stream();
   u1* current_start = cfs->current();
 
-  guarantee_property(attribute_byte_length > sizeof(u2),
+  guarantee_property(attribute_byte_length >= sizeof(u2),
                      "Invalid BootstrapMethods attribute length %u in class file %s",
                      attribute_byte_length,
                      CHECK);
--- a/src/share/vm/classfile/stackMapFrame.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/classfile/stackMapFrame.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,15 +54,19 @@
   return frame;
 }
 
-bool StackMapFrame::has_new_object() const {
+// Return true if frame has an uninitialized (new) object that differs
+// from the target frame's object.
+bool StackMapFrame::has_nonmatching_new_object(const StackMapFrame *target_frame) const {
   int32_t i;
   for (i = 0; i < _max_locals; i++) {
-    if (_locals[i].is_uninitialized()) {
+    if (_locals[i].is_uninitialized() &&
+        !_locals[i].equals(target_frame->_locals[i])) {
       return true;
     }
   }
   for (i = 0; i < _stack_size; i++) {
-    if (_stack[i].is_uninitialized()) {
+    if (_stack[i].is_uninitialized() &&
+        !_stack[i].equals(target_frame->_stack[i])) {
       return true;
     }
   }
--- a/src/share/vm/classfile/stackMapFrame.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/classfile/stackMapFrame.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -155,8 +155,9 @@
     const methodHandle m, VerificationType thisKlass, TRAPS);
 
   // Search local variable type array and stack type array.
-  // Return true if an uninitialized object is found.
-  bool has_new_object() const;
+  // Return true if an uninitialized object is found that is
+  // not equal to the corresponding object on the target frame.
+  bool has_nonmatching_new_object(const StackMapFrame *target_frame) const;
 
   // Search local variable type array and stack type array.
   // Set every element with type of old_object to new_object.
--- a/src/share/vm/classfile/stackMapTable.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/classfile/stackMapTable.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -138,7 +138,10 @@
 
 void StackMapTable::check_new_object(
     const StackMapFrame* frame, int32_t target, TRAPS) const {
-  if (frame->offset() > target && frame->has_new_object()) {
+  int frame_index = get_index_from_offset(target);
+  assert(frame_index >= 0 && frame_index < _frame_count, "bad frame index");
+  if (frame->offset() > target &&
+      frame->has_nonmatching_new_object(_frame_array[frame_index])) {
     frame->verifier()->verify_error(
         ErrorContext::bad_code(frame->offset()),
         "Uninitialized object exists on backward branch %d", target);
--- a/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -172,7 +172,7 @@
 
   // Should be called when we want to release the active region which
   // is returned after it's been retired.
-  HeapRegion* release();
+  virtual HeapRegion* release();
 
 #if G1_ALLOC_REGION_TRACING
   void trace(const char* str, size_t word_size = 0, HeapWord* result = NULL);
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1519,7 +1519,7 @@
     }
 
     if (G1Log::finer()) {
-      g1_policy()->print_detailed_heap_transition();
+      g1_policy()->print_detailed_heap_transition(true /* full */);
     }
 
     print_heap_after_gc();
@@ -6628,6 +6628,35 @@
   _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes,
                                GCAllocForTenured);
 }
+
+HeapRegion* OldGCAllocRegion::release() {
+  HeapRegion* cur = get();
+  if (cur != NULL) {
+    // Determine how far we are from the next card boundary. If it is smaller than
+    // the minimum object size we can allocate into, expand into the next card.
+    HeapWord* top = cur->top();
+    HeapWord* aligned_top = (HeapWord*)align_ptr_up(top, G1BlockOffsetSharedArray::N_bytes);
+
+    size_t to_allocate_words = pointer_delta(aligned_top, top, HeapWordSize);
+
+    if (to_allocate_words != 0) {
+      // We are not at a card boundary. Fill up, possibly into the next, taking the
+      // end of the region and the minimum object size into account.
+      to_allocate_words = MIN2(pointer_delta(cur->end(), cur->top(), HeapWordSize),
+                               MAX2(to_allocate_words, G1CollectedHeap::min_fill_size()));
+
+      // Skip allocation if there is not enough space to allocate even the smallest
+      // possible object. In this case this region will not be retained, so the
+      // original problem cannot occur.
+      if (to_allocate_words >= G1CollectedHeap::min_fill_size()) {
+        HeapWord* dummy = attempt_allocation(to_allocate_words, true /* bot_updates */);
+        CollectedHeap::fill_with_object(dummy, to_allocate_words);
+      }
+    }
+  }
+  return G1AllocRegion::release();
+}
+
 // Heap region set verification
 
 class VerifyRegionListsClosure : public HeapRegionClosure {
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -183,6 +183,13 @@
 public:
   OldGCAllocRegion()
   : G1AllocRegion("Old GC Alloc Region", true /* bot_updates */) { }
+
+  // This specialization of release() makes sure that the last card that has been
+  // allocated into has been completely filled by a dummy object.
+  // This avoids races when remembered set scanning wants to update the BOT of the
+  // last card in the retained old gc alloc region, and allocation threads
+  // allocating into that card at the same time.
+  virtual HeapRegion* release();
 };
 
 // The G1 STW is alive closure.
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -124,9 +124,12 @@
   _last_young_gc(false),
   _last_gc_was_young(false),
 
-  _eden_bytes_before_gc(0),
-  _survivor_bytes_before_gc(0),
-  _capacity_before_gc(0),
+  _eden_used_bytes_before_gc(0),
+  _survivor_used_bytes_before_gc(0),
+  _heap_used_bytes_before_gc(0),
+  _permgen_used_bytes_before_gc(0),
+  _eden_capacity_bytes_before_gc(0),
+  _heap_capacity_bytes_before_gc(0),
 
   _eden_cset_region_length(0),
   _survivor_cset_region_length(0),
@@ -747,7 +750,7 @@
 
 void G1CollectorPolicy::record_full_collection_start() {
   _full_collection_start_sec = os::elapsedTime();
-  record_heap_size_info_at_start();
+  record_heap_size_info_at_start(true /* full */);
   // Release the future to-space so that it is available for compaction into.
   _g1->set_full_collection();
 }
@@ -804,7 +807,7 @@
   _trace_gen0_time_data.record_start_collection(s_w_t_ms);
   _stop_world_start = 0.0;
 
-  record_heap_size_info_at_start();
+  record_heap_size_info_at_start(false /* full */);
 
   phase_times()->record_cur_collection_start_sec(start_time_sec);
   _pending_cards = _g1->pending_card_num();
@@ -939,14 +942,6 @@
   _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
                           end_time_sec, false);
 
-  size_t freed_bytes =
-    _cur_collection_pause_used_at_start_bytes - cur_used_bytes;
-  size_t surviving_bytes = _collection_set_bytes_used_before - freed_bytes;
-
-  double survival_fraction =
-    (double)surviving_bytes/
-    (double)_collection_set_bytes_used_before;
-
   evacuation_info.set_collectionset_used_before(_collection_set_bytes_used_before);
   evacuation_info.set_bytes_copied(_bytes_copied_during_gc);
 
@@ -1002,6 +997,7 @@
       }
     }
   }
+
   bool new_in_marking_window = _in_marking_window;
   bool new_in_marking_window_im = false;
   if (during_initial_mark_pause()) {
@@ -1087,8 +1083,10 @@
     }
     _rs_length_diff_seq->add((double) rs_length_diff);
 
-    size_t copied_bytes = surviving_bytes;
+    size_t freed_bytes = _heap_used_bytes_before_gc - cur_used_bytes;
+    size_t copied_bytes = _collection_set_bytes_used_before - freed_bytes;
     double cost_per_byte_ms = 0.0;
+
     if (copied_bytes > 0) {
       cost_per_byte_ms = phase_times()->average_last_obj_copy_time() / (double) copied_bytes;
       if (_in_marking_window) {
@@ -1152,51 +1150,66 @@
   byte_size_in_proper_unit((double)(bytes)),                    \
   proper_unit_for_byte_size((bytes))
 
-void G1CollectorPolicy::record_heap_size_info_at_start() {
+void G1CollectorPolicy::record_heap_size_info_at_start(bool full) {
   YoungList* young_list = _g1->young_list();
-  _eden_bytes_before_gc = young_list->eden_used_bytes();
-  _survivor_bytes_before_gc = young_list->survivor_used_bytes();
-  _capacity_before_gc = _g1->capacity();
-
-  _cur_collection_pause_used_at_start_bytes = _g1->used();
+  _eden_used_bytes_before_gc = young_list->eden_used_bytes();
+  _survivor_used_bytes_before_gc = young_list->survivor_used_bytes();
+  _heap_capacity_bytes_before_gc = _g1->capacity();
+  _heap_used_bytes_before_gc = _g1->used();
   _cur_collection_pause_used_regions_at_start = _g1->used_regions();
 
-  size_t eden_capacity_before_gc =
-         (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_bytes_before_gc;
+  _eden_capacity_bytes_before_gc =
+         (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
 
-  _prev_eden_capacity = eden_capacity_before_gc;
+  if (full) {
+    _permgen_used_bytes_before_gc = _g1->perm_gen()->used();
+  }
+}
+void G1CollectorPolicy::print_perm_heap_change(size_t perm_prev_used) const {
+  gclog_or_tty->print(", [%s:", _g1->perm_gen()->short_name());
+  _g1->perm_gen()->print_heap_change(perm_prev_used);
+  gclog_or_tty->print("]");
 }
 
 void G1CollectorPolicy::print_heap_transition() {
   _g1->print_size_transition(gclog_or_tty,
-    _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity());
+                             _heap_used_bytes_before_gc,
+                             _g1->used(),
+                             _g1->capacity());
 }
 
-void G1CollectorPolicy::print_detailed_heap_transition() {
-    YoungList* young_list = _g1->young_list();
-    size_t eden_bytes = young_list->eden_used_bytes();
-    size_t survivor_bytes = young_list->survivor_used_bytes();
-    size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
-    size_t used = _g1->used();
-    size_t capacity = _g1->capacity();
-    size_t eden_capacity =
-      (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
+void G1CollectorPolicy::print_detailed_heap_transition(bool full) {
+  YoungList* young_list = _g1->young_list();
+
+  size_t eden_used_bytes_after_gc = young_list->eden_used_bytes();
+  size_t survivor_used_bytes_after_gc = young_list->survivor_used_bytes();
+  size_t heap_used_bytes_after_gc = _g1->used();
+
+  size_t heap_capacity_bytes_after_gc = _g1->capacity();
+  size_t eden_capacity_bytes_after_gc =
+    (_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc;
 
-    gclog_or_tty->print_cr(
-      "   [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
-      "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
-      "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
-      EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
-      EXT_SIZE_PARAMS(_eden_bytes_before_gc),
-      EXT_SIZE_PARAMS(_prev_eden_capacity),
-      EXT_SIZE_PARAMS(eden_bytes),
-      EXT_SIZE_PARAMS(eden_capacity),
-      EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
-      EXT_SIZE_PARAMS(survivor_bytes),
-      EXT_SIZE_PARAMS(used_before_gc),
-      EXT_SIZE_PARAMS(_capacity_before_gc),
-      EXT_SIZE_PARAMS(used),
-      EXT_SIZE_PARAMS(capacity));
+  gclog_or_tty->print(
+    "   [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
+    "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
+    "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
+    EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
+    EXT_SIZE_PARAMS(_eden_used_bytes_before_gc),
+    EXT_SIZE_PARAMS(_eden_capacity_bytes_before_gc),
+    EXT_SIZE_PARAMS(eden_used_bytes_after_gc),
+    EXT_SIZE_PARAMS(eden_capacity_bytes_after_gc),
+    EXT_SIZE_PARAMS(_survivor_used_bytes_before_gc),
+    EXT_SIZE_PARAMS(survivor_used_bytes_after_gc),
+    EXT_SIZE_PARAMS(_heap_used_bytes_before_gc),
+    EXT_SIZE_PARAMS(_heap_capacity_bytes_before_gc),
+    EXT_SIZE_PARAMS(heap_used_bytes_after_gc),
+    EXT_SIZE_PARAMS(heap_capacity_bytes_after_gc));
+
+  if (full) {
+    print_perm_heap_change(_permgen_used_bytes_before_gc);
+  }
+
+  gclog_or_tty->cr();
 }
 
 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -176,7 +176,6 @@
   CollectionSetChooser* _collectionSetChooser;
 
   double _full_collection_start_sec;
-  size_t _cur_collection_pause_used_at_start_bytes;
   uint   _cur_collection_pause_used_regions_at_start;
 
   // These exclude marking times.
@@ -195,7 +194,6 @@
 
   uint _young_list_target_length;
   uint _young_list_fixed_length;
-  size_t _prev_eden_capacity; // used for logging
 
   // The max number of regions we can extend the eden by while the GC
   // locker is active. This should be >= _young_list_target_length;
@@ -694,11 +692,12 @@
 
   // Records the information about the heap size for reporting in
   // print_detailed_heap_transition
-  void record_heap_size_info_at_start();
+  void record_heap_size_info_at_start(bool full);
 
   // Print heap sizing transition (with less and more detail).
   void print_heap_transition();
-  void print_detailed_heap_transition();
+  void print_detailed_heap_transition(bool full = false);
+  void print_perm_heap_change(size_t perm_prev_used) const;
 
   void record_stop_world_start();
   void record_concurrent_pause();
@@ -862,9 +861,16 @@
   uint _max_survivor_regions;
 
   // For reporting purposes.
-  size_t _eden_bytes_before_gc;
-  size_t _survivor_bytes_before_gc;
-  size_t _capacity_before_gc;
+  // The value of _heap_bytes_before_gc is also used to calculate
+  // the cost of copying.
+
+  size_t _eden_used_bytes_before_gc;         // Eden occupancy before GC
+  size_t _survivor_used_bytes_before_gc;     // Survivor occupancy before GC
+  size_t _heap_used_bytes_before_gc;         // Heap occupancy before GC
+  size_t _permgen_used_bytes_before_gc;      // PermGen occupancy before GC
+
+  size_t _eden_capacity_bytes_before_gc;     // Eden capacity before GC
+  size_t _heap_capacity_bytes_before_gc;     // Heap capacity before GC
 
   // The amount of survor regions after a collection.
   uint _recorded_survivor_regions;
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -107,7 +107,15 @@
   jbyte *const first = byte_for(mr.start());
   jbyte *const last = byte_after(mr.last());
 
-  memset(first, g1_young_gen, last - first);
+  // Below we may use an explicit loop instead of memset() because on
+  // certain platforms memset() can give concurrent readers phantom zeros.
+  if (UseMemSetInBOT) {
+    memset(first, g1_young_gen, last - first);
+  } else {
+    for (jbyte* i = first; i < last; i++) {
+      *i = g1_young_gen;
+    }
+  }
 }
 
 #ifndef PRODUCT
--- a/src/share/vm/opto/ifnode.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/opto/ifnode.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -503,7 +503,7 @@
   jint  off = 0;
   if (l->is_top()) {
     return 0;
-  } else if (l->is_Add()) {
+  } else if (l->Opcode() == Op_AddI) {
     if ((off = l->in(1)->find_int_con(0)) != 0) {
       ind = l->in(2);
     } else if ((off = l->in(2)->find_int_con(0)) != 0) {
--- a/src/share/vm/opto/runtime.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/opto/runtime.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1307,6 +1307,7 @@
   // add counters so this is safe.
   NamedCounter* head;
   do {
+    c->set_next(NULL);
     head = _named_counters;
     c->set_next(head);
   } while (Atomic::cmpxchg_ptr(c, &_named_counters, head) != head);
--- a/src/share/vm/opto/runtime.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/opto/runtime.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -85,7 +85,7 @@
 
   NamedCounter* next() const    { return _next; }
   void set_next(NamedCounter* next) {
-    assert(_next == NULL, "already set");
+    assert(_next == NULL || next == NULL, "already set");
     _next = next;
   }
 
--- a/src/share/vm/opto/superword.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/opto/superword.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1262,8 +1262,9 @@
     memops.clear();
     for (DUIterator i = upper_insert_pt->outs(); upper_insert_pt->has_out(i); i++) {
       Node* use = upper_insert_pt->out(i);
-      if (!use->is_Store())
+      if (use->is_Mem() && !use->is_Store()) {
         memops.push(use);
+      }
     }
 
     MemNode* lower_insert_pt = last;
--- a/src/share/vm/prims/jni.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/prims/jni.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
--- a/src/share/vm/prims/jvm.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/prims/jvm.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -527,6 +527,12 @@
   JavaThreadInObjectWaitState jtiows(thread, ms != 0);
   if (JvmtiExport::should_post_monitor_wait()) {
     JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms);
+
+    // The current thread already owns the monitor and it has not yet
+    // been added to the wait queue so the current thread cannot be
+    // made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT
+    // event handler cannot accidentally consume an unpark() meant for
+    // the ParkEvent associated with this ObjectMonitor.
   }
   ObjectSynchronizer::wait(obj, ms, THREAD);
 JVM_END
--- a/src/share/vm/prims/jvmtiEnvBase.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/prims/jvmtiEnvBase.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -400,7 +400,11 @@
   VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; }
   jvmtiError result() { return _result; }
   void doit() {
-    _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
+    _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+    if (Threads::includes(_java_thread) && !_java_thread->is_exiting() &&
+        _java_thread->threadObj() != NULL) {
+      _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
+    }
   }
 };
 
--- a/src/share/vm/runtime/arguments.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1758,24 +1758,22 @@
 // check if do gclog rotation
 // +UseGCLogFileRotation is a must,
 // no gc log rotation when log file not supplied or
-// NumberOfGCLogFiles is 0, or GCLogFileSize is 0
+// NumberOfGCLogFiles is 0
 void check_gclog_consistency() {
   if (UseGCLogFileRotation) {
-    if ((Arguments::gc_log_filename() == NULL) ||
-        (NumberOfGCLogFiles == 0)  ||
-        (GCLogFileSize == 0)) {
+    if ((Arguments::gc_log_filename() == NULL) || (NumberOfGCLogFiles == 0)) {
       jio_fprintf(defaultStream::output_stream(),
-                  "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files> -XX:GCLogFileSize=<num_of_size>\n"
-                  "where num_of_file > 0 and num_of_size > 0\n"
+                  "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files>\n"
+                  "where num_of_file > 0\n"
                   "GC log rotation is turned off\n");
       UseGCLogFileRotation = false;
     }
   }
 
-  if (UseGCLogFileRotation && GCLogFileSize < 8*K) {
-        FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K);
-        jio_fprintf(defaultStream::output_stream(),
-                    "GCLogFileSize changed to minimum 8K\n");
+  if (UseGCLogFileRotation && (GCLogFileSize != 0) && (GCLogFileSize < 8*K)) {
+    FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K);
+    jio_fprintf(defaultStream::output_stream(),
+                "GCLogFileSize changed to minimum 8K\n");
   }
 }
 
@@ -1807,6 +1805,51 @@
   return true;
 }
 
+// This function is called for -Xloggc:<filename>, it can be used
+// to check if a given file name(or string) conforms to the following
+// specification:
+// A valid string only contains "[A-Z][a-z][0-9].-_%[p|t]"
+// %p and %t only allowed once. We only limit usage of filename not path
+bool is_filename_valid(const char *file_name) {
+  const char* p = file_name;
+  char file_sep = os::file_separator()[0];
+  const char* cp;
+  // skip prefix path
+  for (cp = file_name; *cp != '\0'; cp++) {
+    if (*cp == '/' || *cp == file_sep) {
+      p = cp + 1;
+    }
+  }
+
+  int count_p = 0;
+  int count_t = 0;
+  while (*p != '\0') {
+    if ((*p >= '0' && *p <= '9') ||
+        (*p >= 'A' && *p <= 'Z') ||
+        (*p >= 'a' && *p <= 'z') ||
+         *p == '-'               ||
+         *p == '_'               ||
+         *p == '.') {
+       p++;
+       continue;
+    }
+    if (*p == '%') {
+      if(*(p + 1) == 'p') {
+        p += 2;
+        count_p ++;
+        continue;
+      }
+      if (*(p + 1) == 't') {
+        p += 2;
+        count_t ++;
+        continue;
+      }
+    }
+    return false;
+  }
+  return count_p < 2 && count_t < 2;
+}
+
 // Check consistency of GC selection
 bool Arguments::check_gc_consistency() {
   check_gclog_consistency();
@@ -2398,7 +2441,7 @@
                                             (size_t)InitialCodeCacheSize);
       if (errcode != arg_in_range) {
         jio_fprintf(defaultStream::error_stream(),
-                    "Invalid maximum code cache size: %s. Should be greater than InitialCodeCacheSize=%dK\n",
+                    "Invalid maximum code cache size: %s. Should be greater than or equal to InitialCodeCacheSize=%dK\n",
                     option->optionString, InitialCodeCacheSize/K);
         describe_range_error(errcode);
         return JNI_EINVAL;
@@ -2524,6 +2567,13 @@
       // ostream_init_log(), when called will use this filename
       // to initialize a fileStream.
       _gc_log_filename = strdup(tail);
+     if (!is_filename_valid(_gc_log_filename)) {
+       jio_fprintf(defaultStream::output_stream(),
+                  "Invalid file name for use with -Xloggc: Filename can only contain the "
+                  "characters [A-Z][a-z][0-9]-_.%%[p|t] but it has been %s\n"
+                  "Note %%p or %%t can only be used once\n", _gc_log_filename);
+        return JNI_EINVAL;
+      }
       FLAG_SET_CMDLINE(bool, PrintGC, true);
       FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true);
 
@@ -3288,9 +3338,6 @@
 #endif // CC_INTERP
 
 #ifdef COMPILER2
-  if (!UseBiasedLocking || EmitSync != 0) {
-    UseOptoBiasInlining = false;
-  }
   if (!EliminateLocks) {
     EliminateNestedLocks = false;
   }
@@ -3334,6 +3381,12 @@
     }
   }
 
+#ifdef COMPILER2
+  if (!UseBiasedLocking || EmitSync != 0) {
+    UseOptoBiasInlining = false;
+  }
+#endif
+
   // set PauseAtExit if the gamma launcher was used and a debugger is attached
   // but only if not already set on the commandline
   if (Arguments::created_by_gamma_launcher() && os::is_debugger_attached()) {
--- a/src/share/vm/runtime/globals.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/runtime/globals.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1204,7 +1204,7 @@
           "Decay time (in milliseconds) to re-enable bulk rebiasing of a "  \
           "type after previous bulk rebias")                                \
                                                                             \
-  develop(bool, JavaObjectsInPerm, false,                                   \
+  diagnostic(bool, JavaObjectsInPerm, false,                                \
           "controls whether Classes and interned Strings are allocated"     \
           "in perm.  This purely intended to allow debugging issues"        \
           "in production.")                                                 \
@@ -2339,9 +2339,9 @@
           "Number of gclog files in rotation, "                             \
           "Default: 0, no rotation")                                        \
                                                                             \
-  product(uintx, GCLogFileSize, 0,                                          \
-          "GC log file size, Default: 0 bytes, no rotation "                \
-          "Only valid with UseGCLogFileRotation")                           \
+  product(uintx, GCLogFileSize, 8*K,                                        \
+          "GC log file size, requires UseGCLogFileRotation. "               \
+          "Set to 0 to only trigger rotation via jcmd")                     \
                                                                             \
   /* JVMTI heap profiling */                                                \
                                                                             \
--- a/src/share/vm/runtime/objectMonitor.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/runtime/objectMonitor.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -385,6 +385,12 @@
     DTRACE_MONITOR_PROBE(contended__enter, this, object(), jt);
     if (JvmtiExport::should_post_monitor_contended_enter()) {
       JvmtiExport::post_monitor_contended_enter(jt, this);
+
+      // The current thread does not yet own the monitor and does not
+      // yet appear on any queues that would get it made the successor.
+      // This means that the JVMTI_EVENT_MONITOR_CONTENDED_ENTER event
+      // handler cannot accidentally consume an unpark() meant for the
+      // ParkEvent associated with this ObjectMonitor.
     }
 
     OSThreadContendState osts(Self->osthread());
@@ -442,6 +448,12 @@
   DTRACE_MONITOR_PROBE(contended__entered, this, object(), jt);
   if (JvmtiExport::should_post_monitor_contended_entered()) {
     JvmtiExport::post_monitor_contended_entered(jt, this);
+
+    // The current thread already owns the monitor and is not going to
+    // call park() for the remainder of the monitor enter protocol. So
+    // it doesn't matter if the JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
+    // event handler consumed an unpark() issued by the thread that
+    // just exited the monitor.
   }
 
   if (event.should_commit()) {
@@ -1459,6 +1471,14 @@
         // Note: 'false' parameter is passed here because the
         // wait was not timed out due to thread interrupt.
         JvmtiExport::post_monitor_waited(jt, this, false);
+
+        // In this short circuit of the monitor wait protocol, the
+        // current thread never drops ownership of the monitor and
+        // never gets added to the wait queue so the current thread
+        // cannot be made the successor. This means that the
+        // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally
+        // consume an unpark() meant for the ParkEvent associated with
+        // this ObjectMonitor.
      }
      if (event.should_commit()) {
        post_monitor_wait_event(&event, 0, millis, false);
@@ -1502,21 +1522,6 @@
    exit (true, Self) ;                    // exit the monitor
    guarantee (_owner != Self, "invariant") ;
 
-   // As soon as the ObjectMonitor's ownership is dropped in the exit()
-   // call above, another thread can enter() the ObjectMonitor, do the
-   // notify(), and exit() the ObjectMonitor. If the other thread's
-   // exit() call chooses this thread as the successor and the unpark()
-   // call happens to occur while this thread is posting a
-   // MONITOR_CONTENDED_EXIT event, then we run the risk of the event
-   // handler using RawMonitors and consuming the unpark().
-   //
-   // To avoid the problem, we re-post the event. This does no harm
-   // even if the original unpark() was not consumed because we are the
-   // chosen successor for this monitor.
-   if (node._notified != 0 && _succ == Self) {
-      node._event->unpark();
-   }
-
    // The thread is on the WaitSet list - now park() it.
    // On MP systems it's conceivable that a brief spin before we park
    // could be profitable.
@@ -1600,6 +1605,33 @@
        JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT);
      }
 
+     // Without the fix for 8028280, it is possible for the above call:
+     //
+     //   Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ;
+     //
+     // to consume the unpark() that was done when the successor was set.
+     // The solution for this very rare possibility is to redo the unpark()
+     // outside of the JvmtiExport::should_post_monitor_waited() check.
+     //
+     if (node._notified != 0 && _succ == Self) {
+       // In this part of the monitor wait-notify-reenter protocol it
+       // is possible (and normal) for another thread to do a fastpath
+       // monitor enter-exit while this thread is still trying to get
+       // to the reenter portion of the protocol.
+       //
+       // The ObjectMonitor was notified and the current thread is
+       // the successor which also means that an unpark() has already
+       // been done. The JVMTI_EVENT_MONITOR_WAITED event handler can
+       // consume the unpark() that was done when the successor was
+       // set because the same ParkEvent is shared between Java
+       // monitors and JVM/TI RawMonitors (for now).
+       //
+       // We redo the unpark() to ensure forward progress, i.e., we
+       // don't want all pending threads hanging (parked) with none
+       // entering the unlocked monitor.
+       node._event->unpark();
+     }
+
      if (event.should_commit()) {
        post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT);
      }
--- a/src/share/vm/runtime/safepoint.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/runtime/safepoint.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -545,7 +545,7 @@
 
   // rotate log files?
   if (UseGCLogFileRotation) {
-    gclog_or_tty->rotate_log();
+    gclog_or_tty->rotate_log(false);
   }
 
   if (MemTracker::is_on()) {
--- a/src/share/vm/runtime/vm_operations.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/runtime/vm_operations.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,6 +96,7 @@
   template(JFRCheckpoint)                         \
   template(Exit)                                  \
   template(LinuxDllLoad)                          \
+  template(RotateGCLog)                           \
 
 class VM_Operation: public CHeapObj<mtInternal> {
  public:
@@ -409,4 +410,15 @@
   void doit();
 };
 
+
+class VM_RotateGCLog: public VM_Operation {
+ private:
+  outputStream* _out;
+
+ public:
+  VM_RotateGCLog(outputStream* st) : _out(st) {}
+  VMOp_Type type() const { return VMOp_RotateGCLog; }
+  void doit() { gclog_or_tty->rotate_log(true, _out); }
+};
+
 #endif // SHARE_VM_RUNTIME_VM_OPERATIONS_HPP
--- a/src/share/vm/services/diagnosticCommand.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/services/diagnosticCommand.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -51,7 +51,7 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(true,false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(true,false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStopRemoteDCmd>(true,false));
-
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(true, false));
 }
 
 #ifndef HAVE_EXTRA_DCMD
@@ -565,3 +565,11 @@
     JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK);
 }
 
+void RotateGCLogDCmd::execute(TRAPS) {
+  if (UseGCLogFileRotation) {
+    VM_RotateGCLog rotateop(output());
+    VMThread::execute(&rotateop);
+  } else {
+    output()->print_cr("Target VM does not support GC log file rotation.");
+  }
+}
--- a/src/share/vm/services/diagnosticCommand.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/services/diagnosticCommand.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -302,4 +302,14 @@
   virtual void execute(TRAPS);
 };
 
+class RotateGCLogDCmd : public DCmd {
+public:
+  RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
+  static const char* name() { return "GC.rotate_log"; }
+  static const char* description() {
+    return "Force the GC log file to be rotated.";
+  }
+  virtual void execute(TRAPS);
+};
+
 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
--- a/src/share/vm/utilities/ostream.cpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/utilities/ostream.cpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -341,7 +341,7 @@
 }
 
 char* stringStream::as_string() {
-  char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
+  char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1);
   strncpy(copy, buffer, buffer_pos);
   copy[buffer_pos] = 0;  // terminating null
   return copy;
@@ -354,14 +354,148 @@
 outputStream* gclog_or_tty;
 extern Mutex* tty_lock;
 
+#define EXTRACHARLEN   32
+#define CURRENTAPPX    ".current"
+#define FILENAMEBUFLEN  1024
+// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS
+char* get_datetime_string(char *buf, size_t len) {
+  os::local_time_string(buf, len);
+  int i = (int)strlen(buf);
+  while (i-- >= 0) {
+    if (buf[i] == ' ') buf[i] = '_';
+    else if (buf[i] == ':') buf[i] = '-';
+  }
+  return buf;
+}
+
+static const char* make_log_name_internal(const char* log_name, const char* force_directory,
+                                                int pid, const char* tms) {
+  const char* basename = log_name;
+  char file_sep = os::file_separator()[0];
+  const char* cp;
+  char  pid_text[32];
+
+  for (cp = log_name; *cp != '\0'; cp++) {
+    if (*cp == '/' || *cp == file_sep) {
+      basename = cp + 1;
+    }
+  }
+  const char* nametail = log_name;
+  // Compute buffer length
+  size_t buffer_length;
+  if (force_directory != NULL) {
+    buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
+                    strlen(basename) + 1;
+  } else {
+    buffer_length = strlen(log_name) + 1;
+  }
+
+  // const char* star = strchr(basename, '*');
+  const char* pts = strstr(basename, "%p");
+  int pid_pos = (pts == NULL) ? -1 : (pts - nametail);
+
+  if (pid_pos >= 0) {
+    jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid);
+    buffer_length += strlen(pid_text);
+  }
+
+  pts = strstr(basename, "%t");
+  int tms_pos = (pts == NULL) ? -1 : (pts - nametail);
+  if (tms_pos >= 0) {
+    buffer_length += strlen(tms);
+  }
+
+  // File name is too long.
+  if (buffer_length > JVM_MAXPATHLEN) {
+    return NULL;
+  }
+
+  // Create big enough buffer.
+  char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
+
+  strcpy(buf, "");
+  if (force_directory != NULL) {
+    strcat(buf, force_directory);
+    strcat(buf, os::file_separator());
+    nametail = basename;       // completely skip directory prefix
+  }
+
+  // who is first, %p or %t?
+  int first = -1, second = -1;
+  const char *p1st = NULL;
+  const char *p2nd = NULL;
+
+  if (pid_pos >= 0 && tms_pos >= 0) {
+    // contains both %p and %t
+    if (pid_pos < tms_pos) {
+      // case foo%pbar%tmonkey.log
+      first  = pid_pos;
+      p1st   = pid_text;
+      second = tms_pos;
+      p2nd   = tms;
+    } else {
+      // case foo%tbar%pmonkey.log
+      first  = tms_pos;
+      p1st   = tms;
+      second = pid_pos;
+      p2nd   = pid_text;
+    }
+  } else if (pid_pos >= 0) {
+    // contains %p only
+    first  = pid_pos;
+    p1st   = pid_text;
+  } else if (tms_pos >= 0) {
+    // contains %t only
+    first  = tms_pos;
+    p1st   = tms;
+  }
+
+  int buf_pos = (int)strlen(buf);
+  const char* tail = nametail;
+
+  if (first >= 0) {
+    tail = nametail + first + 2;
+    strncpy(&buf[buf_pos], nametail, first);
+    strcpy(&buf[buf_pos + first], p1st);
+    buf_pos = (int)strlen(buf);
+    if (second >= 0) {
+      strncpy(&buf[buf_pos], tail, second - first - 2);
+      strcpy(&buf[buf_pos + second - first - 2], p2nd);
+      tail = nametail + second + 2;
+    }
+  }
+  strcat(buf, tail);      // append rest of name, or all of name
+  return buf;
+}
+
+// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name
+// in log_name, %p => pipd1234 and
+//              %t => YYYY-MM-DD_HH-MM-SS
+static const char* make_log_name(const char* log_name, const char* force_directory) {
+  char timestr[32];
+  get_datetime_string(timestr, sizeof(timestr));
+  return make_log_name_internal(log_name, force_directory, os::current_process_id(),
+                                timestr);
+}
+
 fileStream::fileStream(const char* file_name) {
   _file = fopen(file_name, "w");
-  _need_close = true;
+  if (_file != NULL) {
+    _need_close = true;
+  } else {
+    warning("Cannot open file %s due to %s\n", file_name, strerror(errno));
+    _need_close = false;
+  }
 }
 
 fileStream::fileStream(const char* file_name, const char* opentype) {
   _file = fopen(file_name, opentype);
-  _need_close = true;
+  if (_file != NULL) {
+    _need_close = true;
+  } else {
+    warning("Cannot open file %s due to %s\n", file_name, strerror(errno));
+    _need_close = false;
+  }
 }
 
 void fileStream::write(const char* s, size_t len) {
@@ -422,34 +556,51 @@
   update_position(s, len);
 }
 
-rotatingFileStream::~rotatingFileStream() {
+// dump vm version, os version, platform info, build id,
+// memory usage and command line flags into header
+void gcLogFileStream::dump_loggc_header() {
+  if (is_open()) {
+    print_cr(Abstract_VM_Version::internal_vm_info_string());
+    os::print_memory_info(this);
+    print("CommandLine flags: ");
+    CommandLineFlags::printSetFlags(this);
+  }
+}
+
+gcLogFileStream::~gcLogFileStream() {
   if (_file != NULL) {
     if (_need_close) fclose(_file);
-    _file      = NULL;
+    _file = NULL;
+  }
+  if (_file_name != NULL) {
     FREE_C_HEAP_ARRAY(char, _file_name, mtInternal);
     _file_name = NULL;
   }
 }
 
-rotatingFileStream::rotatingFileStream(const char* file_name) {
+gcLogFileStream::gcLogFileStream(const char* file_name) {
   _cur_file_num = 0;
   _bytes_written = 0L;
-  _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
-  jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
-  _file = fopen(_file_name, "w");
-  _need_close = true;
+  _file_name = make_log_name(file_name, NULL);
+
+  // gc log file rotation
+  if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) {
+    char tempbuf[FILENAMEBUFLEN];
+    jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
+    _file = fopen(tempbuf, "w");
+  } else {
+    _file = fopen(_file_name, "w");
+  }
+  if (_file != NULL) {
+    _need_close = true;
+    dump_loggc_header();
+  } else {
+    warning("Cannot open file %s due to %s\n", _file_name, strerror(errno));
+    _need_close = false;
+  }
 }
 
-rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) {
-  _cur_file_num = 0;
-  _bytes_written = 0L;
-  _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
-  jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
-  _file = fopen(_file_name, opentype);
-  _need_close = true;
-}
-
-void rotatingFileStream::write(const char* s, size_t len) {
+void gcLogFileStream::write(const char* s, size_t len) {
   if (_file != NULL) {
     size_t count = fwrite(s, 1, len, _file);
     _bytes_written += count;
@@ -465,8 +616,13 @@
 // write to gc log file at safepoint. If in future, changes made for mutator threads or
 // concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
 // must be synchronized.
-void rotatingFileStream::rotate_log() {
-  if (_bytes_written < (jlong)GCLogFileSize) {
+void gcLogFileStream::rotate_log(bool force, outputStream* out) {
+  char time_msg[FILENAMEBUFLEN];
+  char time_str[EXTRACHARLEN];
+  char current_file_name[FILENAMEBUFLEN];
+  char renamed_file_name[FILENAMEBUFLEN];
+
+  if (!should_rotate(force)) {
     return;
   }
 
@@ -480,27 +636,105 @@
     // rotate in same file
     rewind();
     _bytes_written = 0L;
+    jio_snprintf(time_msg, sizeof(time_msg), "File  %s rotated at %s\n",
+                 _file_name, os::local_time_string((char *)time_str, sizeof(time_str)));
+    write(time_msg, strlen(time_msg));
+
+    if (out != NULL) {
+      out->print(time_msg);
+    }
+
+    dump_loggc_header();
     return;
   }
 
-  // rotate file in names file.0, file.1, file.2, ..., file.<MaxGCLogFileNumbers-1>
-  // close current file, rotate to next file
+#if defined(_WINDOWS)
+#ifndef F_OK
+#define F_OK 0
+#endif
+#endif // _WINDOWS
+
+  // rotate file in names extended_filename.0, extended_filename.1, ...,
+  // extended_filename.<NumberOfGCLogFiles - 1>. Current rotation file name will
+  // have a form of extended_filename.<i>.current where i is the current rotation
+  // file number. After it reaches max file size, the file will be saved and renamed
+  // with .current removed from its tail.
+  size_t filename_len = strlen(_file_name);
   if (_file != NULL) {
-    _cur_file_num ++;
-    if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0;
-    jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d",
-             Arguments::gc_log_filename(), _cur_file_num);
+    jio_snprintf(renamed_file_name, filename_len + EXTRACHARLEN, "%s.%d",
+                 _file_name, _cur_file_num);
+    jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
+                 _file_name, _cur_file_num);
+
+    const char* msg = force ? "GC log rotation request has been received."
+                            : "GC log file has reached the maximum size.";
+    jio_snprintf(time_msg, sizeof(time_msg), "%s %s Saved as %s\n",
+                     os::local_time_string((char *)time_str, sizeof(time_str)),
+                                                         msg, renamed_file_name);
+    write(time_msg, strlen(time_msg));
+
+    if (out != NULL) {
+      out->print(time_msg);
+    }
+
     fclose(_file);
     _file = NULL;
+
+    bool can_rename = true;
+    if (access(current_file_name, F_OK) != 0) {
+      // current file does not exist?
+      warning("No source file exists, cannot rename\n");
+      can_rename = false;
+    }
+    if (can_rename) {
+      if (access(renamed_file_name, F_OK) == 0) {
+        if (remove(renamed_file_name) != 0) {
+          warning("Could not delete existing file %s\n", renamed_file_name);
+          can_rename = false;
+        }
+      } else {
+        // file does not exist, ok to rename
+      }
+    }
+    if (can_rename && rename(current_file_name, renamed_file_name) != 0) {
+      warning("Could not rename %s to %s\n", _file_name, renamed_file_name);
+    }
   }
-  _file = fopen(_file_name, "w");
+
+  _cur_file_num++;
+  if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0;
+  jio_snprintf(current_file_name,  filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
+               _file_name, _cur_file_num);
+  _file = fopen(current_file_name, "w");
+
   if (_file != NULL) {
     _bytes_written = 0L;
     _need_close = true;
+    // reuse current_file_name for time_msg
+    jio_snprintf(current_file_name, filename_len + EXTRACHARLEN,
+                 "%s.%d", _file_name, _cur_file_num);
+    jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n",
+                           os::local_time_string((char *)time_str, sizeof(time_str)),
+                           current_file_name);
+    write(time_msg, strlen(time_msg));
+
+    if (out != NULL) {
+      out->print(time_msg);
+    }
+
+    dump_loggc_header();
+    // remove the existing file
+    if (access(current_file_name, F_OK) == 0) {
+      if (remove(current_file_name) != 0) {
+        warning("Could not delete existing file %s\n", current_file_name);
+      }
+    }
   } else {
-    tty->print_cr("failed to open rotation log file %s due to %s\n",
+    warning("failed to open rotation log file %s due to %s\n"
+            "Turned off GC log file rotation\n",
                   _file_name, strerror(errno));
     _need_close = false;
+    FLAG_SET_DEFAULT(UseGCLogFileRotation, false);
   }
 }
 
@@ -529,72 +763,7 @@
   return _log_file != NULL;
 }
 
-static const char* make_log_name(const char* log_name, const char* force_directory) {
-  const char* basename = log_name;
-  char file_sep = os::file_separator()[0];
-  const char* cp;
-  for (cp = log_name; *cp != '\0'; cp++) {
-    if (*cp == '/' || *cp == file_sep) {
-      basename = cp+1;
-    }
-  }
-  const char* nametail = log_name;
-
-  // Compute buffer length
-  size_t buffer_length;
-  if (force_directory != NULL) {
-    buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
-                    strlen(basename) + 1;
-  } else {
-    buffer_length = strlen(log_name) + 1;
-  }
-
-  const char* star = strchr(basename, '*');
-  int star_pos = (star == NULL) ? -1 : (star - nametail);
-  int skip = 1;
-  if (star == NULL) {
-    // Try %p
-    star = strstr(basename, "%p");
-    if (star != NULL) {
-      skip = 2;
-    }
-  }
-  star_pos = (star == NULL) ? -1 : (star - nametail);
-
-  char pid[32];
-  if (star_pos >= 0) {
-    jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id());
-    buffer_length += strlen(pid);
-  }
-
-  // File name is too long.
-  if (buffer_length > JVM_MAXPATHLEN) {
-    return NULL;
-  }
-
-  // Create big enough buffer.
-  char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
-
-  strcpy(buf, "");
-  if (force_directory != NULL) {
-    strcat(buf, force_directory);
-    strcat(buf, os::file_separator());
-    nametail = basename;       // completely skip directory prefix
-  }
-
-  if (star_pos >= 0) {
-    // convert foo*bar.log or foo%pbar.log to foo123bar.log
-    int buf_pos = (int) strlen(buf);
-    strncpy(&buf[buf_pos], nametail, star_pos);
-    strcpy(&buf[buf_pos + star_pos], pid);
-    nametail += star_pos + skip;  // skip prefix and pid format
-  }
-
-  strcat(buf, nametail);      // append rest of name, or all of name
-  return buf;
-}
-
-fileStream* defaultStream::open_file(const char* log_name){
+fileStream* defaultStream::open_file(const char* log_name) {
   const char* try_name = make_log_name(log_name, NULL);
   if (try_name == NULL) {
     warning("Cannot open file %s: file name is too long.\n", log_name);
@@ -607,19 +776,20 @@
     return file;
   }
 
-  // Try again to open the file.
+  // Try again to open the file in the temp directory.
   delete file;
   char warnbuf[O_BUFLEN*2];
-  jio_snprintf(warnbuf, sizeof(warnbuf), "Warning:  Cannot open log file: %s\n", try_name);
+  jio_snprintf(warnbuf, sizeof(warnbuf), "Warning:  Cannot open log file: %s\n", log_name);
   // Note:  This feature is for maintainer use only.  No need for L10N.
   jio_print(warnbuf);
-  try_name = make_log_name("hs_pid%p.log", os::get_temp_directory());
+  try_name = make_log_name(log_name, os::get_temp_directory());
   if (try_name == NULL) {
-    warning("Cannot open file %s: file name is too long for directory %s.\n", "hs_pid", os::get_temp_directory());
+    warning("Cannot open file %s: file name is too long for directory %s.\n", log_name, os::get_temp_directory());
     return NULL;
   }
 
-  jio_snprintf(warnbuf, sizeof(warnbuf), "Warning:  Forcing option -XX:LogFile=%s\n", try_name);
+  jio_snprintf(warnbuf, sizeof(warnbuf),
+               "Warning:  Forcing option -XX:LogFile=%s\n", try_name);
   jio_print(warnbuf);
 
   file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
@@ -906,11 +1076,8 @@
 
   gclog_or_tty = tty; // default to tty
   if (Arguments::gc_log_filename() != NULL) {
-    fileStream * gclog  = UseGCLogFileRotation ?
-                          new(ResourceObj::C_HEAP, mtInternal)
-                             rotatingFileStream(Arguments::gc_log_filename()) :
-                          new(ResourceObj::C_HEAP, mtInternal)
-                             fileStream(Arguments::gc_log_filename());
+    fileStream * gclog  = new(ResourceObj::C_HEAP, mtInternal)
+                             gcLogFileStream(Arguments::gc_log_filename());
     if (gclog->is_open()) {
       // now we update the time stamp of the GC log to be synced up
       // with tty.
--- a/src/share/vm/utilities/ostream.hpp	Tue Oct 14 10:33:26 2014 -0700
+++ b/src/share/vm/utilities/ostream.hpp	Tue Oct 14 12:14:57 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -113,7 +113,7 @@
    // flushing
    virtual void flush() {}
    virtual void write(const char* str, size_t len) = 0;
-   virtual void rotate_log() {} // GC log rotation
+   virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation
    virtual ~outputStream() {}   // close properly on deletion
 
    void dec_cr() { dec(); cr(); }
@@ -228,21 +228,28 @@
   void flush() {};
 };
 
-class rotatingFileStream : public fileStream {
+class gcLogFileStream : public fileStream {
  protected:
-  char*  _file_name;
+  const char*  _file_name;
   jlong  _bytes_written;
-  uintx  _cur_file_num;             // current logfile rotation number, from 0 to MaxGCLogFileNumbers-1
+  uintx  _cur_file_num;             // current logfile rotation number, from 0 to NumberOfGCLogFiles-1
  public:
-  rotatingFileStream(const char* file_name);
-  rotatingFileStream(const char* file_name, const char* opentype);
-  rotatingFileStream(FILE* file) : fileStream(file) {}
-  ~rotatingFileStream();
+  gcLogFileStream(const char* file_name);
+  ~gcLogFileStream();
   virtual void write(const char* c, size_t len);
-  virtual void rotate_log();
+  virtual void rotate_log(bool force, outputStream* out = NULL);
+  void dump_loggc_header();
+
+  /* If "force" sets true, force log file rotation from outside JVM */
+  bool should_rotate(bool force) {
+    return force ||
+             ((GCLogFileSize != 0) && ((uintx)_bytes_written >= GCLogFileSize));
+  }
+
 };
 
 #ifndef PRODUCT
+// unit test for checking -Xloggc:<filename> parsing result
 void test_loggc_filename();
 #endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014 Google, Inc.  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
+ * @bug 8043354
+ * @summary  bcEscapeAnalyzer allocated_escapes not conservative enough
+ * @run main/othervm -XX:CompileOnly=.visitAndPop TestAllocatedEscapesPtrComparison
+ * @author Chuck Rasbold rasbold@google.com
+ */
+
+/*
+ * Test always passes with -XX:-OptmimizePtrCompare
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestAllocatedEscapesPtrComparison {
+
+  static TestAllocatedEscapesPtrComparison dummy;
+
+  class Marker {
+  }
+
+  List<Marker> markerList = new ArrayList<>();
+
+  // Suppress compilation of this method, it must be processed
+  // by the bytecode escape analyzer.
+
+  // Make a new marker and put it on the List
+  Marker getMarker() {
+    // result escapes through markerList
+    final Marker result = new Marker();
+    markerList.add(result);
+    return result;
+  }
+
+  void visit(int depth) {
+    // Make a new marker
+    getMarker();
+
+    // Call visitAndPop every once in a while
+    // Cap the depth of our recursive visits
+    if (depth % 10 == 2) {
+      visitAndPop(depth + 1);
+    } else if (depth < 15) {
+      visit(depth + 1);
+    }
+  }
+
+   void visitAndPop(int depth) {
+    // Random dummy allocation to force EscapeAnalysis to process this method
+    dummy = new TestAllocatedEscapesPtrComparison();
+
+    // Make a new marker
+    Marker marker = getMarker();
+
+    visit(depth + 1);
+
+    // Walk and pop the marker list up to the current marker
+    boolean found = false;
+    for (int i = markerList.size() - 1; i >= 0; i--) {
+      Marker removed = markerList.remove(i);
+
+      // In the failure, EA mistakenly converts this comparison to false
+      if (removed == marker) {
+        found = true;
+        break;
+      }
+    }
+
+    if (!found) {
+      throw new RuntimeException("test fails");
+    }
+  }
+
+
+  public static void main(String args[]) {
+    TestAllocatedEscapesPtrComparison tc = new TestAllocatedEscapesPtrComparison();
+
+    // Warmup and run enough times
+    for (int i = 0; i < 20000; i++) {
+      tc.visit(0);
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestPrintGCDetails.java	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 TestPrintGCDetails
+ * @bug 8010738
+ * @summary Ensure that the PrintGCDetails for a full GC with G1 includes PermGen size info.
+ * @key gc
+ * @key regression
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class TestPrintGCDetails {
+  public static void main(String[] args) throws Exception {
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
+                                                              "-XX:+PrintGCDetails",
+                                                              SystemGCTest.class.getName());
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+    System.out.println("Output:\n" + output.getOutput());
+
+    output.shouldContain("Perm");
+    output.shouldHaveExitValue(0);
+  }
+
+  static class SystemGCTest {
+    public static void main(String [] args) {
+      System.out.println("Calling System.gc()");
+      System.gc();
+    }
+  }
+}
--- a/test/runtime/7051189/Xchecksig.sh	Tue Oct 14 10:33:26 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-# 
-#  Copyright (c) 2011, 2012, 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 Xchecksig.sh
-# @bug 7051189
-# @summary Need to suppress info message if -xcheck:jni used with libjsig.so
-# @run shell Xchecksig.sh
-#
-
-if [ "${TESTSRC}" = "" ]
-then
-  TESTSRC=${PWD}
-  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-OS=`uname -s`
-case "$OS" in
-  Windows_* | CYGWIN_* )
-    printf "Not testing libjsig.so on Windows. PASSED.\n "
-    exit 0
-    ;;
-esac
-
-JAVA=${TESTJAVA}${FS}bin${FS}java
-
-# LD_PRELOAD arch needs to match the binary we run, so run the java
-# 64-bit binary directly if we are testing 64-bit (bin/ARCH/java).
-# Check if TESTVMOPS contains -d64, but cannot use 
-# java ${TESTVMOPS} to run "java -d64"  with LD_PRELOAD.
-
-if [ ${OS} -eq "SunOS" ]
-then
-  printf  "SunOS test TESTVMOPTS = ${TESTVMOPTS}"
-  printf ${TESTVMOPTS} | grep d64 > /dev/null
-  if [ $? -eq 0 ]
-  then
-    printf "SunOS 64-bit test\n"
-    BIT_FLAG=-d64
-  fi
-fi
-
-ARCH=`uname -p`
-case $ARCH in
-  i386)
-    if [ X${BIT_FLAG} != "X" ]
-    then
-      ARCH=amd64
-      JAVA=${TESTJAVA}${FS}bin${FS}${ARCH}${FS}java
-    fi
-    ;;
-  sparc)
-    if [ X${BIT_FLAG} != "X" ]
-    then
-      ARCH=sparcv9
-      JAVA=${TESTJAVA}${FS}bin${FS}${ARCH}${FS}java
-    fi
-    ;;
-  * )
-    printf "Not testing architecture $ARCH, skipping test.\n"
-    exit 0
-  ;; 
-esac
-
-LIBJSIG=${COMPILEJAVA}${FS}jre${FS}lib${FS}${ARCH}${FS}libjsig.so
-
-# If libjsig and binary do not match, skip test.
-
-A=`file ${LIBJSIG} | awk '{ print $3 }'`
-B=`file ${JAVA}    | awk '{ print $3 }'`
-
-if [ $A -ne $B ]
-then
-  printf "Mismatching binary and library to preload, skipping test.\n"
-  exit 0
-fi
-
-if [ ! -f ${LIBJSIG} ]
-then
-  printf "Skipping test: libjsig missing for given architecture: ${LIBJSIG}\n"
-  exit 0
-fi
-# Use java -version to test, java version info appears on stderr,
-# the libjsig message we are removing appears on stdout.
-
-# grep returns zero meaning found, non-zero means not found:
-
-LD_PRELOAD=${LIBJSIG} ${JAVA} ${TESTVMOPTS} -Xcheck:jni -version 2>&1  | grep "libjsig is activated"
-if [ $? -eq 0 ]; then
-  printf "Failed: -Xcheck:jni prints message when libjsig.so is loaded.\n"
-  exit 1
-fi
-
-
-LD_PRELOAD=${LIBJSIG} ${JAVA} ${TESTVMOPTS} -Xcheck:jni -verbose:jni -version 2>&1 | grep "libjsig is activated"
-if [ $? != 0 ]; then
-  printf "Failed: -Xcheck:jni does not print message when libjsig.so is loaded and -verbose:jni is set.\n"
-  exit 1
-fi
-
-printf "PASSED\n"
-exit 0
-
--- a/test/runtime/7196045/Test7196045.java	Tue Oct 14 10:33:26 2014 -0700
+++ b/test/runtime/7196045/Test7196045.java	Tue Oct 14 12:14:57 2014 -0700
@@ -26,7 +26,7 @@
  * @test
  * @bug 7196045
  * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
- * @run main/othervm Test7196045
+ * @run main/othervm -XX:+UsePerfData Test7196045
  */
 
 import java.lang.management.ManagementFactory;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/XCheckJniJsig/XCheckJSig.java	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 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
+ * @bug 7051189 8023393
+ * @summary Need to suppress info message if -Xcheck:jni is used with libjsig.so
+ * @library /testlibrary
+ * @run main XCheckJSig
+ */
+
+import java.util.*;
+import com.oracle.java.testlibrary.*;
+
+public class XCheckJSig {
+    public static void main(String args[]) throws Throwable {
+
+        System.out.println("Regression test for bugs 7051189 and 8023393");
+        if (!Platform.isSolaris() && !Platform.isLinux() && !Platform.isOSX()) {
+            System.out.println("Test only applicable on Solaris, Linux, and Mac OSX, skipping");
+            return;
+        }
+
+        String jdk_path = System.getProperty("test.jdk");
+        String os_arch = Platform.getOsArch();
+        String libjsig;
+        String env_var;
+        if (Platform.isOSX()) {
+            libjsig = jdk_path + "/jre/lib/server/libjsig.dylib";
+            env_var = "DYLD_INSERT_LIBRARIES";
+        } else {
+            libjsig = jdk_path + "/jre/lib/" + os_arch + "/libjsig.so";
+            env_var = "LD_PRELOAD";
+        }
+        String java_program;
+        if (Platform.isSolaris()) {
+            // On Solaris, need to call the 64-bit Java directly in order for
+            // LD_PRELOAD to work because libjsig.so is 64-bit.
+            java_program = jdk_path + "/jre/bin/" + os_arch + "/java";
+        } else {
+            java_program = JDKToolFinder.getJDKTool("java");
+        }
+        // If this test fails, these might be useful to know.
+        System.out.println("libjsig: " + libjsig);
+        System.out.println("osArch: " + os_arch);
+        System.out.println("java_program: " + java_program);
+
+        ProcessBuilder pb = new ProcessBuilder(java_program, "-Xcheck:jni", "-version");
+        Map<String, String> env = pb.environment();
+        env.put(env_var, libjsig);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("libjsig is activated");
+        output.shouldHaveExitValue(0);
+
+        pb = new ProcessBuilder(java_program, "-Xcheck:jni", "-verbose:jni", "-version");
+        env = pb.environment();
+        env.put(env_var, libjsig);
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("libjsig is activated");
+        output.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 TestEmptyBootstrapMethodsAttr
+ * @bug 8041918
+ * @library /testlibrary
+ * @summary Test empty bootstrap_methods table within BootstrapMethods attribute
+ * @compile TestEmptyBootstrapMethodsAttr.java
+ * @run main TestEmptyBootstrapMethodsAttr
+ */
+
+import java.io.File;
+import com.oracle.java.testlibrary.*;
+
+public class TestEmptyBootstrapMethodsAttr {
+
+    public static void main(String args[]) throws Throwable {
+        System.out.println("Regression test for bug 8041918");
+        String jarFile = System.getProperty("test.src") + File.separator + "emptynumbootstrapmethods.jar";
+
+        // ====== extract the test case
+        ProcessBuilder pb = new ProcessBuilder(new String[] { JDKToolFinder.getJDKTool("jar"), "xvf", jarFile } );
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+
+        // Test case #1:
+        // Try loading class with empty bootstrap_methods table where no
+        // other attributes are following BootstrapMethods in attribute table.
+        String className = "emptynumbootstrapmethods1";
+
+        // ======= execute test case #1
+        // Expect a lack of main method, this implies that the class loaded correctly
+        // with an empty bootstrap_methods and did not generate a ClassFormatError.
+        pb = ProcessTools.createJavaProcessBuilder("-cp", ".", className);
+        output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("java.lang.ClassFormatError");
+        output.shouldContain("Main method not found in class " + className);
+        output.shouldHaveExitValue(1);
+
+        // Test case #2:
+        // Try loading class with empty bootstrap_methods table where an
+        // AnnotationDefault attribute follows the BootstrapMethods in the attribute table.
+        className = "emptynumbootstrapmethods2";
+
+        // ======= execute test case #2
+        // Expect a lack of main method, this implies that the class loaded correctly
+        // with an empty bootstrap_methods and did not generate ClassFormatError.
+        pb = ProcessTools.createJavaProcessBuilder("-cp", ".", className);
+        output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("java.lang.ClassFormatError");
+        output.shouldContain("Main method not found in class " + className);
+        output.shouldHaveExitValue(1);
+    }
+}
Binary file test/runtime/classFileParserBug/emptynumbootstrapmethods.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a BootstrapMethods attribute with an empty
+ * bootstrap_methods table.  This yields a BootstrapMethods
+ * attribute length of 2 and should not cause a
+ * java.lang.ClassFormatError to be thrown.
+ */
+class emptynumbootstrapmethods1 {
+  0xCAFEBABE;
+  0; // minor version
+  51; // version
+  [12] { // Constant Pool
+    ; // first element is empty
+    class #2; // #1     at 0x0A
+    Utf8 "emptynumbootstrapmethods1"; // #2     at 0x0D
+    class #4; // #3     at 0x1F
+    Utf8 "java/lang/Object"; // #4     at 0x22
+    MethodHandle 5b #9; // #5     at 0x35
+    NameAndType #7 #8; // #6     at 0x39
+    Utf8 "equals"; // #7     at 0x3E
+    Utf8 "(Ljava/lang/Object;)Z"; // #8     at 0x47
+    Method #3 #6; // #9     at 0x5F
+    Utf8 "equalsx"; // #10    at 0x3E
+    Utf8 "BootstrapMethods"; // #11     at 0x69
+  } // Constant Pool
+
+  0x0001; // access
+  #1;// this_cpx
+  #3;// super_cpx
+
+  [0] { // Interfaces
+  } // Interfaces
+
+  [0] { // fields
+  } // fields
+
+  [0] { // methods
+  } // methods
+
+  [1] { // Attributes
+    Attr(#11, 2) { // BootstrapMethods at 0x8A
+      [0] { // bootstrap_methods
+      }
+    } // end BootstrapMethods
+  } // Attributes
+} // end class atrbsm00101m10p
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a BootstrapMethods attribute with an empty
+ * bootstrap_methods table.  This yields a BootstrapMethods
+ * attribute length of 2 and should not cause a
+ * java.lang.ClassFormatError to be thrown. To ensure that an empty
+ * bootstrap_methods table is parsed correctly, another attribute,
+ * AnnotationDefault, follows the BootstrapMethods attribute in 
+ * the attribute table.
+ */
+
+class emptynumbootstrapmethods2 {
+  0xCAFEBABE;
+  0; // minor version
+  51; // version
+  [14] { // Constant Pool
+    ; // first element is empty
+    class #2; // #1     at 0x0A
+    Utf8 "emptynumbootstrapmethods2"; // #2     at 0x0D
+    class #4; // #3     at 0x1F
+    Utf8 "java/lang/Object"; // #4     at 0x22
+    MethodHandle 5b #9; // #5     at 0x35
+    NameAndType #7 #8; // #6     at 0x39
+    Utf8 "equals"; // #7     at 0x3E
+    Utf8 "(Ljava/lang/Object;)Z"; // #8     at 0x47
+    Method #3 #6; // #9     at 0x5F
+    Utf8 "equalsx"; // #10    at 0x3E
+    Utf8 "BootstrapMethods"; // #11     at 0x69
+    Utf8 "AnnotationDefault"; // #12
+    Utf8 "LAnnotationDefaultI;"; // #13
+  } // Constant Pool
+
+  0x0001; // access
+  #1;// this_cpx
+  #3;// super_cpx
+
+  [0] { // Interfaces
+  } // Interfaces
+
+  [0] { // fields
+  } // fields
+
+  [0] { // methods
+  } // methods
+
+  [2] { // Attributes
+    Attr(#11, 2) { // BootstrapMethods at 0x8A
+      [0] { // bootstrap_methods
+      }
+    } // end BootstrapMethods
+    ;
+    Attr(#12) { // AnnotationDefault
+      [] { // type annotations
+        { // type annotation
+          0x00;  // target_type
+          0x00;  // type_parameter_index
+          []b { //  type_path
+          }
+
+          #13; // type_index
+          [] { // element_value_pairs
+          } // element_value_pairs
+        } // type annotation
+      } // type annotations
+    } // end AnnotationDefault
+  } // Attributes
+} // end class atrbsm00101m10p
--- a/test/serviceability/sa/jmap-hashcode/Test8028623.java	Tue Oct 14 10:33:26 2014 -0700
+++ b/test/serviceability/sa/jmap-hashcode/Test8028623.java	Tue Oct 14 12:14:57 2014 -0700
@@ -26,6 +26,8 @@
  * @bug 8028623
  * @summary Test hashing of extended characters in Serviceability Agent.
  * @library /testlibrary
+ * @compile -encoding utf8 Test8028623.java
+ * @run main Test8028623
  */
 
 import com.oracle.java.testlibrary.JDKToolLauncher;
@@ -36,12 +38,12 @@
 
 public class Test8028623 {
 
-  public static int à = 1;
+  public static int ?? = 1;
   public static String dumpFile = "heap.out";
 
   public static void main (String[] args) {
 
-    System.out.println(Ã);
+    System.out.println(??);
 
     try {
         int pid = ProcessTools.getProcessId();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary_tests/AssertsTest.java	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import static com.oracle.java.testlibrary.Asserts.*;
+
+/* @test
+ * @summary Tests the different assertions in the Assert class
+ * @library /testlibrary
+ */
+public class AssertsTest {
+    private static class Foo implements Comparable<Foo> {
+        final int id;
+        public Foo(int id) {
+            this.id = id;
+        }
+
+        public int compareTo(Foo f) {
+            return new Integer(id).compareTo(new Integer(f.id));
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        testLessThan();
+        testLessThanOrEqual();
+        testEquals();
+        testGreaterThanOrEqual();
+        testGreaterThan();
+        testNotEquals();
+        testNull();
+        testNotNull();
+        testTrue();
+        testFalse();
+    }
+
+    private static void testLessThan() throws Exception {
+        expectPass(Assertion.LT, 1, 2);
+
+        expectFail(Assertion.LT, 2, 2);
+        expectFail(Assertion.LT, 2, 1);
+        expectFail(Assertion.LT, null, 2);
+        expectFail(Assertion.LT, 2, null);
+    }
+
+    private static void testLessThanOrEqual() throws Exception {
+        expectPass(Assertion.LTE, 1, 2);
+        expectPass(Assertion.LTE, 2, 2);
+
+        expectFail(Assertion.LTE, 3, 2);
+        expectFail(Assertion.LTE, null, 2);
+        expectFail(Assertion.LTE, 2, null);
+    }
+
+    private static void testEquals() throws Exception {
+        expectPass(Assertion.EQ, 1, 1);
+        expectPass(Assertion.EQ, null, null);
+
+        Foo f1 = new Foo(1);
+        expectPass(Assertion.EQ, f1, f1);
+
+        Foo f2 = new Foo(1);
+        expectFail(Assertion.EQ, f1, f2);
+        expectFail(Assertion.LTE, null, 2);
+        expectFail(Assertion.LTE, 2, null);
+    }
+
+    private static void testGreaterThanOrEqual() throws Exception {
+        expectPass(Assertion.GTE, 1, 1);
+        expectPass(Assertion.GTE, 2, 1);
+
+        expectFail(Assertion.GTE, 1, 2);
+        expectFail(Assertion.GTE, null, 2);
+        expectFail(Assertion.GTE, 2, null);
+    }
+
+    private static void testGreaterThan() throws Exception {
+        expectPass(Assertion.GT, 2, 1);
+
+        expectFail(Assertion.GT, 1, 1);
+        expectFail(Assertion.GT, 1, 2);
+        expectFail(Assertion.GT, null, 2);
+        expectFail(Assertion.GT, 2, null);
+    }
+
+    private static void testNotEquals() throws Exception {
+        expectPass(Assertion.NE, null, 1);
+        expectPass(Assertion.NE, 1, null);
+
+        Foo f1 = new Foo(1);
+        Foo f2 = new Foo(1);
+        expectPass(Assertion.NE, f1, f2);
+
+        expectFail(Assertion.NE, null, null);
+        expectFail(Assertion.NE, f1, f1);
+        expectFail(Assertion.NE, 1, 1);
+    }
+
+    private static void testNull() throws Exception {
+        expectPass(Assertion.NULL, null);
+
+        expectFail(Assertion.NULL, 1);
+    }
+
+    private static void testNotNull() throws Exception {
+        expectPass(Assertion.NOTNULL, 1);
+
+        expectFail(Assertion.NOTNULL, null);
+    }
+
+    private static void testTrue() throws Exception {
+        expectPass(Assertion.TRUE, true);
+
+        expectFail(Assertion.TRUE, false);
+    }
+
+    private static void testFalse() throws Exception {
+        expectPass(Assertion.FALSE, false);
+
+        expectFail(Assertion.FALSE, true);
+    }
+
+    private static <T extends Comparable<T>> void expectPass(Assertion assertion, T ... args)
+        throws Exception {
+        Assertion.run(assertion, args);
+    }
+
+    private static <T extends Comparable<T>> void expectFail(Assertion assertion, T ... args)
+        throws Exception {
+        try {
+            Assertion.run(assertion, args);
+        } catch (RuntimeException e) {
+            return;
+        }
+        throw new Exception("Expected " + Assertion.format(assertion, (Object[]) args) +
+                            " to throw a RuntimeException");
+    }
+
+}
+
+enum Assertion {
+    LT, LTE, EQ, GTE, GT, NE, NULL, NOTNULL, FALSE, TRUE;
+
+    public static <T extends Comparable<T>> void run(Assertion assertion, T ... args) {
+        String msg = "Expected " + format(assertion, args) + " to pass";
+        switch (assertion) {
+            case LT:
+                assertLessThan(args[0], args[1], msg);
+                break;
+            case LTE:
+                assertLessThanOrEqual(args[0], args[1], msg);
+                break;
+            case EQ:
+                assertEquals(args[0], args[1], msg);
+                break;
+            case GTE:
+                assertGreaterThanOrEqual(args[0], args[1], msg);
+                break;
+            case GT:
+                assertGreaterThan(args[0], args[1], msg);
+                break;
+            case NE:
+                assertNotEquals(args[0], args[1], msg);
+                break;
+            case NULL:
+                assertNull(args == null ? args : args[0], msg);
+                break;
+            case NOTNULL:
+                assertNotNull(args == null ? args : args[0], msg);
+                break;
+            case FALSE:
+                assertFalse((Boolean) args[0], msg);
+                break;
+            case TRUE:
+                assertTrue((Boolean) args[0], msg);
+                break;
+            default:
+                // do nothing
+        }
+    }
+
+    public static String format(Assertion assertion, Object ... args) {
+        switch (assertion) {
+            case LT:
+                return asString("assertLessThan", args);
+            case LTE:
+                return asString("assertLessThanOrEqual", args);
+            case EQ:
+                return asString("assertEquals", args);
+            case GTE:
+                return asString("assertGreaterThanOrEquals", args);
+            case GT:
+                return asString("assertGreaterThan", args);
+            case NE:
+                return asString("assertNotEquals", args);
+            case NULL:
+                return asString("assertNull", args);
+            case NOTNULL:
+                return asString("assertNotNull", args);
+            case FALSE:
+                return asString("assertFalse", args);
+            case TRUE:
+                return asString("assertTrue", args);
+            default:
+                return "";
+        }
+    }
+
+    private static String asString(String assertion, Object ... args) {
+        if (args == null) {
+            return String.format("%s(null)", assertion);
+        }
+        if (args.length == 1) {
+            return String.format("%s(%s)", assertion, args[0]);
+        } else {
+            return String.format("%s(%s, %s)", assertion, args[0], args[1]);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary_tests/OutputAnalyzerReportingTest.java	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013, 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
+ * @summary Test the OutputAnalyzer reporting functionality,
+ *     such as printing additional diagnostic info
+ *     (exit code, stdout, stderr, command line, etc.)
+ * @library /testlibrary
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class OutputAnalyzerReportingTest {
+
+    public static void main(String[] args) throws Exception {
+        // Create the output analyzer under test
+        String stdout = "aaaaaa";
+        String stderr = "bbbbbb";
+        OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
+
+        // Expected summary values should be the same for all cases,
+        // since the outputAnalyzer object is the same
+        String expectedExitValue = "-1";
+        String expectedSummary =
+                " stdout: [" + stdout + "];\n" +
+                " stderr: [" + stderr + "]\n" +
+                " exitValue = " + expectedExitValue + "\n";
+
+
+        DiagnosticSummaryTestRunner testRunner =
+                new DiagnosticSummaryTestRunner();
+
+        // should have exit value
+        testRunner.init(expectedSummary);
+        int unexpectedExitValue = 2;
+        try {
+            output.shouldHaveExitValue(unexpectedExitValue);
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should not contain
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldNotContain(stdout);
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should contain
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldContain("unexpected-stuff");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should not match
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldNotMatch("[a]");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should match
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldMatch("[qwerty]");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+    }
+
+    private static class DiagnosticSummaryTestRunner {
+        private ByteArrayOutputStream byteStream =
+                new ByteArrayOutputStream(10000);
+
+        private String expectedSummary = "";
+        private PrintStream errStream;
+
+
+        public void init(String expectedSummary) {
+            this.expectedSummary = expectedSummary;
+            byteStream.reset();
+            errStream = new PrintStream(byteStream);
+            System.setErr(errStream);
+        }
+
+        public void closeAndCheckResults() {
+            // check results
+            errStream.close();
+            String stdErrStr = byteStream.toString();
+            if (!stdErrStr.contains(expectedSummary)) {
+                throw new RuntimeException("The output does not contain "
+                    + "the diagnostic message, or the message is incorrect");
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary_tests/OutputAnalyzerTest.java	Tue Oct 14 12:14:57 2014 -0700
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2013, 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
+ * @summary Test the OutputAnalyzer utility class
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+public class OutputAnalyzerTest {
+
+  public static void main(String args[]) throws Exception {
+
+    String stdout = "aaaaaa";
+    String stderr = "bbbbbb";
+
+    // Regexps used for testing pattern matching of the test input
+    String stdoutPattern = "[a]";
+    String stderrPattern = "[b]";
+    String nonExistingPattern = "[c]";
+
+    OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
+
+    if (!stdout.equals(output.getStdout())) {
+      throw new Exception("getStdout() returned '" + output.getStdout() + "', expected '" + stdout + "'");
+    }
+
+    if (!stderr.equals(output.getStderr())) {
+      throw new Exception("getStderr() returned '" + output.getStderr() + "', expected '" + stderr + "'");
+    }
+
+    try {
+      output.shouldContain(stdout);
+      output.stdoutShouldContain(stdout);
+      output.shouldContain(stderr);
+      output.stderrShouldContain(stderr);
+    } catch (RuntimeException e) {
+      throw new Exception("shouldContain() failed", e);
+    }
+
+    try {
+      output.shouldContain("cccc");
+      throw new Exception("shouldContain() failed to throw exception");
+    } catch (RuntimeException e) {
+      // expected
+    }
+
+    try {
+      output.stdoutShouldContain(stderr);
+      throw new Exception("stdoutShouldContain() failed to throw exception");
+    } catch (RuntimeException e) {
+      // expected
+    }
+
+    try {
+      output.stderrShouldContain(stdout);
+      throw new Exception("stdoutShouldContain() failed to throw exception");
+    } catch (RuntimeException e) {
+      // expected
+    }
+
+    try {
+      output.shouldNotContain("cccc");
+      output.stdoutShouldNotContain("cccc");
+      output.stderrShouldNotContain("cccc");
+    } catch (RuntimeException e) {
+      throw new Exception("shouldNotContain() failed", e);
+    }
+
+    try {
+      output.shouldNotContain(stdout);
+      throw new Exception("shouldContain() failed to throw exception");
+    } catch (RuntimeException e) {
+      // expected
+    }
+
+    try {
+      output.stdoutShouldNotContain(stdout);
+      throw new Exception("shouldContain() failed to throw exception");
+    } catch (RuntimeException e) {
+      // expected
+    }
+
+    try {
+        output.stderrShouldNotContain(stderr);
+        throw new Exception("shouldContain() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    // Should match
+    try {
+        output.shouldMatch(stdoutPattern);
+        output.stdoutShouldMatch(stdoutPattern);
+        output.shouldMatch(stderrPattern);
+        output.stderrShouldMatch(stderrPattern);
+    } catch (RuntimeException e) {
+        throw new Exception("shouldMatch() failed", e);
+    }
+
+    try {
+        output.shouldMatch(nonExistingPattern);
+        throw new Exception("shouldMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    try {
+        output.stdoutShouldMatch(stderrPattern);
+        throw new Exception(
+                "stdoutShouldMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    try {
+        output.stderrShouldMatch(stdoutPattern);
+        throw new Exception(
+                "stderrShouldMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    // Should not match
+    try {
+        output.shouldNotMatch(nonExistingPattern);
+        output.stdoutShouldNotMatch(nonExistingPattern);
+        output.stderrShouldNotMatch(nonExistingPattern);
+    } catch (RuntimeException e) {
+        throw new Exception("shouldNotMatch() failed", e);
+    }
+
+    try {
+        output.shouldNotMatch(stdoutPattern);
+        throw new Exception("shouldNotMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    try {
+        output.stdoutShouldNotMatch(stdoutPattern);
+        throw new Exception("shouldNotMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    try {
+        output.stderrShouldNotMatch(stderrPattern);
+        throw new Exception("shouldNotMatch() failed to throw exception");
+    } catch (RuntimeException e) {
+        // expected
+    }
+
+    {
+      String aaaa = "aaaa";
+      String result = output.firstMatch(aaaa);
+      if (!aaaa.equals(result)) {
+        throw new Exception("firstMatch(String) faild to match. Expected: " + aaaa + " got: " + result);
+      }
+    }
+
+    {
+      String aa = "aa";
+      String aa_grouped_aa = aa + "(" + aa + ")";
+      String result = output.firstMatch(aa_grouped_aa, 1);
+      if (!aa.equals(result)) {
+        throw new Exception("firstMatch(String, int) failed to match. Expected: " + aa + " got: " + result);
+      }
+    }
+  }
+}