changeset 12141:a46f84e4a4d2

Merge
author dlong
date Mon, 03 Oct 2016 12:35:51 -0400
parents ea0313bad050 a575b5865683
children b2b2ec149a24
files src/share/vm/utilities/chunkedList.cpp test/runtime/SharedArchiveFile/SASymbolTableTestAttachee.java
diffstat 36 files changed, 555 insertions(+), 453 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Sep 28 11:17:51 2016 +0200
+++ b/.hgtags	Mon Oct 03 12:35:51 2016 -0400
@@ -539,3 +539,5 @@
 b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134
 3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135
 a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136
+dfcbf839e299e7e2bba1da69bdb347617ea4c7e8 jdk-9+137
+fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138
--- a/src/cpu/ppc/vm/assembler_ppc.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/cpu/ppc/vm/assembler_ppc.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -1575,6 +1575,9 @@
   inline void stdu( Register d, int si16,    Register s1);
   inline void stdux(Register s, Register a,  Register b);
 
+  inline void st_ptr(Register d, int si16,    Register s1);
+  DEBUG_ONLY(inline void st_ptr(Register d, ByteSize b, Register s1);)
+
   // PPC 1, section 3.3.13 Move To/From System Register Instructions
   inline void mtlr( Register s1);
   inline void mflr( Register d);
--- a/src/cpu/ppc/vm/assembler_ppc.inline.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/cpu/ppc/vm/assembler_ppc.inline.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -349,6 +349,9 @@
 inline void Assembler::stdu( Register d, int si16,    Register s1) { emit_int32(STDU_OPCODE | rs(d) | ds(si16)   | rta0mem(s1));}
 inline void Assembler::stdux(Register s, Register a,  Register b)  { emit_int32(STDUX_OPCODE| rs(s) | rta0mem(a) | rb(b));}
 
+inline void Assembler::st_ptr(Register d, int b, Register s1) { std(d, b, s1); }
+DEBUG_ONLY(inline void Assembler::st_ptr(Register d, ByteSize b, Register s1) { std(d, in_bytes(b), s1); })
+
 // PPC 1, section 3.3.13 Move To/From System Register Instructions
 inline void Assembler::mtlr( Register s1)         { emit_int32(MTLR_OPCODE  | rs(s1)); }
 inline void Assembler::mflr( Register d )         { emit_int32(MFLR_OPCODE  | rt(d)); }
--- a/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -261,6 +261,9 @@
 }
 
 void InterpreterMacroAssembler::push_l(Register r) {
+  // Clear unused slot.
+  load_const_optimized(R0, 0L);
+  std(R0, 0, R15_esp);
   std(r, - Interpreter::stackElementSize, R15_esp);
   addi(R15_esp, R15_esp, - 2 * Interpreter::stackElementSize );
 }
--- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -2489,6 +2489,11 @@
     __ verify_oop(R3_RET);
   }
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ load_const_optimized(R0, 0L);
+    __ st_ptr(R0, JavaThread::pending_jni_exception_check_fn_offset(), R16_thread);
+  }
 
   // Reset handle block.
   // --------------------------------------------------------------------------
--- a/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -1544,6 +1544,12 @@
     __ fence();
   }
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ load_const_optimized(R0, 0L);
+    __ st_ptr(R0, JavaThread::pending_jni_exception_check_fn_offset(), R16_thread);
+  }
+
   __ reset_last_Java_frame();
 
   // Jvmdi/jvmpi support. Whether we've got an exception pending or
--- a/src/os/windows/vm/os_windows.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/os/windows/vm/os_windows.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -2366,7 +2366,9 @@
   if (Interpreter::contains(pc)) {
     *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
     if (!fr->is_first_java_frame()) {
-      assert(fr->safe_for_sender(thread), "Safety check");
+      // get_frame_at_stack_banging_point() is only called when we
+      // have well defined stacks so java_sender() calls do not need
+      // to assert safe_for_sender() first.
       *fr = fr->java_sender();
     }
   } else {
@@ -2383,7 +2385,7 @@
       // has been pushed on the stack
       *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp()));
       if (!fr->is_java_frame()) {
-        assert(fr->safe_for_sender(thread), "Safety check");
+        // See java_sender() comment above.
         *fr = fr->java_sender();
       }
     }
--- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -378,7 +378,9 @@
     // method returns the Java sender of the current frame.
     *fr = os::fetch_frame_from_ucontext(thread, uc);
     if (!fr->is_first_java_frame()) {
-      assert(fr->safe_for_sender(thread), "Safety check");
+      // get_frame_at_stack_banging_point() is only called when we
+      // have well defined stacks so java_sender() calls do not need
+      // to assert safe_for_sender() first.
       *fr = fr->java_sender();
     }
   } else {
@@ -395,7 +397,7 @@
       // has been pushed on the stack
       *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp()));
       if (!fr->is_java_frame()) {
-        assert(fr->safe_for_sender(thread), "Safety check");
+        // See java_sender() comment above.
         *fr = fr->java_sender();
       }
     }
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -191,7 +191,9 @@
     // method returns the Java sender of the current frame.
     *fr = os::fetch_frame_from_ucontext(thread, uc);
     if (!fr->is_first_java_frame()) {
-      assert(fr->safe_for_sender(thread), "Safety check");
+      // get_frame_at_stack_banging_point() is only called when we
+      // have well defined stacks so java_sender() calls do not need
+      // to assert safe_for_sender() first.
       *fr = fr->java_sender();
     }
   } else {
@@ -209,8 +211,8 @@
       intptr_t* sp = os::Linux::ucontext_get_sp(uc);
       *fr = frame(sp + 1, fp, (address)*sp);
       if (!fr->is_java_frame()) {
-        assert(fr->safe_for_sender(thread), "Safety check");
         assert(!fr->is_first_frame(), "Safety check");
+        // See java_sender() comment above.
         *fr = fr->java_sender();
       }
     }
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -255,7 +255,9 @@
     // method returns the Java sender of the current frame.
     *fr = os::fetch_frame_from_ucontext(thread, uc);
     if (!fr->is_first_java_frame()) {
-      assert(fr->safe_for_sender(thread), "Safety check");
+      // get_frame_at_stack_banging_point() is only called when we
+      // have well defined stacks so java_sender() calls do not need
+      // to assert safe_for_sender() first.
       *fr = fr->java_sender();
     }
   } else {
@@ -273,7 +275,7 @@
       intptr_t* sp = os::Solaris::ucontext_get_sp(uc);
       *fr = frame(sp + 1, fp, (address)*sp);
       if (!fr->is_java_frame()) {
-        assert(fr->safe_for_sender(thread), "Safety check");
+        // See java_sender() comment above.
         *fr = fr->java_sender();
       }
     }
--- a/src/share/vm/classfile/classLoader.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/classfile/classLoader.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -81,7 +81,6 @@
 typedef void (JNICALL *ZipClose_t)(jzfile *zip);
 typedef jzentry* (JNICALL *FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen);
 typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
-typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
 typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
 typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
 typedef jint     (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
@@ -91,7 +90,6 @@
 static ZipClose_t        ZipClose           = NULL;
 static FindEntry_t       FindEntry          = NULL;
 static ReadEntry_t       ReadEntry          = NULL;
-static ReadMappedEntry_t ReadMappedEntry    = NULL;
 static GetNextEntry_t    GetNextEntry       = NULL;
 static canonicalize_fn_t CanonicalizeEntry  = NULL;
 static ZipInflateFully_t ZipInflateFully    = NULL;
@@ -353,15 +351,10 @@
     filename = NEW_RESOURCE_ARRAY(char, name_len + 1);
   }
 
-  // file found, get pointer to the entry in mmapped jar file.
-  if (ReadMappedEntry == NULL ||
-      !(*ReadMappedEntry)(_zip, entry, &buffer, filename)) {
-      // mmapped access not available, perhaps due to compression,
-      // read contents into resource array
-      int size = (*filesize) + ((nul_terminate) ? 1 : 0);
-      buffer = NEW_RESOURCE_ARRAY(u1, size);
-      if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
-  }
+  // read contents into resource array
+  int size = (*filesize) + ((nul_terminate) ? 1 : 0);
+  buffer = NEW_RESOURCE_ARRAY(u1, size);
+  if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
 
   // return result
   if (nul_terminate) {
@@ -1079,7 +1072,6 @@
   ZipClose     = CAST_TO_FN_PTR(ZipClose_t, os::dll_lookup(handle, "ZIP_Close"));
   FindEntry    = CAST_TO_FN_PTR(FindEntry_t, os::dll_lookup(handle, "ZIP_FindEntry"));
   ReadEntry    = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry"));
-  ReadMappedEntry = CAST_TO_FN_PTR(ReadMappedEntry_t, os::dll_lookup(handle, "ZIP_ReadMappedEntry"));
   GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry"));
   ZipInflateFully = CAST_TO_FN_PTR(ZipInflateFully_t, os::dll_lookup(handle, "ZIP_InflateFully"));
   Crc32        = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32"));
--- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -540,7 +540,7 @@
 
   // Overflow list of grey objects, threaded through mark-word
   // Manipulated with CAS in the parallel/multi-threaded case.
-  oop _overflow_list;
+  oopDesc* volatile _overflow_list;
   // The following array-pair keeps track of mark words
   // displaced for accommodating overflow list above.
   // This code will likely be revisited under RFE#4922830.
--- a/src/share/vm/gc/cms/parNewGeneration.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/cms/parNewGeneration.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -323,7 +323,7 @@
   // A list of from-space images of to-be-scanned objects, threaded through
   // klass-pointers (klass information already copied to the forwarded
   // image.)  Manipulated with CAS.
-  oop _overflow_list;
+  oopDesc* volatile _overflow_list;
   NOT_PRODUCT(ssize_t _num_par_pushes;)
 
   // This closure is used by the reference processor to filter out
--- a/src/share/vm/gc/g1/g1IHOPControl.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/g1/g1IHOPControl.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -81,47 +81,6 @@
   _last_marking_length_s(0.0) {
 }
 
-#ifndef PRODUCT
-static void test_update(G1IHOPControl* ctrl, double alloc_time, size_t alloc_amount, size_t young_size, double mark_time) {
-  for (int i = 0; i < 100; i++) {
-    ctrl->update_allocation_info(alloc_time, alloc_amount, young_size);
-    ctrl->update_marking_length(mark_time);
-  }
-}
-
-void G1StaticIHOPControl::test() {
-  size_t const initial_ihop = 45;
-
-  G1StaticIHOPControl ctrl(initial_ihop);
-  ctrl.update_target_occupancy(100);
-
-  size_t threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold == initial_ihop,
-         "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
-
-  ctrl.update_allocation_info(100.0, 100, 100);
-  threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold == initial_ihop,
-         "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
-
-  ctrl.update_marking_length(1000.0);
-  threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold == initial_ihop,
-         "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
-
-  // Whatever we pass, the IHOP value must stay the same.
-  test_update(&ctrl, 2, 10, 10, 3);
-  threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold == initial_ihop,
-         "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
-
-  test_update(&ctrl, 12, 10, 10, 3);
-  threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold == initial_ihop,
-         "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_ihop, threshold);
-}
-#endif
-
 G1AdaptiveIHOPControl::G1AdaptiveIHOPControl(double ihop_percent,
                                              G1Predictions const* predictor,
                                              size_t heap_reserve_percent,
@@ -224,79 +183,3 @@
                                           _predictor->get_new_prediction(&_marking_times_s),
                                           have_enough_data_for_prediction());
 }
-
-#ifndef PRODUCT
-void G1AdaptiveIHOPControl::test() {
-  size_t const initial_threshold = 45;
-  size_t const young_size = 10;
-  size_t const target_size = 100;
-
-  // The final IHOP value is always
-  // target_size - (young_size + alloc_amount/alloc_time * marking_time)
-
-  G1Predictions pred(0.95);
-  G1AdaptiveIHOPControl ctrl(initial_threshold, &pred, 0, 0);
-  ctrl.update_target_occupancy(target_size);
-
-  // First "load".
-  size_t const alloc_time1 = 2;
-  size_t const alloc_amount1 = 10;
-  size_t const marking_time1 = 2;
-  size_t const settled_ihop1 = target_size - (young_size + alloc_amount1/alloc_time1 * marking_time1);
-
-  size_t threshold;
-  threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold == initial_threshold,
-         "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_threshold, threshold);
-  for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) {
-    ctrl.update_allocation_info(alloc_time1, alloc_amount1, young_size);
-    ctrl.update_marking_length(marking_time1);
-    // Not enough data yet.
-    threshold = ctrl.get_conc_mark_start_threshold();
-    assert(threshold == initial_threshold,
-           "Expected IHOP threshold of " SIZE_FORMAT " but is " SIZE_FORMAT, initial_threshold, threshold);
-  }
-
-  test_update(&ctrl, alloc_time1, alloc_amount1, young_size, marking_time1);
-
-  threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold == settled_ihop1,
-         "Expected IHOP threshold to settle at " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop1, threshold);
-
-  // Second "load". A bit higher allocation rate.
-  size_t const alloc_time2 = 2;
-  size_t const alloc_amount2 = 30;
-  size_t const marking_time2 = 2;
-  size_t const settled_ihop2 = target_size - (young_size + alloc_amount2/alloc_time2 * marking_time2);
-
-  test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2);
-
-  threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold < settled_ihop1,
-         "Expected IHOP threshold to settle at a value lower than " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop1, threshold);
-
-  // Third "load". Very high (impossible) allocation rate.
-  size_t const alloc_time3 = 1;
-  size_t const alloc_amount3 = 50;
-  size_t const marking_time3 = 2;
-  size_t const settled_ihop3 = 0;
-
-  test_update(&ctrl, alloc_time3, alloc_amount3, young_size, marking_time3);
-  threshold = ctrl.get_conc_mark_start_threshold();
-
-  assert(threshold == settled_ihop3,
-         "Expected IHOP threshold to settle at " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop3, threshold);
-
-  // And back to some arbitrary value.
-  test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2);
-
-  threshold = ctrl.get_conc_mark_start_threshold();
-  assert(threshold > settled_ihop3,
-         "Expected IHOP threshold to settle at value larger than " SIZE_FORMAT " but is " SIZE_FORMAT, settled_ihop3, threshold);
-}
-
-void IHOP_test() {
-  G1StaticIHOPControl::test();
-  G1AdaptiveIHOPControl::test();
-}
-#endif
--- a/src/share/vm/gc/g1/g1IHOPControl.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/g1/g1IHOPControl.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -99,10 +99,6 @@
    assert(marking_length_s > 0.0, "Marking length must be larger than zero but is %.3f", marking_length_s);
     _last_marking_length_s = marking_length_s;
   }
-
-#ifndef PRODUCT
-  static void test();
-#endif
 };
 
 // This algorithm tries to return a concurrent mark starting occupancy value that
@@ -148,9 +144,6 @@
 
   virtual void print();
   virtual void send_trace_event(G1NewTracer* tracer);
-#ifndef PRODUCT
-  static void test();
-#endif
 };
 
 #endif // SHARE_VM_GC_G1_G1IHOPCONTROL_HPP
--- a/src/share/vm/gc/g1/g1RemSet.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/g1/g1RemSet.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -668,20 +668,18 @@
   // fail arbitrarily). We tell the iteration code to perform this
   // filtering when it has been determined that there has been an actual
   // allocation in this region and making it safe to check the young type.
-  bool filter_young = true;
 
-  HeapWord* stop_point =
+  bool card_processed =
     r->oops_on_card_seq_iterate_careful(dirtyRegion,
                                         &filter_then_update_rs_oop_cl,
-                                        filter_young,
                                         card_ptr);
 
-  // If stop_point is non-null, then we encountered an unallocated region
-  // (perhaps the unfilled portion of a TLAB.)  For now, we'll dirty the
-  // card and re-enqueue: if we put off the card until a GC pause, then the
-  // unallocated portion will be filled in.  Alternatively, we might try
-  // the full complexity of the technique used in "regular" precleaning.
-  if (stop_point != NULL) {
+  // If unable to process the card then we encountered an unparsable
+  // part of the heap (e.g. a partially allocated object).  Redirty
+  // and re-enqueue: if we put off the card until a GC pause, then the
+  // allocation will have completed.
+  if (!card_processed) {
+    assert(!_g1->is_gc_active(), "Unparsable heap during GC");
     // The card might have gotten re-dirtied and re-enqueued while we
     // worked.  (In fact, it's pretty likely.)
     if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
--- a/src/share/vm/gc/g1/heapRegion.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/g1/heapRegion.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -352,19 +352,10 @@
   _prev_marked_bytes = marked_bytes;
 }
 
-HeapWord*
-HeapRegion::
-oops_on_card_seq_iterate_careful(MemRegion mr,
-                                 FilterOutOfRegionClosure* cl,
-                                 bool filter_young,
-                                 jbyte* card_ptr) {
-  // Currently, we should only have to clean the card if filter_young
-  // is true and vice versa.
-  if (filter_young) {
-    assert(card_ptr != NULL, "pre-condition");
-  } else {
-    assert(card_ptr == NULL, "pre-condition");
-  }
+bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr,
+                                                  FilterOutOfRegionClosure* cl,
+                                                  jbyte* card_ptr) {
+  assert(card_ptr != NULL, "pre-condition");
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   // If we're within a stop-world GC, then we might look at a card in a
@@ -375,7 +366,9 @@
   } else {
     mr = mr.intersection(used_region());
   }
-  if (mr.is_empty()) return NULL;
+  if (mr.is_empty()) {
+    return true;
+  }
   // Otherwise, find the obj that extends onto mr.start().
 
   // The intersection of the incoming mr (for the card) and the
@@ -384,27 +377,21 @@
   // G1CollectedHeap.cpp that allocates a new region sets the
   // is_young tag on the region before allocating. Thus we
   // safely know if this region is young.
-  if (is_young() && filter_young) {
-    return NULL;
+  if (is_young()) {
+    return true;
   }
 
-  assert(!is_young(), "check value of filter_young");
-
   // We can only clean the card here, after we make the decision that
-  // the card is not young. And we only clean the card if we have been
-  // asked to (i.e., card_ptr != NULL).
-  if (card_ptr != NULL) {
-    *card_ptr = CardTableModRefBS::clean_card_val();
-    // We must complete this write before we do any of the reads below.
-    OrderAccess::storeload();
-  }
+  // the card is not young.
+  *card_ptr = CardTableModRefBS::clean_card_val();
+  // We must complete this write before we do any of the reads below.
+  OrderAccess::storeload();
 
   // Cache the boundaries of the memory region in some const locals
   HeapWord* const start = mr.start();
   HeapWord* const end = mr.end();
 
-  // We used to use "block_start_careful" here.  But we're actually happy
-  // to update the BOT while we do this...
+  // Update BOT as needed while finding start of (potential) object.
   HeapWord* cur = block_start(start);
   assert(cur <= start, "Postcondition");
 
@@ -416,7 +403,9 @@
     obj = oop(cur);
     if (obj->klass_or_null() == NULL) {
       // Ran into an unparseable point.
-      return cur;
+      assert(!g1h->is_gc_active(),
+             "Unparsable heap during GC at " PTR_FORMAT, p2i(cur));
+      return false;
     }
     // Otherwise...
     next = cur + block_size(cur);
@@ -433,7 +422,9 @@
     assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant");
     if (obj->klass_or_null() == NULL) {
       // Ran into an unparseable point.
-      return cur;
+      assert(!g1h->is_gc_active(),
+             "Unparsable heap during GC at " PTR_FORMAT, p2i(cur));
+      return false;
     }
 
     // Advance the current pointer. "obj" still points to the object to iterate.
@@ -452,7 +443,7 @@
     }
   } while (cur < end);
 
-  return NULL;
+  return true;
 }
 
 // Code roots support
--- a/src/share/vm/gc/g1/heapRegion.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/g1/heapRegion.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -653,16 +653,17 @@
     }
   }
 
-  // filter_young: if true and the region is a young region then we
-  // skip the iteration.
-  // card_ptr: if not NULL, and we decide that the card is not young
-  // and we iterate over it, we'll clean the card before we start the
-  // iteration.
-  HeapWord*
-  oops_on_card_seq_iterate_careful(MemRegion mr,
-                                   FilterOutOfRegionClosure* cl,
-                                   bool filter_young,
-                                   jbyte* card_ptr);
+  // Iterate over the card in the card designated by card_ptr,
+  // applying cl to all references in the region.
+  // mr: the memory region covered by the card.
+  // card_ptr: if we decide that the card is not young and we iterate
+  // over it, we'll clean the card before we start the iteration.
+  // Returns true if card was successfully processed, false if an
+  // unparsable part of the heap was encountered, which should only
+  // happen when invoked concurrently with the mutator.
+  bool oops_on_card_seq_iterate_careful(MemRegion mr,
+                                        FilterOutOfRegionClosure* cl,
+                                        jbyte* card_ptr);
 
   size_t recorded_rs_length() const        { return _recorded_rs_length; }
   double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; }
--- a/src/share/vm/gc/g1/heapRegionManager.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/g1/heapRegionManager.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -482,8 +482,9 @@
 HeapRegionClaimer::HeapRegionClaimer(uint n_workers) :
     _n_workers(n_workers), _n_regions(G1CollectedHeap::heap()->_hrm._allocated_heapregions_length), _claims(NULL) {
   assert(n_workers > 0, "Need at least one worker.");
-  _claims = NEW_C_HEAP_ARRAY(uint, _n_regions, mtGC);
-  memset(_claims, Unclaimed, sizeof(*_claims) * _n_regions);
+  uint* new_claims = NEW_C_HEAP_ARRAY(uint, _n_regions, mtGC);
+  memset(new_claims, Unclaimed, sizeof(*_claims) * _n_regions);
+  _claims = new_claims;
 }
 
 HeapRegionClaimer::~HeapRegionClaimer() {
--- a/src/share/vm/gc/g1/heapRegionManager.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/gc/g1/heapRegionManager.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -259,9 +259,9 @@
 // The HeapRegionClaimer is used during parallel iteration over heap regions,
 // allowing workers to claim heap regions, gaining exclusive rights to these regions.
 class HeapRegionClaimer : public StackObj {
-  uint  _n_workers;
-  uint  _n_regions;
-  uint* _claims;
+  uint           _n_workers;
+  uint           _n_regions;
+  volatile uint* _claims;
 
   static const uint Unclaimed = 0;
   static const uint Claimed   = 1;
@@ -285,4 +285,3 @@
   bool claim_region(uint region_index);
 };
 #endif // SHARE_VM_GC_G1_HEAPREGIONMANAGER_HPP
-
--- a/src/share/vm/logging/logFileOutput.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/logging/logFileOutput.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -97,11 +97,7 @@
   if (ret != 0) {
     return false;
   }
-#ifdef _WINDOWS
-  return (st.st_mode & S_IFMT) == _S_IFREG;
-#else
-  return S_ISREG(st.st_mode);
-#endif
+  return (st.st_mode & S_IFMT) == S_IFREG;
 }
 
 // Try to find the next number that should be used for file rotation.
--- a/src/share/vm/logging/logTag.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/logging/logTag.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -105,6 +105,7 @@
   LOG_TAG(scavenge) \
   LOG_TAG(scrub) \
   LOG_TAG(stacktrace) \
+  LOG_TAG(stackwalk) \
   LOG_TAG(start) \
   LOG_TAG(startuptime) \
   LOG_TAG(state) \
--- a/src/share/vm/memory/filemap.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/memory/filemap.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -263,7 +263,7 @@
         } else {
           struct stat st;
           if (os::stat(name, &st) == 0) {
-            if ((st.st_mode & S_IFDIR) == S_IFDIR) {
+            if ((st.st_mode & S_IFMT) == S_IFDIR) {
               if (!os::dir_is_empty(name)) {
                 ClassLoader::exit_with_path_failure(
                   "Cannot have non-empty directory in archived classpaths", name);
--- a/src/share/vm/oops/oop.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/oops/oop.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -83,6 +83,7 @@
 
   inline Klass* klass() const;
   inline Klass* klass_or_null() const volatile;
+  inline Klass* klass_or_null_acquire() const volatile;
   inline Klass** klass_addr();
   inline narrowKlass* compressed_klass_addr();
 
--- a/src/share/vm/oops/oop.inline.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/oops/oop.inline.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -109,7 +109,6 @@
 }
 
 Klass* oopDesc::klass_or_null() const volatile {
-  // can be NULL in CMS
   if (UseCompressedClassPointers) {
     return Klass::decode_klass(_metadata._compressed_klass);
   } else {
@@ -117,6 +116,17 @@
   }
 }
 
+Klass* oopDesc::klass_or_null_acquire() const volatile {
+  if (UseCompressedClassPointers) {
+    // Workaround for non-const load_acquire parameter.
+    const volatile narrowKlass* addr = &_metadata._compressed_klass;
+    volatile narrowKlass* xaddr = const_cast<volatile narrowKlass*>(addr);
+    return Klass::decode_klass(OrderAccess::load_acquire(xaddr));
+  } else {
+    return (Klass*)OrderAccess::load_ptr_acquire(&_metadata._klass);
+  }
+}
+
 Klass** oopDesc::klass_addr() {
   // Only used internally and with CMS and will not work with
   // UseCompressedOops
--- a/src/share/vm/prims/stackwalk.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/prims/stackwalk.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -26,6 +26,7 @@
 #include "classfile/javaClasses.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "logging/log.hpp"
 #include "memory/oopFactory.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
@@ -105,10 +106,8 @@
                               int max_nframes, int start_index,
                               objArrayHandle  frames_array,
                               int& end_index, TRAPS) {
-  if (TraceStackWalk) {
-    tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
-                  max_nframes, start_index, frames_array->length());
-  }
+  log_debug(stackwalk)("fill_in_frames limit=%d start=%d frames length=%d",
+                       max_nframes, start_index, frames_array->length());
   assert(max_nframes > 0, "invalid max_nframes");
   assert(start_index + max_nframes <= frames_array->length(), "oob");
 
@@ -122,18 +121,24 @@
     // not set) and when StackWalker::getCallerClass is called
     if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) {
       if (method->is_hidden()) {
-        if (TraceStackWalk) {
-          tty->print("  hidden method: "); method->print_short_name();
-          tty->print("\n");
+        if (log_is_enabled(Debug, stackwalk)) {
+          ResourceMark rm(THREAD);
+          outputStream* st = Log(stackwalk)::debug_stream();
+          st->print("  hidden method: ");
+          method->print_short_name(st);
+          st->cr();
         }
         continue;
       }
     }
 
     int index = end_index++;
-    if (TraceStackWalk) {
-      tty->print("  %d: frame method: ", index); method->print_short_name();
-      tty->print_cr(" bci=%d", stream.bci());
+    if (log_is_enabled(Debug, stackwalk)) {
+      ResourceMark rm(THREAD);
+      outputStream* st = Log(stackwalk)::debug_stream();
+      st->print("  %d: frame method: ", index);
+      method->print_short_name(st);
+      st->print_cr(" bci=%d", stream.bci());
     }
 
     if (!need_method_info(mode) && get_caller_class(mode) &&
@@ -317,10 +322,8 @@
                     TRAPS) {
   ResourceMark rm(THREAD);
   JavaThread* jt = (JavaThread*)THREAD;
-  if (TraceStackWalk) {
-    tty->print_cr("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
-                  mode, skip_frames, frame_count);
-  }
+  log_debug(stackwalk)("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
+                       mode, skip_frames, frame_count);
 
   if (frames_array.is_null()) {
     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
@@ -355,8 +358,12 @@
         break;
       }
 
-      if (TraceStackWalk) {
-        tty->print("  skip "); stream.method()->print_short_name(); tty->print("\n");
+      if (log_is_enabled(Debug, stackwalk)) {
+        ResourceMark rm(THREAD);
+        outputStream* st = Log(stackwalk)::debug_stream();
+        st->print("  skip ");
+        stream.method()->print_short_name(st);
+        st->cr();
       }
       stream.next();
     }
@@ -364,8 +371,12 @@
     // stack frame has been traversed individually and resume stack walk
     // from the stack frame at depth == skip_frames.
     for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) {
-      if (TraceStackWalk) {
-        tty->print("  skip "); stream.method()->print_short_name(); tty->cr();
+      if (log_is_enabled(Debug, stackwalk)) {
+        ResourceMark rm(THREAD);
+        outputStream* st = Log(stackwalk)::debug_stream();
+        st->print("  skip ");
+        stream.method()->print_short_name(st);
+        st->cr();
       }
     }
   }
@@ -438,10 +449,9 @@
     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
   }
 
-  if (TraceStackWalk) {
-    tty->print_cr("StackWalk::fetchNextBatch frame_count %d existing_stream " PTR_FORMAT " start %d frames %d",
-                  frame_count, p2i(existing_stream), start_index, frames_array->length());
-  }
+  log_debug(stackwalk)("StackWalk::fetchNextBatch frame_count %d existing_stream "
+                       PTR_FORMAT " start %d frames %d",
+                       frame_count, p2i(existing_stream), start_index, frames_array->length());
   int end_index = start_index;
   if (frame_count <= 0) {
     return end_index;        // No operation.
--- a/src/share/vm/runtime/globals.hpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/runtime/globals.hpp	Mon Oct 03 12:35:51 2016 -0400
@@ -2887,9 +2887,6 @@
           "exceptions (0 means all)")                                       \
           range(0, max_jint/2)                                              \
                                                                             \
-  develop(bool, TraceStackWalk, false,                                      \
-          "Trace stack walking")                                            \
-                                                                            \
   /* notice: the max range value here is max_jint, not max_intx  */         \
   /* because of overflow issue                                   */         \
   diagnostic(intx, GuaranteedSafepointInterval, 1000,                       \
--- a/src/share/vm/utilities/chunkedList.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "utilities/chunkedList.hpp"
-#include "utilities/debug.hpp"
-
-/////////////// Unit tests ///////////////
-
-#ifndef PRODUCT
-
-template <typename T>
-class TestChunkedList {
-  typedef ChunkedList<T, mtOther> ChunkedListT;
-
- public:
-  static void testEmpty() {
-    ChunkedListT buffer;
-    assert(buffer.size() == 0, "assert");
-  }
-
-  static void testFull() {
-    ChunkedListT buffer;
-    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
-      buffer.push((T)i);
-    }
-    assert(buffer.size() == ChunkedListT::BufferSize, "assert");
-    assert(buffer.is_full(), "assert");
-  }
-
-  static void testSize() {
-    ChunkedListT buffer;
-    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
-      assert(buffer.size() == i, "assert");
-      buffer.push((T)i);
-      assert(buffer.size() == i + 1, "assert");
-    }
-  }
-
-  static void testClear() {
-    ChunkedListT buffer;
-
-    buffer.clear();
-    assert(buffer.size() == 0, "assert");
-
-    for (uintptr_t i = 0; i < ChunkedListT::BufferSize / 2; i++) {
-      buffer.push((T)i);
-    }
-    buffer.clear();
-    assert(buffer.size() == 0, "assert");
-
-    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
-      buffer.push((T)i);
-    }
-    buffer.clear();
-    assert(buffer.size() == 0, "assert");
-  }
-
-  static void testAt() {
-    ChunkedListT buffer;
-
-    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
-      buffer.push((T)i);
-      assert(buffer.at(i) == (T)i, "assert");
-    }
-
-    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
-      assert(buffer.at(i) == (T)i, "assert");
-    }
-  }
-
-  static void test() {
-    testEmpty();
-    testFull();
-    testSize();
-    testClear();
-    testAt();
-  }
-};
-
-class Metadata;
-
-void TestChunkedList_test() {
-  TestChunkedList<Metadata*>::test();
-  TestChunkedList<size_t>::test();
-}
-
-#endif
--- a/src/share/vm/utilities/internalVMTests.cpp	Wed Sep 28 11:17:51 2016 +0200
+++ b/src/share/vm/utilities/internalVMTests.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -60,7 +60,6 @@
   run_unit_test(TestBitMap_test);
   run_unit_test(TestResourcehash_test);
   run_unit_test(ObjectMonitor_test);
-  run_unit_test(TestChunkedList_test);
   run_unit_test(Test_log_tag_combinations_limit);
   run_unit_test(Test_logtarget);
   run_unit_test(Test_logstream);
@@ -86,7 +85,6 @@
   run_unit_test(TestBufferingOopClosure_test);
   if (UseG1GC) {
     run_unit_test(FreeRegionList_test);
-    run_unit_test(IHOP_test);
   }
   run_unit_test(WorkerDataArray_test);
   run_unit_test(ParallelCompact_test);
--- a/test/jprt.config	Wed Sep 28 11:17:51 2016 +0200
+++ b/test/jprt.config	Mon Oct 03 12:35:51 2016 -0400
@@ -86,12 +86,12 @@
     fi
 
     # Add basic solaris system paths
-    path4sdk=/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin
+    path4sdk=/usr/bin
 
     # Find GNU make
-    make=/usr/sfw/bin/gmake
+    make=/usr/bin/gmake
     if [ ! -f ${make} ] ; then
-	make=/opt/sfw/bin/gmake
+	make=/usr/gnu/bin/make
 	if [ ! -f ${make} ] ; then
 	    make=${slashjava}/devtools/${solaris_arch}/bin/gnumake
         fi 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native/gc/g1/test_g1IHOPControl.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1IHOPControl.hpp"
+#include "gc/g1/g1Predictions.hpp"
+#include "unittest.hpp"
+
+static void test_update(G1IHOPControl* ctrl, double alloc_time,
+                        size_t alloc_amount, size_t young_size,
+                        double mark_time) {
+  for (int i = 0; i < 100; i++) {
+    ctrl->update_allocation_info(alloc_time, alloc_amount, young_size);
+    ctrl->update_marking_length(mark_time);
+  }
+}
+
+// @requires UseG1GC
+TEST_VM(G1StaticIHOPControl, simple) {
+  // Test requires G1
+  if (!UseG1GC) {
+    return;
+  }
+
+  const size_t initial_ihop = 45;
+
+  G1StaticIHOPControl ctrl(initial_ihop);
+  ctrl.update_target_occupancy(100);
+
+  size_t threshold = ctrl.get_conc_mark_start_threshold();
+  EXPECT_EQ(initial_ihop, threshold);
+
+  ctrl.update_allocation_info(100.0, 100, 100);
+  threshold = ctrl.get_conc_mark_start_threshold();
+  EXPECT_EQ(initial_ihop, threshold);
+
+  ctrl.update_marking_length(1000.0);
+  threshold = ctrl.get_conc_mark_start_threshold();
+  EXPECT_EQ(initial_ihop, threshold);
+
+  // Whatever we pass, the IHOP value must stay the same.
+  test_update(&ctrl, 2, 10, 10, 3);
+  threshold = ctrl.get_conc_mark_start_threshold();
+
+  EXPECT_EQ(initial_ihop, threshold);
+
+  test_update(&ctrl, 12, 10, 10, 3);
+  threshold = ctrl.get_conc_mark_start_threshold();
+
+  EXPECT_EQ(initial_ihop, threshold);
+}
+
+// @requires UseG1GC
+TEST_VM(G1AdaptiveIHOPControl, simple) {
+  // Test requires G1
+  if (!UseG1GC) {
+    return;
+  }
+
+  const size_t initial_threshold = 45;
+  const size_t young_size = 10;
+  const size_t target_size = 100;
+
+  // The final IHOP value is always
+  // target_size - (young_size + alloc_amount/alloc_time * marking_time)
+
+  G1Predictions pred(0.95);
+  G1AdaptiveIHOPControl ctrl(initial_threshold, &pred, 0, 0);
+  ctrl.update_target_occupancy(target_size);
+
+  // First "load".
+  const size_t alloc_time1 = 2;
+  const size_t alloc_amount1 = 10;
+  const size_t marking_time1 = 2;
+  const size_t settled_ihop1 = target_size
+          - (young_size + alloc_amount1 / alloc_time1 * marking_time1);
+
+  size_t threshold;
+  threshold = ctrl.get_conc_mark_start_threshold();
+
+  EXPECT_EQ(initial_threshold, threshold);
+
+  for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) {
+    ctrl.update_allocation_info(alloc_time1, alloc_amount1, young_size);
+    ctrl.update_marking_length(marking_time1);
+    // Not enough data yet.
+    threshold = ctrl.get_conc_mark_start_threshold();
+
+    ASSERT_EQ(initial_threshold, threshold) << "on step " << i;
+  }
+
+  test_update(&ctrl, alloc_time1, alloc_amount1, young_size, marking_time1);
+
+  threshold = ctrl.get_conc_mark_start_threshold();
+
+  EXPECT_EQ(settled_ihop1, threshold);
+
+  // Second "load". A bit higher allocation rate.
+  const size_t alloc_time2 = 2;
+  const size_t alloc_amount2 = 30;
+  const size_t marking_time2 = 2;
+  const size_t settled_ihop2 = target_size
+          - (young_size + alloc_amount2 / alloc_time2 * marking_time2);
+
+  test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2);
+
+  threshold = ctrl.get_conc_mark_start_threshold();
+
+  EXPECT_LT(threshold, settled_ihop1);
+
+  // Third "load". Very high (impossible) allocation rate.
+  const size_t alloc_time3 = 1;
+  const size_t alloc_amount3 = 50;
+  const size_t marking_time3 = 2;
+  const size_t settled_ihop3 = 0;
+
+  test_update(&ctrl, alloc_time3, alloc_amount3, young_size, marking_time3);
+  threshold = ctrl.get_conc_mark_start_threshold();
+
+  EXPECT_EQ(settled_ihop3, threshold);
+
+  // And back to some arbitrary value.
+  test_update(&ctrl, alloc_time2, alloc_amount2, young_size, marking_time2);
+
+  threshold = ctrl.get_conc_mark_start_threshold();
+
+  EXPECT_GT(threshold, settled_ihop3);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native/utilities/test_chunkedList.cpp	Mon Oct 03 12:35:51 2016 -0400
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2014, 2016, 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.
+ */
+
+#include "precompiled.hpp"
+#include "unittest.hpp"
+#include "utilities/chunkedList.hpp"
+
+class Metadata;
+
+template <typename T>
+class TestChunkedList {
+  typedef ChunkedList<T, mtOther> ChunkedListT;
+
+ public:
+
+  static void testEmpty() {
+    ChunkedListT buffer;
+    ASSERT_EQ((size_t) 0, buffer.size());
+  }
+
+  static void testFull() {
+    ChunkedListT buffer;
+    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
+      buffer.push((T) i);
+    }
+    ASSERT_EQ((size_t) ChunkedListT::BufferSize, buffer.size());
+    ASSERT_TRUE(buffer.is_full());
+  }
+
+  static void testSize() {
+    ChunkedListT buffer;
+    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
+      ASSERT_EQ((size_t) i, buffer.size());
+      buffer.push((T) i);
+      ASSERT_EQ((size_t) (i + 1), buffer.size());
+    }
+  }
+
+  static void testClear() {
+    ChunkedListT buffer;
+
+    buffer.clear();
+    ASSERT_EQ((size_t) 0, buffer.size());
+
+    for (uintptr_t i = 0; i < ChunkedListT::BufferSize / 2; i++) {
+      buffer.push((T) i);
+    }
+    buffer.clear();
+    ASSERT_EQ((size_t) 0, buffer.size());
+
+    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
+      buffer.push((T) i);
+    }
+    buffer.clear();
+    ASSERT_EQ((size_t) 0, buffer.size());
+  }
+
+  static void testAt() {
+    ChunkedListT buffer;
+
+    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
+      buffer.push((T) i);
+      ASSERT_EQ((T) i, buffer.at(i));
+    }
+
+    for (uintptr_t i = 0; i < ChunkedListT::BufferSize; i++) {
+      ASSERT_EQ((T) i, buffer.at(i));
+    }
+  }
+};
+
+TEST(ChunkedList, metadata_empty) {
+  TestChunkedList<Metadata*>::testEmpty();
+}
+
+TEST(ChunkedList, metadata_full) {
+  TestChunkedList<Metadata*>::testFull();
+}
+
+TEST(ChunkedList, metadata_size) {
+  TestChunkedList<Metadata*>::testSize();
+}
+
+TEST(ChunkedList, metadata_clear) {
+  TestChunkedList<Metadata*>::testSize();
+}
+
+TEST(ChunkedList, metadata_at) {
+  TestChunkedList<Metadata*>::testAt();
+}
+
+TEST(ChunkedList, size_t_empty) {
+  TestChunkedList<size_t>::testEmpty();
+}
+
+TEST(ChunkedList, size_t_full) {
+  TestChunkedList<size_t>::testFull();
+}
+
+TEST(ChunkedList, size_t_size) {
+  TestChunkedList<size_t>::testSize();
+}
+
+TEST(ChunkedList, size_t_clear) {
+  TestChunkedList<size_t>::testSize();
+}
+
+TEST(ChunkedList, size_t_at) {
+  TestChunkedList<size_t>::testAt();
+}
--- a/test/runtime/SharedArchiveFile/SASymbolTableTest.java	Wed Sep 28 11:17:51 2016 +0200
+++ b/test/runtime/SharedArchiveFile/SASymbolTableTest.java	Mon Oct 03 12:35:51 2016 -0400
@@ -34,14 +34,17 @@
  *          jdk.hotspot.agent/sun.jvm.hotspot.runtime
  *          jdk.hotspot.agent/sun.jvm.hotspot.tools
  *          java.management
- * @build SASymbolTableTestAgent SASymbolTableTestAttachee
+ * @build SASymbolTableTestAgent
  * @run main SASymbolTableTest
  */
 
