changeset 12217:6772dde13bed

Merge
author amurillo
date Thu, 20 Oct 2016 16:53:56 -0700
parents 7b48d63dfd6b ad2a67815b99
children 732e5293c173 c30b6e2d2ec4
files src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EmptyEventProvider.java src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EventProvider.java src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotJVMCICompilerFactory.java src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotVMEventListener.java src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java src/share/vm/classfile/classFileParser.cpp src/share/vm/logging/log.cpp src/share/vm/runtime/arguments.cpp src/share/vm/utilities/resourceHash.cpp test/compiler/floatingpoint/Test15FloatJNIArgs.java test/compiler/floatingpoint/libTest15FloatJNIArgs.c test/compiler/jvmci/common/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener test/compiler/jvmci/common/services/jdk.vm.ci.runtime.JVMCICompiler test/compiler/jvmci/common/services/jdk.vm.ci.runtime.services.JVMCICompilerFactory
diffstat 630 files changed, 5607 insertions(+), 4513 deletions(-) [+]
line wrap: on
line diff
--- a/make/lib/CompileJvm.gmk	Thu Oct 20 20:01:43 2016 +0000
+++ b/make/lib/CompileJvm.gmk	Thu Oct 20 16:53:56 2016 -0700
@@ -176,6 +176,11 @@
 
 JVM_OPTIMIZATION ?= HIGHEST_JVM
 
+# Need to set JVM_STRIPFLAGS to the default value from SPEC since the STRIPFLAGS
+# parameter to SetupNativeCompilation allows an empty value to override the
+# default.
+JVM_STRIPFLAGS ?= $(STRIPFLAGS)
+
 ################################################################################
 # Now set up the actual compilation of the main hotspot native library
 
@@ -204,6 +209,7 @@
     OBJECT_DIR := $(JVM_OUTPUTDIR)/objs, \
     MAPFILE := $(JVM_MAPFILE), \
     USE_MAPFILE_FOR_SYMBOLS := true, \
+    STRIPFLAGS := $(JVM_STRIPFLAGS), \
     EMBED_MANIFEST := true, \
     RC_FLAGS := $(JVM_RCFLAGS), \
     VERSIONINFO_RESOURCE := $(HOTSPOT_TOPDIR)/src/os/windows/vm/version.rc, \
--- a/make/lib/JvmFeatures.gmk	Thu Oct 20 20:01:43 2016 +0000
+++ b/make/lib/JvmFeatures.gmk	Thu Oct 20 16:53:56 2016 -0700
@@ -59,6 +59,10 @@
 
 ifeq ($(call check-jvm-feature, minimal), true)
   JVM_CFLAGS_FEATURES += -DMINIMAL_JVM -DVMTYPE=\"Minimal\"
+  ifeq ($(OPENJDK_TARGET_OS), linux)
+    # Override the default -g with a more liberal strip policy for the minimal JVM
+    JVM_STRIPFLAGS := --strip-unneeded
+  endif
 endif
 
 ifeq ($(call check-jvm-feature, dtrace), true)
--- a/make/test/JtregNative.gmk	Thu Oct 20 20:01:43 2016 +0000
+++ b/make/test/JtregNative.gmk	Thu Oct 20 16:53:56 2016 -0700
@@ -45,6 +45,7 @@
     $(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \
     $(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \
     $(HOTSPOT_TOPDIR)/test/runtime/jni/checked \
+    $(HOTSPOT_TOPDIR)/test/runtime/jni/PrivateInterfaceMethods \
     $(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
     $(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \
     $(HOTSPOT_TOPDIR)/test/runtime/SameObject \
--- a/src/cpu/aarch64/vm/aarch64.ad	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/aarch64.ad	Thu Oct 20 16:53:56 2016 -0700
@@ -3496,6 +3496,16 @@
   return false;
 }
 
+bool Matcher::const_oop_prefer_decode() {
+  // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
+  return Universe::narrow_oop_base() == NULL;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+  // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
+  return Universe::narrow_klass_base() == NULL;
+}
+
 // Is it better to copy float constants, or load them directly from
 // memory?  Intel can load a float constant from a direct address,
 // requiring no extra registers.  Most RISCs will have to materialize
@@ -15502,6 +15512,24 @@
   ins_pipe(pipe_class_memory);
 %}
 
+instruct string_indexofU_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch,
+                              iRegI_R0 result, iRegI tmp1, iRegI tmp2,
+                              iRegI tmp3, rFlagsReg cr)
+%{
+  match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
+  effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch,
+         TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
+
+  format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result" %}
+
+  ins_encode %{
+    __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register,
+                           $result$$Register, $tmp1$$Register, $tmp2$$Register,
+                           $tmp3$$Register);
+  %}
+  ins_pipe(pipe_class_memory);
+%}
+
 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
                         iRegI_R0 result, rFlagsReg cr)
 %{
--- a/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -130,8 +130,8 @@
   if (_num_fp_args < Argument::n_float_register_parameters_c) {
     __ ldrs(as_FloatRegister(_num_fp_args++), src);
   } else {
-    __ ldrh(r0, src);
-    __ strh(r0, Address(to(), _stack_offset));
+    __ ldrw(r0, src);
+    __ strw(r0, Address(to(), _stack_offset));
     _stack_offset += wordSize;
     _num_fp_args++;
   }
@@ -349,7 +349,7 @@
       _num_fp_args++;
     } else {
       *_to++ = from_obj;
-      _num_int_args++;
+      _num_fp_args++;
     }
   }
 
@@ -364,7 +364,7 @@
       _num_fp_args++;
     } else {
       *_to++ = from_obj;
-      _num_int_args++;
+      _num_fp_args++;
     }
   }
 
--- a/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -60,12 +60,12 @@
 void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
   address pc = _instructions->start() + pc_offset;
   if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
-    narrowKlass narrowOop = record_narrow_metadata_reference(constant, CHECK);
+    narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, CHECK);
     TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop);
     Unimplemented();
   } else {
     NativeMovConstReg* move = nativeMovConstReg_at(pc);
-    void* reference = record_metadata_reference(constant, CHECK);
+    void* reference = record_metadata_reference(_instructions, pc, constant, CHECK);
     move->set_data((intptr_t) reference);
     TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference));
   }
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -4508,6 +4508,67 @@
 typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
 typedef void (MacroAssembler::* uxt_insn)(Register Rd, Register Rn);
 
+void MacroAssembler::string_indexof_char(Register str1, Register cnt1,
+                                         Register ch, Register result,
+                                         Register tmp1, Register tmp2, Register tmp3)
+{
+  Label CH1_LOOP, HAS_ZERO, DO1_SHORT, DO1_LOOP, MATCH, NOMATCH, DONE;
+  Register cnt1_neg = cnt1;
+  Register ch1 = rscratch1;
+  Register result_tmp = rscratch2;
+
+  cmp(cnt1, 4);
+  br(LT, DO1_SHORT);
+
+  orr(ch, ch, ch, LSL, 16);
+  orr(ch, ch, ch, LSL, 32);
+
+  sub(cnt1, cnt1, 4);
+  mov(result_tmp, cnt1);
+  lea(str1, Address(str1, cnt1, Address::uxtw(1)));
+  sub(cnt1_neg, zr, cnt1, LSL, 1);
+
+  mov(tmp3, 0x0001000100010001);
+
+  BIND(CH1_LOOP);
+    ldr(ch1, Address(str1, cnt1_neg));
+    eor(ch1, ch, ch1);
+    sub(tmp1, ch1, tmp3);
+    orr(tmp2, ch1, 0x7fff7fff7fff7fff);
+    bics(tmp1, tmp1, tmp2);
+    br(NE, HAS_ZERO);
+    adds(cnt1_neg, cnt1_neg, 8);
+    br(LT, CH1_LOOP);
+
+    cmp(cnt1_neg, 8);
+    mov(cnt1_neg, 0);
+    br(LT, CH1_LOOP);
+    b(NOMATCH);
+
+  BIND(HAS_ZERO);
+    rev(tmp1, tmp1);
+    clz(tmp1, tmp1);
+    add(cnt1_neg, cnt1_neg, tmp1, LSR, 3);
+    b(MATCH);
+
+  BIND(DO1_SHORT);
+    mov(result_tmp, cnt1);
+    lea(str1, Address(str1, cnt1, Address::uxtw(1)));
+    sub(cnt1_neg, zr, cnt1, LSL, 1);
+  BIND(DO1_LOOP);
+    ldrh(ch1, Address(str1, cnt1_neg));
+    cmpw(ch, ch1);
+    br(EQ, MATCH);
+    adds(cnt1_neg, cnt1_neg, 2);
+    br(LT, DO1_LOOP);
+  BIND(NOMATCH);
+    mov(result, -1);
+    b(DONE);
+  BIND(MATCH);
+    add(result, result_tmp, cnt1_neg, ASR, 1);
+  BIND(DONE);
+}
+
 // Compare strings.
 void MacroAssembler::string_compare(Register str1, Register str2,
                                     Register cnt1, Register cnt2, Register result,
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1229,6 +1229,9 @@
                       Register tmp1, Register tmp2,
                       Register tmp3, Register tmp4,
                       int int_cnt1, Register result, int ae);
+  void string_indexof_char(Register str1, Register cnt1,
+                           Register ch, Register result,
+                           Register tmp1, Register tmp2, Register tmp3);
 private:
   void add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo,
                        Register src1, Register src2);
--- a/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -989,7 +989,16 @@
 
 // A float arg may have to do float reg int reg conversion
 static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
-  if (src.first() != dst.first()) {
+  assert(src.first()->is_stack() && dst.first()->is_stack() ||
+         src.first()->is_reg() && dst.first()->is_reg(), "Unexpected error");
+  if (src.first()->is_stack()) {
+    if (dst.first()->is_stack()) {
+      __ ldrw(rscratch1, Address(rfp, reg2offset_in(src.first())));
+      __ strw(rscratch1, Address(sp, reg2offset_out(dst.first())));
+    } else {
+      ShouldNotReachHere();
+    }
+  } else if (src.first() != dst.first()) {
     if (src.is_single_phys_reg() && dst.is_single_phys_reg())
       __ fmovs(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister());
     else
@@ -1023,7 +1032,16 @@
 
 // A double move
 static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
-  if (src.first() != dst.first()) {
+  assert(src.first()->is_stack() && dst.first()->is_stack() ||
+         src.first()->is_reg() && dst.first()->is_reg(), "Unexpected error");
+  if (src.first()->is_stack()) {
+    if (dst.first()->is_stack()) {
+      __ ldr(rscratch1, Address(rfp, reg2offset_in(src.first())));
+      __ str(rscratch1, Address(sp, reg2offset_out(dst.first())));
+    } else {
+      ShouldNotReachHere();
+    }
+  } else if (src.first() != dst.first()) {
     if (src.is_single_phys_reg() && dst.is_single_phys_reg())
       __ fmovd(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister());
     else
--- a/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -2743,7 +2743,7 @@
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt");
 
-    Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52;
+    Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52, _L_finish;
 
     const Register from        = c_rarg0;  // source array address
     const Register to          = c_rarg1;  // destination array address
@@ -2754,9 +2754,12 @@
     const Register keylen      = rscratch1;
 
     address start = __ pc();
+
       __ enter();
 
-      __ mov(rscratch2, len_reg);
+      __ subsw(rscratch2, len_reg, zr);
+      __ br(Assembler::LE, _L_finish);
+
       __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
 
       __ ld1(v0, __ T16B, rvec);
@@ -2814,11 +2817,13 @@
       __ eor(v0, __ T16B, v0, v31);
 
       __ st1(v0, __ T16B, __ post(to, 16));
-      __ sub(len_reg, len_reg, 16);
-      __ cbnz(len_reg, L_aes_loop);
+
+      __ subw(len_reg, len_reg, 16);
+      __ cbnzw(len_reg, L_aes_loop);
 
       __ st1(v0, __ T16B, rvec);
 
+    __ BIND(_L_finish);
       __ mov(r0, rscratch2);
 
       __ leave();
@@ -2844,7 +2849,7 @@
     __ align(CodeEntryAlignment);
     StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt");
 
-    Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52;
+    Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52, _L_finish;
 
     const Register from        = c_rarg0;  // source array address
     const Register to          = c_rarg1;  // destination array address
@@ -2855,9 +2860,12 @@
     const Register keylen      = rscratch1;
 
     address start = __ pc();
+
       __ enter();
 
-      __ mov(rscratch2, len_reg);
+      __ subsw(rscratch2, len_reg, zr);
+      __ br(Assembler::LE, _L_finish);
+
       __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
 
       __ ld1(v2, __ T16B, rvec);
@@ -2920,11 +2928,12 @@
       __ st1(v0, __ T16B, __ post(to, 16));
       __ orr(v2, __ T16B, v1, v1);
 
-      __ sub(len_reg, len_reg, 16);
-      __ cbnz(len_reg, L_aes_loop);
+      __ subw(len_reg, len_reg, 16);
+      __ cbnzw(len_reg, L_aes_loop);
 
       __ st1(v2, __ T16B, rvec);
 
+    __ BIND(_L_finish);
       __ mov(r0, rscratch2);
 
       __ leave();
--- a/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -454,8 +454,9 @@
   __ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
 
 #if INCLUDE_JVMCI
-  // Check if we need to take lock at entry of synchronized method.
-  if (UseJVMCICompiler) {
+  // Check if we need to take lock at entry of synchronized method.  This can
+  // only occur on method entry so emit it only for vtos with step 0.
+  if (UseJVMCICompiler && state == vtos && step == 0) {
     Label L;
     __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
     __ cbz(rscratch1, L);
@@ -464,8 +465,17 @@
     // Take lock.
     lock_method();
     __ bind(L);
+  } else {
+#ifdef ASSERT
+    if (UseJVMCICompiler) {
+      Label L;
+      __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
+      __ cbz(rscratch1, L);
+      __ stop("unexpected pending monitor in deopt entry");
+      __ bind(L);
+    }
+#endif
   }
-#endif
   // handle exceptions
   {
     Label L;
--- a/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -3717,19 +3717,15 @@
 
   // allocate one if there's no free slot
   {
-    Label entry, loop, no_adjust;
+    Label entry, loop;
     // 1. compute new pointers            // rsp: old expression stack top
     __ ldr(c_rarg1, monitor_block_bot);   // c_rarg1: old expression stack bottom
-    __ sub(esp, esp, entry_size);           // move expression stack top
+    __ sub(esp, esp, entry_size);         // move expression stack top
     __ sub(c_rarg1, c_rarg1, entry_size); // move expression stack bottom
     __ mov(c_rarg3, esp);                 // set start value for copy loop
     __ str(c_rarg1, monitor_block_bot);   // set new monitor block bottom
 
-    __ cmp(sp, c_rarg3);                  // Check if we need to move sp
-    __ br(Assembler::LO, no_adjust);      // to allow more stack space
-                                          // for our new esp
-    __ sub(sp, sp, 2 * wordSize);
-    __ bind(no_adjust);
+    __ sub(sp, sp, entry_size);           // make room for the monitor
 
     __ b(entry);
     // 2. move expression stack contents
--- a/src/cpu/ppc/vm/c1_MacroAssembler_ppc.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/ppc/vm/c1_MacroAssembler_ppc.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -64,17 +64,16 @@
 
 
 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
+  // Avoid stack bang as first instruction. It may get overwritten by patch_verified_entry.
+  const Register return_pc = R20;
+  mflr(return_pc);
+
+  // Make sure there is enough stack space for this method's activation.
   assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
-  // Make sure there is enough stack space for this method's activation.
   generate_stack_overflow_check(bang_size_in_bytes);
 
-  // Create the frame.
-  const Register return_pc  = R0;
-
-  mflr(return_pc);
-  // Get callers sp.
-  std(return_pc, _abi(lr), R1_SP);           // SP->lr = return_pc
-  push_frame(frame_size_in_bytes, R0);       // SP -= frame_size_in_bytes
+  std(return_pc, _abi(lr), R1_SP);     // SP->lr = return_pc
+  push_frame(frame_size_in_bytes, R0); // SP -= frame_size_in_bytes
 }
 
 
--- a/src/cpu/ppc/vm/ppc.ad	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/ppc/vm/ppc.ad	Thu Oct 20 16:53:56 2016 -0700
@@ -1097,21 +1097,19 @@
   // No entry point given, use the current pc.
   if (entry_point == NULL) entry_point = __ pc();
 
-  if (!Compile::current()->in_scratch_emit_size()) {
-    // Put the entry point as a constant into the constant pool.
-    const address entry_point_toc_addr   = __ address_constant(entry_point, RelocationHolder::none);
-    if (entry_point_toc_addr == NULL) {
-      ciEnv::current()->record_out_of_memory_failure();
-      return offsets;
-    }
-    const int     entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
-
-    // Emit the trampoline stub which will be related to the branch-and-link below.
-    CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
-    if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
-    __ relocate(rtype);
+  // Put the entry point as a constant into the constant pool.
+  const address entry_point_toc_addr   = __ address_constant(entry_point, RelocationHolder::none);
+  if (entry_point_toc_addr == NULL) {
+    ciEnv::current()->record_out_of_memory_failure();
+    return offsets;
   }
-
+  const int     entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
+  
+  // Emit the trampoline stub which will be related to the branch-and-link below.
+  CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
+  if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
+  __ relocate(rtype);
+  
   // Note: At this point we do not have the address of the trampoline
   // stub, and the entry point might be too far away for bl, so __ pc()
   // serves as dummy and the bl will be patched later.
@@ -2166,6 +2164,16 @@
   return false;
 }
 
+bool Matcher::const_oop_prefer_decode() {
+  // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
+  return Universe::narrow_oop_base() == NULL;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+  // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
+  return Universe::narrow_klass_base() == NULL;
+}
+
 // Is it better to copy float constants, or load them directly from memory?
 // Intel can load a float constant from a direct address, requiring no
 // extra registers. Most RISCs will have to materialize an address into a
@@ -2424,6 +2432,29 @@
     MacroAssembler _masm(&cbuf);
     int toc_offset = 0;
 
+    address const_toc_addr;
+    // Create a non-oop constant, no relocation needed.
+    // If it is an IC, it has a virtual_call_Relocation.
+    const_toc_addr = __ long_constant((jlong)$src$$constant);
+    if (const_toc_addr == NULL) {
+      ciEnv::current()->record_out_of_memory_failure();
+      return;
+    }
+    
+    // Get the constant's TOC offset.
+    toc_offset = __ offset_to_method_toc(const_toc_addr);
+    
+    // Keep the current instruction offset in mind.
+    ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
+  
+    __ ld($dst$$Register, toc_offset, $toc$$Register);
+  %}
+
+  enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
+
+    MacroAssembler _masm(&cbuf);
+
     if (!ra_->C->in_scratch_emit_size()) {
       address const_toc_addr;
       // Create a non-oop constant, no relocation needed.
@@ -2435,31 +2466,6 @@
       }
 
       // Get the constant's TOC offset.
-      toc_offset = __ offset_to_method_toc(const_toc_addr);
-
-      // Keep the current instruction offset in mind.
-      ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
-    }
-
-    __ ld($dst$$Register, toc_offset, $toc$$Register);
-  %}
-
-  enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
-
-    MacroAssembler _masm(&cbuf);
-
-    if (!ra_->C->in_scratch_emit_size()) {
-      address const_toc_addr;
-      // Create a non-oop constant, no relocation needed.
-      // If it is an IC, it has a virtual_call_Relocation.
-      const_toc_addr = __ long_constant((jlong)$src$$constant);
-      if (const_toc_addr == NULL) {
-        ciEnv::current()->record_out_of_memory_failure();
-        return;
-      }
-
-      // Get the constant's TOC offset.
       const int toc_offset = __ offset_to_method_toc(const_toc_addr);
       // Store the toc offset of the constant.
       ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
@@ -2576,31 +2582,29 @@
     MacroAssembler _masm(&cbuf);
     int toc_offset = 0;
 
-    if (!ra_->C->in_scratch_emit_size()) {
-      intptr_t val = $src$$constant;
-      relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
-      address const_toc_addr;
-      if (constant_reloc == relocInfo::oop_type) {
-        // Create an oop constant and a corresponding relocation.
-        AddressLiteral a = __ allocate_oop_address((jobject)val);
-        const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
-        __ relocate(a.rspec());
-      } else if (constant_reloc == relocInfo::metadata_type) {
-        AddressLiteral a = __ constant_metadata_address((Metadata *)val);
-        const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
-        __ relocate(a.rspec());
-      } else {
-        // Create a non-oop constant, no relocation needed.
-        const_toc_addr = __ long_constant((jlong)$src$$constant);
-      }
-
-      if (const_toc_addr == NULL) {
-        ciEnv::current()->record_out_of_memory_failure();
-        return;
-      }
-      // Get the constant's TOC offset.
-      toc_offset = __ offset_to_method_toc(const_toc_addr);
-    }
+    intptr_t val = $src$$constant;
+    relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
+    address const_toc_addr;
+    if (constant_reloc == relocInfo::oop_type) {
+      // Create an oop constant and a corresponding relocation.
+      AddressLiteral a = __ allocate_oop_address((jobject)val);
+      const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
+      __ relocate(a.rspec());
+    } else if (constant_reloc == relocInfo::metadata_type) {
+      AddressLiteral a = __ constant_metadata_address((Metadata *)val);
+      const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
+      __ relocate(a.rspec());
+    } else {
+      // Create a non-oop constant, no relocation needed.
+      const_toc_addr = __ long_constant((jlong)$src$$constant);
+    }
+
+    if (const_toc_addr == NULL) {
+      ciEnv::current()->record_out_of_memory_failure();
+      return;
+    }
+    // Get the constant's TOC offset.
+    toc_offset = __ offset_to_method_toc(const_toc_addr);
 
     __ ld($dst$$Register, toc_offset, $toc$$Register);
   %}
@@ -3272,28 +3276,26 @@
     } else {
       // Remember the offset not the address.
       const int start_offset = __ offset();
+
       // The trampoline stub.
-      if (!Compile::current()->in_scratch_emit_size()) {
-        // No entry point given, use the current pc.
-        // Make sure branch fits into
-        if (entry_point == 0) entry_point = __ pc();
-
-        // Put the entry point as a constant into the constant pool.
-        const address entry_point_toc_addr   = __ address_constant(entry_point, RelocationHolder::none);
-        if (entry_point_toc_addr == NULL) {
-          ciEnv::current()->record_out_of_memory_failure();
-          return;
-        }
-        const int     entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
-
-
-        // Emit the trampoline stub which will be related to the branch-and-link below.
-        CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
-        if (ciEnv::current()->failing()) { return; } // Code cache may be full.
-        int method_index = resolved_method_index(cbuf);
-        __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
-                                       : static_call_Relocation::spec(method_index));
+      // No entry point given, use the current pc.
+      // Make sure branch fits into
+      if (entry_point == 0) entry_point = __ pc();
+
+      // Put the entry point as a constant into the constant pool.
+      const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
+      if (entry_point_toc_addr == NULL) {
+        ciEnv::current()->record_out_of_memory_failure();
+        return;
       }
+      const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
+
+      // Emit the trampoline stub which will be related to the branch-and-link below.
+      CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
+      if (ciEnv::current()->failing()) { return; } // Code cache may be full.
+      int method_index = resolved_method_index(cbuf);
+      __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
+                  : static_call_Relocation::spec(method_index));
 
       // The real call.
       // Note: At this point we do not have the address of the trampoline
--- a/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -2550,7 +2550,7 @@
   __ lbzx(R17_tos, Rclass_or_obj, Roffset);
   __ extsb(R17_tos, R17_tos);
   __ push(ztos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     // use btos rewriting, no truncating to t/f bit is needed for getfield.
     patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch);
   }
@@ -2874,7 +2874,9 @@
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
   __ andi(R17_tos, R17_tos, 0x1);
   __ stbx(R17_tos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }
--- a/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -71,7 +71,7 @@
   if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
 #ifdef _LP64
     NativeMovConstReg32* move = nativeMovConstReg32_at(pc);
-    narrowKlass narrowOop = record_narrow_metadata_reference(constant, CHECK);
+    narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, CHECK);
     move->set_data((intptr_t)narrowOop);
     TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop);
 #else
@@ -79,7 +79,7 @@
 #endif
   } else {
     NativeMovConstReg* move = nativeMovConstReg_at(pc);
-    void* reference = record_metadata_reference(constant, CHECK);
+    void* reference = record_metadata_reference(_instructions, pc, constant, CHECK);
     move->set_data((intptr_t)reference);
     TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference));
   }
--- a/src/cpu/sparc/vm/sparc.ad	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/sparc/vm/sparc.ad	Thu Oct 20 16:53:56 2016 -0700
@@ -2003,6 +2003,20 @@
   return false;
 }
 
+bool Matcher::const_oop_prefer_decode() {
+  // TODO: Check if loading ConP from TOC in heap-based mode is better:
+  // Prefer ConN+DecodeN over ConP in simple compressed oops mode.
+  // return Universe::narrow_oop_base() == NULL;
+  return true;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+  // TODO: Check if loading ConP from TOC in heap-based mode is better:
+  // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
+  // return Universe::narrow_klass_base() == NULL;
+  return true;
+}
+
 // Is it better to copy float constants, or load them directly from memory?
 // Intel can load a float constant from a direct address, requiring no
 // extra registers.  Most RISCs will have to materialize an address into a
--- a/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -384,8 +384,9 @@
   address entry = __ pc();
   __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
 #if INCLUDE_JVMCI
-  // Check if we need to take lock at entry of synchronized method.
-  if (UseJVMCICompiler) {
+  // Check if we need to take lock at entry of synchronized method.  This can
+  // only occur on method entry so emit it only for vtos with step 0.
+  if (UseJVMCICompiler && state == vtos && step == 0) {
     Label L;
     Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset());
     __ ldbool(pending_monitor_enter_addr, Gtemp);  // Load if pending monitor enter
@@ -395,6 +396,17 @@
     // Take lock.
     lock_method();
     __ bind(L);
+  } else {
+#ifdef ASSERT
+    if (UseJVMCICompiler) {
+      Label L;
+      Address pending_monitor_enter_addr(G2_thread, JavaThread::pending_monitorenter_offset());
+      __ ldbool(pending_monitor_enter_addr, Gtemp);  // Load if pending monitor enter
+      __ cmp_and_br_short(Gtemp, G0, Assembler::equal, Assembler::pn, L);
+      __ stop("unexpected pending monitor in deopt entry");
+      __ bind(L);
+    }
+#endif
   }
 #endif
   { Label L;
--- a/src/cpu/sparc/vm/vmStructs_sparc.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/sparc/vm/vmStructs_sparc.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -84,7 +84,6 @@
   declare_constant(VM_Version::sun4v_m)                                   \
   declare_constant(VM_Version::blk_init_instructions_m)                   \
   declare_constant(VM_Version::fmaf_instructions_m)                       \
-  declare_constant(VM_Version::fmau_instructions_m)                       \
   declare_constant(VM_Version::sparc64_family_m)                          \
   declare_constant(VM_Version::M_family_m)                                \
   declare_constant(VM_Version::T_family_m)                                \
--- a/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -179,7 +179,7 @@
   assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
 
   char buf[512];
-  jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+  jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                (has_v9() ? ", v9" : (has_v8() ? ", v8" : "")),
                (has_hardware_popc() ? ", popc" : ""),
                (has_vis1() ? ", vis1" : ""),
@@ -193,6 +193,7 @@
                (has_sha512() ? ", sha512" : ""),
                (has_crc32c() ? ", crc32c" : ""),
                (is_ultra3() ? ", ultra3" : ""),
+               (has_sparc5_instr() ? ", sparc5" : ""),
                (is_sun4v() ? ", sun4v" : ""),
                (is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")),
                (is_sparc64() ? ", sparc64" : ""),
@@ -487,16 +488,11 @@
     if (strstr(impl, "SPARC-T1") != NULL) {
       features |= T1_model_m;
     }
+  } else if (strstr(impl, "SUN4V-CPU") != NULL) {
+    // Generic or migration class LDOM
+    features |= T_family_m;
   } else {
-    if (strstr(impl, "SPARC") == NULL) {
-#ifndef PRODUCT
-      // kstat on Solaris 8 virtual machines (branded zones)
-      // returns "(unsupported)" implementation. Solaris 8 is not
-      // supported anymore, but include this check to be on the
-      // safe side.
-      warning("Can't parse CPU implementation = '%s', assume generic SPARC", impl);
-#endif
-    }
+    log_info(os, cpu)("Failed to parse CPU implementation = '%s'", impl);
   }
   os::free((void*)impl);
   return features;
--- a/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -34,30 +34,29 @@
 
 protected:
   enum Feature_Flag {
-    v8_instructions      = 0,
-    hardware_mul32       = 1,
-    hardware_div32       = 2,
-    hardware_fsmuld      = 3,
-    hardware_popc        = 4,
-    v9_instructions      = 5,
-    vis1_instructions    = 6,
-    vis2_instructions    = 7,
-    sun4v_instructions   = 8,
+    v8_instructions       = 0,
+    hardware_mul32        = 1,
+    hardware_div32        = 2,
+    hardware_fsmuld       = 3,
+    hardware_popc         = 4,
+    v9_instructions       = 5,
+    vis1_instructions     = 6,
+    vis2_instructions     = 7,
+    sun4v_instructions    = 8,
     blk_init_instructions = 9,
-    fmaf_instructions    = 10,
-    fmau_instructions    = 11,
-    vis3_instructions    = 12,
-    cbcond_instructions  = 13,
-    sparc64_family       = 14,
-    M_family             = 15,
-    T_family             = 16,
-    T1_model             = 17,
-    sparc5_instructions  = 18,
-    aes_instructions     = 19,
-    sha1_instruction     = 20,
-    sha256_instruction   = 21,
-    sha512_instruction   = 22,
-    crc32c_instruction   = 23
+    fmaf_instructions     = 10,
+    vis3_instructions     = 11,
+    cbcond_instructions   = 12,
+    sparc64_family        = 13,
+    M_family              = 14,
+    T_family              = 15,
+    T1_model              = 16,
+    sparc5_instructions   = 17,
+    aes_instructions      = 18,
+    sha1_instruction      = 19,
+    sha256_instruction    = 20,
+    sha512_instruction    = 21,
+    crc32c_instruction    = 22
   };
 
   enum Feature_Flag_Set {
@@ -75,7 +74,6 @@
     sun4v_m                 = 1 << sun4v_instructions,
     blk_init_instructions_m = 1 << blk_init_instructions,
     fmaf_instructions_m     = 1 << fmaf_instructions,
-    fmau_instructions_m     = 1 << fmau_instructions,
     vis3_instructions_m     = 1 << vis3_instructions,
     cbcond_instructions_m   = 1 << cbcond_instructions,
     sparc64_family_m        = 1 << sparc64_family,
--- a/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -89,14 +89,14 @@
   if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
 #ifdef _LP64
     address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
-    *((narrowKlass*) operand) = record_narrow_metadata_reference(constant, CHECK);
+    *((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, constant, CHECK);
     TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
 #else
     JVMCI_ERROR("compressed Klass* on 32bit");
 #endif
   } else {
     address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
-    *((void**) operand) = record_metadata_reference(constant, CHECK);
+    *((void**) operand) = record_metadata_reference(_instructions, operand, constant, CHECK);
     TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
   }
 }
--- a/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -254,8 +254,9 @@
   const Register thread = NOT_LP64(rcx) LP64_ONLY(r15_thread);
   NOT_LP64(__ get_thread(thread));
 #if INCLUDE_JVMCI
-  // Check if we need to take lock at entry of synchronized method.
-  if (UseJVMCICompiler) {
+  // Check if we need to take lock at entry of synchronized method.  This can
+  // only occur on method entry so emit it only for vtos with step 0.
+  if (UseJVMCICompiler && state == vtos && step == 0) {
     Label L;
     __ cmpb(Address(thread, JavaThread::pending_monitorenter_offset()), 0);
     __ jcc(Assembler::zero, L);
@@ -266,6 +267,16 @@
     // Take lock.
     lock_method();
     __ bind(L);
+  } else {
+#ifdef ASSERT
+    if (UseJVMCICompiler) {
+      Label L;
+      __ cmpb(Address(r15_thread, JavaThread::pending_monitorenter_offset()), 0);
+      __ jccb(Assembler::zero, L);
+      __ stop("unexpected pending monitor in deopt entry");
+      __ bind(L);
+    }
+#endif
   }
 #endif
   // handle exceptions
--- a/src/cpu/x86/vm/x86_32.ad	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/x86/vm/x86_32.ad	Thu Oct 20 16:53:56 2016 -0700
@@ -1452,6 +1452,15 @@
   return true;
 }
 
+bool Matcher::const_oop_prefer_decode() {
+  ShouldNotCallThis();
+  return true;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+  ShouldNotCallThis();
+  return true;
+}
 
 // Is it better to copy float constants, or load them directly from memory?
 // Intel can load a float constant from a direct address, requiring no
--- a/src/cpu/x86/vm/x86_64.ad	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/cpu/x86/vm/x86_64.ad	Thu Oct 20 16:53:56 2016 -0700
@@ -1660,6 +1660,19 @@
   return (LogKlassAlignmentInBytes <= 3);
 }
 
+bool Matcher::const_oop_prefer_decode() {
+  // Prefer ConN+DecodeN over ConP.
+  return true;
+}
+
+bool Matcher::const_klass_prefer_decode() {
+  // TODO: Either support matching DecodeNKlass (heap-based) in operand
+  //       or condisider the following:
+  // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode.
+  //return Universe::narrow_klass_base() == NULL;
+  return true;
+}
+
 // Is it better to copy float constants, or load them directly from
 // memory?  Intel can load a float constant from a direct address,
 // requiring no extra registers.  Most RISCs will have to materialize
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Thu Oct 20 16:53:56 2016 -0700
@@ -96,9 +96,6 @@
         if ((config.vmVersionFeatures & config.sparcFmafInstructions) != 0) {
             features.add(CPUFeature.FMAF);
         }
-        if ((config.vmVersionFeatures & config.sparcFmauInstructions) != 0) {
-            features.add(CPUFeature.FMAU);
-        }
         if ((config.vmVersionFeatures & config.sparcSparc64Family) != 0) {
             features.add(CPUFeature.SPARC64_FAMILY);
         }
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotVMConfig.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotVMConfig.java	Thu Oct 20 16:53:56 2016 -0700
@@ -55,7 +55,6 @@
     final int sparcSun4v = getConstant("VM_Version::sun4v_m", Integer.class);
     final int sparcBlkInitInstructions = getConstant("VM_Version::blk_init_instructions_m", Integer.class);
     final int sparcFmafInstructions = getConstant("VM_Version::fmaf_instructions_m", Integer.class);
