Merge jdk7-b49
authorduke
Wed, 05 Jul 2017 16:47:51 +0200
changeset 2049 6b84b04a80af
parent 2048 4b4783f4fa14 (diff)
parent 2002 7b2e683b7c36 (current diff)
child 2050 804c6c2cd89c
child 2051 c7a5f07b79b2
child 2052 90cbd9088155
child 2054 6da6b71a5d0a
child 2059 a615a416ea59
child 2078 4f3bb7d32ea0
child 2080 9c9bf2f9d3f3
child 2082 4dd69fd1b1f9
child 2084 e467ea34f00d
child 2090 f885943f29de
child 2194 b1b06d37c64d
child 2460 15e4d52f9ed4
child 2486 c22da29c4b59
child 2517 3b00287c5c47
child 2557 cd59be8d6c55
Merge
--- a/.hgtags-top-repo	Wed Jul 05 16:47:27 2017 +0200
+++ b/.hgtags-top-repo	Wed Jul 05 16:47:51 2017 +0200
@@ -22,3 +22,4 @@
 99846f001ca214015578d593802d26e27246a802 jdk7-b45
 e8a2a4d187773a62f3309b0fa265c13425bc2258 jdk7-b46
 d7744e86dedc21a8ecf6bdb73eb191b8eaf5b0da jdk7-b47
+4ae9f4bfdb98f65bd957e3fe72471b320150b38e jdk7-b48
--- a/corba/.hgtags	Wed Jul 05 16:47:27 2017 +0200
+++ b/corba/.hgtags	Wed Jul 05 16:47:51 2017 +0200
@@ -22,3 +22,4 @@
 68814aa5b44b1f16931a97e7cd4028c70eb9586b jdk7-b45
 1691dbfc08f8ee3f4e23a1ff30cdff920718696c jdk7-b46
 167ad0164301f318b069a947e1c9c07ed667748a jdk7-b47
+0be222241fd405e48915647facfaa176621b39b9 jdk7-b48
--- a/hotspot/.hgtags	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/.hgtags	Wed Jul 05 16:47:51 2017 +0200
@@ -22,3 +22,4 @@
 945bf754069766e76873c53102fae48abf04cf5b jdk7-b45
 16bb38eeda35b46268eefa4c1f829eb086e0ca46 jdk7-b46
 fcb923bad68e2b10380a030ea83a723f4dc3d4d6 jdk7-b47
+bcb33806d186561c781992e5f4d8a90bb033f9f0 jdk7-b48
--- a/hotspot/make/hotspot_version	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/make/hotspot_version	Wed Jul 05 16:47:51 2017 +0200
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=15
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=01
+HS_BUILD_NUMBER=02
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 16:47:51 2017 +0200
@@ -762,7 +762,7 @@
     case Assembler::stdf_op3: st_op = Op_StoreD; break;
 
     case Assembler::ldsb_op3: ld_op = Op_LoadB; break;
-    case Assembler::lduh_op3: ld_op = Op_LoadC; break;
+    case Assembler::lduh_op3: ld_op = Op_LoadUS; break;
     case Assembler::ldsh_op3: ld_op = Op_LoadS; break;
     case Assembler::ldx_op3:  // may become LoadP or stay LoadI
     case Assembler::ldsw_op3: // may become LoadP or stay LoadI
@@ -3869,6 +3869,8 @@
   constraint(ALLOC_IN_RC(dflt_reg));
   match(RegD);
 
+  match(regD_low);
+
   format %{ %}
   interface(REG_INTER);
 %}
@@ -3883,7 +3885,7 @@
 
 operand regD_low() %{
   constraint(ALLOC_IN_RC(dflt_low_reg));
-  match(RegD);
+  match(regD);
 
   format %{ %}
   interface(REG_INTER);
@@ -5314,9 +5316,9 @@
   ins_pipe(iload_mask_mem);
 %}
 
-// Load Char (16bit UNsigned) into a Long Register
-instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{
-  match(Set dst (AndL (ConvI2L (LoadC mem)) bytemask));
+// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
+instruct loadUS2L(iRegL dst, memory mem, immL_FFFF bytemask) %{
+  match(Set dst (AndL (ConvI2L (LoadUS mem)) bytemask));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
@@ -5326,9 +5328,9 @@
   ins_pipe(iload_mask_mem);
 %}
 
-// Load Char (16bit unsigned)
-instruct loadC(iRegI dst, memory mem) %{
-  match(Set dst (LoadC mem));
+// Load Unsigned Short/Char (16bit unsigned)
+instruct loadUS(iRegI dst, memory mem) %{
+  match(Set dst (LoadUS mem));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 05 16:47:51 2017 +0200
@@ -6413,9 +6413,9 @@
   ins_pipe( ialu_reg_mem );
 %}
 
-// Load Char (16bit unsigned)
-instruct loadC(eRegI dst, memory mem) %{
-  match(Set dst (LoadC mem));
+// Load Unsigned Short/Char (16bit unsigned)
+instruct loadUS(eRegI dst, memory mem) %{
+  match(Set dst (LoadUS mem));
 
   ins_cost(125);
   format %{ "MOVZX  $dst,$mem" %}
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 05 16:47:51 2017 +0200
@@ -6096,25 +6096,25 @@
 //   ins_pipe(ialu_reg_mem);
 // %}
 
-// Load Char (16 bit UNsigned)
-instruct loadC(rRegI dst, memory mem)
-%{
-  match(Set dst (LoadC mem));
+// Load Unsigned Short/Char (16 bit UNsigned)
+instruct loadUS(rRegI dst, memory mem)
+%{
+  match(Set dst (LoadUS mem));
 
   ins_cost(125);
-  format %{ "movzwl  $dst, $mem\t# char" %}
+  format %{ "movzwl  $dst, $mem\t# ushort/char" %}
   opcode(0x0F, 0xB7);
   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
   ins_pipe(ialu_reg_mem);
 %}
 
-// Load Char (16 bit UNsigned) into long
-// instruct loadC2L(rRegL dst, memory mem)
+// Load Unsigned Short/Char (16 bit UNsigned) into long
+// instruct loadUS2L(rRegL dst, memory mem)
 // %{
-//   match(Set dst (ConvI2L (LoadC mem)));
+//   match(Set dst (ConvI2L (LoadUS mem)));
 
 //   ins_cost(125);
-//   format %{ "movzwl  $dst, $mem\t# char -> long" %}
+//   format %{ "movzwl  $dst, $mem\t# ushort/char -> long" %}
 //   opcode(0x0F, 0xB7);
 //   ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem));
 //   ins_pipe(ialu_reg_mem);
@@ -9490,14 +9490,14 @@
 %{
   match(Set dst (AndL dst src));
 
-  format %{ "movzbq  $dst, $src\t# long & 0xFF" %}
+  format %{ "movzbq  $dst, $dst\t# long & 0xFF" %}
   opcode(0x0F, 0xB6);
   ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
   ins_pipe(ialu_reg);
 %}
 
 // And Register with Immediate 65535
-instruct andL_rReg_imm65535(rRegI dst, immL_65535 src)
+instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
 %{
   match(Set dst (AndL dst src));
 
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -1432,6 +1432,10 @@
   return buf;
 }
 
+struct tm* os::localtime_pd(const time_t* clock, struct tm*  res) {
+  return localtime_r(clock, res);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // runtime exit support
 
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -323,6 +323,10 @@
   return (size_t)(base - bottom);
 }
 
+struct tm* os::localtime_pd(const time_t* clock, struct tm*  res) {
+  return localtime_r(clock, res);
+}
+
 // interruptible infrastructure
 
 // setup_interruptible saves the thread state before going into an
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -327,6 +327,14 @@
   return sz;
 }
 
+struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
+  const struct tm* time_struct_ptr = localtime(clock);
+  if (time_struct_ptr != NULL) {
+    *res = *time_struct_ptr;
+    return res;
+  }
+  return NULL;
+}
 
 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
 
--- a/hotspot/src/share/vm/adlc/dict2.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/adlc/dict2.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -316,9 +316,12 @@
   return strcmp((const char *)k1,(const char *)k2);
 }
 
-// Slimey cheap key comparator.
+// Cheap key comparator.
 int cmpkey(const void *key1, const void *key2) {
-  return (int)((intptr_t)key1 - (intptr_t)key2);
+  if (key1 == key2) return 0;
+  intptr_t delta = (intptr_t)key1 - (intptr_t)key2;
+  if (delta > 0) return 1;
+  return -1;
 }
 
 //=============================================================================
--- a/hotspot/src/share/vm/adlc/forms.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/adlc/forms.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -248,7 +248,7 @@
 // True if 'opType', an ideal name, loads or stores.
 Form::DataType Form::is_load_from_memory(const char *opType) const {
   if( strcmp(opType,"LoadB")==0 )  return Form::idealB;
-  if( strcmp(opType,"LoadC")==0 )  return Form::idealC;
+  if( strcmp(opType,"LoadUS")==0 )  return Form::idealC;
   if( strcmp(opType,"LoadD")==0 )  return Form::idealD;
   if( strcmp(opType,"LoadD_unaligned")==0 )  return Form::idealD;
   if( strcmp(opType,"LoadF")==0 )  return Form::idealF;
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -3314,7 +3314,7 @@
     "StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
     "StoreB","StoreC","Store" ,"StoreFP",
     "LoadI" ,"LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
-    "LoadB" ,"LoadC" ,"LoadS" ,"Load"   ,
+    "LoadB" ,"LoadUS" ,"LoadS" ,"Load"   ,
     "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
     "Store8B","Store4B","Store8C","Store4C","Store2C",
     "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -123,6 +123,10 @@
     // addresses constructed before expansions will not be confused.
     cb->free_blob();
   }
+
+  // free any overflow storage
+  delete _overflow_arena;
+
 #ifdef ASSERT
   Copy::fill_to_bytes(this, sizeof(*this), badResourceValue);
 #endif
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -846,6 +846,12 @@
                                 Handle protection_domain,
                                 TRAPS) {
 
+  // UseNewReflection
+  // The result of this call should be consistent with the result
+  // of the call to resolve_instance_class_or_null().
+  // See evaluation 6790209 and 4474172 for more details.
+  class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
+
   unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader);
   int d_index = dictionary()->hash_to_index(d_hash);
 
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -24,7 +24,7 @@
 
 // We need to sort heap regions by collection desirability.
 
-class CSetChooserCache {
+class CSetChooserCache VALUE_OBJ_CLASS_SPEC {
 private:
   enum {
     CacheLength = 16
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -33,7 +33,7 @@
   PYA_cancel     // It's been completed by somebody else: cancel.
 };
 
-class ConcurrentG1Refine {
+class ConcurrentG1Refine: public CHeapObj {
   ConcurrentG1RefineThread* _cg1rThread;
 
   volatile jint _pya;
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -30,7 +30,7 @@
 // A generic CM bit map.  This is essentially a wrapper around the BitMap
 // class, with one bit per (1<<_shifter) HeapWords.
 
-class CMBitMapRO {
+class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
  protected:
   HeapWord* _bmStartWord;      // base address of range covered by map
   size_t    _bmWordSize;       // map size (in #HeapWords covered)
@@ -139,7 +139,7 @@
 
 // Represents a marking stack used by the CM collector.
 // Ideally this should be GrowableArray<> just like MSC's marking stack(s).
-class CMMarkStack {
+class CMMarkStack VALUE_OBJ_CLASS_SPEC {
   ConcurrentMark* _cm;
   oop*   _base;      // bottom of stack
   jint   _index;     // one more than last occupied index
@@ -237,7 +237,7 @@
   void oops_do(OopClosure* f);
 };
 
-class CMRegionStack {
+class CMRegionStack VALUE_OBJ_CLASS_SPEC {
   MemRegion* _base;
   jint _capacity;
   jint _index;
@@ -312,7 +312,7 @@
 
 class ConcurrentMarkThread;
 
-class ConcurrentMark {
+class ConcurrentMark: public CHeapObj {
   friend class ConcurrentMarkThread;
   friend class CMTask;
   friend class CMBitMapClosure;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -141,7 +141,7 @@
     _scan_only_head(NULL), _scan_only_tail(NULL), _curr_scan_only(NULL),
     _length(0), _scan_only_length(0),
     _last_sampled_rs_lengths(0),
-    _survivor_head(NULL), _survivors_tail(NULL), _survivor_length(0)
+    _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0)
 {
   guarantee( check_list_empty(false), "just making sure..." );
 }
@@ -159,16 +159,15 @@
 }
 
 void YoungList::add_survivor_region(HeapRegion* hr) {
-  assert(!hr->is_survivor(), "should not already be for survived");
+  assert(hr->is_survivor(), "should be flagged as survivor region");
   assert(hr->get_next_young_region() == NULL, "cause it should!");
 
   hr->set_next_young_region(_survivor_head);
   if (_survivor_head == NULL) {
-    _survivors_tail = hr;
+    _survivor_tail = hr;
   }
   _survivor_head = hr;
 
-  hr->set_survivor();
   ++_survivor_length;
 }
 
@@ -239,7 +238,7 @@
 
   empty_list(_survivor_head);
   _survivor_head = NULL;
-  _survivors_tail = NULL;
+  _survivor_tail = NULL;
   _survivor_length = 0;
 
   _last_sampled_rs_lengths = 0;
@@ -391,6 +390,7 @@
 
   // Add survivor regions to SurvRateGroup.
   _g1h->g1_policy()->note_start_adding_survivor_regions();
+  _g1h->g1_policy()->finished_recalculating_age_indexes(true /* is_survivors */);
   for (HeapRegion* curr = _survivor_head;
        curr != NULL;
        curr = curr->get_next_young_region()) {
@@ -401,7 +401,7 @@
   if (_survivor_head != NULL) {
     _head           = _survivor_head;
     _length         = _survivor_length + _scan_only_length;
-    _survivors_tail->set_next_young_region(_scan_only_head);
+    _survivor_tail->set_next_young_region(_scan_only_head);
   } else {
     _head           = _scan_only_head;
     _length         = _scan_only_length;
@@ -418,9 +418,9 @@
   _curr_scan_only   = NULL;
 
   _survivor_head    = NULL;
-  _survivors_tail   = NULL;
+  _survivor_tail   = NULL;
   _survivor_length  = 0;
-  _g1h->g1_policy()->finished_recalculating_age_indexes();
+  _g1h->g1_policy()->finished_recalculating_age_indexes(false /* is_survivors */);
 
   assert(check_list_well_formed(), "young list should be well formed");
 }
@@ -553,7 +553,7 @@
   if (_gc_alloc_region_counts[purpose] < g1_policy()->max_regions(purpose)) {
     alloc_region = newAllocRegion_work(word_size, true, zero_filled);
     if (purpose == GCAllocForSurvived && alloc_region != NULL) {
-      _young_list->add_survivor_region(alloc_region);
+      alloc_region->set_survivor();
     }
     ++_gc_alloc_region_counts[purpose];
   } else {
@@ -949,6 +949,10 @@
     GCOverheadReporter::recordSTWEnd(end);
     g1_policy()->record_full_collection_end();
 
+#ifdef TRACESPINNING
+    ParallelTaskTerminator::print_termination_counts();
+#endif
+
     gc_epilogue(true);
 
     // Abandon concurrent refinement.  This must happen last: in the
@@ -2593,6 +2597,9 @@
         _young_list->print();
 #endif // SCAN_ONLY_VERBOSE
 
+        g1_policy()->record_survivor_regions(_young_list->survivor_length(),
+                                             _young_list->first_survivor_region(),
+                                             _young_list->last_survivor_region());
         _young_list->reset_auxilary_lists();
       }
     } else {
@@ -2619,7 +2626,9 @@
 #endif // SCAN_ONLY_VERBOSE
 
     double end_time_sec = os::elapsedTime();
-    g1_policy()->record_pause_time((end_time_sec - start_time_sec)*1000.0);
+    if (!evacuation_failed()) {
+      g1_policy()->record_pause_time((end_time_sec - start_time_sec)*1000.0);
+    }
     GCOverheadReporter::recordSTWEnd(end_time_sec);
     g1_policy()->record_collection_pause_end(popular_region != NULL,
                                              abandoned);
@@ -2642,8 +2651,13 @@
       }
     }
 
-    if (mark_in_progress())
+    if (mark_in_progress()) {
       concurrent_mark()->update_g1_committed();
+    }
+
+#ifdef TRACESPINNING
+    ParallelTaskTerminator::print_termination_counts();
+#endif
 
     gc_epilogue(false);
   }
@@ -2754,6 +2768,13 @@
     _gc_alloc_region_list = r->next_gc_alloc_region();
     r->set_next_gc_alloc_region(NULL);
     r->set_is_gc_alloc_region(false);
+    if (r->is_survivor()) {
+      if (r->is_empty()) {
+        r->set_not_young();
+      } else {
+        _young_list->add_survivor_region(r);
+      }
+    }
     if (r->is_empty()) {
       ++_free_regions;
     }
@@ -3150,6 +3171,20 @@
   return block;
 }
 
+void G1CollectedHeap::retire_alloc_region(HeapRegion* alloc_region,
+                                            bool par) {
+  // Another thread might have obtained alloc_region for the given
+  // purpose, and might be attempting to allocate in it, and might
+  // succeed.  Therefore, we can't do the "finalization" stuff on the
+  // region below until we're sure the last allocation has happened.
+  // We ensure this by allocating the remaining space with a garbage
+  // object.
+  if (par) par_allocate_remaining_space(alloc_region);
+  // Now we can do the post-GC stuff on the region.
+  alloc_region->note_end_of_copying();
+  g1_policy()->record_after_bytes(alloc_region->used());
+}
+
 HeapWord*
 G1CollectedHeap::allocate_during_gc_slow(GCAllocPurpose purpose,
                                          HeapRegion*    alloc_region,
@@ -3167,16 +3202,7 @@
     // Otherwise, continue; this new region is empty, too.
   }
   assert(alloc_region != NULL, "We better have an allocation region");
-  // Another thread might have obtained alloc_region for the given
-  // purpose, and might be attempting to allocate in it, and might
-  // succeed.  Therefore, we can't do the "finalization" stuff on the
-  // region below until we're sure the last allocation has happened.
-  // We ensure this by allocating the remaining space with a garbage
-  // object.
-  if (par) par_allocate_remaining_space(alloc_region);
-  // Now we can do the post-GC stuff on the region.
-  alloc_region->note_end_of_copying();
-  g1_policy()->record_after_bytes(alloc_region->used());
+  retire_alloc_region(alloc_region, par);
 
   if (_gc_alloc_region_counts[purpose] >= g1_policy()->max_regions(purpose)) {
     // Cannot allocate more regions for the given purpose.
@@ -3185,7 +3211,7 @@
     if (purpose != alt_purpose) {
       HeapRegion* alt_region = _gc_alloc_regions[alt_purpose];
       // Has not the alternative region been aliased?
-      if (alloc_region != alt_region) {
+      if (alloc_region != alt_region && alt_region != NULL) {
         // Try to allocate in the alternative region.
         if (par) {
           block = alt_region->par_allocate(word_size);
@@ -3194,9 +3220,10 @@
         }
         // Make an alias.
         _gc_alloc_regions[purpose] = _gc_alloc_regions[alt_purpose];
-      }
-      if (block != NULL) {
-        return block;
+        if (block != NULL) {
+          return block;
+        }
+        retire_alloc_region(alt_region, par);
       }
       // Both the allocation region and the alternative one are full
       // and aliased, replace them with a new allocation region.
@@ -3497,6 +3524,7 @@
   OverflowQueue* _overflowed_refs;
 
   G1ParGCAllocBuffer _alloc_buffers[GCAllocPurposeCount];
+  ageTable           _age_table;
 
   size_t           _alloc_buffer_waste;
   size_t           _undo_waste;
@@ -3538,6 +3566,7 @@
       _refs(g1h->task_queue(queue_num)),
       _hash_seed(17), _queue_num(queue_num),
       _term_attempts(0),
+      _age_table(false),
 #if G1_DETAILED_STATS
       _pushes(0), _pops(0), _steals(0),
       _steal_attempts(0),  _overflow_pushes(0),
@@ -3572,8 +3601,9 @@
 
   RefToScanQueue*   refs()            { return _refs;             }
   OverflowQueue*    overflowed_refs() { return _overflowed_refs;  }
-
-  inline G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
+  ageTable*         age_table()       { return &_age_table;       }
+
+  G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose) {
     return &_alloc_buffers[purpose];
   }
 
@@ -3834,7 +3864,9 @@
           (!from_region->is_young() && young_index == 0), "invariant" );
   G1CollectorPolicy* g1p = _g1->g1_policy();
   markOop m = old->mark();
-  GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, m->age(),
+  int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
+                                           : m->age();
+  GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
                                                              word_sz);
   HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz);
   oop       obj     = oop(obj_ptr);
@@ -3872,9 +3904,12 @@
         obj->incr_age();
       } else {
         m = m->incr_age();
+        obj->set_mark(m);
       }
+      _par_scan_state->age_table()->add(obj, word_sz);
+    } else {
+      obj->set_mark(m);
     }
-    obj->set_mark(m);
 
     // preserve "next" mark bit
     if (_g1->mark_in_progress() && !_g1->is_obj_ill(old)) {
@@ -4129,6 +4164,9 @@
       _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms);
       _g1h->g1_policy()->record_termination_time(i, term_ms);
     }
+    if (G1UseSurvivorSpace) {
+      _g1h->g1_policy()->record_thread_age_table(pss.age_table());
+    }
     _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
 
     // Clean up any par-expanded rem sets.
@@ -4368,7 +4406,7 @@
   // Is this the right thing to do here?  We don't save marks
   // on individual heap regions when we allocate from
   // them in parallel, so this seems like the correct place for this.
-  all_alloc_regions_note_end_of_copying();
+  retire_all_alloc_regions();
   {
     G1IsAliveClosure is_alive(this);
     G1KeepAliveClosure keep_alive(this);
@@ -5008,7 +5046,7 @@
   return no_allocs;
 }
 
-void G1CollectedHeap::all_alloc_regions_note_end_of_copying() {
+void G1CollectedHeap::retire_all_alloc_regions() {
   for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
     HeapRegion* r = _gc_alloc_regions[ap];
     if (r != NULL) {
@@ -5021,8 +5059,7 @@
         }
       }
       if (!has_processed_alias) {
-        r->note_end_of_copying();
-        g1_policy()->record_after_bytes(r->used());
+        retire_alloc_region(r, false /* par */);
       }
     }
   }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -90,7 +90,7 @@
   HeapRegion* _curr_scan_only;
 
   HeapRegion* _survivor_head;
-  HeapRegion* _survivors_tail;
+  HeapRegion* _survivor_tail;
   size_t      _survivor_length;
 
   void          empty_list(HeapRegion* list);
@@ -105,6 +105,7 @@
   bool          is_empty() { return _length == 0; }
   size_t        length() { return _length; }
   size_t        scan_only_length() { return _scan_only_length; }
+  size_t        survivor_length() { return _survivor_length; }
 
   void rs_length_sampling_init();
   bool rs_length_sampling_more();
@@ -120,6 +121,7 @@
   HeapRegion* first_region() { return _head; }
   HeapRegion* first_scan_only_region() { return _scan_only_head; }
   HeapRegion* first_survivor_region() { return _survivor_head; }
+  HeapRegion* last_survivor_region() { return _survivor_tail; }
   HeapRegion* par_get_next_scan_only_region() {
     MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
     HeapRegion* ret = _curr_scan_only;
@@ -219,7 +221,7 @@
   // The to-space memory regions into which objects are being copied during
   // a GC.
   HeapRegion* _gc_alloc_regions[GCAllocPurposeCount];
-  uint _gc_alloc_region_counts[GCAllocPurposeCount];
+  size_t _gc_alloc_region_counts[GCAllocPurposeCount];
 
   // A list of the regions that have been set to be alloc regions in the
   // current collection.
@@ -281,8 +283,8 @@
   // Returns "true" iff none of the gc alloc regions have any allocations
   // since the last call to "save_marks".
   bool all_alloc_regions_no_allocs_since_save_marks();
-  // Calls "note_end_of_copying on all gc alloc_regions.
-  void all_alloc_regions_note_end_of_copying();
+  // Perform finalization stuff on all allocation regions.
+  void retire_all_alloc_regions();
 
   // The number of regions allocated to hold humongous objects.
   int         _num_humongous_regions;
@@ -351,6 +353,10 @@
   // that parallel threads might be attempting allocations.
   void par_allocate_remaining_space(HeapRegion* r);
 
+  // Retires an allocation region when it is full or at the end of a
+  // GC pause.
+  void  retire_alloc_region(HeapRegion* alloc_region, bool par);
+
   // Helper function for two callbacks below.
   // "full", if true, indicates that the GC is for a System.gc() request,
   // and should collect the entire heap.  If "clear_all_soft_refs" is true,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -196,8 +196,13 @@
   _short_lived_surv_rate_group(new SurvRateGroup(this, "Short Lived",
                                                  G1YoungSurvRateNumRegionsSummary)),
   _survivor_surv_rate_group(new SurvRateGroup(this, "Survivor",
-                                              G1YoungSurvRateNumRegionsSummary))
+                                              G1YoungSurvRateNumRegionsSummary)),
   // add here any more surv rate groups
+  _recorded_survivor_regions(0),
+  _recorded_survivor_head(NULL),
+  _recorded_survivor_tail(NULL),
+  _survivors_age_table(true)
+
 {
   _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
   _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
@@ -272,6 +277,15 @@
   _concurrent_mark_cleanup_times_ms->add(0.20);
   _tenuring_threshold = MaxTenuringThreshold;
 
+  if (G1UseSurvivorSpace) {
+    // if G1FixedSurvivorSpaceSize is 0 which means the size is not
+    // fixed, then _max_survivor_regions will be calculated at
+    // calculate_young_list_target_config during initialization
+    _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
+  } else {
+    _max_survivor_regions = 0;
+  }
+
   initialize_all();
 }
 
@@ -283,6 +297,9 @@
 void G1CollectorPolicy::initialize_flags() {
   set_min_alignment(HeapRegion::GrainBytes);
   set_max_alignment(GenRemSet::max_alignment_constraint(rem_set_name()));
+  if (SurvivorRatio < 1) {
+    vm_exit_during_initialization("Invalid survivor ratio specified");
+  }
   CollectorPolicy::initialize_flags();
 }
 
@@ -301,6 +318,8 @@
                                   "-XX:+UseConcMarkSweepGC.");
   }
 
+  initialize_gc_policy_counters();
+
   if (G1Gen) {
     _in_young_gc_mode = true;
 
@@ -322,6 +341,12 @@
   }
 }
 
+// Create the jstat counters for the policy.
+void G1CollectorPolicy::initialize_gc_policy_counters()
+{
+  _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 2 + G1Gen);
+}
+
 void G1CollectorPolicy::calculate_young_list_min_length() {
   _young_list_min_length = 0;
 
@@ -352,6 +377,7 @@
     guarantee( so_length < _young_list_target_length, "invariant" );
     _young_list_so_prefix_length = so_length;
   }
+  calculate_survivors_policy();
 }
 
 // This method calculate the optimal scan-only set for a fixed young
@@ -448,6 +474,9 @@
   if (full_young_gcs() && _free_regions_at_end_of_collection > 0) {
     // we are in fully-young mode and there are free regions in the heap
 
+    double survivor_regions_evac_time =
+        predict_survivor_regions_evac_time();
+
     size_t min_so_length = 0;
     size_t max_so_length = 0;
 
@@ -497,9 +526,8 @@
       scanned_cards = predict_non_young_card_num(adj_rs_lengths);
     // calculate this once, so that we don't have to recalculate it in
     // the innermost loop
-    double base_time_ms = predict_base_elapsed_time_ms(pending_cards,
-                                                       scanned_cards);
-
+    double base_time_ms = predict_base_elapsed_time_ms(pending_cards, scanned_cards)
+                          + survivor_regions_evac_time;
     // the result
     size_t final_young_length = 0;
     size_t final_so_length = 0;
@@ -548,14 +576,14 @@
     bool done = false;
     // this is the outermost loop
     while (!done) {
-#if 0
+#ifdef TRACE_CALC_YOUNG_CONFIG
       // leave this in for debugging, just in case
       gclog_or_tty->print_cr("searching between " SIZE_FORMAT " and " SIZE_FORMAT
                              ", incr " SIZE_FORMAT ", pass %s",
                              from_so_length, to_so_length, so_length_incr,
                              (pass == pass_type_coarse) ? "coarse" :
                              (pass == pass_type_fine) ? "fine" : "final");
-#endif // 0
+#endif // TRACE_CALC_YOUNG_CONFIG
 
       size_t so_length = from_so_length;
       size_t init_free_regions =
@@ -651,11 +679,11 @@
           guarantee( so_length_incr == so_coarse_increments, "invariant" );
           guarantee( final_so_length >= min_so_length, "invariant" );
 
-#if 0
+#ifdef TRACE_CALC_YOUNG_CONFIG
           // leave this in for debugging, just in case
           gclog_or_tty->print_cr("  coarse pass: SO length " SIZE_FORMAT,
                                  final_so_length);
-#endif // 0
+#endif // TRACE_CALC_YOUNG_CONFIG
 
           from_so_length =
             (final_so_length - min_so_length > so_coarse_increments) ?
@@ -687,12 +715,12 @@
             // of the optimal
             size_t new_so_length = 950 * final_so_length / 1000;
 
-#if 0
+#ifdef TRACE_CALC_YOUNG_CONFIG
             // leave this in for debugging, just in case
             gclog_or_tty->print_cr("  fine pass: SO length " SIZE_FORMAT
                                    ", setting it to " SIZE_FORMAT,
                                     final_so_length, new_so_length);
-#endif // 0
+#endif // TRACE_CALC_YOUNG_CONFIG
 
             from_so_length = new_so_length;
             to_so_length = new_so_length;
@@ -719,7 +747,8 @@
     }
 
     // we should have at least one region in the target young length
-    _young_list_target_length = MAX2((size_t) 1, final_young_length);
+    _young_list_target_length =
+        MAX2((size_t) 1, final_young_length + _recorded_survivor_regions);
     if (final_so_length >= final_young_length)
       // and we need to ensure that the S-O length is not greater than
       // the target young length (this is being a bit careful)
@@ -734,7 +763,7 @@
     double end_time_sec = os::elapsedTime();
     double elapsed_time_ms = (end_time_sec - start_time_sec) * 1000.0;
 
-#if 0
+#ifdef TRACE_CALC_YOUNG_CONFIG
     // leave this in for debugging, just in case
     gclog_or_tty->print_cr("target = %1.1lf ms, young = " SIZE_FORMAT
                            ", SO = " SIZE_FORMAT ", "
@@ -747,9 +776,9 @@
                            calculations,
                            full_young_gcs() ? "full" : "partial",
                            should_initiate_conc_mark() ? " i-m" : "",
-                           in_marking_window(),
-                           in_marking_window_im());
-#endif // 0
+                           _in_marking_window,
+                           _in_marking_window_im);
+#endif // TRACE_CALC_YOUNG_CONFIG
 
     if (_young_list_target_length < _young_list_min_length) {
       // bummer; this means that, if we do a pause when the optimal
@@ -768,14 +797,14 @@
         // S-O length
         so_length = calculate_optimal_so_length(_young_list_min_length);
 
-#if 0
+#ifdef TRACE_CALC_YOUNG_CONFIG
       // leave this in for debugging, just in case
       gclog_or_tty->print_cr("adjusted target length from "
                              SIZE_FORMAT " to " SIZE_FORMAT
                              ", SO " SIZE_FORMAT,
                              _young_list_target_length, _young_list_min_length,
                              so_length);
-#endif // 0
+#endif // TRACE_CALC_YOUNG_CONFIG
 
       _young_list_target_length =
         MAX2(_young_list_min_length, (size_t)1);
@@ -785,12 +814,12 @@
     // we are in a partially-young mode or we've run out of regions (due
     // to evacuation failure)
 
-#if 0
+#ifdef TRACE_CALC_YOUNG_CONFIG
     // leave this in for debugging, just in case
     gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT
                            ", SO " SIZE_FORMAT,
                            _young_list_min_length, 0);
-#endif // 0
+#endif // TRACE_CALC_YOUNG_CONFIG
 
     // we'll do the pause as soon as possible and with no S-O prefix
     // (see above for the reasons behind the latter)
@@ -884,6 +913,16 @@
   return true;
 }
 
+double G1CollectorPolicy::predict_survivor_regions_evac_time() {
+  double survivor_regions_evac_time = 0.0;
+  for (HeapRegion * r = _recorded_survivor_head;
+       r != NULL && r != _recorded_survivor_tail->get_next_young_region();
+       r = r->get_next_young_region()) {
+    survivor_regions_evac_time += predict_region_elapsed_time_ms(r, true);
+  }
+  return survivor_regions_evac_time;
+}
+
 void G1CollectorPolicy::check_prediction_validity() {
   guarantee( adaptive_young_list_length(), "should not call this otherwise" );
 
@@ -995,11 +1034,15 @@
   _short_lived_surv_rate_group->start_adding_regions();
   // also call this on any additional surv rate groups
 
+  record_survivor_regions(0, NULL, NULL);
+
   _prev_region_num_young   = _region_num_young;
   _prev_region_num_tenured = _region_num_tenured;
 
   _free_regions_at_end_of_collection = _g1->free_regions();
   _scan_only_regions_at_end_of_collection = 0;
+  // Reset survivors SurvRateGroup.
+  _survivor_surv_rate_group->reset();
   calculate_young_list_min_length();
   calculate_young_list_target_config();
  }
@@ -1104,6 +1147,10 @@
   _short_lived_surv_rate_group->record_scan_only_prefix(short_lived_so_length);
   tag_scan_only(short_lived_so_length);
 
+  if (G1UseSurvivorSpace) {
+    _survivors_age_table.clear();
+  }
+
   assert( verify_young_ages(), "region age verification" );
 }
 
@@ -1965,9 +2012,6 @@
   // </NEW PREDICTION>
 
   _target_pause_time_ms = -1.0;
-
-  // TODO: calculate tenuring threshold
-  _tenuring_threshold = MaxTenuringThreshold;
 }
 
 // <NEW PREDICTION>
@@ -2058,7 +2102,7 @@
     guarantee( hr->is_young() && hr->age_in_surv_rate_group() != -1,
                "invariant" );
     int age = hr->age_in_surv_rate_group();
-    double yg_surv_rate = predict_yg_surv_rate(age);
+    double yg_surv_rate = predict_yg_surv_rate(age, hr->surv_rate_group());
     bytes_to_copy = (size_t) ((double) hr->used() * yg_surv_rate);
   }
 
@@ -2091,7 +2135,7 @@
   }
 #if PREDICTIONS_VERBOSE
   if (young) {
-    _recorded_young_bytes += hr->asSpace()->used();
+    _recorded_young_bytes += hr->used();
   } else {
     _recorded_marked_bytes += hr->max_live_bytes();
   }
@@ -2119,11 +2163,6 @@
       predict_non_young_card_num(_predicted_rs_lengths);
   _recorded_region_num = _recorded_young_regions + _recorded_non_young_regions;
 
-  _predicted_young_survival_ratio = 0.0;
-  for (int i = 0; i < _recorded_young_regions; ++i)
-    _predicted_young_survival_ratio += predict_yg_surv_rate(i);
-  _predicted_young_survival_ratio /= (double) _recorded_young_regions;
-
   _predicted_scan_only_scan_time_ms =
     predict_scan_only_time_ms(_recorded_scan_only_regions);
   _predicted_rs_update_time_ms =
@@ -2673,8 +2712,11 @@
   assert(in_young_gc_mode(), "should be in young GC mode");
   bool ret;
   size_t young_list_length = _g1->young_list_length();
-
-  if (young_list_length < _young_list_target_length) {
+  size_t young_list_max_length = _young_list_target_length;
+  if (G1FixedEdenSize) {
+    young_list_max_length -= _max_survivor_regions;
+  }
+  if (young_list_length < young_list_max_length) {
     ret = true;
     ++_region_num_young;
   } else {
@@ -2710,17 +2752,39 @@
 }
 
 
-uint G1CollectorPolicy::max_regions(int purpose) {
+size_t G1CollectorPolicy::max_regions(int purpose) {
   switch (purpose) {
     case GCAllocForSurvived:
-      return G1MaxSurvivorRegions;
+      return _max_survivor_regions;
     case GCAllocForTenured:
-      return UINT_MAX;
+      return REGIONS_UNLIMITED;
     default:
-      return UINT_MAX;
+      ShouldNotReachHere();
+      return REGIONS_UNLIMITED;
   };
 }
 
+// Calculates survivor space parameters.
+void G1CollectorPolicy::calculate_survivors_policy()
+{
+  if (!G1UseSurvivorSpace) {
+    return;
+  }
+  if (G1FixedSurvivorSpaceSize == 0) {
+    _max_survivor_regions = _young_list_target_length / SurvivorRatio;
+  } else {
+    _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
+  }
+
+  if (G1FixedTenuringThreshold) {
+    _tenuring_threshold = MaxTenuringThreshold;
+  } else {
+    _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
+        HeapRegion::GrainWords * _max_survivor_regions);
+  }
+}
+
+
 void
 G1CollectorPolicy_BestRegionsFirst::
 set_single_region_collection_set(HeapRegion* hr) {
@@ -2743,7 +2807,11 @@
   double max_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
 
   size_t young_list_length = _g1->young_list_length();
-  bool reached_target_length = young_list_length >= _young_list_target_length;
+  size_t young_list_max_length = _young_list_target_length;
+  if (G1FixedEdenSize) {
+    young_list_max_length -= _max_survivor_regions;
+  }
+  bool reached_target_length = young_list_length >= young_list_max_length;
 
   if (in_young_gc_mode()) {
     if (reached_target_length) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -49,7 +49,7 @@
 class MainBodySummary;
 class PopPreambleSummary;
 
-class PauseSummary {
+class PauseSummary: public CHeapObj {
   define_num_seq(total)
     define_num_seq(other)
 
@@ -58,7 +58,7 @@
   virtual PopPreambleSummary* pop_preamble_summary() { return NULL; }
 };
 
-class MainBodySummary {
+class MainBodySummary: public CHeapObj {
   define_num_seq(satb_drain) // optional
   define_num_seq(parallel) // parallel only
     define_num_seq(ext_root_scan)
@@ -75,7 +75,7 @@
   define_num_seq(clear_ct)  // parallel only
 };
 
-class PopPreambleSummary {
+class PopPreambleSummary: public CHeapObj {
   define_num_seq(pop_preamble)
     define_num_seq(pop_update_rs)
     define_num_seq(pop_scan_rs)
@@ -557,6 +557,8 @@
     return get_new_neg_prediction(_young_gc_eff_seq);
   }
 
+  double predict_survivor_regions_evac_time();
+
   // </NEW PREDICTION>
 
 public:
@@ -599,8 +601,8 @@
 
   // Returns an estimate of the survival rate of the region at yg-age
   // "yg_age".
-  double predict_yg_surv_rate(int age) {
-    TruncatedSeq* seq = _short_lived_surv_rate_group->get_seq(age);
+  double predict_yg_surv_rate(int age, SurvRateGroup* surv_rate_group) {
+    TruncatedSeq* seq = surv_rate_group->get_seq(age);
     if (seq->num() == 0)
       gclog_or_tty->print("BARF! age is %d", age);
     guarantee( seq->num() > 0, "invariant" );
@@ -610,6 +612,10 @@
     return pred;
   }
 
+  double predict_yg_surv_rate(int age) {
+    return predict_yg_surv_rate(age, _short_lived_surv_rate_group);
+  }
+
   double accum_yg_surv_rate_pred(int age) {
     return _short_lived_surv_rate_group->accum_surv_rate_pred(age);
   }
@@ -822,6 +828,9 @@
 
   virtual void init();
 
+  // Create jstat counters for the policy.
+  virtual void initialize_gc_policy_counters();
+
   virtual HeapWord* mem_allocate_work(size_t size,
                                       bool is_tlab,
                                       bool* gc_overhead_limit_was_exceeded);
@@ -1047,8 +1056,12 @@
   // Print stats on young survival ratio
   void print_yg_surv_rate_info() const;
 
-  void finished_recalculating_age_indexes() {
-    _short_lived_surv_rate_group->finished_recalculating_age_indexes();
+  void finished_recalculating_age_indexes(bool is_survivors) {
+    if (is_survivors) {
+      _survivor_surv_rate_group->finished_recalculating_age_indexes();
+    } else {
+      _short_lived_surv_rate_group->finished_recalculating_age_indexes();
+    }
     // do that for any other surv rate groups
   }
 
@@ -1097,6 +1110,17 @@
   // maximum amount of suvivors regions.
   int _tenuring_threshold;
 
+  // The limit on the number of regions allocated for survivors.
+  size_t _max_survivor_regions;
+
+  // The amount of survor regions after a collection.
+  size_t _recorded_survivor_regions;
+  // List of survivor regions.
+  HeapRegion* _recorded_survivor_head;
+  HeapRegion* _recorded_survivor_tail;
+
+  ageTable _survivors_age_table;
+
 public:
 
   inline GCAllocPurpose
@@ -1116,7 +1140,9 @@
     return GCAllocForTenured;
   }
 
-  uint max_regions(int purpose);
+  static const size_t REGIONS_UNLIMITED = ~(size_t)0;
+
+  size_t max_regions(int purpose);
 
   // The limit on regions for a particular purpose is reached.
   void note_alloc_region_limit_reached(int purpose) {
@@ -1132,6 +1158,23 @@
   void note_stop_adding_survivor_regions() {
     _survivor_surv_rate_group->stop_adding_regions();
   }
+
+  void record_survivor_regions(size_t      regions,
+                               HeapRegion* head,
+                               HeapRegion* tail) {
+    _recorded_survivor_regions = regions;
+    _recorded_survivor_head    = head;
+    _recorded_survivor_tail    = tail;
+  }
+
+  void record_thread_age_table(ageTable* age_table)
+  {
+    _survivors_age_table.merge_par(age_table);
+  }
+
+  // Calculates survivor space parameters.
+  void calculate_survivors_policy();
+
 };
 
 // This encapsulates a particular strategy for a g1 Collector.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -28,7 +28,7 @@
 /***** ALL TIMES ARE IN SECS!!!!!!! *****/
 
 // this is the "interface"
-class G1MMUTracker {
+class G1MMUTracker: public CHeapObj {
 protected:
   double          _time_slice;
   double          _max_gc_time; // this is per time slice
@@ -67,7 +67,7 @@
   }
 };
 
-class G1MMUTrackerQueueElem {
+class G1MMUTrackerQueueElem VALUE_OBJ_CLASS_SPEC {
 private:
   double _start_time;
   double _end_time;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -572,6 +572,9 @@
   }
   guarantee( _cards_scanned == NULL, "invariant" );
   _cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers());
+  for (uint i = 0; i < n_workers(); ++i) {
+    _cards_scanned[i] = 0;
+  }
   _total_cards_scanned = 0;
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -30,7 +30,7 @@
 class HRInto_G1RemSet;
 class ConcurrentG1Refine;
 
-class G1RemSet {
+class G1RemSet: public CHeapObj {
 protected:
   G1CollectedHeap* _g1;
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -281,7 +281,17 @@
   develop(bool, G1HRRSFlushLogBuffersOnVerify, false,                       \
           "Forces flushing of log buffers before verification.")            \
                                                                             \
-  product(intx, G1MaxSurvivorRegions, 0,                                    \
-          "The maximum number of survivor regions")
+  product(bool, G1UseSurvivorSpace, true,                                   \
+          "When true, use survivor space.")                                 \
+                                                                            \
+  product(bool, G1FixedTenuringThreshold, false,                            \
+          "When set, G1 will not adjust the tenuring threshold")            \
+                                                                            \
+  product(bool, G1FixedEdenSize, false,                                     \
+          "When set, G1 will not allocate unused survivor space regions")   \
+                                                                            \
+  product(uintx, G1FixedSurvivorSpaceSize, 0,                               \
+          "If non-0 is the size of the G1 survivor space, "                 \
+          "otherwise SurvivorRatio is used to determine the size")
 
 G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -566,7 +566,11 @@
   void note_end_of_copying() {
     assert(top() >= _next_top_at_mark_start,
            "Increase only");
-    _next_top_at_mark_start = top();
+    // Survivor regions will be scanned on the start of concurrent
+    // marking.
+    if (!is_survivor()) {
+      _next_top_at_mark_start = top();
+    }
   }
 
   // Returns "false" iff no object in the region was allocated when the
@@ -829,7 +833,7 @@
 
 // A linked lists of heap regions.  It leaves the "next" field
 // unspecified; that's up to subtypes.
-class RegionList {
+class RegionList VALUE_OBJ_CLASS_SPEC {
 protected:
   virtual HeapRegion* get_next(HeapRegion* chr) = 0;
   virtual void set_next(HeapRegion* chr,
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -65,9 +65,11 @@
   // We need access in order to union things into the base table.
   BitMap* bm() { return &_bm; }
 
+#if PRT_COUNT_OCCUPIED
   void recount_occupied() {
     _occupied = (jint) bm()->count_one_bits();
   }
+#endif
 
   PerRegionTable(HeapRegion* hr) :
     _hr(hr),
@@ -1144,7 +1146,9 @@
   size_t i = _outgoing_region_map.get_next_one_offset(0);
   while (i < _outgoing_region_map.size()) {
     HeapRegion* to_region = g1h->region_at(i);
-    to_region->rem_set()->clear_incoming_entry(hr());
+    if (!to_region->in_collection_set()) {
+      to_region->rem_set()->clear_incoming_entry(hr());
+    }
     i = _outgoing_region_map.get_next_one_offset(i+1);
   }
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -58,7 +58,7 @@
 //      is represented.  If a deleted PRT is re-used, a thread adding a bit,
 //      thinking the PRT is for a different region, does no harm.
 
-class OtherRegionsTable: public CHeapObj {
+class OtherRegionsTable VALUE_OBJ_CLASS_SPEC {
   friend class HeapRegionRemSetIterator;
 
   G1CollectedHeap* _g1h;
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -29,7 +29,7 @@
 
 class PtrQueueSet;
 
-class PtrQueue: public CHeapObj {
+class PtrQueue VALUE_OBJ_CLASS_SPEC {
 
 protected:
   // The ptr queue set to which this queue belongs.
@@ -130,7 +130,7 @@
 // In particular, the individual queues allocate buffers from this shared
 // set, and return completed buffers to the set.
 // All these variables are are protected by the TLOQ_CBL_mon. XXX ???
-class PtrQueueSet: public CHeapObj {
+class PtrQueueSet VALUE_OBJ_CLASS_SPEC {
 
 protected:
 
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -33,7 +33,7 @@
 // old versions synchronously.
 
 
-class SparsePRTEntry {
+class SparsePRTEntry: public CHeapObj {
 public:
   enum SomePublicConstants {
     CardsPerEntry = (short)4,
@@ -167,7 +167,7 @@
 };
 
   // ValueObj because will be embedded in HRRS iterator.
-class RSHashTableIter: public CHeapObj {
+class RSHashTableIter VALUE_OBJ_CLASS_SPEC {
     short _tbl_ind;
     short _bl_ind;
     short _card_ind;
@@ -213,7 +213,7 @@
 
 class SparsePRTIter;
 
-class SparsePRT : public CHeapObj {
+class SparsePRT VALUE_OBJ_CLASS_SPEC {
   //  Iterations are done on the _cur hash table, since they only need to
   //  see entries visible at the start of a collection pause.
   //  All other operations are done using the _next hash table.
--- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -29,23 +29,14 @@
                              const char* name,
                              size_t summary_surv_rates_len) :
     _g1p(g1p), _name(name),
-    _all_regions_allocated(0),
-    _curr_length(0), _scan_only_prefix(0), _setup_seq_num(0),
-    _array_length(0), _surv_rate(NULL), _accum_surv_rate_pred(NULL),
-    _accum_surv_rate(0.0), _surv_rate_pred(NULL), _last_pred(0.0),
     _summary_surv_rates_len(summary_surv_rates_len),
     _summary_surv_rates_max_len(0),
-    _summary_surv_rates(NULL) {
-
-  // the following will set up the arrays with length 1
-  _curr_length = 1;
-  stop_adding_regions();
-  guarantee( _array_length == 1, "invariant" );
-  guarantee( _surv_rate_pred[0] != NULL, "invariant" );
-  _surv_rate_pred[0]->add(0.4);
-  all_surviving_words_recorded(false);
-  _curr_length = 0;
-
+    _summary_surv_rates(NULL),
+    _surv_rate(NULL),
+    _accum_surv_rate_pred(NULL),
+    _surv_rate_pred(NULL)
+{
+  reset();
   if (summary_surv_rates_len > 0) {
     size_t length = summary_surv_rates_len;
       _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length);
@@ -60,61 +51,80 @@
   start_adding_regions();
 }
 
+
+void SurvRateGroup::reset()
+{
+  _all_regions_allocated = 0;
+  _scan_only_prefix      = 0;
+  _setup_seq_num         = 0;
+  _stats_arrays_length   = 0;
+  _accum_surv_rate       = 0.0;
+  _last_pred             = 0.0;
+  // the following will set up the arrays with length 1
+  _region_num            = 1;
+  stop_adding_regions();
+  guarantee( _stats_arrays_length == 1, "invariant" );
+  guarantee( _surv_rate_pred[0] != NULL, "invariant" );
+  _surv_rate_pred[0]->add(0.4);
+  all_surviving_words_recorded(false);
+  _region_num = 0;
+}
+
+
 void
 SurvRateGroup::start_adding_regions() {
-  _setup_seq_num   = _array_length;
-  _curr_length     = _scan_only_prefix;
+  _setup_seq_num   = _stats_arrays_length;
+  _region_num      = _scan_only_prefix;
   _accum_surv_rate = 0.0;
 
 #if 0
-  gclog_or_tty->print_cr("start adding regions, seq num %d, length %d",
-                         _setup_seq_num, _curr_length);
+  gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d",
+                         _name, _setup_seq_num, _region_num);
 #endif // 0
 }
 
 void
 SurvRateGroup::stop_adding_regions() {
-  size_t length = _curr_length;
 
 #if 0
-  gclog_or_tty->print_cr("stop adding regions, length %d", length);
+  gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num);
 #endif // 0
 
-  if (length > _array_length) {
+  if (_region_num > _stats_arrays_length) {
     double* old_surv_rate = _surv_rate;
     double* old_accum_surv_rate_pred = _accum_surv_rate_pred;
     TruncatedSeq** old_surv_rate_pred = _surv_rate_pred;
 
-    _surv_rate = NEW_C_HEAP_ARRAY(double, length);
+    _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num);
     if (_surv_rate == NULL) {
-      vm_exit_out_of_memory(sizeof(double) * length,
+      vm_exit_out_of_memory(sizeof(double) * _region_num,
                             "Not enough space for surv rate array.");
     }
-    _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, length);
+    _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num);
     if (_accum_surv_rate_pred == NULL) {
-      vm_exit_out_of_memory(sizeof(double) * length,
+      vm_exit_out_of_memory(sizeof(double) * _region_num,
                          "Not enough space for accum surv rate pred array.");
     }
-    _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, length);
+    _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num);
     if (_surv_rate == NULL) {
-      vm_exit_out_of_memory(sizeof(TruncatedSeq*) * length,
+      vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num,
                             "Not enough space for surv rate pred array.");
     }
 
-    for (size_t i = 0; i < _array_length; ++i)
+    for (size_t i = 0; i < _stats_arrays_length; ++i)
       _surv_rate_pred[i] = old_surv_rate_pred[i];
 
 #if 0
-    gclog_or_tty->print_cr("stop adding regions, new seqs %d to %d",
-                  _array_length, length - 1);
+    gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d",
+                  _name, _array_length, _region_num - 1);
 #endif // 0
 
-    for (size_t i = _array_length; i < length; ++i) {
+    for (size_t i = _stats_arrays_length; i < _region_num; ++i) {
       _surv_rate_pred[i] = new TruncatedSeq(10);
       // _surv_rate_pred[i]->add(last_pred);
     }
 
-    _array_length = length;
+    _stats_arrays_length = _region_num;
 
     if (old_surv_rate != NULL)
       FREE_C_HEAP_ARRAY(double, old_surv_rate);
@@ -124,7 +134,7 @@
       FREE_C_HEAP_ARRAY(NumberSeq*, old_surv_rate_pred);
   }
 
-  for (size_t i = 0; i < _array_length; ++i)
+  for (size_t i = 0; i < _stats_arrays_length; ++i)
     _surv_rate[i] = 0.0;
 }
 
@@ -135,7 +145,7 @@
 
   double ret = _accum_surv_rate;
   if (adjustment > 0) {
-    TruncatedSeq* seq = get_seq(_curr_length+1);
+    TruncatedSeq* seq = get_seq(_region_num+1);
     double surv_rate = _g1p->get_new_prediction(seq);
     ret += surv_rate;
   }
@@ -145,23 +155,23 @@
 
 int
 SurvRateGroup::next_age_index() {
-  TruncatedSeq* seq = get_seq(_curr_length);
+  TruncatedSeq* seq = get_seq(_region_num);
   double surv_rate = _g1p->get_new_prediction(seq);
   _accum_surv_rate += surv_rate;
 
-  ++_curr_length;
+  ++_region_num;
   return (int) ++_all_regions_allocated;
 }
 
 void
 SurvRateGroup::record_scan_only_prefix(size_t scan_only_prefix) {
-  guarantee( scan_only_prefix <= _curr_length, "pre-condition" );
+  guarantee( scan_only_prefix <= _region_num, "pre-condition" );
   _scan_only_prefix = scan_only_prefix;
 }
 
 void
 SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) {
-  guarantee( 0 <= age_in_group && (size_t) age_in_group < _curr_length,
+  guarantee( 0 <= age_in_group && (size_t) age_in_group < _region_num,
              "pre-condition" );
   guarantee( _surv_rate[age_in_group] <= 0.00001,
              "should only update each slot once" );
@@ -178,15 +188,15 @@
 
 void
 SurvRateGroup::all_surviving_words_recorded(bool propagate) {
-  if (propagate && _curr_length > 0) { // conservative
-    double surv_rate = _surv_rate_pred[_curr_length-1]->last();
+  if (propagate && _region_num > 0) { // conservative
+    double surv_rate = _surv_rate_pred[_region_num-1]->last();
 
 #if 0
     gclog_or_tty->print_cr("propagating %1.2lf from %d to %d",
                   surv_rate, _curr_length, _array_length - 1);
 #endif // 0
 
-    for (size_t i = _curr_length; i < _array_length; ++i) {
+    for (size_t i = _region_num; i < _stats_arrays_length; ++i) {
       guarantee( _surv_rate[i] <= 0.00001,
                  "the slot should not have been updated" );
       _surv_rate_pred[i]->add(surv_rate);
@@ -195,7 +205,7 @@
 
   double accum = 0.0;
   double pred = 0.0;
-  for (size_t i = 0; i < _array_length; ++i) {
+  for (size_t i = 0; i < _stats_arrays_length; ++i) {
     pred = _g1p->get_new_prediction(_surv_rate_pred[i]);
     if (pred > 1.0) pred = 1.0;
     accum += pred;
@@ -209,8 +219,8 @@
 void
 SurvRateGroup::print() {
   gclog_or_tty->print_cr("Surv Rate Group: %s (%d entries, %d scan-only)",
-                _name, _curr_length, _scan_only_prefix);
-  for (size_t i = 0; i < _curr_length; ++i) {
+                _name, _region_num, _scan_only_prefix);
+  for (size_t i = 0; i < _region_num; ++i) {
     gclog_or_tty->print_cr("    age %4d   surv rate %6.2lf %%   pred %6.2lf %%%s",
                   i, _surv_rate[i] * 100.0,
                   _g1p->get_new_prediction(_surv_rate_pred[i]) * 100.0,
--- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -29,7 +29,7 @@
   G1CollectorPolicy* _g1p;
   const char* _name;
 
-  size_t  _array_length;
+  size_t  _stats_arrays_length;
   double* _surv_rate;
   double* _accum_surv_rate_pred;
   double  _last_pred;
@@ -40,7 +40,7 @@
   size_t         _summary_surv_rates_max_len;
 
   int _all_regions_allocated;
-  size_t _curr_length;
+  size_t _region_num;
   size_t _scan_only_prefix;
   size_t _setup_seq_num;
 
@@ -48,6 +48,7 @@
   SurvRateGroup(G1CollectorPolicy* g1p,
                 const char* name,
                 size_t summary_surv_rates_len);
+  void reset();
   void start_adding_regions();
   void stop_adding_regions();
   void record_scan_only_prefix(size_t scan_only_prefix);
@@ -55,22 +56,21 @@
   void all_surviving_words_recorded(bool propagate);
   const char* name() { return _name; }
 
-  size_t region_num() { return _curr_length; }
+  size_t region_num() { return _region_num; }
   size_t scan_only_length() { return _scan_only_prefix; }
   double accum_surv_rate_pred(int age) {
     assert(age >= 0, "must be");
-    if ((size_t)age < _array_length)
+    if ((size_t)age < _stats_arrays_length)
       return _accum_surv_rate_pred[age];
     else {
-      double diff = (double) (age - _array_length + 1);
-      return _accum_surv_rate_pred[_array_length-1] + diff * _last_pred;
+      double diff = (double) (age - _stats_arrays_length + 1);
+      return _accum_surv_rate_pred[_stats_arrays_length-1] + diff * _last_pred;
     }
   }
 
   double accum_surv_rate(size_t adjustment);
 
   TruncatedSeq* get_seq(size_t age) {
-    guarantee( 0 <= age, "pre-condition" );
     if (age >= _setup_seq_num) {
       guarantee( _setup_seq_num > 0, "invariant" );
       age = _setup_seq_num-1;
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1	Wed Jul 05 16:47:51 2017 +0200
@@ -48,6 +48,7 @@
 concurrentG1Refine.cpp			space.inline.hpp
 
 concurrentG1Refine.hpp			globalDefinitions.hpp
+concurrentG1Refine.hpp			allocation.hpp
 
 concurrentG1RefineThread.cpp		concurrentG1Refine.hpp
 concurrentG1RefineThread.cpp		concurrentG1RefineThread.hpp
@@ -172,6 +173,7 @@
 g1CollectorPolicy.cpp                   g1CollectorPolicy.hpp
 g1CollectorPolicy.cpp                   heapRegionRemSet.hpp
 g1CollectorPolicy.cpp			mutexLocker.hpp
+g1CollectorPolicy.cpp			gcPolicyCounters.hpp
 
 g1CollectorPolicy.hpp                   collectorPolicy.hpp
 g1CollectorPolicy.hpp                   collectionSetChooser.hpp
@@ -228,7 +230,7 @@
 g1MMUTracker.cpp			mutexLocker.hpp
 
 g1MMUTracker.hpp			debug.hpp
-
+g1MMUTracker.hpp			allocation.hpp
 g1RemSet.cpp				bufferingOopClosure.hpp
 g1RemSet.cpp				concurrentG1Refine.hpp
 g1RemSet.cpp				concurrentG1RefineThread.hpp
@@ -272,6 +274,7 @@
 heapRegion.hpp                          watermark.hpp
 heapRegion.hpp				g1_specialized_oop_closures.hpp
 heapRegion.hpp				survRateGroup.hpp
+heapRegion.hpp				ageTable.hpp
 
 heapRegionRemSet.hpp			sparsePRT.hpp
 
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -362,6 +362,10 @@
   if (PrintHeapAtGC) {
     Universe::print_heap_after_gc();
   }
+
+#ifdef TRACESPINNING
+  ParallelTaskTerminator::print_termination_counts();
+#endif
 }
 
 bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -2203,6 +2203,10 @@
                            collection_exit.ticks());
     gc_task_manager()->print_task_time_stamps();
   }
+
+#ifdef TRACESPINNING
+  ParallelTaskTerminator::print_termination_counts();
+#endif
 }
 
 bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -615,6 +615,10 @@
     gc_task_manager()->print_task_time_stamps();
   }
 
+#ifdef TRACESPINNING
+  ParallelTaskTerminator::print_termination_counts();
+#endif
+
   return !promotion_failure_occurred;
 }
 
--- a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -67,6 +67,12 @@
   }
 }
 
+void ageTable::merge_par(ageTable* subTable) {
+  for (int i = 0; i < table_size; i++) {
+    Atomic::add_ptr(subTable->sizes[i], &sizes[i]);
+  }
+}
+
 int ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
   size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
   size_t total = 0;
--- a/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -56,6 +56,7 @@
   // Merge another age table with the current one.  Used
   // for parallel young generation gc.
   void merge(ageTable* subTable);
+  void merge_par(ageTable* subTable);
 
   // calculate new tenuring threshold based on age information
   int compute_tenuring_threshold(size_t survivor_capacity);
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -42,6 +42,7 @@
 class CollectedHeap : public CHeapObj {
   friend class VMStructs;
   friend class IsGCActiveMark; // Block structured external access to _is_gc_active
+  friend class constantPoolCacheKlass; // allocate() method inserts is_conc_safe
 
 #ifdef ASSERT
   static int       _fire_out_of_memory_count;
@@ -82,8 +83,6 @@
   // Reinitialize tlabs before resuming mutators.
   virtual void resize_all_tlabs();
 
-  debug_only(static void check_for_valid_allocation_state();)
-
  protected:
   // Allocate from the current thread's TLAB, with broken-out slow path.
   inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size);
@@ -142,6 +141,7 @@
     PRODUCT_RETURN;
   virtual void check_for_non_bad_heap_word_value(HeapWord* addr, size_t size)
     PRODUCT_RETURN;
+  debug_only(static void check_for_valid_allocation_state();)
 
  public:
   enum Name {
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -48,9 +48,14 @@
 
 
 // Creates a constant pool cache given an inverse_index_map
+// This creates the constant pool cache initially in a state
+// that is unsafe for concurrent GC processing but sets it to
+// a safe mode before the constant pool cache is returned.
 constantPoolCacheHandle Rewriter::new_constant_pool_cache(intArray& inverse_index_map, TRAPS) {
   const int length = inverse_index_map.length();
-  constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length, CHECK_(constantPoolCacheHandle()));
+  constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length,
+                                             methodOopDesc::IsUnsafeConc,
+                                             CHECK_(constantPoolCacheHandle()));
   cache->initialize(inverse_index_map);
   return constantPoolCacheHandle(THREAD, cache);
 }
--- a/hotspot/src/share/vm/libadt/dict.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/libadt/dict.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -346,9 +346,12 @@
   return strcmp((const char *)k1,(const char *)k2);
 }
 
-// Slimey cheap key comparator.
+// Cheap key comparator.
 int32 cmpkey(const void *key1, const void *key2) {
-  return (int32)((intptr_t)key1 - (intptr_t)key2);
+  if (key1 == key2) return 0;
+  intptr_t delta = (intptr_t)key1 - (intptr_t)key2;
+  if (delta > 0) return 1;
+  return -1;
 }
 
 //=============================================================================
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -610,6 +610,10 @@
     Universe::print_heap_after_gc();
   }
 
+#ifdef TRACESPINNING
+  ParallelTaskTerminator::print_termination_counts();
+#endif
+
   if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) {
     tty->print_cr("Stopping after GC #%d", ExitAfterGCNum);
     vm_exit(-1);
--- a/hotspot/src/share/vm/memory/oopFactory.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/memory/oopFactory.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -90,9 +90,11 @@
 }
 
 
-constantPoolCacheOop oopFactory::new_constantPoolCache(int length, TRAPS) {
+constantPoolCacheOop oopFactory::new_constantPoolCache(int length,
+                                                       bool is_conc_safe,
+                                                       TRAPS) {
   constantPoolCacheKlass* ck = constantPoolCacheKlass::cast(Universe::constantPoolCacheKlassObj());
-  return ck->allocate(length, CHECK_NULL);
+  return ck->allocate(length, is_conc_safe, CHECK_NULL);
 }
 
 
--- a/hotspot/src/share/vm/memory/oopFactory.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/memory/oopFactory.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -84,7 +84,9 @@
   static constantPoolOop      new_constantPool     (int length,
                                                     bool is_conc_safe,
                                                     TRAPS);
-  static constantPoolCacheOop new_constantPoolCache(int length, TRAPS);
+  static constantPoolCacheOop new_constantPoolCache(int length,
+                                                    bool is_conc_safe,
+                                                    TRAPS);
 
   // Instance classes
   static klassOop        new_instanceKlass(int vtable_len, int itable_len, int static_field_size,
--- a/hotspot/src/share/vm/oops/cpCacheKlass.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/oops/cpCacheKlass.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -32,13 +32,43 @@
 }
 
 
-constantPoolCacheOop constantPoolCacheKlass::allocate(int length, TRAPS) {
+constantPoolCacheOop constantPoolCacheKlass::allocate(int length,
+                                                      bool is_conc_safe,
+                                                      TRAPS) {
   // allocate memory
   int size = constantPoolCacheOopDesc::object_size(length);
+
   KlassHandle klass (THREAD, as_klassOop());
-  constantPoolCacheOop cache = (constantPoolCacheOop)
-    CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
+
+  // This is the original code.  The code from permanent_obj_allocate()
+  // was in-lined to allow the setting of is_conc_safe before the klass
+  // is installed.
+  // constantPoolCacheOop cache = (constantPoolCacheOop)
+  //   CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
+
+  oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
+  constantPoolCacheOop cache = (constantPoolCacheOop) obj;
+  cache->set_is_conc_safe(is_conc_safe);
+  // The store to is_conc_safe must be visible before the klass
+  // is set.  This should be done safely because _is_conc_safe has
+  // been declared volatile.  If there are any problems, consider adding
+  // OrderAccess::storestore();
+  CollectedHeap::post_allocation_install_obj_klass(klass, obj, size);
+  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
+                                                              size));
+
+  // The length field affects the size of the object.  The allocation
+  // above allocates the correct size (see calculation of "size") but
+  // the size() method of the constant pool cache oop will not reflect
+  // that size until the correct length is set.
   cache->set_length(length);
+
+  // The store of the length must be visible before is_conc_safe is
+  // set to a safe state.
+  // This should be done safely because _is_conc_safe has
+  // been declared volatile.  If there are any problems, consider adding
+  // OrderAccess::storestore();
+  cache->set_is_conc_safe(methodOopDesc::IsSafeConc);
   cache->set_constant_pool(NULL);
   return cache;
 }
@@ -114,7 +144,6 @@
   return size;
 }
 
-
 int constantPoolCacheKlass::oop_adjust_pointers(oop obj) {
   assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
   constantPoolCacheOop cache = (constantPoolCacheOop)obj;
@@ -131,6 +160,11 @@
   return size;
 }
 
+bool constantPoolCacheKlass::oop_is_conc_safe(oop obj) const {
+  assert(obj->is_constantPoolCache(), "should be constant pool");
+  return constantPoolCacheOop(obj)->is_conc_safe();
+}
+
 #ifndef SERIALGC
 void constantPoolCacheKlass::oop_copy_contents(PSPromotionManager* pm,
                                                oop obj) {
--- a/hotspot/src/share/vm/oops/cpCacheKlass.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/oops/cpCacheKlass.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -32,7 +32,7 @@
 
   // Allocation
   DEFINE_ALLOCATE_PERMANENT(constantPoolCacheKlass);
-  constantPoolCacheOop allocate(int length, TRAPS);
+  constantPoolCacheOop allocate(int length, bool is_conc_safe, TRAPS);
   static klassOop create_klass(TRAPS);
 
   // Casting from klassOop
@@ -48,6 +48,7 @@
   // Garbage collection
   void oop_follow_contents(oop obj);
   int oop_adjust_pointers(oop obj);
+  virtual bool oop_is_conc_safe(oop obj) const;
 
   // Parallel Scavenge and Parallel Old
   PARALLEL_GC_DECLS
--- a/hotspot/src/share/vm/oops/cpCacheOop.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/oops/cpCacheOop.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -291,6 +291,9 @@
  private:
   int             _length;
   constantPoolOop _constant_pool;                // the corresponding constant pool
+  // If true, safe for concurrent GC processing,
+  // Set unconditionally in constantPoolCacheKlass::allocate()
+  volatile bool        _is_conc_safe;
 
   // Sizing
   debug_only(friend class ClassVerifier;)
@@ -316,6 +319,12 @@
   constantPoolOop constant_pool() const          { return _constant_pool; }
   ConstantPoolCacheEntry* entry_at(int i) const  { assert(0 <= i && i < length(), "index out of bounds"); return base() + i; }
 
+  // GC support
+  // If the _length field has not been set, the size of the
+  // constantPoolCache cannot be correctly calculated.
+  bool is_conc_safe()                            { return _is_conc_safe; }
+  void set_is_conc_safe(bool v)                  { _is_conc_safe = v; }
+
   // Code generation
   static ByteSize base_offset()                  { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); }
 
--- a/hotspot/src/share/vm/opto/block.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/block.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -880,6 +880,7 @@
 }
 
 void PhaseCFG::verify( ) const {
+#ifdef ASSERT
   // Verify sane CFG
   for( uint i = 0; i < _num_blocks; i++ ) {
     Block *b = _blocks[i];
@@ -894,10 +895,20 @@
                 "CreateEx must be first instruction in block" );
       }
       for( uint k = 0; k < n->req(); k++ ) {
-        Node *use = n->in(k);
-        if( use && use != n ) {
-          assert( _bbs[use->_idx] || use->is_Con(),
+        Node *def = n->in(k);
+        if( def && def != n ) {
+          assert( _bbs[def->_idx] || def->is_Con(),
                   "must have block; constants for debug info ok" );
+          // Verify that instructions in the block is in correct order.
+          // Uses must follow their definition if they are at the same block.
+          // Mostly done to check that MachSpillCopy nodes are placed correctly
+          // when CreateEx node is moved in build_ifg_physical().
+          if( _bbs[def->_idx] == b &&
+              !(b->head()->is_Loop() && n->is_Phi()) &&
+              // See (+++) comment in reg_split.cpp
+              !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) {
+            assert( b->find_node(def) < j, "uses must follow definitions" );
+          }
         }
       }
     }
@@ -914,6 +925,7 @@
       assert( b->_num_succs == 2, "Conditional branch must have two targets");
     }
   }
+#endif
 }
 #endif
 
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -191,6 +191,9 @@
   notproduct(bool, VerifyHashTableKeys, true,                               \
           "Verify the immutability of keys in the VN hash tables")          \
                                                                             \
+  notproduct(bool, VerifyRegisterAllocator , false,                         \
+          "Verify Register Allocator")                                      \
+                                                                            \
   develop_pd(intx, FLOATPRESSURE,                                           \
           "Number of float LRG's that constitute high register pressure")   \
                                                                             \
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -858,12 +858,18 @@
   // convert the one to the other.
   const TypePtr* ttp = _type->make_ptr();
   const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL;
+  const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_klassptr() : NULL;
   bool is_intf = false;
   if (ttip != NULL) {
     ciKlass* k = ttip->klass();
     if (k->is_loaded() && k->is_interface())
       is_intf = true;
   }
+  if (ttkp != NULL) {
+    ciKlass* k = ttkp->klass();
+    if (k->is_loaded() && k->is_interface())
+      is_intf = true;
+  }
 
   // Default case: merge all inputs
   const Type *t = Type::TOP;        // Merged type starting value
@@ -921,6 +927,8 @@
     // uplift the type.
     if( !t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface() )
       { assert(ft == _type, ""); } // Uplift to interface
+    else if( !t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface() )
+      { assert(ft == _type, ""); } // Uplift to interface
     // Otherwise it's something stupid like non-overlapping int ranges
     // found on dying counted loops.
     else
@@ -936,6 +944,7 @@
     // because the type system doesn't interact well with interfaces.
     const TypePtr *jtp = jt->make_ptr();
     const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL;
+    const TypeKlassPtr *jtkp = (jtp != NULL) ? jtp->isa_klassptr() : NULL;
     if( jtip && ttip ) {
       if( jtip->is_loaded() &&  jtip->klass()->is_interface() &&
           ttip->is_loaded() && !ttip->klass()->is_interface() ) {
@@ -945,6 +954,14 @@
         jt = ft;
       }
     }
+    if( jtkp && ttkp ) {
+      if( jtkp->is_loaded() &&  jtkp->klass()->is_interface() &&
+          ttkp->is_loaded() && !ttkp->klass()->is_interface() ) {
+        assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) ||
+               ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), "");
+        jt = ft;
+      }
+    }
     if (jt != ft && jt->base() == ft->base()) {
       if (jt->isa_int() &&
           jt->is_int()->_lo == ft->is_int()->_lo &&
--- a/hotspot/src/share/vm/opto/chaitin.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/chaitin.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -228,6 +228,11 @@
   // them for real.
   de_ssa();
 
+#ifdef ASSERT
+  // Veify the graph before RA.
+  verify(&live_arena);
+#endif
+
   {
     NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
     _live = NULL;                 // Mark live as being not available
@@ -306,12 +311,6 @@
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
     if (C->failing())  return;
 
-#ifdef ASSERT
-    if( VerifyOpto ) {
-      _cfg.verify();
-      verify_base_ptrs(&live_arena);
-    }
-#endif
     NOT_PRODUCT( C->verify_graph_edges(); )
 
     compact();                  // Compact LRGs; return new lower max lrg
@@ -340,7 +339,7 @@
     compress_uf_map_for_nodes();
 
 #ifdef ASSERT
-    if( VerifyOpto ) _ifg->verify(this);
+    verify(&live_arena, true);
 #endif
   } else {
     ifg.SquareUp();
@@ -376,12 +375,6 @@
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
     if (C->failing())  return;
-#ifdef ASSERT
-    if( VerifyOpto ) {
-      _cfg.verify();
-      verify_base_ptrs(&live_arena);
-    }
-#endif
 
     compact();                  // Compact LRGs; return new lower max lrg
 
@@ -412,7 +405,7 @@
     }
     compress_uf_map_for_nodes();
 #ifdef ASSERT
-    if( VerifyOpto ) _ifg->verify(this);
+    verify(&live_arena, true);
 #endif
     cache_lrg_info();           // Count degree of LRGs
 
@@ -432,6 +425,11 @@
   // Peephole remove copies
   post_allocate_copy_removal();
 
+#ifdef ASSERT
+  // Veify the graph after RA.
+  verify(&live_arena);
+#endif
+
   // max_reg is past the largest *register* used.
   // Convert that to a frame_slot number.
   if( _max_reg <= _matcher._new_SP )
@@ -956,7 +954,7 @@
       while ((neighbor = elements.next()) != 0) {
         LRG *n = &lrgs(neighbor);
 #ifdef ASSERT
-        if( VerifyOpto ) {
+        if( VerifyOpto || VerifyRegisterAllocator ) {
           assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
         }
 #endif
--- a/hotspot/src/share/vm/opto/chaitin.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/chaitin.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -491,6 +491,8 @@
   // Verify that base pointers and derived pointers are still sane
   void verify_base_ptrs( ResourceArea *a ) const;
 
+  void verify( ResourceArea *a, bool verify_ifg = false ) const;
+
   void dump_for_spill_split_recycle() const;
 
 public:
--- a/hotspot/src/share/vm/opto/classes.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/classes.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -129,7 +129,7 @@
 macro(LShiftI)
 macro(LShiftL)
 macro(LoadB)
-macro(LoadC)
+macro(LoadUS)
 macro(LoadD)
 macro(LoadD_unaligned)
 macro(LoadF)
--- a/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -2005,7 +2005,7 @@
   case Op_StoreP:
   case Op_StoreN:
   case Op_LoadB:
-  case Op_LoadC:
+  case Op_LoadUS:
   case Op_LoadI:
   case Op_LoadKlass:
   case Op_LoadNKlass:
--- a/hotspot/src/share/vm/opto/divnode.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/divnode.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -244,42 +244,73 @@
 
 //---------------------long_by_long_mulhi--------------------------------------
 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication
-static Node *long_by_long_mulhi( PhaseGVN *phase, Node *dividend, jlong magic_const) {
+static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) {
   // If the architecture supports a 64x64 mulhi, there is
   // no need to synthesize it in ideal nodes.
   if (Matcher::has_match_rule(Op_MulHiL)) {
-    Node *v = phase->longcon(magic_const);
+    Node* v = phase->longcon(magic_const);
     return new (phase->C, 3) MulHiLNode(dividend, v);
   }
 
+  // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed.
+  // (http://www.hackersdelight.org/HDcode/mulhs.c)
+  //
+  // int mulhs(int u, int v) {
+  //    unsigned u0, v0, w0;
+  //    int u1, v1, w1, w2, t;
+  //
+  //    u0 = u & 0xFFFF;  u1 = u >> 16;
+  //    v0 = v & 0xFFFF;  v1 = v >> 16;
+  //    w0 = u0*v0;
+  //    t  = u1*v0 + (w0 >> 16);
+  //    w1 = t & 0xFFFF;
+  //    w2 = t >> 16;
+  //    w1 = u0*v1 + w1;
+  //    return u1*v1 + w2 + (w1 >> 16);
+  // }
+  //
+  // Note: The version above is for 32x32 multiplications, while the
+  // following inline comments are adapted to 64x64.
+
   const int N = 64;
 
-  Node *u_hi = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
-  Node *u_lo = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
+  // u0 = u & 0xFFFFFFFF;  u1 = u >> 32;
+  Node* u0 = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
+  Node* u1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
+
+  // v0 = v & 0xFFFFFFFF;  v1 = v >> 32;
+  Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF);
+  Node* v1 = phase->longcon(magic_const >> (N / 2));
 
-  Node *v_hi = phase->longcon(magic_const >> N/2);
-  Node *v_lo = phase->longcon(magic_const & 0XFFFFFFFF);
+  // w0 = u0*v0;
+  Node* w0 = phase->transform(new (phase->C, 3) MulLNode(u0, v0));
 
-  Node *hihi_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_hi));
-  Node *hilo_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_lo));
-  Node *lohi_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_hi));
-  Node *lolo_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_lo));
+  // t = u1*v0 + (w0 >> 32);
+  Node* u1v0 = phase->transform(new (phase->C, 3) MulLNode(u1, v0));
+  Node* temp = phase->transform(new (phase->C, 3) URShiftLNode(w0, phase->intcon(N / 2)));
+  Node* t    = phase->transform(new (phase->C, 3) AddLNode(u1v0, temp));
+
+  // w1 = t & 0xFFFFFFFF;
+  Node* w1 = new (phase->C, 3) AndLNode(t, phase->longcon(0xFFFFFFFF));
 
-  Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2)));
-  Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1));
+  // w2 = t >> 32;
+  Node* w2 = new (phase->C, 3) RShiftLNode(t, phase->intcon(N / 2));
+
+  // 6732154: Construct both w1 and w2 before transforming, so t
+  // doesn't go dead prematurely.
+  w1 = phase->transform(w1);
+  w2 = phase->transform(w2);
 
-  // Construct both t3 and t4 before transforming so t2 doesn't go dead
-  // prematurely.
-  Node *t3 = new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2));
-  Node *t4 = new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF));
-  t3 = phase->transform(t3);
-  t4 = phase->transform(t4);
+  // w1 = u0*v1 + w1;
+  Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1));
+  w1         = phase->transform(new (phase->C, 3) AddLNode(u0v1, w1));
 
-  Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product));
-  Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2)));
-  Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product));
+  // return u1*v1 + w2 + (w1 >> 32);
+  Node* u1v1  = phase->transform(new (phase->C, 3) MulLNode(u1, v1));
+  Node* temp1 = phase->transform(new (phase->C, 3) AddLNode(u1v1, w2));
+  Node* temp2 = phase->transform(new (phase->C, 3) RShiftLNode(w1, phase->intcon(N / 2)));
 
-  return new (phase->C, 3) AddLNode(t7, t6);
+  return new (phase->C, 3) AddLNode(temp1, temp2);
 }
 
 
@@ -976,7 +1007,7 @@
 
   // Expand mod
   if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) {
-    uint k = log2_long(con);       // Extract k
+    uint k = exact_log2_long(con+1);  // Extract k
 
     // Basic algorithm by David Detlefs.  See fastmod_long.java for gory details.
     // Used to help a popular random number generator which does a long-mod
--- a/hotspot/src/share/vm/opto/gcm.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -29,6 +29,9 @@
 #include "incls/_precompiled.incl"
 #include "incls/_gcm.cpp.incl"
 
+// To avoid float value underflow
+#define MIN_BLOCK_FREQUENCY 1.e-35f
+
 //----------------------------schedule_node_into_block-------------------------
 // Insert node n into block b. Look for projections of n and make sure they
 // are in b also.
@@ -1380,6 +1383,13 @@
     }
   }
 
+#ifdef ASSERT
+  for (uint i = 0; i < _num_blocks; i++ ) {
+    Block *b = _blocks[i];
+    assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requiers meaningful block frequency");
+  }
+#endif
+
 #ifndef PRODUCT
   if (PrintCFGBlockFreq) {
     tty->print_cr("CFG Block Frequencies");
@@ -1877,7 +1887,9 @@
   float loop_freq = _freq * trip_count();
   for (int i = 0; i < _members.length(); i++) {
     CFGElement* s = _members.at(i);
-    s->_freq *= loop_freq;
+    float block_freq = s->_freq * loop_freq;
+    if (block_freq < MIN_BLOCK_FREQUENCY) block_freq = MIN_BLOCK_FREQUENCY;
+    s->_freq = block_freq;
   }
   CFGLoop* ch = _child;
   while (ch != NULL) {
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -1836,10 +1836,7 @@
     (CardTableModRefBS*)(Universe::heap()->barrier_set());
   Node *b = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) ));
   // We store into a byte array, so do not bother to left-shift by zero
-  // Get base of card map
-  assert(sizeof(*ct->byte_map_base) == sizeof(jbyte),
-         "adjust this code");
-  Node *c = makecon(TypeRawPtr::make((address)ct->byte_map_base));
+  Node *c = byte_map_base_node();
   // Combine
   Node *sb_ctl = control();
   Node *sb_adr = _gvn.transform(new (C, 4) AddPNode( top()/*no base ptr*/, c, b ));
@@ -2945,16 +2942,10 @@
 
   // Now generate allocation code
 
-  // With escape analysis, the entire memory state is needed to be able to
-  // eliminate the allocation.  If the allocations cannot be eliminated, this
-  // will be optimized to the raw slice when the allocation is expanded.
-  Node *mem;
-  if (C->do_escape_analysis()) {
-    mem = reset_memory();
-    set_all_memory(mem);
-  } else {
-    mem = memory(Compile::AliasIdxRaw);
-  }
+  // The entire memory state is needed for slow path of the allocation
+  // since GC and deoptimization can happened.
+  Node *mem = reset_memory();
+  set_all_memory(mem); // Create new memory state
 
   AllocateNode* alloc
     = new (C, AllocateNode::ParmLimit)
@@ -3091,16 +3082,10 @@
 
   // Now generate allocation code
 
-  // With escape analysis, the entire memory state is needed to be able to
-  // eliminate the allocation.  If the allocations cannot be eliminated, this
-  // will be optimized to the raw slice when the allocation is expanded.
-  Node *mem;
-  if (C->do_escape_analysis()) {
-    mem = reset_memory();
-    set_all_memory(mem);
-  } else {
-    mem = memory(Compile::AliasIdxRaw);
-  }
+  // The entire memory state is needed for slow path of the allocation
+  // since GC and deoptimization can happened.
+  Node *mem = reset_memory();
+  set_all_memory(mem); // Create new memory state
 
   // Create the AllocateArrayNode and its result projections
   AllocateArrayNode* alloc
@@ -3233,12 +3218,11 @@
 
   // Now some of the values
 
-  Node* marking = __ load(no_ctrl, marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
-  Node* index   = __ load(no_ctrl, index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw);
-  Node* buffer  = __ load(no_ctrl, buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
+  Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
 
   // if (!marking)
   __ if_then(marking, BoolTest::ne, zero); {
+    Node* index   = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw);
 
     const Type* t1 = adr->bottom_type();
     const Type* t2 = val->bottom_type();
@@ -3246,6 +3230,7 @@
     Node* orig = __ load(no_ctrl, adr, val_type, bt, alias_idx);
     // if (orig != NULL)
     __ if_then(orig, BoolTest::ne, null()); {
+      Node* buffer  = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
 
       // load original value
       // alias_idx correct??
@@ -3365,14 +3350,6 @@
 
   const TypeFunc *tf = OptoRuntime::g1_wb_post_Type();
 
-  // Get the address of the card table
-  CardTableModRefBS* ct =
-    (CardTableModRefBS*)(Universe::heap()->barrier_set());
-  Node *card_table = __ makecon(TypeRawPtr::make((address)ct->byte_map_base));
-  // Get base of card map
-  assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
-
-
   // Offsets into the thread
   const int index_offset  = in_bytes(JavaThread::dirty_card_queue_offset() +
                                      PtrQueue::byte_offset_of_index());
@@ -3402,7 +3379,7 @@
   Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
 
   // Combine card table base and card offset
-  Node *card_adr = __ AddP(no_base, card_table, card_offset );
+  Node *card_adr = __ AddP(no_base, byte_map_base_node(), card_offset );
 
   // If we know the value being stored does it cross regions?
 
--- a/hotspot/src/share/vm/opto/graphKit.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/graphKit.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -83,6 +83,18 @@
   Node* zerocon(BasicType bt)   const { return _gvn.zerocon(bt); }
   // (See also macro MakeConX in type.hpp, which uses intcon or longcon.)
 
+  // Helper for byte_map_base
+  Node* byte_map_base_node() {
+    // Get base of card map
+    CardTableModRefBS* ct = (CardTableModRefBS*)(Universe::heap()->barrier_set());
+    assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust users of this code");
+    if (ct->byte_map_base != NULL) {
+      return makecon(TypeRawPtr::make((address)ct->byte_map_base));
+    } else {
+      return null();
+    }
+  }
+
   jint  find_int_con(Node* n, jint value_if_unknown) {
     return _gvn.find_int_con(n, value_if_unknown);
   }
--- a/hotspot/src/share/vm/opto/ifg.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/ifg.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -471,12 +471,28 @@
     // for the "collect_gc_info" phase later.
     IndexSet liveout(_live->live(b));
     uint last_inst = b->end_idx();
-    // Compute last phi index
-    uint last_phi;
-    for( last_phi = 1; last_phi < last_inst; last_phi++ )
-      if( !b->_nodes[last_phi]->is_Phi() )
+    // Compute first nonphi node index
+    uint first_inst;
+    for( first_inst = 1; first_inst < last_inst; first_inst++ )
+      if( !b->_nodes[first_inst]->is_Phi() )
         break;
 
+    // Spills could be inserted before CreateEx node which should be
+    // first instruction in block after Phis. Move CreateEx up.
+    for( uint insidx = first_inst; insidx < last_inst; insidx++ ) {
+      Node *ex = b->_nodes[insidx];
+      if( ex->is_SpillCopy() ) continue;
+      if( insidx > first_inst && ex->is_Mach() &&
+          ex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
+        // If the CreateEx isn't above all the MachSpillCopies
+        // then move it to the top.
+        b->_nodes.remove(insidx);
+        b->_nodes.insert(first_inst, ex);
+      }
+      // Stop once a CreateEx or any other node is found
+      break;
+    }
+
     // Reset block's register pressure values for each ifg construction
     uint pressure[2], hrp_index[2];
     pressure[0] = pressure[1] = 0;
@@ -485,7 +501,7 @@
     // Liveout things are presumed live for the whole block.  We accumulate
     // 'area' accordingly.  If they get killed in the block, we'll subtract
     // the unused part of the block from the area.
-    int inst_count = last_inst - last_phi;
+    int inst_count = last_inst - first_inst;
     double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
     assert(!(cost < 0.0), "negative spill cost" );
     IndexSetIterator elements(&liveout);
--- a/hotspot/src/share/vm/opto/lcm.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -107,7 +107,7 @@
     was_store = false;
     switch( mach->ideal_Opcode() ) {
     case Op_LoadB:
-    case Op_LoadC:
+    case Op_LoadUS:
     case Op_LoadD:
     case Op_LoadF:
     case Op_LoadI:
--- a/hotspot/src/share/vm/opto/live.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/live.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -271,9 +271,9 @@
 
 //------------------------------verify_base_ptrs-------------------------------
 // Verify that base pointers and derived pointers are still sane.
-// Basically, if a derived pointer is live at a safepoint, then its
-// base pointer must be live also.
 void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
+#ifdef ASSERT
+  Unique_Node_List worklist(a);
   for( uint i = 0; i < _cfg._num_blocks; i++ ) {
     Block *b = _cfg._blocks[i];
     for( uint j = b->end_idx() + 1; j > 1; j-- ) {
@@ -287,28 +287,81 @@
           // Now scan for a live derived pointer
           if (jvms->oopoff() < sfpt->req()) {
             // Check each derived/base pair
-            for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx += 2) {
+            for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx++) {
               Node *check = sfpt->in(idx);
-              uint j = 0;
+              bool is_derived = ((idx - jvms->oopoff()) & 1) == 0;
               // search upwards through spills and spill phis for AddP
-              while(true) {
-                if( !check ) break;
-                int idx = check->is_Copy();
-                if( idx ) {
-                  check = check->in(idx);
-                } else if( check->is_Phi() && check->_idx >= _oldphi ) {
-                  check = check->in(1);
-                } else
-                  break;
-                j++;
-                assert(j < 100000,"Derived pointer checking in infinite loop");
+              worklist.clear();
+              worklist.push(check);
+              uint k = 0;
+              while( k < worklist.size() ) {
+                check = worklist.at(k);
+                assert(check,"Bad base or derived pointer");
+                // See PhaseChaitin::find_base_for_derived() for all cases.
+                int isc = check->is_Copy();
+                if( isc ) {
+                  worklist.push(check->in(isc));
+                } else if( check->is_Phi() ) {
+                  for (uint m = 1; m < check->req(); m++)
+                    worklist.push(check->in(m));
+                } else if( check->is_Con() ) {
+                  if (is_derived) {
+                    // Derived is NULL+offset
+                    assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer");
+                  } else {
+                    assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer");
+                    // Base either ConP(NULL) or loadConP
+                    if (check->is_Mach()) {
+                      assert(check->as_Mach()->ideal_Opcode() == Op_ConP,"Bad base pointer");
+                    } else {
+                      assert(check->Opcode() == Op_ConP &&
+                             check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer");
+                    }
+                  }
+                } else if( check->bottom_type()->is_ptr()->_offset == 0 ) {
+                  if(check->is_Proj() || check->is_Mach() &&
+                     (check->as_Mach()->ideal_Opcode() == Op_CreateEx ||
+                      check->as_Mach()->ideal_Opcode() == Op_ThreadLocal ||
+                      check->as_Mach()->ideal_Opcode() == Op_CMoveP ||
+                      check->as_Mach()->ideal_Opcode() == Op_CheckCastPP ||
+#ifdef _LP64
+                      UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP ||
+                      UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN ||
+#endif
+                      check->as_Mach()->ideal_Opcode() == Op_LoadP ||
+                      check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) {
+                    // Valid nodes
+                  } else {
+                    check->dump();
+                    assert(false,"Bad base or derived pointer");
+                  }
+                } else {
+                  assert(is_derived,"Bad base pointer");
+                  assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer");
+                }
+                k++;
+                assert(k < 100000,"Derived pointer checking in infinite loop");
               } // End while
-              assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer")
             }
           } // End of check for derived pointers
         } // End of Kcheck for debug info
       } // End of if found a safepoint
     } // End of forall instructions in block
   } // End of forall blocks
+#endif
 }
+
+//------------------------------verify-------------------------------------
+// Verify that graphs and base pointers are still sane.
+void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
+#ifdef ASSERT
+  if( VerifyOpto || VerifyRegisterAllocator ) {
+    _cfg.verify();
+    verify_base_ptrs(a);
+    if(verify_ifg)
+      _ifg->verify(this);
+  }
 #endif
+}
+
+#endif
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -2654,7 +2654,7 @@
     case Op_ModF:
     case Op_ModD:
     case Op_LoadB:              // Same with Loads; they can sink
-    case Op_LoadC:              // during loop optimizations.
+    case Op_LoadUS:             // during loop optimizations.
     case Op_LoadD:
     case Op_LoadF:
     case Op_LoadI:
--- a/hotspot/src/share/vm/opto/macro.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/macro.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -952,13 +952,6 @@
   Node* klass_node        = alloc->in(AllocateNode::KlassNode);
   Node* initial_slow_test = alloc->in(AllocateNode::InitialTest);
 
-  // With escape analysis, the entire memory state was needed to be able to
-  // eliminate the allocation.  Since the allocations cannot be eliminated,
-  // optimize it to the raw slice.
-  if (mem->is_MergeMem()) {
-    mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
-  }
-
   assert(ctrl != NULL, "must have control");
   // We need a Region and corresponding Phi's to merge the slow-path and fast-path results.
   // they will not be used if "always_slow" is set
@@ -1016,6 +1009,11 @@
   Node *slow_mem = mem;  // save the current memory state for slow path
   // generate the fast allocation code unless we know that the initial test will always go slow
   if (!always_slow) {
+    // Fast path modifies only raw memory.
+    if (mem->is_MergeMem()) {
+      mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
+    }
+
     Node* eden_top_adr;
     Node* eden_end_adr;
 
@@ -1239,8 +1237,6 @@
     }
   }
 
-  mem = result_phi_rawmem;
-
   // An allocate node has separate i_o projections for the uses on the control and i_o paths
   // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call)
   if (_ioproj_fallthrough == NULL) {
--- a/hotspot/src/share/vm/opto/matcher.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -1824,7 +1824,7 @@
         mem_op = true;
         break;
       case Op_LoadB:
-      case Op_LoadC:
+      case Op_LoadUS:
       case Op_LoadD:
       case Op_LoadF:
       case Op_LoadI:
--- a/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -779,14 +779,14 @@
          "use LoadRangeNode instead");
   switch (bt) {
   case T_BOOLEAN:
-  case T_BYTE:    return new (C, 3) LoadBNode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_INT:     return new (C, 3) LoadINode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_CHAR:    return new (C, 3) LoadCNode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_SHORT:   return new (C, 3) LoadSNode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_LONG:    return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long()   );
-  case T_FLOAT:   return new (C, 3) LoadFNode(ctl, mem, adr, adr_type, rt              );
-  case T_DOUBLE:  return new (C, 3) LoadDNode(ctl, mem, adr, adr_type, rt              );
-  case T_ADDRESS: return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_ptr()    );
+  case T_BYTE:    return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_INT:     return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_CHAR:    return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_SHORT:   return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_LONG:    return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long()   );
+  case T_FLOAT:   return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt              );
+  case T_DOUBLE:  return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt              );
+  case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr()    );
   case T_OBJECT:
 #ifdef _LP64
     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
