Merge
authordlong
Tue, 27 Sep 2016 20:55:13 -0400
changeset 41339 4273117df541
parent 41317 ba006b931e27 (diff)
parent 41338 310c87628696 (current diff)
child 41340 64703e04389c
Merge
hotspot/src/share/vm/utilities/internalVMTests.cpp
hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodAtSlotTest.java
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Tue Sep 27 20:55:13 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/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Tue Sep 27 20:55:13 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/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Tue Sep 27 20:55:13 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/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.hpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.hpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/oops/oop.hpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/oops/oop.hpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/oops/oop.inline.hpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Tue Sep 27 20:55:13 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/hotspot/src/share/vm/utilities/chunkedList.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ /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/hotspot/src/share/vm/utilities/internalVMTests.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp	Tue Sep 27 20:55:13 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/hotspot/test/jprt.config	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/test/jprt.config	Tue Sep 27 20:55:13 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/hotspot/test/native/gc/g1/test_g1IHOPControl.cpp	Tue Sep 27 20:55:13 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/hotspot/test/native/utilities/test_chunkedList.cpp	Tue Sep 27 20:55:13 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();
+}