changeset 5997:9b04c0f54507

Merge
author asaha
date Wed, 10 Sep 2014 15:38:47 -0700
parents 8650025672d3 (diff) b6162d8973c3 (current diff)
children 436c55e3e3bf
files .hgtags
diffstat 51 files changed, 2448 insertions(+), 410 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Sep 08 12:36:58 2014 -0700
+++ b/.hgtags	Wed Sep 10 15:38:47 2014 -0700
@@ -733,3 +733,13 @@
 c17a8487086433e14cd22373039a8b6b48e7cbb8 jdk7u72-b11
 a9e695f0d831f115720a4dcad3d33e0003b0acad jdk7u72-b12
 ac701f87d1ea46033c69f3e1cb84fc0a971da70c jdk7u72-b13
+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
--- a/make/hotspot_version	Mon Sep 08 12:36:58 2014 -0700
+++ b/make/hotspot_version	Wed Sep 10 15:38:47 2014 -0700
@@ -34,8 +34,8 @@
 HOTSPOT_VM_COPYRIGHT=Copyright 2014
 
 HS_MAJOR_VER=24
-HS_MINOR_VER=72
-HS_BUILD_NUMBER=04
+HS_MINOR_VER=80
+HS_BUILD_NUMBER=07
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/jprt.properties	Mon Sep 08 12:36:58 2014 -0700
+++ b/make/jprt.properties	Wed Sep 10 15:38:47 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/cpu/x86/vm/assembler_x86.cpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Wed Sep 10 15:38:47 2014 -0700
@@ -7641,10 +7641,12 @@
   // if fast computation is not possible, result is NaN. Requires
   // fallback from user of this macro.
   // increase precision for intermediate steps of the computation
+  BLOCK_COMMENT("fast_pow {");
   increase_precision();
   fyl2x();                 // Stack: (Y*log2(X)) ...
   pow_exp_core_encoding(); // Stack: exp(X) ...
   restore_precision();
+  BLOCK_COMMENT("} fast_pow");
 }
 
 void MacroAssembler::fast_exp() {
--- a/src/os/bsd/vm/os_bsd.cpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/os/bsd/vm/os_bsd.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/classfile/classFileParser.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/classfile/stackMapFrame.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/classfile/stackMapFrame.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/classfile/stackMapTable.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Wed Sep 10 15:38:47 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/oops/objArrayOop.hpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/oops/objArrayOop.hpp	Wed Sep 10 15:38:47 2014 -0700
@@ -45,9 +45,10 @@
 private:
   // Give size of objArrayOop in HeapWords minus the header
   static int array_size(int length) {
-    const int OopsPerHeapWord = HeapWordSize/heapOopSize;
+    const uint OopsPerHeapWord = HeapWordSize/heapOopSize;
     assert(OopsPerHeapWord >= 1 && (HeapWordSize % heapOopSize == 0),
            "Else the following (new) computation would be in error");
+    uint res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
 #ifdef ASSERT
     // The old code is left in for sanity-checking; it'll
     // go away pretty soon. XXX
@@ -55,16 +56,15 @@
     // oop->length() * HeapWordsPerOop;
     // With narrowOops, HeapWordsPerOop is 1/2 or equal 0 as an integer.
     // The oop elements are aligned up to wordSize
-    const int HeapWordsPerOop = heapOopSize/HeapWordSize;
-    int old_res;
+    const uint HeapWordsPerOop = heapOopSize/HeapWordSize;
+    uint old_res;
     if (HeapWordsPerOop > 0) {
       old_res = length * HeapWordsPerOop;
     } else {
-      old_res = align_size_up(length, OopsPerHeapWord)/OopsPerHeapWord;
+      old_res = align_size_up((uint)length, OopsPerHeapWord)/OopsPerHeapWord;
     }
+    assert(res == old_res, "Inconsistency between old and new.");
 #endif  // ASSERT
-    int res = ((uint)length + OopsPerHeapWord - 1)/OopsPerHeapWord;
-    assert(res == old_res, "Inconsistency between old and new.");
     return res;
   }
 
--- a/src/share/vm/opto/ifnode.cpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/opto/ifnode.cpp	Wed Sep 10 15:38:47 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/library_call.cpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/opto/library_call.cpp	Wed Sep 10 15:38:47 2014 -0700
@@ -201,7 +201,7 @@
   bool inline_math(vmIntrinsics::ID id);
   bool inline_exp();
   bool inline_pow();
-  void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
+  Node* finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
   bool inline_min_max(vmIntrinsics::ID id);
   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
   // This returns Type::AnyPtr, RawPtr, or OopPtr.
@@ -1580,7 +1580,7 @@
   return true;
 }
 
-void LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName) {
+Node* LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName) {
   //-------------------
   //result=(result.isNaN())? funcAddr():result;
   // Check: If isNaN() by checking result!=result? then either trap
@@ -1596,7 +1596,7 @@
       uncommon_trap(Deoptimization::Reason_intrinsic,
                     Deoptimization::Action_make_not_entrant);
     }
-    set_result(result);
+    return result;
   } else {
     // If this inlining ever returned NaN in the past, we compile a call
     // to the runtime to properly handle corner cases
@@ -1626,9 +1626,10 @@
 
       result_region->init_req(2, control());
       result_val->init_req(2, value);
-      set_result(result_region, result_val);
+      set_control(_gvn.transform(result_region));
+      return _gvn.transform(result_val);
     } else {
-      set_result(result);
+      return result;
     }
   }
 }
@@ -1640,7 +1641,8 @@
   Node* arg = round_double_node(argument(0));
   Node* n   = _gvn.transform(new (C) ExpDNode(C, control(), arg));
 
-  finish_pow_exp(n, arg, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
+  n = finish_pow_exp(n, arg, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
+  set_result(n);
 
   C->set_has_split_ifs(true); // Has chance for split-if optimization
   return true;
@@ -1650,27 +1652,48 @@
 // Inline power instructions, if possible.
 bool LibraryCallKit::inline_pow() {
   // Pseudocode for pow
-  // if (x <= 0.0) {
-  //   long longy = (long)y;
-  //   if ((double)longy == y) { // if y is long
-  //     if (y + 1 == y) longy = 0; // huge number: even
-  //     result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
+  // if (y == 2) {
+  //   return x * x;
+  // } else {
+  //   if (x <= 0.0) {
+  //     long longy = (long)y;
+  //     if ((double)longy == y) { // if y is long
+  //       if (y + 1 == y) longy = 0; // huge number: even
+  //       result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
+  //     } else {
+  //       result = NaN;
+  //     }
   //   } else {
-  //     result = NaN;
+  //     result = DPow(x,y);
   //   }
-  // } else {
-  //   result = DPow(x,y);
+  //   if (result != result)?  {
+  //     result = uncommon_trap() or runtime_call();
+  //   }
+  //   return result;
   // }
-  // if (result != result)?  {
-  //   result = uncommon_trap() or runtime_call();
-  // }
-  // return result;
 
   Node* x = round_double_node(argument(0));
   Node* y = round_double_node(argument(2));
 
   Node* result = NULL;
 
+  Node*   const_two_node = makecon(TypeD::make(2.0));
+  Node*   cmp_node       = _gvn.transform(new (C) CmpDNode(y, const_two_node));
+  Node*   bool_node      = _gvn.transform(new (C) BoolNode(cmp_node, BoolTest::eq));
+  IfNode* if_node        = create_and_xform_if(control(), bool_node, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
+  Node*   if_true        = _gvn.transform(new (C) IfTrueNode(if_node));
+  Node*   if_false       = _gvn.transform(new (C) IfFalseNode(if_node));
+
+  RegionNode* region_node = new (C) RegionNode(3);
+  region_node->init_req(1, if_true);
+
+  Node* phi_node = new (C) PhiNode(region_node, Type::DOUBLE);
+  // special case for x^y where y == 2, we can convert it to x * x
+  phi_node->init_req(1, _gvn.transform(new (C) MulDNode(x, x)));
+
+  // set control to if_false since we will now process the false branch
+  set_control(if_false);
+
   if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
     // Short form: skip the fancy tests and just check for NaN result.
     result = _gvn.transform(new (C) PowDNode(C, control(), x, y));
@@ -1794,7 +1817,15 @@
     result = _gvn.transform(phi);
   }
 
-  finish_pow_exp(result, x, y, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
+  result = finish_pow_exp(result, x, y, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
+
+  // control from finish_pow_exp is now input to the region node
+  region_node->set_req(2, control());
+  // the result from finish_pow_exp is now input to the phi node
+  phi_node->init_req(2, result);
+  set_control(_gvn.transform(region_node));
+  record_for_igvn(region_node);
+  set_result(_gvn.transform(phi_node));
 
   C->set_has_split_ifs(true); // Has chance for split-if optimization
   return true;
--- a/src/share/vm/opto/loopopts.cpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/opto/loopopts.cpp	Wed Sep 10 15:38:47 2014 -0700
@@ -2754,11 +2754,11 @@
       // Hit!  Refactor use to use the post-incremented tripcounter.
       // Compute a post-increment tripcounter.
       Node *opaq = new (C) Opaque2Node( C, cle->incr() );
-      register_new_node( opaq, u_ctrl );
+      register_new_node(opaq, exit);
       Node *neg_stride = _igvn.intcon(-cle->stride_con());
       set_ctrl(neg_stride, C->root());
       Node *post = new (C) AddINode( opaq, neg_stride);
-      register_new_node( post, u_ctrl );
+      register_new_node(post, exit);
       _igvn.rehash_node_delayed(use);
       for (uint j = 1; j < use->req(); j++) {
         if (use->in(j) == phi)
--- a/src/share/vm/opto/runtime.cpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/opto/runtime.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/opto/runtime.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/opto/superword.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/prims/jni.cpp	Wed Sep 10 15:38:47 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.
  *
@@ -5037,6 +5037,7 @@
 #include "gc_implementation/shared/gcTimer.hpp"
 #include "gc_interface/collectedHeap.hpp"
 #include "utilities/quickSort.hpp"
+#include "utilities/ostream.hpp"
 
 #define run_unit_test(unit_test_function_call)              \
   tty->print_cr("Running test: " #unit_test_function_call); \
@@ -5058,6 +5059,7 @@
     run_unit_test(QuickSort::test_quick_sort());
     run_unit_test(AltHashing::test_alt_hash());
     run_unit_test(TestOldFreeSpaceCalculation_test());
+    run_unit_test(test_loggc_filename());
     tty->print_cr("All internal VM tests passed");
   }
 }
--- a/src/share/vm/prims/jvm.cpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/prims/jvm.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/prims/jvmtiEnvBase.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Wed Sep 10 15:38:47 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();
@@ -2037,6 +2080,9 @@
                                      1, 100, "TLABWasteTargetPercent");
 
   status = status && verify_object_alignment();
+#ifdef COMPILER1
+  status = status && verify_min_value(ValueMapInitialSize, 1, "ValueMapInitialSize");
+#endif
 
 #ifdef SPARC
   if (UseConcMarkSweepGC || UseG1GC) {
@@ -2398,7 +2444,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 +2570,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 +3341,6 @@
 #endif // CC_INTERP
 
 #ifdef COMPILER2
-  if (!UseBiasedLocking || EmitSync != 0) {
-    UseOptoBiasInlining = false;
-  }
   if (!EliminateLocks) {
     EliminateNestedLocks = false;
   }
@@ -3334,6 +3384,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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/runtime/globals.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/runtime/objectMonitor.cpp	Wed Sep 10 15:38:47 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());
@@ -415,6 +421,15 @@
       jt->java_suspend_self();
     }
     Self->set_current_pending_monitor(NULL);
+
+    // We cleared the pending monitor info since we've just gotten past
+    // the enter-check-for-suspend dance and we now own the monitor free
+    // and clear, i.e., it is no longer pending. The ThreadBlockInVM
+    // destructor can go to a safepoint at the end of this block. If we
+    // do a thread dump during that safepoint, then this thread will show
+    // as having "-locked" the monitor, but the OS and java.lang.Thread
+    // states will still report that the thread is blocked trying to
+    // acquire it.
   }
 
   Atomic::dec_ptr(&_count);
@@ -442,6 +457,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 +1480,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 +1531,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 +1614,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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/runtime/safepoint.cpp	Wed Sep 10 15:38:47 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/vframe.cpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/runtime/vframe.cpp	Wed Sep 10 15:38:47 2014 -0700
@@ -197,6 +197,7 @@
         continue;
       }
       if (monitor->owner() != NULL) {
+        // the monitor is associated with an object, i.e., it is locked
 
         // First, assume we have the monitor locked. If we haven't found an
         // owned monitor before and this is the first frame, then we need to
@@ -207,7 +208,11 @@
         if (!found_first_monitor && frame_count == 0) {
           markOop mark = monitor->owner()->mark();
           if (mark->has_monitor() &&
-              mark->monitor() == thread()->current_pending_monitor()) {
+              ( // we have marked ourself as pending on this monitor
+                mark->monitor() == thread()->current_pending_monitor() ||
+                // we are not the owner of this monitor
+                !mark->monitor()->is_entered(thread())
+              )) {
             lock_state = "waiting to lock";
           }
         }
--- a/src/share/vm/runtime/vm_operations.hpp	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/runtime/vm_operations.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/services/diagnosticCommand.cpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/services/diagnosticCommand.hpp	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/utilities/ostream.cpp	Wed Sep 10 15:38:47 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,190 @@
 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);
+  }
+
+  // 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);
+}
+
+#ifndef PRODUCT
+void test_loggc_filename() {
+  int pid;
+  char  tms[32];
+  char  i_result[FILENAMEBUFLEN];
+  const char* o_result;
+  get_datetime_string(tms, sizeof(tms));
+  pid = os::current_process_id();
+
+  // test.log
+  jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms);
+  o_result = make_log_name_internal("test.log", NULL, pid, tms);
+  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)");
+  FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+  // test-%t-%p.log
+  jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid);
+  o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms);
+  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)");
+  FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+  // test-%t%p.log
+  jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid);
+  o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms);
+  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)");
+  FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+  // %p%t.log
+  jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms);
+  o_result = make_log_name_internal("%p%t.log", NULL, pid, tms);
+  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)");
+  FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+  // %p-test.log
+  jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid);
+  o_result = make_log_name_internal("%p-test.log", NULL, pid, tms);
+  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)");
+  FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+
+  // %t.log
+  jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms);
+  o_result = make_log_name_internal("%t.log", NULL, pid, tms);
+  assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)");
+  FREE_C_HEAP_ARRAY(char, o_result, mtInternal);
+}
+#endif // PRODUCT
+
 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 +598,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 +658,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 +678,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,66 +805,6 @@
   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);
-  }
-
-  // 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;
-}
-
 void defaultStream::init_log() {
   // %%% Need a MutexLocker?
   const char* log_name = LogFile != NULL ? LogFile : "hotspot.log";
@@ -876,11 +1092,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	Mon Sep 08 12:36:58 2014 -0700
+++ b/src/share/vm/utilities/ostream.hpp	Wed Sep 10 15:38:47 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,20 +228,31 @@
   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
+
 void ostream_init();
 void ostream_init_log();
 void ostream_exit();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java	Wed Sep 10 15:38:47 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/compiler/loopopts/TestLogSum.java	Wed Sep 10 15:38:47 2014 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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
+ * @bug 8046516
+ * @summary Segmentation fault in JVM (easily reproducible)
+ * @run main/othervm -XX:-TieredCompilation -Xbatch TestLogSum
+ * @author jackkamm@gmail.com
+ */
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+public class TestLogSum {
+  public static void main(String[] args) {
+    double sum;
+
+    for (int i = 0; i < 6; i++) {
+        for (int n = 2; n < 30; n++) {
+           for (int j = 1; j <= n; j++) {
+              for (int k = 1; k <= j; k++) {
+                // System.out.println(computeSum(k, j));
+                sum = computeSum(k, j);
+              }
+           }
+        }
+      }
+   }
+
+   private static Map<List<Integer>, Double> cache = new HashMap<List<Integer>, Double>();
+   public static double computeSum(int x, int y) {
+      List<Integer> key = Arrays.asList(new Integer[] {x, y});
+
+      if (!cache.containsKey(key)) {
+
+        // explicitly creating/updating a double[] array, instead of using the LogSumArray wrapper object, will prevent the error
+        LogSumArray toReturn = new LogSumArray(x);
+
+        // changing loop indices will prevent the error
+        // in particular, for(z=0; z<x-1; z++), and then using z+1 in place of z, will not produce error
+        for (int z = 1; z < x+1; z++) {
+           double logSummand = Math.log(z + x + y);
+           toReturn.addLogSummand(logSummand);
+        }
+
+        // returning the value here without cacheing it will prevent the segfault
+        cache.put(key, toReturn.retrieveLogSum());
+      }
+      return cache.get(key);
+   }
+
+   /*
+    * Given a bunch of logarithms log(X),log(Y),log(Z),...
+    * This class is used to compute the log of the sum, log(X+Y+Z+...)
+    */
+   private static class LogSumArray {
+      private double[] logSummandArray;
+      private int currSize;
+
+      private double maxLogSummand;
+
+      public LogSumArray(int maxEntries) {
+        this.logSummandArray = new double[maxEntries];
+
+        this.currSize = 0;
+        this.maxLogSummand = Double.NEGATIVE_INFINITY;
+      }
+
+      public void addLogSummand(double logSummand) {
+        logSummandArray[currSize] = logSummand;
+        currSize++;
+        // removing this line will prevent the error
+        maxLogSummand = Math.max(maxLogSummand, logSummand);
+      }
+
+      public double retrieveLogSum() {
+        if (maxLogSummand == Double.NEGATIVE_INFINITY) return Double.NEGATIVE_INFINITY;
+
+        assert currSize <= logSummandArray.length;
+
+        double factorSum = 0;
+        for (int i = 0; i < currSize; i++) {
+           factorSum += Math.exp(logSummandArray[i] - maxLogSummand);
+        }
+
+        return Math.log(factorSum) + maxLogSummand;
+      }
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/TestPrintGCDetails.java	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/test/runtime/7196045/Test7196045.java	Wed Sep 10 15:38:47 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/Thread/TestThreadDumpMonitorContention.java	Wed Sep 10 15:38:47 2014 -0700
@@ -0,0 +1,534 @@
+/*
+ * 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
+ * @bug     8036823
+ * @bug     8046287
+ * @summary Creates two threads contending for the same lock and checks
+ *      whether jstack reports "locked" by more than one thread.
+ *
+ * @library /testlibrary
+ * @run main/othervm TestThreadDumpMonitorContention
+ */
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.oracle.java.testlibrary.*;
+
+public class TestThreadDumpMonitorContention {
+    // jstack tends to be closely bound to the VM that we are running
+    // so use getTestJDKTool() instead of getCompileJDKTool() or even
+    // getJDKTool() which can fall back to "compile.jdk".
+    final static String JSTACK = JDKToolFinder.getTestJDKTool("jstack");
+    final static String PID = getPid();
+
+    // looking for header lines with these patterns:
+    // "ContendingThread-1" #19 prio=5 os_prio=64 tid=0x000000000079c000 nid=0x23 runnable [0xffff80ffb8b87000]
+    // "ContendingThread-2" #21 prio=5 os_prio=64 tid=0x0000000000780000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000]
+    // "ContendingThread-2" #24 prio=5 os_prio=64 tid=0x0000000000ec8800 nid=0x31 waiting on condition [0xfffffd7bbfffe000]
+    final static Pattern HEADER_PREFIX_PATTERN = Pattern.compile(
+        "^\"ContendingThread-.*");
+    final static Pattern HEADER_WAITING_PATTERN1 = Pattern.compile(
+        "^\"ContendingThread-.* waiting for monitor entry .*");
+    final static Pattern HEADER_WAITING_PATTERN2 = Pattern.compile(
+        "^\"ContendingThread-.* waiting on condition .*");
+    final static Pattern HEADER_RUNNABLE_PATTERN = Pattern.compile(
+        "^\"ContendingThread-.* runnable .*");
+
+    // looking for thread state lines with these patterns:
+    // java.lang.Thread.State: RUNNABLE
+    // java.lang.Thread.State: BLOCKED (on object monitor)
+    final static Pattern THREAD_STATE_PREFIX_PATTERN = Pattern.compile(
+        " *java\\.lang\\.Thread\\.State: .*");
+    final static Pattern THREAD_STATE_BLOCKED_PATTERN = Pattern.compile(
+        " *java\\.lang\\.Thread\\.State: BLOCKED \\(on object monitor\\)");
+    final static Pattern THREAD_STATE_RUNNABLE_PATTERN = Pattern.compile(
+        " *java\\.lang\\.Thread\\.State: RUNNABLE");
+
+    // looking for duplicates of this pattern:
+    // - locked <0x000000076ac59e20> (a TestThreadDumpMonitorContention$1)
+    final static Pattern LOCK_PATTERN = Pattern.compile(
+        ".* locked \\<.*\\(a TestThreadDumpMonitorContention.*");
+
+    // sanity checking header and thread state lines associated
+    // with this pattern:
+    // - waiting to lock <0x000000076ac59e20> (a TestThreadDumpMonitorContention$1)
+    final static Pattern WAITING_PATTERN = Pattern.compile(
+        ".* waiting to lock \\<.*\\(a TestThreadDumpMonitorContention.*");
+
+    final static Object barrier = new Object();
+    volatile static boolean done = false;
+
+    static int barrier_cnt = 0;
+    static int blank_line_match_cnt = 0;
+    static int error_cnt = 0;
+    static boolean have_header_line = false;
+    static boolean have_thread_state_line = false;
+    static String header_line = null;
+    static int header_prefix_match_cnt = 0;
+    static int locked_line_match_cnt = 0;
+    static String[] locked_match_list = new String[2];
+    static int n_samples = 15;
+    static int sum_both_running_cnt = 0;
+    static int sum_both_waiting_cnt = 0;
+    static int sum_contended_cnt = 0;
+    static int sum_locked_hdr_runnable_cnt = 0;
+    static int sum_locked_hdr_waiting1_cnt = 0;
+    static int sum_locked_hdr_waiting2_cnt = 0;
+    static int sum_locked_thr_state_blocked_cnt = 0;
+    static int sum_locked_thr_state_runnable_cnt = 0;
+    static int sum_one_waiting_cnt = 0;
+    static int sum_uncontended_cnt = 0;
+    static int sum_waiting_hdr_waiting1_cnt = 0;
+    static int sum_waiting_thr_state_blocked_cnt = 0;
+    static String thread_state_line = null;
+    static boolean verbose = false;
+    static int waiting_line_match_cnt = 0;
+
+    public static void main(String[] args) throws Exception {
+        if (args.length != 0) {
+            int arg_i = 0;
+            if (args[arg_i].equals("-v")) {
+                verbose = true;
+                arg_i++;
+            }
+
+            try {
+                n_samples = Integer.parseInt(args[arg_i]);
+            } catch (NumberFormatException nfe) {
+                System.err.println(nfe);
+                usage();
+            }
+        }
+
+        Runnable runnable = new Runnable() {
+            public void run() {
+                synchronized (barrier) {
+                    // let the main thread know we're running
+                    barrier_cnt++;
+                    barrier.notify();
+                }
+                while (!done) {
+                    synchronized (this) { }
+                }
+            }
+        };
+        Thread[] thread_list = new Thread[2];
+        thread_list[0] = new Thread(runnable, "ContendingThread-1");
+        thread_list[1] = new Thread(runnable, "ContendingThread-2");
+        synchronized (barrier) {
+            thread_list[0].start();
+            thread_list[1].start();
+
+            // Wait until the contending threads are running so that
+            // we don't sample any thread init states.
+            while (barrier_cnt < 2) {
+                barrier.wait();
+            }
+        }
+
+        doSamples();
+
+        done = true;
+
+        thread_list[0].join();
+        thread_list[1].join();
+
+        if (error_cnt == 0) {
+            System.out.println("Test PASSED.");
+        } else {
+            System.out.println("Test FAILED.");
+            throw new AssertionError("error_cnt=" + error_cnt);
+        }
+    }
+
+    // Reached a blank line which is the end of the
+    // stack trace without matching either LOCK_PATTERN
+    // or WAITING_PATTERN. Rare, but it's not an error.
+    //
+    // Example:
+    // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000]
+    //    java.lang.Thread.State: RUNNABLE
+    //         at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
+    //         at java.lang.Thread.run(Thread.java:745)
+    //
+    static boolean checkBlankLine(String line) {
+        if (line.length() == 0) {
+            blank_line_match_cnt++;
+            have_header_line = false;
+            have_thread_state_line = false;
+            return true;
+        }
+
+        return false;
+    }
+
+    // Process the locked line here if we found one.
+    //
+    // Example 1:
+    // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000]
+    //    java.lang.Thread.State: RUNNABLE
+    //         at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
+    //         - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
+    //         at java.lang.Thread.run(Thread.java:745)
+    //
+    // Example 2:
+    // "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000]
+    //    java.lang.Thread.State: BLOCKED (on object monitor)
+    //         at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
+    //         - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
+    //         at java.lang.Thread.run(Thread.java:745)
+    //
+    // Example 3:
+    // "ContendingThread-2" #24 prio=5 os_prio=64 tid=0x0000000000ec8800 nid=0x31 waiting on condition [0xfffffd7bbfffe000]
+    //    java.lang.Thread.State: RUNNABLE
+    //    JavaThread state: _thread_blocked
+    // Thread: 0x0000000000ec8800  [0x31] State: _at_safepoint _has_called_back 0 _at_poll_safepoint 0
+    //    JavaThread state: _thread_blocked
+    //         at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
+    //         - locked <0xfffffd7e6d03eb28> (a TestThreadDumpMonitorContention$1)
+    //         at java.lang.Thread.run(Thread.java:745)
+    //
+    static boolean checkLockedLine(String line) {
+        Matcher matcher = LOCK_PATTERN.matcher(line);
+        if (matcher.matches()) {
+            if (verbose) {
+                System.out.println("locked_line='" + line + "'");
+            }
+            locked_match_list[locked_line_match_cnt] = new String(line);
+            locked_line_match_cnt++;
+
+            matcher = HEADER_RUNNABLE_PATTERN.matcher(header_line);
+            if (matcher.matches()) {
+                sum_locked_hdr_runnable_cnt++;
+            } else {
+                // It's strange, but a locked line can also
+                // match the HEADER_WAITING_PATTERN{1,2}.
+                matcher = HEADER_WAITING_PATTERN1.matcher(header_line);
+                if (matcher.matches()) {
+                    sum_locked_hdr_waiting1_cnt++;
+                } else {
+                    matcher = HEADER_WAITING_PATTERN2.matcher(header_line);
+                    if (matcher.matches()) {
+                        sum_locked_hdr_waiting2_cnt++;
+                    } else {
+                        System.err.println();
+                        System.err.println("ERROR: header line does " +
+                            "not match runnable or waiting patterns.");
+                        System.err.println("ERROR: header_line='" +
+                            header_line + "'");
+                        System.err.println("ERROR: locked_line='" + line +
+                            "'");
+                        error_cnt++;
+                    }
+                }
+            }
+
+            matcher = THREAD_STATE_RUNNABLE_PATTERN.matcher(thread_state_line);
+            if (matcher.matches()) {
+                sum_locked_thr_state_runnable_cnt++;
+            } else {
+                // It's strange, but a locked line can also
+                // match the THREAD_STATE_BLOCKED_PATTERN.
+                matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(
+                              thread_state_line);
+                if (matcher.matches()) {
+                    sum_locked_thr_state_blocked_cnt++;
+                } else {
+                    System.err.println();
+                    System.err.println("ERROR: thread state line does not " +
+                        "match runnable or waiting patterns.");
+                    System.err.println("ERROR: " + "thread_state_line='" +
+                        thread_state_line + "'");
+                    System.err.println("ERROR: locked_line='" + line + "'");
+                    error_cnt++;
+                }
+            }
+
+            // Have everything we need from this thread stack
+            // that matches the LOCK_PATTERN.
+            have_header_line = false;
+            have_thread_state_line = false;
+            return true;
+        }
+
+        return false;
+    }
+
+    // Process the waiting line here if we found one.
+    //
+    // Example:
+    // "ContendingThread-2" #22 prio=5 os_prio=64 tid=0x00000000007b9800 nid=0x30 waiting for monitor entry [0xfffffd7fc1010000]
+    //    java.lang.Thread.State: BLOCKED (on object monitor)
+    //         at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
+    //         - waiting to lock <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
+    //         at java.lang.Thread.run(Thread.java:745)
+    //
+    static boolean checkWaitingLine(String line) {
+        Matcher matcher = WAITING_PATTERN.matcher(line);
+        if (matcher.matches()) {
+            waiting_line_match_cnt++;
+            if (verbose) {
+                System.out.println("waiting_line='" + line + "'");
+            }
+
+            matcher = HEADER_WAITING_PATTERN1.matcher(header_line);
+            if (matcher.matches()) {
+                sum_waiting_hdr_waiting1_cnt++;
+            } else {
+                System.err.println();
+                System.err.println("ERROR: header line does " +
+                    "not match a waiting pattern.");
+                System.err.println("ERROR: header_line='" + header_line + "'");
+                System.err.println("ERROR: waiting_line='" + line + "'");
+                error_cnt++;
+            }
+
+            matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(thread_state_line);
+            if (matcher.matches()) {
+                sum_waiting_thr_state_blocked_cnt++;
+            } else {
+                System.err.println();
+                System.err.println("ERROR: thread state line " +
+                    "does not match a waiting pattern.");
+                System.err.println("ERROR: thread_state_line='" +
+                    thread_state_line + "'");
+                System.err.println("ERROR: waiting_line='" + line + "'");
+                error_cnt++;
+            }
+
+            // Have everything we need from this thread stack
+            // that matches the WAITING_PATTERN.
+            have_header_line = false;
+            have_thread_state_line = false;
+            return true;
+        }
+
+        return false;
+    }
+
+    static void doSamples() throws Exception {
+        for (int count = 0; count < n_samples; count++) {
+            blank_line_match_cnt = 0;
+            header_prefix_match_cnt = 0;
+            locked_line_match_cnt = 0;
+            waiting_line_match_cnt = 0;
+            // verbose mode or an error has a lot of output so add more space
+            if (verbose || error_cnt > 0) System.out.println();
+            System.out.println("Sample #" + count);
+
+            // We don't use the ProcessTools, OutputBuffer or
+            // OutputAnalyzer classes from the testlibrary because
+            // we have a complicated multi-line parse to perform
+            // on a narrow subset of the JSTACK output.
+            //
+            // - we only care about stack traces that match
+            //   HEADER_PREFIX_PATTERN; only two should match
+            // - we care about at most three lines from each stack trace
+            // - if both stack traces match LOCKED_PATTERN, then that's
+            //   a failure and we report it
+            // - for a stack trace that matches LOCKED_PATTERN, we verify:
+            //   - the header line matches HEADER_RUNNABLE_PATTERN
+            //     or HEADER_WAITING_PATTERN{1,2}
+            //   - the thread state line matches THREAD_STATE_BLOCKED_PATTERN
+            //     or THREAD_STATE_RUNNABLE_PATTERN
+            //   - we report any mismatches as failures
+            // - for a stack trace that matches WAITING_PATTERN, we verify:
+            //   - the header line matches HEADER_WAITING_PATTERN1
+            //   - the thread state line matches THREAD_STATE_BLOCKED_PATTERN
+            //   - we report any mismatches as failures
+            // - the stack traces that match HEADER_PREFIX_PATTERN may
+            //   not match either LOCKED_PATTERN or WAITING_PATTERN
+            //   because we might observe the thread outside of
+            //   monitor operations; this is not considered a failure
+            //
+            // When we do observe LOCKED_PATTERN or WAITING_PATTERN,
+            // then we are checking the header and thread state patterns
+            // that occurred earlier in the current stack trace that
+            // matched HEADER_PREFIX_PATTERN. We don't use data from
+            // stack traces that don't match HEADER_PREFIX_PATTERN and
+            // we don't mix data between the two stack traces that do
+            // match HEADER_PREFIX_PATTERN.
+            //
+            Process process = new ProcessBuilder(JSTACK, PID)
+                .redirectErrorStream(true).start();
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(
+                                        process.getInputStream()));
+            String line;
+            while ((line = reader.readLine()) != null) {
+                Matcher matcher = null;
+
+                // process the header line here
+                if (!have_header_line) {
+                    matcher = HEADER_PREFIX_PATTERN.matcher(line);
+                    if (matcher.matches()) {
+                        header_prefix_match_cnt++;
+                        if (verbose) {
+                            System.out.println();
+                            System.out.println("header='" + line + "'");
+                        }
+                        header_line = new String(line);
+                        have_header_line = true;
+                        continue;
+                    }
+                    continue;  // skip until have a header line
+                }
+
+                // process the thread state line here
+                if (!have_thread_state_line) {
+                    matcher = THREAD_STATE_PREFIX_PATTERN.matcher(line);
+                    if (matcher.matches()) {
+                        if (verbose) {
+                            System.out.println("thread_state='" + line + "'");
+                        }
+                        thread_state_line = new String(line);
+                        have_thread_state_line = true;
+                        continue;
+                    }
+                    continue;  // skip until we have a thread state line
+                }
+
+                // process the locked line here if we find one
+                if (checkLockedLine(line)) {
+                    continue;
+                }
+
+                // process the waiting line here if we find one
+                if (checkWaitingLine(line)) {
+                    continue;
+                }
+
+                // process the blank line here if we find one
+                if (checkBlankLine(line)) {
+                    continue;
+                }
+            }
+            process.waitFor();
+
+            if (header_prefix_match_cnt != 2) {
+                System.err.println();
+                System.err.println("ERROR: should match exactly two headers.");
+                System.err.println("ERROR: header_prefix_match_cnt=" +
+                    header_prefix_match_cnt);
+                error_cnt++;
+            }
+
+            if (locked_line_match_cnt == 2) {
+                if (locked_match_list[0].equals(locked_match_list[1])) {
+                    System.err.println();
+                    System.err.println("ERROR: matching lock lines:");
+                    System.err.println("ERROR: line[0]'" +
+                        locked_match_list[0] + "'");
+                    System.err.println("ERROR: line[1]'" +
+                        locked_match_list[1] + "'");
+                    error_cnt++;
+                }
+            }
+
+            if (locked_line_match_cnt == 1) {
+                // one thread has the lock
+                if (waiting_line_match_cnt == 1) {
+                    // and the other contended for it
+                    sum_contended_cnt++;
+                } else {
+                    // and the other is just running
+                    sum_uncontended_cnt++;
+                }
+            } else if (waiting_line_match_cnt == 1) {
+                // one thread is waiting
+                sum_one_waiting_cnt++;
+            } else if (waiting_line_match_cnt == 2) {
+                // both threads are waiting
+                sum_both_waiting_cnt++;
+            } else {
+                // both threads are running
+                sum_both_running_cnt++;
+            }
+
+            // slight delay between jstack launches
+            Thread.sleep(500);
+        }
+
+        if (error_cnt != 0) {
+            // skip summary info since there were errors
+            return;
+        }
+
+        System.out.println("INFO: Summary for all samples:");
+        System.out.println("INFO: both_running_cnt=" + sum_both_running_cnt);
+        System.out.println("INFO: both_waiting_cnt=" + sum_both_waiting_cnt);
+        System.out.println("INFO: contended_cnt=" + sum_contended_cnt);
+        System.out.println("INFO: one_waiting_cnt=" + sum_one_waiting_cnt);
+        System.out.println("INFO: uncontended_cnt=" + sum_uncontended_cnt);
+        System.out.println("INFO: locked_hdr_runnable_cnt=" +
+            sum_locked_hdr_runnable_cnt);
+        System.out.println("INFO: locked_hdr_waiting1_cnt=" +
+            sum_locked_hdr_waiting1_cnt);
+        System.out.println("INFO: locked_hdr_waiting2_cnt=" +
+            sum_locked_hdr_waiting2_cnt);
+        System.out.println("INFO: locked_thr_state_blocked_cnt=" +
+            sum_locked_thr_state_blocked_cnt);
+        System.out.println("INFO: locked_thr_state_runnable_cnt=" +
+            sum_locked_thr_state_runnable_cnt);
+        System.out.println("INFO: waiting_hdr_waiting1_cnt=" +
+            sum_waiting_hdr_waiting1_cnt);
+        System.out.println("INFO: waiting_thr_state_blocked_cnt=" +
+            sum_waiting_thr_state_blocked_cnt);
+
+        if (sum_contended_cnt == 0) {
+            System.err.println("WARNING: the primary scenario for 8036823" +
+                " has not been exercised by this test run.");
+        }
+    }
+
+    // This helper relies on RuntimeMXBean.getName() returning a string
+    // that looks like this: 5436@mt-haku
+    //
+    // The testlibrary has tryFindJvmPid(), but that uses a separate
+    // process which is much more expensive for finding out your own PID.
+    //
+    static String getPid() {
+        RuntimeMXBean runtimebean = ManagementFactory.getRuntimeMXBean();
+        String vmname = runtimebean.getName();
+        int i = vmname.indexOf('@');
+        if (i != -1) {
+            vmname = vmname.substring(0, i);
+        }
+        return vmname;
+    }
+
+    static void usage() {
+        System.err.println("Usage: " +
+            "java TestThreadDumpMonitorContention [-v] [n_samples]");
+        System.exit(1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/XCheckJniJsig/XCheckJSig.java	Wed Sep 10 15:38:47 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	Wed Sep 10 15:38:47 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	Wed Sep 10 15:38:47 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	Wed Sep 10 15:38:47 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	Mon Sep 08 12:36:58 2014 -0700
+++ b/test/serviceability/sa/jmap-hashcode/Test8028623.java	Wed Sep 10 15:38:47 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;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary_tests/AssertsTest.java	Wed Sep 10 15:38:47 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	Wed Sep 10 15:38:47 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	Wed Sep 10 15:38:47 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);
+      }
+    }
+  }
+}