@@ -1076,13 +1076,14 @@
       // of the original value.
       Node* mem_phi = in(Memory);
       Node* offset = in(Address)->in(AddPNode::Offset);
+      Node* region = base->in(0);
 
       Node* in1 = clone();
       Node* in1_addr = in1->in(Address)->clone();
       in1_addr->set_req(AddPNode::Base, base->in(allocation_index));
       in1_addr->set_req(AddPNode::Address, base->in(allocation_index));
       in1_addr->set_req(AddPNode::Offset, offset);
-      in1->set_req(0, base->in(allocation_index));
+      in1->set_req(0, region->in(allocation_index));
       in1->set_req(Address, in1_addr);
       in1->set_req(Memory, mem_phi->in(allocation_index));
 
@@ -1091,7 +1092,7 @@
       in2_addr->set_req(AddPNode::Base, base->in(load_index));
       in2_addr->set_req(AddPNode::Address, base->in(load_index));
       in2_addr->set_req(AddPNode::Offset, offset);
-      in2->set_req(0, base->in(load_index));
+      in2->set_req(0, region->in(load_index));
       in2->set_req(Address, in2_addr);
       in2->set_req(Memory, mem_phi->in(load_index));
 
@@ -1100,7 +1101,7 @@
       in2_addr = phase->transform(in2_addr);
       in2 =      phase->transform(in2);
 
-      PhiNode* result = PhiNode::make_blank(base->in(0), this);
+      PhiNode* result = PhiNode::make_blank(region, this);
       result->set_req(allocation_index, in1);
       result->set_req(load_index, in2);
       return result;
@@ -1303,6 +1304,7 @@
     Node*    base   = AddPNode::Ideal_base_and_offset(address, phase, ignore);
     if (base != NULL
         && phase->type(base)->higher_equal(TypePtr::NOTNULL)
+        && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw
         && all_controls_dominate(base, phase->C->start())) {
       // A method-invariant, non-null address (constant or 'this' argument).
       set_req(MemNode::Control, NULL);
@@ -1356,7 +1358,7 @@
   // Steps (a), (b):  Walk past independent stores to find an exact match.
   if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) {
     // (c) See if we can fold up on the spot, but don't fold up here.
-    // Fold-up might require truncation (for LoadB/LoadS/LoadC) or
+    // Fold-up might require truncation (for LoadB/LoadS/LoadUS) or
     // just return a prior value, which is done by Identity calls.
     if (can_see_stored_value(prev_mem, phase)) {
       // Make ready for step (d):
@@ -1605,14 +1607,14 @@
   return LoadNode::Ideal(phase, can_reshape);
 }
 
-//--------------------------LoadCNode::Ideal--------------------------------------
+//--------------------------LoadUSNode::Ideal-------------------------------------
 //
 //  If the previous store is to the same address as this load,
 //  and the value stored was larger than a char, replace this load
 //  with the value stored truncated to a char.  If no truncation is
 //  needed, the replacement is done in LoadNode::Identity().
 //
-Node *LoadCNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
   Node* mem = in(MemNode::Memory);
   Node* value = can_see_stored_value(mem,phase);
   if( value && !phase->type(value)->higher_equal( _type ) )
--- a/hotspot/src/share/vm/opto/memnode.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/memnode.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -207,11 +207,11 @@
   virtual BasicType memory_type() const { return T_BYTE; }
 };
 
-//------------------------------LoadCNode--------------------------------------
-// Load a char (16bits unsigned) from memory
-class LoadCNode : public LoadNode {
+//------------------------------LoadUSNode-------------------------------------
+// Load an unsigned short/char (16bits unsigned) from memory
+class LoadUSNode : public LoadNode {
 public:
-  LoadCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR )
+  LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR )
     : LoadNode(c,mem,adr,at,ti) {}
   virtual int Opcode() const;
   virtual uint ideal_reg() const { return Op_RegI; }
--- a/hotspot/src/share/vm/opto/mulnode.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/mulnode.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -442,16 +442,17 @@
         return load;
     }
     uint lop = load->Opcode();
-    if( lop == Op_LoadC &&
+    if( lop == Op_LoadUS &&
         con == 0x0000FFFF )     // Already zero-extended
       return load;
     // Masking off the high bits of a unsigned-shift-right is not
     // needed either.
     if( lop == Op_URShiftI ) {
       const TypeInt *t12 = phase->type( load->in(2) )->isa_int();
-      if( t12 && t12->is_con() ) {
-        int shift_con = t12->get_con();
-        int mask = max_juint >> shift_con;
+      if( t12 && t12->is_con() ) {  // Shift is by a constant
+        int shift = t12->get_con();
+        shift &= BitsPerJavaInteger - 1;  // semantics of Java shifts
+        int mask = max_juint >> shift;
         if( (mask&con) == mask )  // If AND is useless, skip it
           return load;
       }
@@ -470,19 +471,19 @@
   uint lop = load->Opcode();
 
   // Masking bits off of a Character?  Hi bits are already zero.
-  if( lop == Op_LoadC &&
+  if( lop == Op_LoadUS &&
       (mask & 0xFFFF0000) )     // Can we make a smaller mask?
     return new (phase->C, 3) AndINode(load,phase->intcon(mask&0xFFFF));
 
   // Masking bits off of a Short?  Loading a Character does some masking
   if( lop == Op_LoadS &&
       (mask & 0xFFFF0000) == 0 ) {
-    Node *ldc = new (phase->C, 3) LoadCNode(load->in(MemNode::Control),
+    Node *ldus = new (phase->C, 3) LoadUSNode(load->in(MemNode::Control),
                                   load->in(MemNode::Memory),
                                   load->in(MemNode::Address),
                                   load->adr_type());
-    ldc = phase->transform(ldc);
-    return new (phase->C, 3) AndINode(ldc,phase->intcon(mask&0xFFFF));
+    ldus = phase->transform(ldus);
+    return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF));
   }
 
   // Masking sign bits off of a Byte?  Let the matcher use an unsigned load
@@ -579,9 +580,10 @@
     // needed either.
     if( lop == Op_URShiftL ) {
       const TypeInt *t12 = phase->type( usr->in(2) )->isa_int();
-      if( t12 && t12->is_con() ) {
-        int shift_con = t12->get_con();
-        jlong mask = max_julong >> shift_con;
+      if( t12 && t12->is_con() ) {  // Shift is by a constant
+        int shift = t12->get_con();
+        shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
+        jlong mask = max_julong >> shift;
         if( (mask&con) == mask )  // If AND is useless, skip it
           return usr;
       }
@@ -605,8 +607,8 @@
     const TypeInt *t12 = phase->type(rsh->in(2))->isa_int();
     if( t12 && t12->is_con() ) { // Shift is by a constant
       int shift = t12->get_con();
-      shift &= (BitsPerJavaInteger*2)-1;  // semantics of Java shifts
-      const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - shift)) -1);
+      shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
+      const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1);
       // If the AND'ing of the 2 masks has no bits, then only original shifted
       // bits survive.  NO sign-extension bits survive the maskings.
       if( (sign_bits_mask & mask) == 0 ) {
@@ -786,7 +788,7 @@
 
   // Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits
   // before shifting them away.
-  const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - con)) - CONST64(1);
+  const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1);
   if( add1_op == Op_AndL &&
       phase->type(add1->in(2)) == TypeLong::make( bits_mask ) )
     return new (phase->C, 3) LShiftLNode( add1->in(1), in(2) );
@@ -820,7 +822,7 @@
     return TypeLong::LONG;
 
   uint shift = r2->get_con();
-  shift &= (BitsPerJavaInteger*2)-1;  // semantics of Java shifts
+  shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
   // Shift by a multiple of 64 does nothing:
   if (shift == 0)  return t1;
 
@@ -913,7 +915,7 @@
       set_req(2, phase->intcon(0));
       return this;
     }
-    else if( ld->Opcode() == Op_LoadC )
+    else if( ld->Opcode() == Op_LoadUS )
       // Replace zero-extension-load with sign-extension-load
       return new (phase->C, 3) LoadSNode( ld->in(MemNode::Control),
                                 ld->in(MemNode::Memory),
@@ -1235,7 +1237,7 @@
   if ( con == 0 ) return NULL;  // let Identity() handle a 0 shift count
                               // note: mask computation below does not work for 0 shift count
   // We'll be wanting the right-shift amount as a mask of that many bits
-  const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - con)) -1);
+  const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) -1);
 
   // Check for ((x << z) + Y) >>> z.  Replace with x + con>>>z
   // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z".
@@ -1302,7 +1304,7 @@
 
   if (r2->is_con()) {
     uint shift = r2->get_con();
-    shift &= (2*BitsPerJavaInteger)-1;  // semantics of Java shifts
+    shift &= BitsPerJavaLong - 1;  // semantics of Java shifts
     // Shift by a multiple of 64 does nothing:
     if (shift == 0)  return t1;
     // Calculate reasonably aggressive bounds for the result.
@@ -1325,7 +1327,7 @@
     const TypeLong* tl = TypeLong::make(lo, hi, MAX2(r1->_widen,r2->_widen));
     #ifdef ASSERT
     // Make sure we get the sign-capture idiom correct.
-    if (shift == (2*BitsPerJavaInteger)-1) {
+    if (shift == BitsPerJavaLong - 1) {
       if (r1->_lo >= 0) assert(tl == TypeLong::ZERO, ">>>63 of + is 0");
       if (r1->_hi < 0)  assert(tl == TypeLong::ONE,  ">>>63 of - is +1");
     }
--- a/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -1444,7 +1444,7 @@
 // (Start, end] half-open range defining which operands are vector
 void SuperWord::vector_opd_range(Node* n, uint* start, uint* end) {
   switch (n->Opcode()) {
-  case Op_LoadB:   case Op_LoadC:
+  case Op_LoadB:   case Op_LoadUS:
   case Op_LoadI:   case Op_LoadL:
   case Op_LoadF:   case Op_LoadD:
   case Op_LoadP:
--- a/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -2471,6 +2471,8 @@
   const Type* ft = join(kills);
   const TypeInstPtr* ftip = ft->isa_instptr();
   const TypeInstPtr* ktip = kills->isa_instptr();
+  const TypeKlassPtr* ftkp = ft->isa_klassptr();
+  const TypeKlassPtr* ktkp = kills->isa_klassptr();
 
   if (ft->empty()) {
     // Check for evil case of 'this' being a class and 'kills' expecting an
@@ -2484,6 +2486,8 @@
     // uplift the type.
     if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface())
       return kills;             // Uplift to interface
+    if (!empty() && ktkp != NULL && ktkp->klass()->is_loaded() && ktkp->klass()->is_interface())
+      return kills;             // Uplift to interface
 
     return Type::TOP;           // Canonical empty value
   }
@@ -2499,6 +2503,12 @@
     // Happens in a CTW of rt.jar, 320-341, no extra flags
     return ktip->cast_to_ptr_type(ftip->ptr());
   }
+  if (ftkp != NULL && ktkp != NULL &&
+      ftkp->is_loaded() &&  ftkp->klass()->is_interface() &&
+      ktkp->is_loaded() && !ktkp->klass()->is_interface()) {
+    // Happens in a CTW of rt.jar, 320-341, no extra flags
+    return ktkp->cast_to_ptr_type(ftkp->ptr());
+  }
 
   return ft;
 }
@@ -3657,7 +3667,7 @@
 
 //------------------------------cast_to_ptr_type-------------------------------
 const Type *TypeKlassPtr::cast_to_ptr_type(PTR ptr) const {
-  assert(_base == OopPtr, "subclass must override cast_to_ptr_type");
+  assert(_base == KlassPtr, "subclass must override cast_to_ptr_type");
   if( ptr == _ptr ) return this;
   return make(ptr, _klass, _offset);
 }
--- a/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -882,6 +882,8 @@
 public:
   ciSymbol* name()  const { return _klass->name(); }
 
+  bool  is_loaded() const { return _klass->is_loaded(); }
+
   // ptr to klass 'k'
   static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); }
   // ptr to klass 'k' with offset
--- a/hotspot/src/share/vm/opto/vectornode.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/opto/vectornode.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -239,7 +239,7 @@
     return Op_XorV;
 
   case Op_LoadB:
-  case Op_LoadC:
+  case Op_LoadUS:
   case Op_LoadS:
   case Op_LoadI:
   case Op_LoadL:
@@ -269,7 +269,7 @@
     case 16:       return Op_Load16B;
     }
     break;
-  case Op_LoadC:
+  case Op_LoadUS:
     switch (vlen) {
     case  2:       return Op_Load2C;
     case  4:       return Op_Load4C;
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -2489,7 +2489,7 @@
     vm_args.version = JNI_VERSION_1_2;
     vm_args.options = options;
     vm_args.nOptions = i;
-    vm_args.ignoreUnrecognized = false;
+    vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions;
 
     if (PrintVMOptions) {
       const char* tail;
@@ -2536,13 +2536,12 @@
 
   // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
   bool settings_file_specified = false;
+  const char* flags_file;
   int index;
   for (index = 0; index < args->nOptions; index++) {
     const JavaVMOption *option = args->options + index;
     if (match_option(option, "-XX:Flags=", &tail)) {
-      if (!process_settings_file(tail, true, args->ignoreUnrecognized)) {
-        return JNI_EINVAL;
-      }
+      flags_file = tail;
       settings_file_specified = true;
     }
     if (match_option(option, "-XX:+PrintVMOptions", &tail)) {
@@ -2551,6 +2550,24 @@
     if (match_option(option, "-XX:-PrintVMOptions", &tail)) {
       PrintVMOptions = false;
     }
+    if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions", &tail)) {
+      IgnoreUnrecognizedVMOptions = true;
+    }
+    if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions", &tail)) {
+      IgnoreUnrecognizedVMOptions = false;
+    }
+  }
+
+  if (IgnoreUnrecognizedVMOptions) {
+    // uncast const to modify the flag args->ignoreUnrecognized
+    *(jboolean*)(&args->ignoreUnrecognized) = true;
+  }
+
+  // Parse specified settings file
+  if (settings_file_specified) {
+    if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) {
+      return JNI_EINVAL;
+    }
   }
 
   // Parse default .hotspotrc settings file
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -1426,10 +1426,10 @@
   develop(bool, CMSOverflowEarlyRestoration, false,                         \
           "Whether preserved marks should be restored early")               \
                                                                             \
-  product(uintx, CMSMarkStackSize, 32*K,                                    \
+  product(uintx, CMSMarkStackSize, NOT_LP64(32*K) LP64_ONLY(4*M),           \
           "Size of CMS marking stack")                                      \
                                                                             \
-  product(uintx, CMSMarkStackSizeMax, 4*M,                                  \
+  product(uintx, CMSMarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M),       \
           "Max size of CMS marking stack")                                  \
                                                                             \
   notproduct(bool, CMSMarkStackOverflowALot, false,                         \
@@ -1655,6 +1655,13 @@
   develop(uintx, WorkStealingYieldsBeforeSleep, 1000,                       \
           "Number of yields before a sleep is done during workstealing")    \
                                                                             \
+  develop(uintx, WorkStealingHardSpins, 4096,                               \
+          "Number of iterations in a spin loop between checks on "          \
+          "time out of hard spin")                                          \
+                                                                            \
+  develop(uintx, WorkStealingSpinToYieldRatio, 10,                          \
+          "Ratio of hard spins to calls to yield")                          \
+                                                                            \
   product(uintx, PreserveMarkStackSize, 1024,                               \
            "Size for stack used in promotion failure handling")             \
                                                                             \
@@ -2187,6 +2194,9 @@
   product(bool, PrintVMOptions, trueInDebug,                                \
          "print VM flag settings")                                          \
                                                                             \
+  product(bool, IgnoreUnrecognizedVMOptions, false,                         \
+         "Ignore unrecognized VM options")                                  \
+                                                                            \
   diagnostic(bool, SerializeVMOutput, true,                                 \
          "Use a mutex to serialize output to tty and hotspot.log")          \
                                                                             \
--- a/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -74,13 +74,11 @@
   const int milliseconds_after_second =
     milliseconds_since_19700101 % milliseconds_per_microsecond;
   // Convert the time value to a tm and timezone variable
-  const struct tm *time_struct_temp = localtime(&seconds_since_19700101);
-  if (time_struct_temp == NULL) {
-    assert(false, "Failed localtime");
+  struct tm time_struct;
+  if (localtime_pd(&seconds_since_19700101, &time_struct) == NULL) {
+    assert(false, "Failed localtime_pd");
     return NULL;
   }
-  // Save the results of localtime
-  const struct tm time_struct = *time_struct_temp;
   const time_t zone = timezone;
 
   // If daylight savings time is in effect,
@@ -93,10 +91,10 @@
     UTC_to_local = UTC_to_local - seconds_per_hour;
   }
   // Compute the time zone offset.
-  //    localtime(3C) sets timezone to the difference (in seconds)
+  //    localtime_pd() sets timezone to the difference (in seconds)
   //    between UTC and and local time.
   //    ISO 8601 says we need the difference between local time and UTC,
-  //    we change the sign of the localtime(3C) result.
+  //    we change the sign of the localtime_pd() result.
   const time_t local_to_UTC = -(UTC_to_local);
   // Then we have to figure out if if we are ahead (+) or behind (-) UTC.
   char sign_local_to_UTC = '+';
--- a/hotspot/src/share/vm/runtime/os.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/runtime/os.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -120,7 +120,8 @@
   // Return current local time in a string (YYYY-MM-DD HH:MM:SS).
   // It is MT safe, but not async-safe, as reading time zone
   // information may require a lock on some platforms.
-  static char* local_time_string(char *buf, size_t buflen);
+  static char*      local_time_string(char *buf, size_t buflen);
+  static struct tm* localtime_pd     (const time_t* clock, struct tm*  res);
   // Fill in buffer with current local time as an ISO-8601 string.
   // E.g., YYYY-MM-DDThh:mm:ss.mmm+zzzz.
   // Returns buffer, or NULL if it failed.
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,6 +74,7 @@
 extern int BitsPerHeapOop;
 
 const int BitsPerJavaInteger = 32;
+const int BitsPerJavaLong    = 64;
 const int BitsPerSize_t      = size_tSize * BitsPerByte;
 
 // Size of a char[] needed to represent a jint as a string in decimal.
@@ -906,6 +907,14 @@
   return log2_intptr(x);
 }
 
+//* the argument must be exactly a power of 2
+inline int exact_log2_long(jlong x) {
+  #ifdef ASSERT
+    if (!is_power_of_2_long(x)) basic_fatal("x must be a power of 2");
+  #endif
+  return log2_long(x);
+}
+
 
 // returns integer round-up to the nearest multiple of s (s must be a power of two)
 inline intptr_t round_to(intptr_t x, uintx s) {
--- a/hotspot/src/share/vm/utilities/taskqueue.cpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/utilities/taskqueue.cpp	Wed Jul 05 16:47:51 2017 +0200
@@ -25,6 +25,12 @@
 # include "incls/_precompiled.incl"
 # include "incls/_taskqueue.cpp.incl"
 
+#ifdef TRACESPINNING
+uint ParallelTaskTerminator::_total_yields = 0;
+uint ParallelTaskTerminator::_total_spins = 0;
+uint ParallelTaskTerminator::_total_peeks = 0;
+#endif
+
 bool TaskQueueSuper::peek() {
   return _bottom != _age.top();
 }
@@ -69,15 +75,62 @@
 ParallelTaskTerminator::offer_termination(TerminatorTerminator* terminator) {
   Atomic::inc(&_offered_termination);
 
-  juint yield_count = 0;
+  uint yield_count = 0;
+  // Number of hard spin loops done since last yield
+  uint hard_spin_count = 0;
+  // Number of iterations in the hard spin loop.
+  uint hard_spin_limit = WorkStealingHardSpins;
+
+  // If WorkStealingSpinToYieldRatio is 0, no hard spinning is done.
+  // If it is greater than 0, then start with a small number
+  // of spins and increase number with each turn at spinning until
+  // the count of hard spins exceeds WorkStealingSpinToYieldRatio.
+  // Then do a yield() call and start spinning afresh.
+  if (WorkStealingSpinToYieldRatio > 0) {
+    hard_spin_limit = WorkStealingHardSpins >> WorkStealingSpinToYieldRatio;
+    hard_spin_limit = MAX2(hard_spin_limit, 1U);
+  }
+  // Remember the initial spin limit.
+  uint hard_spin_start = hard_spin_limit;
+
+  // Loop waiting for all threads to offer termination or
+  // more work.
   while (true) {
+    // Are all threads offering termination?
     if (_offered_termination == _n_threads) {
-      //inner_termination_loop();
       return true;
     } else {
+      // Look for more work.
+      // Periodically sleep() instead of yield() to give threads
+      // waiting on the cores the chance to grab this code
       if (yield_count <= WorkStealingYieldsBeforeSleep) {
+        // Do a yield or hardspin.  For purposes of deciding whether
+        // to sleep, count this as a yield.
         yield_count++;
-        yield();
+
+        // Periodically call yield() instead spinning
+        // After WorkStealingSpinToYieldRatio spins, do a yield() call
+        // and reset the counts and starting limit.
+        if (hard_spin_count > WorkStealingSpinToYieldRatio) {
+          yield();
+          hard_spin_count = 0;
+          hard_spin_limit = hard_spin_start;
+#ifdef TRACESPINNING
+          _total_yields++;
+#endif
+        } else {
+          // Hard spin this time
+          // Increase the hard spinning period but only up to a limit.
+          hard_spin_limit = MIN2(2*hard_spin_limit,
+                                 (uint) WorkStealingHardSpins);
+          for (uint j = 0; j < hard_spin_limit; j++) {
+            SpinPause();
+          }
+          hard_spin_count++;
+#ifdef TRACESPINNING
+          _total_spins++;
+#endif
+        }
       } else {
         if (PrintGCDetails && Verbose) {
          gclog_or_tty->print_cr("ParallelTaskTerminator::offer_termination() "
@@ -92,6 +145,9 @@
         sleep(WorkStealingSleepMillis);
       }
 
+#ifdef TRACESPINNING
+      _total_peeks++;
+#endif
       if (peek_in_queue_set() ||
           (terminator != NULL && terminator->should_exit_termination())) {
         Atomic::dec(&_offered_termination);
@@ -101,6 +157,16 @@
   }
 }
 
+#ifdef TRACESPINNING
+void ParallelTaskTerminator::print_termination_counts() {
+  gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: %lld  "
+    "Total spins: %lld  Total peeks: %lld",
+    total_yields(),
+    total_spins(),
+    total_peeks());
+}
+#endif
+
 void ParallelTaskTerminator::reset_for_reuse() {
   if (_offered_termination != 0) {
     assert(_offered_termination == _n_threads,
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -22,67 +22,76 @@
  *
  */
 
+#ifdef LP64
+typedef juint TAG_TYPE;
+// for a taskqueue size of 4M
+#define LOG_TASKQ_SIZE 22
+#else
+typedef jushort TAG_TYPE;
+// for a taskqueue size of 16K
+#define LOG_TASKQ_SIZE 14
+#endif
+
 class TaskQueueSuper: public CHeapObj {
 protected:
   // The first free element after the last one pushed (mod _n).
-  // (For now we'll assume only 32-bit CAS).
-  volatile juint _bottom;
+  volatile uint _bottom;
 
   // log2 of the size of the queue.
   enum SomeProtectedConstants {
-    Log_n = 14
+    Log_n = LOG_TASKQ_SIZE
   };
+#undef LOG_TASKQ_SIZE
 
   // Size of the queue.
-  juint n() { return (1 << Log_n); }
+  uint n() { return (1 << Log_n); }
   // For computing "x mod n" efficiently.
-  juint n_mod_mask() { return n() - 1; }
+  uint n_mod_mask() { return n() - 1; }
 
   struct Age {
-    jushort _top;
-    jushort _tag;
+    TAG_TYPE _top;
+    TAG_TYPE _tag;
 
-    jushort tag() const { return _tag; }
-    jushort top() const { return _top; }
+    TAG_TYPE tag() const { return _tag; }
+    TAG_TYPE top() const { return _top; }
 
     Age() { _tag = 0; _top = 0; }
 
     friend bool operator ==(const Age& a1, const Age& a2) {
       return a1.tag() == a2.tag() && a1.top() == a2.top();
     }
-
   };
   Age _age;
   // These make sure we do single atomic reads and writes.
   Age get_age() {
-    jint res = *(volatile jint*)(&_age);
+    uint res = *(volatile uint*)(&_age);
     return *(Age*)(&res);
   }
   void set_age(Age a) {
-    *(volatile jint*)(&_age) = *(int*)(&a);
+    *(volatile uint*)(&_age) = *(uint*)(&a);
   }
 
-  jushort get_top() {
+  TAG_TYPE get_top() {
     return get_age().top();
   }
 
   // These both operate mod _n.
-  juint increment_index(juint ind) {
+  uint increment_index(uint ind) {
     return (ind + 1) & n_mod_mask();
   }
-  juint decrement_index(juint ind) {
+  uint decrement_index(uint ind) {
     return (ind - 1) & n_mod_mask();
   }
 
   // Returns a number in the range [0.._n).  If the result is "n-1", it
   // should be interpreted as 0.
-  juint dirty_size(juint bot, juint top) {
-    return ((jint)bot - (jint)top) & n_mod_mask();
+  uint dirty_size(uint bot, uint top) {
+    return ((int)bot - (int)top) & n_mod_mask();
   }
 
   // Returns the size corresponding to the given "bot" and "top".
-  juint size(juint bot, juint top) {
-    juint sz = dirty_size(bot, top);
+  uint size(uint bot, uint top) {
+    uint sz = dirty_size(bot, top);
     // Has the queue "wrapped", so that bottom is less than top?
     // There's a complicated special case here.  A pair of threads could
     // perform pop_local and pop_global operations concurrently, starting
@@ -94,7 +103,7 @@
     // owner performs pop_local's, and several concurrent threads
     // attempting to perform the pop_global will all perform the same CAS,
     // and only one can succeed.  Any stealing thread that reads after
-    // either the increment or decrement will seen an empty queue, and will
+    // either the increment or decrement will see an empty queue, and will
     // not join the competitors.  The "sz == -1 || sz == _n-1" state will
     // not be modified  by concurrent queues, so the owner thread can reset
     // the state to _bottom == top so subsequent pushes will be performed
@@ -112,11 +121,11 @@
   // Return an estimate of the number of elements in the queue.
   // The "careful" version admits the possibility of pop_local/pop_global
   // races.
-  juint size() {
+  uint size() {
     return size(_bottom, get_top());
   }
 
-  juint dirty_size() {
+  uint dirty_size() {
     return dirty_size(_bottom, get_top());
   }
 
@@ -127,15 +136,15 @@
 
   // Maximum number of elements allowed in the queue.  This is two less
   // than the actual queue size, for somewhat complicated reasons.
-  juint max_elems() { return n() - 2; }
+  uint max_elems() { return n() - 2; }
 
 };
 
 template<class E> class GenericTaskQueue: public TaskQueueSuper {
 private:
   // Slow paths for push, pop_local.  (pop_global has no fast path.)
-  bool push_slow(E t, juint dirty_n_elems);
-  bool pop_local_slow(juint localBot, Age oldAge);
+  bool push_slow(E t, uint dirty_n_elems);
+  bool pop_local_slow(uint localBot, Age oldAge);
 
 public:
   // Initializes the queue to empty.
@@ -170,7 +179,7 @@
 
 template<class E>
 GenericTaskQueue<E>::GenericTaskQueue():TaskQueueSuper() {
-  assert(sizeof(Age) == sizeof(jint), "Depends on this.");
+  assert(sizeof(Age) == sizeof(int), "Depends on this.");
 }
 
 template<class E>
@@ -182,9 +191,9 @@
 template<class E>
 void GenericTaskQueue<E>::oops_do(OopClosure* f) {
   // tty->print_cr("START OopTaskQueue::oops_do");
-  int iters = size();
-  juint index = _bottom;
-  for (int i = 0; i < iters; ++i) {
+  uint iters = size();
+  uint index = _bottom;
+  for (uint i = 0; i < iters; ++i) {
     index = decrement_index(index);
     // tty->print_cr("  doing entry %d," INTPTR_T " -> " INTPTR_T,
     //            index, &_elems[index], _elems[index]);
@@ -198,10 +207,10 @@
 
 
 template<class E>
-bool GenericTaskQueue<E>::push_slow(E t, juint dirty_n_elems) {
+bool GenericTaskQueue<E>::push_slow(E t, uint dirty_n_elems) {
   if (dirty_n_elems == n() - 1) {
     // Actually means 0, so do the push.
-    juint localBot = _bottom;
+    uint localBot = _bottom;
     _elems[localBot] = t;
     _bottom = increment_index(localBot);
     return true;
@@ -211,7 +220,7 @@
 
 template<class E>
 bool GenericTaskQueue<E>::
-pop_local_slow(juint localBot, Age oldAge) {
+pop_local_slow(uint localBot, Age oldAge) {
   // This queue was observed to contain exactly one element; either this
   // thread will claim it, or a competing "pop_global".  In either case,
   // the queue will be logically empty afterwards.  Create a new Age value
@@ -230,9 +239,8 @@
     Age tempAge;
     // No competing pop_global has yet incremented "top"; we'll try to
     // install new_age, thus claiming the element.
-    assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint),
-           "Assumption about CAS unit.");
-    *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
+    assert(sizeof(Age) == sizeof(int), "Assumption about CAS unit.");
+    *(uint*)&tempAge = Atomic::cmpxchg(*(uint*)&newAge, (volatile uint*)&_age, *(uint*)&oldAge);
     if (tempAge == oldAge) {
       // We win.
       assert(dirty_size(localBot, get_top()) != n() - 1,
@@ -253,8 +261,8 @@
 bool GenericTaskQueue<E>::pop_global(E& t) {
   Age newAge;
   Age oldAge = get_age();
-  juint localBot = _bottom;
-  juint n_elems = size(localBot, oldAge.top());
+  uint localBot = _bottom;
+  uint n_elems = size(localBot, oldAge.top());
   if (n_elems == 0) {
     return false;
   }
@@ -263,7 +271,7 @@
   newAge._top = increment_index(newAge.top());
   if ( newAge._top == 0 ) newAge._tag++;
   Age resAge;
-  *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge);
+  *(uint*)&resAge = Atomic::cmpxchg(*(uint*)&newAge, (volatile uint*)&_age, *(uint*)&oldAge);
   // Note that using "_bottom" here might fail, since a pop_local might
   // have decremented it.
   assert(dirty_size(localBot, newAge._top) != n() - 1,
@@ -287,7 +295,7 @@
 
 template<class E> class GenericTaskQueueSet: public TaskQueueSetSuper {
 private:
-  int _n;
+  uint _n;
   GenericTaskQueue<E>** _queues;
 
 public:
@@ -300,51 +308,51 @@
     }
   }
 
-  bool steal_1_random(int queue_num, int* seed, E& t);
-  bool steal_best_of_2(int queue_num, int* seed, E& t);
-  bool steal_best_of_all(int queue_num, int* seed, E& t);
+  bool steal_1_random(uint queue_num, int* seed, E& t);
+  bool steal_best_of_2(uint queue_num, int* seed, E& t);
+  bool steal_best_of_all(uint queue_num, int* seed, E& t);
 
-  void register_queue(int i, GenericTaskQueue<E>* q);
+  void register_queue(uint i, GenericTaskQueue<E>* q);
 
-  GenericTaskQueue<E>* queue(int n);
+  GenericTaskQueue<E>* queue(uint n);
 
   // The thread with queue number "queue_num" (and whose random number seed
   // is at "seed") is trying to steal a task from some other queue.  (It
   // may try several queues, according to some configuration parameter.)
   // If some steal succeeds, returns "true" and sets "t" the stolen task,
   // otherwise returns false.
-  bool steal(int queue_num, int* seed, E& t);
+  bool steal(uint queue_num, int* seed, E& t);
 
   bool peek();
 };
 
 template<class E>
-void GenericTaskQueueSet<E>::register_queue(int i, GenericTaskQueue<E>* q) {
-  assert(0 <= i && i < _n, "index out of range.");
+void GenericTaskQueueSet<E>::register_queue(uint i, GenericTaskQueue<E>* q) {
+  assert(i < _n, "index out of range.");
   _queues[i] = q;
 }
 
 template<class E>
-GenericTaskQueue<E>* GenericTaskQueueSet<E>::queue(int i) {
+GenericTaskQueue<E>* GenericTaskQueueSet<E>::queue(uint i) {
   return _queues[i];
 }
 
 template<class E>
-bool GenericTaskQueueSet<E>::steal(int queue_num, int* seed, E& t) {
-  for (int i = 0; i < 2 * _n; i++)
+bool GenericTaskQueueSet<E>::steal(uint queue_num, int* seed, E& t) {
+  for (uint i = 0; i < 2 * _n; i++)
     if (steal_best_of_2(queue_num, seed, t))
       return true;
   return false;
 }
 
 template<class E>
-bool GenericTaskQueueSet<E>::steal_best_of_all(int queue_num, int* seed, E& t) {
+bool GenericTaskQueueSet<E>::steal_best_of_all(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
     int best_k;
-    jint best_sz = 0;
-    for (int k = 0; k < _n; k++) {
+    uint best_sz = 0;
+    for (uint k = 0; k < _n; k++) {
       if (k == queue_num) continue;
-      jint sz = _queues[k]->size();
+      uint sz = _queues[k]->size();
       if (sz > best_sz) {
         best_sz = sz;
         best_k = k;
@@ -362,9 +370,9 @@
 }
 
 template<class E>
-bool GenericTaskQueueSet<E>::steal_1_random(int queue_num, int* seed, E& t) {
+bool GenericTaskQueueSet<E>::steal_1_random(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
-    int k = queue_num;
+    uint k = queue_num;
     while (k == queue_num) k = randomParkAndMiller(seed) % _n;
     return _queues[2]->pop_global(t);
   } else if (_n == 2) {
@@ -378,20 +386,20 @@
 }
 
 template<class E>
-bool GenericTaskQueueSet<E>::steal_best_of_2(int queue_num, int* seed, E& t) {
+bool GenericTaskQueueSet<E>::steal_best_of_2(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
-    int k1 = queue_num;
+    uint k1 = queue_num;
     while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
-    int k2 = queue_num;
+    uint k2 = queue_num;
     while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n;
     // Sample both and try the larger.
-    juint sz1 = _queues[k1]->size();
-    juint sz2 = _queues[k2]->size();
+    uint sz1 = _queues[k1]->size();
+    uint sz2 = _queues[k2]->size();
     if (sz2 > sz1) return _queues[k2]->pop_global(t);
     else return _queues[k1]->pop_global(t);
   } else if (_n == 2) {
     // Just try the other one.
-    int k = (queue_num + 1) % 2;
+    uint k = (queue_num + 1) % 2;
     return _queues[k]->pop_global(t);
   } else {
     assert(_n == 1, "can't be zero.");
@@ -402,7 +410,7 @@
 template<class E>
 bool GenericTaskQueueSet<E>::peek() {
   // Try all the queues.
-  for (int j = 0; j < _n; j++) {
+  for (uint j = 0; j < _n; j++) {
     if (_queues[j]->peek())
       return true;
   }
@@ -418,11 +426,19 @@
 // A class to aid in the termination of a set of parallel tasks using
 // TaskQueueSet's for work stealing.
 
+#undef TRACESPINNING
+
 class ParallelTaskTerminator: public StackObj {
 private:
   int _n_threads;
   TaskQueueSetSuper* _queue_set;
-  jint _offered_termination;
+  int _offered_termination;
+
+#ifdef TRACESPINNING
+  static uint _total_yields;
+  static uint _total_spins;
+  static uint _total_peeks;
+#endif
 
   bool peek_in_queue_set();
 protected:
@@ -454,13 +470,19 @@
   // the terminator is finished.
   void reset_for_reuse();
 
+#ifdef TRACESPINNING
+  static uint total_yields() { return _total_yields; }
+  static uint total_spins() { return _total_spins; }
+  static uint total_peeks() { return _total_peeks; }
+  static void print_termination_counts();
+#endif
 };
 
 #define SIMPLE_STACK 0
 
 template<class E> inline bool GenericTaskQueue<E>::push(E t) {
 #if SIMPLE_STACK
-  juint localBot = _bottom;
+  uint localBot = _bottom;
   if (_bottom < max_elems()) {
     _elems[localBot] = t;
     _bottom = localBot + 1;
@@ -469,10 +491,10 @@
     return false;
   }
 #else
-  juint localBot = _bottom;
+  uint localBot = _bottom;
   assert((localBot >= 0) && (localBot < n()), "_bottom out of range.");
-  jushort top = get_top();
-  juint dirty_n_elems = dirty_size(localBot, top);
+  TAG_TYPE top = get_top();
+  uint dirty_n_elems = dirty_size(localBot, top);
   assert((dirty_n_elems >= 0) && (dirty_n_elems < n()),
          "n_elems out of range.");
   if (dirty_n_elems < max_elems()) {
@@ -487,19 +509,19 @@
 
 template<class E> inline bool GenericTaskQueue<E>::pop_local(E& t) {
 #if SIMPLE_STACK
-  juint localBot = _bottom;
+  uint localBot = _bottom;
   assert(localBot > 0, "precondition.");
   localBot--;
   t = _elems[localBot];
   _bottom = localBot;
   return true;
 #else
-  juint localBot = _bottom;
+  uint localBot = _bottom;
   // This value cannot be n-1.  That can only occur as a result of
   // the assignment to bottom in this method.  If it does, this method
   // resets the size( to 0 before the next call (which is sequential,
   // since this is pop_local.)
-  juint dirty_n_elems = dirty_size(localBot, get_top());
+  uint dirty_n_elems = dirty_size(localBot, get_top());
   assert(dirty_n_elems != n() - 1, "Shouldn't be possible...");
   if (dirty_n_elems == 0) return false;
   localBot = decrement_index(localBot);
@@ -512,7 +534,7 @@
   // If there's still at least one element in the queue, based on the
   // "_bottom" and "age" we've read, then there can be no interference with
   // a "pop_global" operation, and we're done.
-  juint tp = get_top();
+  TAG_TYPE tp = get_top();    // XXX
   if (size(localBot, tp) > 0) {
     assert(dirty_size(localBot, tp) != n() - 1,
            "Shouldn't be possible...");
@@ -581,7 +603,7 @@
   bool is_empty();
   bool stealable_is_empty();
   bool overflow_is_empty();
-  juint stealable_size() { return _region_queue.size(); }
+  uint stealable_size() { return _region_queue.size(); }
   RegionTaskQueue* task_queue() { return &_region_queue; }
 };
 
--- a/hotspot/src/share/vm/utilities/workgroup.hpp	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/src/share/vm/utilities/workgroup.hpp	Wed Jul 05 16:47:51 2017 +0200
@@ -32,7 +32,7 @@
 
 // An abstract task to be worked on by a gang.
 // You subclass this to supply your own work() method
-class AbstractGangTask: public CHeapObj {
+class AbstractGangTask VALUE_OBJ_CLASS_SPEC {
 public:
   // The abstract work method.
   // The argument tells you which member of the gang you are.
--- a/hotspot/test/Makefile	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/test/Makefile	Wed Jul 05 16:47:51 2017 +0200
@@ -28,9 +28,9 @@
 
 # Get OS/ARCH specifics
 OSNAME = $(shell uname -s)
-SLASH_JAVA = /java
 ifeq ($(OSNAME), SunOS)
   PLATFORM = solaris
+  SLASH_JAVA = /java
   ARCH = $(shell uname -p)
   ifeq ($(ARCH), i386)
     ARCH=i586
@@ -38,6 +38,7 @@
 endif
 ifeq ($(OSNAME), Linux)
   PLATFORM = linux
+  SLASH_JAVA = /java
   ARCH = $(shell uname -m)
   ifeq ($(ARCH), i386)
     ARCH = i586
@@ -62,6 +63,10 @@
   EXESUFFIX = .exe
 endif
 
+ifdef ALT_SLASH_JAVA
+  SLASH_JAVA = $(ALT_SLASH_JAVA)
+endif
+
 # Utilities used
 CD    = cd
 CP    = cp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6603011/Test.java	Wed Jul 05 16:47:51 2017 +0200
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6603011
+ * @summary long/int division by constant
+ *
+ * @run main/othervm -Xcomp -Xbatch -XX:-Inline Test
+ */
+
+//
+// -XX:-Inline is essential to this test so that verification functions
+//   divi, modi, divl and modl generate "plain" divides.
+// -Xcomp -Xbatch are also useful to ensure the full range of
+//   dividend and divisor combinations are tested
+//
+
+import java.net.*;
+
+class s {
+  static int  divi(int  dividend, int  divisor) { return dividend / divisor; }
+  static int  modi(int  dividend, int  divisor) { return dividend % divisor; }
+  static long divl(long dividend, long divisor) { return dividend / divisor; }
+  static long modl(long dividend, long divisor) { return dividend % divisor; }
+}
+
+public class Test implements Runnable {
+  // Report verbose messages on failure; turn off to suppress
+  // too much output with gross numbers of failures.
+  static final boolean VERBOSE = true;
+
+  // Initailize DIVISOR so that it is final in this class.
+  static final int DIVISOR;
+  static {
+    int value = 0;
+    try {
+      value = Integer.decode(System.getProperty("divisor"));
+    } catch (Throwable e) {
+    }
+    DIVISOR = value;
+  }
+
+  // The methods of interest. We want the JIT to compile these
+  // and convert the divide into a multiply.
+  public int divbyI (int dividend)   { return dividend / DIVISOR; }
+  public int modbyI (int dividend)   { return dividend % DIVISOR; }
+  public long divbyL (long dividend) { return dividend / DIVISOR; }
+  public long modbyL (long dividend) { return dividend % DIVISOR; }
+
+  public int divisor() { return DIVISOR; }
+
+  public boolean checkI (int dividend) {
+    int quo = divbyI(dividend);
+    int rem = modbyI(dividend);
+    int quo0 = s.divi(dividend, divisor());
+    int rem0 = s.modi(dividend, divisor());
+
+    if (quo != quo0 || rem != rem0) {
+      if (VERBOSE) {
+        System.out.println("Computed: " + dividend + " / " + divisor() + " = " +
+                           quo  + ", " + dividend + " % " + divisor() + " = " + rem );
+        System.out.println("expected: " + dividend + " / " + divisor() + " = " +
+                           quo0 + ", " + dividend + " % " + divisor() + " = " + rem0);
+        // Report sign of rem failure
+        if (rem != 0 && (rem ^ dividend) < 0) {
+          System.out.println("  rem & dividend have different signs");
+        }
+        // Report range of rem failure
+        if (java.lang.Math.abs(rem) >= java.lang.Math.abs(divisor())) {
+          System.out.println("  remainder out of range");
+        }
+        // Report quo/rem identity relationship failure
+        if ((quo * divisor()) + rem != dividend) {
+          System.out.println("  quotien/remainder invariant broken");
+        }
+      }
+      return false;
+    }
+    return true;
+  }
+
+  public boolean checkL (long dividend) {
+    long quo = divbyL(dividend);
+    long rem = modbyL(dividend);
+    long quo0 = s.divl(dividend, divisor());
+    long rem0 = s.modl(dividend, divisor());
+
+    if (quo != quo0 || rem != rem0) {
+      if (VERBOSE) {
+        System.out.println("  " + dividend + " / " + divisor() + " = " +
+                           quo + ", " + dividend + " % " + divisor() + " = " + rem);
+        // Report sign of rem failure
+        if (rem != 0 && (rem ^ dividend) < 0) {
+          System.out.println("  rem & dividend have different signs");
+        }
+        // Report range of rem failure
+        if (java.lang.Math.abs(rem) >= java.lang.Math.abs(divisor())) {
+          System.out.println("  remainder out of range");
+        }
+        // Report quo/rem identity relationship failure
+        if ((quo * divisor()) + rem != dividend) {
+          System.out.println(" (" + quo + " * " + divisor() + ") + " + rem + " != "
+                             + dividend);
+        }
+      }
+      return false;
+    }
+    return true;
+  }
+
+  public void run() {
+    // Don't try to divide by zero
+    if (divisor() == 0) return;
+
+    // Range of dividends to check. Try dividends from start to end
+    // inclusive, as well as variations on those values as shifted
+    // left.
+    int start = -1024;
+    int end = 1024;
+
+    // Test int division using a variety of dividends.
+    int wrong = 0;
+    int total = 0;
+
+    outerloop:
+    for (int i = start; i <= end; i++) {
+      for (int s = 0; s < 32; s += 4) {
+        total++;
+        int dividend = i << s;
+        if (!checkI(dividend)) {
+          wrong++;
+          // Stop on the first failure
+          // break outerloop;
+        }
+      }
+    }
+    if (wrong > 0) {
+      System.out.println("divisor " + divisor() + ": " +
+                         wrong + "/" + total + " wrong int divisions");
+    }
+
+    // Test long division using a variety of dividends.
+    wrong = 0;
+    total = 0;
+
+    outerloop:
+    for (int i = start; i <= end; i++) {
+      for (int s = 0; s < 64; s += 4) {
+        total++;
+        long dividend = i << s;
+        if (!checkL(dividend)) {
+          wrong++;
+          // Stop on the first failure
+          // break outerloop;
+        }
+      }
+    }
+    if (wrong > 0) {
+      System.out.println("divisor " + divisor() + ": " +
+                         wrong + "/" + total + " wrong long divisions");
+    }
+
+  }
+
+  // Reload this class with the "divisor" property set to the input parameter.
+  // This allows the JIT to see q.DIVISOR as a final constant, and change
+  // any divisions or mod operations into multiplies.
+  public static void test_divisor(int divisor,
+                                  URLClassLoader apploader) throws Exception {
+    System.setProperty("divisor", "" + divisor);
+    ClassLoader loader = new URLClassLoader(apploader.getURLs(),
+                                            apploader.getParent());
+    Class c = loader.loadClass("Test");
+    Runnable r = (Runnable)c.newInstance();
+    r.run();
+  }
+
+  public static void main(String[] args) throws Exception {
+    Class cl = Class.forName("Test");
+    URLClassLoader apploader = (URLClassLoader)cl.getClassLoader();
+
+
+    // Test every divisor between -100 and 100.
+    for (int i = -100; i <= 100; i++) {
+      test_divisor(i, apploader);
+    }
+
+    // Try a few divisors outside the typical range.
+    // The values below have been observed in rt.jar.
+    test_divisor(101, apploader);
+    test_divisor(400, apploader);
+    test_divisor(1000, apploader);
+    test_divisor(3600, apploader);
+    test_divisor(9973, apploader);
+    test_divisor(86400, apploader);
+    test_divisor(1000000, apploader);
+  }
+
+}
--- a/hotspot/test/compiler/6775880/Test.java	Wed Jul 05 16:47:27 2017 +0200
+++ b/hotspot/test/compiler/6775880/Test.java	Wed Jul 05 16:47:51 2017 +0200
@@ -27,7 +27,7 @@
  * @bug 6775880
  * @summary EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
  * @compile -source 1.4 -target 1.4 Test.java
- * @run main/othervm -server -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
  */
 
 public class Test {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6795161/Test.java	Wed Jul 05 16:47:51 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6795161
+ * @summary Escape analysis leads to data corruption
+ * @run main/othervm -server -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test
+ */
+
+class Test_Class_1 {
+    static String var_1;
+
+    static void badFunc(int size)
+    {
+        try {
+          for (int i = 0; i < 1; (new byte[size-i])[0] = 0, i++) {}
+        } catch (Exception e) {
+          // don't comment it out, it will lead to correct results ;)
+          //System.out.println("Got exception: " + e);
+        }
+    }
+}
+
+public class Test {
+    static String var_1_copy = Test_Class_1.var_1;
+
+    static byte var_check;
+
+    public static void main(String[] args)
+    {
+        var_check = 1;
+
+        Test_Class_1.badFunc(-1);
+
+        System.out.println("EATester.var_check = " + Test.var_check + " (expected 1)\n");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6795362/Test6795362.java	Wed Jul 05 16:47:51 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6795362
+ * @summary 32bit server compiler leads to wrong results on solaris-x86
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6795362.sub Test6795362
+ */
+
+public class Test6795362 {
+    public static void main(String[] args)
+    {
+        sub();
+
+        if (var_bad != 0)
+            throw new InternalError(var_bad + " != 0");
+    }
+
+    static long var_bad = -1L;
+
+    static void sub()
+    {
+        var_bad >>= 65;
+        var_bad /= 65;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6799693/Test.java	Wed Jul 05 16:47:51 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6799693
+ * @summary Server compiler leads to data corruption when expression throws an Exception
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test Test
+ */
+
+public class Test {
+   static int var_bad = 1;
+
+   public static void main(String[] args)
+   {
+      var_bad++;
+
+      try {
+         for (int i = 0; i < 10; i++) (new byte[((byte)-1 << i)])[0]  = 0;
+      }
+      catch (Exception e) { System.out.println("Got " + e); }
+
+      System.out.println("Test.var_bad = " +  var_bad + " (expected 2)\n");
+   }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6800154/Test6800154.java	Wed Jul 05 16:47:51 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6800154
+ * @summary Add comments to long_by_long_mulhi() for better understandability
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6800154.divcomp Test6800154
+ */
+
+import java.net.URLClassLoader;
+
+public class Test6800154 implements Runnable {
+    static final long[] DIVIDENDS = {
+        0,
+        1,
+        2,
+        1423487,
+        4444441,
+        4918923241323L,
+        -1,
+        -24351,
+        0x3333,
+        0x0000000080000000L,
+        0x7fffffffffffffffL,
+        0x8000000000000000L
+    };
+
+    static final long[] DIVISORS = {
+        1,
+        2,
+        17,
+        12342,
+        24123,
+        143444,
+        123444442344L,
+        -1,
+        -2,
+        -4423423234231423L,
+        0x0000000080000000L,
+        0x7fffffffffffffffL,
+        0x8000000000000000L
+    };
+
+    // Initialize DIVISOR so that it is final in this class.
+    static final long DIVISOR;
+
+    static {
+        long value = 0;
+        try {
+            value = Long.decode(System.getProperty("divisor"));
+        } catch (Throwable e) {
+        }
+        DIVISOR = value;
+    }
+
+    public static void main(String[] args) throws Exception
+    {
+        Class cl = Class.forName("Test6800154");
+        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
+
+        // Iterate over all divisors.
+        for (int i = 0; i < DIVISORS.length; i++) {
+            System.setProperty("divisor", "" + DIVISORS[i]);
+            ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+            Class c = loader.loadClass("Test6800154");
+            Runnable r = (Runnable) c.newInstance();
+            r.run();
+        }
+    }
+
+    public void run()
+    {
+        // Iterate over all dividends.
+        for (int i = 0; i < DIVIDENDS.length; i++) {
+            long dividend = DIVIDENDS[i];
+
+            long expected = divint(dividend);
+            long result = divcomp(dividend);
+
+            if (result != expected)
+                throw new InternalError(dividend + " / " + DIVISOR + " failed: " + result + " != " + expected);
+        }
+    }
+
+    static long divint(long a)  { return a / DIVISOR; }
+    static long divcomp(long a) { return a / DIVISOR; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6805724/Test6805724.java	Wed Jul 05 16:47:51 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6805724
+ * @summary ModLNode::Ideal() generates functionally incorrect graph when divisor is any (2^k-1) constant.
+ *
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test6805724.fcomp Test6805724
+ */
+
+import java.net.URLClassLoader;
+
+public class Test6805724 implements Runnable {
+    // Initialize DIVISOR so that it is final in this class.
+    static final long DIVISOR;  // 2^k-1 constant
+
+    static {
+        long value = 0;
+        try {
+            value = Long.decode(System.getProperty("divisor"));
+        } catch (Throwable t) {
+            // This one is required for the Class.forName() in main.
+        }
+        DIVISOR = value;
+    }
+
+    static long fint(long x) {
+        return x % DIVISOR;
+    }
+
+    static long fcomp(long x) {
+        return x % DIVISOR;
+    }
+
+    public void run() {
+        long a = 0x617981E1L;
+
+        long expected = fint(a);
+        long result = fcomp(a);
+
+        if (result != expected)
+            throw new InternalError(result + " != " + expected);
+    }
+
+    public static void main(String args[]) throws Exception {
+        Class cl = Class.forName("Test6805724");
+        URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
+
+        // Iterate over all 2^k-1 divisors.
+        for (int k = 1; k < Long.SIZE; k++) {
+            long divisor = (1L << k) - 1;
+            System.setProperty("divisor", "" + divisor);
+            ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
+            Class c = loader.loadClass("Test6805724");
+            Runnable r = (Runnable) c.newInstance();
+            r.run();
+        }
+    }
+}
--- a/jaxp/.hgtags	Wed Jul 05 16:47:27 2017 +0200
+++ b/jaxp/.hgtags	Wed Jul 05 16:47:51 2017 +0200
@@ -22,3 +22,4 @@
 0f113667880d335cfa2c35721b1b45144fb757f5 jdk7-b45
 b2271877894af809b7703767fe8d4e38591a02a2 jdk7-b46
 d711ad1954b294957737ea386cfd4d3c05028a36 jdk7-b47
+39de90eb4822cafaacc69edd67ab5547e55ae920 jdk7-b48
--- a/jaxws/.hgtags	Wed Jul 05 16:47:27 2017 +0200
+++ b/jaxws/.hgtags	Wed Jul 05 16:47:51 2017 +0200
@@ -22,3 +22,4 @@
 dea7753d713936c5b6fd942a91811b0676537fd0 jdk7-b45
 af4a3eeb7812a5d09a241c50b51b3c648a9d45c1 jdk7-b46
 223011570edbd49bb0fe51cdeb2089f95d305267 jdk7-b47
+01e5dd31d0c10a2db3d50db346905d2d3db45e88 jdk7-b48
--- a/jdk/.hgtags	Wed Jul 05 16:47:27 2017 +0200
+++ b/jdk/.hgtags	Wed Jul 05 16:47:51 2017 +0200
@@ -22,3 +22,4 @@
 527b426497a259d0605d069e3930e838948531a6 jdk7-b45
 4b03e27a44090d1f646af28dc58f9ead827e24c7 jdk7-b46
 b4ac413b1f129eeef0acab3f31081c1b7dfe3b27 jdk7-b47
+5fbd9ea7def17186693b6f7099b5d0dc73903eee jdk7-b48
--- a/langtools/.hgtags	Wed Jul 05 16:47:27 2017 +0200
+++ b/langtools/.hgtags	Wed Jul 05 16:47:51 2017 +0200
@@ -22,3 +22,4 @@
 30db5e0aaf83fe262d9a7227d3fc3e451cd5d459 jdk7-b45
 be546a6c08e3c31fba2edcae1de43ae3515d2e59 jdk7-b46
 2b8f6bab23926aa32b9cf7e4c540b9d1ce74b7d5 jdk7-b47
+c53007f34195f69223bdd4125ec6c0740f7d6736 jdk7-b48