+import java.util.Arrays;
+import java.util.List;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.Platform;
+import jdk.test.lib.apps.LingeredApp;
 
 /*
  * The purpose of this test is to validate that we can use SA to
@@ -53,6 +56,7 @@
  */
 public class SASymbolTableTest {
     static String jsaName = "./SASymbolTableTest.jsa";
+    private static LingeredApp theApp = null;
 
     public static void main(String[] args) throws Exception {
         if (!Platform.shouldSAAttach()) {
@@ -78,50 +82,44 @@
     private static void run(boolean useArchive) throws Exception {
         String flag = useArchive ? "auto" : "off";
 
-        // (1) Launch the attachee process
-        ProcessBuilder attachee = ProcessTools.createJavaProcessBuilder(
-            "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=" + jsaName,
-            "-Xshare:" + flag,
-            "-showversion",                // so we can see "sharing" in the output
-            "SASymbolTableTestAttachee");
+        try {
+            // (1) Launch the attachee process
+            System.out.println("Starting LingeredApp");
+            List<String> vmOpts = Arrays.asList(
+                    "-XX:+UnlockDiagnosticVMOptions",
+                    "-XX:SharedArchiveFile=" + jsaName,
+                    "-Xshare:" + flag,
+                    "-showversion");                // so we can see "sharing" in the output
 
-        final Process p = attachee.start();
+            theApp = LingeredApp.startApp(vmOpts);
 
-        // (2) Launch the agent process
-        long pid = p.getPid();
-        System.out.println("Attaching agent " + pid);
-        ProcessBuilder tool = ProcessTools.createJavaProcessBuilder(
-            "--add-modules=jdk.hotspot.agent",
-            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
-            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED",
-            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED",
-            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED",
-            "SASymbolTableTestAgent",
-            Long.toString(pid));
-        OutputAnalyzer output = ProcessTools.executeProcess(tool);
-        System.out.println(output.getOutput());
-        output.shouldHaveExitValue(0);
-
-        Thread t = new Thread() {
-                public void run() {
-                    try {
-                        OutputAnalyzer output = new OutputAnalyzer(p);
-                        System.out.println("STDOUT[");
-                        System.out.print(output.getStdout());
-                        System.out.println("]");
-                        System.out.println("STDERR[");
-                        System.out.print(output.getStderr());
-                        System.out.println("]");
-                    } catch (Throwable t) {
-                        t.printStackTrace();
-                    }
-                }
-            };
-        t.start();
-
-        Thread.sleep(2 * 1000);
-        p.destroy();
-        t.join();
+            // (2) Launch the agent process
+            long pid = theApp.getPid();
+            System.out.println("Attaching agent to " + pid );
+            ProcessBuilder tool = ProcessTools.createJavaProcessBuilder(
+                    "--add-modules=jdk.hotspot.agent",
+                    "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
+                    "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED",
+                    "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED",
+                    "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED",
+                    "SASymbolTableTestAgent",
+                    Long.toString(pid));
+            OutputAnalyzer output = ProcessTools.executeProcess(tool);
+            System.out.println("STDOUT[");
+            System.out.println(output.getOutput());
+            if (output.getStdout().contains("connected too early")) {
+                System.out.println("SymbolTable not created by VM - test skipped");
+                return;
+            }
+            System.out.println("]");
+            System.out.println("STDERR[");
+            System.out.print(output.getStderr());
+            System.out.println("]");
+            output.shouldHaveExitValue(0);
+        } catch (Exception ex) {
+            throw new RuntimeException("Test ERROR " + ex, ex);
+        } finally {
+            LingeredApp.stopApp(theApp);
+        }
     }
 }
--- a/test/runtime/SharedArchiveFile/SASymbolTableTestAgent.java	Wed Sep 28 11:17:51 2016 +0200
+++ b/test/runtime/SharedArchiveFile/SASymbolTableTestAgent.java	Mon Oct 03 12:35:51 2016 -0400
@@ -112,31 +112,35 @@
 
     public void run() {
         System.out.println("SASymbolTableTestAgent: starting");
-        VM vm = VM.getVM();
-        SymbolTable table = vm.getSymbolTable();
+        try {
+            VM vm = VM.getVM();
+            SymbolTable table = vm.getSymbolTable();
 
-        // (a) These are names that are likely to exist in the symbol table
-        //     of a JVM after start-up. They were taken from vmSymbols.hpp
-        //     during the middle of JDK9 development.
-        //
-        //     The purpose is not to check that each name must exist (a future
-        //     version of JDK may not preload some of the classes).
-        //
-        //     The purpose of this loops is to ensure that we check a lot of symbols,
-        //     so we will (most likely) hit on both VALUE_ONLY_BUCKET_TYPE and normal bucket type
-        //     in CompactHashTable.probe().
-        for (String n : commonNames) {
-            Symbol s = table.probe(n);
-            System.out.format("%-40s = %s\n", n, s);
-        }
+            // (a) These are names that are likely to exist in the symbol table
+            //     of a JVM after start-up. They were taken from vmSymbols.hpp
+            //     during the middle of JDK9 development.
+            //
+            //     The purpose is not to check that each name must exist (a future
+            //     version of JDK may not preload some of the classes).
+            //
+            //     The purpose of this loops is to ensure that we check a lot of symbols,
+            //     so we will (most likely) hit on both VALUE_ONLY_BUCKET_TYPE and normal bucket type
+            //     in CompactHashTable.probe().
+            for (String n : commonNames) {
+                Symbol s = table.probe(n);
+                System.out.format("%-40s = %s\n", n, s);
+            }
 
-        System.out.println("======================================================================");
+            System.out.println("======================================================================");
 
-        // (b) Also test a few strings that are known to not exist in the table. This will
-        //     both the compact table (if it exists) and the regular table to be walked.
-        for (String n : badNames) {
-            Symbol s = table.probe(n);
-            System.out.format("%-40s = %s\n", n, s);
+            // (b) Also test a few strings that are known to not exist in the table. This will
+            //     both the compact table (if it exists) and the regular table to be walked.
+            for (String n : badNames) {
+                Symbol s = table.probe(n);
+                System.out.format("%-40s = %s\n", n, s);
+            }
+        } catch (NullPointerException e) {
+            System.out.println("connected too early -- please try again");
         }
     }
 }
--- a/test/runtime/SharedArchiveFile/SASymbolTableTestAttachee.java	Wed Sep 28 11:17:51 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2016, 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 class is launched in a sub-process by the main test,
- * SASymbolTableTest.java.
- *
- * This class does nothing in particular. It just sleeps for 120
- * seconds so SASymbolTableTestAgent can have a chance to examine its
- * SymbolTable. This process should be killed by the parent process
- * after SASymbolTableTestAgent has completed testing.
- */
-public class SASymbolTableTestAttachee {
-    public static void main(String args[]) throws Throwable {
-        System.out.println("SASymbolTableTestAttachee: sleeping to wait for SA tool to attach ...");
-        Thread.sleep(120 * 1000);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/logging/StackWalkTest.java	Mon Oct 03 12:35:51 2016 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016, 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 StackWalkTest
+ * @bug 8160064
+ * @summary -Xlog:stackwalk should produce logging from the source code
+ * @library /test/lib
+ * @run driver StackWalkTest
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class StackWalkTest {
+    static void analyzeOutputOn(ProcessBuilder pb) throws Exception {
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Start walking");
+        output.shouldContain("fill_in_frames");
+        output.shouldHaveExitValue(0);
+    }
+
+    static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("[stackwalk]");
+        output.shouldHaveExitValue(0);
+    }
+
+    public static void main(String... args) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:stackwalk=debug",
+                                                                  InnerClass.class.getName());
+        analyzeOutputOn(pb);
+
+        pb = ProcessTools.createJavaProcessBuilder("-Xlog:stackwalk=off",
+                                                   InnerClass.class.getName());
+        analyzeOutputOff(pb);
+    }
+
+    public static class InnerClass {
+        public static void main(String[] args) throws Exception {
+            System.out.println("Testing stackwalk.");
+            StackWalker sw = StackWalker.getInstance();
+            sw.forEach(System.out::println);
+        }
+    }
+}