-    final int sparcFmauInstructions = getConstant("VM_Version::fmau_instructions_m", Integer.class);
     final int sparcSparc64Family = getConstant("VM_Version::sparc64_family_m", Integer.class);
     final int sparcMFamily = getConstant("VM_Version::M_family_m", Integer.class);
     final int sparcTFamily = getConstant("VM_Version::T_family_m", Integer.class);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EmptyEventProvider.java	Thu Oct 20 16:53:56 2016 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+/**
+ * An empty implementation for {@link EventProvider}. This implementation is used when no logging is
+ * requested.
+ */
+final class EmptyEventProvider implements EventProvider {
+
+    static InternalError shouldNotReachHere() {
+        throw new InternalError("should not reach here");
+    }
+
+    @Override
+    public CompilationEvent newCompilationEvent() {
+        return new EmptyCompilationEvent();
+    }
+
+    static class EmptyCompilationEvent implements CompilationEvent {
+        public void commit() {
+            throw shouldNotReachHere();
+        }
+
+        public boolean shouldWrite() {
+            // Events of this class should never been written.
+            return false;
+        }
+
+        public void begin() {
+        }
+
+        public void end() {
+        }
+
+        public void setMethod(String method) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCompileId(int compileId) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCompileLevel(int compileLevel) {
+            throw shouldNotReachHere();
+        }
+
+        public void setSucceeded(boolean succeeded) {
+            throw shouldNotReachHere();
+        }
+
+        public void setIsOsr(boolean isOsr) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCodeSize(int codeSize) {
+            throw shouldNotReachHere();
+        }
+
+        public void setInlinedBytes(int inlinedBytes) {
+            throw shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public CompilerFailureEvent newCompilerFailureEvent() {
+        return new EmptyCompilerFailureEvent();
+    }
+
+    static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
+        public void commit() {
+            throw shouldNotReachHere();
+        }
+
+        public boolean shouldWrite() {
+            // Events of this class should never been written.
+            return false;
+        }
+
+        public void setCompileId(int compileId) {
+            throw shouldNotReachHere();
+        }
+
+        public void setMessage(String message) {
+            throw shouldNotReachHere();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java	Thu Oct 20 16:53:56 2016 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilationEvent;
+import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilerFailureEvent;
+import jdk.vm.ci.services.JVMCIPermission;
+
+/**
+ * Service-provider class for logging compiler related events.
+ */
+public interface EventProvider {
+
+    /**
+     * Creates and returns an empty implementation for {@link EventProvider}. This implementation
+     * can be used when no logging is requested.
+     */
+    static EventProvider createEmptyEventProvider() {
+        return new EmptyEventProvider();
+    }
+
+    /**
+     * Creates and returns an empty implementation for {@link CompilationEvent}.
+     */
+    static CompilationEvent createEmptyCompilationEvent() {
+        return new EmptyCompilationEvent();
+    }
+
+    /**
+     * Creates and returns an empty implementation for {@link CompilationEvent}.
+     */
+    static CompilerFailureEvent createEmptyCompilerFailureEvent() {
+        return new EmptyCompilerFailureEvent();
+    }
+
+    /**
+     * An instant event is an event that is not considered to have taken any time.
+     */
+    public interface InstantEvent {
+        /**
+         * Commits the event.
+         */
+        void commit();
+
+        /**
+         * Determines if this particular event instance would be committed to the data stream right
+         * now if application called {@link #commit()}. This in turn depends on whether the event is
+         * enabled and possible other factors.
+         *
+         * @return if this event would be committed on a call to {@link #commit()}.
+         */
+        boolean shouldWrite();
+    }
+
+    /**
+     * Timed events describe an operation that somehow consumes time.
+     */
+    public interface TimedEvent extends InstantEvent {
+        /**
+         * Starts the timing for this event.
+         */
+        void begin();
+
+        /**
+         * Ends the timing period for this event.
+         */
+        void end();
+    }
+
+    /**
+     * Creates a new {@link CompilationEvent}.
+     *
+     * @return a compilation event
+     */
+    public abstract CompilationEvent newCompilationEvent();
+
+    /**
+     * A compilation event.
+     */
+    public interface CompilationEvent extends TimedEvent {
+        void setMethod(String method);
+
+        void setCompileId(int compileId);
+
+        void setCompileLevel(int compileLevel);
+
+        void setSucceeded(boolean succeeded);
+
+        void setIsOsr(boolean isOsr);
+
+        void setCodeSize(int codeSize);
+
+        void setInlinedBytes(int inlinedBytes);
+    }
+
+    /**
+     * Creates a new {@link CompilerFailureEvent}.
+     *
+     * @return a compiler failure event
+     */
+    public abstract CompilerFailureEvent newCompilerFailureEvent();
+
+    /**
+     * A compiler failure event.
+     */
+    public interface CompilerFailureEvent extends InstantEvent {
+        void setCompileId(int compileId);
+
+        void setMessage(String message);
+    }
+}
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Thu Oct 20 16:53:56 2016 -0700
@@ -26,8 +26,10 @@
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
 import jdk.vm.ci.runtime.JVMCICompiler;
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
 import jdk.vm.ci.runtime.JVMCIRuntime;
-import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
+import jdk.vm.ci.services.JVMCIServiceLocator;
+import jdk.vm.ci.services.JVMCIPermission;
 import jdk.vm.ci.services.Services;
 
 final class HotSpotJVMCICompilerConfig {
@@ -37,7 +39,7 @@
      * to perform a compilation. This allows the reflective parts of the JVMCI API to be used
      * without requiring a compiler implementation to be available.
      */
-    private static class DummyCompilerFactory extends JVMCICompilerFactory implements JVMCICompiler {
+    private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler {
 
         public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) {
             throw new JVMCIError("no JVMCI compiler selected");
@@ -63,15 +65,16 @@
      * Gets the selected system compiler factory.
      *
      * @return the selected system compiler factory
+     * @throws SecurityException if a security manager is present and it denies
+     *             {@link JVMCIPermission} for any {@link JVMCIServiceLocator} loaded by this method
      */
     static JVMCICompilerFactory getCompilerFactory() {
         if (compilerFactory == null) {
             JVMCICompilerFactory factory = null;
             String compilerName = Option.Compiler.getString();
             if (compilerName != null) {
-                for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
+                for (JVMCICompilerFactory f : JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class)) {
                     if (f.getCompilerName().equals(compilerName)) {
-                        Services.exportJVMCITo(f.getClass());
                         factory = f;
                     }
                 }
@@ -80,8 +83,9 @@
                 }
             } else {
                 // Auto select a single available compiler
-                for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
+                for (JVMCICompilerFactory f : JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class)) {
                     if (factory == null) {
+                        Services.exportJVMCITo(f.getClass());
                         factory = f;
                     } else {
                         // Multiple factories seen - cancel auto selection
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java	Thu Oct 20 16:53:56 2016 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
+
+/**
+ * HotSpot extensions to {@link JVMCICompilerFactory}.
+ */
+public abstract class HotSpotJVMCICompilerFactory implements JVMCICompilerFactory {
+
+    /**
+     * Gets 0 or more prefixes identifying classes that should by compiled by C1 in simple mode
+     * (i.e., {@code CompLevel_simple}) when HotSpot is running with tiered compilation. The
+     * prefixes should be class or package names using "/" as the separator, e.g. "jdk/vm/ci".
+     *
+     * @return 0 or more Strings identifying packages that should by compiled by the first tier only
+     *         or null if no redirection to C1 should be performed.
+     */
+    public String[] getTrivialPrefixes() {
+        return null;
+    }
+
+    public enum CompilationLevelAdjustment {
+        /**
+         * No adjustment.
+         */
+        None,
+
+        /**
+         * Adjust based on declaring class of method.
+         */
+        ByHolder,
+
+        /**
+         * Adjust based on declaring class, name and signature of method.
+         */
+        ByFullSignature
+    }
+
+    /**
+     * Determines if this object may want to adjust the compilation level for a method that is being
+     * scheduled by the VM for compilation.
+     */
+    public CompilationLevelAdjustment getCompilationLevelAdjustment() {
+        return CompilationLevelAdjustment.None;
+    }
+
+    public enum CompilationLevel {
+        None,
+        Simple,
+        LimitedProfile,
+        FullProfile,
+        FullOptimization
+    }
+
+    /**
+     * Potentially modifies the compilation level currently selected by the VM compilation policy
+     * for a method.
+     *
+     * @param declaringClass the class in which the method is declared
+     * @param name the name of the method or {@code null} depending on the value that was returned
+     *            by {@link #getCompilationLevelAdjustment()}
+     * @param signature the signature of the method or {@code null} depending on the value that was
+     *            returned by {@link #getCompilationLevelAdjustment()}
+     * @param isOsr specifies if the compilation being scheduled in an OSR compilation
+     * @param level the compilation level currently selected by the VM compilation policy
+     * @return the compilation level to use for the compilation being scheduled (must be a valid
+     *         {@code CompLevel} enum value)
+     */
+    public CompilationLevel adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, CompilationLevel level) {
+        throw new InternalError("Should not reach here");
+    }
+}
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Thu Oct 20 16:53:56 2016 -0700
@@ -27,13 +27,11 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.ServiceLoader;
 import java.util.TreeMap;
 
 import jdk.internal.misc.VM;
@@ -43,16 +41,15 @@
 import jdk.vm.ci.code.InstalledCode;
 import jdk.vm.ci.common.InitTimer;
 import jdk.vm.ci.common.JVMCIError;
-import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory;
-import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory.CompilationLevel;
-import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory.CompilationLevel;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.runtime.JVMCI;
 import jdk.vm.ci.runtime.JVMCIBackend;
 import jdk.vm.ci.runtime.JVMCICompiler;
-import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
+import jdk.vm.ci.services.JVMCIServiceLocator;
 import jdk.vm.ci.services.Services;
 
 /**
@@ -90,14 +87,17 @@
      * A list of all supported JVMCI options.
      */
     public enum Option {
+        // @formatter:off
         Compiler(String.class, null, "Selects the system compiler."),
         // Note: The following one is not used (see InitTimer.ENABLED). It is added here
-        // so that -Djvmci.PrintFlags=true shows the option.
-        InitTimer(boolean.class, false, "Specifies if initialization timing is enabled."),
-        PrintConfig(boolean.class, false, "Prints VM configuration available via JVMCI and exits."),
-        PrintFlags(boolean.class, false, "Prints all JVMCI flags and exits."),
-        ShowFlags(boolean.class, false, "Prints all JVMCI flags and continues."),
-        TraceMethodDataFilter(String.class, null, "");
+        // so that -XX:+JVMCIPrintProperties shows the option.
+        InitTimer(Boolean.class, false, "Specifies if initialization timing is enabled."),
+        PrintConfig(Boolean.class, false, "Prints VM configuration available via JVMCI."),
+        TraceMethodDataFilter(String.class, null,
+                        "Enables tracing of profiling info when read by JVMCI.",
+                        "Empty value: trace all methods",
+                        "Non-empty value: trace methods whose fully qualified name contains the value.");
+        // @formatter:on
 
         /**
          * The prefix for system properties that are JVMCI options.
@@ -113,25 +113,25 @@
         private Object value;
         private final Object defaultValue;
         private boolean isDefault;
-        private final String help;
+        private final String[] helpLines;
 
-        Option(Class<?> type, Object defaultValue, String help) {
+        Option(Class<?> type, Object defaultValue, String... helpLines) {
             assert Character.isUpperCase(name().charAt(0)) : "Option name must start with upper-case letter: " + name();
             this.type = type;
             this.value = UNINITIALIZED;
             this.defaultValue = defaultValue;
-            this.help = help;
+            this.helpLines = helpLines;
         }
 
         @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "sentinel must be String since it's a static final in an enum")
         private Object getValue() {
             if (value == UNINITIALIZED) {
-                String propertyValue = VM.getSavedProperty(JVMCI_OPTION_PROPERTY_PREFIX + name());
+                String propertyValue = VM.getSavedProperty(getPropertyName());
                 if (propertyValue == null) {
                     this.value = defaultValue;
                     this.isDefault = true;
                 } else {
-                    if (type == boolean.class) {
+                    if (type == Boolean.class) {
                         this.value = Boolean.parseBoolean(propertyValue);
                     } else if (type == String.class) {
                         this.value = propertyValue;
@@ -147,6 +147,13 @@
         }
 
         /**
+         * Gets the name of system property from which this option gets its value.
+         */
+        public String getPropertyName() {
+            return JVMCI_OPTION_PROPERTY_PREFIX + name();
+        }
+
+        /**
          * Returns the option's value as boolean.
          *
          * @return option's value
@@ -165,16 +172,31 @@
         }
 
         /**
-         * Prints all option flags to {@code out}.
+         * Prints a description of the properties used to configure shared JVMCI code.
          *
          * @param out stream to print to
          */
-        public static void printFlags(PrintStream out) {
-            out.println("[List of JVMCI options]");
-            for (Option option : values()) {
+        public static void printProperties(PrintStream out) {
+            out.println("[JVMCI properties]");
+            int typeWidth = 0;
+            int nameWidth = 0;
+            Option[] values = values();
+            for (Option option : values) {
+                typeWidth = Math.max(typeWidth, option.type.getSimpleName().length());
+                nameWidth = Math.max(nameWidth, option.getPropertyName().length());
+            }
+            for (Option option : values) {
                 Object value = option.getValue();
-                String assign = option.isDefault ? ":=" : " =";
-                out.printf("%9s %-40s %s %-14s %s%n", option.type.getSimpleName(), option, assign, value, option.help);
+                if (value instanceof String) {
+                    value = '"' + String.valueOf(value) + '"';
+                }
+                String assign = option.isDefault ? " =" : ":=";
+                String format = "%" + (typeWidth + 1) + "s %-" + (nameWidth + 1) + "s %s %s%n";
+                out.printf(format, option.type.getSimpleName(), option.getPropertyName(), assign, value);
+                String helpFormat = "%" + (typeWidth + 1) + "s %s%n";
+                for (String line : option.helpLines) {
+                    out.printf(helpFormat, "", line);
+                }
             }
         }
     }
@@ -221,11 +243,7 @@
         if (vmEventListeners == null) {
             synchronized (this) {
                 if (vmEventListeners == null) {
-                    List<HotSpotVMEventListener> listeners = new ArrayList<>();
-                    for (HotSpotVMEventListener vmEventListener : ServiceLoader.load(HotSpotVMEventListener.class)) {
-                        listeners.add(vmEventListener);
-                    }
-                    vmEventListeners = listeners;
+                    vmEventListeners = JVMCIServiceLocator.getProviders(HotSpotVMEventListener.class);
                 }
             }
         }
@@ -239,7 +257,6 @@
     @SuppressWarnings("unused") private final String[] trivialPrefixes;
 
     @SuppressWarnings("try")
-    @SuppressFBWarnings(value = "DM_EXIT", justification = "PrintFlags is meant to exit the VM")
     private HotSpotJVMCIRuntime() {
         compilerToVm = new CompilerToVM();
 
@@ -261,20 +278,6 @@
 
         metaAccessContext = new HotSpotJVMCIMetaAccessContext();
 
-        boolean printFlags = Option.PrintFlags.getBoolean();
-        boolean showFlags = Option.ShowFlags.getBoolean();
-        if (printFlags || showFlags) {
-            Option.printFlags(System.out);
-            if (printFlags) {
-                System.exit(0);
-            }
-        }
-
-        if (Option.PrintConfig.getBoolean()) {
-            printConfig(configStore, compilerToVm);
-            System.exit(0);
-        }
-
         compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
         if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
             hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
@@ -298,6 +301,16 @@
             trivialPrefixes = null;
             compilationLevelAdjustment = config.compLevelAdjustmentNone;
         }
+
+        if (config.getFlag("JVMCIPrintProperties", Boolean.class)) {
+            PrintStream out = new PrintStream(getLogStream());
+            Option.printProperties(out);
+            compilerFactory.printProperties(out);
+        }
+
+        if (Option.PrintConfig.getBoolean()) {
+            printConfig(configStore, compilerToVm);
+        }
     }
 
     private JVMCIBackend registerBackend(JVMCIBackend backend) {
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java	Thu Oct 20 16:53:56 2016 -0700
@@ -53,9 +53,9 @@
      * Reference to the C++ MethodData object.
      */
     final long metaspaceMethodData;
-    @SuppressWarnings("unused") private final HotSpotResolvedJavaMethodImpl method;
+    private final HotSpotResolvedJavaMethodImpl method;
 
-    public HotSpotMethodData(long metaspaceMethodData, HotSpotResolvedJavaMethodImpl method) {
+    HotSpotMethodData(long metaspaceMethodData, HotSpotResolvedJavaMethodImpl method) {
         this.metaspaceMethodData = metaspaceMethodData;
         this.method = method;
     }
@@ -107,6 +107,18 @@
         return UNSAFE.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + config.deoptReasonOSROffset + reasonIndex) & 0xFF;
     }
 
+    public int getDecompileCount() {
+        return UNSAFE.getInt(metaspaceMethodData + config.methodDataDecompiles);
+    }
+
+    public int getOverflowRecompileCount() {
+        return UNSAFE.getInt(metaspaceMethodData + config.methodDataOverflowRecompiles);
+    }
+
+    public int getOverflowTrapCount() {
+        return UNSAFE.getInt(metaspaceMethodData + config.methodDataOverflowTraps);
+    }
+
     public HotSpotMethodDataAccessor getNormalData(int position) {
         if (position >= normalDataSize()) {
             return null;
@@ -214,6 +226,12 @@
         StringBuilder sb = new StringBuilder();
         String nl = String.format("%n");
         String nlIndent = String.format("%n%38s", "");
+        sb.append("Raw method data for ");
+        sb.append(method.format("%H.%n(%p)"));
+        sb.append(":");
+        sb.append(nl);
+        sb.append(String.format("nof_decompiles(%d) nof_overflow_recompiles(%d) nof_overflow_traps(%d)%n",
+                        getDecompileCount(), getOverflowRecompileCount(), getOverflowTrapCount()));
         if (hasNormalData()) {
             int pos = 0;
             HotSpotMethodDataAccessor data;
@@ -427,6 +445,10 @@
 
         protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position);
 
+        public int getNonprofiledCount(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, NONPROFILED_COUNT_OFFSET);
+        }
+
         private JavaTypeProfile createTypeProfile(TriState nullSeen, RawItemProfile<ResolvedJavaType> profile) {
             if (profile.entries <= 0 || profile.totalCount <= 0) {
                 return null;
@@ -462,7 +484,7 @@
             TriState nullSeen = getNullSeen(data, pos);
             TriState exceptionSeen = getExceptionSeen(data, pos);
             sb.append(format("count(%d) null_seen(%s) exception_seen(%s) nonprofiled_count(%d) entries(%d)", getCounterValue(data, pos), nullSeen, exceptionSeen,
-                            getTypesNotRecordedExecutionCount(data, pos), profile.entries));
+                            getNonprofiledCount(data, pos), profile.entries));
             for (int i = 0; i < profile.entries; i++) {
                 long count = profile.counts[i];
                 sb.append(format("%n  %s (%d, %4.2f)", profile.items[i].toJavaName(), count, (double) count / profile.totalCount));
@@ -490,7 +512,7 @@
 
         @Override
         protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) {
-            return data.readUnsignedIntAsSignedInt(position, NONPROFILED_COUNT_OFFSET);
+            return getNonprofiledCount(data, position);
         }
     }
 
@@ -788,7 +810,8 @@
 
         @Override
         public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
-            return null;
+            sb.append("unknown profile data with tag: " + tag);
+            return sb;
         }
     }
 
@@ -822,10 +845,10 @@
     private static boolean checkAccessorTags() {
         int expectedTag = 0;
         for (HotSpotMethodDataAccessor accessor : PROFILE_DATA_ACCESSORS) {
-            if (expectedTag ==0 ) {
+            if (expectedTag == 0) {
                 assert accessor == null;
             } else {
-                assert accessor.tag == expectedTag: expectedTag + " != " + accessor.tag + " " + accessor;
+                assert accessor.tag == expectedTag : expectedTag + " != " + accessor.tag + " " + accessor;
             }
             expectedTag++;
         }
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java	Thu Oct 20 16:53:56 2016 -0700
@@ -57,6 +57,18 @@
         return method.getCodeSize();
     }
 
+    public int getDecompileCount() {
+        return methodData.getDecompileCount();
+    }
+
+    public int getOverflowRecompileCount() {
+        return methodData.getOverflowRecompileCount();
+    }
+
+    public int getOverflowTrapCount() {
+        return methodData.getOverflowTrapCount();
+    }
+
     @Override
     public JavaTypeProfile getTypeProfile(int bci) {
         if (!isMature) {
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Thu Oct 20 16:53:56 2016 -0700
@@ -434,7 +434,6 @@
                 methodData = new HotSpotMethodData(metaspaceMethodData, this);
                 String methodDataFilter = Option.TraceMethodDataFilter.getString();
                 if (methodDataFilter != null && this.format("%H.%n").contains(methodDataFilter)) {
-                    System.out.println("Raw method data for " + this.format("%H.%n(%p)") + ":");
                     System.out.println(methodData.toString());
                 }
             }
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Thu Oct 20 16:53:56 2016 -0700
@@ -160,6 +160,10 @@
     final int methodDataOopTrapHistoryOffset = getFieldOffset("MethodData::_trap_hist._array[0]", Integer.class, "u1");
     final int methodDataIRSizeOffset = getFieldOffset("MethodData::_jvmci_ir_size", Integer.class, "int");
 
+    final int methodDataDecompiles = getFieldOffset("MethodData::_nof_decompiles", Integer.class, "uint");
+    final int methodDataOverflowRecompiles = getFieldOffset("MethodData::_nof_overflow_recompiles", Integer.class, "uint");
+    final int methodDataOverflowTraps = getFieldOffset("MethodData::_nof_overflow_traps", Integer.class, "uint");
+
     final int nmethodCompLevelOffset = getFieldOffset("nmethod::_comp_level", Integer.class, "int");
 
     final int compilationLevelNone = getConstant("CompLevel_none", Integer.class);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java	Thu Oct 20 16:53:56 2016 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.CompiledCode;
+import jdk.vm.ci.code.InstalledCode;
+
+/**
+ * Listener for responding to VM events.
+ */
+public interface HotSpotVMEventListener {
+
+    /**
+     * Notifies this client that the VM is shutting down.
+     */
+    default void notifyShutdown() {
+    }
+
+    /**
+     * Notify on successful install into the code cache.
+     *
+     * @param hotSpotCodeCacheProvider the code cache into which the code was installed
+     * @param installedCode the code that was installed
+     * @param compiledCode the compiled code from which {@code installedCode} was produced
+     */
+    default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
+    }
+
+    /**
+     * Notify on completion of a bootstrap.
+     */
+    default void notifyBootstrapFinished() {
+    }
+}
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EmptyEventProvider.java	Thu Oct 20 20:01:43 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot.services;
-
-/**
- * An empty implementation for {@link EventProvider}. This implementation is used when no logging is
- * requested.
- */
-final class EmptyEventProvider extends EventProvider {
-
-    EmptyEventProvider() {
-        super(null);
-    }
-
-    static InternalError shouldNotReachHere() {
-        throw new InternalError("should not reach here");
-    }
-
-    @Override
-    public CompilationEvent newCompilationEvent() {
-        return new EmptyCompilationEvent();
-    }
-
-    static class EmptyCompilationEvent implements CompilationEvent {
-        public void commit() {
-            throw shouldNotReachHere();
-        }
-
-        public boolean shouldWrite() {
-            // Events of this class should never been written.
-            return false;
-        }
-
-        public void begin() {
-        }
-
-        public void end() {
-        }
-
-        public void setMethod(String method) {
-            throw shouldNotReachHere();
-        }
-
-        public void setCompileId(int compileId) {
-            throw shouldNotReachHere();
-        }
-
-        public void setCompileLevel(int compileLevel) {
-            throw shouldNotReachHere();
-        }
-
-        public void setSucceeded(boolean succeeded) {
-            throw shouldNotReachHere();
-        }
-
-        public void setIsOsr(boolean isOsr) {
-            throw shouldNotReachHere();
-        }
-
-        public void setCodeSize(int codeSize) {
-            throw shouldNotReachHere();
-        }
-
-        public void setInlinedBytes(int inlinedBytes) {
-            throw shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public CompilerFailureEvent newCompilerFailureEvent() {
-        return new EmptyCompilerFailureEvent();
-    }
-
-    static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
-        public void commit() {
-            throw shouldNotReachHere();
-        }
-
-        public boolean shouldWrite() {
-            // Events of this class should never been written.
-            return false;
-        }
-
-        public void setCompileId(int compileId) {
-            throw shouldNotReachHere();
-        }
-
-        public void setMessage(String message) {
-            throw shouldNotReachHere();
-        }
-    }
-
-}
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EventProvider.java	Thu Oct 20 20:01:43 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot.services;
-
-import jdk.vm.ci.hotspot.services.EmptyEventProvider.EmptyCompilationEvent;
-import jdk.vm.ci.hotspot.services.EmptyEventProvider.EmptyCompilerFailureEvent;
-import jdk.vm.ci.services.JVMCIPermission;
-
-/**
- * Service-provider class for logging compiler related events.
- */
-public abstract class EventProvider {
-
-    private static Void checkPermission() {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new JVMCIPermission());
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unused")
-    EventProvider(Void ignore) {
-    }
-
-    /**
-     * Initializes a new instance of this class.
-     *
-     * @throws SecurityException if a security manager has been installed and it denies
-     *             {@link JVMCIPermission}
-     */
-    protected EventProvider() {
-        this(checkPermission());
-    }
-
-    /**
-     * Creates and returns an empty implementation for {@link EventProvider}. This implementation
-     * can be used when no logging is requested.
-     */
-    public static EventProvider createEmptyEventProvider() {
-        return new EmptyEventProvider();
-    }
-
-    /**
-     * Creates and returns an empty implementation for {@link CompilationEvent}.
-     */
-    public static CompilationEvent createEmptyCompilationEvent() {
-        return new EmptyCompilationEvent();
-    }
-
-    /**
-     * Creates and returns an empty implementation for {@link CompilationEvent}.
-     */
-    public static CompilerFailureEvent createEmptyCompilerFailureEvent() {
-        return new EmptyCompilerFailureEvent();
-    }
-
-    /**
-     * An instant event is an event that is not considered to have taken any time.
-     */
-    public interface InstantEvent {
-        /**
-         * Commits the event.
-         */
-        void commit();
-
-        /**
-         * Determines if this particular event instance would be committed to the data stream right
-         * now if application called {@link #commit()}. This in turn depends on whether the event is
-         * enabled and possible other factors.
-         *
-         * @return if this event would be committed on a call to {@link #commit()}.
-         */
-        boolean shouldWrite();
-    }
-
-    /**
-     * Timed events describe an operation that somehow consumes time.
-     */
-    public interface TimedEvent extends InstantEvent {
-        /**
-         * Starts the timing for this event.
-         */
-        void begin();
-
-        /**
-         * Ends the timing period for this event.
-         */
-        void end();
-    }
-
-    /**
-     * Creates a new {@link CompilationEvent}.
-     *
-     * @return a compilation event
-     */
-    public abstract CompilationEvent newCompilationEvent();
-
-    /**
-     * A compilation event.
-     */
-    public interface CompilationEvent extends TimedEvent {
-        void setMethod(String method);
-
-        void setCompileId(int compileId);
-
-        void setCompileLevel(int compileLevel);
-
-        void setSucceeded(boolean succeeded);
-
-        void setIsOsr(boolean isOsr);
-
-        void setCodeSize(int codeSize);
-
-        void setInlinedBytes(int inlinedBytes);
-    }
-
-    /**
-     * Creates a new {@link CompilerFailureEvent}.
-     *
-     * @return a compiler failure event
-     */
-    public abstract CompilerFailureEvent newCompilerFailureEvent();
-
-    /**
-     * A compiler failure event.
-     */
-    public interface CompilerFailureEvent extends InstantEvent {
-        void setCompileId(int compileId);
-
-        void setMessage(String message);
-    }
-}
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotJVMCICompilerFactory.java	Thu Oct 20 20:01:43 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot.services;
-
-import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
-
-/**
- * HotSpot extensions to {@link JVMCICompilerFactory}.
- */
-public abstract class HotSpotJVMCICompilerFactory extends JVMCICompilerFactory {
-
-    /**
-     * Gets 0 or more prefixes identifying classes that should by compiled by C1 in simple mode
-     * (i.e., {@code CompLevel_simple}) when HotSpot is running with tiered compilation. The
-     * prefixes should be class or package names using "/" as the separator, e.g. "jdk/vm/ci".
-     *
-     * @return 0 or more Strings identifying packages that should by compiled by the first tier only
-     *         or null if no redirection to C1 should be performed.
-     */
-    public String[] getTrivialPrefixes() {
-        return null;
-    }
-
-    public enum CompilationLevelAdjustment {
-        /**
-         * No adjustment.
-         */
-        None,
-
-        /**
-         * Adjust based on declaring class of method.
-         */
-        ByHolder,
-
-        /**
-         * Adjust based on declaring class, name and signature of method.
-         */
-        ByFullSignature
-    }
-
-    /**
-     * Determines if this object may want to adjust the compilation level for a method that is being
-     * scheduled by the VM for compilation.
-     */
-    public CompilationLevelAdjustment getCompilationLevelAdjustment() {
-        return CompilationLevelAdjustment.None;
-    }
-
-    public enum CompilationLevel {
-        None,
-        Simple,
-        LimitedProfile,
-        FullProfile,
-        FullOptimization
-    }
-
-    /**
-     * Potentially modifies the compilation level currently selected by the VM compilation policy
-     * for a method.
-     *
-     * @param declaringClass the class in which the method is declared
-     * @param name the name of the method or {@code null} depending on the value that was returned
-     *            by {@link #getCompilationLevelAdjustment()}
-     * @param signature the signature of the method or {@code null} depending on the value that was
-     *            returned by {@link #getCompilationLevelAdjustment()}
-     * @param isOsr specifies if the compilation being scheduled in an OSR compilation
-     * @param level the compilation level currently selected by the VM compilation policy
-     * @return the compilation level to use for the compilation being scheduled (must be a valid
-     *         {@code CompLevel} enum value)
-     */
-    public CompilationLevel adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, CompilationLevel level) {
-        throw new InternalError("Should not reach here");
-    }
-}
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotVMEventListener.java	Thu Oct 20 20:01:43 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot.services;
-
-import jdk.vm.ci.code.CompiledCode;
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
-import jdk.vm.ci.services.JVMCIPermission;
-
-/**
- * Service-provider class for responding to VM events.
- */
-public abstract class HotSpotVMEventListener {
-
-    private static Void checkPermission() {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new JVMCIPermission());
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unused")
-    HotSpotVMEventListener(Void ignore) {
-    }
-
-    /**
-     * Initializes a new instance of this class.
-     *
-     * @throws SecurityException if a security manager has been installed and it denies
-     *             {@link JVMCIPermission}
-     */
-    protected HotSpotVMEventListener() {
-        this(checkPermission());
-    }
-
-    /**
-     * Notifies this client that the VM is shutting down.
-     */
-    public void notifyShutdown() {
-    }
-
-    /**
-     * Notify on successful install into the code cache.
-     *
-     * @param hotSpotCodeCacheProvider
-     * @param installedCode
-     * @param compiledCode
-     */
-    public void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
-    }
-
-    /**
-     * Notify on completion of a bootstrap.
-     */
-    public void notifyBootstrapFinished() {
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java	Thu Oct 20 16:53:56 2016 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.runtime;
+
+import java.io.PrintStream;
+
+/**
+ * Factory for creating JVMCI compilers.
+ */
+public interface JVMCICompilerFactory {
+
+    /**
+     * Get the name of this compiler. The name is used by JVMCI to determine which factory to use.
+     */
+    String getCompilerName();
+
+    /**
+     * Notifies this object that it has been selected to {@linkplain #createCompiler(JVMCIRuntime)
+     * create} a compiler and it should now perform any heavy weight initialization that it deferred
+     * during construction.
+     */
+    default void onSelection() {
+    }
+
+    /**
+     * Create a new instance of a {@link JVMCICompiler}.
+     */
+    JVMCICompiler createCompiler(JVMCIRuntime runtime);
+
+    /**
+     * Prints a description of the properties used to configure this compiler.
+     *
+     * @param out where to print the message
+     */
+    default void printProperties(PrintStream out) {
+    }
+}
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java	Thu Oct 20 20:01:43 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.runtime.services;
-
-import jdk.vm.ci.runtime.JVMCICompiler;
-import jdk.vm.ci.runtime.JVMCIRuntime;
-import jdk.vm.ci.services.JVMCIPermission;
-
-/**
- * Service-provider class for creating JVMCI compilers.
- */
-public abstract class JVMCICompilerFactory {
-
-    private static Void checkPermission() {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new JVMCIPermission());
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unused")
-    private JVMCICompilerFactory(Void ignore) {
-    }
-
-    /**
-     * Initializes a new instance of this class.
-     *
-     * @throws SecurityException if a security manager has been installed and it denies
-     *             {@link JVMCIPermission}
-     */
-    protected JVMCICompilerFactory() {
-        this(checkPermission());
-    }
-
-    /**
-     * Get the name of this compiler. The name is used by JVMCI to determine which factory to use.
-     */
-    public abstract String getCompilerName();
-
-    /**
-     * Notifies this object that it has been selected to {@linkplain #createCompiler(JVMCIRuntime)
-     * create} a compiler and it should now perform any heavy weight initialization that it deferred
-     * during construction.
-     */
-    public void onSelection() {
-    }
-
-    /**
-     * Create a new instance of a {@link JVMCICompiler}.
-     */
-    public abstract JVMCICompiler createCompiler(JVMCIRuntime runtime);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java	Thu Oct 20 16:53:56 2016 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.services;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Service-provider class for the runtime to locate providers of JVMCI services where the latter are
+ * not in packages exported by the JVMCI module. As part of instantiating
+ * {@link JVMCIServiceLocator}, all JVMCI packages will be {@linkplain Services#exportJVMCITo(Class)
+ * exported} to the module defining the class of the instantiated object.
+ *
+ * While the {@link #getProvider(Class)} method can be used directly, it's usually easier to use
+ * {@link #getProviders(Class)}.
+ */
+public abstract class JVMCIServiceLocator {
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new JVMCIPermission());
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    private JVMCIServiceLocator(Void ignore) {
+    }
+
+    /**
+     * Creates a capability for accessing JVMCI. Once successfully instantiated, JVMCI exports all
+     * its packages to the module defining the type of this object.
+     *
+     * @throws SecurityException if a security manager has been installed and it denies
+     *             {@link JVMCIPermission}
+     */
+    protected JVMCIServiceLocator() {
+        this(checkPermission());
+        Services.exportJVMCITo(getClass());
+    }
+
+    /**
+     * Gets the provider of the service defined by {@code service} or {@code null} if this object
+     * does not have a provider for {@code service}.
+     */
+    public abstract <S> S getProvider(Class<S> service);
+
+    /**
+     * Gets the providers of the service defined by {@code service} by querying the
+     * {@link JVMCIServiceLocator} providers obtained by {@link Services#load(Class)}.
+     */
+    public static <S> List<S> getProviders(Class<S> service) {
+        List<S> providers = new ArrayList<>();
+        for (JVMCIServiceLocator access : Services.load(JVMCIServiceLocator.class)) {
+            S provider = access.getProvider(service);
+            if (provider != null) {
+                providers.add(provider);
+            }
+        }
+        return providers;
+    }
+}
--- a/src/jdk.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARC.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARC.java	Thu Oct 20 16:53:56 2016 -0700
@@ -349,7 +349,6 @@
         SUN4V,
         BLK_INIT_INSTRUCTIONS,
         FMAF,
-        FMAU,
         SPARC64_FAMILY,
         M_FAMILY,
         T_FAMILY,
--- a/src/jdk.vm.ci/share/classes/module-info.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/jdk.vm.ci/share/classes/module-info.java	Thu Oct 20 16:53:56 2016 -0700
@@ -25,12 +25,9 @@
 
 module jdk.vm.ci {
     exports jdk.vm.ci.services;
-    exports jdk.vm.ci.runtime.services;
-    exports jdk.vm.ci.hotspot.services;
 
-    uses jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
+    uses jdk.vm.ci.services.JVMCIServiceLocator;
     uses jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
-    uses jdk.vm.ci.runtime.services.JVMCICompilerFactory;
 
     provides jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory with
         jdk.vm.ci.hotspot.aarch64.AArch64HotSpotJVMCIBackendFactory;
--- a/src/os/solaris/vm/os_solaris.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/os/solaris/vm/os_solaris.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -2563,7 +2563,7 @@
   uint64_t outdata[2];
   uint_t validity = 0;
 
-  if (os::Solaris::meminfo(&addr, 1, info_types, 2, outdata, &validity) < 0) {
+  if (meminfo(&addr, 1, info_types, 2, outdata, &validity) < 0) {
     return false;
   }
 
@@ -2601,7 +2601,7 @@
       addrs_count++;
     }
 
-    if (os::Solaris::meminfo(addrs, addrs_count, info_types, types, outdata, validity) < 0) {
+    if (meminfo(addrs, addrs_count, info_types, types, outdata, validity) < 0) {
       return NULL;
     }
 
@@ -4160,9 +4160,6 @@
 void report_error(const char* file_name, int line_no, const char* title,
                   const char* format, ...);
 
-// (Static) wrapper for getisax(2) call.
-os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
-
 // (Static) wrappers for the liblgrp API
 os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
 os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
@@ -4174,9 +4171,6 @@
 os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale;
 os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
 
-// (Static) wrapper for meminfo() call.
-os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
-
 static address resolve_symbol_lazy(const char* name) {
   address addr = (address) dlsym(RTLD_DEFAULT, name);
   if (addr == NULL) {
@@ -4300,27 +4294,6 @@
   return false;
 }
 
-void os::Solaris::misc_sym_init() {
-  address func;
-
-  // getisax
-  func = resolve_symbol_lazy("getisax");
-  if (func != NULL) {
-    os::Solaris::_getisax = CAST_TO_FN_PTR(getisax_func_t, func);
-  }
-
-  // meminfo
-  func = resolve_symbol_lazy("meminfo");
-  if (func != NULL) {
-    os::Solaris::set_meminfo(CAST_TO_FN_PTR(meminfo_func_t, func));
-  }
-}
-
-uint_t os::Solaris::getisax(uint32_t* array, uint_t n) {
-  assert(_getisax != NULL, "_getisax not set");
-  return _getisax(array, n);
-}
-
 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem);
 typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem);
 static pset_getloadavg_type pset_getloadavg_ptr = NULL;
@@ -4351,10 +4324,6 @@
 
   Solaris::initialize_system_info();
 
-  // Initialize misc. symbols as soon as possible, so we can use them
-  // if we need them.
-  Solaris::misc_sym_init();
-
   int fd = ::open("/dev/zero", O_RDWR);
   if (fd < 0) {
     fatal("os::init: cannot open /dev/zero (%s)", os::strerror(errno));
--- a/src/os/solaris/vm/os_solaris.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/os/solaris/vm/os_solaris.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -73,8 +73,6 @@
     LGRP_VIEW_OS            // what's available to operating system
   } lgrp_view_t;
 
-  typedef uint_t (*getisax_func_t)(uint32_t* array, uint_t n);
-
   typedef lgrp_id_t (*lgrp_home_func_t)(idtype_t idtype, id_t id);
   typedef lgrp_cookie_t (*lgrp_init_func_t)(lgrp_view_t view);
   typedef int (*lgrp_fini_func_t)(lgrp_cookie_t cookie);
@@ -86,11 +84,6 @@
                                        lgrp_rsrc_t type);
   typedef int (*lgrp_nlgrps_func_t)(lgrp_cookie_t cookie);
   typedef int (*lgrp_cookie_stale_func_t)(lgrp_cookie_t cookie);
-  typedef int (*meminfo_func_t)(const uint64_t inaddr[],   int addr_count,
-                                const uint_t  info_req[],  int info_count,
-                                uint64_t  outdata[], uint_t validity[]);
-
-  static getisax_func_t _getisax;
 
   static lgrp_home_func_t _lgrp_home;
   static lgrp_init_func_t _lgrp_init;
@@ -102,8 +95,6 @@
   static lgrp_cookie_stale_func_t _lgrp_cookie_stale;
   static lgrp_cookie_t _lgrp_cookie;
 
-  static meminfo_func_t _meminfo;
-
   // Large Page Support
   static bool is_valid_page_size(size_t bytes);
   static size_t page_size_for_alignment(size_t alignment);
@@ -191,8 +182,6 @@
   static void libthread_init();
   static void synchronization_init();
   static bool liblgrp_init();
-  // Load miscellaneous symbols.
-  static void misc_sym_init();
   // This boolean allows users to forward their own non-matching signals
   // to JVM_handle_solaris_signal, harmlessly.
   static bool signal_handlers_are_installed;
@@ -272,17 +261,6 @@
   }
   static lgrp_cookie_t lgrp_cookie()                 { return _lgrp_cookie; }
 
-  static bool supports_getisax()                     { return _getisax != NULL; }
-  static uint_t getisax(uint32_t* array, uint_t n);
-
-  static void set_meminfo(meminfo_func_t func)       { _meminfo = func; }
-  static int meminfo (const uint64_t inaddr[],   int addr_count,
-                      const uint_t  info_req[],  int info_count,
-                      uint64_t  outdata[], uint_t validity[]) {
-    return _meminfo != NULL ? _meminfo(inaddr, addr_count, info_req, info_count,
-                                       outdata, validity) : -1;
-  }
-
   static sigset_t* unblocked_signals();
   static sigset_t* vm_signals();
   static sigset_t* allowdebug_blocked_signals();
--- a/src/os/windows/vm/os_windows.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/os/windows/vm/os_windows.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -784,7 +784,7 @@
 
   __try {
     RaiseException (MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR*)&info );
-  } __except(EXCEPTION_CONTINUE_EXECUTION) {}
+  } __except(EXCEPTION_EXECUTE_HANDLER) {}
 }
 
 bool os::distribute_processes(uint length, uint* distribution) {
--- a/src/os/windows/vm/perfMemory_windows.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/os/windows/vm/perfMemory_windows.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1404,12 +1404,14 @@
                objectname);      /* name for object */
 
   if (fmh == NULL) {
+    DWORD lasterror = GetLastError();
     if (PrintMiscellaneous && Verbose) {
       warning("OpenFileMapping failed for shared memory object %s:"
-              " lasterror = %d\n", objectname, GetLastError());
+              " lasterror = %d\n", objectname, lasterror);
     }
-    THROW_MSG_(vmSymbols::java_lang_Exception(),
-               "Could not open PerfMemory", INVALID_HANDLE_VALUE);
+    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+               err_msg("Could not open PerfMemory, error %d", lasterror),
+               INVALID_HANDLE_VALUE);
   }
 
   return fmh;;
--- a/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -343,8 +343,15 @@
 #define _SC_L2CACHE_LINESZ      527     /* Size of L2 cache line */
 #endif
 
+// Hardware capability bits that appeared after Solaris 11.1
+#ifndef AV_SPARC_FMAF
+#define AV_SPARC_FMAF    0x00000100 /* Fused Multiply-Add */
+#endif
+#ifndef AV2_SPARC_SPARC5
+#define AV2_SPARC_SPARC5 0x00000008 /* The 29 new fp and sub instructions */
+#endif
+
 int VM_Version::platform_features(int features) {
-  assert(os::Solaris::supports_getisax(), "getisax() must be available");
 
   // Check 32-bit architecture.
   if (Sysinfo(SI_ARCHITECTURE_32).match("sparc")) {
@@ -357,119 +364,75 @@
   }
 
   // Extract valid instruction set extensions.
-  uint_t avs[2];
-  uint_t avn = os::Solaris::getisax(avs, 2);
-  assert(avn <= 2, "should return two or less av's");
-  uint_t av = avs[0];
+  uint_t avs[AV_HW2_IDX + 1];
+  uint_t avn = getisax(avs, ARRAY_SIZE(avs));
 
-  log_info(os, cpu)("getisax(2) returned: " PTR32_FORMAT, av);
-  if (avn > 1) {
-    log_info(os, cpu)(" " PTR32_FORMAT, avs[1]);
+  log_info(os, cpu)("getisax(2) returned %d words:", avn);
+  for (int i = 0; i < avn; i++) {
+    log_info(os, cpu)("    word %d: " PTR32_FORMAT, i, avs[i]);
   }
 
-  if (av & AV_SPARC_MUL32)  features |= hardware_mul32_m;
-  if (av & AV_SPARC_DIV32)  features |= hardware_div32_m;
-  if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;
-  if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m;
-  if (av & AV_SPARC_POPC)   features |= hardware_popc_m;
-  if (av & AV_SPARC_VIS)    features |= vis1_instructions_m;
-  if (av & AV_SPARC_VIS2)   features |= vis2_instructions_m;
-  if (avn > 1) {
-    uint_t av2 = avs[1];
-#ifndef AV2_SPARC_SPARC5
-#define AV2_SPARC_SPARC5 0x00000008 /* The 29 new fp and sub instructions */
-#endif
-    if (av2 & AV2_SPARC_SPARC5)       features |= sparc5_instructions_m;
+  uint_t av1 = avs[AV_HW1_IDX];
+  if (av1 & AV_SPARC_MUL32)        features |= hardware_mul32_m;
+  if (av1 & AV_SPARC_DIV32)        features |= hardware_div32_m;
+  if (av1 & AV_SPARC_FSMULD)       features |= hardware_fsmuld_m;
+  if (av1 & AV_SPARC_V8PLUS)       features |= v9_instructions_m;
+  if (av1 & AV_SPARC_POPC)         features |= hardware_popc_m;
+  if (av1 & AV_SPARC_VIS)          features |= vis1_instructions_m;
+  if (av1 & AV_SPARC_VIS2)         features |= vis2_instructions_m;
+  if (av1 & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
+  if (av1 & AV_SPARC_FMAF)         features |= fmaf_instructions_m;
+  if (av1 & AV_SPARC_VIS3)         features |= vis3_instructions_m;
+  if (av1 & AV_SPARC_CBCOND)       features |= cbcond_instructions_m;
+  if (av1 & AV_SPARC_CRC32C)       features |= crc32c_instruction_m;
+  if (av1 & AV_SPARC_AES)          features |= aes_instructions_m;
+  if (av1 & AV_SPARC_SHA1)         features |= sha1_instruction_m;
+  if (av1 & AV_SPARC_SHA256)       features |= sha256_instruction_m;
+  if (av1 & AV_SPARC_SHA512)       features |= sha512_instruction_m;
+
+  if (avn > AV_HW2_IDX) {
+    uint_t av2 = avs[AV_HW2_IDX];
+    if (av2 & AV2_SPARC_SPARC5)    features |= sparc5_instructions_m;
   }
 
-  // We only build on Solaris 10 and up, but some of the values below
-  // are not defined on all versions of Solaris 10, so we define them,
-  // if necessary.
-#ifndef AV_SPARC_ASI_BLK_INIT
-#define AV_SPARC_ASI_BLK_INIT 0x0080  /* ASI_BLK_INIT_xxx ASI */
-#endif
-  if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
-
-#ifndef AV_SPARC_FMAF
-#define AV_SPARC_FMAF 0x0100        /* Fused Multiply-Add */
-#endif
-  if (av & AV_SPARC_FMAF)         features |= fmaf_instructions_m;
-
-#ifndef AV_SPARC_FMAU
-#define AV_SPARC_FMAU    0x0200  /* Unfused Multiply-Add */
-#endif
-  if (av & AV_SPARC_FMAU)         features |= fmau_instructions_m;
-
-#ifndef AV_SPARC_VIS3
-#define AV_SPARC_VIS3    0x0400  /* VIS3 instruction set extensions */
-#endif
-  if (av & AV_SPARC_VIS3)         features |= vis3_instructions_m;
-
-#ifndef AV_SPARC_CBCOND
-#define AV_SPARC_CBCOND 0x10000000  /* compare and branch instrs supported */
-#endif
-  if (av & AV_SPARC_CBCOND)       features |= cbcond_instructions_m;
-
-#ifndef AV_SPARC_CRC32C
-#define AV_SPARC_CRC32C 0x20000000  /* crc32c instruction supported */
-#endif
-  if (av & AV_SPARC_CRC32C)       features |= crc32c_instruction_m;
-
-#ifndef AV_SPARC_AES
-#define AV_SPARC_AES 0x00020000  /* aes instrs supported */
-#endif
-  if (av & AV_SPARC_AES)       features |= aes_instructions_m;
-
-#ifndef AV_SPARC_SHA1
-#define AV_SPARC_SHA1   0x00400000  /* sha1 instruction supported */
-#endif
-  if (av & AV_SPARC_SHA1)         features |= sha1_instruction_m;
-
-#ifndef AV_SPARC_SHA256
-#define AV_SPARC_SHA256 0x00800000  /* sha256 instruction supported */
-#endif
-  if (av & AV_SPARC_SHA256)       features |= sha256_instruction_m;
-
-#ifndef AV_SPARC_SHA512
-#define AV_SPARC_SHA512 0x01000000  /* sha512 instruction supported */
-#endif
-  if (av & AV_SPARC_SHA512)       features |= sha512_instruction_m;
-
   // Determine the machine type.
   if (Sysinfo(SI_MACHINE).match("sun4v")) {
     features |= sun4v_m;
   }
 
-  bool use_solaris_12_api = false;
-  Sysinfo impl(SI_CPUBRAND);
-  if (impl.valid()) {
-    // If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes
-    // is available to us as well
-    use_solaris_12_api = true;
-    features |= parse_features(impl.value());
+  // If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes
+  // is available to us as well
+  Sysinfo cpu_info(SI_CPUBRAND);
+  bool use_solaris_12_api = cpu_info.valid();
+  const char* impl;
+  int impl_m = 0;
+  if (use_solaris_12_api) {
+    impl = cpu_info.value();
+    log_info(os, cpu)("Parsing CPU implementation from %s", impl);
+    impl_m = parse_features(impl);
   } else {
     // Otherwise use kstat to determine the machine type.
     kstat_ctl_t* kc = kstat_open();
-    kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
-    const char* implementation;
-    bool has_implementation = false;
-    if (ksp != NULL) {
-      if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
-        kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
-        for (int i = 0; i < ksp->ks_ndata; i++) {
-          if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
-            implementation = KSTAT_NAMED_STR_PTR(&knm[i]);
-            has_implementation = true;
-            log_info(os, cpu)("cpu_info.implementation: %s", implementation);
-            features |= parse_features(implementation);
-            break;
+    if (kc != NULL) {
+      kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
+      if (ksp != NULL) {
+        if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
+          kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
+          for (int i = 0; i < ksp->ks_ndata; i++) {
+            if (strcmp((const char*)&(knm[i].name), "implementation") == 0) {
+              impl = KSTAT_NAMED_STR_PTR(&knm[i]);
+              log_info(os, cpu)("Parsing CPU implementation from %s", impl);
+              impl_m = parse_features(impl);
+              break;
+            }
           }
-        } // for(
+        }
       }
+      kstat_close(kc);
     }
-    assert(has_implementation, "unknown cpu info (changed kstat interface?)");
-    kstat_close(kc);
   }
+  assert(impl_m != 0, "Unknown CPU implementation %s", impl);
+  features |= impl_m;
 
   bool is_sun4v = (features & sun4v_m) != 0;
   if (use_solaris_12_api && is_sun4v) {
--- a/src/share/vm/asm/assembler.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/asm/assembler.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -153,6 +153,8 @@
 
 void Label::add_patch_at(CodeBuffer* cb, int branch_loc) {
   assert(_loc == -1, "Label is unbound");
+  // Don't add patch locations during scratch emit.
+  if (cb->insts()->scratch_emit()) { return; }
   if (_patch_index < PatchCacheSize) {
     _patches[_patch_index] = branch_loc;
   } else {
--- a/src/share/vm/asm/codeBuffer.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/asm/codeBuffer.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -331,6 +331,8 @@
 }
 
 void CodeSection::relocate(address at, RelocationHolder const& spec, int format) {
+  // Do not relocate in scratch buffers.
+  if (scratch_emit()) { return; }
   Relocation* reloc = spec.reloc();
   relocInfo::relocType rtype = (relocInfo::relocType) reloc->type();
   if (rtype == relocInfo::none)  return;
--- a/src/share/vm/asm/codeBuffer.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/asm/codeBuffer.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -92,6 +92,7 @@
   address     _locs_point;      // last relocated position (grows upward)
   bool        _locs_own;        // did I allocate the locs myself?
   bool        _frozen;          // no more expansion of this section
+  bool        _scratch_emit;    // Buffer is used for scratch emit, don't relocate.
   char        _index;           // my section number (SECT_INST, etc.)
   CodeBuffer* _outer;           // enclosing CodeBuffer
 
@@ -108,6 +109,7 @@
     _locs_point    = NULL;
     _locs_own      = false;
     _frozen        = false;
+    _scratch_emit  = false;
     debug_only(_index = (char)-1);
     debug_only(_outer = (CodeBuffer*)badAddress);
   }
@@ -166,6 +168,10 @@
   bool        is_frozen() const     { return _frozen; }
   bool        has_locs() const      { return _locs_end != NULL; }
 
+  // Mark scratch buffer.
+  void        set_scratch_emit()    { _scratch_emit = true; }
+  bool        scratch_emit()        { return _scratch_emit; }
+
   CodeBuffer* outer() const         { return _outer; }
 
   // is a given address in this section?  (2nd version is end-inclusive)
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1493,6 +1493,21 @@
   // Check to see whether we are inlining. If so, Return
   // instructions become Gotos to the continuation point.
   if (continuation() != NULL) {
+
+    int invoke_bci = state()->caller_state()->bci();
+
+    if (x != NULL  && !ignore_return) {
+      ciMethod* caller = state()->scope()->caller()->method();
+      Bytecodes::Code invoke_raw_bc = caller->raw_code_at_bci(invoke_bci);
+      if (invoke_raw_bc == Bytecodes::_invokehandle || invoke_raw_bc == Bytecodes::_invokedynamic) {
+        ciType* declared_ret_type = caller->get_declared_signature_at_bci(invoke_bci)->return_type();
+        if (declared_ret_type->is_klass() && x->exact_type() == NULL &&
+            x->declared_type() != declared_ret_type && declared_ret_type != compilation()->env()->Object_klass()) {
+          x = append(new TypeCast(declared_ret_type->as_klass(), x, copy_state_before()));
+        }
+      }
+    }
+
     assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet");
 
     if (compilation()->env()->dtrace_method_probes()) {
@@ -1516,7 +1531,6 @@
     // State at end of inlined method is the state of the caller
     // without the method parameters on stack, including the
     // return value, if any, of the inlined method on operand stack.
-    int invoke_bci = state()->caller_state()->bci();
     set_state(state()->caller_state()->copy_for_parsing());
     if (x != NULL) {
       if (!ignore_return) {
@@ -1929,7 +1943,7 @@
         // number of implementors for decl_interface is 0 or 1. If
         // it's 0 then no class implements decl_interface and there's
         // no point in inlining.
-        if (!holder->is_loaded() || decl_interface->nof_implementors() != 1 || decl_interface->has_default_methods()) {
+        if (!holder->is_loaded() || decl_interface->nof_implementors() != 1 || decl_interface->has_nonstatic_concrete_methods()) {
           singleton = NULL;
         }
       }
@@ -4308,7 +4322,7 @@
 void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) {
   assert(known_holder == NULL || (known_holder->is_instance_klass() &&
                                   (!known_holder->is_interface() ||
-                                   ((ciInstanceKlass*)known_holder)->has_default_methods())), "should be default method");
+                                   ((ciInstanceKlass*)known_holder)->has_nonstatic_concrete_methods())), "should be non-static concrete method");
   if (known_holder != NULL) {
     if (known_holder->exact_klass() == NULL) {
       known_holder = compilation()->cha_exact_type(known_holder);
--- a/src/share/vm/c1/c1_Instruction.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/c1/c1_Instruction.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -360,7 +360,8 @@
 }
 
 ciType* Invoke::declared_type() const {
-  ciType *t = _target->signature()->return_type();
+  ciSignature* declared_signature = state()->scope()->method()->get_declared_signature_at_bci(state()->bci());
+  ciType *t = declared_signature->return_type();
   assert(t->basic_type() != T_VOID, "need return value of void method?");
   return t;
 }
--- a/src/share/vm/ci/ciInstanceKlass.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/ci/ciInstanceKlass.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -58,7 +58,7 @@
   _init_state = ik->init_state();
   _nonstatic_field_size = ik->nonstatic_field_size();
   _has_nonstatic_fields = ik->has_nonstatic_fields();
-  _has_default_methods = ik->has_default_methods();
+  _has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods();
   _is_anonymous = ik->is_anonymous();
   _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
   _has_injected_fields = -1;
--- a/src/share/vm/ci/ciInstanceKlass.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/ci/ciInstanceKlass.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
   bool                   _has_finalizer;
   bool                   _has_subklass;
   bool                   _has_nonstatic_fields;
-  bool                   _has_default_methods;
+  bool                   _has_nonstatic_concrete_methods;
   bool                   _is_anonymous;
 
   ciFlags                _flags;
@@ -174,9 +174,9 @@
       return 2;
     }
   }
-  bool has_default_methods()  {
+  bool has_nonstatic_concrete_methods()  {
     assert(is_loaded(), "must be loaded");
-    return _has_default_methods;
+    return _has_nonstatic_concrete_methods;
   }
 
   bool is_anonymous() {
--- a/src/share/vm/ci/ciMethod.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/ci/ciMethod.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -256,6 +256,14 @@
     return get_method_at_bci(bci, ignored_will_link, &ignored_declared_signature);
   }
 
+  ciSignature*  get_declared_signature_at_bci(int bci) {
+    bool ignored_will_link;
+    ciSignature* declared_signature;
+    get_method_at_bci(bci, ignored_will_link, &declared_signature);
+    assert(declared_signature != NULL, "cannot be null");
+    return declared_signature;
+  }
+
   // Given a certain calling environment, find the monomorphic target
   // for the call.  Return NULL if the call is not monomorphic in
   // its calling environment.
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -798,11 +798,11 @@
 void ClassFileParser::parse_interfaces(const ClassFileStream* const stream,
                                        const int itfs_len,
                                        ConstantPool* const cp,
-                                       bool* const has_default_methods,
+                                       bool* const has_nonstatic_concrete_methods,
                                        TRAPS) {
   assert(stream != NULL, "invariant");
   assert(cp != NULL, "invariant");
-  assert(has_default_methods != NULL, "invariant");
+  assert(has_nonstatic_concrete_methods != NULL, "invariant");
 
   if (itfs_len == 0) {
     _local_interfaces = Universe::the_empty_klass_array();
@@ -844,8 +844,8 @@
                    "Implementing class");
       }
 
-      if (InstanceKlass::cast(interf())->has_default_methods()) {
-        *has_default_methods = true;
+      if (InstanceKlass::cast(interf())->has_nonstatic_concrete_methods()) {
+        *has_nonstatic_concrete_methods = true;
       }
       _local_interfaces->at_put(index, interf());
     }
@@ -2830,12 +2830,12 @@
                                     bool is_interface,
                                     AccessFlags* promoted_flags,
                                     bool* has_final_method,
-                                    bool* declares_default_methods,
+                                    bool* declares_nonstatic_concrete_methods,
                                     TRAPS) {
   assert(cfs != NULL, "invariant");
   assert(promoted_flags != NULL, "invariant");
   assert(has_final_method != NULL, "invariant");
-  assert(declares_default_methods != NULL, "invariant");
+  assert(declares_nonstatic_concrete_methods != NULL, "invariant");
 
   assert(NULL == _methods, "invariant");
 
@@ -2860,11 +2860,11 @@
       if (method->is_final()) {
         *has_final_method = true;
       }
-      // declares_default_methods: declares concrete instance methods, any access flags
+      // declares_nonstatic_concrete_methods: declares concrete instance methods, any access flags
       // used for interface initialization, and default method inheritance analysis
-      if (is_interface && !(*declares_default_methods)
+      if (is_interface && !(*declares_nonstatic_concrete_methods)
         && !method->is_abstract() && !method->is_static()) {
-        *declares_default_methods = true;
+        *declares_nonstatic_concrete_methods = true;
       }
       _methods->at_put(index, method);
     }
@@ -5250,8 +5250,8 @@
 
   ik->set_minor_version(_minor_version);
   ik->set_major_version(_major_version);
-  ik->set_has_default_methods(_has_default_methods);
-  ik->set_declares_default_methods(_declares_default_methods);
+  ik->set_has_nonstatic_concrete_methods(_has_nonstatic_concrete_methods);
+  ik->set_declares_nonstatic_concrete_methods(_declares_nonstatic_concrete_methods);
 
   if (_host_klass != NULL) {
     assert (ik->is_anonymous(), "should be the same");
@@ -5311,12 +5311,9 @@
   // check if this class overrides any final method
   check_final_method_override(ik, CHECK);
 
-  // check that if this class is an interface then it doesn't have static methods
-  if (ik->is_interface()) {
-    /* An interface in a JAVA 8 classfile can be static */
-    if (_major_version < JAVA_8_VERSION) {
-      check_illegal_static_method(ik, CHECK);
-    }
+  // reject static interface methods prior to Java 8
+  if (ik->is_interface() && _major_version < JAVA_8_VERSION) {
+    check_illegal_static_method(ik, CHECK);
   }
 
   // Obtain this_klass' module entry
@@ -5336,9 +5333,9 @@
 
   assert(_all_mirandas != NULL, "invariant");
 
-  // Generate any default methods - default methods are interface methods
-  // that have a default implementation.  This is new with Lambda project.
-  if (_has_default_methods ) {
+  // Generate any default methods - default methods are public interface methods
+  // that have a default implementation.  This is new with Java 8.
+  if (_has_nonstatic_concrete_methods) {
     DefaultMethods::generate_default_methods(ik,
                                              _all_mirandas,
                                              CHECK);
@@ -5523,8 +5520,8 @@
   _java_fields_count(0),
   _need_verify(false),
   _relax_verify(false),
-  _has_default_methods(false),
-  _declares_default_methods(false),
+  _has_nonstatic_concrete_methods(false),
+  _declares_nonstatic_concrete_methods(false),
   _has_final_method(false),
   _has_finalizer(false),
   _has_empty_finalizer(false),
@@ -5778,9 +5775,22 @@
       // Anonymous classes such as generated LambdaForm classes are also not included.
       if (SystemDictionaryShared::is_sharing_possible(_loader_data) &&
           _host_klass == NULL) {
+        oop class_loader = _loader_data->class_loader();
         ResourceMark rm(THREAD);
-        classlist_file->print_cr("%s", _class_name->as_C_string());
-        classlist_file->flush();
+        // For the boot and platform class loaders, check if the class is not found in the
+        // java runtime image. Additional check for the boot class loader is if the class
+        // is not found in the boot loader's appended entries. This indicates that the class
+        // is not useable during run time, such as the ones found in the --patch-module entries,
+        // so it should not be included in the classlist file.
+        if (((class_loader == NULL && !ClassLoader::contains_append_entry(stream->source())) ||
+             SystemDictionary::is_platform_class_loader(class_loader)) &&
+            !ClassLoader::is_jrt(stream->source())) {
+          tty->print_cr("skip writing class %s from source %s to classlist file",
+            _class_name->as_C_string(), stream->source());
+        } else {
+          classlist_file->print_cr("%s", _class_name->as_C_string());
+          classlist_file->flush();
+        }
       }
     }
 #endif
@@ -5798,7 +5808,7 @@
   parse_interfaces(stream,
                    _itfs_len,
                    cp,
-                   &_has_default_methods,
+                   &_has_nonstatic_concrete_methods,
                    CHECK);
 
   assert(_local_interfaces != NULL, "invariant");
@@ -5821,7 +5831,7 @@
                 _access_flags.is_interface(),
                 &promoted_flags,
                 &_has_final_method,
-                &_declares_default_methods,
+                &_declares_nonstatic_concrete_methods,
                 CHECK);
 
   assert(_methods != NULL, "invariant");
@@ -5829,8 +5839,8 @@
   // promote flags from parse_methods() to the klass' flags
   _access_flags.add_promoted_flags(promoted_flags.as_int());
 
-  if (_declares_default_methods) {
-    _has_default_methods = true;
+  if (_declares_nonstatic_concrete_methods) {
+    _has_nonstatic_concrete_methods = true;
   }
 
   // Additional attributes/annotations
@@ -5884,8 +5894,8 @@
   }
 
   if (_super_klass != NULL) {
-    if (_super_klass->has_default_methods()) {
-      _has_default_methods = true;
+    if (_super_klass->has_nonstatic_concrete_methods()) {
+      _has_nonstatic_concrete_methods = true;
     }
 
     if (_super_klass->is_interface()) {
--- a/src/share/vm/classfile/classFileParser.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/classFileParser.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -139,8 +139,8 @@
   bool _need_verify;
   bool _relax_verify;
 
-  bool _has_default_methods;
-  bool _declares_default_methods;
+  bool _has_nonstatic_concrete_methods;
+  bool _declares_nonstatic_concrete_methods;
   bool _has_final_method;
 
   // precomputed flags
@@ -186,7 +186,7 @@
   void parse_interfaces(const ClassFileStream* const stream,
                         const int itfs_len,
                         ConstantPool* const cp,
-                        bool* has_default_methods,
+                        bool* has_nonstatic_concrete_methods,
                         TRAPS);
 
   const InstanceKlass* parse_super_class(ConstantPool* const cp,
@@ -224,7 +224,7 @@
                      bool is_interface,
                      AccessFlags* const promoted_flags,
                      bool* const has_final_method,
-                     bool* const declares_default_methods,
+                     bool* const declares_nonstatic_concrete_methods,
                      TRAPS);
 
   const u2* parse_exception_table(const ClassFileStream* const stream,
--- a/src/share/vm/classfile/classLoader.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/classLoader.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -81,7 +81,6 @@
 typedef void (JNICALL *ZipClose_t)(jzfile *zip);
 typedef jzentry* (JNICALL *FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen);
 typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
-typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
 typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
 typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
 typedef jint     (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
@@ -91,7 +90,6 @@
 static ZipClose_t        ZipClose           = NULL;
 static FindEntry_t       FindEntry          = NULL;
 static ReadEntry_t       ReadEntry          = NULL;
-static ReadMappedEntry_t ReadMappedEntry    = NULL;
 static GetNextEntry_t    GetNextEntry       = NULL;
 static canonicalize_fn_t CanonicalizeEntry  = NULL;
 static ZipInflateFully_t ZipInflateFully    = NULL;
@@ -353,15 +351,10 @@
     filename = NEW_RESOURCE_ARRAY(char, name_len + 1);
   }
 
-  // file found, get pointer to the entry in mmapped jar file.
-  if (ReadMappedEntry == NULL ||
-      !(*ReadMappedEntry)(_zip, entry, &buffer, filename)) {
-      // mmapped access not available, perhaps due to compression,
-      // read contents into resource array
-      int size = (*filesize) + ((nul_terminate) ? 1 : 0);
-      buffer = NEW_RESOURCE_ARRAY(u1, size);
-      if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
-  }
+  // read contents into resource array
+  int size = (*filesize) + ((nul_terminate) ? 1 : 0);
+  buffer = NEW_RESOURCE_ARRAY(u1, size);
+  if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
 
   // return result
   if (nul_terminate) {
@@ -952,11 +945,11 @@
 }
 
 // returns true if entry already on class path
-bool ClassLoader::contains_entry(ClassPathEntry *entry) {
+bool ClassLoader::contains_append_entry(const char* name) {
   ClassPathEntry* e = _first_append_entry;
   while (e != NULL) {
     // assume zip entries have been canonicalized
-    if (strcmp(entry->name(), e->name()) == 0) {
+    if (strcmp(name, e->name()) == 0) {
       return true;
     }
     e = e->next();
@@ -998,7 +991,7 @@
 
     // Do not reorder the bootclasspath which would break get_system_package().
     // Add new entry to linked list
-    if (!check_for_duplicates || !contains_entry(new_entry)) {
+    if (!check_for_duplicates || !contains_append_entry(new_entry->name())) {
       ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry);
     }
     return true;
@@ -1079,7 +1072,6 @@
   ZipClose     = CAST_TO_FN_PTR(ZipClose_t, os::dll_lookup(handle, "ZIP_Close"));
   FindEntry    = CAST_TO_FN_PTR(FindEntry_t, os::dll_lookup(handle, "ZIP_FindEntry"));
   ReadEntry    = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry"));
-  ReadMappedEntry = CAST_TO_FN_PTR(ReadMappedEntry_t, os::dll_lookup(handle, "ZIP_ReadMappedEntry"));
   GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry"));
   ZipInflateFully = CAST_TO_FN_PTR(ZipInflateFully_t, os::dll_lookup(handle, "ZIP_InflateFully"));
   Crc32        = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32"));
@@ -2049,7 +2041,6 @@
                 if (nm != NULL && !m->is_method_handle_intrinsic()) {
                   // Throw out the code so that the code cache doesn't fill up
                   nm->make_not_entrant();
-                  m->clear_code();
                 }
                 CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization,
                                               methodHandle(), 0, CompileTask::Reason_CTW, THREAD);
@@ -2068,7 +2059,6 @@
             if (nm != NULL && !m->is_method_handle_intrinsic()) {
               // Throw out the code so that the code cache doesn't fill up
               nm->make_not_entrant();
-              m->clear_code();
             }
           }
         }
--- a/src/share/vm/classfile/classLoader.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/classLoader.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -451,7 +451,7 @@
   static void set_first_append_entry(ClassPathEntry* entry);
 
   // indicates if class path already contains a entry (exact match by name)
-  static bool contains_entry(ClassPathEntry* entry);
+  static bool contains_append_entry(const char* name);
 
   // adds a class path list
   static void add_to_list(ClassPathEntry* new_entry);
--- a/src/share/vm/classfile/classLoaderData.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/classLoaderData.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -639,7 +639,6 @@
 #undef CLD_DUMP_KLASSES
 
 void ClassLoaderData::dump(outputStream * const out) {
-  ResourceMark rm;
   out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: " PTR_FORMAT " %s {",
       p2i(this), p2i((void *)class_loader()),
       p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name());
@@ -656,7 +655,6 @@
 
 #ifdef CLD_DUMP_KLASSES
   if (Verbose) {
-    ResourceMark rm;
     Klass* k = _klasses;
     while (k != NULL) {
       out->print_cr("klass " PTR_FORMAT ", %s, CT: %d, MUT: %d", k, k->name()->as_C_string(),
--- a/src/share/vm/classfile/defaultMethods.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/defaultMethods.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -914,7 +914,7 @@
       BytecodeBuffer buffer;
 
       if (log_is_enabled(Debug, defaultmethods)) {
-        ResourceMark rm;
+        ResourceMark rm(THREAD);
         outputStream* logstream = Log(defaultmethods)::debug_stream();
         logstream->print("for slot: ");
         slot->print_on(logstream);
@@ -929,6 +929,7 @@
       if (method->has_target()) {
         Method* selected = method->get_selected_target();
         if (selected->method_holder()->is_interface()) {
+          assert(!selected->is_private(), "pushing private interface method as default");
           defaults.push(selected);
         }
       } else if (method->throws_exception()) {
--- a/src/share/vm/classfile/javaClasses.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/javaClasses.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -780,19 +780,26 @@
     // Put the class on the fixup_module_list to patch later when the java.lang.reflect.Module
     // for java.base is known.
     assert(!Universe::is_module_initialized(), "Incorrect java.lang.reflect.Module pre module system initialization");
-    MutexLocker m1(Module_lock, THREAD);
-    // Keep list of classes needing java.base module fixup
-    if (!ModuleEntryTable::javabase_defined()) {
-      if (fixup_module_field_list() == NULL) {
-        GrowableArray<Klass*>* list =
-          new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
-        set_fixup_module_field_list(list);
+
+    bool javabase_was_defined = false;
+    {
+      MutexLocker m1(Module_lock, THREAD);
+      // Keep list of classes needing java.base module fixup
+      if (!ModuleEntryTable::javabase_defined()) {
+        if (fixup_module_field_list() == NULL) {
+          GrowableArray<Klass*>* list =
+            new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
+          set_fixup_module_field_list(list);
+        }
+        k->class_loader_data()->inc_keep_alive();
+        fixup_module_field_list()->push(k());
+      } else {
+        javabase_was_defined = true;
       }
-      k->class_loader_data()->inc_keep_alive();
-      fixup_module_field_list()->push(k());
-    } else {
-      // java.base was defined at some point between calling create_mirror()
-      // and obtaining the Module_lock, patch this particular class with java.base.
+    }
+
+    // If java.base was already defined then patch this particular class with java.base.
+    if (javabase_was_defined) {
       ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry();
       assert(javabase_entry != NULL && javabase_entry->module() != NULL,
              "Setting class module field, java.base should be defined");
--- a/src/share/vm/classfile/klassFactory.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/klassFactory.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -74,7 +74,7 @@
         (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
       ClassFileStream* stream = new ClassFileStream(ptr,
                                                     end_ptr - ptr,
-                                                    ent->_name,
+                                                    ent == NULL ? NULL : ent->_name,
                                                     ClassFileStream::verify);
       ClassFileParser parser(stream,
                              class_name,
--- a/src/share/vm/classfile/moduleEntry.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/moduleEntry.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -368,9 +368,6 @@
 
   // Store pointer to the ModuleEntry for java.base in the java.lang.reflect.Module object.
   java_lang_reflect_Module::set_module_entry(module_handle(), jb_module);
-
-  // Patch any previously loaded classes' module field with java.base's java.lang.reflect.Module.
-  patch_javabase_entries(module_handle);
 }
 
 // Within java.lang.Class instances there is a java.lang.reflect.Module field
@@ -378,7 +375,6 @@
 // definition, classes needing their module field set are added to the fixup_module_list.
 // Their module field is set once java.base's java.lang.reflect.Module is known to the VM.
 void ModuleEntryTable::patch_javabase_entries(Handle module_handle) {
-  assert(Module_lock->owned_by_self(), "should have the Module_lock");
   if (module_handle.is_null()) {
     fatal("Unable to patch the module field of classes loaded prior to java.base's definition, invalid java.lang.reflect.Module");
   }
--- a/src/share/vm/classfile/modules.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/modules.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -244,6 +244,12 @@
               "Module java.base is already defined");
   }
 
+  // Only the thread that actually defined the base module will get here,
+  // so no locking is needed.
+
+  // Patch any previously loaded class's module field with java.base's java.lang.reflect.Module.
+  ModuleEntryTable::patch_javabase_entries(module_handle);
+
   log_debug(modules)("define_javabase_module(): Definition of module: java.base,"
                      " version: %s, location: %s, package #: %d",
                      module_version != NULL ? module_version : "NULL",
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1234,7 +1234,7 @@
   SharedClassPathEntry* ent =
             (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
   if (!Universe::is_module_initialized()) {
-    assert(ent->is_jrt(),
+    assert(ent != NULL && ent->is_jrt(),
            "Loading non-bootstrap classes before the module system is initialized");
     assert(class_loader.is_null(), "sanity");
     return true;
@@ -1257,6 +1257,7 @@
   }
 
   if (class_loader.is_null()) {
+    assert(ent != NULL, "Shared class for NULL classloader must have valid SharedClassPathEntry");
     // The NULL classloader can load archived class originated from the
     // "modules" jimage and the -Xbootclasspath/a. For class from the
     // "modules" jimage, the PackageEntry/ModuleEntry must be defined
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -226,7 +226,7 @@
     WKID_LIMIT,
 
 #if INCLUDE_JVMCI
-    FIRST_JVMCI_WKID = WK_KLASS_ENUM_NAME(HotSpotCompiledCode_klass),
+    FIRST_JVMCI_WKID = WK_KLASS_ENUM_NAME(JVMCI_klass),
     LAST_JVMCI_WKID  = WK_KLASS_ENUM_NAME(Value_klass),
 #endif
 
--- a/src/share/vm/code/nmethod.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/code/nmethod.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1252,7 +1252,7 @@
     if (method() != NULL && (method()->code() == this ||
                              method()->from_compiled_entry() == verified_entry_point())) {
       HandleMark hm;
-      method()->clear_code();
+      method()->clear_code(false /* already owns Patching_lock */);
     }
   } // leave critical region under Patching_lock
 
--- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -2340,13 +2340,11 @@
   {
     StrongRootsScope srs(1);
 
-    gch->gen_process_roots(&srs,
-                           GenCollectedHeap::OldGen,
+    gch->cms_process_roots(&srs,
                            true,   // young gen as roots
                            GenCollectedHeap::ScanningOption(roots_scanning_options()),
                            should_unload_classes(),
                            &notOlder,
-                           NULL,
                            NULL);
   }
 
@@ -2414,13 +2412,11 @@
   {
     StrongRootsScope srs(1);
 
-    gch->gen_process_roots(&srs,
-                           GenCollectedHeap::OldGen,
+    gch->cms_process_roots(&srs,
                            true,   // young gen as roots
                            GenCollectedHeap::ScanningOption(roots_scanning_options()),
                            should_unload_classes(),
                            &notOlder,
-                           NULL,
                            &cld_closure);
   }
 
@@ -2903,13 +2899,11 @@
 
       StrongRootsScope srs(1);
 
-      gch->gen_process_roots(&srs,
-                             GenCollectedHeap::OldGen,
+      gch->cms_process_roots(&srs,
                              true,   // young gen as roots
                              GenCollectedHeap::ScanningOption(roots_scanning_options()),
                              should_unload_classes(),
                              &notOlder,
-                             NULL,
                              &cld_closure);
     }
   }
@@ -4290,13 +4284,11 @@
 
   CLDToOopClosure cld_closure(&par_mri_cl, true);
 
-  gch->gen_process_roots(_strong_roots_scope,
-                         GenCollectedHeap::OldGen,
+  gch->cms_process_roots(_strong_roots_scope,
                          false,     // yg was scanned above
                          GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
                          _collector->should_unload_classes(),
                          &par_mri_cl,
-                         NULL,
                          &cld_closure);
   assert(_collector->should_unload_classes()
          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
@@ -4421,13 +4413,11 @@
   // ---------- remaining roots --------------
   _timer.reset();
   _timer.start();
-  gch->gen_process_roots(_strong_roots_scope,
-                         GenCollectedHeap::OldGen,
+  gch->cms_process_roots(_strong_roots_scope,
                          false,     // yg was scanned above
                          GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
                          _collector->should_unload_classes(),
                          &par_mrias_cl,
-                         NULL,
                          NULL);     // The dirty klasses will be handled below
 
   assert(_collector->should_unload_classes()
@@ -4970,13 +4960,11 @@
     gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
     StrongRootsScope srs(1);
 
-    gch->gen_process_roots(&srs,
-                           GenCollectedHeap::OldGen,
+    gch->cms_process_roots(&srs,
                            true,  // young gen as roots
                            GenCollectedHeap::ScanningOption(roots_scanning_options()),
                            should_unload_classes(),
                            &mrias_cl,
-                           NULL,
                            NULL); // The dirty klasses will be handled below
 
     assert(should_unload_classes()
--- a/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/gc/cms/parNewGeneration.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -605,14 +605,10 @@
                                            false);
 
   par_scan_state.start_strong_roots();
-  gch->gen_process_roots(_strong_roots_scope,
-                         GenCollectedHeap::YoungGen,
-                         true,  // Process younger gens, if any, as strong roots.
-                         GenCollectedHeap::SO_ScavengeCodeCache,
-                         GenCollectedHeap::StrongAndWeakRoots,
-                         &par_scan_state.to_space_root_closure(),
-                         &par_scan_state.older_gen_closure(),
-                         &cld_scan_closure);
+  gch->young_process_roots(_strong_roots_scope,
+                           &par_scan_state.to_space_root_closure(),
+                           &par_scan_state.older_gen_closure(),
+                           &cld_scan_closure);
 
   par_scan_state.end_strong_roots();
 
--- a/src/share/vm/gc/g1/g1BiasedArray.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/gc/g1/g1BiasedArray.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,99 +53,4 @@
             biased_index, bias(), length());
 }
 
-class TestMappedArray : public G1BiasedMappedArray<int> {
-protected:
-  virtual int default_value() const { return 0xBAADBABE; }
-public:
-  static void test_biasedarray() {
-    const size_t REGION_SIZE_IN_WORDS = 512;
-    const size_t NUM_REGIONS = 20;
-    HeapWord* fake_heap = (HeapWord*)LP64_ONLY(0xBAAA00000) NOT_LP64(0xBA000000); // Any value that is non-zero
-
-    TestMappedArray array;
-    array.initialize(fake_heap, fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS,
-            REGION_SIZE_IN_WORDS * HeapWordSize);
-    // Check address calculation (bounds)
-    assert(array.bottom_address_mapped() == fake_heap,
-           "bottom mapped address should be " PTR_FORMAT ", but is " PTR_FORMAT, p2i(fake_heap), p2i(array.bottom_address_mapped()));
-    assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be");
-
-    int* bottom = array.address_mapped_to(fake_heap);
-    assert((void*)bottom == (void*) array.base(), "must be");
-    int* end = array.address_mapped_to(fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS);
-    assert((void*)end == (void*)(array.base() + array.length()), "must be");
-    // The entire array should contain default value elements
-    for (int* current = bottom; current < end; current++) {
-      assert(*current == array.default_value(), "must be");
-    }
-
-    // Test setting values in the table
-
-    HeapWord* region_start_address = fake_heap + REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2);
-    HeapWord* region_end_address = fake_heap + (REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2) + REGION_SIZE_IN_WORDS - 1);
-
-    // Set/get by address tests: invert some value; first retrieve one
-    int actual_value = array.get_by_index(NUM_REGIONS / 2);
-    array.set_by_index(NUM_REGIONS / 2, ~actual_value);
-    // Get the same value by address, should correspond to the start of the "region"
-    int value = array.get_by_address(region_start_address);
-    assert(value == ~actual_value, "must be");
-    // Get the same value by address, at one HeapWord before the start
-    value = array.get_by_address(region_start_address - 1);
-    assert(value == array.default_value(), "must be");
-    // Get the same value by address, at the end of the "region"
-    value = array.get_by_address(region_end_address);
-    assert(value == ~actual_value, "must be");
-    // Make sure the next value maps to another index
-    value = array.get_by_address(region_end_address + 1);
-    assert(value == array.default_value(), "must be");
-
-    // Reset the value in the array
-    array.set_by_address(region_start_address + (region_end_address - region_start_address) / 2, actual_value);
-
-    // The entire array should have the default value again
-    for (int* current = bottom; current < end; current++) {
-      assert(*current == array.default_value(), "must be");
-    }
-
-    // Set/get by index tests: invert some value
-    idx_t index = NUM_REGIONS / 2;
-    actual_value = array.get_by_index(index);
-    array.set_by_index(index, ~actual_value);
-
-    value = array.get_by_index(index);
-    assert(value == ~actual_value, "must be");
-
-    value = array.get_by_index(index - 1);
-    assert(value == array.default_value(), "must be");
-
-    value = array.get_by_index(index + 1);
-    assert(value == array.default_value(), "must be");
-
-    array.set_by_index(0, 0);
-    value = array.get_by_index(0);
-    assert(value == 0, "must be");
-
-    array.set_by_index(array.length() - 1, 0);
-    value = array.get_by_index(array.length() - 1);
-    assert(value == 0, "must be");
-
-    array.set_by_index(index, 0);
-
-    // The array should have three zeros, and default values otherwise
-    size_t num_zeros = 0;
-    for (int* current = bottom; current < end; current++) {
-      assert(*current == array.default_value() || *current == 0, "must be");
-      if (*current == 0) {
-        num_zeros++;
-      }
-    }
-    assert(num_zeros == 3, "must be");
-  }
-};
-
-void TestG1BiasedArray_test() {
-  TestMappedArray::test_biasedarray();
-}
-
 #endif
--- a/src/share/vm/gc/serial/defNewGeneration.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/gc/serial/defNewGeneration.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -648,15 +648,10 @@
     // See: CardTableModRefBSForCTRS::non_clean_card_iterate_possibly_parallel.
     StrongRootsScope srs(0);
 
-    gch->gen_process_roots(&srs,
-                           GenCollectedHeap::YoungGen,
-                           true,  // Process younger gens, if any,
-                                  // as strong roots.
-                           GenCollectedHeap::SO_ScavengeCodeCache,
-                           GenCollectedHeap::StrongAndWeakRoots,
-                           &fsc_with_no_gc_barrier,
-                           &fsc_with_gc_barrier,
-                           &cld_scan_closure);
+    gch->young_process_roots(&srs,
+                             &fsc_with_no_gc_barrier,
+                             &fsc_with_gc_barrier,
+                             &cld_scan_closure);
   }
 
   // "evacuate followers".
--- a/src/share/vm/gc/serial/genMarkSweep.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/gc/serial/genMarkSweep.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -196,14 +196,13 @@
   {
     StrongRootsScope srs(1);
 
-    gch->gen_process_roots(&srs,
-                           GenCollectedHeap::OldGen,
-                           false, // Younger gens are not roots.
-                           GenCollectedHeap::SO_None,
-                           ClassUnloading,
-                           &follow_root_closure,
-                           &follow_root_closure,
-                           &follow_cld_closure);
+    gch->full_process_roots(&srs,
+                            false, // not the adjust phase
+                            GenCollectedHeap::SO_None,
+                            ClassUnloading, // only strong roots if ClassUnloading
+                                            // is enabled
+                            &follow_root_closure,
+                            &follow_cld_closure);
   }
 
   // Process reference objects found during marking
@@ -295,14 +294,12 @@
   {
     StrongRootsScope srs(1);
 
-    gch->gen_process_roots(&srs,
-                           GenCollectedHeap::OldGen,
-                           false, // Younger gens are not roots.
-                           GenCollectedHeap::SO_AllCodeCache,
-                           GenCollectedHeap::StrongAndWeakRoots,
-                           &adjust_pointer_closure,
-                           &adjust_pointer_closure,
-                           &adjust_cld_closure);
+    gch->full_process_roots(&srs,
+                            true,  // this is the adjust phase
+                            GenCollectedHeap::SO_AllCodeCache,
+                            false, // all roots
+                            &adjust_pointer_closure,
+                            &adjust_cld_closure);
   }
 
   gch->gen_process_weak_roots(&adjust_pointer_closure);
--- a/src/share/vm/gc/shared/gcTraceTime.inline.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/gc/shared/gcTraceTime.inline.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -35,7 +35,6 @@
 #include "prims/jni_md.h"
 #include "utilities/ticks.hpp"
 
-#define LOG_STOP_TIME_FORMAT "(%.3fs, %.3fs) %.3fms"
 #define LOG_STOP_HEAP_FORMAT SIZE_FORMAT "M->" SIZE_FORMAT "M("  SIZE_FORMAT "M)"
 
 inline void GCTraceTimeImpl::log_start(jlong start_counter) {
@@ -46,7 +45,7 @@
     if (_gc_cause != GCCause::_no_gc) {
       out.print(" (%s)", GCCause::to_string(_gc_cause));
     }
-    out.print_cr(" (%.3fs)", TimeHelper::counter_to_seconds(start_counter));
+    out.cr();
   }
 }
 
@@ -71,7 +70,7 @@
     out.print(" " LOG_STOP_HEAP_FORMAT, used_before_m, used_m, capacity_m);
   }
 
-  out.print_cr(" " LOG_STOP_TIME_FORMAT, start_time_in_secs, stop_time_in_secs, duration_in_ms);
+  out.print_cr(" %.3fms", duration_in_ms);
 }
 
 inline void GCTraceTimeImpl::time_stamp(Ticks& ticks) {
@@ -117,7 +116,7 @@
 GCTraceConcTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::GCTraceConcTimeImpl(const char* title) :
   _enabled(LogImpl<T0, T1, T2, T3, T4, GuardTag>::is_level(Level)), _start_time(os::elapsed_counter()), _title(title) {
   if (_enabled) {
-    LogImpl<T0, T1, T2, T3, T4>::template write<Level>("%s (%.3fs)", _title, TimeHelper::counter_to_seconds(_start_time));
+    LogImpl<T0, T1, T2, T3, T4>::template write<Level>("%s", _title);
   }
 }
 
@@ -125,11 +124,8 @@
 GCTraceConcTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::~GCTraceConcTimeImpl() {
   if (_enabled) {
     jlong stop_time = os::elapsed_counter();
-    LogImpl<T0, T1, T2, T3, T4>::template write<Level>("%s " LOG_STOP_TIME_FORMAT,
-                                                   _title,
-                                                   TimeHelper::counter_to_seconds(_start_time),
-                                                   TimeHelper::counter_to_seconds(stop_time),
-                                                   TimeHelper::counter_to_millis(stop_time - _start_time));
+    LogImpl<T0, T1, T2, T3, T4>::template write<Level>("%s %0.3fms", _title,
+                                                       TimeHelper::counter_to_millis(stop_time - _start_time));
   }
 }
 
--- a/src/share/vm/gc/shared/genCollectedHeap.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/gc/shared/genCollectedHeap.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -613,16 +613,6 @@
     SystemDictionary::roots_oops_do(strong_roots, weak_roots);
   }
 
-  // All threads execute the following. A specific chunk of buckets
-  // from the StringTable are the individual tasks.
-  if (weak_roots != NULL) {
-    if (is_par) {
-      StringTable::possibly_parallel_oops_do(weak_roots);
-    } else {
-      StringTable::oops_do(weak_roots);
-    }
-  }
-
   if (!_process_strong_tasks->is_task_claimed(GCH_PS_CodeCache_oops_do)) {
     if (so & SO_ScavengeCodeCache) {
       assert(code_roots != NULL, "must supply closure for code cache");
@@ -644,46 +634,82 @@
   }
 }
 
-void GenCollectedHeap::gen_process_roots(StrongRootsScope* scope,
-                                         GenerationType type,
+void GenCollectedHeap::process_string_table_roots(StrongRootsScope* scope,
+                                                  OopClosure* root_closure) {
+  assert(root_closure != NULL, "Must be set");
+  // All threads execute the following. A specific chunk of buckets
+  // from the StringTable are the individual tasks.
+  if (scope->n_threads() > 1) {
+    StringTable::possibly_parallel_oops_do(root_closure);
+  } else {
+    StringTable::oops_do(root_closure);
+  }
+}
+
+void GenCollectedHeap::young_process_roots(StrongRootsScope* scope,
+                                           OopsInGenClosure* root_closure,
+                                           OopsInGenClosure* old_gen_closure,
+                                           CLDClosure* cld_closure) {
+  MarkingCodeBlobClosure mark_code_closure(root_closure, CodeBlobToOopClosure::FixRelocations);
+
+  process_roots(scope, SO_ScavengeCodeCache, root_closure, root_closure,
+                cld_closure, cld_closure, &mark_code_closure);
+  process_string_table_roots(scope, root_closure);
+
+  if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
+    root_closure->reset_generation();
+  }
+
+  // When collection is parallel, all threads get to cooperate to do
+  // old generation scanning.
+  old_gen_closure->set_generation(_old_gen);
+  rem_set()->younger_refs_iterate(_old_gen, old_gen_closure, scope->n_threads());
+  old_gen_closure->reset_generation();
+
+  _process_strong_tasks->all_tasks_completed(scope->n_threads());
+}
+
+void GenCollectedHeap::cms_process_roots(StrongRootsScope* scope,
                                          bool young_gen_as_roots,
                                          ScanningOption so,
                                          bool only_strong_roots,
-                                         OopsInGenClosure* not_older_gens,
-                                         OopsInGenClosure* older_gens,
+                                         OopsInGenClosure* root_closure,
                                          CLDClosure* cld_closure) {
-  const bool is_adjust_phase = !only_strong_roots && !young_gen_as_roots;
+  MarkingCodeBlobClosure mark_code_closure(root_closure, !CodeBlobToOopClosure::FixRelocations);
+  OopsInGenClosure* weak_roots = only_strong_roots ? NULL : root_closure;
+  CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
 
-  bool is_moving_collection = false;
-  if (type == YoungGen || is_adjust_phase) {
-    // young collections are always moving
-    is_moving_collection = true;
+  process_roots(scope, so, root_closure, weak_roots, cld_closure, weak_cld_closure, &mark_code_closure);
+  if (!only_strong_roots) {
+    process_string_table_roots(scope, root_closure);
   }
 
-  MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection);
-  OopsInGenClosure* weak_roots = only_strong_roots ? NULL : not_older_gens;
+  if (young_gen_as_roots &&
+      !_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
+    root_closure->set_generation(_young_gen);
+    _young_gen->oop_iterate(root_closure);
+    root_closure->reset_generation();
+  }
+
+  _process_strong_tasks->all_tasks_completed(scope->n_threads());
+}
+
+void GenCollectedHeap::full_process_roots(StrongRootsScope* scope,
+                                          bool is_adjust_phase,
+                                          ScanningOption so,
+                                          bool only_strong_roots,
+                                          OopsInGenClosure* root_closure,
+                                          CLDClosure* cld_closure) {
+  MarkingCodeBlobClosure mark_code_closure(root_closure, is_adjust_phase);
+  OopsInGenClosure* weak_roots = only_strong_roots ? NULL : root_closure;
   CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
 
-  process_roots(scope, so,
-                not_older_gens, weak_roots,
-                cld_closure, weak_cld_closure,
-                &mark_code_closure);
-
-  if (young_gen_as_roots) {
-    if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
-      if (type == OldGen) {
-        not_older_gens->set_generation(_young_gen);
-        _young_gen->oop_iterate(not_older_gens);
-      }
-      not_older_gens->reset_generation();
-    }
-  }
-  // When collection is parallel, all threads get to cooperate to do
-  // old generation scanning.
-  if (type == YoungGen) {
-    older_gens->set_generation(_old_gen);
-    rem_set()->younger_refs_iterate(_old_gen, older_gens, scope->n_threads());
-    older_gens->reset_generation();
+  process_roots(scope, so, root_closure, weak_roots, cld_closure, weak_cld_closure, &mark_code_closure);
+  if (is_adjust_phase) {
+    // We never treat the string table as roots during marking
+    // for the full gc, so we only need to process it during
+    // the adjust phase.
+    process_string_table_roots(scope, root_closure);
   }
 
   _process_strong_tasks->all_tasks_completed(scope->n_threads());
--- a/src/share/vm/gc/shared/genCollectedHeap.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/gc/shared/genCollectedHeap.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -374,16 +374,7 @@
   // asserted to be this type.
   static GenCollectedHeap* heap();
 
-  // Invoke the "do_oop" method of one of the closures "not_older_gens"
-  // or "older_gens" on root locations for the generations depending on
-  // the type.  (The "older_gens" closure is used for scanning references
-  // from older generations; "not_older_gens" is used everywhere else.)
-  // If "younger_gens_as_roots" is false, younger generations are
-  // not scanned as roots; in this case, the caller must be arranging to
-  // scan the younger generations itself.  (For example, a generation might
-  // explicitly mark reachable objects in younger generations, to avoid
-  // excess storage retention.)
-  // The "so" argument determines which of the roots
+  // The ScanningOption determines which of the roots
   // the closure is applied to:
   // "SO_None" does none;
   enum ScanningOption {
@@ -401,19 +392,34 @@
                      CLDClosure* weak_cld_closure,
                      CodeBlobToOopClosure* code_roots);
 
+  void process_string_table_roots(StrongRootsScope* scope,
+                                  OopClosure* root_closure);
+
  public:
-  static const bool StrongAndWeakRoots = false;
-  static const bool StrongRootsOnly    = true;
+  void young_process_roots(StrongRootsScope* scope,
+                           OopsInGenClosure* root_closure,
+                           OopsInGenClosure* old_gen_closure,
+                           CLDClosure* cld_closure);
 
-  void gen_process_roots(StrongRootsScope* scope,
-                         GenerationType type,
+  // If "young_gen_as_roots" is false, younger generations are
+  // not scanned as roots; in this case, the caller must be arranging to
+  // scan the younger generations itself.  (For example, a generation might
+  // explicitly mark reachable objects in younger generations, to avoid
+  // excess storage retention.)
+  void cms_process_roots(StrongRootsScope* scope,
                          bool young_gen_as_roots,
                          ScanningOption so,
                          bool only_strong_roots,
-                         OopsInGenClosure* not_older_gens,
-                         OopsInGenClosure* older_gens,
+                         OopsInGenClosure* root_closure,
                          CLDClosure* cld_closure);
 
+  void full_process_roots(StrongRootsScope* scope,
+                          bool is_adjust_phase,
+                          ScanningOption so,
+                          bool only_strong_roots,
+                          OopsInGenClosure* root_closure,
+                          CLDClosure* cld_closure);
+
   // Apply "root_closure" to all the weak roots of the system.
   // These include JNI weak roots, string table,
   // and referents of reachable weak refs.
--- a/src/share/vm/interpreter/invocationCounter.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/interpreter/invocationCounter.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -40,6 +40,7 @@
 
 class InvocationCounter VALUE_OBJ_CLASS_SPEC {
   friend class VMStructs;
+  friend class JVMCIVMStructs;
   friend class ciReplay;
  private:                             // bit no: |31  3|  2  | 1 0 |
   unsigned int _counter;              // format: [count|carry|state]
--- a/src/share/vm/interpreter/linkResolver.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/interpreter/linkResolver.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -858,8 +858,10 @@
   }
 
   if (log_develop_is_enabled(Trace, itables)) {
-    trace_method_resolution("invokeinterface resolved method: caller-class",
-                            link_info.current_klass(), resolved_klass,
+    char buf[200];
+    jio_snprintf(buf, sizeof(buf), "%s resolved interface method: caller-class:",
+                 Bytecodes::name(code));
+    trace_method_resolution(buf, link_info.current_klass(), resolved_klass,
                             resolved_method, true);
   }
 
@@ -1424,7 +1426,7 @@
   }
 
   if (log_develop_is_enabled(Trace, itables)) {
-    trace_method_resolution("invokeinterface selected method: receiver-class",
+    trace_method_resolution("invokeinterface selected method: receiver-class:",
                             recv_klass, resolved_klass, sel_method, true);
   }
   // setup result
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -172,7 +172,7 @@
   return map;
 }
 
-void* CodeInstaller::record_metadata_reference(Handle constant, TRAPS) {
+void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) {
   /*
    * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base
    * class is in general not equal to the pointer of the subclass. When patching metaspace pointers,
@@ -184,12 +184,14 @@
     Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
     assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed klass pointer %s @ " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass));
     int index = _oop_recorder->find_index(klass);
+    section->relocate(dest, metadata_Relocation::spec(index));
     TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
     return klass;
   } else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
     Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj);
     assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed method pointer %s @ " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method));
     int index = _oop_recorder->find_index(method);
+    section->relocate(dest, metadata_Relocation::spec(index));
     TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string());
     return method;
   } else {
@@ -198,7 +200,7 @@
 }
 
 #ifdef _LP64
-narrowKlass CodeInstaller::record_narrow_metadata_reference(Handle constant, TRAPS) {
+narrowKlass CodeInstaller::record_narrow_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) {
   oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
   assert(HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected uncompressed pointer");
 
@@ -208,6 +210,7 @@
 
   Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
   int index = _oop_recorder->find_index(klass);
+  section->relocate(dest, metadata_Relocation::spec(index));
   TRACE_jvmci_3("narrowKlass[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
   return Klass::encode_klass(klass);
 }
@@ -701,12 +704,12 @@
     if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
       if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
 #ifdef _LP64
-        *((narrowKlass*) dest) = record_narrow_metadata_reference(constant, CHECK_OK);
+        *((narrowKlass*) dest) = record_narrow_metadata_reference(_constants, dest, constant, CHECK_OK);
 #else
         JVMCI_ERROR_OK("unexpected compressed Klass* in 32-bit mode");
 #endif
       } else {
-        *((void**) dest) = record_metadata_reference(constant, CHECK_OK);
+        *((void**) dest) = record_metadata_reference(_constants, dest, constant, CHECK_OK);
       }
     } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
       Handle obj = HotSpotObjectConstantImpl::object(constant);
--- a/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -189,9 +189,9 @@
   ScopeValue* get_scope_value(Handle value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, TRAPS);
   MonitorValue* get_monitor_value(Handle value, GrowableArray<ScopeValue*>* objects, TRAPS);
 
-  void* record_metadata_reference(Handle constant, TRAPS);
+  void* record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS);
 #ifdef _LP64
-  narrowKlass record_narrow_metadata_reference(Handle constant, TRAPS);
+  narrowKlass record_narrow_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS);
 #endif
 
   // extract the fields of the HotSpotCompiledCode
--- a/src/share/vm/jvmci/jvmciRuntime.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/jvmci/jvmciRuntime.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -640,8 +640,6 @@
 JVM_END
 
 Handle JVMCIRuntime::callStatic(const char* className, const char* methodName, const char* signature, JavaCallArguments* args, TRAPS) {
-  guarantee(!_HotSpotJVMCIRuntime_initialized, "cannot reinitialize HotSpotJVMCIRuntime");
-
   TempNewSymbol name = SymbolTable::new_symbol(className, CHECK_(Handle()));
   KlassHandle klass = SystemDictionary::resolve_or_fail(name, true, CHECK_(Handle()));
   TempNewSymbol runtime = SymbolTable::new_symbol(methodName, CHECK_(Handle()));
@@ -656,42 +654,37 @@
 }
 
 void JVMCIRuntime::initialize_HotSpotJVMCIRuntime(TRAPS) {
-  if (JNIHandles::resolve(_HotSpotJVMCIRuntime_instance) == NULL) {
-    ResourceMark rm;
-#ifdef ASSERT
-    // This should only be called in the context of the JVMCI class being initialized
-    TempNewSymbol name = SymbolTable::new_symbol("jdk/vm/ci/runtime/JVMCI", CHECK);
-    Klass* k = SystemDictionary::resolve_or_null(name, CHECK);
-    instanceKlassHandle klass = InstanceKlass::cast(k);
-    assert(klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD),
-           "HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization");
-#endif
+  guarantee(!_HotSpotJVMCIRuntime_initialized, "cannot reinitialize HotSpotJVMCIRuntime");
+  JVMCIRuntime::initialize_well_known_classes(CHECK);
+  // This should only be called in the context of the JVMCI class being initialized
+  instanceKlassHandle klass = InstanceKlass::cast(SystemDictionary::JVMCI_klass());
+  guarantee(klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD),
+         "HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization");
 
-    Handle result = callStatic("jdk/vm/ci/hotspot/HotSpotJVMCIRuntime",
-                               "runtime",
-                               "()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;", NULL, CHECK);
-    objArrayOop trivial_prefixes = HotSpotJVMCIRuntime::trivialPrefixes(result);
-    if (trivial_prefixes != NULL) {
-      char** prefixes = NEW_C_HEAP_ARRAY(char*, trivial_prefixes->length(), mtCompiler);
-      for (int i = 0; i < trivial_prefixes->length(); i++) {
-        oop str = trivial_prefixes->obj_at(i);
-        if (str == NULL) {
-          THROW(vmSymbols::java_lang_NullPointerException());
-        } else {
-          prefixes[i] = strdup(java_lang_String::as_utf8_string(str));
-        }
+  Handle result = callStatic("jdk/vm/ci/hotspot/HotSpotJVMCIRuntime",
+                             "runtime",
+                             "()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;", NULL, CHECK);
+  objArrayOop trivial_prefixes = HotSpotJVMCIRuntime::trivialPrefixes(result);
+  if (trivial_prefixes != NULL) {
+    char** prefixes = NEW_C_HEAP_ARRAY(char*, trivial_prefixes->length(), mtCompiler);
+    for (int i = 0; i < trivial_prefixes->length(); i++) {
+      oop str = trivial_prefixes->obj_at(i);
+      if (str == NULL) {
+        THROW(vmSymbols::java_lang_NullPointerException());
+      } else {
+        prefixes[i] = strdup(java_lang_String::as_utf8_string(str));
       }
-      _trivial_prefixes = prefixes;
-      _trivial_prefixes_count = trivial_prefixes->length();
     }
-    int adjustment = HotSpotJVMCIRuntime::compilationLevelAdjustment(result);
-    assert(adjustment >= JVMCIRuntime::none &&
-           adjustment <= JVMCIRuntime::by_full_signature,
-           "compilation level adjustment out of bounds");
-    _comp_level_adjustment = (CompLevelAdjustment) adjustment;
-    _HotSpotJVMCIRuntime_initialized = true;
-    _HotSpotJVMCIRuntime_instance = JNIHandles::make_global(result());
+    _trivial_prefixes = prefixes;
+    _trivial_prefixes_count = trivial_prefixes->length();
   }
+  int adjustment = HotSpotJVMCIRuntime::compilationLevelAdjustment(result);
+  assert(adjustment >= JVMCIRuntime::none &&
+         adjustment <= JVMCIRuntime::by_full_signature,
+         "compilation level adjustment out of bounds");
+  _comp_level_adjustment = (CompLevelAdjustment) adjustment;
+  _HotSpotJVMCIRuntime_initialized = true;
+  _HotSpotJVMCIRuntime_instance = JNIHandles::make_global(result());
 }
 
 void JVMCIRuntime::initialize_JVMCI(TRAPS) {
--- a/src/share/vm/jvmci/jvmci_globals.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/jvmci/jvmci_globals.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -85,6 +85,7 @@
   CHECK_NOT_SET(JVMCIUseFastLocking,          EnableJVMCI)
   CHECK_NOT_SET(JVMCINMethodSizeLimit,        EnableJVMCI)
   CHECK_NOT_SET(MethodProfileWidth,           EnableJVMCI)
+  CHECK_NOT_SET(JVMCIPrintProperties,         EnableJVMCI)
   CHECK_NOT_SET(TraceUncollectedSpeculations, EnableJVMCI)
 
 #ifndef PRODUCT
--- a/src/share/vm/jvmci/jvmci_globals.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/jvmci/jvmci_globals.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -49,6 +49,9 @@
   experimental(bool, UseJVMCICompiler, false,                               \
           "Use JVMCI as the default compiler")                              \
                                                                             \
+  experimental(bool, JVMCIPrintProperties, false,                           \
+          "Prints properties used by the JVMCI compiler")                   \
+                                                                            \
   experimental(bool, BootstrapJVMCI, false,                                 \
           "Bootstrap JVMCI before running Java main method")                \
                                                                             \
--- a/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -29,6 +29,7 @@
 #else
 #define JVMCI_WK_KLASSES_DO(do_klass)                                                                                           \
   /* JVMCI classes. These are loaded on-demand. */                                                                              \
+  do_klass(JVMCI_klass,                                  jdk_vm_ci_runtime_JVMCI,                               Jvmci) \
   do_klass(HotSpotCompiledCode_klass,                    jdk_vm_ci_hotspot_HotSpotCompiledCode,                 Jvmci) \
   do_klass(HotSpotCompiledCode_Comment_klass,            jdk_vm_ci_hotspot_HotSpotCompiledCode_Comment,         Jvmci) \
   do_klass(HotSpotCompiledNmethod_klass,                 jdk_vm_ci_hotspot_HotSpotCompiledNmethod,              Jvmci) \
--- a/src/share/vm/jvmci/vmStructs_jvmci.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/jvmci/vmStructs_jvmci.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -169,6 +169,8 @@
   nonstatic_field(JVMCIEnv,                    _task,                                         CompileTask*)                          \
   nonstatic_field(JVMCIEnv,                    _jvmti_can_hotswap_or_post_breakpoint,         bool)                                  \
                                                                                                                                      \
+  nonstatic_field(InvocationCounter,           _counter,                                      unsigned int)                          \
+                                                                                                                                     \
   nonstatic_field(Klass,                       _secondary_super_cache,                        Klass*)                                \
   nonstatic_field(Klass,                       _secondary_supers,                             Array<Klass*>*)                        \
   nonstatic_field(Klass,                       _super,                                        Klass*)                                \
@@ -199,13 +201,34 @@
   volatile_nonstatic_field(Method,             _code,                                         CompiledMethod*)                       \
   volatile_nonstatic_field(Method,             _from_compiled_entry,                          address)                               \
                                                                                                                                      \
+  nonstatic_field(MethodCounters,              _nmethod_age,                                  int)                                   \
+  nonstatic_field(MethodCounters,              _interpreter_invocation_limit,                 int)                                   \
+  nonstatic_field(MethodCounters,              _interpreter_backward_branch_limit,            int)                                   \
+  nonstatic_field(MethodCounters,              _interpreter_profile_limit,                    int)                                   \
+  nonstatic_field(MethodCounters,              _invoke_mask,                                  int)                                   \
+  nonstatic_field(MethodCounters,              _backedge_mask,                                int)                                   \
+  nonstatic_field(MethodCounters,              _interpreter_invocation_count,                 int)                                   \
+  nonstatic_field(MethodCounters,              _interpreter_throwout_count,                   u2)                                    \
+  JVMTI_ONLY(nonstatic_field(MethodCounters,   _number_of_breakpoints,                        u2))                                   \
   nonstatic_field(MethodCounters,              _invocation_counter,                           InvocationCounter)                     \
   nonstatic_field(MethodCounters,              _backedge_counter,                             InvocationCounter)                     \
                                                                                                                                      \
   nonstatic_field(MethodData,                  _size,                                         int)                                   \
+  nonstatic_field(MethodData,                  _method,                                       Method*)                               \
   nonstatic_field(MethodData,                  _data_size,                                    int)                                   \
   nonstatic_field(MethodData,                  _data[0],                                      intptr_t)                              \
+  nonstatic_field(MethodData,                  _parameters_type_data_di,                      int)                                   \
+  nonstatic_field(MethodData,                  _nof_decompiles,                               uint)                                  \
+  nonstatic_field(MethodData,                  _nof_overflow_recompiles,                      uint)                                  \
+  nonstatic_field(MethodData,                  _nof_overflow_traps,                           uint)                                  \
   nonstatic_field(MethodData,                  _trap_hist._array[0],                          u1)                                    \
+  nonstatic_field(MethodData,                  _eflags,                                       intx)                                  \
+  nonstatic_field(MethodData,                  _arg_local,                                    intx)                                  \
+  nonstatic_field(MethodData,                  _arg_stack,                                    intx)                                  \
+  nonstatic_field(MethodData,                  _arg_returned,                                 intx)                                  \
+  nonstatic_field(MethodData,                  _tenure_traps,                                 uint)                                  \
+  nonstatic_field(MethodData,                  _invoke_mask,                                  int)                                   \
+  nonstatic_field(MethodData,                  _backedge_mask,                                int)                                   \
   nonstatic_field(MethodData,                  _jvmci_ir_size,                                int)                                   \
                                                                                                                                      \
   nonstatic_field(nmethod,                     _verified_entry_point,                         address)                               \
@@ -290,6 +313,7 @@
   declare_toplevel_type(ExceptionTableElement)                            \
   declare_toplevel_type(Flag)                                             \
   declare_toplevel_type(Flag*)                                            \
+  declare_toplevel_type(InvocationCounter)                                \
   declare_toplevel_type(JVMCIEnv)                                         \
   declare_toplevel_type(LocalVariableTableElement)                        \
   declare_toplevel_type(narrowKlass)                                      \
@@ -688,7 +712,6 @@
   declare_constant(VM_Version::sun4v_m)                                   \
   declare_constant(VM_Version::blk_init_instructions_m)                   \
   declare_constant(VM_Version::fmaf_instructions_m)                       \
-  declare_constant(VM_Version::fmau_instructions_m)                       \
   declare_constant(VM_Version::sparc64_family_m)                          \
   declare_constant(VM_Version::M_family_m)                                \
   declare_constant(VM_Version::T_family_m)                                \
--- a/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -29,6 +29,7 @@
 #define JVMCI_VM_SYMBOLS_DO(template, do_alias)
 #else
 #define JVMCI_VM_SYMBOLS_DO(template, do_alias)                                                                            \
+  template(jdk_vm_ci_runtime_JVMCI,                               "jdk/vm/ci/runtime/JVMCI")                               \
   template(jdk_vm_ci_hotspot_HotSpotCompiledCode,                 "jdk/vm/ci/hotspot/HotSpotCompiledCode")                 \
   template(jdk_vm_ci_hotspot_HotSpotCompiledCode_Comment,         "jdk/vm/ci/hotspot/HotSpotCompiledCode$Comment")         \
   template(jdk_vm_ci_hotspot_HotSpotCompiledNmethod,              "jdk/vm/ci/hotspot/HotSpotCompiledNmethod")              \
--- a/src/share/vm/logging/log.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1197 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-
-/////////////// Unit tests ///////////////
-
-#ifndef PRODUCT
-
-#include "gc/shared/gcTraceTime.inline.hpp"
-#include "logging/log.hpp"
-#include "logging/logConfiguration.hpp"
-#include "logging/logFileOutput.hpp"
-#include "logging/logMessage.hpp"
-#include "logging/logMessageBuffer.hpp"
-#include "logging/logOutput.hpp"
-#include "logging/logTagLevelExpression.hpp"
-#include "logging/logTagSet.hpp"
-#include "logging/logTagSetDescriptions.hpp"
-#include "logging/logStream.inline.hpp"
-#include "memory/resourceArea.hpp"
-
-#define assert_str_eq(s1, s2) \
-  assert(strcmp(s1, s2) == 0, "Expected '%s' to equal '%s'", s1, s2)
-
-#define assert_char_in(c, s) \
-  assert(strchr(s, c) != NULL, "Expected '%s' to contain character '%c'", s, c)
-
-#define assert_char_not_in(c, s) \
-  assert(strchr(s, c) == NULL, "Expected '%s' to *not* contain character '%c'", s, c)
-
-void Test_log_tag_combinations_limit() {
-  assert(LogTagLevelExpression::MaxCombinations > LogTagSet::ntagsets(),
-      "Combination limit (" SIZE_FORMAT ") not sufficient "
-      "for configuring all available tag sets (" SIZE_FORMAT ")",
-      LogTagLevelExpression::MaxCombinations, LogTagSet::ntagsets());
-}
-
-// Read a complete line from fp and return it as a resource allocated string.
-// Returns NULL on EOF.
-static char* read_line(FILE* fp) {
-  assert(fp != NULL, "bad fp");
-  int buflen = 512;
-  char* buf = NEW_RESOURCE_ARRAY(char, buflen);
-  long pos = ftell(fp);
-
-  char* ret = fgets(buf, buflen, fp);
-  while (ret != NULL && buf[strlen(buf) - 1] != '\n' && !feof(fp)) {
-    // retry with a larger buffer
-    buf = REALLOC_RESOURCE_ARRAY(char, buf, buflen, buflen * 2);
-    buflen *= 2;
-    // rewind to beginning of line
-    fseek(fp, pos, SEEK_SET);
-    // retry read with new buffer
-    ret = fgets(buf, buflen, fp);
-  }
-  return ret;
-}
-
-static bool file_contains_substrings_in_order(const char* filename, const char* substrs[]) {
-  FILE* fp = fopen(filename, "r");
-  assert(fp != NULL, "error opening file %s: %s", filename, strerror(errno));
-
-  size_t idx = 0;
-  while (substrs[idx] != NULL) {
-    ResourceMark rm;
-    char* line = read_line(fp);
-    if (line == NULL) {
-      break;
-    }
-    for (char* match = strstr(line, substrs[idx]); match != NULL;) {
-      size_t match_len = strlen(substrs[idx]);
-      idx++;
-      if (substrs[idx] == NULL) {
-        break;
-      }
-      match = strstr(match + match_len, substrs[idx]);
-    }
-  }
-
-  fclose(fp);
-  return substrs[idx] == NULL;
-}
-
-static bool file_contains_substring(const char* filename, const char* substr) {
-  const char* strs[] = {substr, NULL};
-  return file_contains_substrings_in_order(filename, strs);
-}
-
-static size_t number_of_lines_with_substring_in_file(const char* filename,
-                                                     const char* substr) {
-  FILE* fp = fopen(filename, "r");
-  assert(fp != NULL, "error opening file %s: %s", filename, strerror(errno));
-
-  size_t ret = 0;
-  for (;;) {
-    ResourceMark rm;
-    char* line = read_line(fp);
-    if (line == NULL) {
-      break;
-    }
-    if (strstr(line, substr) != NULL) {
-      ret++;
-    }
-  }
-
-  fclose(fp);
-  return ret;
-}
-
-static bool file_exists(const char* filename) {
-  struct stat st;
-  return os::stat(filename, &st) == 0;
-}
-
-static void delete_file(const char* filename) {
-  if (!file_exists(filename)) {
-    return;
-  }
-  int ret = remove(filename);
-  assert(ret == 0, "failed to remove file '%s': %s", filename, strerror(errno));
-}
-
-static void create_directory(const char* name) {
-  assert(!file_exists(name), "can't create directory: %s already exists", name);
-  bool failed;
-#ifdef _WINDOWS
-  failed = !CreateDirectory(name, NULL);
-#else
-  failed = mkdir(name, 0777);
-#endif
-  assert(!failed, "failed to create directory %s", name);
-}
-
-class TestLogFile {
- private:
-  char file_name[256];
-
-  void set_name(const char* test_name) {
-    const char* tmpdir = os::get_temp_directory();
-    int pos = jio_snprintf(file_name, sizeof(file_name), "%s%svmtest.%s.%d.log", tmpdir, os::file_separator(), test_name, os::current_process_id());
-    assert(pos > 0, "too small log file name buffer");
-    assert((size_t)pos < sizeof(file_name), "too small log file name buffer");
-  }
-
- public:
-  TestLogFile(const char* test_name) {
-    set_name(test_name);
-    remove(name());
-  }
-
-  ~TestLogFile() {
-    remove(name());
-  }
-
-  const char* name() {
-    return file_name;
-  }
-};
-
-class TestLogSavedConfig {
- private:
-  char* _saved_config;
-  char* _new_output;
-  Log(logging) _log;
- public:
-  TestLogSavedConfig(const char* apply_output = NULL, const char* apply_setting = NULL) : _new_output(0) {
-    ResourceMark rm;
-    _saved_config = os::strdup_check_oom(LogOutput::Stdout->config_string());
-    bool success = LogConfiguration::parse_log_arguments("stdout", "all=off", NULL, NULL, _log.error_stream());
-    assert(success, "test unable to turn all off");
-
-    if (apply_output) {
-      _new_output = os::strdup_check_oom(apply_output);
-      bool success = LogConfiguration::parse_log_arguments(_new_output, apply_setting,  NULL, NULL, _log.error_stream());
-      assert(success, "test unable to apply test log configuration");
-    }
-  }
-
-  ~TestLogSavedConfig() {
-    ResourceMark rm;
-    if (_new_output) {
-      bool success = LogConfiguration::parse_log_arguments(_new_output, "all=off", NULL, NULL, _log.error_stream());
-      assert(success, "test unable to turn all off");
-      os::free(_new_output);
-    }
-
-    bool success = LogConfiguration::parse_log_arguments("stdout", _saved_config, NULL, NULL, _log.error_stream());
-    assert(success, "test unable to restore log configuration");
-    os::free(_saved_config);
-  }
-};
-
-void Test_configure_stdout() {
-  LogOutput* stdoutput = LogOutput::Stdout;
-  TestLogSavedConfig tlsc;
-
-  // Enable 'logging=info', verifying it has been set
-  LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(logging));
-  assert_str_eq("logging=info", stdoutput->config_string());
-  assert(log_is_enabled(Info, logging), "logging was not properly enabled");
-
-  // Enable 'gc=debug' (no wildcard), verifying no other tags are enabled
-  LogConfiguration::configure_stdout(LogLevel::Debug, true, LOG_TAGS(gc));
-  // No '+' character means only single tags are enabled, and no combinations
-  assert_char_not_in('+', stdoutput->config_string());
-  assert(log_is_enabled(Debug, gc), "logging was not properly enabled");
-
-  // Enable 'gc*=trace' (with wildcard), verifying at least one tag combination is enabled (gc+...)
-  LogConfiguration::configure_stdout(LogLevel::Trace, false, LOG_TAGS(gc));
-  assert_char_in('+', stdoutput->config_string());
-  assert(log_is_enabled(Trace, gc), "logging was not properly enabled");
-
-  // Disable 'gc*' and 'logging', verifying all logging is properly disabled
-  LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(gc));
-  LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(logging));
-  assert_str_eq("all=off", stdoutput->config_string());
-}
-
-static const char* ExpectedLine = "a (hopefully) unique log line for testing";
-
-static void init_file(const char* filename, const char* options = "") {
-  LogConfiguration::parse_log_arguments(filename, "logging=trace", "", options,
-                                        Log(logging)::error_stream());
-  log_debug(logging)("%s", ExpectedLine);
-  LogConfiguration::parse_log_arguments(filename, "all=off", "", "",
-                                        Log(logging)::error_stream());
-}
-
-void Test_log_file_startup_rotation() {
-  ResourceMark rm;
-  const size_t rotations = 5;
-  const char* filename = "start-rotate-test";
-  char* rotated_file[rotations];
-  for (size_t i = 0; i < rotations; i++) {
-    size_t len = strlen(filename) + 3;
-    rotated_file[i] = NEW_RESOURCE_ARRAY(char, len);
-    jio_snprintf(rotated_file[i], len, "%s." SIZE_FORMAT, filename, i);
-    delete_file(rotated_file[i]);
-  };
-
-  delete_file(filename);
-  init_file(filename);
-  assert(file_exists(filename),
-         "configured logging to file '%s' but file was not found", filename);
-
-  // Initialize the same file a bunch more times to trigger rotations
-  for (size_t i = 0; i < rotations; i++) {
-    init_file(filename);
-    assert(file_exists(rotated_file[i]), "existing file was not rotated");
-  }
-
-  // Remove a file and expect its slot to be re-used
-  delete_file(rotated_file[1]);
-  init_file(filename);
-  assert(file_exists(rotated_file[1]), "log file not properly rotated");
-
-  // Clean up after test
-  delete_file(filename);
-  for (size_t i = 0; i < rotations; i++) {
-    delete_file(rotated_file[i]);
-  }
-}
-
-void Test_log_file_startup_truncation() {
-  ResourceMark rm;
-  const char* filename = "start-truncate-test";
-  const char* archived_filename = "start-truncate-test.0";
-
-  delete_file(filename);
-  delete_file(archived_filename);
-
-  // Use the same log file twice and expect it to be overwritten/truncated
-  init_file(filename, "filecount=0");
-  assert(file_exists(filename), "couldn't find log file: %s", filename);
-
-  init_file(filename, "filecount=0");
-  assert(file_exists(filename), "couldn't find log file: %s", filename);
-  assert(!file_exists(archived_filename),
-         "existing log file %s was not properly truncated when filecount was 0",
-         filename);
-
-  // Verify that the file was really truncated and not just appended
-  assert(number_of_lines_with_substring_in_file(filename, ExpectedLine) == 1,
-         "log file %s appended rather than truncated", filename);
-
-  delete_file(filename);
-  delete_file(archived_filename);
-}
-
-class LogMessageTest {
- private:
-  static Log(logging) _log;
-  static const char* _level_filename[];
-
-  static void test_level_inclusion();
-  static void test_long_message();
-  static void test_message_with_many_lines();
-  static void test_line_order();
-  static void test_prefixing();
-  static void test_scoped_messages();
-  static void test_scoped_flushing();
-  static void test_scoped_reset();
-
- public:
-  static void test();
-};
-
-const char* LogMessageTest::_level_filename[] = {
-  NULL, // LogLevel::Off
-#define LOG_LEVEL(name, printname) "multiline-" #printname ".log",
-  LOG_LEVEL_LIST
-#undef LOG_LEVEL
-};
-
-void Test_multiline_logging() {
-  LogMessageTest::test();
-}
-
-void LogMessageTest::test() {
-  ResourceMark rm;
-
-  for (int i = 0; i < LogLevel::Count; i++) {
-    char buf[32];
-    // Attempt to remove possibly pre-existing log files
-    remove(_level_filename[i]);
-
-    jio_snprintf(buf, sizeof(buf), "logging=%s", LogLevel::name(static_cast<LogLevelType>(i)));
-    bool success = LogConfiguration::parse_log_arguments(_level_filename[i], buf,
-                                                         NULL, NULL, _log.error_stream());
-    assert(success, "unable to configure logging to file '%s'", _level_filename[i]);
-  }
-
-  test_level_inclusion();
-  test_line_order();
-  test_long_message();
-  test_message_with_many_lines();
-  test_prefixing();
-  test_scoped_messages();
-  test_scoped_flushing();
-  test_scoped_reset();
-
-  // Stop logging to the files and remove them.
-  for (int i = 0; i < LogLevel::Count; i++) {
-    LogConfiguration::parse_log_arguments(_level_filename[i], "all=off", NULL, NULL, _log.error_stream());
-    remove(_level_filename[i]);
-  }
-}
-
-// Verify that messages with multiple levels are written
-// to outputs configured for all the corresponding levels
-void LogMessageTest::test_level_inclusion() {
-  const size_t message_count = 10;
-  LogMessageBuffer msg[message_count];
-
-  struct {
-    int message_number;
-    LogLevelType level;
-  } lines[] = {
-    { 0, LogLevel::Error },
-    { 1, LogLevel::Info },
-    { 2, LogLevel::Info }, { 2, LogLevel::Debug },
-    { 3, LogLevel::Info }, { 3, LogLevel::Warning },
-    { 4, LogLevel::Debug }, { 4, LogLevel::Warning },
-    { 5, LogLevel::Trace }, { 5, LogLevel::Debug },
-    { 6, LogLevel::Warning }, { 6, LogLevel::Error },
-    { 7, LogLevel::Trace }, { 7, LogLevel::Info }, { 7, LogLevel::Debug },
-    { 8, LogLevel::Trace }, { 8, LogLevel::Debug }, { 8, LogLevel::Info },
-    { 8, LogLevel::Warning }, { 8, LogLevel::Error},
-    { 9, LogLevel::Trace }
-  };
-
-  // Fill in messages with the above lines
-  for (size_t i = 0; i < ARRAY_SIZE(lines); i++) {
-    switch (lines[i].level) {
-#define LOG_LEVEL(name, printname) \
-    case LogLevel::name: \
-      msg[lines[i].message_number].printname("msg[%d]: " #printname, lines[i].message_number); \
-      break;
-LOG_LEVEL_LIST
-#undef LOG_LEVEL
-    }
-  }
-
-  for (size_t i = 0; i < message_count; i++) {
-    _log.write(msg[i]);
-  }
-
-  // Verify that lines are written to the expected log files
-  for (size_t i = 0; i < ARRAY_SIZE(lines); i++) {
-    char expected[256];
-    jio_snprintf(expected, sizeof(expected), "msg[%d]: %s",
-                 lines[i].message_number, LogLevel::name(lines[i].level));
-    for (int level = lines[i].level; level > 0; level--) {
-      assert(file_contains_substring(_level_filename[level], expected),
-      "line #" SIZE_FORMAT " missing from log file '%s'", i, _level_filename[level]);
-    }
-    for (int level = lines[i].level + 1; level < LogLevel::Count; level++) {
-      assert(!file_contains_substring(_level_filename[level], expected),
-      "line #" SIZE_FORMAT " erroneously included in log file '%s'", i, _level_filename[level]);
-    }
-  }
-}
-
-// Verify that messages are logged in the order they are added to the log message
-void LogMessageTest::test_line_order() {
-  LogMessageBuffer msg;
-  msg.info("info line").error("error line").trace("trace line")
-      .error("another error").warning("warning line").debug("debug line");
-  _log.write(msg);
-
-  const char* expected[] = { "info line", "error line", "trace line",
-                             "another error", "warning line", "debug line", NULL };
-  assert(file_contains_substrings_in_order(_level_filename[LogLevel::Trace], expected),
-         "output missing or in incorrect order");
-}
-
-void LogMessageTest::test_long_message() {
-  // Write 10K bytes worth of log data
-  LogMessageBuffer msg;
-  const size_t size = 10 * K;
-  const char* start_marker = "#start#";
-  const char* end_marker = "#the end#";
-  char* data = NEW_C_HEAP_ARRAY(char, size, mtLogging);
-
-  // fill buffer with start_marker...some data...end_marker
-  sprintf(data, "%s", start_marker);
-  for (size_t i = strlen(start_marker); i < size; i++) {
-    data[i] = '0' + (i % 10);
-  }
-  sprintf(data + size - strlen(end_marker) - 1, "%s", end_marker);
-
-  msg.trace("%s", data); // Adds a newline, making the message exactly 10K in length.
-  _log.write(msg);
-
-  const char* expected[] = { start_marker, "0123456789", end_marker, NULL };
-  assert(file_contains_substrings_in_order(_level_filename[LogLevel::Trace], expected),
-         "unable to print long line");
-  FREE_C_HEAP_ARRAY(char, data);
-}
-
-void LogMessageTest::test_message_with_many_lines() {
-  const size_t lines = 100;
-  const size_t line_length = 16;
-
-  LogMessageBuffer msg;
-  for (size_t i = 0; i < lines; i++) {
-    msg.info("Line #" SIZE_FORMAT, i);
-  }
-  _log.write(msg);
-
-  char expected_lines_data[lines][line_length];
-  const char* expected_lines[lines + 1];
-  for (size_t i = 0; i < lines; i++) {
-    jio_snprintf(&expected_lines_data[i][0], line_length, "Line #" SIZE_FORMAT, i);
-    expected_lines[i] = expected_lines_data[i];
-  }
-  expected_lines[lines] = NULL;
-
-  assert(file_contains_substrings_in_order(_level_filename[LogLevel::Trace], expected_lines),
-         "couldn't find all lines in multiline message");
-}
-
-static size_t dummy_prefixer(char* buf, size_t len) {
-  static int i = 0;
-  const char* prefix = "some prefix: ";
-  const size_t prefix_len = strlen(prefix);
-  if (len < prefix_len) {
-    return prefix_len;
-  }
-  jio_snprintf(buf, len, "%s", prefix);
-  return prefix_len;
-}
-
-void LogMessageTest::test_prefixing() {
-  LogMessageBuffer msg;
-  msg.set_prefix(dummy_prefixer);
-  for (int i = 0; i < 3; i++) {
-    msg.info("test %d", i);
-  }
-  msg.set_prefix(NULL);
-  msg.info("test 3");
-  _log.write(msg);
-
-  const char* expected[] = {
-    "] some prefix: test 0",
-    "] some prefix: test 1",
-    "] some prefix: test 2",
-    "] test 3",
-    NULL
-  };
-  assert(file_contains_substrings_in_order(_level_filename[LogLevel::Trace], expected), "error in prefixed output");
-}
-
-void LogMessageTest::test_scoped_messages() {
-  {
-    LogMessage(logging) msg;
-    msg.info("scoped info");
-    msg.warning("scoped warn");
-    assert(!file_contains_substring(_level_filename[LogLevel::Info], "scoped info"),
-           "scoped log message written prematurely");
-  }
-  assert(file_contains_substring(_level_filename[LogLevel::Info], "scoped info"),
-         "missing output from scoped log message");
-  assert(file_contains_substring(_level_filename[LogLevel::Warning], "scoped warn"),
-         "missing output from scoped log message");
-}
-
-void LogMessageTest::test_scoped_flushing() {
-  {
-    LogMessage(logging) msg;
-    msg.info("manual flush info");
-    msg.flush();
-    assert(file_contains_substring(_level_filename[LogLevel::Info], "manual flush info"),
-           "missing output from manually flushed scoped log message");
-  }
-  const char* tmp[] = {"manual flush info", "manual flush info", NULL};
-  assert(!file_contains_substrings_in_order(_level_filename[LogLevel::Info], tmp),
-         "log file contains duplicate lines from single scoped log message");
-}
-
-void LogMessageTest::test_scoped_reset() {
-  {
-    LogMessage(logging) msg, partial;
-    msg.info("%s", "info reset msg");
-    msg.reset();
-    partial.info("%s", "info reset msg");
-    partial.reset();
-    partial.trace("%s", "trace reset msg");
-  }
-  assert(!file_contains_substring(_level_filename[LogLevel::Info], "info reset msg"),
-         "reset message written anyway");
-  assert(file_contains_substring(_level_filename[LogLevel::Trace], "trace reset msg"),
-         "missing message from partially reset scoped log message");
-}
-
-
-static int Test_logconfiguration_subscribe_triggered = 0;
-
-static void Test_logconfiguration_subscribe_helper() {
-  Test_logconfiguration_subscribe_triggered++;
-}
-
-void Test_logconfiguration_subscribe() {
-  ResourceMark rm;
-  Log(logging) log;
-
-  TestLogSavedConfig log_cfg("stdout", "logging*=trace");
-
-  LogConfiguration::register_update_listener(&Test_logconfiguration_subscribe_helper);
-
-  LogConfiguration::parse_log_arguments("stdout", "logging=trace", NULL, NULL, log.error_stream());
-  assert(Test_logconfiguration_subscribe_triggered == 1, "subscription not triggered (1)");
-
-  LogConfiguration::configure_stdout(LogLevel::Debug, true, LOG_TAGS(gc));
-  assert(Test_logconfiguration_subscribe_triggered == 2, "subscription not triggered (2)");
-
-  LogConfiguration::disable_logging();
-  assert(Test_logconfiguration_subscribe_triggered == 3, "subscription not triggered (3)");
-}
-
-#define LOG_PREFIX_STR "THE_PREFIX "
-#define LOG_LINE_STR "a log line"
-
-size_t Test_log_prefix_prefixer(char* buf, size_t len) {
-  int ret = jio_snprintf(buf, len, LOG_PREFIX_STR);
-  assert(ret > 0, "Failed to print prefix. Log buffer too small?");
-  return (size_t) ret;
-}
-
-void Test_log_prefix() {
-  TestLogFile log_file("log_prefix");
-  TestLogSavedConfig log_cfg(log_file.name(), "logging+test=trace");
-
-  log_trace(logging, test)(LOG_LINE_STR);
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-  char output[1024];
-  if (fgets(output, 1024, fp) != NULL) {
-    assert(strstr(output, LOG_PREFIX_STR LOG_LINE_STR), "logging prefix error");
-  }
-  fclose(fp);
-}
-
-void Test_log_big() {
-  char big_msg[4096] = {0};
-  char Xchar = '~';
-
-  TestLogFile log_file("log_big");
-  TestLogSavedConfig log_cfg(log_file.name(), "logging+test=trace");
-
-  memset(big_msg, Xchar, sizeof(big_msg) - 1);
-
-  log_trace(logging, test)("%s", big_msg);
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-  char output[sizeof(big_msg)+128 /*decorators*/ ];
-  if (fgets(output, sizeof(output), fp) != NULL) {
-    assert(strstr(output, LOG_PREFIX_STR), "logging prefix error");
-    size_t count = 0;
-    for (size_t ps = 0 ; output[ps + count] != '\0'; output[ps + count] == Xchar ? count++ : ps++);
-    assert(count == (sizeof(big_msg) - 1) , "logging msg error");
-  }
-  fclose(fp);
-}
-
-void Test_logtagset_duplicates() {
-  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
-    char ts_name[512];
-    ts->label(ts_name, sizeof(ts_name), ",");
-
-    // verify that NO_TAG is never followed by a real tag
-    for (size_t i = 0; i < LogTag::MaxTags; i++) {
-      if (ts->tag(i) == LogTag::__NO_TAG) {
-        for (i++; i < LogTag::MaxTags; i++) {
-          assert(ts->tag(i) == LogTag::__NO_TAG,
-                 "NO_TAG was followed by a real tag (%s) in tagset %s",
-                 LogTag::name(ts->tag(i)), ts_name);
-        }
-      }
-    }
-
-    // verify that there are no duplicate tagsets (same tags in different order)
-    for (LogTagSet* other = ts->next(); other != NULL; other = other->next()) {
-      if (ts->ntags() != other->ntags()) {
-        continue;
-      }
-      bool equal = true;
-      for (size_t i = 0; i < ts->ntags(); i++) {
-        LogTagType tag = ts->tag(i);
-        if (!other->contains(tag)) {
-          equal = false;
-          break;
-        }
-      }
-      // Since tagsets are implemented using template arguments, using both of
-      // the (logically equivalent) tagsets (t1, t2) and (t2, t1) somewhere will
-      // instantiate two different LogTagSetMappings. This causes multiple
-      // tagset instances to be created for the same logical set. We want to
-      // avoid this to save time, memory and prevent any confusion around it.
-      if (equal) {
-        char other_name[512];
-        other->label(other_name, sizeof(other_name), ",");
-        assert(false, "duplicate LogTagSets found: '%s' vs '%s' "
-               "(tags must always be specified in the same order for each tagset)",
-               ts_name, other_name);
-      }
-    }
-  }
-}
-
-#define Test_logtarget_string_literal "First line"
-
-
-static void Test_logtarget_on() {
-  TestLogFile log_file("log_target");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=debug");
-
-  LogTarget(Debug, gc) log;
-
-  assert(log.is_enabled(), "assert");
-
-  // Log the line and expect it to be available in the output file.
-  log.print(Test_logtarget_string_literal);
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp != NULL, "File read error");
-
-  char output[256 /* Large enough buffer */];
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  assert(strstr(output, Test_logtarget_string_literal) != NULL, "log line missing");
-
-  fclose(fp);
-}
-
-static void Test_logtarget_off() {
-  TestLogFile log_file("log_target");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=info");
-
-  LogTarget(Debug, gc) log;
-
-  if (log.is_enabled()) {
-    // The log config could have been redirected gc=debug to a file. If gc=debug
-    // is enabled, we can only test that the LogTarget returns the same value
-    // as the log_is_enabled function. The rest of the test will be ignored.
-    assert(log.is_enabled() == log_is_enabled(Debug, gc), "assert");
-    log_warning(logging)("This test doesn't support runs with -Xlog");
-    return;
-  }
-
-  // Try to log, but expect this to be filtered out.
-  log.print(Test_logtarget_string_literal);
-
-  // Log a dummy line so that fgets doesn't return NULL because the file is empty.
-  log_info(gc)("Dummy line");
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp != NULL, "File read error");
-
-  char output[256 /* Large enough buffer */];
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  assert(strstr(output, Test_logtarget_string_literal) == NULL, "log line not missing");
-
-  fclose(fp);
-}
-
-void Test_logtarget() {
-  Test_logtarget_on();
-  Test_logtarget_off();
-}
-
-
-static void Test_logstream_helper(outputStream* stream) {
-  TestLogFile log_file("log_stream");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=debug");
-
-  // Try to log, but expect this to be filtered out.
-  stream->print("%d ", 3); stream->print("workers"); stream->cr();
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp != NULL, "File read error");
-
-  char output[256 /* Large enough buffer */];
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  assert(strstr(output, "3 workers") != NULL, "log line missing");
-
-  fclose(fp);
-}
-
-static void Test_logstream_log() {
-  Log(gc) log;
-  LogStream stream(log.debug());
-
-  Test_logstream_helper(&stream);
-}
-
-static void Test_logstream_logtarget() {
-  LogTarget(Debug, gc) log;
-  LogStream stream(log);
-
-  Test_logstream_helper(&stream);
-}
-
-static void Test_logstream_logstreamhandle() {
-  LogStreamHandle(Debug, gc) stream;
-
-  Test_logstream_helper(&stream);
-}
-
-static void Test_logstream_no_rm() {
-  ResourceMark rm;
-  outputStream* stream = LogTarget(Debug, gc)::stream();
-
-  Test_logstream_helper(stream);
-}
-
-static void Test_logstreamcheap_log() {
-  Log(gc) log;
-  LogStreamCHeap stream(log.debug());
-
-  Test_logstream_helper(&stream);
-}
-
-static void Test_logstreamcheap_logtarget() {
-  LogTarget(Debug, gc) log;
-  LogStreamCHeap stream(log);
-
-  Test_logstream_helper(&stream);
-}
-
-void Test_logstream() {
-  // Test LogStreams with embedded ResourceMark.
-  Test_logstream_log();
-  Test_logstream_logtarget();
-  Test_logstream_logstreamhandle();
-
-  // Test LogStreams without embedded ResourceMark.
-  Test_logstream_no_rm();
-
-  // Test LogStreams backed by CHeap memory.
-  Test_logstreamcheap_log();
-  Test_logstreamcheap_logtarget();
-}
-
-void Test_loghandle_on() {
-  TestLogFile log_file("log_handle");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=debug");
-
-  Log(gc) log;
-  LogHandle log_handle(log);
-
-  assert(log_handle.is_debug(), "assert");
-
-  // Try to log through a LogHandle.
-  log_handle.debug("%d workers", 3);
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  assert(strstr(output, "3 workers") != NULL, "log line missing");
-
-  fclose(fp);
-}
-
-void Test_loghandle_off() {
-  TestLogFile log_file("log_handle");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=info");
-
-  Log(gc) log;
-  LogHandle log_handle(log);
-
-  if (log_handle.is_debug()) {
-    // The log config could have been redirected gc=debug to a file. If gc=debug
-    // is enabled, we can only test that the LogTarget returns the same value
-    // as the log_is_enabled function. The rest of the test will be ignored.
-    assert(log_handle.is_debug() == log_is_enabled(Debug, gc), "assert");
-    log_warning(logging)("This test doesn't support runs with -Xlog");
-    return;
-  }
-
-  // Try to log through a LogHandle. Should fail, since only info is turned on.
-  log_handle.debug("%d workers", 3);
-
-  // Log a dummy line so that fgets doesn't return NULL because the file is empty.
-  log_info(gc)("Dummy line");
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  assert(strstr(output, "3 workers") == NULL, "log line missing");
-
-  fclose(fp);
-}
-
-void Test_loghandle() {
-  Test_loghandle_on();
-  Test_loghandle_off();
-}
-
-static void Test_logtargethandle_on() {
-  TestLogFile log_file("log_handle");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=debug");
-
-  LogTarget(Debug, gc) log;
-  LogTargetHandle log_handle(log);
-
-  assert(log_handle.is_enabled(), "assert");
-
-  // Try to log through a LogHandle.
-  log_handle.print("%d workers", 3);
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  assert(strstr(output, "3 workers") != NULL, "log line missing");
-
-  fclose(fp);
-}
-
-static void Test_logtargethandle_off() {
-  TestLogFile log_file("log_handle");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=info");
-
-  LogTarget(Debug, gc) log;
-  LogTargetHandle log_handle(log);
-
-  if (log_handle.is_enabled()) {
-    // The log config could have been redirected gc=debug to a file. If gc=debug
-    // is enabled, we can only test that the LogTarget returns the same value
-    // as the log_is_enabled function. The rest of the test will be ignored.
-    assert(log_handle.is_enabled() == log_is_enabled(Debug, gc), "assert");
-    log_warning(logging)("This test doesn't support runs with -Xlog");
-    return;
-  }
-
-  // Try to log through a LogHandle. Should fail, since only info is turned on.
-  log_handle.print("%d workers", 3);
-
-  // Log a dummy line so that fgets doesn't return NULL because the file is empty.
-  log_info(gc)("Dummy line");
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  assert(strstr(output, "3 workers") == NULL, "log line missing");
-
-  fclose(fp);
-}
-
-void Test_logtargethandle() {
-  Test_logtargethandle_on();
-  Test_logtargethandle_off();
-}
-
-static void Test_log_gctracetime_full() {
-  TestLogFile log_file("log_gctracetime");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=debug,gc+start=debug");
-
-  LogTarget(Debug, gc) gc_debug;
-  LogTarget(Debug, gc, start) gc_start_debug;
-
-  assert(gc_debug.is_enabled(), "assert");
-  assert(gc_start_debug.is_enabled(), "assert");
-
-  {
-    MutexLocker lock(Heap_lock); // Needed to read heap usage
-    GCTraceTime(Debug, gc) timer("Test GC", NULL, GCCause::_allocation_failure, true);
-  }
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc,start] Test GC (Allocation Failure) (2.975s)
-  assert(strstr(output, "[gc,start") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (Allocation Failure) (") != NULL, "Incorrect log line");
-  assert(strstr(output, "s)") != NULL, "Incorrect log line");
-
-  res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc      ] Test GC (Allocation Failure) 59M->59M(502M) (2.975s, 2.975s) 0.026ms
-  assert(strstr(output, "[gc ") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (Allocation Failure) ") != NULL, "Incorrect log line");
-  assert(strstr(output, "M) (") != NULL, "Incorrect log line");
-  assert(strstr(output, "s, ") != NULL, "Incorrect log line");
-  assert(strstr(output, "s) ") != NULL, "Incorrect log line");
-  assert(strstr(output, "ms") != NULL, "Incorrect log line");
-
-  fclose(fp);
-}
-
-static void Test_log_gctracetime_full_multitag() {
-  TestLogFile log_file("log_gctracetime");
-  TestLogSavedConfig tlsc(log_file.name(), "gc+ref=debug,gc+ref+start=debug");
-
-  LogTarget(Debug, gc, ref) gc_debug;
-  LogTarget(Debug, gc, ref, start) gc_start_debug;
-
-  assert(gc_debug.is_enabled(), "assert");
-  assert(gc_start_debug.is_enabled(), "assert");
-
-  {
-    MutexLocker lock(Heap_lock); // Needed to read heap usage
-    GCTraceTime(Debug, gc, ref) timer("Test GC", NULL, GCCause::_allocation_failure, true);
-  }
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc,start] Test GC (Allocation Failure) (2.975s)
-  assert(strstr(output, "[gc,ref,start") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (Allocation Failure) (") != NULL, "Incorrect log line");
-  assert(strstr(output, "s)") != NULL, "Incorrect log line");
-
-  res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc      ] Test GC (Allocation Failure) 59M->59M(502M) (2.975s, 2.975s) 0.026ms
-  assert(strstr(output, "[gc,ref ") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (Allocation Failure) ") != NULL, "Incorrect log line");
-  assert(strstr(output, "M) (") != NULL, "Incorrect log line");
-  assert(strstr(output, "s, ") != NULL, "Incorrect log line");
-  assert(strstr(output, "s) ") != NULL, "Incorrect log line");
-  assert(strstr(output, "ms") != NULL, "Incorrect log line");
-
-  fclose(fp);
-}
-
-static void Test_log_gctracetime_no_heap() {
-  TestLogFile log_file("log_gctracetime");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=debug,gc+start=debug");
-
-  LogTarget(Debug, gc) gc_debug;
-  LogTarget(Debug, gc, start) gc_start_debug;
-
-  assert(gc_debug.is_enabled(), "assert");
-  assert(gc_start_debug.is_enabled(), "assert");
-
-  {
-    GCTraceTime(Debug, gc) timer("Test GC", NULL, GCCause::_allocation_failure, false);
-  }
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc,start] Test GC (Allocation Failure) (2.975s)
-  assert(strstr(output, "[gc,start") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (Allocation Failure) (") != NULL, "Incorrect log line");
-  assert(strstr(output, "s)") != NULL, "Incorrect log line");
-
-  res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc      ] Test GC (Allocation Failure) (2.975s, 2.975s) 0.026ms
-  assert(strstr(output, "[gc ") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (Allocation Failure) (") != NULL, "Incorrect log line");
-  assert(strstr(output, "M) (") == NULL, "Incorrect log line");
-  assert(strstr(output, "s, ") != NULL, "Incorrect log line");
-  assert(strstr(output, "s) ") != NULL, "Incorrect log line");
-  assert(strstr(output, "ms") != NULL, "Incorrect log line");
-
-  fclose(fp);
-}
-
-static void Test_log_gctracetime_no_cause() {
-  TestLogFile log_file("log_gctracetime");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=debug,gc+start=debug");
-
-  LogTarget(Debug, gc) gc_debug;
-  LogTarget(Debug, gc, start) gc_start_debug;
-
-  assert(gc_debug.is_enabled(), "assert");
-  assert(gc_start_debug.is_enabled(), "assert");
-
-  {
-    MutexLocker lock(Heap_lock); // Needed to read heap usage
-    GCTraceTime(Debug, gc) timer("Test GC", NULL, GCCause::_no_gc, true);
-  }
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc,start] Test GC (2.975s)
-  assert(strstr(output, "[gc,start") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (") != NULL, "Incorrect log line");
-  assert(strstr(output, "s)") != NULL, "Incorrect log line");
-
-  res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc      ] Test GC 59M->59M(502M) (2.975s, 2.975s) 0.026ms
-  assert(strstr(output, "[gc ") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC ") != NULL, "Incorrect log line");
-  assert(strstr(output, "M) (") != NULL, "Incorrect log line");
-  assert(strstr(output, "s, ") != NULL, "Incorrect log line");
-  assert(strstr(output, "s) ") != NULL, "Incorrect log line");
-  assert(strstr(output, "ms") != NULL, "Incorrect log line");
-
-  fclose(fp);
-}
-
-static void Test_log_gctracetime_no_heap_no_cause() {
-  TestLogFile log_file("log_gctracetime");
-  TestLogSavedConfig tlsc(log_file.name(), "gc=debug,gc+start=debug");
-
-  LogTarget(Debug, gc) gc_debug;
-  LogTarget(Debug, gc, start) gc_start_debug;
-
-  assert(gc_debug.is_enabled(), "assert");
-  assert(gc_start_debug.is_enabled(), "assert");
-
-  {
-    MutexLocker lock(Heap_lock); // Needed to read heap usage
-    GCTraceTime(Debug, gc) timer("Test GC", NULL, GCCause::_no_gc, false);
-  }
-
-  FILE* fp = fopen(log_file.name(), "r");
-  assert(fp, "File read error");
-
-  char output[256 /* Large enough buffer */];
-
-  char* res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc,start] Test GC (2.975s)
-  assert(strstr(output, "[gc,start") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (") != NULL, "Incorrect log line");
-  assert(strstr(output, "s)") != NULL, "Incorrect log line");
-
-  res = fgets(output, sizeof(output), fp);
-  assert(res != NULL, "assert");
-
-  // [2.975s][debug][gc      ] Test GC (2.975s, 2.975s) 0.026ms
-  assert(strstr(output, "[gc ") != NULL, "Incorrect tag set");
-  assert(strstr(output, "] Test GC (") != NULL, "Incorrect log line");
-  assert(strstr(output, "M) (") == NULL, "Incorrect log line");
-  assert(strstr(output, "s, ") != NULL, "Incorrect log line");
-  assert(strstr(output, "s) ") != NULL, "Incorrect log line");
-  assert(strstr(output, "ms") != NULL, "Incorrect log line");
-
-  fclose(fp);
-}
-
-void Test_log_gctracetime() {
-  Test_log_gctracetime_full();
-  Test_log_gctracetime_full_multitag();
-  Test_log_gctracetime_no_heap();
-  Test_log_gctracetime_no_cause();
-  Test_log_gctracetime_no_heap_no_cause();
-}
-
-void Test_invalid_log_file() {
-  ResourceMark rm;
-  stringStream ss;
-  const char* target_name = "tmplogdir";
-
-  // Attempt to log to a directory (existing log not a regular file)
-  create_directory(target_name);
-  LogFileOutput bad_file("file=tmplogdir");
-  assert(bad_file.initialize("", &ss) == false, "file was initialized "
-         "when there was an existing directory with the same name");
-  assert(strstr(ss.as_string(), "tmplogdir is not a regular file") != NULL,
-         "missing expected error message, received msg: %s", ss.as_string());
-  ss.reset();
-  remove(target_name);
-}
-
-// Ensure -Xlog:help and LogConfiguration::describe contain tagset descriptions
-void Test_logtagset_descriptions() {
-  for (LogTagSetDescription* d = tagset_descriptions; d->tagset != NULL; d++) {
-    char expected[1024];
-    d->tagset->label(expected, sizeof(expected), "+");
-    jio_snprintf(expected + strlen(expected),
-                 sizeof(expected) - strlen(expected),
-                 ": %s", d->descr);
-
-    ResourceMark rm;
-    stringStream ss;
-    LogConfiguration::describe(&ss);
-    assert(strstr(ss.as_string(), expected) != NULL,
-           "missing log tag set descriptions in LogConfiguration::describe");
-
-    TestLogFile file("log_tagset_descriptions");
-    FILE* fp = fopen(file.name(), "w+");
-    assert(fp != NULL, "File open error");
-    LogConfiguration::print_command_line_help(fp);
-    fclose(fp);
-    assert(number_of_lines_with_substring_in_file(file.name(), expected) > 0,
-           "missing log tag set descriptions in -Xlog:help output");
-  }
-}
-#endif // PRODUCT
--- a/src/share/vm/logging/logFileOutput.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/logging/logFileOutput.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -97,11 +97,7 @@
   if (ret != 0) {
     return false;
   }
-#ifdef _WINDOWS
-  return (st.st_mode & S_IFMT) == _S_IFREG;
-#else
-  return S_ISREG(st.st_mode);
-#endif
+  return (st.st_mode & S_IFMT) == S_IFREG;
 }
 
 // Try to find the next number that should be used for file rotation.
--- a/src/share/vm/logging/logTag.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/logging/logTag.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -40,6 +40,7 @@
   LOG_TAG(attach) \
   LOG_TAG(barrier) \
   LOG_TAG(biasedlocking) \
+  LOG_TAG(blocks) \
   LOG_TAG(bot) \
   LOG_TAG(breakpoint) \
   LOG_TAG(census) \
@@ -105,6 +106,7 @@
   LOG_TAG(scavenge) \
   LOG_TAG(scrub) \
   LOG_TAG(stacktrace) \
+  LOG_TAG(stackwalk) \
   LOG_TAG(start) \
   LOG_TAG(startuptime) \
   LOG_TAG(state) \
--- a/src/share/vm/memory/filemap.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/memory/filemap.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -263,7 +263,7 @@
         } else {
           struct stat st;
           if (os::stat(name, &st) == 0) {
-            if ((st.st_mode & S_IFDIR) == S_IFDIR) {
+            if ((st.st_mode & S_IFMT) == S_IFDIR) {
               if (!os::dir_is_empty(name)) {
                 ClassLoader::exit_with_path_failure(
                   "Cannot have non-empty directory in archived classpaths", name);
--- a/src/share/vm/memory/filemap.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/memory/filemap.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -283,11 +283,15 @@
   bool validate_classpath_entry_table();
 
   static SharedClassPathEntry* shared_classpath(int index) {
+    if (index < 0) {
+      return NULL;
+    }
     char* p = (char*)_classpath_entry_table;
     p += _classpath_entry_size * index;
     return (SharedClassPathEntry*)p;
   }
   static const char* shared_classpath_name(int index) {
+    assert(index >= 0, "Sanity");
     return shared_classpath(index)->_name;
   }
 
--- a/src/share/vm/memory/metaspace.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/memory/metaspace.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -249,10 +249,65 @@
   void print_on(outputStream* st) const;
 };
 
+class SmallBlocks : public CHeapObj<mtClass> {
+  const static uint _small_block_max_size = sizeof(TreeChunk<Metablock,  FreeList<Metablock> >)/HeapWordSize;
+  const static uint _small_block_min_size = sizeof(Metablock)/HeapWordSize;
+
+ private:
+  FreeList<Metablock> _small_lists[_small_block_max_size - _small_block_min_size];
+
+  FreeList<Metablock>& list_at(size_t word_size) {
+    assert(word_size >= _small_block_min_size, "There are no metaspace objects less than %u words", _small_block_min_size);
+    return _small_lists[word_size - _small_block_min_size];
+  }
+
+ public:
+  SmallBlocks() {
+    for (uint i = _small_block_min_size; i < _small_block_max_size; i++) {
+      uint k = i - _small_block_min_size;
+      _small_lists[k].set_size(i);
+    }
+  }
+
+  size_t total_size() const {
+    size_t result = 0;
+    for (uint i = _small_block_min_size; i < _small_block_max_size; i++) {
+      uint k = i - _small_block_min_size;
+      result = result + _small_lists[k].count() * _small_lists[k].size();
+    }
+    return result;
+  }
+
+  static uint small_block_max_size() { return _small_block_max_size; }
+  static uint small_block_min_size() { return _small_block_min_size; }
+
+  MetaWord* get_block(size_t word_size) {
+    if (list_at(word_size).count() > 0) {
+      MetaWord* new_block = (MetaWord*) list_at(word_size).get_chunk_at_head();
+      return new_block;
+    } else {
+      return NULL;
+    }
+  }
+  void return_block(Metablock* free_chunk, size_t word_size) {
+    list_at(word_size).return_chunk_at_head(free_chunk, false);
+    assert(list_at(word_size).count() > 0, "Should have a chunk");
+  }
+
+  void print_on(outputStream* st) const {
+    st->print_cr("SmallBlocks:");
+    for (uint i = _small_block_min_size; i < _small_block_max_size; i++) {
+      uint k = i - _small_block_min_size;
+      st->print_cr("small_lists size " SIZE_FORMAT " count " SIZE_FORMAT, _small_lists[k].size(), _small_lists[k].count());
+    }
+  }
+};
+
 // Used to manage the free list of Metablocks (a block corresponds
 // to the allocation of a quantum of metadata).
-class BlockFreelist VALUE_OBJ_CLASS_SPEC {
+class BlockFreelist : public CHeapObj<mtClass> {
   BlockTreeDictionary* const _dictionary;
+  SmallBlocks* _small_blocks;
 
   // Only allocate and split from freelist if the size of the allocation
   // is at least 1/4th the size of the available block.
@@ -260,6 +315,12 @@
 
   // Accessors
   BlockTreeDictionary* dictionary() const { return _dictionary; }
+  SmallBlocks* small_blocks() {
+    if (_small_blocks == NULL) {
+      _small_blocks = new SmallBlocks();
+    }
+    return _small_blocks;
+  }
 
  public:
   BlockFreelist();
@@ -269,8 +330,15 @@
   MetaWord* get_block(size_t word_size);
   void return_block(MetaWord* p, size_t word_size);
 
-  size_t total_size() { return dictionary()->total_size(); }
-
+  size_t total_size() const  {
+    size_t result = dictionary()->total_size();
+    if (_small_blocks != NULL) {
+      result = result + _small_blocks->total_size();
+    }
+    return result;
+  }
+
+  static size_t min_dictionary_size()   { return TreeChunk<Metablock, FreeList<Metablock> >::min_size(); }
   void print_on(outputStream* st) const;
 };
 
@@ -629,7 +697,7 @@
   // are assumed to be in chunks in use by the SpaceManager
   // and all chunks in use by a SpaceManager are freed when
   // the class loader using the SpaceManager is collected.
-  BlockFreelist _block_freelists;
+  BlockFreelist* _block_freelists;
 
   // protects virtualspace and chunk expansions
   static const char*  _expand_lock_name;
@@ -643,9 +711,7 @@
     _chunks_in_use[index] = v;
   }
 
-  BlockFreelist* block_freelists() const {
-    return (BlockFreelist*) &_block_freelists;
-  }
+  BlockFreelist* block_freelists() const { return _block_freelists; }
 
   Metaspace::MetadataType mdtype() { return _mdtype; }
 
@@ -763,7 +829,9 @@
   void verify_allocated_blocks_words();
 #endif
 
-  size_t get_raw_word_size(size_t word_size) {
+  // This adjusts the size given to be greater than the minimum allocation size in
+  // words for data in metaspace.  Esentially the minimum size is currently 3 words.
+  size_t get_allocation_word_size(size_t word_size) {
     size_t byte_size = word_size * BytesPerWord;
 
     size_t raw_bytes_size = MAX2(byte_size, sizeof(Metablock));
@@ -807,20 +875,45 @@
 
 // BlockFreelist methods
 
-BlockFreelist::BlockFreelist() : _dictionary(new BlockTreeDictionary()) {}
+BlockFreelist::BlockFreelist() : _dictionary(new BlockTreeDictionary()), _small_blocks(NULL) {}
 
 BlockFreelist::~BlockFreelist() {
   delete _dictionary;
+  if (_small_blocks != NULL) {
+    delete _small_blocks;
+  }
 }
 
 void BlockFreelist::return_block(MetaWord* p, size_t word_size) {
+  assert(word_size >= SmallBlocks::small_block_min_size(), "never return dark matter");
+
   Metablock* free_chunk = ::new (p) Metablock(word_size);
+  if (word_size < SmallBlocks::small_block_max_size()) {
+    small_blocks()->return_block(free_chunk, word_size);
+  } else {
   dictionary()->return_chunk(free_chunk);
 }
+  log_trace(gc, metaspace, freelist, blocks)("returning block at " INTPTR_FORMAT " size = "
+            SIZE_FORMAT, p2i(free_chunk), word_size);
+}
 
 MetaWord* BlockFreelist::get_block(size_t word_size) {
-  if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
-    // Dark matter.  Too small for dictionary.
+  assert(word_size >= SmallBlocks::small_block_min_size(), "never get dark matter");
+
+  // Try small_blocks first.
+  if (word_size < SmallBlocks::small_block_max_size()) {
+    // Don't create small_blocks() until needed.  small_blocks() allocates the small block list for
+    // this space manager.
+    MetaWord* new_block = (MetaWord*) small_blocks()->get_block(word_size);
+    if (new_block != NULL) {
+      log_trace(gc, metaspace, freelist, blocks)("getting block at " INTPTR_FORMAT " size = " SIZE_FORMAT,
+              p2i(new_block), word_size);
+      return new_block;
+    }
+  }
+
+  if (word_size < BlockFreelist::min_dictionary_size()) {
+    // If allocation in small blocks fails, this is Dark Matter.  Too small for dictionary.
     return NULL;
   }
 
@@ -839,15 +932,20 @@
   MetaWord* new_block = (MetaWord*)free_block;
   assert(block_size >= word_size, "Incorrect size of block from freelist");
   const size_t unused = block_size - word_size;
-  if (unused >= TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
+  if (unused >= SmallBlocks::small_block_min_size()) {
     return_block(new_block + word_size, unused);
   }
 
+  log_trace(gc, metaspace, freelist, blocks)("getting block at " INTPTR_FORMAT " size = " SIZE_FORMAT,
+            p2i(new_block), word_size);
   return new_block;
 }
 
 void BlockFreelist::print_on(outputStream* st) const {
   dictionary()->print_free_lists(st);
+  if (_small_blocks != NULL) {
+    _small_blocks->print_on(st);
+  }
 }
 
 // VirtualSpaceNode methods
@@ -2075,6 +2173,7 @@
   _allocated_blocks_words(0),
   _allocated_chunks_words(0),
   _allocated_chunks_count(0),
+  _block_freelists(NULL),
   _lock(lock)
 {
   initialize();
@@ -2164,8 +2263,10 @@
     log.trace("~SpaceManager(): " PTR_FORMAT, p2i(this));
     ResourceMark rm;
     locked_print_chunks_in_use_on(log.trace_stream());
+    if (block_freelists() != NULL) {
     block_freelists()->print_on(log.trace_stream());
   }
+  }
 
   // Have to update before the chunks_in_use lists are emptied
   // below.
@@ -2215,6 +2316,10 @@
   }
   log.trace("updated dictionary count " SIZE_FORMAT " %s", chunk_manager()->humongous_dictionary()->total_count(), chunk_size_name(HumongousIndex));
   chunk_manager()->slow_locked_verify();
+
+  if (_block_freelists != NULL) {
+    delete _block_freelists;
+  }
 }
 
 const char* SpaceManager::chunk_size_name(ChunkIndex index) const {
@@ -2253,10 +2358,12 @@
 
 void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
   assert_lock_strong(_lock);
-  size_t raw_word_size = get_raw_word_size(word_size);
-  size_t min_size = TreeChunk<Metablock, FreeList<Metablock> >::min_size();
-  assert(raw_word_size >= min_size,
-         "Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size);
+  // Allocations and deallocations are in raw_word_size
+  size_t raw_word_size = get_allocation_word_size(word_size);
+  // Lazily create a block_freelist
+  if (block_freelists() == NULL) {
+    _block_freelists = new BlockFreelist();
+  }
   block_freelists()->return_block(p, raw_word_size);
 }
 
@@ -2312,8 +2419,9 @@
 void SpaceManager::retire_current_chunk() {
   if (current_chunk() != NULL) {
     size_t remaining_words = current_chunk()->free_word_size();
-    if (remaining_words >= TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
-      block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words);
+    if (remaining_words >= BlockFreelist::min_dictionary_size()) {
+      MetaWord* ptr = current_chunk()->allocate(remaining_words);
+      deallocate(ptr, remaining_words);
       inc_used_metrics(remaining_words);
     }
   }
@@ -2350,7 +2458,7 @@
  * will be made to allocate a small chunk.
  */
 MetaWord* SpaceManager::get_small_chunk_and_allocate(size_t word_size) {
-  size_t raw_word_size = get_raw_word_size(word_size);
+  size_t raw_word_size = get_allocation_word_size(word_size);
 
   if (raw_word_size + Metachunk::overhead() > small_chunk_size()) {
     return NULL;
@@ -2380,8 +2488,7 @@
 
 MetaWord* SpaceManager::allocate(size_t word_size) {
   MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
-
-  size_t raw_word_size = get_raw_word_size(word_size);
+  size_t raw_word_size = get_allocation_word_size(word_size);
   BlockFreelist* fl =  block_freelists();
   MetaWord* p = NULL;
   // Allocation from the dictionary is expensive in the sense that
@@ -2389,7 +2496,7 @@
   // from the dictionary until it starts to get fat.  Is this
   // a reasonable policy?  Maybe an skinny dictionary is fast enough
   // for allocations.  Do some profiling.  JJJ
-  if (fl->total_size() > allocation_from_dictionary_limit) {
+  if (fl != NULL && fl->total_size() > allocation_from_dictionary_limit) {
     p = fl->get_block(raw_word_size);
   }
   if (p == NULL) {
@@ -2441,7 +2548,7 @@
   // If there are blocks in the dictionary, then
   // verification of chunks does not work since
   // being in the dictionary alters a chunk.
-  if (block_freelists()->total_size() == 0) {
+  if (block_freelists() != NULL && block_freelists()->total_size() == 0) {
     for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) {
       Metachunk* curr = chunks_in_use(i);
       while (curr != NULL) {
@@ -2499,7 +2606,7 @@
   }
 
   if (log_is_enabled(Trace, gc, metaspace, freelist)) {
-    block_freelists()->print_on(out);
+    if (block_freelists() != NULL) block_freelists()->print_on(out);
   }
 
   size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size();
@@ -3410,18 +3517,11 @@
          || Thread::current()->is_VM_thread(), "should be the VM thread");
 
   if (DumpSharedSpaces && PrintSharedSpaces) {
-    record_deallocation(ptr, vsm()->get_raw_word_size(word_size));
+    record_deallocation(ptr, vsm()->get_allocation_word_size(word_size));
   }
 
   MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag);
 
-  if (word_size < TreeChunk<Metablock, FreeList<Metablock> >::min_size()) {
-    // Dark matter.  Too small for dictionary.
-#ifdef ASSERT
-    Copy::fill_to_words((HeapWord*)ptr, word_size, 0xf5f5f5f5);
-#endif
-    return;
-  }
   if (is_class && using_class_space()) {
     class_vsm()->deallocate(ptr, word_size);
   } else {
@@ -3451,7 +3551,7 @@
       report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
     }
     if (PrintSharedSpaces) {
-      space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
+      space->record_allocation(result, type, space->vsm()->get_allocation_word_size(word_size));
     }
 
     // Zero initialize.
@@ -3509,10 +3609,11 @@
 
   // If result is still null, we are out of memory.
   Log(gc, metaspace, freelist) log;
-  if (log.is_trace()) {
-    log.trace("Metaspace allocation failed for size " SIZE_FORMAT, word_size);
+  if (log.is_info()) {
+    log.info("Metaspace (%s) allocation failed for size " SIZE_FORMAT,
+             is_class_space_allocation(mdtype) ? "class" : "data", word_size);
     ResourceMark rm;
-    outputStream* out = log.trace_stream();
+    outputStream* out = log.info_stream();
     if (loader_data->metaspace_or_null() != NULL) {
       loader_data->dump(out);
     }
--- a/src/share/vm/oops/constMethod.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/oops/constMethod.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -368,23 +368,36 @@
   return (AnnotationArray**)constMethod_end() - offset;
 }
 
+Array<u1>* copy_annotations(ClassLoaderData* loader_data, AnnotationArray* from, TRAPS) {
+  int length = from->length();
+  Array<u1>* a = MetadataFactory::new_array<u1>(loader_data, length, 0, CHECK_NULL);
+  memcpy((void*)a->adr_at(0), (void*)from->adr_at(0), length);
+  return a;
+}
+
 // copy annotations from 'cm' to 'this'
-void ConstMethod::copy_annotations_from(ConstMethod* cm) {
+// Must make copy because these are deallocated with their constMethod, if redefined.
+void ConstMethod::copy_annotations_from(ClassLoaderData* loader_data, ConstMethod* cm, TRAPS) {
+  Array<u1>* a;
   if (cm->has_method_annotations()) {
     assert(has_method_annotations(), "should be allocated already");
-    set_method_annotations(cm->method_annotations());
+    a = copy_annotations(loader_data, cm->method_annotations(), CHECK);
+    set_method_annotations(a);
   }
   if (cm->has_parameter_annotations()) {
     assert(has_parameter_annotations(), "should be allocated already");
-    set_parameter_annotations(cm->parameter_annotations());
+    a = copy_annotations(loader_data, cm->parameter_annotations(), CHECK);
+    set_parameter_annotations(a);
   }
   if (cm->has_type_annotations()) {
     assert(has_type_annotations(), "should be allocated already");
-    set_type_annotations(cm->type_annotations());
+    a = copy_annotations(loader_data, cm->type_annotations(), CHECK);
+    set_type_annotations(a);
   }
   if (cm->has_default_annotations()) {
     assert(has_default_annotations(), "should be allocated already");
-    set_default_annotations(cm->default_annotations());
+    a = copy_annotations(loader_data, cm->default_annotations(), CHECK);
+    set_default_annotations(a);
   }
 }
 
--- a/src/share/vm/oops/constMethod.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/oops/constMethod.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -469,7 +469,7 @@
   }
 
   // Copy annotations from other ConstMethod
-  void copy_annotations_from(ConstMethod* cm);
+  void copy_annotations_from(ClassLoaderData* loader_data, ConstMethod* cm, TRAPS);
 
   // byte codes
   void    set_code(address code) {
--- a/src/share/vm/oops/instanceKlass.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/oops/instanceKlass.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -674,20 +674,20 @@
 
 // Eagerly initialize superinterfaces that declare default methods (concrete instance: any access)
 void InstanceKlass::initialize_super_interfaces(instanceKlassHandle this_k, TRAPS) {
-  assert (this_k->has_default_methods(), "caller should have checked this");
+  assert (this_k->has_nonstatic_concrete_methods(), "caller should have checked this");
   for (int i = 0; i < this_k->local_interfaces()->length(); ++i) {
     Klass* iface = this_k->local_interfaces()->at(i);
     InstanceKlass* ik = InstanceKlass::cast(iface);
 
     // Initialization is depth first search ie. we start with top of the inheritance tree
-    // has_default_methods drives searching superinterfaces since it
-    // means has_default_methods in its superinterface hierarchy
-    if (ik->has_default_methods()) {
+    // has_nonstatic_concrete_methods drives searching superinterfaces since it
+    // means has_nonstatic_concrete_methods in its superinterface hierarchy
+    if (ik->has_nonstatic_concrete_methods()) {
       ik->initialize_super_interfaces(ik, CHECK);
     }
 
     // Only initialize() interfaces that "declare" concrete methods.
-    if (ik->should_be_initialized() && ik->declares_default_methods()) {
+    if (ik->should_be_initialized() && ik->declares_nonstatic_concrete_methods()) {
       ik->initialize(CHECK);
     }
   }
@@ -761,11 +761,11 @@
     if (super_klass != NULL && super_klass->should_be_initialized()) {
       super_klass->initialize(THREAD);
     }
-    // If C implements any interfaces that declares a non-abstract, non-static method,
+    // If C implements any interface that declares a non-static, concrete method,
     // the initialization of C triggers initialization of its super interfaces.
-    // Only need to recurse if has_default_methods which includes declaring and
-    // inheriting default methods
-    if (!HAS_PENDING_EXCEPTION && this_k->has_default_methods()) {
+    // Only need to recurse if has_nonstatic_concrete_methods which includes declaring and
+    // having a superinterface that declares, non-static, concrete methods
+    if (!HAS_PENDING_EXCEPTION && this_k->has_nonstatic_concrete_methods()) {
       this_k->initialize_super_interfaces(this_k, THREAD);
     }
 
--- a/src/share/vm/oops/instanceKlass.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/oops/instanceKlass.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -207,18 +207,18 @@
 
   // Start after _misc_kind field.
   enum {
-    _misc_rewritten                = 1 << 2,  // methods rewritten.
-    _misc_has_nonstatic_fields     = 1 << 3,  // for sizing with UseCompressedOops
-    _misc_should_verify_class      = 1 << 4,  // allow caching of preverification
-    _misc_is_anonymous             = 1 << 5,  // has embedded _host_klass field
-    _misc_is_contended             = 1 << 6,  // marked with contended annotation
-    _misc_has_default_methods      = 1 << 7,  // class/superclass/implemented interfaces has default methods
-    _misc_declares_default_methods = 1 << 8,  // directly declares default methods (any access)
-    _misc_has_been_redefined       = 1 << 9,  // class has been redefined
-    _misc_is_scratch_class         = 1 << 10, // class is the redefined scratch class
-    _misc_is_shared_boot_class     = 1 << 11, // defining class loader is boot class loader
-    _misc_is_shared_platform_class = 1 << 12, // defining class loader is platform class loader
-    _misc_is_shared_app_class      = 1 << 13  // defining class loader is app class loader
+    _misc_rewritten                           = 1 << 2,  // methods rewritten.
+    _misc_has_nonstatic_fields                = 1 << 3,  // for sizing with UseCompressedOops
+    _misc_should_verify_class                 = 1 << 4,  // allow caching of preverification
+    _misc_is_anonymous                        = 1 << 5,  // has embedded _host_klass field
+    _misc_is_contended                        = 1 << 6,  // marked with contended annotation
+    _misc_has_nonstatic_concrete_methods      = 1 << 7,  // class/superclass/implemented interfaces has non-static, concrete methods
+    _misc_declares_nonstatic_concrete_methods = 1 << 8,  // directly declares non-static, concrete methods
+    _misc_has_been_redefined                  = 1 << 9,  // class has been redefined
+    _misc_is_scratch_class                    = 1 << 10, // class is the redefined scratch class
+    _misc_is_shared_boot_class                = 1 << 11, // defining class loader is boot class loader
+    _misc_is_shared_platform_class            = 1 << 12, // defining class loader is platform class loader
+    _misc_is_shared_app_class                 = 1 << 13  // defining class loader is app class loader
   };
   u2 loader_type_bits() {
     return _misc_is_shared_boot_class|_misc_is_shared_platform_class|_misc_is_shared_app_class;
@@ -814,25 +814,25 @@
 
 #endif // INCLUDE_JVMTI
 
-  bool has_default_methods() const {
-    return (_misc_flags & _misc_has_default_methods) != 0;
+  bool has_nonstatic_concrete_methods() const {
+    return (_misc_flags & _misc_has_nonstatic_concrete_methods) != 0;
   }
-  void set_has_default_methods(bool b) {
+  void set_has_nonstatic_concrete_methods(bool b) {
     if (b) {
-      _misc_flags |= _misc_has_default_methods;
+      _misc_flags |= _misc_has_nonstatic_concrete_methods;
     } else {
-      _misc_flags &= ~_misc_has_default_methods;
+      _misc_flags &= ~_misc_has_nonstatic_concrete_methods;
     }
   }
 
-  bool declares_default_methods() const {
-    return (_misc_flags & _misc_declares_default_methods) != 0;
+  bool declares_nonstatic_concrete_methods() const {
+    return (_misc_flags & _misc_declares_nonstatic_concrete_methods) != 0;
   }
-  void set_declares_default_methods(bool b) {
+  void set_declares_nonstatic_concrete_methods(bool b) {
     if (b) {
-      _misc_flags |= _misc_declares_default_methods;
+      _misc_flags |= _misc_declares_nonstatic_concrete_methods;
     } else {
-      _misc_flags &= ~_misc_declares_default_methods;
+      _misc_flags &= ~_misc_declares_nonstatic_concrete_methods;
     }
   }
 
--- a/src/share/vm/oops/klassVtable.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/oops/klassVtable.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -226,7 +226,7 @@
           HandleMark hm(THREAD);
           assert(default_methods->at(i)->is_method(), "must be a Method*");
           methodHandle mh(THREAD, default_methods->at(i));
-
+          assert(!mh->is_private(), "private interface method in the default method list");
           bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, i, checkconstraints, CHECK);
 
           // needs new entry
@@ -362,14 +362,16 @@
 
   Array<int>* def_vtable_indices = NULL;
   bool is_default = false;
-  // default methods are concrete methods in superinterfaces which are added to the vtable
-  // with their real method_holder
+
+  // default methods are non-private concrete methods in superinterfaces which are added
+  // to the vtable with their real method_holder.
   // Since vtable and itable indices share the same storage, don't touch
-  // the default method's real vtable/itable index
+  // the default method's real vtable/itable index.
   // default_vtable_indices stores the vtable value relative to this inheritor
   if (default_index >= 0 ) {
     is_default = true;
     def_vtable_indices = klass->default_vtable_indices();
+    assert(!target_method()->is_private(), "private interface method flagged as default");
     assert(def_vtable_indices != NULL, "def vtable alloc?");
     assert(default_index <= def_vtable_indices->length(), "def vtable len?");
   } else {
@@ -395,12 +397,15 @@
     // This method will either be assigned its own itable index later,
     // or be assigned an inherited vtable index in the loop below.
     // default methods inherited by classes store their vtable indices
-    // in the inheritor's default_vtable_indices
+    // in the inheritor's default_vtable_indices.
     // default methods inherited by interfaces may already have a
-    // valid itable index, if so, don't change it
-    // overpass methods in an interface will be assigned an itable index later
-    // by an inheriting class
-    if (!is_default || !target_method()->has_itable_index()) {
+    // valid itable index, if so, don't change it.
+    // Overpass methods in an interface will be assigned an itable index later
+    // by an inheriting class.
+    // Private interface methods have no itable index and are always invoked nonvirtually,
+    // so they retain their nonvirtual_vtable_index value, and therefore can_be_statically_bound()
+    // will return true.
+    if ((!is_default || !target_method()->has_itable_index()) && !target_method()->is_private()) {
       target_method()->set_vtable_index(Method::pending_itable_index);
     }
   }
@@ -597,7 +602,9 @@
   // abstract method entries using default inheritance rules
   if (target_method()->method_holder() != NULL &&
       target_method()->method_holder()->is_interface()  &&
-      !target_method()->is_abstract() ) {
+      !target_method()->is_abstract()) {
+    assert(target_method()->is_default_method() || target_method()->is_private(),
+           "unexpected interface method type");
     return false;
   }
 
@@ -606,10 +613,8 @@
     return true;
   }
 
-  // private methods in classes always have a new entry in the vtable
-  // specification interpretation since classic has
-  // private methods not overriding
-  // JDK8 adds private  methods in interfaces which require invokespecial
+  // private methods in classes always have a new entry in the vtable.
+  // Specification interpretation since classic has private methods not overriding.
   if (target_method()->is_private()) {
     return true;
   }
@@ -1088,6 +1093,7 @@
 inline bool interface_method_needs_itable_index(Method* m) {
   if (m->is_static())           return false;   // e.g., Stream.empty
   if (m->is_initializer())      return false;   // <init> or <clinit>
+  if (m->is_private())          return false;   // requires invokeSpecial
   // If an interface redeclares a method from java.lang.Object,
   // it should already have a vtable index, don't touch it.
   // e.g., CharSequence.toString (from initialize_vtable)
--- a/src/share/vm/oops/method.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/oops/method.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -97,7 +97,7 @@
   // Fix and bury in Method*
   set_interpreter_entry(NULL); // sets i2i entry and from_int
   set_adapter_entry(NULL);
-  clear_code(); // from_c/from_i get set to c2i/i2i
+  clear_code(false /* don't need a lock */); // from_c/from_i get set to c2i/i2i
 
   if (access_flags.is_native()) {
     clear_native_function();
@@ -277,7 +277,8 @@
 }
 
 address Method::bcp_from(int bci) const {
-  assert((is_native() && bci == 0) || (!is_native() && 0 <= bci && bci < code_size()), "illegal bci: %d", bci);
+  assert((is_native() && bci == 0) || (!is_native() && 0 <= bci && bci < code_size()),
+         "illegal bci: %d for %s method", bci, is_native() ? "native" : "non-native");
   address bcp = code_base() + bci;
   assert(is_native() && bcp == code_base() || contains(bcp), "bcp doesn't belong to this method");
   return bcp;
@@ -558,7 +559,7 @@
 bool Method::is_final_method(AccessFlags class_access_flags) const {
   // or "does_not_require_vtable_entry"
   // default method or overpass can occur, is not final (reuses vtable entry)
-  // private methods get vtable entries for backward class compatibility.
+  // private methods in classes get vtable entries for backward class compatibility.
   if (is_overpass() || is_default_method())  return false;
   return is_final() || class_access_flags.is_final();
 }
@@ -570,7 +571,7 @@
 bool Method::is_default_method() const {
   if (method_holder() != NULL &&
       method_holder()->is_interface() &&
-      !is_abstract()) {
+      !is_abstract() && !is_private()) {
     return true;
   } else {
     return false;
@@ -583,7 +584,9 @@
   ResourceMark rm;
   bool is_nonv = (vtable_index() == nonvirtual_vtable_index);
   if (class_access_flags.is_interface()) {
-    assert(is_nonv == is_static(), "is_nonv=%s", name_and_sig_as_C_string());
+      assert(is_nonv == is_static() || is_nonv == is_private(),
+             "nonvirtual unexpected for non-static, non-private: %s",
+             name_and_sig_as_C_string());
   }
 #endif
   assert(valid_vtable_index() || valid_itable_index(), "method must be linked before we ask this question");
@@ -904,8 +907,8 @@
 }
 
 // Revert to using the interpreter and clear out the nmethod
-void Method::clear_code() {
-
+void Method::clear_code(bool acquire_lock /* = true */) {
+  MutexLockerEx pl(acquire_lock ? Patching_lock : NULL, Mutex::_no_safepoint_check_flag);
   // this may be NULL if c2i adapters have not been made yet
   // Only should happen at allocate time.
   if (adapter() == NULL) {
@@ -1074,6 +1077,7 @@
 
 // Install compiled code.  Instantly it can execute.
 void Method::set_code(methodHandle mh, CompiledMethod *code) {
+  MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
   assert( code, "use clear_code to remove code" );
   assert( mh->check_code(), "" );
 
@@ -1376,7 +1380,7 @@
   }
 
   // copy annotations over to new method
-  newcm->copy_annotations_from(cm);
+  newcm->copy_annotations_from(loader_data, cm, CHECK_NULL);
   return newm;
 }
 
--- a/src/share/vm/oops/method.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/oops/method.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -436,7 +436,7 @@
   address verified_code_entry();
   bool check_code() const;      // Not inline to avoid circular ref
   CompiledMethod* volatile code() const                 { assert( check_code(), "" ); return (CompiledMethod *)OrderAccess::load_ptr_acquire(&_code); }
-  void clear_code();            // Clear out any compiled code
+  void clear_code(bool acquire_lock = true);    // Clear out any compiled code
   static void set_code(methodHandle mh, CompiledMethod* code);
   void set_adapter_entry(AdapterHandlerEntry* adapter) {
     constMethod()->set_adapter_entry(adapter);
@@ -584,6 +584,7 @@
   // checks method and its method holder
   bool is_final_method() const;
   bool is_final_method(AccessFlags class_access_flags) const;
+  // interface method declared with 'default' - excludes private interface methods
   bool is_default_method() const;
 
   // true if method needs no dynamic dispatch (final and/or no vtable entry)
--- a/src/share/vm/oops/methodData.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/oops/methodData.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1190,12 +1190,11 @@
 #if INCLUDE_JVMCI
     // Description of the different counters
     // ReceiverTypeData for instanceof/checkcast/aastore:
-    //   C1/C2: count is incremented on type overflow and decremented for failed type checks
-    //   JVMCI: count decremented for failed type checks and nonprofiled_count is incremented on type overflow
-    //          TODO (chaeubl): in fact, JVMCI should also increment the count for failed type checks to mimic the C1/C2 behavior
+    //   count is decremented for failed type checks
+    //   JVMCI only: nonprofiled_count is incremented on type overflow
     // VirtualCallData for invokevirtual/invokeinterface:
-    //   C1/C2: count is incremented on type overflow
-    //   JVMCI: count is incremented on type overflow, nonprofiled_count is incremented on method overflow
+    //   count is incremented on type overflow
+    //   JVMCI only: nonprofiled_count is incremented on method overflow
 
     // JVMCI is interested in knowing the percentage of type checks involving a type not explicitly in the profile
     nonprofiled_count_off_set = counter_cell_count,
--- a/src/share/vm/opto/compile.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/opto/compile.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -574,6 +574,10 @@
   buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize);
   buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize);
   buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize);
+  // Mark as scratch buffer.
+  buf.consts()->set_scratch_emit();
+  buf.insts()->set_scratch_emit();
+  buf.stubs()->set_scratch_emit();
 
   // Do the emission.
 
@@ -2867,15 +2871,20 @@
         addp->Opcode() == Op_ConP &&
         addp == n->in(AddPNode::Base) &&
         n->in(AddPNode::Offset)->is_Con()) {
+      // If the transformation of ConP to ConN+DecodeN is beneficial depends
+      // on the platform and on the compressed oops mode.
       // Use addressing with narrow klass to load with offset on x86.
-      // On sparc loading 32-bits constant and decoding it have less
-      // instructions (4) then load 64-bits constant (7).
+      // Some platforms can use the constant pool to load ConP.
       // Do this transformation here since IGVN will convert ConN back to ConP.
       const Type* t = addp->bottom_type();
-      if (t->isa_oopptr() || t->isa_klassptr()) {
+      bool is_oop   = t->isa_oopptr() != NULL;
+      bool is_klass = t->isa_klassptr() != NULL;
+
+      if ((is_oop   && Matcher::const_oop_prefer_decode()  ) ||
+          (is_klass && Matcher::const_klass_prefer_decode())) {
         Node* nn = NULL;
 
-        int op = t->isa_oopptr() ? Op_ConN : Op_ConNKlass;
+        int op = is_oop ? Op_ConN : Op_ConNKlass;
 
         // Look for existing ConN node of the same exact type.
         Node* r  = root();
@@ -2891,7 +2900,7 @@
         if (nn != NULL) {
           // Decode a narrow oop to match address
           // [R12 + narrow_oop_reg<<3 + offset]
-          if (t->isa_oopptr()) {
+          if (is_oop) {
             nn = new DecodeNNode(nn, t);
           } else {
             nn = new DecodeNKlassNode(nn, t);
--- a/src/share/vm/opto/loopnode.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/opto/loopnode.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1687,6 +1687,12 @@
     Node *init2 = phi2->in( LoopNode::EntryControl );
     int stride_con2 = incr2->in(2)->get_int();
 
+    // The ratio of the two strides cannot be represented as an int
+    // if stride_con2 is min_int and stride_con is -1.
+    if (stride_con2 == min_jint && stride_con == -1) {
+      continue;
+    }
+
     // The general case here gets a little tricky.  We want to find the
     // GCD of all possible parallel IV's and make a new IV using this
     // GCD for the loop.  Then all possible IVs are simple multiples of
--- a/src/share/vm/opto/macro.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/opto/macro.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -439,12 +439,6 @@
     Node* adr = _igvn.transform(new AddPNode(base, base, MakeConX(offset)));
     const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset);
     Node* m = ac->in(TypeFunc::Memory);
-    while (m->is_MergeMem()) {
-      m = m->as_MergeMem()->memory_at(C->get_alias_index(adr_type));
-      if (m->is_Proj() && m->in(0)->is_MemBar()) {
-        m = m->in(0)->in(TypeFunc::Memory);
-      }
-    }
     res = LoadNode::make(_igvn, ctl, m, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
   } else {
     if (ac->modifies(offset, offset, &_igvn, true)) {
@@ -978,6 +972,17 @@
   return true;
 }
 
+static void disconnect_projections(MultiNode* n, PhaseIterGVN& igvn) {
+  Node* ctl_proj = n->proj_out(TypeFunc::Control);
+  Node* mem_proj = n->proj_out(TypeFunc::Memory);
+  if (ctl_proj != NULL) {
+    igvn.replace_node(ctl_proj, n->in(0));
+  }
+  if (mem_proj != NULL) {
+    igvn.replace_node(mem_proj, n->in(TypeFunc::Memory));
+  }
+}
+
 // Process users of eliminated allocation.
 void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
   Node* res = alloc->result_cast();
@@ -1008,13 +1013,13 @@
             // Disconnect ArrayCopy node
             ArrayCopyNode* ac = n->as_ArrayCopy();
             assert(ac->is_clonebasic(), "unexpected array copy kind");
-            Node* ctl_proj = ac->proj_out(TypeFunc::Control);
-            Node* mem_proj = ac->proj_out(TypeFunc::Memory);
-            if (ctl_proj != NULL) {
-              _igvn.replace_node(ctl_proj, n->in(0));
-            }
-            if (mem_proj != NULL) {
-              _igvn.replace_node(mem_proj, n->in(TypeFunc::Memory));
+            Node* membar_after = ac->proj_out(TypeFunc::Control)->unique_ctrl_out();
+            disconnect_projections(ac, _igvn);
+            assert(alloc->in(0)->is_Proj() && alloc->in(0)->in(0)->Opcode() == Op_MemBarCPUOrder, "mem barrier expected before allocation");
+            Node* membar_before = alloc->in(0)->in(0);
+            disconnect_projections(membar_before->as_MemBar(), _igvn);
+            if (membar_after->is_MemBar()) {
+              disconnect_projections(membar_after->as_MemBar(), _igvn);
             }
           } else {
             eliminate_card_mark(n);
--- a/src/share/vm/opto/matcher.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/opto/matcher.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -457,6 +457,9 @@
   static bool narrow_oop_use_complex_address();
   static bool narrow_klass_use_complex_address();
 
+  static bool const_oop_prefer_decode();
+  static bool const_klass_prefer_decode();
+
   // Generate implicit null check for narrow oops if it can fold
   // into address expression (x64).
   //
--- a/src/share/vm/prims/jni.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/prims/jni.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1173,7 +1173,7 @@
   args->set_java_argument_object(&java_args);
 
   // handle arguments
-  assert(!method->is_static(), "method should not be static");
+  assert(!method->is_static(), "method %s should not be static", method->name_and_sig_as_C_string());
   args->push_receiver(h_recv); // Push jobject handle
 
   // Fill out JavaCallArguments object
--- a/src/share/vm/prims/stackwalk.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/prims/stackwalk.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -26,6 +26,7 @@
 #include "classfile/javaClasses.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "logging/log.hpp"
 #include "memory/oopFactory.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
@@ -105,10 +106,8 @@
                               int max_nframes, int start_index,
                               objArrayHandle  frames_array,
                               int& end_index, TRAPS) {
-  if (TraceStackWalk) {
-    tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
-                  max_nframes, start_index, frames_array->length());
-  }
+  log_debug(stackwalk)("fill_in_frames limit=%d start=%d frames length=%d",
+                       max_nframes, start_index, frames_array->length());
   assert(max_nframes > 0, "invalid max_nframes");
   assert(start_index + max_nframes <= frames_array->length(), "oob");
 
@@ -122,18 +121,24 @@
     // not set) and when StackWalker::getCallerClass is called
     if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) {
       if (method->is_hidden()) {
-        if (TraceStackWalk) {
-          tty->print("  hidden method: "); method->print_short_name();
-          tty->print("\n");
+        if (log_is_enabled(Debug, stackwalk)) {
+          ResourceMark rm(THREAD);
+          outputStream* st = Log(stackwalk)::debug_stream();
+          st->print("  hidden method: ");
+          method->print_short_name(st);
+          st->cr();
         }
         continue;
       }
     }
 
     int index = end_index++;
-    if (TraceStackWalk) {
-      tty->print("  %d: frame method: ", index); method->print_short_name();
-      tty->print_cr(" bci=%d", stream.bci());
+    if (log_is_enabled(Debug, stackwalk)) {
+      ResourceMark rm(THREAD);
+      outputStream* st = Log(stackwalk)::debug_stream();
+      st->print("  %d: frame method: ", index);
+      method->print_short_name(st);
+      st->print_cr(" bci=%d", stream.bci());
     }
 
     if (!need_method_info(mode) && get_caller_class(mode) &&
@@ -317,10 +322,8 @@
                     TRAPS) {
   ResourceMark rm(THREAD);
   JavaThread* jt = (JavaThread*)THREAD;
-  if (TraceStackWalk) {
-    tty->print_cr("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
-                  mode, skip_frames, frame_count);
-  }
+  log_debug(stackwalk)("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
+                       mode, skip_frames, frame_count);
 
   if (frames_array.is_null()) {
     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
@@ -355,8 +358,12 @@
         break;
       }
 
-      if (TraceStackWalk) {
-        tty->print("  skip "); stream.method()->print_short_name(); tty->print("\n");
+      if (log_is_enabled(Debug, stackwalk)) {
+        ResourceMark rm(THREAD);
+        outputStream* st = Log(stackwalk)::debug_stream();
+        st->print("  skip ");
+        stream.method()->print_short_name(st);
+        st->cr();
       }
       stream.next();
     }
@@ -364,8 +371,12 @@
     // stack frame has been traversed individually and resume stack walk
     // from the stack frame at depth == skip_frames.
     for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) {
-      if (TraceStackWalk) {
-        tty->print("  skip "); stream.method()->print_short_name(); tty->cr();
+      if (log_is_enabled(Debug, stackwalk)) {
+        ResourceMark rm(THREAD);
+        outputStream* st = Log(stackwalk)::debug_stream();
+        st->print("  skip ");
+        stream.method()->print_short_name(st);
+        st->cr();
       }
     }
   }
@@ -438,10 +449,9 @@
     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
   }
 
-  if (TraceStackWalk) {
-    tty->print_cr("StackWalk::fetchNextBatch frame_count %d existing_stream " PTR_FORMAT " start %d frames %d",
-                  frame_count, p2i(existing_stream), start_index, frames_array->length());
-  }
+  log_debug(stackwalk)("StackWalk::fetchNextBatch frame_count %d existing_stream "
+                       PTR_FORMAT " start %d frames %d",
+                       frame_count, p2i(existing_stream), start_index, frames_array->length());
   int end_index = start_index;
   if (frame_count <= 0) {
     return end_index;        // No operation.
--- a/src/share/vm/runtime/arguments.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/runtime/arguments.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -351,14 +351,6 @@
  *         Deprecated options should be tested in VMDeprecatedOptions.java.
  */
 
-// Obsolete or deprecated -XX flag.
-typedef struct {
-  const char* name;
-  JDK_Version deprecated_in; // When the deprecation warning started (or "undefined").
-  JDK_Version obsolete_in;   // When the obsolete warning started (or "undefined").
-  JDK_Version expired_in;    // When the option expires (or "undefined").
-} SpecialFlag;
-
 // The special_jvm_flags table declares options that are being deprecated and/or obsoleted. The
 // "deprecated_in" or "obsolete_in" fields may be set to "undefined", but not both.
 // When the JDK version reaches 'deprecated_in' limit, the JVM will process this flag on
@@ -380,6 +372,8 @@
   // -------------- Deprecated Flags --------------
   // --- Non-alias flags - sorted by obsolete_in then expired_in:
   { "MaxGCMinorPauseMillis",        JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
+  { "AutoGCSelectPauseMillis",      JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
+  { "UseAutoGCSelectPolicy",        JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
   { "UseParNewGC",                  JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
   { "ConvertSleepToYield",          JDK_Version::jdk(9), JDK_Version::jdk(10),     JDK_Version::jdk(11) },
   { "ConvertYieldToSleep",          JDK_Version::jdk(9), JDK_Version::jdk(10),     JDK_Version::jdk(11) },
@@ -500,7 +494,14 @@
   }
 }
 
+extern bool lookup_special_flag_ext(const char *flag_name, SpecialFlag& flag);
+
 static bool lookup_special_flag(const char *flag_name, SpecialFlag& flag) {
+  // Allow extensions to have priority
+  if (lookup_special_flag_ext(flag_name, flag)) {
+    return true;
+  }
+
   for (size_t i = 0; special_jvm_flags[i].name != NULL; i++) {
     if ((strcmp(special_jvm_flags[i].name, flag_name) == 0)) {
       flag = special_jvm_flags[i];
@@ -1805,10 +1806,15 @@
 void Arguments::select_gc_ergonomically() {
 #if INCLUDE_ALL_GCS
   if (os::is_server_class_machine()) {
-    if (should_auto_select_low_pause_collector()) {
-      FLAG_SET_ERGO_IF_DEFAULT(bool, UseConcMarkSweepGC, true);
+    if (!UseAutoGCSelectPolicy) {
+       FLAG_SET_ERGO_IF_DEFAULT(bool, UseG1GC, true);
     } else {
-      FLAG_SET_ERGO_IF_DEFAULT(bool, UseG1GC, true);
+      if (should_auto_select_low_pause_collector()) {
+        FLAG_SET_ERGO_IF_DEFAULT(bool, UseConcMarkSweepGC, true);
+        FLAG_SET_ERGO_IF_DEFAULT(bool, UseParNewGC, true);
+      } else {
+        FLAG_SET_ERGO_IF_DEFAULT(bool, UseParallelGC, true);
+      }
     }
   } else {
     FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true);
@@ -2875,11 +2881,13 @@
       if (FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
+      handle_extra_cms_flags("-Xconcgc uses UseConcMarkSweepGC");
     // -Xnoconcgc
     } else if (match_option(option, "-Xnoconcgc")) {
       if (FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false) != Flag::SUCCESS) {
         return JNI_EINVAL;
       }
+      handle_extra_cms_flags("-Xnoconcgc uses UseConcMarkSweepGC");
     // -Xbatch
     } else if (match_option(option, "-Xbatch")) {
       if (FLAG_SET_CMDLINE(bool, BackgroundCompilation, false) != Flag::SUCCESS) {
@@ -4169,6 +4177,15 @@
   return true;
 }
 
+void Arguments::handle_extra_cms_flags(const char* msg) {
+  SpecialFlag flag;
+  const char *flag_name = "UseConcMarkSweepGC";
+  if (lookup_special_flag(flag_name, flag)) {
+    handle_aliases_and_deprecation(flag_name, /* print warning */ true);
+    warning("%s", msg);
+  }
+}
+
 // Parse entry point called from JNI_CreateJavaVM
 
 jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
--- a/src/share/vm/runtime/arguments.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/runtime/arguments.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -41,6 +41,14 @@
   typedef jint (JNICALL *vfprintf_hook_t)(FILE *fp, const char *format, va_list args)  ATTRIBUTE_PRINTF(2, 0);
 }
 
+// Obsolete or deprecated -XX flag.
+struct SpecialFlag {
+  const char* name;
+  JDK_Version deprecated_in; // When the deprecation warning started (or "undefined").
+  JDK_Version obsolete_in;   // When the obsolete warning started (or "undefined").
+  JDK_Version expired_in;    // When the option expires (or "undefined").
+};
+
 // PathString is used as:
 //  - the underlying value for a SystemProperty
 //  - the path portion of an --patch-module module/path pair
@@ -519,6 +527,8 @@
 
   static bool handle_deprecated_print_gc_flags();
 
+  static void handle_extra_cms_flags(const char* msg);
+
   static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
                                  const JavaVMInitArgs *java_options_args,
                                  const JavaVMInitArgs *cmd_line_args);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/runtime/arguments_ext.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/arguments.hpp"
+
+bool lookup_special_flag_ext(const char *flag_name, SpecialFlag& flag) {
+  return false;
+}
--- a/src/share/vm/runtime/globals.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/runtime/globals.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -2887,9 +2887,6 @@
           "exceptions (0 means all)")                                       \
           range(0, max_jint/2)                                              \
                                                                             \
-  develop(bool, TraceStackWalk, false,                                      \
-          "Trace stack walking")                                            \
-                                                                            \
   /* notice: the max range value here is max_jint, not max_intx  */         \
   /* because of overflow issue                                   */         \
   diagnostic(intx, GuaranteedSafepointInterval, 1000,                       \
--- a/src/share/vm/runtime/mutex.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/runtime/mutex.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -452,7 +452,7 @@
   ParkEvent * const ESelf = Self->_MutexEvent;
   assert(_OnDeck != ESelf, "invariant");
 
-  // As an optimization, spinners could conditionally try to set ONDECK to _LBIT
+  // As an optimization, spinners could conditionally try to set _OnDeck to _LBIT
   // Synchronizer.cpp uses a similar optimization.
   if (TrySpin(Self)) goto Exeunt;
 
@@ -463,7 +463,7 @@
   OrderAccess::fence();
 
   // Optional optimization ... try barging on the inner lock
-  if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(Self)) == 0) {
+  if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(ESelf)) == 0) {
     goto OnDeck_LOOP;
   }
 
@@ -471,14 +471,14 @@
 
   // At any given time there is at most one ondeck thread.
   // ondeck implies not resident on cxq and not resident on EntryList
-  // Only the OnDeck thread can try to acquire -- contended for -- the lock.
+  // Only the OnDeck thread can try to acquire -- contend for -- the lock.
   // CONSIDER: use Self->OnDeck instead of m->OnDeck.
   // Deschedule Self so that others may run.
-  while (_OnDeck != ESelf) {
+  while (OrderAccess::load_ptr_acquire(&_OnDeck) != ESelf) {
     ParkCommon(ESelf, 0);
   }
 
-  // Self is now in the ONDECK position and will remain so until it
+  // Self is now in the OnDeck position and will remain so until it
   // manages to acquire the lock.
  OnDeck_LOOP:
   for (;;) {
@@ -501,8 +501,8 @@
   // A. Shift or defer dropping the inner lock until the subsequent IUnlock() operation.
   //    This might avoid potential reacquisition of the inner lock in IUlock().
   // B. While still holding the inner lock, attempt to opportunistically select
-  //    and unlink the next ONDECK thread from the EntryList.
-  //    If successful, set ONDECK to refer to that thread, otherwise clear ONDECK.
+  //    and unlink the next OnDeck thread from the EntryList.
+  //    If successful, set OnDeck to refer to that thread, otherwise clear OnDeck.
   //    It's critical that the select-and-unlink operation run in constant-time as
   //    it executes when holding the outer lock and may artificially increase the
   //    effective length of the critical section.
@@ -529,7 +529,7 @@
   OrderAccess::release_store(&_LockWord.Bytes[_LSBINDEX], 0); // drop outer lock
 
   OrderAccess::storeload();
-  ParkEvent * const w = _OnDeck;
+  ParkEvent * const w = _OnDeck; // raw load as we will just return if non-NULL
   assert(RelaxAssert || w != Thread::current()->_MutexEvent, "invariant");
   if (w != NULL) {
     // Either we have a valid ondeck thread or ondeck is transiently "locked"
@@ -537,7 +537,7 @@
     // OnDeck allows us to discriminate two cases.  If the latter, the
     // responsibility for progress and succession lies with that other thread.
     // For good performance, we also depend on the fact that redundant unpark()
-    // operations are cheap.  That is, repeated Unpark()ing of the ONDECK thread
+    // operations are cheap.  That is, repeated Unpark()ing of the OnDeck thread
     // is inexpensive.  This approach provides implicit futile wakeup throttling.
     // Note that the referent "w" might be stale with respect to the lock.
     // In that case the following unpark() is harmless and the worst that'll happen
@@ -586,8 +586,13 @@
     _EntryList = w->ListNext;
     // as a diagnostic measure consider setting w->_ListNext = BAD
     assert(UNS(_OnDeck) == _LBIT, "invariant");
-    _OnDeck = w;  // pass OnDeck to w.
-                  // w will clear OnDeck once it acquires the outer lock
+
+    // Pass OnDeck role to w, ensuring that _EntryList has been set first.
+    // w will clear _OnDeck once it acquires the outer lock.
+    // Note that once we set _OnDeck that thread can acquire the mutex, proceed
+    // with its critical section and then enter this code to unlock the mutex. So
+    // you can have multiple threads active in IUnlock at the same time.
+    OrderAccess::release_store_ptr(&_OnDeck, w);
 
     // Another optional optimization ...
     // For heavily contended locks it's not uncommon that some other
@@ -835,7 +840,7 @@
     // ESelf is now on the cxq, EntryList or at the OnDeck position.
     // The following fragment is extracted from Monitor::ILock()
     for (;;) {
-      if (_OnDeck == ESelf && TrySpin(Self)) break;
+      if (OrderAccess::load_ptr_acquire(&_OnDeck) == ESelf && TrySpin(Self)) break;
       ParkCommon(ESelf, 0);
     }
     assert(_OnDeck == ESelf, "invariant");
@@ -1050,10 +1055,10 @@
 
   // At any given time there is at most one ondeck thread.
   // ondeck implies not resident on cxq and not resident on EntryList
-  // Only the OnDeck thread can try to acquire -- contended for -- the lock.
+  // Only the OnDeck thread can try to acquire -- contend for -- the lock.
   // CONSIDER: use Self->OnDeck instead of m->OnDeck.
   for (;;) {
-    if (_OnDeck == ESelf && TrySpin(NULL)) break;
+    if (OrderAccess::load_ptr_acquire(&_OnDeck) == ESelf && TrySpin(NULL)) break;
     ParkCommon(ESelf, 0);
   }
 
--- a/src/share/vm/runtime/mutex.hpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/runtime/mutex.hpp	Thu Oct 20 16:53:56 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,9 @@
 // *in that order*.  If their implementations change such that these
 // assumptions are violated, a whole lot of code will break.
 
-// The default length of monitor name is chosen to be 64 to avoid false sharing.
+// The default length of monitor name was originally chosen to be 64 to avoid
+// false sharing. Now, PaddedMonitor is available for this purpose.
+// TODO: Check if _name[MONITOR_NAME_LEN] should better get replaced by const char*.
 static const int MONITOR_NAME_LEN = 64;
 
 class Monitor : public CHeapObj<mtInternal> {
@@ -254,6 +256,18 @@
 
 };
 
+class PaddedMonitor : public Monitor {
+  enum {
+    CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Monitor),
+    PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
+  };
+  char _padding[PADDING_LEN];
+ public:
+  PaddedMonitor(int rank, const char *name, bool allow_vm_block = false,
+               SafepointCheckRequired safepoint_check_required = _safepoint_check_always) :
+    Monitor(rank, name, allow_vm_block, safepoint_check_required) {};
+};
+
 // Normally we'd expect Monitor to extend Mutex in the sense that a monitor
 // constructed from pthreads primitives might extend a mutex by adding
 // a condvar and some extra metadata.  In fact this was the case until J2SE7.
@@ -292,5 +306,16 @@
    }
 };
 
+class PaddedMutex : public Mutex {
+  enum {
+    CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex),
+    PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
+  };
+  char _padding[PADDING_LEN];
+public:
+  PaddedMutex(int rank, const char *name, bool allow_vm_block = false,
+              SafepointCheckRequired safepoint_check_required = _safepoint_check_always) :
+    Mutex(rank, name, allow_vm_block, safepoint_check_required) {};
+};
 
 #endif // SHARE_VM_RUNTIME_MUTEX_HPP
--- a/src/share/vm/runtime/mutexLocker.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/runtime/mutexLocker.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -169,122 +169,123 @@
   _mutex_array[_num_mutex++] = var;                                      \
 }
 
+// Using Padded subclasses to prevent false sharing of these global monitors and mutexes.
 void mutex_init() {
-  def(tty_lock                     , Mutex  , event,       true,  Monitor::_safepoint_check_never);      // allow to lock in VM
+  def(tty_lock                     , PaddedMutex  , event,       true,  Monitor::_safepoint_check_never);      // allow to lock in VM
 
-  def(CGC_lock                     , Monitor, special,     true,  Monitor::_safepoint_check_never);      // coordinate between fore- and background GC
-  def(STS_lock                     , Monitor, leaf,        true,  Monitor::_safepoint_check_never);
+  def(CGC_lock                     , PaddedMonitor, special,     true,  Monitor::_safepoint_check_never);      // coordinate between fore- and background GC
+  def(STS_lock                     , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);
 
   if (UseConcMarkSweepGC || UseG1GC) {
-    def(FullGCCount_lock           , Monitor, leaf,        true,  Monitor::_safepoint_check_never);      // in support of ExplicitGCInvokesConcurrent
+    def(FullGCCount_lock           , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);      // in support of ExplicitGCInvokesConcurrent
   }
   if (UseG1GC) {
 
-    def(SATB_Q_FL_lock             , Mutex  , special,     true,  Monitor::_safepoint_check_never);
-    def(SATB_Q_CBL_mon             , Monitor, nonleaf,     true,  Monitor::_safepoint_check_never);
-    def(Shared_SATB_Q_lock         , Mutex,   nonleaf,     true,  Monitor::_safepoint_check_never);
+    def(SATB_Q_FL_lock             , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);
+    def(SATB_Q_CBL_mon             , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_never);
+    def(Shared_SATB_Q_lock         , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
 
-    def(DirtyCardQ_FL_lock         , Mutex  , special,     true,  Monitor::_safepoint_check_never);
-    def(DirtyCardQ_CBL_mon         , Monitor, nonleaf,     true,  Monitor::_safepoint_check_never);
-    def(Shared_DirtyCardQ_lock     , Mutex,   nonleaf,     true,  Monitor::_safepoint_check_never);
+    def(DirtyCardQ_FL_lock         , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);
+    def(DirtyCardQ_CBL_mon         , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_never);
+    def(Shared_DirtyCardQ_lock     , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
 
-    def(FreeList_lock              , Mutex,   leaf     ,   true,  Monitor::_safepoint_check_never);
-    def(SecondaryFreeList_lock     , Monitor, leaf     ,   true,  Monitor::_safepoint_check_never);
-    def(OldSets_lock               , Mutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
-    def(RootRegionScan_lock        , Monitor, leaf     ,   true,  Monitor::_safepoint_check_never);
-    def(MMUTracker_lock            , Mutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
+    def(FreeList_lock              , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
+    def(SecondaryFreeList_lock     , PaddedMonitor, leaf     ,   true,  Monitor::_safepoint_check_never);
+    def(OldSets_lock               , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
+    def(RootRegionScan_lock        , PaddedMonitor, leaf     ,   true,  Monitor::_safepoint_check_never);
+    def(MMUTracker_lock            , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
 
-    def(StringDedupQueue_lock      , Monitor, leaf,        true,  Monitor::_safepoint_check_never);
-    def(StringDedupTable_lock      , Mutex  , leaf,        true,  Monitor::_safepoint_check_never);
+    def(StringDedupQueue_lock      , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);
+    def(StringDedupTable_lock      , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
 
-    def(MarkStackFreeList_lock     , Mutex , leaf      ,   true,  Monitor::_safepoint_check_never);
-    def(MarkStackChunkList_lock    , Mutex , leaf      ,   true,  Monitor::_safepoint_check_never);
+    def(MarkStackFreeList_lock     , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
+    def(MarkStackChunkList_lock    , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_never);
   }
-  def(ParGCRareEvent_lock          , Mutex  , leaf     ,   true,  Monitor::_safepoint_check_sometimes);
-  def(DerivedPointerTableGC_lock   , Mutex,   leaf,        true,  Monitor::_safepoint_check_never);
-  def(CodeCache_lock               , Mutex  , special,     true,  Monitor::_safepoint_check_never);
-  def(RawMonitor_lock              , Mutex,   special,     true,  Monitor::_safepoint_check_never);
-  def(OopMapCacheAlloc_lock        , Mutex,   leaf,        true,  Monitor::_safepoint_check_always);     // used for oop_map_cache allocation.
+  def(ParGCRareEvent_lock          , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_sometimes);
+  def(DerivedPointerTableGC_lock   , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
+  def(CodeCache_lock               , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);
+  def(RawMonitor_lock              , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);
+  def(OopMapCacheAlloc_lock        , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);     // used for oop_map_cache allocation.
 
-  def(Patching_lock                , Mutex  , special,     true,  Monitor::_safepoint_check_never);      // used for safepointing and code patching.
-  def(Service_lock                 , Monitor, special,     true,  Monitor::_safepoint_check_never);      // used for service thread operations
-  def(JmethodIdCreation_lock       , Mutex  , leaf,        true,  Monitor::_safepoint_check_always);     // used for creating jmethodIDs.
+  def(Patching_lock                , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);      // used for safepointing and code patching.
+  def(Service_lock                 , PaddedMonitor, special,     true,  Monitor::_safepoint_check_never);      // used for service thread operations
+  def(JmethodIdCreation_lock       , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);     // used for creating jmethodIDs.
 
-  def(SystemDictionary_lock        , Monitor, leaf,        true,  Monitor::_safepoint_check_always);     // lookups done by VM thread
-  def(Module_lock                  , Mutex  , leaf+2,      true,  Monitor::_safepoint_check_always);
-  def(InlineCacheBuffer_lock       , Mutex  , leaf,        true,  Monitor::_safepoint_check_always);
-  def(VMStatistic_lock             , Mutex  , leaf,        false, Monitor::_safepoint_check_always);
-  def(ExpandHeap_lock              , Mutex  , leaf,        true,  Monitor::_safepoint_check_always);     // Used during compilation by VM thread
-  def(JNIHandleBlockFreeList_lock  , Mutex  , leaf,        true,  Monitor::_safepoint_check_never);      // handles are used by VM thread
-  def(SignatureHandlerLibrary_lock , Mutex  , leaf,        false, Monitor::_safepoint_check_always);
-  def(SymbolTable_lock             , Mutex  , leaf+2,      true,  Monitor::_safepoint_check_always);
-  def(StringTable_lock             , Mutex  , leaf,        true,  Monitor::_safepoint_check_always);
-  def(ProfilePrint_lock            , Mutex  , leaf,        false, Monitor::_safepoint_check_always);     // serial profile printing
-  def(ExceptionCache_lock          , Mutex  , leaf,        false, Monitor::_safepoint_check_always);     // serial profile printing
-  def(OsrList_lock                 , Mutex  , leaf,        true,  Monitor::_safepoint_check_never);
-  def(Debug1_lock                  , Mutex  , leaf,        true,  Monitor::_safepoint_check_never);
+  def(SystemDictionary_lock        , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_always);     // lookups done by VM thread
+  def(Module_lock                  , PaddedMutex  , leaf+2,      true,  Monitor::_safepoint_check_always);
+  def(InlineCacheBuffer_lock       , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);
+  def(VMStatistic_lock             , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always);
+  def(ExpandHeap_lock              , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);     // Used during compilation by VM thread
+  def(JNIHandleBlockFreeList_lock  , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);      // handles are used by VM thread
+  def(SignatureHandlerLibrary_lock , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always);
+  def(SymbolTable_lock             , PaddedMutex  , leaf+2,      true,  Monitor::_safepoint_check_always);
+  def(StringTable_lock             , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);
+  def(ProfilePrint_lock            , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always);     // serial profile printing
+  def(ExceptionCache_lock          , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always);     // serial profile printing
+  def(OsrList_lock                 , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
+  def(Debug1_lock                  , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
 #ifndef PRODUCT
-  def(FullGCALot_lock              , Mutex  , leaf,        false, Monitor::_safepoint_check_always);     // a lock to make FullGCALot MT safe
+  def(FullGCALot_lock              , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always);     // a lock to make FullGCALot MT safe
 #endif
-  def(BeforeExit_lock              , Monitor, leaf,        true,  Monitor::_safepoint_check_always);
-  def(PerfDataMemAlloc_lock        , Mutex  , leaf,        true,  Monitor::_safepoint_check_always);     // used for allocating PerfData memory for performance data
-  def(PerfDataManager_lock         , Mutex  , leaf,        true,  Monitor::_safepoint_check_always);     // used for synchronized access to PerfDataManager resources
+  def(BeforeExit_lock              , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_always);
+  def(PerfDataMemAlloc_lock        , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);     // used for allocating PerfData memory for performance data
+  def(PerfDataManager_lock         , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);     // used for synchronized access to PerfDataManager resources
 
   // CMS_modUnionTable_lock                   leaf
   // CMS_bitMap_lock                          leaf 1
   // CMS_freeList_lock                        leaf 2
 
-  def(Safepoint_lock               , Monitor, safepoint,   true,  Monitor::_safepoint_check_sometimes);  // locks SnippetCache_lock/Threads_lock
+  def(Safepoint_lock               , PaddedMonitor, safepoint,   true,  Monitor::_safepoint_check_sometimes);  // locks SnippetCache_lock/Threads_lock
 
-  def(Threads_lock                 , Monitor, barrier,     true,  Monitor::_safepoint_check_sometimes);
+  def(Threads_lock                 , PaddedMonitor, barrier,     true,  Monitor::_safepoint_check_sometimes);
 
-  def(VMOperationQueue_lock        , Monitor, nonleaf,     true,  Monitor::_safepoint_check_sometimes);  // VM_thread allowed to block on these
-  def(VMOperationRequest_lock      , Monitor, nonleaf,     true,  Monitor::_safepoint_check_sometimes);
-  def(RetData_lock                 , Mutex  , nonleaf,     false, Monitor::_safepoint_check_always);
-  def(Terminator_lock              , Monitor, nonleaf,     true,  Monitor::_safepoint_check_sometimes);
-  def(VtableStubs_lock             , Mutex  , nonleaf,     true,  Monitor::_safepoint_check_always);
-  def(Notify_lock                  , Monitor, nonleaf,     true,  Monitor::_safepoint_check_always);
-  def(JNIGlobalHandle_lock         , Mutex  , nonleaf,     true,  Monitor::_safepoint_check_always);     // locks JNIHandleBlockFreeList_lock
-  def(JNICritical_lock             , Monitor, nonleaf,     true,  Monitor::_safepoint_check_always);     // used for JNI critical regions
-  def(AdapterHandlerLibrary_lock   , Mutex  , nonleaf,     true,  Monitor::_safepoint_check_always);
+  def(VMOperationQueue_lock        , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_sometimes);  // VM_thread allowed to block on these
+  def(VMOperationRequest_lock      , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_sometimes);
+  def(RetData_lock                 , PaddedMutex  , nonleaf,     false, Monitor::_safepoint_check_always);
+  def(Terminator_lock              , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_sometimes);
+  def(VtableStubs_lock             , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_always);
+  def(Notify_lock                  , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_always);
+  def(JNIGlobalHandle_lock         , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_always);     // locks JNIHandleBlockFreeList_lock
+  def(JNICritical_lock             , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_always);     // used for JNI critical regions
+  def(AdapterHandlerLibrary_lock   , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_always);
 
-  def(Heap_lock                    , Monitor, nonleaf+1,   false, Monitor::_safepoint_check_sometimes);
-  def(JfieldIdCreation_lock        , Mutex  , nonleaf+1,   true,  Monitor::_safepoint_check_always);     // jfieldID, Used in VM_Operation
-  def(MemberNameTable_lock         , Mutex  , nonleaf+1,   false, Monitor::_safepoint_check_always);     // Used to protect MemberNameTable
+  def(Heap_lock                    , PaddedMonitor, nonleaf+1,   false, Monitor::_safepoint_check_sometimes);
+  def(JfieldIdCreation_lock        , PaddedMutex  , nonleaf+1,   true,  Monitor::_safepoint_check_always);     // jfieldID, Used in VM_Operation
+  def(MemberNameTable_lock         , PaddedMutex  , nonleaf+1,   false, Monitor::_safepoint_check_always);     // Used to protect MemberNameTable
 
-  def(CompiledIC_lock              , Mutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // locks VtableStubs_lock, InlineCacheBuffer_lock
-  def(CompileTaskAlloc_lock        , Mutex  , nonleaf+2,   true,  Monitor::_safepoint_check_always);
-  def(CompileStatistics_lock       , Mutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);
-  def(DirectivesStack_lock         , Mutex  , special,     true,  Monitor::_safepoint_check_never);
-  def(MultiArray_lock              , Mutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // locks SymbolTable_lock
+  def(CompiledIC_lock              , PaddedMutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // locks VtableStubs_lock, InlineCacheBuffer_lock
+  def(CompileTaskAlloc_lock        , PaddedMutex  , nonleaf+2,   true,  Monitor::_safepoint_check_always);
+  def(CompileStatistics_lock       , PaddedMutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);
+  def(DirectivesStack_lock         , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);
+  def(MultiArray_lock              , PaddedMutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // locks SymbolTable_lock
 
-  def(JvmtiThreadState_lock        , Mutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // Used by JvmtiThreadState/JvmtiEventController
-  def(Management_lock              , Mutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // used for JVM management
+  def(JvmtiThreadState_lock        , PaddedMutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // Used by JvmtiThreadState/JvmtiEventController
+  def(Management_lock              , PaddedMutex  , nonleaf+2,   false, Monitor::_safepoint_check_always);     // used for JVM management
 
-  def(Compile_lock                 , Mutex  , nonleaf+3,   true,  Monitor::_safepoint_check_sometimes);
-  def(MethodData_lock              , Mutex  , nonleaf+3,   false, Monitor::_safepoint_check_always);
-  def(TouchedMethodLog_lock        , Mutex  , nonleaf+3,   false, Monitor::_safepoint_check_always);
+  def(Compile_lock                 , PaddedMutex  , nonleaf+3,   true,  Monitor::_safepoint_check_sometimes);
+  def(MethodData_lock              , PaddedMutex  , nonleaf+3,   false, Monitor::_safepoint_check_always);
+  def(TouchedMethodLog_lock        , PaddedMutex  , nonleaf+3,   false, Monitor::_safepoint_check_always);
 
-  def(MethodCompileQueue_lock      , Monitor, nonleaf+4,   true,  Monitor::_safepoint_check_always);
-  def(Debug2_lock                  , Mutex  , nonleaf+4,   true,  Monitor::_safepoint_check_never);
-  def(Debug3_lock                  , Mutex  , nonleaf+4,   true,  Monitor::_safepoint_check_never);
-  def(CompileThread_lock           , Monitor, nonleaf+5,   false, Monitor::_safepoint_check_always);
-  def(PeriodicTask_lock            , Monitor, nonleaf+5,   true,  Monitor::_safepoint_check_sometimes);
-  def(RedefineClasses_lock         , Monitor, nonleaf+5,   true,  Monitor::_safepoint_check_always);
+  def(MethodCompileQueue_lock      , PaddedMonitor, nonleaf+4,   true,  Monitor::_safepoint_check_always);
+  def(Debug2_lock                  , PaddedMutex  , nonleaf+4,   true,  Monitor::_safepoint_check_never);
+  def(Debug3_lock                  , PaddedMutex  , nonleaf+4,   true,  Monitor::_safepoint_check_never);
+  def(CompileThread_lock           , PaddedMonitor, nonleaf+5,   false, Monitor::_safepoint_check_always);
+  def(PeriodicTask_lock            , PaddedMonitor, nonleaf+5,   true,  Monitor::_safepoint_check_sometimes);
+  def(RedefineClasses_lock         , PaddedMonitor, nonleaf+5,   true,  Monitor::_safepoint_check_always);
   if (WhiteBoxAPI) {
-    def(Compilation_lock           , Monitor, leaf,        false, Monitor::_safepoint_check_never);
+    def(Compilation_lock           , PaddedMonitor, leaf,        false, Monitor::_safepoint_check_never);
   }
 
 #ifdef INCLUDE_TRACE
-  def(JfrMsg_lock                  , Monitor, leaf,        true,  Monitor::_safepoint_check_always);
-  def(JfrBuffer_lock               , Mutex,   leaf,        true,  Monitor::_safepoint_check_never);
-  def(JfrThreadGroups_lock         , Mutex,   leaf,        true,  Monitor::_safepoint_check_always);
-  def(JfrStream_lock               , Mutex,   leaf+1,      true,  Monitor::_safepoint_check_never);      // ensure to rank lower than 'safepoint'
-  def(JfrStacktrace_lock           , Mutex,   special,     true,  Monitor::_safepoint_check_sometimes);
+  def(JfrMsg_lock                  , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_always);
+  def(JfrBuffer_lock               , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
+  def(JfrThreadGroups_lock         , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);
+  def(JfrStream_lock               , PaddedMutex  , leaf+1,      true,  Monitor::_safepoint_check_never);      // ensure to rank lower than 'safepoint'
+  def(JfrStacktrace_lock           , PaddedMutex  , special,     true,  Monitor::_safepoint_check_sometimes);
 #endif
 
 #ifndef SUPPORTS_NATIVE_CX8
-  def(UnsafeJlong_lock             , Mutex,   special,     false, Monitor::_safepoint_check_never);
+  def(UnsafeJlong_lock             , PaddedMutex  , special,     false, Monitor::_safepoint_check_never);
 #endif
 }
 
--- a/src/share/vm/runtime/thread.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/runtime/thread.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -3768,10 +3768,21 @@
   SystemDictionary::compute_java_system_loader(CHECK_(JNI_ERR));
 
 #if INCLUDE_JVMCI
-  if (EnableJVMCI && UseJVMCICompiler && (!UseInterpreter || !BackgroundCompilation)) {
-    // 8145270: Force initialization of JVMCI runtime otherwise requests for blocking
-    // compilations via JVMCI will not actually block until JVMCI is initialized.
-    JVMCIRuntime::force_initialization(CHECK_JNI_ERR);
+  if (EnableJVMCI) {
+    // Initialize JVMCI eagerly if JVMCIPrintProperties is enabled.
+    // The JVMCI Java initialization code will read this flag and
+    // do the printing if it's set.
+    bool init = JVMCIPrintProperties;
+
+    if (!init) {
+      // 8145270: Force initialization of JVMCI runtime otherwise requests for blocking
+      // compilations via JVMCI will not actually block until JVMCI is initialized.
+      init = UseJVMCICompiler && (!UseInterpreter || !BackgroundCompilation);
+    }
+
+    if (init) {
+      JVMCIRuntime::force_initialization(CHECK_JNI_ERR);
+    }
   }
 #endif
 
--- a/src/share/vm/utilities/internalVMTests.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ b/src/share/vm/utilities/internalVMTests.cpp	Thu Oct 20 16:53:56 2016 -0700
@@ -58,30 +58,12 @@
   run_unit_test(TestNewSize_test);
   run_unit_test(TestOldSize_test);
   run_unit_test(TestBitMap_test);
-  run_unit_test(TestResourcehash_test);
   run_unit_test(ObjectMonitor_test);
-  run_unit_test(Test_log_tag_combinations_limit);
-  run_unit_test(Test_logtarget);
-  run_unit_test(Test_logstream);
-  run_unit_test(Test_loghandle);
-  run_unit_test(Test_logtargethandle);
-  run_unit_test(Test_log_gctracetime);
-  run_unit_test(Test_configure_stdout);
-  run_unit_test(Test_logconfiguration_subscribe);
-  run_unit_test(Test_log_prefix);
-  run_unit_test(Test_log_big);
-  run_unit_test(Test_logtagset_duplicates);
-  run_unit_test(Test_logtagset_descriptions);
-  run_unit_test(Test_log_file_startup_rotation);
-  run_unit_test(Test_log_file_startup_truncation);
-  run_unit_test(Test_invalid_log_file);
-  run_unit_test(Test_multiline_logging);
   run_unit_test(DirectivesParser_test);
 #if INCLUDE_VM_STRUCTS
   run_unit_test(VMStructs_test);
 #endif
 #if INCLUDE_ALL_GCS
-  run_unit_test(TestG1BiasedArray_test);
   run_unit_test(TestBufferingOopClosure_test);
   if (UseG1GC) {
     run_unit_test(FreeRegionList_test);
--- a/src/share/vm/utilities/resourceHash.cpp	Thu Oct 20 20:01:43 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "memory/allocation.hpp"
-#include "memory/resourceArea.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/resourceHash.hpp"
-
-#ifndef PRODUCT
-
-/////////////// Unit tests ///////////////
-
-class TestResourceHashtable : public AllStatic {
-  typedef void* K;
-  typedef int V;
-
-  static unsigned identity_hash(const K& k) {
-    return (unsigned)(uintptr_t)k;
-  }
-
-  static unsigned bad_hash(const K& k) {
-    return 1;
-  }
-
-  class EqualityTestIter {
-   public:
-    bool do_entry(K const& k, V const& v) {
-      assert((uintptr_t)k == (uintptr_t)v, "");
-      return true; // continue iteration
-    }
-  };
-
-  template<
-  unsigned (*HASH)  (K const&)           = primitive_hash<K>,
-  bool     (*EQUALS)(K const&, K const&) = primitive_equals<K>,
-  unsigned SIZE = 256,
-  ResourceObj::allocation_type ALLOC_TYPE = ResourceObj::RESOURCE_AREA,
-  MEMFLAGS MEM_TYPE = mtInternal
-  >
-  class Runner : public AllStatic {
-    static void* as_K(uintptr_t val) { return (void*)val; }
-
-   public:
-    static void test_small() {
-      EqualityTestIter et;
-      ResourceHashtable<K, V, HASH, EQUALS, SIZE, ALLOC_TYPE, MEM_TYPE> rh;
-
-      assert(!rh.contains(as_K(0x1)), "");
-
-      assert(rh.put(as_K(0x1), 0x1), "");
-      assert(rh.contains(as_K(0x1)), "");
-
-      assert(!rh.put(as_K(0x1), 0x1), "");
-
-      assert(rh.put(as_K(0x2), 0x2), "");
-      assert(rh.put(as_K(0x3), 0x3), "");
-      assert(rh.put(as_K(0x4), 0x4), "");
-      assert(rh.put(as_K(0x5), 0x5), "");
-
-      assert(!rh.remove(as_K(0x0)), "");
-      rh.iterate(&et);
-
-      assert(rh.remove(as_K(0x1)), "");
-      rh.iterate(&et);
-
-    }
-
-    // We use keys with the low bits cleared since the default hash will do some shifting
-    static void test_small_shifted() {
-      EqualityTestIter et;
-      ResourceHashtable<K, V, HASH, EQUALS, SIZE, ALLOC_TYPE, MEM_TYPE> rh;
-
-      assert(!rh.contains(as_K(0x10)), "");
-
-      assert(rh.put(as_K(0x10), 0x10), "");
-      assert(rh.contains(as_K(0x10)), "");
-
-      assert(!rh.put(as_K(0x10), 0x10), "");
-
-      assert(rh.put(as_K(0x20), 0x20), "");
-      assert(rh.put(as_K(0x30), 0x30), "");
-      assert(rh.put(as_K(0x40), 0x40), "");
-      assert(rh.put(as_K(0x50), 0x50), "");
-
-      assert(!rh.remove(as_K(0x00)), "");
-
-      assert(rh.remove(as_K(0x10)), "");
-
-      rh.iterate(&et);
-    }
-
-    static void test(unsigned num_elements = SIZE) {
-      EqualityTestIter et;
-      ResourceHashtable<K, V, HASH, EQUALS, SIZE, ALLOC_TYPE, MEM_TYPE> rh;
-
-      for (uintptr_t i = 0; i < num_elements; ++i) {
-        assert(rh.put(as_K(i), i), "");
-      }
-
-      rh.iterate(&et);
-
-      for (uintptr_t i = num_elements; i > 0; --i) {
-        uintptr_t index = i - 1;
-        assert(rh.remove(as_K(index)), "");
-      }
-      rh.iterate(&et);
-      for (uintptr_t i = num_elements; i > 0; --i) {
-        uintptr_t index = i - 1;
-        assert(!rh.remove(as_K(index)), "");
-      }
-      rh.iterate(&et);
-    }
-  };
-
- public:
-  static void run_tests() {
-    {
-      ResourceMark rm;
-      Runner<>::test_small();
-      Runner<>::test_small_shifted();
-      Runner<>::test();
-    }
-
-    {
-      ResourceMark rm;
-      Runner<identity_hash>::test_small();
-      Runner<identity_hash>::test_small_shifted();
-      Runner<identity_hash>::test();
-    }
-
-    {
-      ResourceMark rm;
-      Runner<bad_hash>::test_small();
-      Runner<bad_hash>::test_small_shifted();
-      Runner<bad_hash>::test();
-    }
-
-
-    assert(Thread::current()->resource_area()->nesting() == 0, "this code depends on not having an active ResourceMark");
-    // The following test calls will cause an assert if resource allocations occur since we don't have an active mark
-    Runner<primitive_hash<K>, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test_small();
-    Runner<primitive_hash<K>, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test_small_shifted();
-    Runner<primitive_hash<K>, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test();
-
-    Runner<bad_hash, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test_small();
-    Runner<bad_hash, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test_small_shifted();
-    Runner<bad_hash, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test();
-
-    Runner<identity_hash, primitive_equals<K>, 1, ResourceObj::C_HEAP>::test_small();
-    Runner<identity_hash, primitive_equals<K>, 1, ResourceObj::C_HEAP>::test_small_shifted();
-    Runner<identity_hash, primitive_equals<K>, 1, ResourceObj::C_HEAP>::test(512);
-  }
-};
-
-void TestResourcehash_test() {
-  TestResourceHashtable::run_tests();
-}
-
-#endif // not PRODUCT
-
--- a/test/Makefile	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/Makefile	Thu Oct 20 16:53:56 2016 -0700
@@ -66,6 +66,7 @@
   ifeq ($(ARCH), i386)
     ARCH=i586
   endif
+  NUM_CORES := $(shell LC_MESSAGES=C /usr/sbin/psrinfo -v | grep -c on-line)
 endif
 ifeq ($(UNAME_S), Linux)
   PLATFORM = linux
@@ -74,6 +75,7 @@
   ifeq ($(ARCH), i386)
     ARCH = i586
   endif
+  NUM_CORES := $(shell cat /proc/cpuinfo  | grep -c processor)
 endif
 ifeq ($(UNAME_S), Darwin)
   PLATFORM = bsd
@@ -82,6 +84,7 @@
   ifeq ($(ARCH), i386)
     ARCH = i586
   endif
+  NUM_CORES := $(shell /usr/sbin/sysctl -n hw.ncpu)
 endif
 ifeq ($(findstring BSD,$(UNAME_S)), BSD)
   PLATFORM = bsd
@@ -115,6 +118,13 @@
     endif
   endif
   EXESUFFIX = .exe
+  ifneq ($(NUMBER_OF_PROCESSORS), )
+    NUM_CORES := $(NUMBER_OF_PROCESSORS)
+  else
+    ifneq ($(HOTSPOT_BUILD_JOBS), )
+      NUM_CORES := $(HOTSPOT_BUILD_JOBS)
+    endif
+  endif
 endif
 
 ifdef ALT_SLASH_JAVA
@@ -308,9 +318,22 @@
   TEST_SELECTION = $(TESTDIRS)
 endif
 
-ifdef CONCURRENCY
-  JTREG_BASIC_OPTIONS += -concurrency:$(CONCURRENCY)
+# Concurrency based on min(cores / 2, 12)
+ifdef NUM_CORES
+  CONCURRENCY := $(shell expr $(NUM_CORES) / 2)
+  ifeq ($(CONCURRENCY), 0)
+    CONCURRENCY := 1
+  else ifeq ($(shell expr $(CONCURRENCY) \> 12), 1)
+    CONCURRENCY := 12
+  endif
+else 
+  CONCURRENCY := 1
 endif
+JTREG_BASIC_OPTIONS += -concurrency:$(CONCURRENCY)
+
+# Make sure MaxRAMFraction is high enough to not cause OOM or swapping since we may end up with a lot of JVM's
+JTREG_BASIC_OPTIONS += -vmoption:-XX:MaxRAMFraction=$(shell expr $(CONCURRENCY) \* 4)
+
 ifdef EXTRA_JTREG_OPTIONS
   JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
 endif
--- a/test/TEST.groups	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/TEST.groups	Thu Oct 20 16:53:56 2016 -0700
@@ -370,6 +370,7 @@
  -runtime/modules/ModuleStress/ModuleStressGC.java \
  -runtime/NMT \
  -runtime/RedefineObject/TestRedefineObject.java \
+ -runtime/RedefineTests/RedefineLeak.java \
  -runtime/RedefineTests/RedefinePreviousVersions.java \
  -runtime/RedefineTests/RedefineRunningMethods.java \
  -runtime/RedefineTests/RedefineRunningMethodsWithBacktrace.java \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/arraycopy/TestEliminatedCloneBadMemEdge.java	Thu Oct 20 16:53:56 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, Red Hat, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8166836
+ * @summary Elimination of clone's ArrayCopyNode may make compilation fail silently
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestEliminatedCloneBadMemEdge::not_inlined TestEliminatedCloneBadMemEdge
+ *
+ */
+
+public class TestEliminatedCloneBadMemEdge implements Cloneable {
+
+    int f1;
+    int f2;
+    int f3;
+    int f4;
+    int f5;
+    int f6;
+    int f7;
+    int f8;
+    int f9;
+
+    static void not_inlined() {}
+
+    static void test(TestEliminatedCloneBadMemEdge o1) throws CloneNotSupportedException {
+        TestEliminatedCloneBadMemEdge o2 = (TestEliminatedCloneBadMemEdge)o1.clone();
+        not_inlined();
+        o2.f1 = 0x42;
+    }
+
+    static public void main(String[] args) throws CloneNotSupportedException {
+        TestEliminatedCloneBadMemEdge o1 = new TestEliminatedCloneBadMemEdge();
+        for (int i = 0; i < 20000; i++) {
+            test(o1);
+        }
+    }
+}
--- a/test/compiler/c1/NullCheckTest.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/NullCheckTest.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test6579789.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test6579789.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test6795465.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test6795465.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test6849574.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test6849574.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test6855215.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test6855215.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test6932496.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test6932496.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test7042153.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test7042153.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test7090976.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test7090976.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test7103261.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test7103261.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test7123108.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test7123108.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/Test8004051.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/Test8004051.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/TestArrayCopy.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/TestArrayCopy.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/TestDeoptInt.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/TestDeoptInt.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c1/TestUnalignedLoad.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c1/TestUnalignedLoad.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/FloatingPointFoldingTest.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/FloatingPointFoldingTest.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/IVTest.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/IVTest.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/InterruptedTest.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/InterruptedTest.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /*
--- a/test/compiler/c2/Test6186134.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6186134.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/Test6196102.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6196102.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/Test6357214.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6357214.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/Test6443505.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6443505.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/Test6559156.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6559156.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/Test6661247.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6661247.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /*
--- a/test/compiler/c2/Test6732154.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6732154.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/Test6753639.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6753639.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/Test6792161.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6792161.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
- *
  */
 
 /**
--- a/test/compiler/c2/Test6796786.java	Thu Oct 20 20:01:43 2016 +0000
+++ b/test/compiler/c2/Test6796786.java	Thu Oct 20 16:53:56 2016 -0700
@@ -19,7 +19,6 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA